我想输入这样的内容:
|--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}
输出与其他版本相同。