避免使用 xparser 传递空的 [可选参数] 环境(带有逐字内容)?

避免使用 xparser 传递空的 [可选参数] 环境(带有逐字内容)?

此查询与以下内容相关如何将可选参数传递给具有逐字内容的环境?(其解决方案在我的案例中不起作用)并且在 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}

输出如下所示:

输出外观 可以使用吗xparse/expl3

问候

答案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}

在此处输入图片描述

相关内容