出于好奇,我想知道如何用expl3
做的基础mhchem
(如第基本在里面mhchem
手动的) 好像?
我在 TeX 和 LuaTeX 中找到了例子http://wiki.contextgarden.net/Programming_in_LuaTeX但是它们的输入风格太接近数学(在我看来,不如方便mhchem
)。
因此,大师们,请展示一下的力量expl3
。
答案1
我不知道这是否足以完全实现它\ce
的功能,但这里有一个关于如何实现它的简单示例。请注意,这里没有状态机或活动字符,只是明智地使用了搜索和替换。我想,这是正则表达式解决方案的 TeX 等效方案。不过,谁知道它是否有效。
\documentclass{文章} \usepackage{expl3,xparse, fixltx2e, % 为 \textsubscript amstext % 表示 \text } \newcommand\textsubsuperscript[2]{$_{\text{#1}}^{\text{#2}}$} \newcommand\textsupersubscript[2]{$_{\text{#2}}^{\text{#1}}$} \ExplSyntaxOn % \catcode 12 个其他特殊字符的字符串: \tl_set:Nx \c_underscore_char { \cs_to_str:N \_ } \tl_set:Nx \c_caret_char { \cs_to_str:N \^ } \tl_set:Nx \c_bgroup_char { \cs_to_str:N \{ } \tl_set:Nx \c_egroup_char { \cs_to_str:N \} } \DeclareDocumentCommand \ce {m} { \tl_set:Nx \l_ce_tl { \tl_to_str:n {#1} } \tl_replace_all_in:Nnn \l_ce_tl {1} {\ce_sub:w{1}} \tl_replace_all_in:Nnn \l_ce_tl {2} {\ce_sub:w{2}} \tl_replace_all_in:Nnn \l_ce_tl {3} {\ce_sub:w{3}} \tl_replace_all_in:Nnn \l_ce_tl {4} {\ce_sub:w{4}} \tl_replace_all_in:Nnn \l_ce_tl {5} {\ce_sub:w{5}} \tl_replace_all_in:Nnn \l_ce_tl {6} {\ce_sub:w{6}} \tl_replace_all_in:Nnn \l_ce_tl {7} {\ce_sub:w{7}} \tl_replace_all_in:Nnn \l_ce_tl {8} {\ce_sub:w{8}} \tl_replace_all_in:Nnn \l_ce_tl {9} {\ce_sub:w{9}} \tl_replace_all_in:Nnn \l_ce_tl {0} {\ce_sub:w{0}} \tl_replace_all_in:非 \l_ce_tl \c_caret_char {\ce_super:w} \tl_replace_all_in:非 \l_ce_tl \c_underscore_char {\ce_sub:w} \tl_replace_all_in:Nnn \l_ce_tl {+} {\ce_super:w{+}} \tl_replace_all_in:Nnn \l_ce_tl {-} {\ce_super:w{$-$}} % 修复类似“^2”的语法: \tl_replace_all_in:Nnn \l_ce_tl {\ce_super:w \ce_sub:w} {\ce_super:w} %最后,修复被去标记化的括号: \tl_rescan:nV {\ExplSyntaxOn} \l_ce_tl } \cs_set:Npn \ce_super:w #1 { \peek_meaning_remove_ignore_spaces:NTF \ce_sub:w {\textsupersubscript{\ce_disable_subsuper: #1}} {\textsuperscript{\ce_disable_subsuper: #1}} } \cs_set:Npn \ce_sub:w #1 { \peek_meaning_remove_ignore_spaces:NTF \ce_super:w {\textsubsuperscript{\ce_disable_subsuper: #1}} {\textsubscript{\ce_disable_subsuper: #1}} } \cs_set:Nn \ce_disable_subsuper: { \cs_set_eq:NN \ce_super:w \use:n \cs_set_eq:NN \ce_sub:w \use:n } %需要这些变体: \cs_generate_variant:Nn \tl_replace_all_in:Nnn {非} \cs_generate_variant:Nn \tl_rescan:nn {nV} \ExplSyntaxOff \开始{文档} \ce{Y^{99}+}\par \ce{Y^{99+}}\par \ce{H20}\par \ce{Sb2O3}\par \ce{H+}\par \ce{CrO4^2-}\par \ce{AgCl2-}\par \ce{[AgCl2]-}\par \ce{H2_{(aq)}}\par \ce{NO3-}\par \ce{(NH4)2S}\par \结束{文档}
的前提\ce
是将参数转换为字符串,然后用宏替换各种字符以扩展为所需的输出。首先,条件下标中的数字被替换为它们自己,然后^
和_
被替换宏执行“条件上标和下标”(分别),最后+
和-
被替换为它们自己的上标。
对于类似 的语法^2
,需要用[superscript]
+来替换,我们将+[subscript 2]
的组合单独用条件上标来替换。[superscript]
[subscript]
最后,使用 expl3 包装器对字符串进行“重新标记”,\scantokens
以执行所有排版工作。
我上面提到的“条件下标”和“条件上标”只是文本的上标/下标,它们在嵌套材料中会自行停用。例如,[subscript [subscript x]]
被解释为[subscript x]
。这允许上标内部的内容+
不再自行上标。