活动字符之间的每个标记都固定为水平盒子

活动字符之间的每个标记都固定为水平盒子

我想输入这样的内容:

|--1-23-|--4-5---|

并获得这样的输出:每个|都是一条垂直线,每个-看起来像\rule[.8ex]{1em}{.5pt},并且所有其他(非活动)字符都位于相同宽度的水平盒子中(例如\hbox to 1em{\hss\the\token\hss)。

我可以制作宏\fw,使其参数对那些固定宽度的水平盒子起作用(如此处的注释所示:我可以将可变宽度字体转换为固定宽度字体吗?)。然而,我不知道如何在不使用括号写参数的情况下调用它。

我创建了-活动字符并尝试检查下一个字符是否也是-。如果是,我只需打印规则,如果不是,我想\fw用下一个分隔的参数调用-。但是,这不起作用,因为 1) 它将also\fi末尾的if作为参数的一部分,这会破坏事情(至少这是我从日志中理解到的),2) 它消耗了最后一个-,我可能想再次使用它作为固定宽度文本的开头,3) 我对正确开始和结束组的位置感到困惑。

另一种选择是以某种方式在整行/段落上使用固定宽度,但这也会影响那些|,而且我也没有找到如何在这里处理活动字符。

我也在考虑先使用令牌寄存器读取令牌,然后决定做什么,但我不知道如何使用它们,以及如何决定用哪个令牌做什么。

|编辑:我忘了提及这个词里面可能还有更多实例。

答案1

这使用了一个 tokencycle,并假设 OP 想要按字面意思输入|--1-23---4-5---|并获得所需的输出。当然,这是通过|激活来实现的,这限制了它在其他方面的使用。

在这个版本中,输入中的组和控制序列被忽略。

\documentclass{article}
\usepackage{tokcycle,amsmath}
\catcode`\|=\active
\def|#1|{$\lvert$%
  \tokencycle
  {\ifx-##1\rule[.8ex]{1em}{.5pt}\else\makebox[1em]{##1}\fi}
  {}
  {}
  {\makebox[1em]{##1}}#1\endtokencycle
  $\rvert$}
\begin{document}
This is |--1-23---4-5---| and done.
\end{document}

在此处输入图片描述

为了避免使用活动|标记,可以仅定义\fw采用分隔参数:

\documentclass{article}
\usepackage{tokcycle,amsmath}
\def\fw|#1|{$\lvert$%
  \tokencycle
  {\ifx-##1\rule[.8ex]{1em}{.5pt}\else\makebox[1em]{##1}\fi}
  {}
  {}
  {\makebox[1em]{##1}}#1\endtokencycle
  $\rvert$}
\begin{document}
This is \fw|--1-23---4-5---| and done.
\end{document}

答案2

我并不建议这样做,但这是可能的。

\documentclass{article}

\ExplSyntaxOn

\cs_new_protected:Nn \zuz_textfw:
 {
  \mode_if_math:TF { \vert } { \__zuz_textfw:w }
 }
\char_set_active_eq:NN | \zuz_textfw:

\AtBeginDocument
 {
  \char_set_catcode_active:N |
 }

\cs_new_protected:Npn \__zuz_textfw:w
 {
  \peek_regex_replace_once:nn { [\- \| [:alnum:]]* } { \c{__zuz_textfw:n}\{|\0\} }
 }

\cs_new_protected:Nn \__zuz_textfw:n
 {
  \tl_map_function:nN { #1 } \__zuz_textfw_char:n
 }

\cs_new_protected:Nn \__zuz_textfw_char:n
 {
  \makebox[1em]
   {
    \str_case:nnF { #1 }
     {
      {|}{\textbar}
      {-}{\rule[0.8ex]{\dim_eval:n { 1em-1pt }}{0.5pt}}
     }
     {#1}
   }
 }


\ExplSyntaxOff

\begin{document}

|--1-23-|--4-5---|

|----------------|

$\sqrt{x^2}=|x|$

\end{document}

的目的\zuz_textfw:是辨别我们是否处于数学模式;在第一种情况下,只需发出\vert,否则\__zuz_textfw:w。此函数查找连字符、竖线或字母数字字符,并将找到的内容替换为

\__zuz_textwf:n { |<what's been found> }

最后一个函数的作用是映射每个字符,并根据它是 还是字母数字字符做出适当的|决定-

该字符|在文档开始时处于活动状态,并被赋予含义\zuz_textfw:

在此处输入图片描述

您可以决定扩充允许的字符列表,只需在搜索正则表达式中添加所需的任何内容:

[\- \| [:alnum:]]*

|意思是“找到所有由、或字母数字字符组成的字符序列-,当找不到更多字符时停止”。

使用如下语法会更加容易和健壮

\textfw{|--1-23-|--4-5---|}

所以你根本就不需要使用主动角色来玩。

\documentclass{article}

\ExplSyntaxOn

\NewDocumentCommand{\textfw}{m}
 {
  \tl_map_function:nN { #1 } \__zuz_textfw_char:n
 }

\cs_new_protected:Nn \__zuz_textfw_char:n
 {
  \makebox[1em]
   {
    \str_case:nnF { #1 }
     {
      {|}{\textbar}
      {-}{\rule[0.8ex]{\dim_eval:n { 1em-1pt }}{0.5pt}}
     }
     {#1}
   }
 }


\ExplSyntaxOff

\begin{document}

\textfw{|--1-23-|--4-5---|}

\textfw{|----------------|}

\end{document}

输出与其他版本相同。

相关内容