以下文章中的最后一个解决方案很棒,我们可以添加其他快捷方式。
我不明白的一件事是我无法添加带有 _ 的快捷方式:
例如:\mathbb{R}_+ 作为快捷方式无法正确转换... + 是正常大小而不是正确大小。
知道为什么吗?
我不明白 expl3,所以我不知道问题是什么(由于某种原因,它可以与 ^ 一起使用而不能与 _ 一起使用),以及是否可以改进代码以与下划线一起使用,或者我是否必须在文本中手动执行此操作。
代码如下:
\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}
\ExplSyntaxOn
\seq_new:N \l_math_subs_seq
\msg_new:nnn {math} {symbol-exists} {symbol~#1~already~exists}
\int_new:N \g_math_struct_counter
\int_gset:Nn \g_math_struct_counter {1}
\cs_new_protected:Npn \mathstruct_new:N #1
{
\tl_set:Nx #1 {l_mathstruct_internal_\int_use:N \g_math_struct_counter _prop}
\prop_new:c {#1}
\int_gincr:N \g_math_struct_counter
\prop_new:c {l_mathstruct_internal_\int_use:N \g_math_struct_counter _prop}
\prop_put:cnn {#1} {value} {}
\prop_put:cnn {#1} {exist} {\c_false_bool}
\prop_put:cnn {#1} {mapping} {}
\prop_put:cnx {#1} {children} {l_mathstruct_internal_\int_use:N \g_math_struct_counter _prop}
\int_gincr:N \g_math_struct_counter
}
\mathstruct_new:N \l_math_prefix_tree_root
\tl_new:N \l_math_children_prop_tl
\tl_new:N \l_math_tmpa_tl
\tl_new:N \l_math_tmpb_tl
\tl_new:N \l_math_tmpc_tl
\cs_new_protected:Npn \math__recursive_add_sub:nnnn #1#2#3#4
{
\str_if_empty:nTF {#2}
{
\prop_get:cnN {#1} {exist} \l_math_tmpa_tl
\exp_args:NV \bool_if:nTF {\l_math_tmpa_tl}
{
% if symbol alreasy exists, send a warning
\msg_warning:nnn {math} {symbol-exists} {#4}
}
{
% need to set this symbol as "exists" and set the mapping
\prop_put:cnn {#1} {exist} {\c_true_bool}
\prop_put:cnn {#1} {mapping} {#3}
}
}
{
\prop_get:cnN {#1} {children} \l_math_children_prop_tl
\str_set:Nx \l_math_tmpa_tl {\str_head:n {#2}}
% see if it is one of its children
\prop_if_in:cVTF {\l_math_children_prop_tl} \l_math_tmpa_tl
{
% if the node exists, continue recursively
\tl_set:Nx \l_math_tmpc_tl {\str_tail:n {#2}}
\prop_get:cVN {\l_math_children_prop_tl} \l_math_tmpa_tl \l_math_tmpb_tl
\math__recursive_add_sub:Vxnn \l_math_tmpb_tl {\str_tail:n {#2}} {#3} {#4}
}
{
% otherwise, need to create new node
\mathstruct_new:N \l_math_tmpb_tl
\prop_put:cnV {\l_math_tmpb_tl} {value} \l_math_tmpa_tl
\prop_put:cVV {\l_math_children_prop_tl} \l_math_tmpa_tl \l_math_tmpb_tl
% apply recursively
\math__recursive_add_sub:Vxnn \l_math_tmpb_tl {\str_tail:n {#2}} {#3} {#4}
}
}
}
\cs_generate_variant:Nn \math__recursive_add_sub:nnnn {Vxnn,VVVV}
\tl_new:N \l_math_add_tmpa_tl
\tl_new:N \l_math_add_tmpb_tl
\cs_new_protected:Npn \math_add_sub:nn #1 #2
{
\tl_set_rescan:Nnn \l_math_add_tmpa_tl {\cctab_select:N\c_code_cctab} {#1}
\tl_set_rescan:Nnn \l_math_add_tmpb_tl {\cctab_select:N\c_code_cctab} {#2}
\math__recursive_add_sub:VVVV \l_math_prefix_tree_root \l_math_add_tmpa_tl \l_math_add_tmpb_tl \l_math_add_tmpa_tl
}
% post order traversal
\cs_new_protected:Npn \math__sub_recursive_generate:nn #1#2
{
\group_begin:
% check children first
\prop_get:cnN {#1} {children} \l_math_children_prop_tl
\prop_map_inline:cn {\l_math_children_prop_tl}
{
\math__sub_recursive_generate:nn {##2} {#2##1}
}
% check current node
\prop_get:cnN {#1} {exist} \l_math_tmpa_tl
\bool_if:nT {\l_math_tmpa_tl}
{
\prop_get:cnN {#1} {mapping} \l_math_tmpb_tl
\tl_set_rescan:Nnn \l_math_tmpc_tl { \cctab_select:N \c_document_cctab } {#2}
\seq_gput_right:Nx \l_math_subs_seq { {\exp_not:V \l_math_tmpc_tl} {\exp_not:V \l_math_tmpb_tl} }
}
\group_end:
}
% traverse the tree to get the correct order
\cs_new_protected:Npn \math_sub_generate:
{
\seq_gclear:N \l_math_subs_seq
\exp_args:NV \math__sub_recursive_generate:nn \l_math_prefix_tree_root {}
}
\cs_new_protected:Npn \math_ascii_sub:n #1
{
\tl_set:Nn \l_tmpa_tl { #1 }
\seq_map_inline:Nn \l_math_subs_seq
{
\tl_replace_all:Nnn \l_tmpa_tl ##1
}
\tl_use:N \l_tmpa_tl
}
\cs_new_protected:Npn \math_grabinline:w #1 $
{
\math_ascii_sub:n { #1 } $
}
\cs_new_protected:Npn \math_grabdisplay:w #1 \]
{
\math_ascii_sub:n { #1 } \]
}
\cs_set_eq:NN \MathAddSub \math_add_sub:nn
\cs_set_eq:NN \MathGenSub \math_sub_generate:
% Enable substitutions for $...$ and \[...\]
\everymath { \math_grabinline:w }
\tl_put_right:Nn \[ { \math_grabdisplay:w }
\ExplSyntaxOff
\begin{document}
\centering
\newcommand*{\test}[1]{%
$#1$%
\[#1\]%
}
\MathAddSub{ << }{ \ll }
\MathAddSub{ <> }{ \neq }
\MathAddSub{ <= }{ \leq }
\MathAddSub{ >> }{ \gg }
\MathAddSub{ >= }{ \geq }
\MathAddSub{ -+ }{ \mp }
\MathAddSub{ +- }{ \pm }
\MathAddSub{ == }{ \equiv }
\MathAddSub{ =. }{ \doteq }
\MathAddSub{ =( }{ \subseteq }
\MathAddSub{ =) }{ \supseteq }
\MathAddSub{ =[ }{ \sqsubseteq }
\MathAddSub{ =] }{ \sqsubseteq }
\MathAddSub{ <== }{ \Leftarrow }
\MathAddSub{ <=> }{ \Leftrightarrow }
\MathAddSub{ <-- }{ \leftarrow }
\MathAddSub{ <-> }{ \leftrightarrow }
\MathAddSub{ --> }{ \rightarrow }
\MathAddSub{ ==> }{ \Rightarrow }
\MathAddSub{ ... }{ \dots }
\MathAddSub{ int }{ \int }
\MathAddSub{ Re }{ \mathbb{R}^* } %---------- This works
\MathAddSub{ Rp }{ \mathbb{R}_+ } %---------- This doesn't works
\MathAddSub{ RR }{ \mathbb{R}} %---------- This works
% generate the substitution table based on post-order traversal of the prefix tree
\MathGenSub
\ExplSyntaxOn
% show the substitution table
\seq_show:N \l_math_subs_seq
\ExplSyntaxOff
\test{RR \qquad Re \qquad Rp (doesn't work) while \qquad RR_+ (does)}
\test{a << b < c <= d >= e > f >> g}
\test{a <> b = c =. d == e}
\test{a <== b <-- c <-> d <=> e --> f ==> g}
\test{a +- b = -(-a -+ +b)}
\test{a, ..., z <> a + ...+ z}
\test{a =( b =) c =[ e =] f}
\test{int _a^b}
\test{@@@@@ @@@@ @@@}
\MathAddSub{ @@@ }{ \mbox{~}THREE\mbox{~} }
\MathAddSub{ @@@@ }{ \mbox{~}FOUR\mbox{~} }
\MathAddSub{ @@@@@ }{ \mbox{~}FIVE\mbox{~} }
% generate the substitution table again
\MathGenSub
\ExplSyntaxOn
% show the substitution table
\seq_show:N \l_math_subs_seq
\ExplSyntaxOff
\test{@@@@@ @@@@ @@@}
\end{document}