4

Thank to the people asking and answering this question for how to import a part of a file into Latex. I want to extend this question a bit more.

What if you have such a file resulted from a C++ simulation:

parmeters.tex

time=5 sec
max_velocity=3 m/s
tolerance=$10^{-6}$
start_time=349872034 sec
stop_time=349872039 sec
distance=11 m

In my latex, I would like to type

The trajectory travels the distance of \paraminput[distance]{parameters.tex} in 
\paraminput[time]{parameters.tex}. The simulation stops when the relative error is
less than \paraminput[tolerance]{parameters.tex}. The maximum observed velocity 
is \paraminput[max_velocity]{parameters.tex}. ...

And the result

The trajectory travels the distance of 11 m in 
5 sec. The simulation stops when the relative error is
less than $10^{-6}$. The maximum observed velocity 
is 3 m/s. ...

So I do not need to change the report everytime I run the simulation.

How is it possible in Latex?

  • 1
    Is the order of the parameters in the output always the same? – user31729 May 23 '16 at 5:02
  • @ChristianHupfer, the program gives the parameters always in the same order but I dont want to account on it. I want it finds the value from the name not the line as it is error prone. – ar2015 May 23 '16 at 5:06
  • Did you consider using R and Sweave? And: Would it be possible to get the C++ program output with quotation marks, i.e. time="5 sec"? – vaettchen May 23 '16 at 5:37
  • 1
    vaettchen, it is possible to save with quotes. there is not limitation about that. How does it help? – ar2015 May 23 '16 at 6:22
  • 1
    I suggest to provide usage of \SI{...} with siunitx package generated by the C++ code to get better display of numbers and units in the .pdf output – user31729 May 23 '16 at 6:55
4

An expl3 based solution, reading the file, storing the contents and matching the first [#1] parameter.

It would be better to read the file once instead of opening and closing it all the time (I will provide another solution later on)

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn

\ior_new:N \ar_param_file

\seq_new:N \g_ar_param_seq


\cs_new:Nn \ar_read_by_line:n {%
  \seq_gput_right:Nn \g_ar_param_seq {#1}% Appending the current line to the global sequence buffer
}




\NewDocumentCommand{\paraminput}{O{}m}{%
  \seq_gclear:N \g_ar_param_seq% Clearing the sequence
  \ior_open:Nn \ar_param_file {#2} % Open the input file
  \ior_map_inline:Nn \ar_param_file {\ar_read_by_line:n{##1}}% Reading line by line
  \ior_close:N \ar_param_file% Closing the line
  \seq_map_inline:Nn \g_ar_param_seq {% Traversing through the line
    \seq_set_split:Nnn \l_tmpa_seq {=} {##1} % Splitting each line into 'key=value' pairs
    \seq_if_in:NxT \l_tmpa_seq {#1} {\seq_item:Nn \l_tmpa_seq {2}\seq_map_break:}% Checking if `#1` is in the sequence and display it with \seq_item:Nn..., then break the mapping loop.
  }
}

\ExplSyntaxOff

\begin{document}
The trajectory travels the distance of \paraminput[distance]{parameters.tex} in 
\paraminput[time]{parameters.tex}. The simulation stops when the relative error is
less than \paraminput[tolerance]{parameters.tex}. The maximum observed velocity 
is \paraminput[max_velocity]{parameters.tex}. ...
\end{document}

enter image description here

Update

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn

\ior_new:N \ar_param_file

\seq_new:N \g_ar_param_seq


\cs_new:Nn \ar_read_by_line:n {%
  \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{}m}{%
  \seq_gclear:N \g_ar_param_seq
  \ior_open:Nn \ar_param_file {\g_paramfile_path_tl #2}
  \ior_map_inline:Nn \ar_param_file {\ar_read_by_line:n{##1}}
  \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

\begin{document}

The trajectory travels the distance of \paraminput[distance]{parameters.tex} in 
\paraminput[time]{parameters.tex}. The simulation stops when the relative error is
less than \paraminput[tolerance]{parameters.tex}. The maximum observed velocity 
is \paraminput[max_velocity]{parameters.tex}. ...


\parampath{/tmp/output_from_simulation/}
The trajectory travels the distance of \paraminput[distance]{parameters.tex} in 
\paraminput[time]{parameters.tex}. The simulation stops when the relative error is
less than \paraminput[tolerance]{parameters.tex}. The maximum observed velocity 
is \paraminput[max_velocity]{parameters.tex}. ...
\end{document}
  • Thanks a lot. may I please ask you if it is possible to add another command to set a prefix path for it such as \parampath{/path/to/folder}. so \paraminput[distance]{parameters.tex} will be interpreted into \paraminput[distance]{/path/to/folder/parameters.tex}? – ar2015 May 23 '16 at 6:32
  • @ar2015: See the update please -- it's possible. Initially, the content of the \l_paramfile_path_tl variable is empty, i.e. the local directory is searched – user31729 May 23 '16 at 6:45
  • Thanks. That works perfect. The author of the latex file just have to be careful of putting a / at the end of path. – ar2015 May 23 '16 at 6:51
  • @ar2015: Well, a test if the file exists at all could be done, of course – user31729 May 23 '16 at 6:53
  • +1 it is the portable solution texlive-latex-extra is enough for that. – ar2015 May 23 '16 at 7:05
2

Quite simple with LuaLaTeX:

\documentclass{article}

\usepackage{luacode}

\begin{document}

\begin{luacode*}
function read_param(filename,paramname)
    for line in io.lines(filename) do
        param,value=string.match(line,"(.*)=(.*)")
        if param==paramname then 
            tex.print(value)
        end
    end
end
\end{luacode*}

\newcommand{\paraminput}[2][]{\directlua{read_param("#2","#1")}}

The trajectory travels the distance of \paraminput[distance]{parmeters.tex} in 
\paraminput[time]{parmeters.tex}. The simulation stops when the relative error is
less than \paraminput[tolerance]{parmeters.tex}. The maximum observed velocity 
is \paraminput[max_velocity]{parmeters.tex}.

\end{document}
1

Provided your parameters.tex looks like this (with "")

time="5 sec"
max_velocity="3 m/s"
tolerance="$10^{-6}$"
start_time="349872034 sec"
stop_time="349872039 sec"
distance="11 m"

you could create a noweb file (so.Rnw) like

\documentclass[a4paper,12pt]{article}
\usepackage{Sweave}

\begin{document}

<<echo=FALSE>>=
source( "parameters.tex" )
@

This is an easy - can be done in \Sexpr{time} or less.\\
There is a tolerance of \Sexpr{tolerance} over a distance of \Sexpr{distance}. 

\end{document}

and compile it with

R CMD Sweave so.Rnw && pdflatex so.tex

which gives you

enter image description here

This may look more complicated but it gives you easy access to real variables and actually is set up rather easily.

  • I took it for granted that you are using R - should have mentioned that... – vaettchen May 23 '16 at 7:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.