我想替换 XeTeX 中的 unicode 字符对,类似于国家国旗 unicode 字符。我不想指定每个选项(每个国家代码),并且希望灵活处理其他表情符号(肤色变化、其他非国家代码标志等)。上述答案中的代码的问题在于,它不允许单个可配对字符(即使我相应地修改了 False-statement)。
经过几天的努力,我找到了一个解决方案(见下文),它适用于我能想到的几乎所有情况。
我的问题:
- 我如何检查最后几种情况(9:在 ~ 之后和 21:在对齐字符之后),为什么如果我在字符和对齐字符之间放置一个字母(情况 22)它不起作用,但使用分隔空格(情况 21)却可以工作?
- 我有忘记什么案例吗?
- 有没有更优雅的方法?我的解决方案对我来说似乎很粗糙。
我的解决方案包括提及案例的示例列表(不起作用的案例[最后两项]被注释掉):
\documentclass[varwidth,border=10pt]{standalone}
\usepackage{expl3}
\usepackage{newunicodechar}
\renewcommand{\familydefault}{\sfdefault} % math is more obvious
\ExplSyntaxOn
\cs_new_protected:Npn \single_uni:n #1 {
\int_to_Hex:n{`#1}
}
% method is very specific, am I forgetting something? Not possible with ^^7e(~), ...
\cs_new_protected:Nn \dual_uni:n {
\peek_catcode:NTF \c_space_token {
\int_to_Hex:n{`#1}
}{
\peek_catcode:NTF \c_other_token {
\int_to_Hex:n{`#1}
}{
\peek_charcode:NTF ^^24 { % math, \c_math_toggle_token not working
\int_to_Hex:n{`#1}
}{
\peek_charcode:NTF ^^5e { % math sub, \c_math_subscript_token not working
\int_to_Hex:n{`#1}
}{
\peek_charcode:NTF ^^5f { % math super, \c_math_superscript_token not working
\int_to_Hex:n{`#1}
}{
\peek_catcode:NTF \c_group_end_token { % end group
\int_to_Hex:n{`#1}
}{
\peek_catcode:NTF \c_group_begin_token { % begin group
\int_to_Hex:n{`#1}
}{
\peek_catcode:NTF \c_alignment_token { % has no effect?!
\int_to_Hex:n{`#1}
}{
\dual_uni_cont:nn{#1}
}
}
}
}
}
}
}
}
}
\cs_new_protected:Nn \dual_uni_cont:nn{
\textbf{\int_to_Hex:n{`#1}}\textit{\int_to_Hex:n{`#2}}
}
\newunicodechar{➀}{\single_uni:n{➀}} % single_uni
\newunicodechar{➁}{\dual_uni:n{➁}} % dual_uni
% ➂ undeclared newunicodechar
\ExplSyntaxOff
\begin{document}
\begin{enumerate}
\item[] expected \quad -- \quad result
\item ➂ \quad -- \quad ➂ % comparsion undeclared uni (expected blank, because not in font)
\item 2780 \quad -- \quad ➀ % comparsion single_uni
\item \textbf{2781}\textit{78} \quad -- \quad ➁x % following letter
\item \textbf{2781}\textit{21} \quad -- \quad ➁! % following other
\item \textbf{2781}\textit{2782} \quad -- \quad ➁➂ % following unicode (other)
\item \textbf{2781}\textit{2781} \quad -- \quad ➁➀ % following "newunicode" as \single_uni (active?!)
\item \textbf{2781}\textit{2780}x \quad -- \quad ➁➁x % following "newunicode" as \dual_uni (active?!), following letter
\item 2781 x \quad -- \quad ➁ x % following space
\item 2781~x \quad -- \quad ➁~x % following active
\item 2781 \quad -- \quad ➁\\ % following newline
\phantom{nothing} % nothing for a new line
\item $\textbf{2781}\textit{78}$ \quad -- \quad $➁x$ % in math (following letter)
\item $2781^x$ \quad -- \quad $➁^x$ % following math superscript
\item $2781_x$ \quad -- \quad $➁_x$ % following math subscript
\item $2781$ \quad -- \quad $➁$ % in math (following math toggle)
\item 2781\$ \quad -- \quad ➁\$ % following \$
\item 2781\textbullet \quad -- \quad ➁\textbullet % following command
\item 2781\footnote{x} \quad -- \quad ➁\footnote{x} % following command
\item {2781} \quad -- \quad {➁} % following group end
\item 2781{x} \quad -- \quad ➁{x} % following group begin
\item 2781 \quad -- \quad ➁% %x following comment
\item \begin{tabular}{llllll} % in tabular, following space
2781&x &\quad -- \quad& ➁ x& x\\
\end{tabular}
\item \begin{tabular}{llllll} % in tabular, following letter, alignment
2781&x &\quad -- \quad& %➁x& x\\
\end{tabular}
\item \begin{tabular}{llllll} % in tabular, following alignment, space, letter
2781&x &\quad -- \quad& %➁& x\\
\end{tabular}
\end{enumerate}
\end{document}
目前结果如下(最后两项没有结果):如果定义为潜在双字符的字符找到了后面的“伙伴”,则结果为原始字符以粗体显示,后面的字符以斜体显示。如果该字符不是双字符或没有找到“伙伴”,则正常打印:
更新:我尝试了另一种方法,但遇到了不同的问题:比较宏名称而不是含义。但这个问题仍然需要回答……
答案1
我想这就是我要做的。你创建一个包含所有选项的列表,检查是否可以安全地获取令牌,如果可以,就获取它,检查它是否在列表中,如果在列表中,则使用双重选项,否则使用单一选项并保留令牌。
\documentclass{article}
\usepackage{expl3}
\usepackage{newunicodechar}
\ExplSyntaxOn
\str_new:N \g_fjs_duals_list_str
\str_gset:Nn \g_fjs_duals_list_str { ➀➁ }
\cs_new:Nn \fjs_uni:N { [ \int_to_Hex:n { `#1 } ] }
\cs_new:Nn \fjs_uni:NN { [ \int_to_Hex:n { `#1 } ; \int_to_Hex:n { `#2 } ] }
\cs_new_protected:Nn \fjs_checkdual:N
{
\peek_N_type:TF { \fjs_checkdual_grab:NN #1 } { \fjs_uni:N #1 }
}
\cs_new_protected:Nn \fjs_checkdual_grab:NN
{
\tl_if_in:NoTF \g_fjs_duals_list_str { \token_to_str:N #2 }
{ \fjs_uni:NN #1 #2 }
{ \fjs_uni:N #1 #2 }
}
\cs_generate_variant:Nn \tl_if_in:NnTF { No }
\newunicodechar{➀}{ \fjs_checkdual:N ➀ }
\newunicodechar{➁}{ \fjs_checkdual:N ➁ }
\ExplSyntaxOff
\begin{document}
➁➀
➁➁
➀➁
➀➀
\end{document}
我不知道什么是理想的方法,因为在这里我将str
函数与混合在一起tl
,但它是必要的(至少在当前方法中),因为否则符号将被激活并具有不同的 catcode,因此它们不在原始列表中。