Skip to content

Commit

Permalink
Clarified/fixed error messages; added error IDs; easier use of -updat…
Browse files Browse the repository at this point in the history
…e option; various other small fixes
  • Loading branch information
altmany committed Jan 15, 2020
1 parent 243db06 commit d5538e9
Show file tree
Hide file tree
Showing 7 changed files with 196 additions and 92 deletions.
11 changes: 7 additions & 4 deletions eps2pdf.m
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ function eps2pdf(source, dest, crop, append, gray, quality, gs_options)
% 16/01/18: Improved appending of multiple EPS files into single PDF (issue #233; thanks @shartjen)
% 18/10/19: Workaround for GS 9.51+ .setpdfwrite removal problem (issue #285)
% 18/10/19: Warn when ignoring GS fontpath or quality options; clarified error messages
% 15/01/20: Added information about the GS/destination filepath in case of error (issue #294)

% Intialise the options string for ghostscript
options = ['-q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -sOutputFile="' dest '"'];
Expand Down Expand Up @@ -177,21 +178,23 @@ function eps2pdf(source, dest, crop, append, gray, quality, gs_options)

% Report error
if isempty(message)
error('Unable to generate pdf. Ensure that the destination folder is writable.');
error(['Unable to generate pdf. Ensure that the destination folder (' fileparts(dest) ') is writable.']);
elseif ~isempty(strfind(message,'/typecheck in /findfont')) %#ok<STREMP>
% Suggest a workaround for issue #41 (missing font path)
font_name = strtrim(regexprep(message,'.*Operand stack:\s*(.*)\s*Execution.*','$1'));
fprintf(2, 'Ghostscript error: could not find the following font(s): %s\n', font_name);
fpath = fileparts(mfilename('fullpath'));
gs_fonts_file = fullfile(fpath, '.ignore', 'gs_font_path.txt');
%fpath = fileparts(mfilename('fullpath'));
%gs_fonts_file = fullfile(fpath, '.ignore', 'gs_font_path.txt');
[unused, gs_fonts_file] = user_string('gs_font_path'); %#ok<ASGLU>
fprintf(2, ' try to add the font''s folder to your %s file\n\n', gs_fonts_file);
error('export_fig error');
else
fprintf(2, '\nGhostscript error: perhaps %s is open by another application\n', dest);
if ~isempty(gs_options)
fprintf(2, ' or maybe your Ghostscript version does not accept the extra "%s" option(s) that you requested\n', gs_options);
end
fprintf(2, ' or maybe you have another gs executable in your system''s path\n');
fprintf(2, ' or maybe you have another gs executable in your system''s path\n\n');
fprintf(2, 'Ghostscript path: %s\n', user_string('ghostscript'));
fprintf(2, 'Ghostscript options: %s\n\n', orig_options);
error(message);
end
Expand Down
158 changes: 92 additions & 66 deletions export_fig.m

Large diffs are not rendered by default.

44 changes: 28 additions & 16 deletions ghostscript.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@
%
% Once found, the executable is called with the input command string.
%
% This function requires that you have Ghostscript installed on your
% system. You can download this from: http://www.ghostscript.com
% This function requires a Ghostscript installation on your system.
% You can download Ghostscript from http://ghostscript.com (Windows/Linux)
% or http://pages.uoregon.edu/koch (MacOS).
%
% IN:
% cmd - Command string to be passed into ghostscript.
Expand Down Expand Up @@ -41,6 +42,7 @@
% 14/05/15 - Clarified warning message in case GS path could not be saved
% 29/05/15 - Avoid cryptic error in case the ghostscipt path cannot be saved (issue #74)
% 10/11/15 - Custom GS installation webpage for MacOS. Thanks to Andy Hueni via FEX
% 15/01/20 - Various message cleanups/fixes in case of errors
%}

try
Expand All @@ -51,18 +53,24 @@
url1 = 'https://github.com/altmany/export_fig/issues/12#issuecomment-61467998'; % issue #12
url2 = 'https://github.com/altmany/export_fig/issues/20#issuecomment-63826270'; % issue #20
hg2_str = ''; if using_hg2, hg2_str = ' or Matlab R2014a'; end
fprintf(2, 'Ghostscript error. Rolling back to GS 9.10%s may possibly solve this:\n * <a href="%s">%s</a> ',hg2_str,url1,url1);
fprintf(2, 'Ghostscript error. Rolling back to GS 9.10%s may possibly solve this:\n * %s ', hg2_str, hyperlink(url1));
if using_hg2
fprintf(2, '(GS 9.10)\n * <a href="%s">%s</a> (R2014a)',url2,url2);
fprintf(2, '(GS 9.10)\n * %s (R2014a)', hyperlink(url2));
end
fprintf('\n\n');
if ismac || isunix
url3 = 'https://github.com/altmany/export_fig/issues/27'; % issue #27
fprintf(2, 'Alternatively, this may possibly be due to a font path issue:\n * <a href="%s">%s</a>\n\n',url3,url3);
fprintf(2, 'Alternatively, this may possibly be due to a font path issue:\n * %s\n\n', hyperlink(url3));
% issue #20
fpath = which(mfilename);
if isempty(fpath), fpath = [mfilename('fullpath') '.m']; end
fprintf(2, 'Alternatively, if you are using csh, modify shell_cmd from "export..." to "setenv ..."\nat the bottom of <a href="matlab:opentoline(''%s'',174)">%s</a>\n\n',fpath,fpath);
% TODO: in Unix/Mac, find a way to automatically determine whether to use "export" (bash) or "setenv" (csh/tcsh)
if isdeployed
url = [mfilename '.m'];
else
fpath = which(mfilename);
if isempty(fpath), fpath = [mfilename('fullpath') '.m']; end
url = ['<a href="matlab:opentoline(''' fpath ''',201)">' fpath '</a>'];
end
fprintf(2, 'Alternatively, if you are using csh, modify shell_cmd from "export ..." to "setenv ..."\nat the bottom of %s\n\n', url);
end
rethrow(err);
end
Expand Down Expand Up @@ -127,10 +135,12 @@
while true
if strncmp(computer, 'MAC', 3) % Is a Mac
% Give separate warning as the uigetdir dialogue box doesn't have a
% title
uiwait(warndlg('Ghostscript not found. Please locate the program.'))
% title on MacOS
uiwait(warndlg('Ghostscript installation not found - please locate the program.', 'Ghostscript'))
base = uigetdir('/', 'Ghostcript program location');
else
base = uigetdir('/', 'Ghostcript program not found - please locate it');
end
base = uigetdir('/', 'Ghostcript not found. Please locate the program.');
if isequal(base, 0)
% User hit cancel or closed window
break;
Expand All @@ -149,10 +159,11 @@
end
end
if ismac
error('Ghostscript not found. Have you installed it (http://pages.uoregon.edu/koch)?');
url = 'http://pages.uoregon.edu/koch';
else
error('Ghostscript not found. Have you installed it from www.ghostscript.com?');
url = 'http://ghostscript.com';
end
error('Ghostscript:NotFound', 'Ghostscript not found. Have you installed it from %s ?', hyperlink(url));
end

function good = check_store_gs_path(path_)
Expand All @@ -163,8 +174,9 @@
end
% Update the current default path to the path found
if ~user_string('ghostscript', path_)
filename = fullfile(fileparts(which('user_string.m')), '.ignore', 'ghostscript.txt');
warning('Path to ghostscript installation could not be saved in %s (perhaps a permissions issue). You can manually create this file and set its contents to %s, to improve performance in future invocations (this warning is safe to ignore).', filename, path_);
%filename = fullfile(fileparts(which('user_string.m')), '.ignore', 'ghostscript.txt');
[unused, filename] = user_string('ghostscript'); %#ok<ASGLU>
warning('Ghostscript:path', 'Path to ghostscript installation could not be saved in %s (perhaps a permissions issue). You can manually create this file and set its contents to %s, to improve performance in future invocations (this warning is safe to ignore).', filename, path_);
return
end
end
Expand All @@ -183,7 +195,7 @@

function cmd = gs_command(path_)
% Initialize any required system calls before calling ghostscript
% TODO: in Unix/Mac, find a way to determine whether to use "export" (bash) or "setenv" (csh/tcsh)
% TODO: in Unix/Mac, find a way to automatically determine whether to use "export" (bash) or "setenv" (csh/tcsh)
shell_cmd = '';
if isunix
shell_cmd = 'export LD_LIBRARY_PATH=""; '; % Avoids an error on Linux with GS 9.07
Expand Down
53 changes: 53 additions & 0 deletions hyperlink.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
function str = hyperlink(url, label, msg)
%HYPERLINK create a string that is displayable as hyperlink in Matlab console
%
% Usage examples:
% fprintf('Search on %s\n', hyperlink('http://google.com','Google'));
% fprintf(hyperlink('http://google.com','Google','Search on Google\n'));
%
% HYPERLINK converts the specified URL and text label into a string that is
% displayed as a hyperlink in the Matlab console (Command Window).
% In a deployed (compiled) program, the URL and text label (if different
% from the URL) are displayed in a non-hyperlinked plain-text manner.
% If the optional 3rd input argument (msg) is specified, then all instances of
% the specified label within msg will be handled as above (hyperlinked etc.)
%
% IN:
% url - (mandatory) URL of webpage or Matlab command (e.g., 'matlab:which(...')
% label - (optional) text label of the hyperlink. Default: url
% msg - (optional) string in which all label instances should be hyperlinked
%
% OUT:
% str - string output

% Copyright: Yair Altman 2020-
%{
% 15/01/20 - Initial version
%}

error(nargchk(1,3,nargin)); %#ok<NCHKN> narginchk is only available in R2011b+
if nargin > 2 % msg was specified
% replace all instances of label within msg with corresponding hyperlink
str = strrep(msg, label, hyperlink(url,label));
return
end
if nargin < 2, label = url; end
isWebpage = strncmpi(url,'http',4);

% Only hyperlink in interactive Matlab sessions, not in a deployed program
if ~isdeployed % interactive Matlab session
if isWebpage % open in a web browser
str = ['<a href="matlab:web(''-browser'',''' url ''');">' label '</a>'];
else % Matlab command e.g. 'matlab:which(...'
str = ['<a href="' url '">' label '</a>'];
end
else % deployed (compiled)
if isWebpage && ~strcmp(label,url) % display label next to url
str = [label ' (' url ')'];
elseif isWebpage % text==url - display only the url
str = url;
else % Matlab command (not a webpage) - just display the label
str = label;
end
end
end
9 changes: 6 additions & 3 deletions pdftops.m
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
% 03/05/2016 - Display the specific error message if pdftops fails for some reason (issue #148)
% 22/09/2018 - Xpdf website changed to xpdfreader.com; improved popup logic
% 03/02/2019 - Fixed one-off 'pdftops not found' error after install (Mac/Linux) (issue #266)
% 15/01/2020 - Fixed reported path of pdftops.txt file in case of error; added warning ID

% Call pdftops
[varargout{1:nargout}] = system([xpdf_command(xpdf_path()) cmd]);
Expand Down Expand Up @@ -70,7 +71,7 @@
% Ask the user to enter the path
errMsg1 = 'Pdftops not found. Please locate the program, or install xpdf-tools from ';
url1 = 'http://xpdfreader.com/download.html'; %='http://foolabs.com/xpdf';
fprintf(2, '%s\n', [errMsg1 '<a href="matlab:web(''-browser'',''' url1 ''');">' url1 '</a>']);
fprintf(2, '%s%s\n', errMsg1, hyperlink(url1));
errMsg1 = [errMsg1 url1];
%if strncmp(computer,'MAC',3) % Is a Mac
% % Give separate warning as the MacOS uigetdir dialogue box doesn't have a title
Expand All @@ -80,7 +81,7 @@
% Provide an alternative possible explanation as per issue #137
errMsg2 = 'If you have pdftops installed, perhaps Matlab is shaddowing it as described in ';
url2 = 'https://github.com/altmany/export_fig/issues/137';
fprintf(2, '%s\n', [errMsg2 '<a href="matlab:web(''-browser'',''' url2 ''');">issue #137</a>']);
fprintf(2, '%s%s\n', errMsg2, hyperlink(url2,'issue #137'));
errMsg2 = [errMsg2 url1];

state = 1;
Expand Down Expand Up @@ -132,7 +133,9 @@
end
% Update the current default path to the path found
if ~user_string('pdftops', path_)
warning('Path to pdftops executable could not be saved. Enter it manually in %s.', fullfile(fileparts(which('user_string.m')), '.ignore', 'pdftops.txt'));
%filename = fullfile(fileparts(which('user_string.m')), '.ignore', 'pdftops.txt');
[unused, filename] = user_string('pdftops'); %#ok<ASGLU>
warning('export_fig:pdftops','Path to pdftops executable could not be saved. Enter it manually in %s.', filename);
return
end
end
Expand Down
3 changes: 2 additions & 1 deletion print2eps.m
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ function print2eps(name, fig, export_options, varargin)
% 14/05/19: Made Helvetica the top default font-swap, replacing Courier
% 12/06/19: Issue #277: Enabled preservation of figure's PaperSize in output PDF/EPS file
% 06/08/19: Issue #281: only fix patch/textbox color if it's not opaque
% 15/01/20: Added warning ID for easier suppression by users
%}

options = {'-loose'};
Expand Down Expand Up @@ -355,7 +356,7 @@ function print2eps(name, fig, export_options, varargin)

% Bail out if EPS post-processing is not possible
if isempty(fstrm)
warning('Loading EPS file failed, so unable to perform post-processing. This is usually because the figure contains a large number of patch objects. Consider exporting to a bitmap format in this case.');
warning('YMA:export_fig:EPS','Loading EPS file failed, so unable to perform post-processing. This is usually because the figure contains a large number of patch objects. Consider exporting to a bitmap format in this case.');
return
end

Expand Down
10 changes: 8 additions & 2 deletions user_string.m
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
function string = user_string(string_name, string)
function [string, file_name] = user_string(string_name, string)
%USER_STRING Get/set a user specific string
%
% Examples:
% string = user_string(string_name)
% isSaved = user_string(string_name, new_string)
% [value, file_name] = user_string(...)
%
% Function to get and set a string in a system or user specific file. This
% enables, for example, system specific paths to binaries to be saved.
Expand All @@ -20,6 +21,7 @@
% OUT:
% string - The currently saved string. Default: ''
% isSaved - Boolean indicating whether the save was succesful
% file_name - path of the .txt file used to contain the requested string

% Copyright (C) Oliver Woodford 2011-2014, Yair Altman 2015-

Expand All @@ -33,6 +35,7 @@
% errors. Thanks to Christian for pointing this out.
% 29/05/2015 - Save file in prefdir if current folder is non-writable (issue #74)
% 09/01/2018 - Fix issue #232: if the string looks like a file/folder path, ensure it actually exists
% 15/01/2020 - Added file_name output argument

if ~ischar(string_name)
error('string_name must be a string.');
Expand All @@ -41,6 +44,7 @@
fname = [string_name '.txt'];
dname = fullfile(fileparts(mfilename('fullpath')), '.ignore');
file_name = fullfile(dname, fname);
default_file_name = file_name;
if nargin > 1
% Set string
if ~ischar(string)
Expand Down Expand Up @@ -76,7 +80,8 @@
end
if fid == -1
string = false;
return;
file_name = default_file_name;
return
end
end
try
Expand All @@ -97,6 +102,7 @@
fid = fopen(file_name, 'rt');
if fid == -1
string = '';
file_name = default_file_name;
return
end
end
Expand Down

0 comments on commit d5538e9

Please sign in to comment.