1

I would like to divide a list of parameters for a series of tikz graphics into a bunch of separate, named tex files.

Specifically: each parameter file should be loaded by an \input command which in turn is contained inside the definition of one cumulative \newcommand, see setspecs-command.tex below.

The \newcommand is itself loaded via another \input in the main.tex file.

I naively thought the \newcommand parameter numbers e.g. #1 would work inside the inputted files, but I am getting the error message:

./parameters1.tex:5:
Illegal parameter number in definition of \tikz@math@marshal.

A related error message:

./parameters1.tex:1: You can't use `macro parameter character #' in horizontal mode.

comes from printing the parameter value inside the inputted file, e.g. by inserting the line:

Parameter file #1 was loaded.

before the \tikzmath environment in parameters1.tex.

Any thoughts on how to deal with \newcommand macro parameters inside a file loaded via \input?

Full MWE below:

main.tex

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{math}

%%
%Courtesy of egreg, see https://tex.stackexchange.com/questions/415138
\usepackage{pdftexcmds}
\makeatletter
\newcommand{\strequal}[2]{\pdf@strcmp{#1}{#2}==0}
\makeatother
%%

\input{setspecs-command}

\begin{document}
First graphic:\\
\setspecs{parameters2}
\begin{tikzpicture}
    \draw (-2,-2) rectangle (2,2);
    \node at (0,0) {\var};
\end{tikzpicture}
\clearpage

Then second graphic:\\
\setspecs{parameters1}
\begin{tikzpicture}
    \draw (-2,-2) rectangle (2,2);
    \node at (0,0) {\var};
\end{tikzpicture}
\end{document}

The file containing the definition of the setspecs command:

setspecs-command.tex

\newcommand\setspecs[1]{
    \input{parameters1}
    \input{parameters2}
    %... further files to be added as and when needed
}

Two examples of the parameter files below:

parameters1.tex

%Parameter file #1 was loaded.
%All parameter files will have the following overarching structure
\tikzmath{
    if \strequal{#1}{parameters1} then {
        \var = 111;
    };
}

parameters2.tex

\tikzmath{
    if \strequal{#1}{parameters2} then {
        \var = 222;
    };
}
2
  • Is there a reason why you want to have all of the specifications in different files? It’s not clear to me what you are trying to do but at first guess using pgfkeys looks to be a better approach. If you really do need to do it this way it would be simpler, and much more efficient, to have \setspecs input only the required file. Something like \newcommand\setspecs[1]{\input{parameter#1}}, although you might need some \expandafters to make this work in practise. Will look tomorrow to see if no one else has answered.
    – user30471
    Commented Apr 18, 2018 at 15:45
  • @Andrew good point, the reason is I am trying to make the parameter files as user-friendly as possible for someone else to add or modify without getting into the guts of a complicated main file which generates a mail-merge tikz-graphic. I looked into pgfkeys (thanks!) from this post and unfortunately my basic issue persists. When I put the contents of the \newcommand definition inside an inputted file, parameters such as #1 aren't recognized. But I am hoping someone here knows the right syntax, viz. your \expandafter comment.
    – demodave
    Commented Apr 18, 2018 at 16:15

1 Answer 1

1

It works with the following code in setspecs-command.tex, although I don't fully understand what you're trying to accomplish.

You need to add \usepackage{catchfile} to the document preamble.

\newcommand{\setspecs}[1]{%
  \begingroup
  \CatchFileDef\temp{#1}{}%
  % double the #'s
  \toks0=\expandafter{\temp}%
  % define and evaluate
  \edef\x{\endgroup\def\noexpand\temp####1{\the\toks0}}\x\temp{#1}%
}

You may be interested in a much simpler code:

\documentclass{article}
\usepackage{xparse}
\usepackage{tikz}
\usetikzlibrary{math}

\ExplSyntaxOn
\NewExpandableDocumentCommand{\strequal}{mm}
 {
  \str_if_eq:nnTF { #1 } { #2 } { 0==0~ } { 0==1~ }
 }
\NewDocumentCommand{\setspecs}{m}
 {
  \tl_set_from_file:Nnn \l__demodave_spec_tl {} { #1 }
  \cs_set:NV \__demodave_temp:n \l__demodave_spec_tl
  \__demodave_temp:n { #1 }
 }
\tl_new:N \l__demodave_spec_tl
\cs_generate_variant:Nn \cs_set:Nn { NV }
\ExplSyntaxOff


\begin{document}
First graphic:\\
\setspecs{parameters2}
\begin{tikzpicture}
    \draw (-2,-2) rectangle (2,2);
    \node at (0,0) {\var};
\end{tikzpicture}

\bigskip

Then second graphic:\\
\setspecs{parameters1}
\begin{tikzpicture}
    \draw (-2,-2) rectangle (2,2);
    \node at (0,0) {\var};
\end{tikzpicture}
\end{document}

The contents of parameters1.tex and parameters2.tex are exactly the same.

The idea is exactly the same as before, but the expl3 code is more transparent with respect to “doubling the #’s”.

9
  • would I need to add some packages to the preamble to make this work?
    – demodave
    Commented Apr 18, 2018 at 20:44
  • 1
    @demodave Yes, sorry, I forgot to mention that you need to load catchfile.
    – egreg
    Commented Apr 18, 2018 at 21:05
  • @demodave I added a simpler version based on expl3.
    – egreg
    Commented Apr 18, 2018 at 21:16
  • the expl3 version works perfectly. I'm still having trouble with the first part of your answer and still getting the original error message. I added the two \input{parameters_} instructions in your version of the definition of \setspecs after the line \edef\x{\endgroup\def\noexpand\temp####1{\the\toks0}}\x\temp{#1}%. Was that what you intended?
    – demodave
    Commented Apr 19, 2018 at 9:30
  • 1
    @demodave No; that \input is unnecessary.
    – egreg
    Commented Apr 19, 2018 at 9:31

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .