20 如何在coffin里实现\obeyspaces 和\obeylines 命令所指定的效果?

发布于 2023-07-25 22:14:36

想要在coffin(后续要用此coffin与其它coffin组合)中构建一个能够保留空格将每一行都作为一个段落的环境(用命令实现l3doc文档中syntax环境的操作),代码大致如下:

\ExplSyntaxOn
\NewDocumentCommand{\test}{ O{\linewidth} +m }
  {
    \coffin_clear:N \l_tmpa_coffin
    \vcoffin_set:Nnn \l_tmpa_coffin {#1} 
      {
        \small \ttfamily
        \obeyspaces
        \obeylines 
        #2
        \ignorespacesafterend
      }
    \coffin_typeset:Nnnnn \l_tmpa_coffin {H}{l}{0pt}{0pt}
  }
\ExplSyntaxOff

其中

  1. \obeyspaces表示:保留其后文本中的空格(其定义为:\def\obeyspaces{\catcode'\ \active});
  2. \obeylines表示将其后每一行都作为一个段落(其定义为:\gdef\obeylines{\catcode'\^^M\active \let^^M\par})。

想要实现的效果为:

\test{ha   ha
hahahha
}
ha   ha
hahahha    

但实际输出却是:

ha ha hahahha  

\obeyspaces\obeylines命令似乎并没生效。

请问大佬,我需要怎样改进代码才能完成想要实现的效果?

查看更多

关注者
0
被浏览
734
雾月
雾月 2023-07-26
这家伙很懒,什么也没写!

TeX 在获取命令的参数时,参数的 catcode 已经固定了,多个空格合并为一个,行结束符(一般是换行符)转为空格。所以再使用修改 catcode 的命令(比如 \obeyspaces)已经无效了。

要么用环境,且不能用 b 参数,要么原样获取参数,然后重新扫描(使用 \scantokens\tl_rescan:nn 及类似命令)。

\documentclass{article}
\begin{document}

\ExplSyntaxOn
\NewDocumentCommand{\test}{ O{\linewidth} +v }
  {
    \coffin_clear:N \l_tmpa_coffin
    \vcoffin_set:Nnn \l_tmpa_coffin {#1} 
      { % 注意如果 \parindent>0pt 这里会有缩进
        \small \ttfamily
        \obeyspaces
        \obeylines 
        \scantokens{#2}
        \ignorespacesafterend
      }
    \coffin_typeset:Nnnnn \l_tmpa_coffin {H}{l}{0pt}{0pt}
  }
\ExplSyntaxOff

\noindent % 移除段首缩进
\test{ha   ha
hahahha
}

\end{document}

当然也还有其它办法,不过比这个略微复杂。

PS:使用 varwidth 还能有不一样的效果:

\documentclass{article}
\usepackage{varwidth}
\begin{document}

\ExplSyntaxOn
\NewDocumentCommand{\testa}{ O{\linewidth} +v }
  {
    \coffin_clear:N \l_tmpa_coffin
    \hcoffin_set:Nn \l_tmpa_coffin 
      { 
        \varwidth [b] { \dim_eval:n {#1} } 
        \dim_set:Nn \parindent { \c_zero_dim }
        \small \ttfamily
        \obeyspaces
        \obeylines 
        \scantokens{#2}
        \endvarwidth 
      }
%    \coffin_typeset:Nnnnn \l_tmpa_coffin {H}{l}{0pt}{0pt}
    \coffin_display_handles:Nn \l_tmpa_coffin { blue }
  }
\NewDocumentCommand{\testb}{ O{\linewidth} +v }
  {
    \coffin_clear:N \l_tmpa_coffin
    \vcoffin_set:Nnn \l_tmpa_coffin {#1} 
      {
        \dim_set:Nn \parindent { \c_zero_dim }
        \small \ttfamily
        \obeyspaces
        \obeylines 
        \scantokens{#2}
        \ignorespacesafterend
      }
%    \coffin_typeset:Nnnnn \l_tmpa_coffin {H}{l}{0pt}{0pt}
    \coffin_display_handles:Nn \l_tmpa_coffin { red }
  }
\ExplSyntaxOff

\noindent
\testa{ha   ha
hahahha
}

\vspace{1cm}

\noindent
\testb{ha   ha
hahahha
}

\end{document}

image.png

2 个回答
⁡⁢  待定
⁡⁢  待定 2023-07-26
这家伙很懒,什么也没写!

~

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友

手机
浏览

扫码手机浏览