Skip to content

Commit

Permalink
Merge pull request #1085 from matlab2tikz/develop
Browse files Browse the repository at this point in the history
Reduce git-flow to github-flow
  • Loading branch information
egeerardyn committed Aug 18, 2020
2 parents 56c94a1 + 6926d9f commit f299888
Show file tree
Hide file tree
Showing 10 changed files with 796 additions and 134 deletions.
7 changes: 4 additions & 3 deletions AUTHORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Thanks for patches, suggestions, and other contributions go to:
* Martijn Aben (The MathWorks)
* [Nicolas Alt](https://github.com/nalt)
* [Eshwar Andhavarapu](https://github.com/gontadu)
* Matt Bauman
* [Matt Bauman](https://github.com/mbauman)
* Eike Blechschmidt
* [Klaus Broelemann](https://github.com/Broele)
* [Katherine Elkington](https://github.com/kelkington)
Expand All @@ -24,7 +24,7 @@ Thanks for patches, suggestions, and other contributions go to:
* [David Horsley](https://github.com/widdma)
* Kári Hreinsson
* [Lucas Jeub](https://github.com/LJeub)
* Martin Kiefel
* [Martin Kiefel](https://github.com/mkiefel)
* [Andreas Kloeckner](https://github.com/akloeckner)
* Mykel Kochenderfer
* [Oleg Komarov](https://github.com/okomarov)
Expand All @@ -43,6 +43,7 @@ Thanks for patches, suggestions, and other contributions go to:
* Julien Ridoux
* [Christoph Rüdiger](https://github.com/mredd)
* Carlos Russo
* [Michael Schellenberger Costa](https://github.com/miscco)
* [Manuel Schiller](https://github.com/dachziegel)
* [Nico Schlömer](https://github.com/nschloe)
* Johannes Schmitz
Expand All @@ -55,7 +56,7 @@ Thanks for patches, suggestions, and other contributions go to:
* Robert Whittlesey
* Pooya Ziraksaz
* Bastiaan Zuurendonk (The MathWorks)
* GitHub users: [andreas12345](https://github.com/andreas12345), [theswitch](https://github.com/theswitch)
* GitHub users: [andreas12345](https://github.com/andreas12345), [karih](https://github.com/karih), [theswitch](https://github.com/theswitch)

# Acknowledgements
Matlab2tikz has once greatly profited from its ancestor: [Matfig2PGF](http://www.mathworks.com/matlabcentral/fileexchange/12962) written by Paul Wagenaars.
Expand Down
216 changes: 216 additions & 0 deletions src/m2tcustom.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
function [value] = m2tcustom(handle, varargin)
% M2TCUSTOM creates user-defined options for matlab2tikz output
%
% M2TCUSTOM can be used to create, get and set a properly formatted data
% structure to customize the conversion of MATLAB figures to TikZ using
% matlab2tikz. In particular, it allows to:
%
% * add blocks of LaTeX/TikZ code around any HG object,
% * add blocks of comments around any HG object,
% * add TikZ options to any HG object,
% * add LaTeX/TikZ code inside some HG objects (e.g. axes),
% * provide a custom handler to convert a particular HG object.
%
% Note that this provides advanced functionality. Only very basic
% sanity checks are performed such that injudicious use may produce
% broken TikZ figures!
%
% It is HIGHLY recommended that you are comfortable with:
%
% * writing pgfplots, TikZ and LaTeX code,
% * using the Handle Graphics (HG) framework in MATLAB/Octave, and
% * the inner working of matlab2tikz (for custom handlers)
%
% when you use this function. I.e. you should know what you are doing.
%
%
% Usage as a GETTER:
% ------------------
%
% value = M2TCUSTOM(handle)
% retrieves the current custom data structure from the HG object "handle"
%
%
% Usage as a SETTER:
% ------------------
%
% M2TCUSTOM(handle, ...)
% value = M2TCUSTOM(handle, ...)
% will construct the proper data structure and try to set it to the object
% |handle| if possible. The arguments (see below) are specified in
% key-value pairs akin to a normal |struct|, but here we do a few checks
% and data normalization.
%
% If we denote BLOCK to mean either a |char| or a |cellstr|, the following
% options can be passed. Different entries in a cellstr are assumed
% separated by a newline. The default values are empty.
%
% M2TCUSTOM(handle, 'commentBefore', BLOCK, ...)
% M2TCUSTOM(handle, 'commentAfter' , BLOCK, ...)
% to add comments before/after the object. Our code translates newlines
% and adds the percentage signs for you.
%
% M2TCUSTOM(handle, 'codeBefore', BLOCK, ...)
% M2TCUSTOM(handle, 'codeAfter', BLOCK, ...)
% M2TCUSTOM(handle, 'codeInsideFirst', BLOCK, ...)
% M2TCUSTOM(handle, 'codeInsideLast', BLOCK, ...)
% to add raw LaTeX/TikZ code respectively before, after, as first thing
% inside or as last thing inside the pgfplots representation of the object.
% Note that for some HG objects, (e.g. line objects), |codeInsideFirst|
% and |codeInsideLast| do not make any sense and are hence ignored.
%
% M2TCUSTOM(handle, 'extraOptions', OPTIONS, ...)
% adds extra pgfplots/TikZ options to the end of the option list. Here,
% OPTIONS is properly formatted TikZ code in
% - a |char| (e.g. 'color=red, line width=1pt' )
% - a |cellstr| (e.g. {'color=red','line width=1pt'})
%
% M2TCUSTOM(handle, 'customHandler', FUNCTION_HANDLE, ...)
% allows you to replace the default matlab2tikz handler for this object.
% This is not for the faint of heart and requires intimate knowledge of
% the matlab2tikz code base! We expect a function (either as |char| or
% function handle) that will be called as
%
% [m2t, str] = feval(handler, m2t, handle, custom)
%
% such that the expected function signature is:
%
% function [m2t, str] = handler(m2t, handle, custom)
%
% where |m2t| is an undocumented/unstable data structure,
% |str| is a char containing TikZ code representing the
% HG object |handle| as generated by your handler,
% |custom| is a structure as returned by |m2tcustom|
% from which you only need to handle |extraOptions|,
% |codeInsideFirst| and |codeInsideLast| when applicable.
% A particularly useful value for |customHandler| is 'drawNothing',
% which remove the object from the output.
%
%
% Example:
% --------
%
% Executing the following MATLAB code fragment:
%
% figure;
% plot(1:10);
% EOL = sprintf('\n');
% m2tCustom(gca, 'codeBefore' , ['<codeBefore>' EOL] , ...
% 'codeAfter' , ['<codeAfter>' EOL] , ...
% 'commentsBefore' , '<commentsBefore>' , ...
% 'commentsAfter' , '<commentsAfter>' , ...
% 'codeInsideFirst' , ['<codeInsideFirst>' EOL], ...
% 'codeInsideLast' , ['<codeInsideLast>' EOL], ...
% 'extraOptions' , '<extraOptions>');
%
% matlab2tikz('test.tikz')
%
% Should result in a |test.tikz| file with contents that look somewhat
% like this:
%
% \begin{tikzpicture}
% %<commentsBefore>
% <codeBefore>
% \begin{axis}[..., <extraOptions>]
% <codeInsideFirst>
% \addplot{...};
% <codeInsideLast>
% \end{axis}
% %<commentsAfter>
% <codeAfter>
% \end{tikzpicture}
%
% See also: matlab2tikz, setappdata, getappdata

%% arguments specific to this constructor function
ipp = m2tInputParser();
ipp = ipp.addRequired(ipp, 'handle', @isHgObject);

%% Declaration of the custom data structure
ipp = ipp.addParamValue(ipp, 'codeBefore', '', @isCellstrOrChar);
ipp = ipp.addParamValue(ipp, 'codeAfter', '', @isCellstrOrChar);

ipp = ipp.addParamValue(ipp, 'commentsBefore', '', @isCellstrOrChar);
ipp = ipp.addParamValue(ipp, 'commentsAfter', '', @isCellstrOrChar);

ipp = ipp.addParamValue(ipp, 'codeInsideFirst', '', @isCellstrOrChar);
ipp = ipp.addParamValue(ipp, 'codeInsideLast', '', @isCellstrOrChar);

ipp = ipp.addParamValue(ipp, 'extraOptions', '', @isCellstrOrChar);
ipp = ipp.addParamValue(ipp, 'customHandler', '', @isHandler);

%% Parse the arguments
ipp = ipp.parse(ipp, handle, varargin{:});

%% Construct custom data structure
% We leverage the results from the input parser. It provides us
% with validation already. We just need to remove bookkeeping fields
value = ipp.Results;
value = rmfield(value, {'handle'});

%% Normalize the actual values
value.codeBefore = cellstr2char(value.codeBefore);
value.codeAfter = cellstr2char(value.codeAfter);
value.codeInsideFirst = cellstr2char(value.codeInsideFirst);
value.codeInsideLast = cellstr2char(value.codeInsideLast);
value.commentsBefore = cellstr2char(value.commentsBefore);
value.commentsAfter = cellstr2char(value.commentsAfter);
if isempty(value.customHandler)
value = rmfield(value, 'customHandler');
end
% extraOptions gets normalized by |opts_append_userdefined|

%% Different Usage modes
MATLAB2TIKZ = 'matlab2tikz'; % key used for application data storage
if numel(varargin) == 0
%% GETTER MODE
% syntax: value = m2tcustom(h);
if ~isempty(handle)
object = getappdata(handle, MATLAB2TIKZ);
else
object = [];
end
if ~isempty(object)
value = object;
else
% |value| contains all default (empty) values
end
else
%% SETTER MODE
% syntax: m2tcustom(h , key1, val1, ...)
% syntax: value = m2tcustom([], key1, val1, ...)
if ~isempty(handle)
setappdata(handle, MATLAB2TIKZ, value);
end
end
end
% == INPUT VALIDATORS ==========================================================
function bool = isHgObject(value)
% true for HG object or empty (or numeric for backwards compatibility)
bool = isempty(value) || ishghandle(value) || isnumeric(value);
end
function bool = isCellstrOrChar(value)
% true for cellstr or char
bool = ischar(value) || iscellstr(value);
end
function bool = isHandler(value)
% true for char or function handle of the form [m2t, str] = f(m2t, h, opts)
bool = isempty(value) || ischar(value) || ...
(isa(value, 'function_handle') && ...
atLeastOrUnknown(nargin(value), 3) && ...
atLeastOrUnknown(nargout(value), 2));
end
function bool = atLeastOrUnknown(nargs, limit)
% checks for |nargin| and |nargout| >= |limit| (or equal to -1)
UNKNOWN = -1;
bool = (nargs == UNKNOWN) || nargs >= limit;
end
% == FIELD NORMALIZATION =======================================================
function value = cellstr2char(value)
% convert cellstr to char (and keep char unaffected)
if iscellstr(value)
EOL = sprintf('\n');
value = m2tstrjoin(value, EOL);
end
end
% ==============================================================================
Loading

0 comments on commit f299888

Please sign in to comment.