我是纯 TeX 领域的菜鸟。此问题中使用的所有命令都是在此网站和“LaTeX Wikibook”的答案的帮助下编写的。我想使用 TeX 命令更改键盘映射。我想对非拉丁文字执行此操作。因此,我已将该文字的所有字符激活,并使用catcode
s 和def
命令重新定义它们。这里的许多用户都无法阅读该文字,因此我之前的问题没有得到完整的解决方案。在这里,我在这个问题中给出了一个拉丁语示例。
假设我已将 A、B、C、D 分别重新映射到 P、Q、R、S
代码 -
\documentclass{article}
\makeatletter
\catcode`\A=\active
\protected\def A{P}
\catcode`\B=\active
\protected\def B{Q}
\catcode`\C=\active
\protected\def C{R}
\catcode`\D=\active
\protected\def D{S}
\makeatother
\begin{document}
ABCD
\end{document}
这将产生 -
但现在我有一个条件。当 A、B、C 或 D 是不是后面跟着字母“a”,在它们后面添加字母“x”。
因此现在我的代码是-
\documentclass{article}
\makeatletter
\catcode`\A=\active
\protected\def A{\bgroup P\futurelet\tmp\check}
\catcode`\B=\active
\protected\def B{\bgroup Q\futurelet\tmp\check}
\catcode`\C=\active
\protected\def C{\bgroup R\futurelet\tmp\check}
\catcode`\D=\active
\protected\def D{\bgroup S\futurelet\tmp\check}
\protected\def\check{\ifx\tmp a\egroup\expandafter\@gobble\else x\egroup\fi}
\makeatother
\begin{document}
AaBCD
\end{document}
这将产生 -
到目前为止一切都很好。现在我有多个条件。如果 A、B、C 或 D 是不是接着是“a”、“e”、“i”、“o”和“u”,然后添加“x”。
我不知道如何在这一行中添加多个条件 -
\protected\def\check{\ifx\tmp a\egroup\expandafter\@gobble\else x\egroup\fi}
第二个问题 -
我也想针对这种情况调整我的文件。
- 如果“A”后面是“X”,则将其更改为“L”
- 如果“B”后面是“X”,则将其更改为“M”
- 如果“C”后面是“X”,则将其更改为“N”
我甚至不知道如何用 TeX 语言表达这些条件。任何帮助我都感激不尽!
答案1
代码变得有点长。比我最初想象的要长得多。
我认为您的条件不太清楚。我(用蹩脚的伪代码)实现的是:
procedure cur_char // (a, b, c, or d)
if next_char is lowercase_vowel
print replacement (cur_char) // replaces ABCD by PQRS
else
if next_char is uppercase_X
override_replacement // changes replacement of ABC to LMN
end
print replacement (cur_char) // possibly overriden because of X
print "x"
end
end
这或多或少就是代码以过于简单的方式所做的事情。
使用该代码,会发生以下替换:
我用expl3
它来完成这项工作,否则代码会更长。我定义了一个\niranjan_define_active:Nn
你应该使用的宏,例如,像这样:
\niranjan_define_active:Nn A { \__niranjan_process:NN A P }
另一对宏\activateall
和\deactivateall
控制何时应发生替换行为。理想情况下,您希望此替换在组中激活以避免混乱。
如果您愿意,可以扩展代码来处理其他类型的替换。这\__niranjan_define_charset_conditional:Nn
允许您定义一个条件函数来检查下一个字符是否属于给定的字符集。
但是该代码仅适用于 catcode 为 11 的字符。我没有对其他 catcode 进行任何验证。
我必须说,我怀疑这段代码是否只适用于梵文脚本。但是,由于您需要拉丁字符的示例,因此这里是示例:
\documentclass{article}
\usepackage{expl3}
\ExplSyntaxOn
% Main code
\cs_new_protected:Npn \__niranjan_process:NN #1#2
{
\cs_set_eq:NN \l__niranjan_curr_char #1
\cs_set_eq:NN \l__niranjan_replacement_char #2
\niranjan_deactivate_all:
\peek_after:Nw \__niranjan_process_aux:
}
\cs_new_protected:Npn \__niranjan_process_aux:
{
\__niranjan_if_lower_vowel:NTF \l_peek_token
{
\l__niranjan_replacement_char
\__niranjan_rescan_token:w
}
{
\__niranjan_if_upper_X:NT \l_peek_token
{ \__niranjan_followed_by_X: }
\l__niranjan_replacement_char
x
\__niranjan_rescan_token:w
}
}
\cs_new_protected:Npn \__niranjan_followed_by_X:
{
\__niranjan_if_upper_ABC:NT \l__niranjan_curr_char
{
\exp_args:Nf \__niranjan_replace_char:n
{ \__niranjan_get_char:N \l__niranjan_curr_char }
}
}
\cs_new:Npn \__niranjan_replace_char:n #1
{
\exp_last_unbraced:NNf \cs_set_eq:NN \l__niranjan_replacement_char
\str_case:nnF {#1}
{
{ A } { L }
{ B } { M }
{ C } { N }
}
{#1}
}
\cs_new_protected:Npn \__niranjan_rescan_token:w
{
\peek_N_type:TF
{ \__niranjan_rescan_token:Nw }
{ \niranjan_activate_all: }
}
\cs_new_protected:Npn \__niranjan_rescan_token:Nw #1
{
\niranjan_activate_all:
\tl_rescan:nn { } {#1}
}
% Checking for following charset
\cs_set:Npn \__niranjan_tmp:w #1
{
\cs_new_protected:Npn \__niranjan_define_charset_conditional:Nn ##1 ##2
{
\prg_new_protected_conditional:Npnn ##1 ####1 { T, F, TF }
{
\exp_last_unbraced:No \__niranjan_if_charset:wn
\token_to_meaning:N ####1 #1 \q_nil \q_stop {##2}
}
}
\cs_new_protected:Npn \__niranjan_if_charset:wn ##1 #1 ##2##3 \q_stop ##4
{
\quark_if_nil:NTF ##2
{ \prg_return_false: }
{
\str_if_in:nnTF {##4} {##2}
{ \prg_return_true: }
{ \prg_return_false: }
}
}
\cs_new:Npn \__niranjan_get_char:N ##1
{ \exp_last_unbraced:No \__niranjan_get_char:w \token_to_meaning:N ##1 }
\cs_new:Npn \__niranjan_get_char:w #1 ##1 { ##1 }
}
\use:x { \exp_not:N \__niranjan_tmp:w { \tl_to_str:n { the~letter~ } } }
\__niranjan_define_charset_conditional:Nn \__niranjan_if_lower_vowel:N { aeiou }
\__niranjan_define_charset_conditional:Nn \__niranjan_if_upper_X:N { X }
\__niranjan_define_charset_conditional:Nn \__niranjan_if_upper_ABC:N { ABC }
% Setting active chars
\tl_new:N \g__niranjan_chars_tl
\cs_new_protected:Npn \niranjan_define_active:Nn #1#2
{
\cs_gset_protected:cpn { __niranjan_active_letter_#1: } {#2}
\char_set_active_eq:Nc #1 { __niranjan_active_letter_#1: }
\tl_gput_right:Nn \g__niranjan_chars_tl { #1 }
}
\cs_new_protected:Npn \niranjan_activate_all:
{ \tl_map_function:NN \g__niranjan_chars_tl \char_set_catcode_active:N }
\cs_new_protected:Npn \niranjan_deactivate_all:
{ \tl_map_function:NN \g__niranjan_chars_tl \char_set_catcode_letter:N }
\cs_new_eq:NN \activateall \niranjan_activate_all:
\cs_new_eq:NN \deactivateall \niranjan_deactivate_all:
\niranjan_define_active:Nn A { \__niranjan_process:NN A P }
\niranjan_define_active:Nn B { \__niranjan_process:NN B Q }
\niranjan_define_active:Nn C { \__niranjan_process:NN C R }
\niranjan_define_active:Nn D { \__niranjan_process:NN D S }
\ExplSyntaxOff
\begin{document}
\ttfamily
AaBeCiDoAu ->
\activateall
AaBeCiDoAu
\deactivateall
ABCDA ->
\activateall
ABCDA
\deactivateall
AXBXCXDXAX ->
\activateall
AXBXCXDXAX
\deactivateall
\end{document}
答案2
使用,\futurelet
您可以得出以下标记是{
或}
或空格标记的情况。
如果以下标记不是这些标记中的任何一个,则可以让 LaTeX 将其作为宏参数处理。
反过来,宏观论点可以用多种方式来检验。
解释你的模糊规范的一种方法是:
\documentclass{article}
\makeatletter
\newcommand\fetchargendgroup[1]{#1\endgroup}%
\begingroup
\def\tmp{\ActiveABCD}%
\catcode`\A=\active
\catcode`\B=\active
\catcode`\C=\active
\catcode`\D=\active
\@firstofone{%
\expandafter\endgroup
\expandafter\newcommand\expandafter{\tmp}{%
\begingroup
\protected\def A{\bgroup\futurelet\tmp\checka}%
\protected\def B{\bgroup\futurelet\tmp\checkb}%
\protected\def C{\bgroup\futurelet\tmp\checkc}%
\protected\def D{\bgroup\futurelet\tmp\checkd}%
\catcode`\A=\active
\catcode`\B=\active
\catcode`\C=\active
\catcode`\D=\active
\fetchargendgroup
}%
}%
\newcommand\checka{\check{P}{Lx}}
\newcommand\checkb{\check{Q}{Mx}}
\newcommand\checkc{\check{R}{Nx}}
\newcommand\checkd{\check{S}{SxX}}
\protected\def\check#1#2{%
\ifcat\noexpand\tmp\bgroup\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{\egroup#1x}{%
\ifcat\noexpand\tmp\egroup\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{\egroup#1x}{%
\ifcat\noexpand\tmp\@sptoken\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{\egroup#1x}{%
\nextargfork{#1}{#2}%
}%
}%
}%
}%
\newcommand*\mya{a}
\newcommand*\mye{e}
\newcommand*\myi{i}
\newcommand*\myo{o}
\newcommand*\myu{u}
\newcommand*\myX{X}
\newcommand\nextargfork[3]{%
\def\tmp{#3}%
\ifx\tmp\myX\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{\egroup#2}{%
\ifx\tmp\mya\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{\egroup#1}{%
\ifx\tmp\mye\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{\egroup#1}{%
\ifx\tmp\myi\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{\egroup#1}{%
\ifx\tmp\myo\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{\egroup#1}{%
\ifx\tmp\myu\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{\egroup#1}{\egroup#1x#3}%
}%
}%
}%
}%
}%
}%
\makeatother
\begin{document}
\verb|\ActiveABCD{AaeBCD AXaBXCXDX}|: \ActiveABCD{AaeBCD AXaBXCXDX}%
\end{document}
如果这不符合预期,请准确指定有关更换的所有要求。