使用 l3 的用户定义标记别名

使用 l3 的用户定义标记别名

我想编写一个提供人文学科学术研究语义标记的软件包(大致遵循 TEI-XML)。在源代码中,用户可以使用宏,例如\term用于外来词或\socalled“引号”。

我想提供一组默认的排版命令,每个宏都会扩展为(\term-> \emph\socalled-> \enquote)。我还想提供一个简单的键值接口,供用户重新配置这些(例如,满足出版商的规范)。而且,为了未来的稳健性和灵活性,我希望在 中expl3或至少使用 来完成xparse。(我必须承认我完全被 搞糊涂了,expl3但我希望在这里学到一些东西。)

我已经获得了一条\setTagFormat命令,该命令创建一个新命令,将标记标签别名到其排版宏。我如何使用诸如这样的键值接口来实现这一点l3keys

在当前版本(下面的 MWE)中,用户必须为每个标签输入命令\setTagFormat{\term}{\emph}。因此,也许这样的界面会更好:

\setSemanticTagFormat{                                                                                                                 
  \term = \emph                                                                                                                      
  \q = \enquote                                                                                                                      
}    

在另一种方法中,由于许多标签将被别名为相同的排版命令(基本上是斜体或引号),因此您可以朝另一个方向努力:

\setSemanticTagFormat{                                                                                                               
   \emph = \term, \mentioned, \foreign, \worktitle                                                                                    
   \enquote = \q, \socalled, \parttitle                                                                                               
}           

我还想到(回到纯 TeX)我可以这样做:

\let\term\emph
\let\q\enquote

这是一个有效但不理想的例子,xparse但不是l3keys

\documentclass{article}

\usepackage{csquotes}
\usepackage{xparse}

\NewDocumentCommand\setTagFormat{m m}{%                                                                                                 
  \NewDocumentCommand #1{m}{#2{##1}}%                                                                                                   
}
\setTagFormat{\term}{\emph}
\setTagFormat{\q}{\enquote}                                                                                                                

\begin{document}

\term{Musica ficta} is the practice of adding accidentals where they are not notated.
The teacher told us, \q{Always sing F-sharp before a cadence on G!}

\end{document}

答案1

稍微简单一点\keyval_parse:NNn

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\cs_new_protected:Nn \cashner_make_semantic:Nn
  {
    \tl_map_inline:nn {#2} % for every token in the second argument,
      { \NewDocumentCommand ##1 {} {#1} } % create the alias to the first
  }

\NewDocumentCommand \NewSemanticMarkup { m }
  % with keyval syntax,
  % |          / ignore single keys
  % |         |     \           /  and apply our function
  % |         |      \         /  /                      \ to our argument
  { \keyval_parse:NNn \use_none:n \cashner_make_semantic:Nn {#1} }

\ExplSyntaxOff

\usepackage{csquotes}

\NewSemanticMarkup {
  \textit = \term,
  \enquote = \scare \socalled
}

\begin{document}
hi

\term{hi}

\scare{hi}

\socalled{hi}
\end{document}

答案2

我会避免对应该等同于其他宏的宏进行分组,因为这将使改变含义变得更加困难:如果它们的数量很大,则很难在组中发现它们。

每个等价物一行似乎更好,并且更容易管理变化。

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand \SetSemanticMarkup { m }
 {
  \clist_map_inline:nn { #1 }
   {
    \SetEquivalent{ ##1 }
   }
 }
\NewDocumentCommand{\SetEquivalent}{ >{\SplitArgument{1}{=}} m }
 {
  \cashner_set_equivalent:nn #1
 }
\cs_new_protected:Nn \cashner_set_equivalent:nn
 {
  \cs_new_eq:NN #1 #2
 }
\ExplSyntaxOff

\usepackage{csquotes}

\SetSemanticMarkup {
  \term = \textit,
  \scare = \enquote,
  \socalled = \enquote,
  \q = \enquote,
}

\begin{document}
hi

\term{hi}

\scare{hi}

\socalled{hi}

\term{Musica ficta} is the practice of adding accidentals where they are not notated.
The teacher told us, \q{Always sing F-sharp before a cadence on G\@!}

\end{document}

在此处输入图片描述

相关内容