下列的这个帖子,我试图将其用作soul
hack-y 标记器,但在某些字符串上遇到了意外行为。我将问题简化为以下 MWE,但未能取得进一步进展:
\documentclass{article}
\usepackage{soul}
% Initially empty, then should be nonempty afterward
\newcommand*{\state}{}
\makeatletter
\def\SOUL@soeverytoken{%
\ifx\state\empty% Should only happen once...
\renewcommand*{\state}{Nonempty}%
(\the\SOUL@token)%
\else%
[\the\SOUL@token]%
\fi%
}
\makeatother
\begin{document}
% For some reason, the string "unrnn" gives an unexpected result.
\so{nnrnn} \par % (n)[n][r][n][n]
\so{unrnn} \par % (u)[n](r)[n][n]
\so{unnnn} \par % (u)[n][n][n][n]
\so{unrn} \par % (u)[n][r][n]
\end{document}
在字符串上unrnn
,它打印出来与我预期的(r)
不一样。从打印出来来看,似乎在读取后它变得非空,但我不确定为什么在其他示例中没有发生这种情况。[r]
\state
r
答案1
我不知道为什么,但是当检查字符串时unrnn
,TeX 处于分组级别 3;然而,在r
处理时,分组级别降低到 2。
\documentclass{article}
\usepackage{soul}
% Initially empty, then should be nonempty afterward
\newcommand*{\state}{}
\makeatletter
\def\SOUL@soeverytoken{%
\showthe\currentgrouplevel
\show\state
\showthe\SOUL@token
\ifx\state\empty% Should only happen once...
\renewcommand*{\state}{Nonempty}%
(\the\SOUL@token)%
\else
[\the\SOUL@token]%
\fi
}
\makeatother
\begin{document}
% For some reason, the string "unrnn" gives an unexpected result.
% \so{nnrnn} \par % (n)[n][r][n][n]
\so{unrnn} \par % (u)[n](r)[n][n]
% \so{unnnn} \par % (u)[n][n][n][n]
% \so{unrn} \par % (u)[n][r][n]
\end{document}
我添加了一些诊断命令来查看发生了什么。
> 3.
\SOUL@everytoken ->\showthe \currentgrouplevel
\show \state \showthe \SOUL@t...
l.24 \so{unrnn}
\par % (u)[n](r)[n][n]
?
> \state=macro:
->.
\SOUL@everytoken ...urrentgrouplevel \show \state
\showthe \SOUL@token \ifx ...
l.24 \so{unrnn}
\par % (u)[n](r)[n][n]
?
> u.
\SOUL@everytoken ...w \state \showthe \SOUL@token
\ifx \state \empty \renewc...
l.24 \so{unrnn}
\par % (u)[n](r)[n][n]
?
> 3.
\SOUL@everytoken ->\showthe \currentgrouplevel
\show \state \showthe \SOUL@t...
l.24 \so{unrnn}
\par % (u)[n](r)[n][n]
?
> \state=macro:
->Nonempty.
\SOUL@everytoken ...urrentgrouplevel \show \state
\showthe \SOUL@token \ifx ...
l.24 \so{unrnn}
\par % (u)[n](r)[n][n]
?
> n.
\SOUL@everytoken ...w \state \showthe \SOUL@token
\ifx \state \empty \renewc...
l.24 \so{unrnn}
\par % (u)[n](r)[n][n]
?
> 2.
\SOUL@everytoken ->\showthe \currentgrouplevel
\show \state \showthe \SOUL@t...
l.24 \so{unrnn}
\par % (u)[n](r)[n][n]
?
> \state=macro:
->.
\SOUL@everytoken ...urrentgrouplevel \show \state
\showthe \SOUL@token \ifx ...
l.24 \so{unrnn}
\par % (u)[n](r)[n][n]
?
> r.
\SOUL@everytoken ...w \state \showthe \SOUL@token
\ifx \state \empty \renewc...
l.24 \so{unrnn}
\par % (u)[n](r)[n][n]
?
> 2.
\SOUL@everytoken ->\showthe \currentgrouplevel
\show \state \showthe \SOUL@t...
l.24 \so{unrnn}
\par % (u)[n](r)[n][n]
?
如果我尝试\so{nnrnn}
分组级别从 2 开始。
我会避免超负荷\so
。
\documentclass{article}
\usepackage{soul}
\makeatletter
\newcommand{\myso}[1]{%
\begingroup
\gdef\my@state{}%
\def\SOUL@soeverytoken{%
\ifx\my@state\empty% Should only happen once...
\gdef\my@state{x}%
(\the\SOUL@token)%
\else
[\the\SOUL@token]%
\fi
}%
\so{#1}
\endgroup
}
\makeatother
\begin{document}
\myso{nnrnn} \par % (n)[n][r][n][n]
\myso{unrnn} \par % (u)[n](r)[n][n]
\myso{unnnn} \par % (u)[n][n][n][n]
\myso{unrn} \par % (u)[n][r][n]
\end{document}
expl3
使用和 的不同实现\text_map_inline:nn
。
\documentclass{article}
\ExplSyntaxOn
\NewDocumentCommand{\myso}{m}
{
\airwreck_process:n { #1 }
}
\bool_new:N \l_airwreck_first_bool
\cs_new_protected:Nn \airwreck_process:n
{
\bool_set_true:N \l_airwreck_first_bool
\text_map_inline:nn { #1 }
{
\bool_if:NTF \l_airwreck_first_bool
{% first item
(##1)
\bool_set_false:N \l_airwreck_first_bool
}
{% other items
[##1]
}
}
}
\ExplSyntaxOff
\begin{document}
\myso{nnrnn} \par % (n)[n][r][n][n]
\myso{unrnn} \par % (u)[n](r)[n][n]
\myso{unnnn} \par % (u)[n][n][n][n]
\myso{unrn} \par % (u)[n][r][n]
\end{document}
答案2
作为背景:soul 分析音节,以便进行连字符连接。因此,解析结果可能取决于语言:在德语中unt
是一个音节,因此解析器重新启动:
\documentclass{article}
\usepackage[ngerman,english]{babel}
\usepackage{soul}
% Initially empty, then should be nonempty afterward
\newcommand*{\state}{}
\makeatletter
\def\SOUL@soeverytoken{%
\ifx\state\empty% Should only happen once...
\renewcommand*{\state}{Nonempty}%
(\the\SOUL@token)%
\else%
[\the\SOUL@token]%
\fi%
}
\makeatother
\begin{document}
\so{untnn} \par %
\selectlanguage{ngerman}
\so{untnn}
\end{document}