[Tex/LaTex] \input inside \newcommand and macro parameters

inputmacrosparameterstikz-pgftikzmath

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;
    };
}

Best Answer

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”.

Related Question