使用 xparse 将环境主体逐字保存到文件中

使用 xparse 将环境主体逐字保存到文件中

\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\NewDocumentEnvironmentunmolested。如果这是可能的,那么在定义环境时使用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 的建议使用

相关内容