ctex-kit
ctex-kit copied to clipboard
xeCJK: 将汉字放进盒子里面
目前对汉字的特殊处理可以通过重新定义 \CJKsymbol 来实现,但是这种方法有很大的局限性,很容易与 XeTeX 的字符类机制冲突。
事实上,我们可以在 \XeTeXinterchartoks 中把汉字放进一个盒子变量里,然后通过自定义函数来操作这个盒子变量实现特殊效果。这种方法应该更为安全和灵活。
下面是一个简单的汉字旋转和基线调整的例子。
% !TeX program = XeTeX
% !TeX encoding = UTF-8
\input expl3-generic %
\ExplSyntaxOn
\char_set_catcode_letter:N \@
\newXeTeXintercharclass \l_@@_rotate_class
\newXeTeXintercharclass \l_@@_raise_class
\xetex_interchartoks:D \c_one \l_@@_rotate_class
{ \@@_box_begin:w }
\xetex_interchartoks:D \l_@@_rotate_class \c_one
{ \@@_box_end:N \@@_rotate_char: }
\xetex_interchartoks:D \l_@@_rotate_class \xe@charclass@boundary
{ \@@_box_end:N \@@_rotate_char: }
\xetex_interchartoks:D \c_one \l_@@_raise_class
{ \@@_box_begin:w }
\xetex_interchartoks:D \l_@@_raise_class \c_one
{ \@@_box_end:N \@@_raise_char: }
\xetex_interchartoks:D \l_@@_raise_class \xe@charclass@boundary
{ \@@_box_end:N \@@_raise_char: }
\cs_new_protected_nopar:Npn \@@_box_begin:w
{ \hbox_set:Nw \l_@@_char_box }
\cs_new_protected_nopar:Npn \@@_box_end:N #1
{ \hbox_set_end: #1 }
\box_new:N \l_@@_char_box
\cs_new_protected_nopar:Npn \@@_rotate_char:
{
\box_rotate:Nn \l_@@_char_box { \l_@@_char_rotate_fp }
\box_use:N \l_@@_char_box
}
\cs_new_protected_nopar:Npn \@@_raise_char:
{
\box_move_up:nn { \l_@@_char_raise_tl }
{ \box_use:N \l_@@_char_box }
}
\keys_define:nn { @@ }
{
rotate .fp_set:N = \l_@@_char_rotate_fp ,
raise .tl_set:N = \l_@@_char_raise_tl ,
raise .initial:n = \c_zero_dim
}
\cs_new_protected_nopar:Npn \set
{ \keys_set:nn { @@ } }
\xetex_charclass:D `地 = \l_@@_rotate_class
\xetex_charclass:D `黄 = \l_@@_raise_class
\int_set_eq:NN \xetex_interchartokenstate:D \c_one
\tex_font:D \l_@@_main_font = "[FandolSong-Regular.otf]" \scan_stop:
\l_@@_main_font
\ExplSyntaxOff
天地玄黄
\set{rotate=45, raise=1ex}
天地玄黄
\set{rotate=-45, raise=-1ex}
天地玄黄
\bye

看起来不错