function shareIt(options)
% SHAREIT Share an exported figure or Simulink model (printed to a file) via email.
% SYNTAX
% shareIt(options)
%
% options is a structure containing the following fields:
% toSend: REQUIRED - single handle or vector of handles of
% figures/Simulink models to share
% eg. gcf for figures
% get_param(gcs, 'handle') for open Simulink models
% mailTo: REQUIRED - email address to send output to
% ** multiple addresses can be specified using a cell array of
% strings
% baseFile: REQUIRED - temp file pathname to print output to
% ** files will be created using this baseFile name, with an
% index/counter and an extension appended to it
% eg. test1.bmp, test2.bmp, ...
% note: no index/counter will be applied if generating
% postscript output and the optional 'append' flag is
% set to 1; instead a single postscript file will be
% created containing the combined output of all
% figures/models specified in the 'toSend' setting
% ** extension used will be derived from the specified device
% ** one file will be generated for each handle in the
% 'toSend' vector, unless generating postscript output and
% the optional 'append' is set to 1
% note: this WILL OVERWRITE files of the same name in the
% output folder
% device: OPTIONAL - output format to create, as in 'png', 'jpeg' etc, as recognized by
% the MATLAB print command.
% ** if not specified, 'png' will be used as the default.
% message: OPTIONAL - text string to use as the email's message body
% ** if not specified it will be left blank (unless 'tags'
% field is specified
% subject: OPTIONAL - text string to use as subject line of email
% ** if not specified, 'MATLAB images' will be used as the
% default
% tags: OPTIONAL - text string include in body of email message
% (supports tagging images sent to flickr)
% ** if specified, it will be prefixed with the string: 'tags: '
% ** if not specified it will not be included
% delete: OPTIONAL - set to 1 to delete temporary files after sending
% email, or set to 0 to retain the temporary files.
% ** if not specified, default is 1 - delete temporary files
% append: OPTIONAL - for POSTSCRIPT devices only. Set to 1 to place
% all output into a single postscript file. Ignored if the
% output device is encapsulated postscript (eps) or any
% non-postscript device.
% ** if not specified, default is 0 - create separate files
%
% Example:
% create a plot and email the output to someuser@somedomain.com
% fig = figure;
% plot(1:10);
% title('MATLAB');
% myOptions.toSend = fig;
% myOptions.mailTo = 'someuser@somedomain.com';
% myOptions.baseFile = [tempdir 'test'];
% myOptions.device ='png';
% myOptions.message = 'see what MATLAB can do';
% myOptions.subject = ['Output from MATLAB v' version];
% myOptions.tags = 'MATLAB';
% myOptions.delete = 1;
% shareIt(myOptions);
%
% reprint the plot to .jpg and email the output to
% multiple users:
% myOptions.mailTo = {'someuser@somedomain.com', ...
% 'anotheruser@somedomain.com'}
% myOptions.device ='jpeg';
% shareIt(myOptions);
%
% open a Simulink model, print to bitmap and email that
% (other settings for myOptions are same as above)
% f14;
% myOptions.toSend = get_param('f14', 'handle');
% myOptions.device='bmp';
% shareIt(myOptions);
%
% See also PRINT, SENDMAIL.
% Copyright 2007-2008 The MathWorks, Inc.
theSettings = LocalCheckArgs(options);
numToPrint = length(theSettings.theHandles);
for idx = 1:numToPrint
if theSettings.theAppendFlag
% postscript output, all going into 1 file
thisFile = sprintf('%s.%s', theSettings.theFile, theSettings.theExtension);
else
% separate files per figure/system
thisFile = sprintf('%s%s.%s', theSettings.theFile, num2str(idx), theSettings.theExtension);
end
printArgs = {theSettings.theHandles(idx) theSettings.theDevice, thisFile};
if theSettings.theAppendFlag
printArgs{end+1} = '-append'; %#ok<AGROW>
end
print(printArgs{:});
% sendmail('uses26growth@photos.flickr.com', 'test subj', {'test mess' 'tags: MATLAB'}', 'test.jpg')
% only email if 1) we're appending and we've printed everything or 2)
% if we're not appending
if (theSettings.theAppendFlag && idx == numToPrint) || ~theSettings.theAppendFlag
sendmail(theSettings.theMailTo, theSettings.theSubject, ...
{theSettings.theMessage 10 theSettings.theTags}, thisFile);
end
if theSettings.theDeleteFlag
% only delete if 1) we're appending and we've printed everything or 2)
% if we're not appending
if (theSettings.theAppendFlag && idx == numToPrint) || ~theSettings.theAppendFlag
delete(thisFile);
end
end
end
end
% LocalCheckArgs
% parses input args
function theSettings = LocalCheckArgs(options)
if ~isstruct(options)
error( 'MATLAB:shareIt:NoStruct', 'Parameter must be a structure. See help for details');
end
if ~isfield(options, 'toSend') || isempty(options.toSend)
error( 'MATLAB:shareIt:InvalidStruct','Structure parameter ''toSend'' invalid. See help for details');
end
if ~isfield(options, 'mailTo') || isempty(options.mailTo)
error( 'MATLAB:shareIt:InvalidStruct','Structure parameter ''mailTo'' invalid. See help for details');
end
if ~isfield(options, 'baseFile') || isempty(options.baseFile)
error( 'MATLAB:shareIt:InvalidStruct','Structure parameter ''baseFile'' invalid. See help for details');
end
if ~isfield(options, 'device') || isempty(options.device)
theDevice = 'png';
else
theDevice = options.device;
end
% ok to have an empty subject field
if ~isfield(options, 'subject')
theSubject = 'MATLAB images';
else
theSubject = options.subject;
end
% ok to have an empty message field
if ~isfield(options, 'message')
theMessage = '';
else
theMessage = options.message;
end
% ok to have an empty tags field
if ~isfield(options, 'tags')
theTags = '';
else
theTags = ['tags: ' options.tags];
end
% ok to NOT have a 'delete' field
if ~isfield(options, 'delete')
theDeleteFlag = 1;
else
theDeleteFlag = options.delete;
if ~isnumeric(theDeleteFlag) || theDeleteFlag < 0 || theDeleteFlag > 1
error( 'MATLAB:shareIt:InvalidStruct','Structure parameter ''delete'' invalid. See help for details');
end
end
if strncmp(theDevice, '-d', 2)
theDevice = theDevice(3:end);
end
[pOpts pDev pExt pCls] = printtables();
devIdx = strmatch(theDevice, pDev);
if isempty(devIdx)
error( 'MATLAB:shareIt:InvalidDevice',['Invalid Format Requested: ' theDevice]);
end
theExtension = pExt{devIdx(1)}; % take first matching extension
if ~strncmp(theDevice, '-d', 2)
theDevice = ['-d' theDevice];
end
% ok to NOT have an 'append' field
if ~isfield(options, 'append') || ~strcmpi(pCls(devIdx(1)), 'PS')
theAppendFlag = 0; % do NOT append
else
theAppendFlag = options.append;
if ~isnumeric(theAppendFlag) || theAppendFlag < 0 || theAppendFlag > 1
error( 'MATLAB:shareIt:InvalidStruct','Structure parameter ''append'' invalid. See help for details');
end
end
% setup our return structure
theSettings.theHandles = LocalCheckHandles(options.toSend);
theSettings.theFile = options.baseFile;
theSettings.theMailTo = options.mailTo;
% we may have modified theDevice value
theSettings.theDevice = theDevice;
% we figured out extension based on device
theSettings.theExtension = theExtension;
% if these settings were not set in options then we defaulted them
theSettings.theSubject = theSubject;
theSettings.theMessage = theMessage;
theSettings.theTags = theTags;
theSettings.theDeleteFlag = theDeleteFlag;
theSettings.theAppendFlag = theAppendFlag;
end % end function
%%%%
%%%% LocalCheckHandles
%%%% returns vector of handles to figure/model to print or throws an error
%%%%
function h = LocalCheckHandles( cur_arg )
% Checks that input matrix is full of handles to Figures and/or models.
%the easiest form of generating output is just with a scalar.
if ~iscell( cur_arg )
cur_arg = { cur_arg };
end
h = [];
for i = 1 : length(cur_arg)
v = cur_arg{i};
dims = size( v );
if length(dims) > 2 || dims(1) ~= 1
v = v'; % try transposing it
dims = size(v);
if length(dims) > 2 || dims(1) ~= 1
error( 'MATLAB:shareIt:handleType', 'Handle input must be scalar, vector, or cell-array of vectors.')
end
end
if ~all( ishandle(v) )
error( 'MATLAB:shareIt:handleArgs', 'Handle input argument contains non-handle value(s).' )
end
for j = 1 : length(v)
h(end+1) = v(j); %#ok<AGROW>
end
end
end