循环使用空格的宏参数并构建部分命令

循环使用空格的宏参数并构建部分命令

请考虑以下代码:

\documentclass{article}

\usepackage{ruby}

\newcommand{\strsymbol}{\large\bfseries∗}
\newcommand{\unssymbol}{\large·}
\newcommand{\str}[1]{\textbf{\ruby{#1}{\strsymbol}}{}}
\newcommand{\uns}[1]{\ruby{#1}{\unssymbol}{}}

\begin{document}

\uns{A} \uns{po}\uns{ly}\str{syl}\uns{la}\uns{ble} \uns{should} \uns{be} \str{fun} \uns{to} \uns{de}\str{fine}.

\end{document}

它生成如下输出:

在此处输入图片描述 (好吧,我使用了更好的字体和符号,但你明白我的意思)。

如您所见,该代码非常笨重。理想情况下,我希望某个函数接受如下参数:

\stress{A po-ly*syl*la-ble should be *fun* to de*fine*.}

事实上,上面的工作示例不是手写的;它是我编写的一些丑陋的 Emacs Lisp 代码的输出,用于转换更好的参数格式。它只是循环处理几种不同情况的字符(*、、-Unicode 字母数字和空格/标点符号),跟踪状态以相应地开始和结束 Latex 命令。

我对 Tex 编程完全陌生,想知道是否有可能使用 Latex 解决方案。出于某些原因,我不得不使用 Xetex。我的尝试没有取得很大进展;我无法循环遍历字符串,\@tfor因为它会占用内部空格,即使可以,我也不知道如何编写跨越许多循环交互的零碎命令(例如\ruby{…… })。我看到了关于可扩展的“字符扫描”命令,可保留空格,但我甚至无法弄清楚如何修改示例代码来实现这样的功能。

编写接受这样的参数的 Latex 宏的最佳方法是什么?

答案1

l3regex

\documentclass{article}

\usepackage{ruby}
\usepackage{textcomp}
\usepackage{xparse,l3regex}

\newcommand{\strsymbol}{\large\bfseries\textasteriskcentered}
\newcommand{\unssymbol}{\large\textperiodcentered}
\newcommand{\str}[1]{\textbf{\ruby{#1}{\strsymbol}}{}}
\newcommand{\uns}[1]{\ruby{#1}{\unssymbol}{}}

\ExplSyntaxOn
\NewDocumentCommand{\stress}{m}
 {
  \leoboiko_stress:n { #1 }
 }

\tl_new:N \l_leoboiko_stress_sentence_tl

\cs_new_protected:Nn \leoboiko_stress:n
 {
  \tl_set:Nn \l_leoboiko_stress_sentence_tl { #1 }
  % change *<syllable>* into -*<syllable>*-
  \regex_replace_all:nnN { \*(.*?)\* } { -*\1*- } \l_leoboiko_stress_sentence_tl
  % change <space> into -<space>
  \regex_replace_all:nnN { \s } { -\cS\  } \l_leoboiko_stress_sentence_tl
  % change <space> into <space>-
  \regex_replace_all:nnN { \s } { \cS\ - } \l_leoboiko_stress_sentence_tl
  % add - at either end
  \regex_replace_once:nnN { \A (.*) \Z } { - \1 - } \l_leoboiko_stress_sentence_tl
  % normalize -- to -
  \regex_replace_all:nnN { \-\- } { \cO\- } \l_leoboiko_stress_sentence_tl
  % change -<letters>- into \uns{letters}-
  \regex_replace_all:nnN { \-([[:alpha:]]*?)\- } { \c{uns}\cB\{\1\cE\}- } \l_leoboiko_stress_sentence_tl
  % do it again
  \regex_replace_all:nnN { \-([[:alpha:]]*?)\- } { \c{uns}\cB\{\1\cE\}- } \l_leoboiko_stress_sentence_tl
  % remove the surplus -
  \regex_replace_all:nnN { \- } { } \l_leoboiko_stress_sentence_tl
  % change *<syllable>* into \str{<syllable>}
  \regex_replace_all:nnN { \*(.*?)\* } { \c{str}\cB\{\1\cE\} } \l_leoboiko_stress_sentence_tl
  % print
  \tl_use:N \l_leoboiko_stress_sentence_tl
 }

\ExplSyntaxOff

\begin{document}

\uns{A} \uns{po}\uns{ly}\str{syl}\uns{la}\uns{ble} \uns{should} \uns{be} \str{fun} \uns{to} \uns{de}\str{fine}

\stress{A po-ly*syl*la-ble should be *fun* to de*fine*}

\end{document}

在此处输入图片描述

相关内容