此查询与以下内容相关如何将可选参数传递给具有逐字内容的环境?(其解决方案在我的案例中不起作用)并且在 expl3 中模拟 @ifnextchar(这是我正在尝试适应的)。
我已经定义了一个环境(listcontents
),xparse
它使用该参数进行封装\filecontentsdef
(即verbatim
加上\macro
)!O{}
,并且[key = val]
如果总是传递可选参数。
我的想法是能够编写环境而不必使用空的可选参数[]
,这就是我迷失的地方,我已经阅读了文档,\peek_meaning:NF
但我完全不明白它(这\catcodes
让我很困惑)。
如果使用,它可以正常工作:
\begin{listcontents}[]
\begin{listcontents}[key=val]
\begin{listcontents}[
key=val
]
我想按照以下方式进行:
\begin{listcontents}
\begin{listcontents}
[not key = value, only a bracket whit text]
也就是说,如果您[key = val]
在 之后没有找到}
,则插入一个行尾\^^M
和 ,[not key = value, just a square bracket with text]
环境会记录下来。该包xsim
(仅使用 编写expl3
)的工作原理与 类似filecontents
,有一个代码可以解决这个问题,但是,对我来说,适应起来非常复杂。
这是我的示例文件:
\documentclass{article}
\usepackage{fancyvrb,filecontentsdef,xparse}
\pagestyle{empty}
\begin{document}
\makeatletter
\ExplSyntaxOn
\keys_define:nn { listcontents }
{
save-env .tl_set:N = \l_env_save_tl,
save-env .initial:n = content,
show-env .bool_set:N = \l_env_show_tl,
show-env .initial:n = true,
name-tmp .tl_set:N = \l_tmp_name_tl,
name-tmp .initial:n = \jobname.tsc,
}
\NewDocumentEnvironment{ listcontents }{ !O{} }
{
\group_begin:
\IfNoValueF { #1 } { \keys_set:nn { listcontents } { #1 } }
%\peek_meaning_ignore_spaces:NF [ { \char_set_catcode_active:N \^^M \char_set_catcode_end_line:N \^^M \\ }
%\peek_meaning:NF \c_space_tl { \char_set_catcode_active:N \^^M \char_set_catcode_end_line:N \^^M \^^M }
% Acording a doc of v1.4 this its a correct line
\csname filecontentsdef*\endcsname{ \l_tmp_name_tl }{ \l_tmpa_tl }
}
{
\endfilecontentsdef
\group_end:
\group_begin:
\IfNoValueF { #1 } { \keys_set:nn { listcontents } { #1 } }
\IfBooleanT{ \l_env_show_tl } { \filecontentsexec\l_tmpa_tl }
\group_end:
}
\ExplSyntaxOff
\makeatother
\section{[not key = value, just a square bracket with text]}
\begin{listcontents}
[not key = value, just a square bracket with text]
This is correct for key=val, but space between letters in [...] disappeared
% some comented lines
\begin{verbatim*}
\begin{listcontents}
[not key = value, just a square bracket with text]
\end{verbatim*}
and \verb+[not key = value, just a square bracket with text]+ its not save
in \verb+\jobname.tsc+ and \verb+\l_tmpa_tl+.
\end{listcontents}
The \textbf{file generate} is:
\VerbatimInput[frame=single]{\jobname.tsc}
\section{Omit a [optional argument] after begin\{listcontents\} }
\begin{listcontents}
This is what I want to happen when omit []
% some comented lines
\begin{verbatim*}
\begin{listcontents}
This is what I want to happen when omit []
% some comented lines
\end{verbatim*}
if ommit \verb*+[ ]+ the first lines and and space between
letters disappeared, the contents of environments not save
in \verb+\jobname.tsc+ and \verb+\l_tmpa_tl+.
\end{listcontents}
The \textbf{file generate} is:
\VerbatimInput[frame=single]{\jobname.tsc}
\end{document}
输出如下所示:
问候
答案1
您必须延迟搜索可选参数,因为否则后面的结束符\begin{listcontent}
将被标记并转换为空格\filecontentsdef
才能起作用
\documentclass{article}
\usepackage{fancyvrb,filecontentsdef,xparse}
\pagestyle{empty}
\makeatletter
\ExplSyntaxOn
\keys_define:nn { listcontents }
{
save-env .tl_set:N = \l_env_save_tl,
save-env .initial:n = content,
show-env .bool_set:N = \l_env_show_bool,
show-env .initial:n = true,
name-tmp .tl_set:N = \l_tmp_name_tl,
name-tmp .initial:n = \c_sys_jobname_str.tsc,
save-macro .bool_set:N = \l_save_macro_bool,
save-macro .initial:n = true,
}
\NewDocumentEnvironment{ listcontents }{}
{
\char_set_catcode_active:N \^^M
\pedro_start_listcontents:w
}
{
\endfilecontentsdef
\group_end:
\IfBooleanT{ \l_env_show_bool } { \filecontentsexec\l_tmpa_tl }
}
\cs_new_protected:Npn \pedro_listcontents_set:w [#1]
{
\keys_set:nn { listcontents } { #1 }
}
\group_begin:
\char_set_catcode_active:N \^^M
\cs_new_protected:Npn \pedro_start_listcontents:w #1 ^^M
{
\tl_if_blank:nF { #1 } { \pedro_listcontents_set:w #1 }
\group_begin:
\use:c { filecontentsdef* } { \l_tmp_name_tl } { \l_tmpa_tl } ^^M
}
\group_end:
\ExplSyntaxOff
\makeatother
\begin{document}
\section{No optional argument}
\begin{listcontents}
[text in brackets]
Some text
% a comment
\begin{verbatim*}
\foo
\end{verbatim*}
Some text
\end{listcontents}
The \textbf{generated file} is:
\VerbatimInput[frame=single]{\jobname.tsc}
\section{Optional argument}
\begin{listcontents}[name-tmp=\jobname-2.tsc]
Some text
% a comment
\begin{verbatim*}
\foo
\end{verbatim*}
Some text
\end{listcontents}
The \textbf{generated file} is:
\VerbatimInput[frame=single]{\jobname-2.tsc}
\end{document}