The MWE works just fine using the externalisation library. Converting the syntax to use pgfkeys
actually solves the scoping problem since keys are local to the current scope. Thus you can pass the keys and values as an option to the matlabfig
command and they will be used only internally to that command.
I'm only a newcomer to the world of of pgfkeys
so there may be better ways of implementing this, but here's a conversion of your macros into pgfkeys
language. I only changed one thing in the input syntax: the ranges are specified as x range=0:6
instead of x range={0}{6}
.
When putting this in to an environment, the problem is that the externalisation library looks for \end{tikzpicture}
without doing any expansion. In an ordinary environment, this doesn't work because the \end{tikzpicture}
is hidden behind a \end{myenvironment}
. So we have to have a method whereby the \end{myenvironment}
is expanded at the same time as the \begin{tikzpicture}
. Fortunately such a method exists and is to use the environ package. This makes environments behave a little like commands.
\documentclass{article}
\usepackage{environ}
\usepackage{tikz}
\usetikzlibrary{external}
\tikzexternalize
\tikzset{external/force remake=true}
\usepackage{pgfplots}
\def\figurewidth{7.5cm}
\def\figureheight{4cm}
\pgfkeys{/matlab plot/.cd,
title/.default={\null},
title height/.default={0cm},
x label/.default={\null},
x label height/.default={0},
x range/.code args={#1:#2}{\pgfkeyssetvalue{/matlab plot/x range}{xmin=#1,xmax=#2}},
y range/.code args={#1:#2}{\pgfkeyssetvalue{/matlab plot/y range}{ymin=#1,ymax=#2}},
legend/.code args={#1#2}{\pgfkeyssetvalue{/matlab plot/legend}{legend entries=#1,legend pos=#2}},
title/.code={%
\pgfkeyssetvalue{/matlab plot/title}{#1}%
\pgfkeyssetvalue{/matlab plot/title height}{0.45cm}},
x label/.code={%
\pgfkeyssetvalue{/matlab plot/x label}{#1}%
\pgfkeyssetvalue{/matlab plot/x label height}{-0.35}},
caption/.code={%
\pgfkeyssetvalue{/matlab plot/caption}{\caption{#1}}},
label/.code={\pgfkeyssetvalue{/matlab plot/caption}{\label{#1}}}%
}
% Initialise
\pgfkeyssetvalue{/matlab plot/caption}{}
\pgfkeyssetvalue{/matlab plot/label}{}
\pgfkeyssetvalue{/matlab plot/x label}{}
\pgfkeyssetvalue{/matlab plot/y label}{}
\pgfkeyssetvalue{/matlab plot/extra}{}
\pgfkeyssetvalue{/matlab plot/legend}{}
\pgfkeyssetvalue{/matlab plot/x range}{}
\pgfkeyssetvalue{/matlab plot/x range}{}
\pgfkeyssetvalue{/matlab plot/y range}{}
\pgfkeyssetvalue{/matlab plot/y range}{}
\pgfkeyssetvalue{/matlab plot/pos}{}
\def\figysep{1}
\newcommand{\matlabfig}[2][]{%figuur zelf
\begingroup
\pgfkeys{/matlab plot/.cd,#1}
\begin{figure}[\pgfkeysvalueof{/matlab plot/pos}]
\centering
\begin{tikzpicture}[]
% \draw[use as bounding box,draw=none](0,0+\pgfkeysvalueof{x label height})rectangle(\figurewidth,\figureheight+\pgfkeysvalueof{title height});
\begin{axis}[%
view={0}{90},
scale only axis,
width=\figurewidth,
height=\figureheight,
y tick label style={font={\tiny}},
x tick label style={font={\tiny}},
title={\textbf{\textsc{\pgfkeysvalueof{/matlab plot/title}}}},
xlabel={\textbf{\pgfkeysvalueof{/matlab plot/x label}}},
ylabel={\textbf{\pgfkeysvalueof{/matlab plot/y label}}},
\pgfkeysvalueof{/matlab plot/x range},
\pgfkeysvalueof{/matlab plot/y range},
axis on top,
\pgfkeysvalueof{/matlab plot/legend},
\pgfkeysvalueof{/matlab plot/extra}
minor tick num=1
]
\input{#2}
\end{axis}
\end{tikzpicture}
\pgfkeysvalueof{/matlab plot/caption}
\pgfkeysvalueof{/matlab plot/label}
\end{figure}
\endgroup}
\NewEnviron{MatlabFig}[1][]{%
\begingroup
\pgfkeys{/matlab plot/.cd,#1}
\begin{figure}[\pgfkeysvalueof{/matlab plot/pos}]
\centering
\begin{tikzpicture}
% \draw[use as bounding box,draw=none](0,0+\pgfkeysvalueof{x label height})rectangle(\figurewidth,\figureheight+\pgfkeysvalueof{title height});
\begin{axis}[%
view={0}{90},
scale only axis,
width=\figurewidth,
height=\figureheight,
y tick label style={font={\tiny}},
x tick label style={font={\tiny}},
title={\textbf{\textsc{\pgfkeysvalueof{/matlab plot/title}}}},
xlabel={\textbf{\pgfkeysvalueof{/matlab plot/x label}}},
ylabel={\textbf{\pgfkeysvalueof{/matlab plot/y label}}},
\pgfkeysvalueof{/matlab plot/x range},
\pgfkeysvalueof{/matlab plot/y range},
axis on top,
\pgfkeysvalueof{/matlab plot/legend},
\pgfkeysvalueof{/matlab plot/extra}
minor tick num=1
]
\BODY
\end{axis}
\end{tikzpicture}
\pgfkeysvalueof{/matlab plot/caption}
\pgfkeysvalueof{/matlab plot/label}
\end{figure}
\endgroup}
\pgfplotsset{
every tick/.style={thin,color=black},
every axis legend/.append style={nodes={right}},
every axis legend/.append style={font=\tiny},
compat=newest
}
\tikzstyle{every node}=[font=\scriptsize]
\begin{document}
%%
\matlabfig[
caption=an example fig,
label=fig:example,
title=example,
x label=$x$ axis,
y label=$y$ axis,
legend={data.tikz}{north west},
x range=0:6,
y range=0:5,
]{tikzextkeys_data.tikz}
%%
%another fig, but as you can see all was resetted
\matlabfig{tikzextkeys_data.tikz}
\begin{MatlabFig}[
caption=an example fig,
label=fig:example,
title=example,
x label=$x$ axis,
y label=$y$ axis,
legend={data.tikz}{north west},
x range=0:6,
y range=0:5,
]
\input{tikzextkeys_data.tikz}
\end{MatlabFig}
\end{document}
(NB In this code, something is going wrong when I uncomment the bounding box line. It's to do with getting the lengths and values of the keys to interact properly.)
You can't use \verbatim ... \endverbatim
inside a macro. A detailed explanation you can find here:
TeX Frequently Asked Questions - Why doesn’t verbatim work within …?
You can use packages like listings
, fancyvrb
...
Here an example with fancyvrb:
\documentclass[]{scrartcl}
\usepackage[T1]{fontenc}
\usepackage{fancyvrb}
\DefineVerbatimEnvironment{DoxyVerb}{Verbatim}%
{fontfamily=ptm,fontseries=m,fontshape=n}
\begin{document}
\begin{DoxyVerb}
get_asd_asd
\end{DoxyVerb}
\end{document}
EDIT: Using listings
:
\documentclass[]{scrartcl}
\usepackage[T1]{fontenc}
\usepackage{listings}
\lstnewenvironment{lstDoxyVerb}%
{\lstset{basicstyle=\fontsize{10pt}{10}\usefont{OT1}{ptm}{m}{n}}}%
{}
\begin{document}
\begin{lstDoxyVerb}
get_asd_asd
\end{lstDoxyVerb}
\end{document}
Best Answer
There are two problems: the first is that after
the text
\sa and \sb
will render asbecause TeX ignores spaces after control words.
Second problem. A control sequence can consist either of
[A-Za-z]
(control words)Spaces are not ignored after control symbols.
However definitions with
\def
allow for a fairly general syntax:Here
<parameter text>
can be whatever sequence of tokens, including the argument indicators#1
to#9
to denote arguments. But if there are tokens different from the argument indicators, they must appear after\cs
. Sois legal and defines a command
\s
which requires the two tokens_a
to follow it. If you say after thisthe command
\s
is redefined and usage of\s_a
will trigger the error messagesince
\s
is not followed by_b
.To solve both problems at once, use
and then
\sa/ and \sb/
will render asbecause the required
/
after the commands' names stops the space ignoring feature.