# Evaluating a raw expression before passing to a function

This question comes from combination of two previous questions A and B which worked properly without any problem. But it fails when I combine them.

I have a result file

results/measurements.txt

length1=0.111111111
length2=0.123456789
length3=0.333333333


And I would like to call it in my code as

\paraminput[length2]{results.txt}


It reads the file and extract the result. It works fine except for 0.123456789 is too long and I do not like to touch the result file because it should be updated everytime and I cannot always keep editing it.

So I need another command to perform rounding. So the defined command \round[2]{0.123456789} also works fine. It prints what it should.

The problem is with when I combine them as

 \round[2]{\paraminput[length2]{results.txt}}


It does not work and it give an error:

Missing \endcsname inserted. ...2]{\paraminput[length2]{measurements.txt}}

...

LaTeX error: "kernel/file-not-found" File '"results/\endcsname "' not found. For immediate help type H . ...2]{\paraminput[length2]{measurements.txt}}

,

Undefined control sequence. ...2]{\paraminput[length2]{measurements.txt}}

How should I fix this problem?

source.tex

\documentclass{article}
\usepackage{tikz}
\usepackage{xparse} % for paraminput

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcommand{\round}[2][2]{
\pgfkeys{/pgf/number format/.cd,std,precision=#1}
\pgfmathprintnumber{#2}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\ExplSyntaxOn

\ior_new:N \ar_param_file

\seq_new:N \g_ar_param_seq

\seq_gput_right:Nn \g_ar_param_seq {#1}
}

\tl_new:N \g_paramfile_path_tl

\NewDocumentCommand{\parampath}{m}{%
\tl_gset:Nn \g_paramfile_path_tl {#1}
}

\NewDocumentCommand{\paraminput}{O{default1}  m}{%
\seq_gclear:N \g_ar_param_seq
\ior_open:Nn \ar_param_file {\g_paramfile_path_tl #2}
\ior_close:N \ar_param_file
\seq_map_inline:Nn \g_ar_param_seq {%
\seq_set_split:Nnn \l_tmpa_seq {=} {##1}
\seq_if_in:NxT \l_tmpa_seq {#1} {\seq_item:Nn \l_tmpa_seq {2}\seq_map_break:}
}
}

\ExplSyntaxOff
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\parampath{results/}

\begin{document}
It shows fine: $\paraminput[length2]{measurements.txt}$.

It shows fine: $\round[2]{0.123456789}$.

But this one shows error: $\round[2]{\paraminput[length2]{measurements.txt}}$.
\end{document}


The operation \paraminput is not expandable, so you cannot pass it to \round.

I suggest to split the operation into first loading the values from the file and then using \getparam for retrieving a value.

\begin{filecontents*}{\jobname.txt}
length1=0.111111111
length2=0.123456789
length3=0.333333333
\end{filecontents*}

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\ior_new:N \ar_param_stream
\clist_new:N \l_ar_param_clist
\tl_new:N \l_ar_param_path_tl
\prop_new:N \l_ar_param_prop

\cs_generate_variant:Nn \prop_set_from_keyval:Nn { NV }

\NewDocumentCommand{\parampath}{m}
{
\tl_set:Nn \l_ar_param_path_tl {#1}
}

\NewDocumentCommand{\paraminput}{O{default}m}
{
\clist_clear:N \l_ar_param_seq
\ior_open:Nn \ar_param_stream {\l_ar_param_path_tl #2}
\ior_map_inline:Nn \ar_param_stream { \clist_put_right:Nn \l_ar_param_clist { ##1 } }
\ior_close:N \ar_param_stream
\prop_set_from_keyval:NV \l_ar_param_prop \l_ar_param_clist
\prop_clear_new:c { l_ar_param_#1_prop }
\prop_set_eq:cN  { l_ar_param_#1_prop } \l_ar_param_prop
}

\NewExpandableDocumentCommand{\getparam}{O{default}m}
{
\prop_item:cn { l_ar_param_#1_prop } { #2 }
}
\NewExpandableDocumentCommand{\round}{O{5}m}
{
\fp_eval:n { round(#2,#1) }
}

\ExplSyntaxOff
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%\parampath{results/} % non subdirectory for me

\begin{document}

% read a file and store the values
\paraminput{\jobname.txt}

It shows fine: $\getparam{length2}$.

It shows fine: $\round[2]{0.123456789}$.

It shows fine: $\round[2]{\getparam{length2}}$

\end{document}


You can have as many parameter files as you want, just load them with

\paraminput[<symbolic name>]{<filename>}


and retrieve a value with

\getparam[<symbolic name>]{<parameter name>}


• Why did you choose \prop_set_from_keyval:NV and then \prop_set_eq:cN rather than just having :cV in the first command? – Manuel May 24 '18 at 9:51
• @Manuel No precise reason. I felt it's cleaner this way. – egreg May 24 '18 at 9:57
• How to get around this error? LaTeX error: "kernel/command-not-defined" ! ! Control sequence \prop_set_from_keyval:Nn undefined. – ar2015 May 24 '18 at 12:43
• @ar2015 Update your TeX distribution. – egreg May 24 '18 at 12:44
• Using \DeclareExpandableDocumentCommand instead of \NewExpandableDocumentCommand fixes some of the errors but not all. Upgrading will be a trouble and the target journal will face with an error. I cannot ask them to update their latex version. Are these features replaceable with the older versions? – ar2015 May 24 '18 at 13:00