From 514373c000dc69882cdcb746f8a6700a2c4cb5ac Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Sat, 7 Apr 2018 20:59:35 +0000 Subject: xecjk (7apr18) git-svn-id: svn://tug.org/texlive/trunk@47362 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/source/xelatex/xecjk/xeCJK.dtx | 561 ++++++++++++++--------- 1 file changed, 336 insertions(+), 225 deletions(-) (limited to 'Master/texmf-dist/source/xelatex/xecjk/xeCJK.dtx') diff --git a/Master/texmf-dist/source/xelatex/xecjk/xeCJK.dtx b/Master/texmf-dist/source/xelatex/xecjk/xeCJK.dtx index 47ffa072f5a..7b529c66f37 100644 --- a/Master/texmf-dist/source/xelatex/xecjk/xeCJK.dtx +++ b/Master/texmf-dist/source/xelatex/xecjk/xeCJK.dtx @@ -194,7 +194,7 @@ Copyright and Licence %<*package|config|fntef|listings|xunicode|xunextra> %\NeedsTeXFormat{LaTeX2e} %\RequirePackage{expl3} -%<+!driver>\GetIdInfo$Id: xeCJK.dtx 25e85c2 2018-02-27 02:44:39 +0800 Qing Lee $ +%<+!driver>\GetIdInfo$Id: xeCJK.dtx 2041e49 2018-04-07 17:31:56 +0800 Qing Lee $ % {Typesetting CJK scripts with XeLaTeX} % {Configuration file for xeCJK package} % {xeCJK font effect} @@ -207,7 +207,7 @@ Copyright and Licence %\ProvidesExplPackage{xeCJK-listings} %\ProvidesExplPackage{xunicode-addon} %\ProvidesExplFile{xunicode-extra.def} -% {\ExplFileDate}{3.6.1}{\ExplFileDescription} +% {\ExplFileDate}{3.7.0}{\ExplFileDescription} % %<*driver> \documentclass{ctxdoc} @@ -280,7 +280,7 @@ Copyright and Licence % \changes{v3.6.0}{2018/01/13}{同步 \LaTeXiii{} 2017/12/16。} % \changes{v3.6.1}{2018/02/27}{减少 \texttt{bool} 运算。} % -% \CheckSum{10801} +% \CheckSum{10889} % \GetFileId{xeCJK.sty} % % \title{\bfseries\pkg{xeCJK} 宏包} @@ -2120,6 +2120,14 @@ Copyright and Licence % \end{macrocode} % \end{macro} % +% \begin{macro}[int]{\xeCJK_make_boundary:} +% 利用 \cs{scan_stop:} 结束 CJK 分组,用于恢复字体等。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \xeCJK_make_boundary: + { \bool_if:NT \l_@@_CJK_group_bool { \scan_stop: } } +% \end{macrocode} +% \end{macro} +% % \subsection{功能开关} % % \begin{macro}{xeCJKactive} @@ -3857,7 +3865,7 @@ Copyright and Licence \cs_new_protected_nopar:Npn \@@_punct_bound_kern_aux:NNN #1#2 { \str_if_eq:nnTF {#1} {#2} - { \@@_punct_bound_kern:N } + { \@@_nobreak_hskip:N } { \@@_punct_if_long:NTF #1 { \skip_horizontal:N } @@ -5444,65 +5452,112 @@ Copyright and Licence \tl_if_exist:cF { \@@_punct_csname:n { dim/glue/#1/#2 } } { \@@_get_punct_bounds_aux:NN #1 #2 } } -\cs_new_protected_nopar:Npn \@@_get_punct_bounds_aux:NN #1#2 +\cs_new_protected_nopar:Npn \@@_get_punct_bounds_aux:NN { \tl_if_eq:NNTF \l_xeCJK_punct_style_tl \c_@@_punct_style_plain_tl - { - \@@_save_punct_dim:nNNn { rule } #1 #2 { \c_zero_dim } - \@@_save_punct_dim:nNNn { glue } #1 #2 { \c_zero_dim } - \@@_save_punct_dim:nNNn { offset } #1 #2 { \c_zero_dim } - \@@_save_punct_dim:nNNn { bound } \c_@@_left_tl {#2} { \c_zero_dim } - \@@_save_punct_dim:nNNn { bound } \c_@@_right_tl {#2} { \c_zero_dim } - \@@_save_punct_skip:nNNn { glue } #1 #2 { \c_zero_skip } - } - { - { \xeCJK_select_punct_font: \xeCJK_calc_punct_dimen:N #2 } - \dim_set:Nn \l_@@_bound_dim - { \@@_use_punct_dim:nNN { bound } #1 #2 } - \dim_set:Nn \l_@@_reverse_bound_dim - { - \tl_if_eq:NNTF #1 \c_@@_left_tl - { \@@_use_punct_dim:nNN { bound } \c_@@_right_tl } - { \@@_use_punct_dim:nNN { bound } \c_@@_left_tl } - #2 - } - \UseInstance { xeCJK / punctuation } { \l_xeCJK_punct_style_tl } - \xeCJK_punct_margin_process:NN #1 #2 - \xeCJK_punct_offset_process:NN #1 #2 - } + { \@@_save_punct_margin_plain:NN } + { \@@_save_punct_margin:NN } } \cs_new_protected_nopar:Npn \xeCJK_get_punct_bounds:No { \exp_last_unbraced:NNo \xeCJK_get_punct_bounds:NN } +\cs_new_protected_nopar:Npn \@@_save_punct_margin_plain:NN #1#2 + { + \@@_save_punct_dim:nNNn { rule } #1 #2 { \c_zero_dim } + \@@_save_punct_dim:nNNn { glue } #1 #2 { \c_zero_dim } + \@@_save_punct_dim:nNNn { offset } #1 #2 { \c_zero_dim } + \@@_save_punct_dim:nNNn { bound } \c_@@_left_tl {#2} { \c_zero_dim } + \@@_save_punct_dim:nNNn { bound } \c_@@_right_tl {#2} { \c_zero_dim } + \@@_save_punct_skip:nNNn { glue } #1 #2 { \c_zero_skip } + } +\cs_new_protected_nopar:Npn \@@_save_punct_margin:NN #1#2 + { + \group_begin: + \xeCJK_select_punct_font: + \xeCJK_calc_punct_dimen:N #2 + \group_end: + \dim_set:Nn \l_@@_bound_dim + { \@@_use_punct_dim:nNN { bound } #1 #2 } + \dim_set:Nn \l_@@_reverse_bound_dim + { + \tl_if_eq:NNTF #1 \c_@@_left_tl + { \@@_use_punct_dim:nNN { bound } \c_@@_right_tl } + { \@@_use_punct_dim:nNN { bound } \c_@@_left_tl } + #2 + } + \UseInstance { xeCJK / punctuation } { \l_xeCJK_punct_style_tl } + \xeCJK_punct_margin_process:NN #1 #2 + \xeCJK_punct_offset_process:NN #1 #2 + \@@_punct_if_long:NT #2 + { \@@_long_punct_kerning:N #2 } + } \dim_new:N \l_@@_bound_dim \dim_new:N \l_@@_reverse_bound_dim % \end{macrocode} % \end{macro} % +% \changes{v3.7.0}{2018/03/12}{修正长标点被隔开时的压缩处理错误。} +% +% \begin{macro}[int]{\@@_long_punct_kerning:N} +% \changes{v3.4.3}{2016/10/27}{考虑破折号边界为负值的情况。} +% 相同长标点压缩。对于破折号,计算两标点之间的空白,保证它中间不被断开。 +% 注意,破折号的边界可能为负值(比如方正新书宋),此时不必压缩。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_long_punct_kerning:N #1 + { + \dim_set:Nn \l_@@_tmp_dim + { + \dim_max:nn + { \l_@@_bound_dim + \l_@@_reverse_bound_dim } + { \c_zero_dim } + } + \@@_save_punct_dim:nNNn { bound_width } #1 #1 { \l_@@_tmp_dim } + \dim_set:Nn \l_@@_tmp_dim + { + \str_case:nnTF {#1} + { { ^^^^2025 } { } { ^^^^2026 } { } } + { \c_zero_dim } + { -\l_@@_tmp_dim } + } + \@@_save_punct_dim:nNNn { kern } #1 #1 { \l_@@_tmp_dim } + \@@_save_punct_skip:nNNn { kern } #1 #1 { \l_@@_tmp_dim } + \dim_add:Nn \l_@@_tmp_dim + { \dim_max:nn { \l_@@_bound_dim } { \c_zero_dim } } + \@@_save_punct_dim:nNNn { bound_kern } #1 #1 { \l_@@_tmp_dim } + \@@_save_punct_skip:nNNn { bound_kern } #1 #1 { \l_@@_tmp_dim } + } +% \end{macrocode} +% \end{macro} +% % \begin{macro}[int]{\xeCJK_get_punct_kerning:NN} -% 标点挤压。 +% 标点压缩。 % \begin{macrocode} \cs_new_protected_nopar:Npn \xeCJK_get_punct_kerning:NN #1#2 { \tl_if_exist:cF { \@@_punct_csname:n { dim/kern/#1/#2 } } { \tl_if_eq:NNTF \l_xeCJK_punct_style_tl \c_@@_punct_style_plain_tl - { - \@@_save_punct_dim:nNNn { kern } #1 #2 { \c_zero_dim } - \@@_save_punct_dim:nNNn { break_kern } #1 #2 { \c_zero_dim } - \@@_save_punct_dim:nNNn { bound_kern } #1 #2 { \c_zero_dim } - \@@_save_punct_dim:nNNn { bound_width } #1 #2 { \c_zero_dim } - \@@_save_punct_skip:nNNn { kern } #1 #2 { \c_zero_skip } - \@@_save_punct_skip:nNNn { break_kern } #1 #2 { \c_zero_skip } - \@@_save_punct_skip:nNNn { bound_kern } #1 #2 { \c_zero_skip } - } - { - \UseInstance { xeCJK / punctuation } { \l_xeCJK_punct_style_tl } - \xeCJK_punct_kerning_process:NN #1 #2 - } + { \@@_save_punct_kerning_plain:NN } + { \@@_save_punct_kerning:NN } + #1 #2 } } \cs_new_protected_nopar:Npn \xeCJK_get_punct_kerning:oN { \exp_after:wN \xeCJK_get_punct_kerning:NN } +\cs_new_protected_nopar:Npn \@@_save_punct_kerning_plain:NN #1#2 + { + \@@_save_punct_dim:nNNn { kern } #1 #2 { \c_zero_dim } + \@@_save_punct_dim:nNNn { break_kern } #1 #2 { \c_zero_dim } + \@@_save_punct_dim:nNNn { bound_kern } #1 #2 { \c_zero_dim } + \@@_save_punct_dim:nNNn { bound_width } #1 #2 { \c_zero_dim } + \@@_save_punct_skip:nNNn { kern } #1 #2 { \c_zero_skip } + \@@_save_punct_skip:nNNn { break_kern } #1 #2 { \c_zero_skip } + \@@_save_punct_skip:nNNn { bound_kern } #1 #2 { \c_zero_skip } + } +\cs_new_protected_nopar:Npn \@@_save_punct_kerning:NN + { + \UseInstance { xeCJK / punctuation } { \l_xeCJK_punct_style_tl } + \xeCJK_punct_kerning_process:NN + } % \end{macrocode} % \end{macro} % @@ -5945,9 +6000,7 @@ Copyright and Licence % \end{macro} % % \begin{macro}[int]{\xeCJK_calc_punct_dimen:N} -% \changes{v3.4.3}{2016/10/27}{考虑破折号边界为负值的情况。} -% 计算标点的左右实际边距和实际尺寸。对于破折号,计算两标点之间的空白,保证它中间 -% 不被断开。注意,破折号的边界可能为负值(比如方正新书宋),此时不必压缩。 +% 计算标点的左右实际边距和实际尺寸。 % \begin{macrocode} \cs_new_protected_nopar:Npn \xeCJK_calc_punct_dimen:N #1 { @@ -5955,26 +6008,13 @@ Copyright and Licence { \xeCJK_glyph_bounds:NN \c_one #1 } \@@_save_punct_dim:nNNn { bound } \c_@@_right_tl #1 { \xeCJK_glyph_bounds:NN \c_three #1 } - \dim_set:Nn \l_@@_tmp_dim - { - ( \@@_use_punct_dim:nNN { bound } \c_@@_left_tl #1 ) + - ( \@@_use_punct_dim:nNN { bound } \c_@@_right_tl #1 ) - } \@@_save_punct_dim:nNn { width } #1 { \etex_fontcharwd:D \tex_font:D `#1 } \@@_save_punct_dim:nNn { dimen } #1 - { \@@_use_punct_dim:nN { width } #1 - \l_@@_tmp_dim } - \@@_punct_if_long:NT #1 { - \dim_set:Nn \l_@@_tmp_dim - { - \str_case:nnTF {#1} - { { ^^^^2025 } { } { ^^^^2026 } { } } - { \c_zero_dim } - { \dim_min:nn { - \l_@@_tmp_dim } { \c_zero_dim } } - } - \@@_save_punct_dim:nNNn { kern } #1 #1 { \l_@@_tmp_dim } - \@@_save_punct_skip:nNNn { kern } #1 #1 { \l_@@_tmp_dim } + ( \@@_use_punct_dim:nN { width } #1 ) - + ( \@@_use_punct_dim:nNN { bound } \c_@@_left_tl #1 ) - + ( \@@_use_punct_dim:nNN { bound } \c_@@_right_tl #1 ) } } % \end{macrocode} @@ -7797,7 +7837,7 @@ Copyright and Licence % \begin{macrocode} \cs_new_protected_nopar:Npn \xeCJK_visible_space: { - \bool_if:NT \l_@@_CJK_group_bool { \scan_stop: } + \xeCJK_make_boundary: \xeCJK_glyph_if_exist:NTF { ^^^^2423 } { ^^^^2423 } { @@ -7998,11 +8038,12 @@ Copyright and Licence \xeCJKsetwidth { ^^^^2013 } { 0.5 em } % \end{macrocode} % -% 执行宏包选项,并载入 \pkg{fontspec} 宏包和 \pkg{xunicode-addon}。 +% \changes{v3.7.0}{2018/03/16}{不再默认引入 \pkg{xunicode} 宏包。} +% +% 执行宏包选项,并载入 \pkg{fontspec} 宏包。 % \begin{macrocode} \ProcessKeysOptions { xeCJK / options } \RequirePackage { fontspec } [ 2012/05/01 ] -\RequirePackage { xunicode-addon } % \end{macrocode} % % \begin{variable}{\c_@@_encoding_tl} @@ -8323,21 +8364,10 @@ Copyright and Licence % \changes{v3.2.5}{2013/07/25}{解决 \pkg{fixltx2e} 和 \pkg{amsthm} 的冲突。} % \changes{v3.3.1}{2015/04/15}{删去 \pkg{fixltx2e} 和 \pkg{amsthm} 的冲突补丁。} % -% \begin{macro}[int]{\nobreakspace} % \changes{v3.1.2}{2013/01/01} % {修正非 \tn{UTFencname} 编码下面 \pkg{xunicode} 重定义的 \tn{nobreakspace} 会失效的问题。} % \changes{v3.2.5}{2013/07/18}{恢复 \tn{nobreakspace} 的原始定义。} -% 空格在 \TeX 中是特殊的记号,似乎不应该把它定义为字体中的符号(\texttt{U+00A0})。 -% \begin{macrocode} -\UndeclareTextCommand \nobreakspace { \UTFencname } -\RenewDocumentCommand \nobreakspace { } { \leavevmode \nobreak \ } -% \end{macrocode} -% \end{macro} -% -% 当符号命令紧跟在 CJK 字符类后面时,强制发生状态转移,使字体回到西文状态。 -% \begin{macrocode} -\AtBeginUTFCommand { \bool_if:NT \l_@@_CJK_group_bool { \scan_stop: } } -% \end{macrocode} +% \changes{v3.7.0}{2018/03/18}{对 \tn{nobreakspace} 的恢复放到 \pkg{xunicode-addon} 中处理。} % % \changes{v3.1.1}{2012/12/13}{对于与 \pkg{xltxtra} 的冲突给出错误警告。} % 比较老版本的 \pkg{realscripts} 定义了 \cs{dim_max:nn} 和 \cs{dim_min:nn},这与 @@ -8555,33 +8585,155 @@ Copyright and Licence % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_group_begin:,\@@_group_end:} +% \begin{macro}{\@@_inactive_group_begin:,\@@_inactive_group_end:} % 用于保护下面歧义宽度标点的分组。 % \begin{macrocode} -\cs_new_eq:NN \@@_group_begin: \group_begin: -\cs_new_eq:NN \@@_group_end: \group_end: +\cs_new_protected_nopar:Npn \@@_inactive_group_begin: + { \group_begin: \makexeCJKinactive } +\cs_new_eq:NN \@@_inactive_group_end: \group_end: % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\textellipsis} +% \begin{macro}{\@@_patch_text_command:} +% \begin{variable}{\c_@@_ambigious_char_prop} % 单独处理宽度有分歧的几个标点:包括省略号、破折号、间隔号、引号等中西文混用的 % 符号, 保证其命令形式输出的是西文字体。 +% 如果 \pkg{xunicode} 宏包被载入,则通过 \pkg{xunicode-addon} 处理。 % \begin{macrocode} -\tl_map_inline:nn +\prop_const_from_keyval:Nn \c_@@_ambigious_char_prop { - \textellipsis \textendash \textemdash \textperiodcentered - \textcentereddot \textquoteleft \textquoteright \textquotedblleft - \textquotedblright \textcdot \textgrq \textgrqq + "00B7 = \textperiodcentered \textcentereddot \textcdot , + "2013 = \textendash , + "2014 = \textemdash , + "2018 = \textquoteleft \textgrq , + "2019 = \textquoteright , + "201C = \textquotedblleft \textgrqq , + "201D = \textquotedblright , + "2025 = \texthdotfor , + "2026 = \textellipsis , + "2027 = \texthyphenationpoint , + "2E3A = \texttwoemdash } +\@@_at_end_preamble:n { \@@_patch_text_command: } +\cs_new_protected_nopar:Npn \@@_patch_text_command: { - \AtBeginUTFCommand [#1] { \@@_group_begin: \makexeCJKinactive } - \AtEndUTFCommand [#1] { \@@_group_end: } + \xeCJK_if_package_loaded:nTF { xunicode } + { \@@_patch_xunicode_ambigious_char: } + { + \exp_args:Nx \@@_patch_tuenc_ambigious_char:n + { \UnicodeEncodingName } + \@@_patch_tuenc_accent: + \@@_patch_tuenc_composite: + } + } +\cs_new_protected_nopar:Npn \@@_patch_xunicode_ambigious_char: + { + \RequirePackage { xunicode-addon } + \prop_map_inline:Nn \c_@@_ambigious_char_prop + { + \tl_map_inline:nn { ##2 } + { + \xunadd_set_begin_hook:nn { ####1 } + { \@@_inactive_group_begin: } + \xunadd_set_end_hook:nn { ####1 } + { \@@_inactive_group_end: } + } + } + \xunadd_append_begin_hook:n { \xeCJK_make_boundary: } + } +\cs_new_protected_nopar:Npn \@@_patch_tuenc_ambigious_char:n #1 + { + \prop_map_inline:Nn \c_@@_ambigious_char_prop + { + \tl_map_inline:nn { ##2 } + { + \cs_if_exist:NF ####1 + { \DeclareTextSymbol ####1 {#1} { ##1 } } + \@@_patch_ambigious_char:nN {#1} ####1 + } + } + } +\cs_new_protected_nopar:Npn \@@_patch_ambigious_char:nN #1#2 + { + \exp_args:Nx \@@_patch_ambigious_char:n + { #1 \token_to_str:N #2 } + } +\cs_new_protected_nopar:Npx \@@_patch_ambigious_char:nNn #1#2#3 + { + \exp_args:Nx \exp_not:N \@@_patch_ambigious_char:n + { + \c_backslash_str #1 + \exp_not:N \token_to_str:N #2 - + \exp_not:N \token_to_str:N #3 + } + } +\cs_new_protected_nopar:Npn \@@_patch_ambigious_char:n #1 + { + \cs_if_free:cF {#1} + { \exp_args:Nc \@@_patch_ambigious_char:N {#1} } + } +\cs_new_protected_nopar:Npn \@@_patch_ambigious_char:N #1 + { + \cs_set_protected_nopar:Npx #1 + { + \@@_ambigious_char:n + { \token_if_chardef:NTF #1 { \utex_char:D } { \exp_not:o } #1 } + } + } +\cs_new_protected_nopar:Npn \@@_ambigious_char:n #1 + { + \int_compare:nNnTF \xetex_interchartokenstate:D > \c_zero + { \@@_inactive_group_begin: #1 \@@_inactive_group_end: } + {#1} + } +% \end{macrocode} +% \end{variable} +% \end{macro} +% +% \begin{macro}{\@@_patch_tuenc_composite:} +% \tn{DeclareUnicodeComposite} 具有检查字符是否存在的功能, +% 当符号命令紧跟在 CJK 字符类后面时,需要使字体回到西文状态 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \xeCJK@composite@patch + { + \str_if_eq_x:nnT { \f@encoding } { \UnicodeEncodingName } + { \xeCJK_make_boundary: } + } +\cs_new_protected_nopar:Npn \@@_patch_tuenc_composite: + { + \cs_set_nopar:Npn \@text@composite@x ##1 + { + \xeCJK@composite@patch + \ifx ##1 \relax + \expandafter \@secondoftwo + \else + \expandafter \@firstoftwo + \fi + ##1 + } } % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_patch_Bxii:n} -% \begin{variable}{\l_@@_patch_Bxii_tl} +% \begin{macro}{\@@_patch_tuenc_accent:} +% \tn{add@unicode@accent} 定义最后用于截断数字展开的 \tn{relax} 会造成边界,可能会影响组合标记。 +% \begin{macrocode} +\group_begin: +\char_set_catcode_other:n { "A0 } +\cs_new_protected_nopar:Npn \@@_patch_tuenc_accent: + { + \cs_set_protected_nopar:Npn \add@unicode@accent ##1 ##2 + { + \tl_if_blank:nTF { ##2 } { ^^a0 } { ##2 } + \utex_char:D \etex_numexpr:D ##1 \scan_stop: + } + } +\group_end: +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_patch_middle_dot:} +% \begin{variable}{\c_@@_middle_dot_prop} % \changes{v3.2.9}{2013/12/08} % {完整处理 \file{encguide.pdf} 的编码符号表中,与旧编码的 \texttt{U+00B7} 冲突。} % 常被用作中文间隔号的 \texttt{U+00B7} 与 T1 等旧字体编码下定义的符号命令冲突。 @@ -8600,78 +8752,36 @@ Copyright and Licence % \DeclareTextSymbol{\textperiodcentered}{LY1}{183} % \end{verbatim} % LGR 编码的符号表有 \texttt{183} 号字符,但在 \file{lgrenc.def} 中未找到相应的 -% 符号命令,它的输入方式为 |>`w| 或者 |\accpsilivaria{w}|。前者比较特殊,如果 -% 与 \pkg{xeCJK} 一起使用,\XeTeX\ 会出现如下错误。 -% \begin{verbatim} -% ! Cannot use \xetex_glyphbounds:D with grmn1000; not a native platform font. -% \xeCJK_glyph_bounds:NN ...use:N \xetex_glyphbounds:D -% #1 \xetex_charglyph:D \xeCJK_... -% \end{verbatim} -% 这个不好处理,只修改后者。 +% 符号命令。 % \begin{macrocode} -\@@_after_end_preamble:n { \l_@@_patch_Bxii_tl } -\tl_new:N \l_@@_patch_Bxii_tl -\cs_new_protected_nopar:Npn \@@_patch_Bxii:nN #1#2 +\prop_const_from_keyval:Nn \c_@@_middle_dot_prop { - \tl_put_right:Nx \l_@@_patch_Bxii_tl - { \@@_patch_Bxii:n { #1 \token_to_str:N #2 } } + T2A = \cyrchvcrs , + T2B = \cyrchldsc , + T2C = \cyrabhha , + X2 = \cyrchldsc , + TS1 = \textperiodcentered , + LY1 = \textperiodcentered , + T1 = \r u , + T4 = \B t , + T5 = \` \ecircumflex } -\group_begin: -\cs_set:Npn \@@_tmp:w #1 +\@@_after_end_preamble:n { \@@_patch_middle_dot: } +\cs_new_protected_nopar:Npn \@@_patch_middle_dot: { - \group_end: - \cs_new_protected_nopar:Npn \@@_patch_Bxii:nNN ##1##2##3 - { - \tl_put_right:Nx \l_@@_patch_Bxii_tl - { - \@@_patch_Bxii:Nnn - #1 { ##1 \token_to_str:N ##2 } { \token_to_str:N ##3 } - } - } - } -\use:n - { - \char_set_catcode_other:N \\ - \@@_tmp:w + \prop_map_inline:Nn \c_@@_middle_dot_prop + { \@@_patch_middle_dot:nw { ##1 } ##2 \q_stop } + \@@_patch_ambigious_char:nNn { T5 } \` { \^ - e } } - { \ } -\cs_new_protected_nopar:Npn \@@_patch_Bxii:n #1 - { \cs_if_free:cF {#1} { \cs_gset_eq:cN {#1} \@@_Default_Bxii: } } -\cs_new_protected_nopar:Npn \@@_patch_Bxii:Nnn #1#2#3 - { \cs_if_free:cF {#2} { \cs_gset_eq:cN { #1#2 - #3 } \@@_Default_Bxii: } } -\group_begin: -\char_set_catcode_other:n { 183 } -\cs_new_protected_nopar:Npn \@@_Default_Bxii: +\cs_new_protected_nopar:Npn \@@_patch_middle_dot:nw #1#2#3 \q_stop { - \int_compare:nNnTF \xetex_interchartokenstate:D > \c_zero - { \@@_group_begin: \makexeCJKinactive ^^b7 \@@_group_end: } - { ^^b7 } - } -\group_end: -\clist_map_inline:nn - { - { T3 } \textvibyy , - { T2A } \cyrchvcrs , - { T2B } \cyrchldsc , - { T2C } \cyrabhha , - { X2 } \cyrchldsc , - { TS1 } \textperiodcentered , - { LY1 } \textperiodcentered - } - { \@@_patch_Bxii:nN #1 } -\clist_map_inline:nn - { - { T1 } \r u , - { T4 } \B t , - { T5 } \` \ecircumflex , - { LGR } \accpsilivaria w - } - { \@@_patch_Bxii:nNN #1 } -\tl_put_right:Nx \l_@@_patch_Bxii_tl - { - \@@_patch_Bxii:n - { \token_to_str:N \T 5 \token_to_str:N \` - \token_to_str:N \^ - e } + \tl_if_empty:nTF {#3} + { \@@_patch_ambigious_char:nN {#1} #2 } + { \@@_patch_ambigious_char:nNn {#1} #2 {#3} } } +% \end{macrocode} +% \pkg{pifont} 宏包的符号 |\ding{183}| 也有冲突。 +% \begin{macrocode} \@@_after_end_preamble:n { \xeCJK_if_package_loaded:nT { pifont } @@ -8688,15 +8798,15 @@ Copyright and Licence % \begin{macrocode} \@@_after_end_preamble:n { - \xeCJK_if_package_loaded:nT { hyperref } + \cs_if_exist_use:NT \pdfstringdefDisableCommands { - \pdfstringdefDisableCommands - { - \@@_gobble_CJKfamily: - \xeCJK_cs_clear:N \makexeCJKinactive - \xeCJK_cs_clear:N \@@_group_begin: - \xeCJK_cs_clear:N \@@_group_end: - } + { + \@@_gobble_CJKfamily: + \xeCJK_cs_clear:N \@@_inactive_group_begin: + \xeCJK_cs_clear:N \@@_inactive_group_end: + \xeCJK_cs_clear:N \makexeCJKinactive + \xeCJK_cs_clear:N \xeCJK@composite@patch + } } } % \end{macrocode} @@ -8781,39 +8891,20 @@ Copyright and Licence \str_if_eq:nnT {#1} { \CJK@UnicodeEnc } { \group_begin: - \cs_set_eq:NN \Unicode \@@_calc_unicode:nn - \cs_set_eq:NN \def \xeCJK_char_from_charcode:Nn + \cs_set_eq:NN \Unicode \xeCJK_unicode_char:nn + \cs_set_eq:NN \def \xdef #2 \group_end: - \tl_gset:Nn \CJK@tenthousand { ^^^^4e07 } - \tl_gset:Nn \CJK@hundredmillion { ^^^^4ebf } + \str_gset:Nx \CJK@tenthousand { ^^^^4e07 } + \str_gset:Nx \CJK@hundredmillion { ^^^^4ebf } \tl_if_exist:NF \CJK@UnicodeEnc { \tl_const:Nn \CJK@UnicodeEnc { UTF8 } } \cs_if_exist:NF \Unicode { \cs_new_eq:NN \Unicode \xeCJK_unicode_char:nn } } } -\cs_if_exist:NTF \utex_charcat:D - { - \cs_new_protected_nopar:Npn \xeCJK_char_from_charcode:Nn #1#2 - { \tl_const:Nx #1 { \char_generate:nn {#2} { \c_eleven } } } - } - { - \cs_new_protected_nopar:Npn \xeCJK_char_from_charcode:Nn #1#2 - { - \group_begin: - \char_set_lccode:nn { "4E00 } {#2} - \tex_lowercase:D - { - \group_end: - \tl_const:Nn #1 { ^^^^4e00 } - } - } - } -\cs_new_nopar:Npn \@@_calc_unicode:nn #1#2 - { (#1) * \c_two_hundred_fifty_six + (#2) } -\cs_new_protected_nopar:Npn \xeCJK_unicode_char:nn #1#2 - { \tex_char:D \etex_numexpr:D \@@_calc_unicode:nn {#1} {#2} \scan_stop: } +\cs_new_nopar:Npn \xeCJK_unicode_char:nn #1#2 + { \utex_char:D \etex_numexpr:D (#1) * 256 + (#2) \scan_stop: } % \end{macrocode} % \end{macro} % @@ -10744,8 +10835,8 @@ Copyright and Licence { \clist_get:NNF \g_@@_encname_clist \UTFencname { - \file_if_exist:nTF { tuenc.def } - { \tl_set:Nn \UTFencname { TU } } + \cs_if_exist:NTF \UnicodeEncodingName + { \tl_set:Nx \UTFencname { \UnicodeEncodingName } } { \sys_if_engine_xetex:TF { \tl_set:Nn \UTFencname { EU1 } } @@ -10939,8 +11030,8 @@ Copyright and Licence % \begin{macrocode} \RenewDocumentCommand \DeclareUTFcharacter { O { \UTFencname } m m } { - \str_if_eq:nnTF {#3} { \hbar } - { \@@_restore_hbar: } + \cs_if_exist_use:cF + { @@_restore_ \tl_to_str:n {#3} : } { \@@_if_csname:nTF {#3} { \@@_declare_character:Nnn #3 } @@ -10951,38 +11042,42 @@ Copyright and Licence % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_restore_hbar:} -% 恢复 \tn{hbar} 为原本定义。 +% \begin{macro}{\@@_restore_cmd:N} +% 恢复 \tn{hbar} 和 \tn{nobreakspace} 为原本定义。 % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_restore_hbar: +\cs_new_protected_nopar:cpn + { @@_restore_ \tl_to_str:n { \hbar } : } + { \@@_restore_cmd:N \hbar } +\cs_new_protected_nopar:cpn + { @@_restore_ \tl_to_str:n { \nobreakspace } : } + { \@@_restore_cmd:N \nobreakspace } +\cs_new_protected_nopar:Npn \@@_restore_cmd:N #1 + { \@@_restore_cmd:Nx #1 { ? - \token_to_str:N #1 } } +\cs_new_protected_nopar:Npn \@@_restore_cmd:Nn #1#2 { - \cs_if_free:cF { ? - \token_to_str:N \hbar } - { \@@_restore_hbar:c { ? - \token_to_str:N \hbar } } + \cs_if_free:cF {#2} + { \@@_restore_cmd:Nc #1 {#2} } } -\cs_new_protected_nopar:Npn \@@_restore_hbar:N #1 +\cs_new_protected_nopar:Npn \@@_restore_cmd:NN #1#2 { - \cs_gset_eq:NN \hbar #1 - \cs_undefine:N #1 + \cs_gset_eq:NN #1 #2 + \cs_undefine:N #2 } -\cs_generate_variant:Nn \@@_restore_hbar:N { c } +\cs_generate_variant:Nn \@@_restore_cmd:Nn { Nx } +\cs_generate_variant:Nn \@@_restore_cmd:NN { Nc } % \end{macrocode} % \end{macro} % % \begin{macro}{\@@_declare_character:Nnn} -% 通过 \texttt{lowercase} 技巧,直接由 Unicode |#3| 得到编码 |#2| 下的符号命令 +% 通过 \cs{utex_char:D} 直接由 Unicode |#3| 得到编码 |#2| 下的符号命令 % |#1| 对应的实际字符。\tn{DeclareUTFSymbol} 的参数格式与 \tn{DeclareTextSymbol} % 完全一致。 % \begin{macrocode} \cs_new_protected:Npn \@@_declare_character:Nnn #1#2#3 { \@@_provide_text_command_default:N #1 - \group_begin: - \char_set_lccode:nn { `0 } { \@@_check_slot:n {#3} } - \tex_lowercase:D - { - \group_end: - \@@_declare_character:NNxn 0 - } + \exp_after:wN \@@_declare_character:NNxn + \utex_char:D \@@_check_slot:n {#3} \exp_stop_f: #1 { \token_to_str:N #1 } {#2} } \cs_generate_variant:Nn \@@_declare_character:Nnn { c } @@ -11236,18 +11331,13 @@ Copyright and Licence % \end{macro} % % \begin{macro}{\@@_declare_encoded:NNnnn} -% 通过 \texttt{lowercase} 技巧,直接由重音符号的 Unicode 得到实际字符。 +% 通过 \cs{utex_char:D} 直接由重音符号的 Unicode 得到实际字符。 % \begin{macrocode} \cs_new_protected:Npn \@@_declare_encoded:NNnnn #1#2#3#4#5 { - \group_begin: - \char_set_lccode:nn { `4 } { \@@_check_slot:n {#4} } - \char_set_lccode:nn { `5 } { \@@_check_slot:n {#5} } - \tex_lowercase:D - { - \group_end: - \@@_declare_encoded:NNNNxx 4 5 - } + \exp_after:wN \@@_declare_encoded:NNNNxx + \utex_char:D \@@_check_slot:n {#4} \exp_after:wN \exp_stop_f: + \utex_char:D \@@_check_slot:n {#5} \exp_stop_f: #1 #2 { \token_to_str:N #2 } {#3} } \cs_new_protected:Npn \@@_declare_encoded:NNNNnn #1#2#3#4#5#6 @@ -11497,28 +11587,39 @@ Copyright and Licence \tl_if_blank:nTF {#2} { \IfBooleanTF {#1} - { \tl_set:Nn \l_@@_begin_hook_tl {#3} } - { \tl_put_right:Nn \l_@@_begin_hook_tl {#3} } + { \xunadd_set_begin_hook:n } + { \xunadd_append_begin_hook:n } } - { \@@_set_cmd_hook:nnn { begin } {#2} {#3} } + { \xunadd_set_begin_hook:nn {#2} } } \NewDocumentCommand \AtEndUTFCommand { s O { } +m } { \tl_if_blank:nTF {#2} { \IfBooleanTF {#1} - { \tl_set:Nn \l_@@_end_hook_tl {#3} } - { \tl_put_right:Nn \l_@@_end_hook_tl {#3} } + { \xunadd_set_end_hook:n } + { \xunadd_append_end_hook:n } } - { \@@_set_cmd_hook:nnn { end } {#2} {#3} } + { \xunadd_set_begin_hook:nn {#2} } + {#3} } -\tl_new:N \l_@@_begin_hook_tl -\tl_new:N \l_@@_end_hook_tl % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_set_cmd_hook:nnn} +% \begin{macro}[int]{\xunadd_set_begin_hook:n,\xunadd_set_end_hook:n} % \begin{macrocode} +\cs_new_protected_nopar:Npn \xunadd_set_begin_hook:n + { \tl_set:Nn \l_@@_begin_hook_tl } +\cs_new_protected_nopar:Npn \xunadd_append_begin_hook:n + { \tl_put_right:Nn \l_@@_begin_hook_tl } +\cs_new_protected_nopar:Npn \xunadd_set_end_hook:n + { \tl_set:Nn \l_@@_end_hook_tl } +\cs_new_protected_nopar:Npn \xunadd_append_end_hook:n + { \tl_put_right:Nn \l_@@_end_hook_tl } +\cs_new_protected_nopar:Npn \xunadd_set_begin_hook:nn + { \@@_set_cmd_hook:nnn { begin } } +\cs_new_protected_nopar:Npn \xunadd_set_end_hook:nn + { \@@_set_cmd_hook:nnn { end } } \cs_new_protected:Npn \@@_set_cmd_hook:nnn #1#2#3 { \cs_set_protected:cpn @@ -11533,6 +11634,8 @@ Copyright and Licence { \use:c { @@_#3_csname:n } { \token_to_str:N #1 - \tl_to_str:n {#2} } } \cs_new_nopar:Npn \@@_begin_csname:n #1 { @@_begin_#1_hook:n } \cs_new_nopar:Npn \@@_end_csname:n #1 { @@_end_#1_hook:n } +\tl_new:N \l_@@_begin_hook_tl +\tl_new:N \l_@@_end_hook_tl % \end{macrocode} % \end{macro} % @@ -11590,6 +11693,14 @@ Copyright and Licence %<*xunextra> % \end{macrocode} % +% \changes{v3.7.0}{2018/03/16}{补充定义 \tn{texthyphenationpoint} 和 \tn{texttwoemdash}。} +% +% 我们补充定义 HYPHENATION POINT 和 TWO-EM DASH,他们默认被归入 CJK 标点符号。 +% \begin{macrocode} +\DeclareUTFSymbol\texthyphenationpoint{"2027} +\DeclareUTFSymbol\texttwoemdash{"2E3A} +% \end{macrocode} +% % 以下内容选自 \pkg{xunicode},并做了适当修改。 % \begin{macrocode} \DeclareUTFComposite\textsuperscript -- cgit v1.2.3