收集环境内容并存储以供日后检索

收集环境内容并存储以供日后检索

我想存储环境的内容并将它们添加到宏或命令中,以便轻松检索它们,但我不想使用 collect 包。还有其他选择吗?

\documentclass{article}
\usepackage{environ}
\usepackage{blindtext}



\NewEnviron{env}{
\global\let\content\BODY
%i want to add content to running list and later get whole contents
}

\begin{document}
  \begin{env}
 text text text\\
 \end{env}

\blindtext


\begin{env}
  moretext moretext more text\\
\end{env}

\end{document}

答案1

您可以按“名称”打印已保存的环境,也可以打印全部已保存的环境。

由于使用了,这需要两次运行(当保存的环境发生变化时)\label

更新

由于etex现在不鼓励使用方法,因此这里使用 重新实现expl3

\documentclass{article}
\usepackage{refcount}

\ExplSyntaxOn

\newcounter{savedenv}
\seq_new:N \g_ephraim_savedenv_seq

\NewDocumentEnvironment{savedenv}{ o +b }
 {
  \refstepcounter{savedenv}
  \IfValueT{#1}{\label{savedenv@#1}}
  \seq_gput_right:Nn \g_ephraim_savedenv_seq { #2 }
}{}

\NewDocumentCommand{\printsaved}{m}
 {% #1 is a list of labels
  \clist_map_inline:nn { #1 }
   {
    \seq_item:Nn \g_ephraim_savedenv_seq { \getrefnumber{savedenv@##1} }
    \par
   }
 }
\NewDocumentCommand{\printallsaved}{}
 {
  \seq_use:Nn \g_ephraim_savedenv_seq { \par }
 }


\ExplSyntaxOff

\begin{document}

\begin{savedenv}[a]
Something for a
\end{savedenv}

\begin{savedenv}[b]
Something for b
\end{savedenv}

\begin{savedenv}
Something with no label
\end{savedenv}

\textbf{Let's print them}

This is a: \printsaved{a}

This is b: \printsaved{b}

\textbf{Let's print them in different order}

\printsaved{b,a}

\textbf{Print all of them}

\printallsaved

\end{document}

在此处输入图片描述

原始代码

\documentclass{article}
\usepackage{etex,environ,refcount}

\globtoksblk\savedenvtoks{1000}
\newcounter{savedenvcount}

\NewEnviron{savedenv}[1][]{%
  \refstepcounter{savedenvcount}%
  \if\relax\detokenize{#1}\relax
  \else
    \label{#1}%
  \fi
  \global\toks\numexpr\savedenvtoks+\value{savedenvcount}\relax=\expandafter{\BODY}%
}
\toks\savedenvtoks={??}

\newcommand{\printsaved}[1]{%
  \the\toks\numexpr\savedenvtoks+\getrefnumber{#1}\relax
}

\makeatletter
\newcommand{\printallsaved}{%
  \@tempcnta=\z@
  \loop
    \ifnum\@tempcnta<\value{savedenvcount}
    \advance\@tempcnta\@ne
    \the\toks\numexpr\savedenvtoks+\@tempcnta\relax\par
  \repeat
}
\makeatother

\begin{document}

\begin{savedenv}[a]
Something for a
\end{savedenv}

\begin{savedenv}[b]
Something for b
\end{savedenv}

\begin{savedenv}
Something with no label
\end{savedenv}

\textbf{Let's print them}

This is a: \printsaved{a}

This is b: \printsaved{b}

\textbf{Print all of them}

\printallsaved

\end{document}

您最多可以保存 1000 个环境,但您可以用明显的方式更改该数字。不要尝试将数字设置为超过 30000。

在此处输入图片描述

答案2

我建议使用newenviron 包而不是environ,因为它定义了一个\envnamebody命令。

注意:不要调用你的环境env,因为它会与\envbody始终由 为任何环境定义的隐式命令发生冲突newenviron

更改后,可以使用etoolbox-list 命令\listgadd等,将forlistloop当前内容添加到列表中并稍后进行处理,例如打印它。

你需要一个‘打印’命令,我将其命名为\showlist

内容在环境代码的末尾粘合在一起,中间没有任何空格。

编辑版本——将“任意(?)”文本粘合在一起

\documentclass{article}
\usepackage{tcolorbox}
\usepackage{newenviron}
\usepackage{blindtext}
\usepackage{etoolbox}

\def\mylist{}%
\listadd{\mylist}{}% Initialize list

\newrobustcmd{\myexpandingcommand}[1]{%
\listgadd{\mylist}{#1}%
}%

\newenviron{content}{%
}{%
\noindent\textbf{\LARGE \textcolor{blue}{Environment content}}  % Remove later on!

\noindent\envbody%
\expandafter\myexpandingcommand\expandafter{\envbody}%
\endgraf\bigskip\bigskip% Can be removed
}%




% Macro showing the current list element%
\newrobustcmd{\showlist}[1]{%
#1%
}%

\begin{document}

\begin{content}  % Store some content%
\blindtext%
\end{content}

\noindent\textbf{\LARGE \textcolor{green}{Text content outside of environment}}  % Can be removed, just for diagnosis/test

\noindent\blindtext
\endgraf\bigskip

\begin{content}

\textbf{\textcolor{red}{Even more text and now even some math: \huge \(\displaystyle\int\limits^{b}_{a} f(x) dx\)}}%

\end{content}


\begin{center}
\begin{tcolorbox}[width=0.8\textwidth,title={Now the combined content of the list}]
\forlistloop{\showlist}{\mylist}%
\end{tcolorbox}%
\end{center}

\end{document}

在此处输入图片描述

答案3

我把这个答案留在这里,因为它们对创建这个scontents包很有启发。有了这个包,你很容易就能做你想做的事。所有内容都存储在内存中,包括逐字内容。如果你愿意,你也可以使用键将内容保存在外部文件中write-env=file.tex。我总是倾向于将内容存储在内存中:)

\documentclass{article}
\usepackage{scontents}
\pagestyle{empty}
\begin{document}
\begin{scontents}[store-env=main]
Something for main A.
\end{scontents}

\begin{scontents}[store-env=main]
Something for \verb|main B|.
\end{scontents}

\begin{scontents}[store-env=other]
Something for \verb|other|.
\end{scontents}

\textbf{Let's print them}

This is first stored in main: \getstored[1]{main}\par
This is second stored in main: \getstored[2]{main}\par
This is stored in other: \getstored[1]{other}

\textbf{Print all of stored in main}\par
\foreachsc[sep={\\[10pt]}]{main}
\end{document}

问候语

答案4

这个答案涉及收集和存储环境的内容逐字。(一些优点包括在检索时使用等于 catcode 的 catcode 执行内容,这可以使用例如来完成\scantokens),否则您可能希望将选定的内容传递给 Python 或类似的东西)

其他选择:


方法 标签 空间 新队 最后换行符 信件 其他的
+vxparse 中的参数类型(*) 不起作用(链接包含解决方法的补丁) 空间猫代码 \ExplSyntax- Off: 字符 13 猫其他,\ExplSyntax- On:第一个字符与\endlinechar(固有的 TeX 限制,无法修复)相同,其余同上 用户指定 其他猫 其他猫
\collectverb\Collectverb(*) \ExplSyntax- On:忽略;\ExplSyntax- Off:行首:删除,否则:用空格分隔符 catcode 活跃空间 \ExplSyntax- On:活动空间,\ExplSyntax- Off:活动字符 13 用户指定 信猫 其他猫
\collectverb*\Collectverb*(*) \ExplSyntax- On:忽略;\ExplSyntax- Off:行首:删除,否则:与空格 → 相同 与其他猫有空间 \ExplSyntax- On:空格,\ExplSyntax- Off:活动字符 13 用户指定 信猫 其他猫
\collect-verbenv\Collect- verbenv\ExplSyntaxOn删除环境中的第一行 活动标签(字符 9) 活跃空间 活动换行符(字符 13) 用户指定 信猫 其他猫
file- contents-defmacro环境 \FCDtab由-控制tomacro,默认:与空格相同 主动,默认展开到太空(太空猫) 活动,字符 13,默认扩展为\par 始终存在 信猫 其他猫
scontents内部宏 其他猫 其他猫 字符10猫其他 剥离 信猫 其他猫

(*): 不是一个真正的环境

评论:

  1. 对于以{}:分隔的,{}可以使用它作为分隔符,只要内部{}是平衡的。
  2. 该线\begin{...}通常\end{...}必须在单独的线上。
  3. 大多数情况下,如果作者没有对制表符/换行符进行任何特殊处理,则其行为是“实现定义的默认行为”。 (可以通过重新定义\endlinechar或手动设置其 catcode 等来更改)
  4. 通过重新定义活动角色的含义,可以改变其扩展内容。
  5. scontents宏是内部方法,随时都有可能断裂。
  6. 正如文档中提到的,大多数情况下它可以嵌套。
  7. \getstored不可扩展。
  8. 但是有一个内部方法(见下面的示例代码)
\begin{scontents}[store-env=test]
\a test & test %comment

second line
third line
\end{scontents}

\ExplSyntaxOn

\tl_new:N \my__a
are stored as characters. 
\tl_set:Nx \my__a { \__scontents_getfrom_seq:nn {1} {test} }

\tl_remove_once:NV \my__a \c__scontents_hidden_space_str
\tl_analysis_show:N \my__a

\ExplSyntaxOff

  1. 包定义的环境environ不会逐字存储内容。
  2. 包定义的环境newenviron不会逐字存储内容。(加上我在评论中提到的另一个问题)收集环境内容并存储以供日后检索

相关内容