感谢提问和回答的人这个问题如何将文件的一部分导入到 Latex。我想进一步扩展这个问题。
如果你有这样一个由 C++ 模拟产生的文件,结果会怎样?
参数.tex
time=5 sec
max_velocity=3 m/s
tolerance=$10^{-6}$
start_time=349872034 sec
stop_time=349872039 sec
distance=11 m
在我的乳胶中,我想输入
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}. ...
结果
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. ...
所以我不需要每次运行模拟时更改报告。
在 Latex 中如何实现这一点?
答案1
一个expl3
基于的解决方案,读取文件,存储内容并匹配第一个[#1]
参数。
最好只读取一次文件,而不是一直打开和关闭它(我稍后会提供另一种解决方案)
\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}
更新
\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}
答案2
使用 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}
答案3
只要你parameters.tex
看起来像这样(带有“”)
time="5 sec"
max_velocity="3 m/s"
tolerance="$10^{-6}$"
start_time="349872034 sec"
stop_time="349872039 sec"
distance="11 m"
你可以创建一个 noweb 文件(so.Rnw
)像这样
\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}
并使用
R CMD Sweave so.Rnw && pdflatex so.tex
这给你
这可能看起来更复杂,但它可以让您轻松访问真实变量,并且实际上设置起来相当容易。