\NewDocumentEnvironment
这个问题的变体以前也曾被问过,但这些答案在from中使用时似乎不起作用xparse
。例如,参见
将环境主体逐字写入文件
最小目标是将环境主体逐字保存到文件中,并用其他文件替换主体。读取替换文件很容易,但保存主体很难。
\documentclass[10pt]{article}
\ExplSyntaxOn
% I'm using xparse because I'm doing messy things with the arguments. That part works.
\NewDocumentEnvironment{intfig} { > { \SplitArgument { 1 } { , } } m o }
{
\group_begin:
\str_set:Nn \l_intfig_fout_str { test.out }
\str_set:Nn \l_intfig_fin_str { test.in }
% Here, I want to save the body to test.out.
% I tried variations with \VerbatimOut and \endVerbatimOut, along
% with elements of the listings package (\lst@BeginWriteFile).
% Reading in the replacement works.
\file_if_exist:nTF { \l_intfig_fin_str } { \input { \l_intfig_fin_str }}{}
\group_end:
}{
}
\ExplSyntaxOff
\begin{document}
\begin{intfig}{junk,14.4pt}[2cm,rubbish]
Send me to an external file, you !#^%?
Don't mess with anything in here either. I want
every space, semi-colon;;; etc.
\end{intfig}
\end{document}
@Phelype 说目前这样做是不可能的,并链接到一些有关当前状态的信息。
有没有办法将环境中的几行换行,以便将它们作为逐字文本传递到包含环境?像这样
\begin{intfig}{junk,14.4pt}[2cm,rubbish]
\begin{makeintoverbatim}
Send me to an external file, you !#^%?
Don't mess with anything in here either. I want
every space, semi-colon;;; etc.
\end{makeintoverbatim}
\end{intfig}
这个想法是将 中的内容传递makeintoverbatim
给\NewDocumentEnvironment
unmolested。如果这是可能的,那么在定义环境时使用b
(或) 可能会有效。b+
intfig
答案1
该xsimverb
包似乎提供了您想要的东西:
\documentclass[10pt]{article}
\usepackage{xsimverb,listings}
\ExplSyntaxOn
\cs_generate_variant:Nn \file_if_exist:nT {V}
\cs_generate_variant:Nn \file_input:n {V}
\str_new:N \l_intfig_fout_str
\str_new:N \l_intfig_fin_str
\NewDocumentEnvironment{intfig}{ >{ \SplitArgument {1} {,} } m!o }
{
\str_set:Nn \l_intfig_fout_str {test.out}
\str_set:Nn \l_intfig_fin_str {test.in}
\IfValueTF {#2}
{ \xsim_file_write_start:nn { \c_true_bool } }
{ \xsim_file_write_start:nn { \c_false_bool } }
{ \l_intfig_fout_str }
}
{
\xsim_file_write_stop:
\file_if_exist:VT \l_intfig_fin_str { \file_input:V \l_intfig_fin_str }
}
\ExplSyntaxOff
\begin{document}
\begin{intfig}{junk,14.4pt}[2cm,rubbish]
Send me to an external file, you !#^%?
Don't mess with anything in here either. I want
every space, semi-colon;;; etc.
\end{intfig}
\lstset{basicstyle=\ttfamily,showspaces=true}
\lstinputlisting{test.out}
\begin{intfig}{junk,14.4pt}
another test
\end{intfig}
\lstinputlisting{test.out}
\end{document}
一些评论:
第一个参数\xsim_file_write_start:nn
是一个布尔值,表示后面是否有可选参数(只有当可选参数是最后的第一个参数是环境变量,第二个参数是要写入内容的文件名。
还要注意,可选参数应指定为,!o
否则,如果没有指定可选参数,第一行的前导空格将被忽略。请参阅手册中有关可选参数和空格的部分,xparse
并检查如果省略,输出中的区别!
。
命令\xsim_file_write_start:nn
和\xsim_file_write_stop:
可能尚未记录(尚未?),但已公开并可以使用。它们的 2e 对应项\XSIMfilewritestart
和\XSIMfilewritestop
是记录下来。
答案2
根据上面提供的出色信息以及一些额外的研究和调整,这里是一个总结。
一种方法相对简单,使用xparse
:
\NewDocumentCommand{\takeverbatim} { +v }
{
\str_set:Nn \g_intfig_verb_str { #1 }
}
% You can use the above to associate (almost) arbitrary text with a global
% variable.
\takeverbatim {
verbatim text that can include anything you like ($#%^_/)
but NOT a closing brace.
}
这种方法的缺点是,您感兴趣的环境中自然出现的文本必须在该环境之外给出。
另一种方法是使用scontents
:
\begin{scontents}[store-env=testoutput]
\begin{verbatim}
Verbatim text again, but this time a closing brace would be OK.
\end{verbatim}
\end{scontents}
scontents
将逐字文本存储在模块变量中。通过查看源代码scontents
,似乎可以使用以下方法在其他地方访问逐字文本:
\__scontents_getstored_internal:nn { 1 }{ testoutput }
这很好,因为逐字文本可能包含右括号,但它仍然要求您关心的文本与您实际想要定义的环境分开给出。
最好的解决方案(在我看来)xsim
按照@cgnieder 的建议使用