我正在尝试封装几个环境,以便使用将它们传递给列表xparse/expl3
。我定义了一个命令和两个环境,但其中一个出现了问题。
我使用环境来保存笔记类型问题/答案将答案存储在列表中以显示在文件末尾或其他位置,问题是有时需要逐字使用。
环境scontent
使用+b
的参数xparse
,并且只能使用Verb[...]{...}
(from fvextra
)(例如,不能使用 verbatim 环境)。
该scontent*
环境基于filecontentsdef
并可verb|...|
在一行或\begin{verbatim}
环境中使用,这会生成一个外部文件,但可以将内容保存在\macro
.
执行时\begin{scontent*}
传递以下内容:
- 保存当前内容
\macro
\macro
复制当前内容\l_my_macro_copy_tl
- 使用以下方式将内容传递
\l_my_macro_copy_tl
到列表中\expanddafter\envtolist\expanddafter{ content save in \l_my_macro_copy_tl}
- 如果这是关键的
[show-env = true]
跑动\usecontent[-1]{\l_scontent_env_save_tl}
问题在于执行
\expanddafter\envtolist\expanddafter{\l_my_macro_copy_tl}
在环境结束时scontent*
,我尝试了以下(丑陋且不正确的)行:
% \begin{scontent*}[...] verbatim env save in \macro
% Copy a current content of \macro in \l_my_macro_copy_tl and pass to list
\tl_new:N \l_my_macro_copy_tl
\NewDocumentEnvironment{scontent*}{ !O{} }
{
\group_begin:
\filecontentsdef{\jobname.tsc}{\macro} % save in \macro
}{
\endfilecontentsdef %
\group_end:
\IfNoValueF {#1} { \keys_set:nn { scontent } {#1} }
\tl_set:Nx \l_my_macro_copy_tl \macro
\exp_after:wN \envtolist \exp_after:wN { \exp_not:N \tex_newlinechar:D = 13 \exp_not:N \scantokens \exp_after:wN { \l_my_macro_copy_tl } }%
\IfBooleanT { \l_scontent_env_show_tl } { \usecontent[-1]{ \l_scontent_env_save_tl} }
}
通过这个,我消除了编译时的错误,但是内容没有保存在列表中......我怎样才能解决这个问题?
我的想法是不要直接占用\showme{...}
,只\usecontent[index]{list name}
在文档中使用。
我知道如果在环境之外执行该命令,它会起作用,但我的想法是在运行时自动执行该\showme{...}
命令。\usecontent[index]{list name}
scontent*
这是我的示例文件(MWE),应该删除注释才能查看发生的错误。
\documentclass{article}
\usepackage{filecontentsdef,etoolbox,xparse,fvextra,xcolor}
\usepackage[margin=0.6in,noheadfoot,papersize={8.5in,13in}]{geometry}
\setlength{\parindent}{0pt}
\pagestyle{empty}
\ExplSyntaxOn
% show content save in \macro
\tl_new:N \l_temp_argument_tl
\NewDocumentCommand\showme{ +m }{%
\tl_set:Nx \l_temp_argument_tl { #1 }
\tex_newlinechar:D = 13
\exp_not:N { \scantokens \exp_after:wN { \l_temp_argument_tl } }
}
% \elementin{listname} and \clearlist{listname}
\cs_new:Npn \elementin #1 { \seq_count:c {l_savecontent_content_#1_seq} }
\cs_new:Npn \clearlist #1 { \seq_clear_new:c {l_savecontent_content_#1_seq} }
% \addcontent{listname}{{#1}} ...need double {{...}}
\NewDocumentCommand{\addcontent}{ m +m } { \savecontent_add_content:nn { #1 } { #2 } }
% \usecontent[index]{listname}
\DeclareExpandableDocumentCommand{\usecontent}{O{1}m} { \savecontent_use_content:nn { #1 } { #2 } }
\cs_new_protected:Npn \savecontent_add_content:nn #1 #2
{
\seq_if_exist:cF { l_savecontent_content_#1_seq }
{ \seq_new:c { l_savecontent_content_#1_seq } }
\__savecontent_add_content:nn { #1 } { #2 }
}
\cs_new_protected:Npn \__savecontent_add_content:nn #1 #2
{
\tl_map_inline:nn { #2 }
{
\seq_gput_right:cn { l_savecontent_content_#1_seq } { ##1 }
}
}
\cs_new:Npn \savecontent_use_content:nn #1 #2 { \seq_item:cn { l_savecontent_content_#2_seq } { #1 } }
\keys_define:nn { scontent }
{
save-cmd .tl_set:N = \l_scontent_cmd_save_tl, save-cmd .initial:n = content,%
save-env .tl_set:N = \l_scontent_env_save_tl, save-env .initial:n = content, %
show-cmd .bool_set:N = \l_scontent_cmd_show_tl, show-cmd .initial:n = false, show-cmd .value_required:n = true,%
show-env .bool_set:N = \l_scontent_env_show_tl, show-env .initial:n = false, show-env .value_required:n = true,%
show-all .meta:n = { show-env = true , show-cmd = true },%
}
\NewDocumentCommand{\Setscontent}{ +m } { \keys_set:nn { scontent } {#1} }
% pass to list
\newrobustcmd{\envtolist}[1]{\addcontent{ \l_scontent_env_save_tl }{{#1}}}
% \Scontent[...]{...} NO verbatim env support, but \Verb[...]{...} yes
\NewDocumentCommand{\Scontent}{ O{} +m }
{
\group_begin:
\IfNoValueF{#1} { \keys_set:nn { scontent } {#1} }
\addcontent{ \l_scontent_cmd_save_tl }{ { #2 } } % pass direct to list
\IfBooleanT{ \l_scontent_cmd_show_tl } { \usecontent[-1]{ \l_scontent_cmd_save_tl} }
\group_end:
}
% \begin{scontent}[...] NO verbatim env suport, but \Verb[...]{...} yes
\NewDocumentEnvironment{scontent}{ !o +b }
{
\group_begin:
\IfNoValueF {#1} { \keys_set:nn { scontent } {#1} }
}{
\expandafter\envtolist\expandafter{#2}
\IfBooleanT { \l_scontent_env_show_tl } { \usecontent[-1]{ \l_scontent_env_save_tl} }
\group_end:
}
% \begin{scontent*}[...] verbatim env save in \macro
\tl_new:N \l_my_macro_copy_tl % \tl_var to copy \macro at definition time
\NewDocumentEnvironment{scontent*}{ !O{} }
{
\group_begin:
\IfNoValueF {#1} { \keys_set:nn { scontent } {#1} }
\filecontentsdef{\jobname.tsc}{\macro}
}{
\endfilecontentsdef %
\group_end:
% Copy \macro every time in \tl_var (at definition time) and pass to list
%\cs_set_eq:NN \l_my_macro_copy_tl \macro
%\expandafter\envtolist\expandafter\showme{\l_my_macro_copy_tl}
%\IfBooleanT { \l_scontent_env_show_tl } { \usecontent[-1]{ \l_scontent_env_save_tl} }
}
\ExplSyntaxOff
% set name of lists
\Setscontent{ save-env=test-env, save-cmd=test-cmd }
\begin{document}
\section{Using \texttt{scontent} environment whit new \texttt{+b} argument from \texttt{xparse}}
\subsection{Whit \texttt{[show-env=false]}}
Text save in \verb|\begin{scontent}[show-env=false]| (hidden)
\begin{scontent}[show-env=false]
Some first text whit verbatim inline saved in \Verb{\usecontent[1]{test-env}} \par
We have coded this in \LaTeX: both $E=mc^2$.
\end{scontent}
OK
\subsection{Whit \texttt{[show-env=true]}}
Text save in \verb|\begin{scontent}[show-env=true]| (Not hidden)
\begin{scontent}[show-env=true]
Some second text whit verbatim inline saved in \Verb{\usecontent[2]{test-env}}...more text \par
We have coded this in \LaTeX: both $E=mc^2$.
\end{scontent}
OK
\subsection{Using \Verb{\usecontent[1]{test-env}}}
Now see saved text in list:\par
\usecontent[2]{test-env}\par
\usecontent[1]{test-env}
\section{Using \Verb*{\Scontent[...]{...}}}
Text save whit \verb|\Scontent{....}| (hidden)\par
\Scontent{
using a \Verb*{\Scontent[...]{...}} \textcolor{red}{whit verbatim} \Verb*{\Verb[...]{...}}\par
(by \Verb*{fvextra}) \textcolor{magenta}{inline}
}\par
And see saved text in list using \verb|\usecontent[1]{test-cmd}| \par
\usecontent[1]{test-cmd}\par
OK
\section{Using \texttt{scontent*} environment wraped \texttt{filecontentsdef} using \texttt{xparse}}
\subsection{Whit \texttt{[show-env=false]}}
Some Text save using \verb|\begin{scontent*}[show-env=false]| save in \verb|\macro| (hidden)
\begin{scontent*}[show-env=false]
Some text in whit verbatim environment ¿saved in list ...\verb+\usecontent[3]{test-env}+?(not get for now).\par
\begin{Verbatim}
This is from the verbatim environment: &%{}_"`´~
xxxxx
\end{Verbatim}
\end{scontent*}\par
OK...it's posible to see \verb|\macro| whit \verb|\showme{\macro}|:\par
\showme{\macro}\par
or pass to list using \verb|\Scontent{\showme{\macro}}| and see in list whit \verb+\usecontent[2]{test-cmd}+:\par
\Scontent{\showme{\macro}}
\usecontent[2]{test-cmd}
\subsection{The idea whit \texttt{[show-env=true]}}
\Setscontent{ save-cmd=test-other }
XXXXXXXXX\par
\begin{scontent*}[show-env=false]
Some text in whit verbatim A
\begin{Verbatim}
verbatim environment A: &%{}_"`´~
\end{Verbatim}
\end{scontent*}
\Scontent[show-cmd=true]{\showme{\macro}}\par
XXXXXXXXX\par
\begin{scontent*}[show-env=false]
Some text in whit verbatim B
\begin{Verbatim}
verbatim environment B: &%{}_"`´~
\end{Verbatim}
\end{scontent*}
\Scontent[show-cmd=true]{\showme{\macro}}
XXXXXXXXX\par
And see in reverse order:\par
\usecontent[2]{test-other}\par
\usecontent[1]{test-other}\par
NOT OK,...
\subsection{The problem whit \texttt{[show-env=true]}}
\begin{scontent*}[show-env=true]
Some text in whit verbatim C
\begin{Verbatim}
verbatim environment C: &%{}_"`´~
\end{Verbatim}
\end{scontent*}
\end{document}
问候
答案1
在仔细查看了文档并阅读了论坛上的大量资料后,我设法自己完成了...
% arara: lualatex
% arara: clean: { extensions: [ aux, log, tsc] }
\documentclass{article}
\usepackage{filecontentsdef,xparse,fvextra,xcolor}
\usepackage[margin=0.6in,noheadfoot,papersize={8.5in,13in}]{geometry}
\setlength{\parindent}{0pt}
\pagestyle{empty}
\makeatletter
\ExplSyntaxOn
% \elementin{listname}
\cs_new:Npn \elementin #1
{
\seq_count:c { l_savecontent_content_#1_seq }
}
% \clearlist{listname}
\cs_new:Npn \clearlist #1
{
\seq_clear_new:c { l_savecontent_content_#1_seq }
}
% \@add@content{listname}{{#1}} ...need double {{...}}
\NewDocumentCommand{\@add@content}{ m +m }
{
\savecontent_add_content:nn { #1 } { #2 }
}
% \usecontent[index]{listname}
\DeclareExpandableDocumentCommand{\usecontent}{ O{1} m }
{
\savecontent_use_content:nn { #1 } { #2 }
}
\cs_new_protected:Npn \savecontent_add_content:nn #1 #2
{
\seq_if_exist:cF { l_savecontent_content_#1_seq }
{ \seq_new:c { l_savecontent_content_#1_seq } }
\__savecontent_add_content:nn { #1 } { #2 }
}
\cs_new_protected:Npn \__savecontent_add_content:nn #1 #2
{
\tl_map_inline:nn { #2 }
{
\seq_gput_right:cn { l_savecontent_content_#1_seq } { ##1 }
}
}
\cs_new:Npn \savecontent_use_content:nn #1 #2
{
\seq_item:cn { l_savecontent_content_#2_seq } { #1 }
}
\keys_define:nn { scontent }
{
save-cmd .tl_set:N = \l_scontent_cmd_save_tl,%
save-cmd .initial:n = content,%
save-env .tl_set:N = \l_scontent_env_save_tl,%
save-env .initial:n = content,%
show-cmd .bool_set:N = \l_scontent_cmd_show_tl,%
show-cmd .initial:n = false,%
show-cmd .value_required:n = true,%
show-env .bool_set:N = \l_scontent_env_show_tl,%
show-env .initial:n = false,%
show-env .value_required:n = true,%
show-all .meta:n = { show-env = true , show-cmd = true },%
}
\NewDocumentCommand{\Setscontent}{ +m }
{
\keys_set:nn { scontent } {#1}
}
% \Scontent[...]{...} NO verbatim env support, but \Verb[...]{...} yes
\NewDocumentCommand{\Scontent}{ O{} +m }
{
\group_begin:
\IfNoValueF{ #1 } { \keys_set:nn { scontent } {#1} }
\@add@content{ \l_scontent_cmd_save_tl }{ { #2 } } % pass direct to list
\IfBooleanT{ \l_scontent_cmd_show_tl } { \usecontent[-1]{ \l_scontent_cmd_save_tl} }
\group_end:
}
% \begin{scontent}[...] NO verbatim env suport, but \Verb[...]{...} yes
\NewDocumentEnvironment{scontent}{ !o +b }
{
\group_begin:
\IfNoValueF{ #1 } { \keys_set:nn { scontent } {#1} }
}{
\@add@content{ \l_scontent_env_save_tl }{ { #2 } } % pass direct to list
\IfBooleanT{ \l_scontent_env_show_tl } { \usecontent[-1]{ \l_scontent_env_save_tl} }
\group_end:
}
% \begin{scontent*}[...] verbatim env suport in \macro
\tl_new:N \l_add_@temp@save@content_tl
\NewDocumentEnvironment{scontent*}{ !O{} }
{
\group_begin:
% save a tmp file.tsc in \@temp@save@content
\filecontentsdef{\jobname.tsc}{\@temp@save@content}
}{
\endfilecontentsdef%
\group_end:
\group_begin:
\IfNoValueF{ #1 } { \keys_set:nn { scontent } {#1} }
% copy \@temp@save@content in \l_tmpa_tl
\tl_set:Nx \l_tmpa_tl \@temp@save@content
% expand \l_tmpa_tl in \l_tmpb_tl
\tl_put_right:Nx \l_tmpb_tl
{
\tex_newlinechar:D = 13 \tex_everyeof:D = {\noexpand}
\exp_not:N \scantokens \exp_after:wN { \l_tmpa_tl }
}
% pass \l_tmpb_tl to list
\tl_put_right:Nx \l_add_@temp@save@content_tl
{
\exp_not:N \@add@content { \exp_not:V \l_scontent_env_save_tl } { {\exp_not:V \l_tmpb_tl } }
}
\l_add_@temp@save@content_tl
\IfBooleanT{ \l_scontent_env_show_tl } { \usecontent[-1]{ \l_scontent_env_save_tl} }
\group_end:
}
\ExplSyntaxOff
\makeatother
% set name of lists
\Setscontent{ save-env=test-env, save-cmd=test-cmd }
\begin{document}
\section{Using \Verb{scontent} environment (\Verb{+b} argument from \Verb{xparse})}
\subsection{Whit \texttt{[show-env=false]}}
Text save in \verb|\begin{scontent}[show-env=false]| (hidden)
\begin{scontent}[show-env=false]
first text whit verbatim inline saved in \Verb{\usecontent[1]{test-env}} \par
We have coded this in \LaTeX: both $E=mc^2$.
\end{scontent}
\subsection{Whit \Verb{[show-env=true]}}
Text save in \verb|\begin{scontent}[show-env=true]| (Not hidden)\par
\begin{scontent}[show-env=true]
second text whit verbatim inline saved in \Verb{\usecontent[2]{test-env}}\par
More code in \LaTeX: both $E=mc^2$.
\end{scontent}
\section{Using \Verb{scontent*} environment (wraped \Verb{filecontentsdef})}
\subsection{Whit \Verb{[show-env=false]}}
Some Text save using \verb|\begin{scontent*}[show-env=false]| save in \verb|\macro| (hidden)
\begin{scontent*}[show-env=false]
Text in whit verbatim environment ... saved in list ...\verb+\usecontent[3]{test-env}+.\par
\begin{Verbatim}
(A) verbatim environment: &%{}_"`´~
\end{Verbatim}
\end{scontent*}
\subsection{Whit \Verb{[show-env=true]}}
Some Text save using \verb|\begin{scontent*}[show-env=true]| save in \verb|\macro| (Not hidden)
\begin{scontent*}[show-env=true]
Text in whit verbatim environment ... saved in list ...\verb+\usecontent[4]{test-env}+.\par
\begin{Verbatim}
(B) verbatim environment: &%{}_"`´~
\end{Verbatim}
\end{scontent*}
\section{Using \Verb{\Scontent[...]{...}}}
\subsection{Whit \texttt{[show-cmd=false]}}
Text save whit \verb|\Scontent[show-cmd=false]{....}| (hidden)\par
\Scontent[show-cmd=false]{
using a \Verb*{\Scontent[show-cmd=false]{...}} \textcolor{red}{whit verbatim} saved in \Verb*{\usecontent[1]{test-cmd}}\par
(by \Verb*{fvextra}) \textcolor{magenta}{inline}
}\par
\subsection{Whit \Verb{[show-cmd=true]}}
Text save whit \verb|\Scontent[show-cmd=true]{....}| (Not hidden)\par
\Scontent[show-cmd=true]{
using a \Verb*{\Scontent[show-cmd=true]{...}} \textcolor{green}{whit verbatim} saved in \Verb*{\usecontent[2]{test-cmd}}\par
(by \Verb*{fvextra}) \textcolor{blue}{inline}
}
\section{Using \Verb{\usecontent[index]{list name}}}
\subsection{\Verb{\usecontent[index]{test-env}}}
Now see the \elementin{test-env} environment saved in list (reverse order):\par
\usecontent[4]{test-env}\par
\usecontent[3]{test-env}\par
\usecontent[2]{test-env}\par
\usecontent[1]{test-env}
\subsection{\Verb{\usecontent[index]{test-cmd}}}
Now see the \elementin{test-cmd} command saved in list (reverse order):\par
\usecontent[2]{test-cmd}\par
\usecontent[1]{test-cmd}\par
\end{document}
现在它按预期工作 我澄清一下,如果没有以下出色的答案,这是不可能的:
非常感谢参与这个社区的所有人……