%% %% This is file `xeCJK.sty', %% generated with the docstrip utility. %% %% The original source files were: %% %% xeCJK.dtx (with options: `package') %% %% Copyright (C) 2007--2010 by Wenchang Sun %% Copyright (C) 2009--2016 by Leo Liu %% Copyright (C) 2012--2016 by Qing Lee %% ---------------------------------------------------------------------- %% %% This work may be distributed and/or modified under the %% conditions of the LaTeX Project Public License, either %% version 1.3c of this license or (at your option) any later %% version. This version of this license is in %% http://www.latex-project.org/lppl/lppl-1-3c.txt %% and the latest version of this license is in %% http://www.latex-project.org/lppl.txt %% and version 1.3 or later is part of all distributions of %% LaTeX version 2005/12/01 or later. %% %% This work has the LPPL maintenance status `maintained'. %% %% The Current Maintainers of this work are Leo Liu and Qing Lee. %% %% ---------------------------------------------------------------------- %% \NeedsTeXFormat{LaTeX2e} \RequirePackage{expl3} \GetIdInfo$Id: xeCJK.dtx 10a8836 2016-08-27 11:02:24 +0800 Qing Lee $ {Typesetting CJK scripts with XeLaTeX} \ProvidesExplPackage{\ExplFileName} {\ExplFileDate}{3.4.1}{\ExplFileDescription} \msg_new:nnn { xeCJK } { Require-XeTeX } { The~xeCJK~package~requires~XeTeX~to~function.\\\\ You~must~change~your~typesetting~engine~to~"xelatex" \\ instead~of~plain~"latex"~or~"pdflatex"~or~"lualatex".\\ Loading~xeCJK~will~abort! } \sys_if_engine_xetex:F { \msg_critical:nn { xeCJK } { Require-XeTeX } } \msg_new:nnn { xeCJK } { l3-too-old } { Support~package~`#1'~too~old. \\\\ Please~update~an~up~to~date~version~of~the~bundles\\\\ `l3kernel'~and~`l3packages'\\\\ using~your~TeX~package~manager~or~from~CTAN.\\ \str_if_eq:nnT {#1} { expl3 } { Loading~xeCJK~will~abort! } } \@ifpackagelater { expl3 } { 2015/09/24 } { } { \msg_critical:nnn { xeCJK } { l3-too-old } { expl3 } } \prg_new_conditional:Npnn \xeCJK_if_package_loaded:n #1 { p , T , F , TF } { \tl_if_exist:cTF { ver@ #1 . \c__xeCJK_package_ext_tl } { \prg_return_true: } { \prg_return_false: } } \tl_const:Nx \c__xeCJK_package_ext_tl { \@pkgextension } \msg_new:nnn { xeCJK } { incompatible-package } { The~`#1'~package~and~xeCJK~are~incompatible.\\\\ Please~do~not~use~it. } \msg_new:nnn { xeCJK } { after-package } { The~`#1'~package~and~xeCJK~are~incompatible.\\\\ Please~load~it~after~xeCJK. } \clist_map_inline:nn { CJKfntef , CJKnumb } { \xeCJK_if_package_loaded:nT {#1} { \msg_error:nnn { xeCJK } { after-package } {#1} } } \clist_map_inline:nn { CJKulem , CJKvert , CJKpunct , CJKutf8 , CJK } { \xeCJK_if_package_loaded:nTF {#1} { \msg_error:nnn { xeCJK } { incompatible-package } {#1} } { \tl_const:cn { ver@ #1 . \c__xeCJK_package_ext_tl } { 9999/99/99 } } } \RequirePackage { xtemplate } \@ifpackagelater { xtemplate } { 2012/11/10 } { } { \msg_error:nnn { xeCJK } { l3-too-old } { xtemplate } } \RequirePackage { xparse , l3keys2e } \tl_new:N \l__xeCJK_tmp_tl \int_new:N \l__xeCJK_tmp_int \box_new:N \l__xeCJK_tmp_box \dim_new:N \l__xeCJK_tmp_dim \bool_new:N \l__xeCJK_tmp_bool \skip_new:N \l__xeCJK_tmp_skip \clist_new:N \l__xeCJK_tmp_clist \cs_new_protected_nopar:Npn \__xeCJK_msg_new:nn { \msg_new:nnn { xeCJK } } \cs_new_protected_nopar:Npn \__xeCJK_msg_new:nnn { \msg_new:nnnn { xeCJK } } \cs_new_protected_nopar:Npn \__xeCJK_error:n { \msg_error:nn { xeCJK } } \cs_new_protected_nopar:Npn \__xeCJK_error:nx { \msg_error:nnx { xeCJK } } \cs_new_protected_nopar:Npn \__xeCJK_warning:n { \msg_warning:nn { xeCJK } } \cs_new_protected_nopar:Npn \__xeCJK_warning:nx { \msg_warning:nnx { xeCJK } } \cs_new_protected_nopar:Npn \__xeCJK_warning:nxx { \msg_warning:nnxx { xeCJK } } \cs_new_protected_nopar:Npn \__xeCJK_warning:nxxx { \msg_warning:nnxxx { xeCJK } } \cs_new_protected_nopar:Npn \__xeCJK_info:nxx { \msg_info:nnxx { xeCJK } } \cs_new_protected_nopar:Npn \xeCJK_allow_break: { \tex_penalty:D \c_zero } \cs_new_protected_nopar:Npn \xeCJK_no_break: { \tex_penalty:D \c_ten_thousand } \tl_new:N \g__xeCJK_at_end_preamble_hook_tl \tl_new:N \g__xeCJK_after_preamble_hook_tl \tl_new:N \g__xeCJK_after_end_preamble_hook_tl \cs_new_protected:Npn \__xeCJK_at_end_preamble:n #1 { \tl_gput_right:Nn \g__xeCJK_at_end_preamble_hook_tl {#1} } \cs_new_protected:Npn \__xeCJK_after_preamble:n #1 { \tl_gput_right:Nn \g__xeCJK_after_preamble_hook_tl {#1} } \cs_new_protected:Npn \__xeCJK_after_end_preamble:n #1 { \tl_gput_right:Nn \g__xeCJK_after_end_preamble_hook_tl {#1} } \xeCJK_if_package_loaded:nTF { etoolbox } { \AtEndPreamble { \g__xeCJK_at_end_preamble_hook_tl } \AfterPreamble { \g__xeCJK_after_preamble_hook_tl } \AfterEndPreamble { \g__xeCJK_after_end_preamble_hook_tl } } { \AtBeginDocument { \g__xeCJK_after_preamble_hook_tl } \cs_new_protected_nopar:Npn \xeCJK@document@left@hook { \group_end: \g__xeCJK_at_end_preamble_hook_tl \group_begin: } \cs_new_protected_nopar:Npn \xeCJK@document@right@hook { \scan_stop: \g__xeCJK_after_end_preamble_hook_tl \tex_ignorespaces:D } \cs_gset_nopar:Npx \document { \xeCJK@document@left@hook \exp_not:o { \document } \xeCJK@document@right@hook } } \__xeCJK_after_preamble:n { \tl_put_right:Nn \@begindvi { \xeCJK@first@begindvi } } \cs_new_protected_nopar:Npn \xeCJK@first@begindvi { \xeCJKShipoutHook \cs_if_exist:NTF \@begindvi { \tl_gput_right:Nn } { \tl_const:Nn } \@begindvi { \xeCJKShipoutHook } } \NewDocumentCommand \xeCJKShipoutHook { } { \bool_if:NF \l__xeCJK_shipout_hook_bool { \bool_set_true:N \l__xeCJK_shipout_hook_bool \tl_use:N \l__xeCJK_shipout_hook_tl } } \cs_new_protected:Npn \xeCJK_add_to_shipout:n { \tl_put_right:Nn \l__xeCJK_shipout_hook_tl } \tl_new:N \l__xeCJK_shipout_hook_tl \bool_new:N \l__xeCJK_shipout_hook_bool \cs_new_nopar:Npn \xeCJK_reverse:nnn #1#2#3 { \str_if_eq_x:nnTF {#1} {#2} {#3} {#2} } \cs_new_protected_nopar:Npn \xeCJK_tl_remove_outer_braces:N #1 { \tl_set:Nx #1 { \exp_args:NV \xeCJK_tl_remove_outer_braces:n #1 } } \cs_new:Npn \xeCJK_tl_remove_outer_braces:n #1 { \exp_last_unbraced:Nf \__xeCJK_tl_remove_outer_braces:w { \tl_trim_spaces:n {#1} } \s__stop } \cs_new:Npn \__xeCJK_tl_remove_outer_braces:w #1 \s__stop { \bool_if:nTF { \tl_if_single_p:n {#1} && ! ( \tl_if_head_is_N_type_p:n {#1} ) } { \xeCJK_tl_remove_outer_braces:n {#1} } { \tl_trim_spaces:n {#1} } } \cs_new_protected:Npn \xeCJK_cs_clear:N #1 { \cs_set_eq:NN #1 \prg_do_nothing: } \cs_new_protected:Npn \xeCJK_cs_gclear:N #1 { \cs_gset_eq:NN #1 \prg_do_nothing: } \cs_new_protected:Npn \xeCJK_swap_cs:NN #1#2 { \cs_set_eq:NN \__xeCJK_swap_cs_aux:w #1 \cs_set_eq:NN #1 #2 \cs_set_eq:NN #2 \__xeCJK_swap_cs_aux:w \cs_undefine:N \__xeCJK_swap_cs_aux:w } \cs_new_protected_nopar:Npn \xeCJK_font_gset_to_current:c #1 { \exp_after:wN \cs_gset_eq:NN \cs:w #1 \exp_after:wN \cs_end: \tex_the:D \tex_font:D } \prg_new_conditional:Npnn \xeCJK_glyph_if_exist:N #1 { p , T , F , TF } { \etex_iffontchar:D \tex_font:D `#1 \exp_stop_f: \prg_return_true: \else: \prg_return_false: \fi: } \tl_const:Nn \c_xeCJK_space_skip_tl { \int_compare:nNnTF \g__xeCJK_spacefactor_int = \c_one_thousand { \skip_if_eq:nnTF \tex_spaceskip:D \c_zero_skip { \tex_fontdimen:D \c_two \tex_font:D plus \tex_fontdimen:D \c_three \tex_font:D minus \tex_fontdimen:D \c_four \tex_font:D } { \tex_spaceskip:D } } { \skip_if_eq:nnTF \tex_spaceskip:D \c_zero_skip { \int_compare:nNnTF \g__xeCJK_spacefactor_int < { 2000 } { \__xeCJK_space_skip_scale:nnn { \tex_fontdimen:D \c_two \tex_font:D } } { \skip_if_eq:nnTF \tex_xspaceskip:D \c_zero_skip { \__xeCJK_space_skip_scale:nnn { \tex_fontdimen:D \c_two \tex_font:D + \tex_fontdimen:D \c_seven \tex_font:D } } { \tex_xspaceskip:D \use_none:nn } } { \tex_fontdimen:D \c_three \tex_font:D } { \tex_fontdimen:D \c_four \tex_font:D } } { \int_compare:nNnTF \g__xeCJK_spacefactor_int < { 2000 } { \__xeCJK_space_skip_scale:nnn { \tex_spaceskip:D } } { \skip_if_eq:nnTF \tex_xspaceskip:D \c_zero_skip { \__xeCJK_space_skip_scale:nnn { \tex_spaceskip:D + \tex_fontdimen:D \c_seven \tex_font:D } } { \tex_xspaceskip:D \use_none:nn } } { \etex_gluestretch:D \tex_spaceskip:D } { \etex_glueshrink:D \tex_spaceskip:D } } } } \cs_new_nopar:Npn \__xeCJK_space_skip_scale:nnn #1#2#3 { \dim_eval:n {#1} plus \fp_eval:n { \g__xeCJK_spacefactor_int / 1000 } #2 minus \int_div_truncate:nn { 1000 * \tex_number:D #3 } { \g__xeCJK_spacefactor_int } sp } \int_new:N \g__xeCJK_spacefactor_int \int_gset_eq:NN \g__xeCJK_spacefactor_int \c_one_thousand \cs_new_protected_nopar:Npn \xeCJK_glue_to_skip:nN #1#2 { \group_begin: \hbox_set:Nw \l__xeCJK_tmp_box #1 \scan_stop: \int_compare:nNnTF \etex_lastnodetype:D = \c_eleven { \exp_after:wN \hbox_set_end: \exp_after:wN \group_end: \exp_after:wN \skip_set:Nn \exp_after:wN #2 \exp_after:wN { \skip_use:N \tex_lastskip:D } } { \hbox_set_end: \exp_after:wN \group_end: \exp_after:wN \skip_set:Nn \exp_after:wN #2 \exp_after:wN { \dim_use:N \box_wd:N \l__xeCJK_tmp_box } } } \prg_new_conditional:Npnn \xeCJK_if_blank_x:n #1 { p , T , F , TF } { \if_case:w \pdftex_strcmp:D { } {#1} \exp_stop_f: \prg_return_true: \else: \if_case:w \pdftex_strcmp:D { ~ } {#1} \exp_stop_f: \prg_return_true: \else: \prg_return_false: \fi: \fi: } \cs_new_protected:Npn \xeCJK_int_until_do:nn #1#2 { \__xeCJK_int_until_do:wn \use_none:n { \reverse_if:N \if_int_compare:w #1#2 } } \cs_new_protected:Npn \__xeCJK_int_until_do:wn \use_none:n #1 { #1 \exp_after:wN \__xeCJK_int_until_do:wn \fi: \use_none:n {#1} } \int_new:N \l__xeCJK_begin_int \int_new:N \l__xeCJK_end_int \cs_new_protected:Npn \xeCJK_peek_catcode_ignore_spaces:NTF #1#2#3 { \cs_set_eq:NN \l__peek_search_token #1 \scan_stop: \tl_set:Nn \__xeCJK_peek_catcode_true:w { \group_align_safe_end: #2 } \tl_set:Nn \__xeCJK_peek_catcode_false:w { \group_align_safe_end: #3 } \bool_set_false:N \l__xeCJK_peek_ignore_spaces_bool \group_align_safe_begin: \peek_after:Nw \__xeCJK_peek_catcode_ignore_spaces_branches:w } \cs_new_protected_nopar:Npn \__xeCJK_peek_catcode_ignore_spaces_branches:w { \if_meaning:w \l_peek_token \c_space_token \bool_set_true:N \l__xeCJK_peek_ignore_spaces_bool \exp_after:wN \peek_after:Nw \exp_after:wN \__xeCJK_peek_catcode_ignore_spaces_branches:w \tex_romannumeral:D 0 \else: \if_catcode:w \exp_not:N \l_peek_token \exp_not:N \l__peek_search_token \exp_after:wN \exp_after:wN \exp_after:wN \__xeCJK_peek_catcode_true:w \else: \exp_after:wN \exp_after:wN \exp_after:wN \__xeCJK_peek_catcode_false:w \fi: \fi: } \tl_new:N \__xeCJK_peek_catcode_true:w \tl_new:N \__xeCJK_peek_catcode_false:w \bool_new:N \l__xeCJK_peek_ignore_spaces_bool \cs_new_protected:Npn \xeCJK_peek_after_ignore_spaces:nw #1 { \tl_set:Nn \__xeCJK_peek_after_do:w { \group_align_safe_end: #1 } \group_align_safe_begin: \peek_after:Nw \__xeCJK_peek_ignore_spaces_branches:w } \cs_new_protected_nopar:Npn \__xeCJK_peek_ignore_spaces_branches:w { \if_meaning:w \l_peek_token \c_space_token \exp_after:wN \peek_after:Nw \exp_after:wN \__xeCJK_peek_ignore_spaces_branches:w \tex_romannumeral:D 0 \else: \exp_after:wN \__xeCJK_peek_after_do:w \fi: } \cs_new_nopar:Npn \xeCJK_token_value_class:N #1 { \xetex_charclass:D \xeCJK_token_value_charcode:N #1 } \cs_new_nopar:Npn \xeCJK_token_value_charcode:N #1 { \exp_after:wN \__xeCJK_get_charcode:w \token_to_meaning:N #1 \q_stop } \group_begin: \cs_set:Npn \__xeCJK_tmp:w #1 ~ #2 ~ #3#4#5 \q_stop { \tl_if_empty:nTF { #4#5 } { \cs_new_nopar:Npn \__xeCJK_get_charcode:w ##1 ~ ##2 ~ ##3 \q_stop { \int_eval:n { `##3 } } } { \tl_if_empty:nTF {#5} { \cs_new_nopar:Npn \__xeCJK_get_charcode:w ##1 ~ ##2 ~ ##3##4 \q_stop { \int_eval:n { \tl_if_empty:nTF { ##4 } { `##3 } { ( `##3 - "D800 ) * "400 + ( `##4 - "DC00 ) + "10000 } } } } { \cs_new_nopar:Npn \__xeCJK_get_charcode:w ##1 ~ ##2 ~ ##3##4 \q_stop { \int_eval:n { \tl_if_empty:nTF { ##4 } { `##3 } { "20000 } } } } } } \exp_after:wN \__xeCJK_tmp:w \token_to_meaning:N ^^^^^20000 { } \q_stop \group_end: \prg_new_conditional:Npnn \xeCJK_if_CJK_class:N #1 { p , T , F , TF } { \if_cs_exist:w \__xeCJK_CJK_class_tl:n { \xeCJK_token_value_class:N #1 } \cs_end: \prg_return_true: \else: \prg_return_false: \fi: } \cs_new_nopar:Npn \__xeCJK_CJK_class_tl:n #1 { c__xeCJK_CJK_class_ \int_eval:n {#1} _tl } \cs_generate_variant:Nn \__xeCJK_CJK_class_tl:n { c } \prg_new_conditional:Npnn \xeCJK_if_same_class:NN #1#2 { p , T , F , TF } { \if_int_compare:w \xeCJK_token_value_class:N #1 = \xeCJK_token_value_class:N #2 \exp_stop_f: \prg_return_true: \else: \prg_return_false: \fi: } \keys_define:nn { xeCJK / options } { xeCJKactive .choice: , xeCJKactive / true .code:n = { \makexeCJKactive } , xeCJKactive / false .code:n = { \makexeCJKinactive } , xeCJKactive .default:n = { true } } \NewDocumentCommand \makexeCJKactive { } { \xetex_interchartokenstate:D = \c_one } \NewDocumentCommand \makexeCJKinactive { } { \xetex_interchartokenstate:D = \c_zero } \char_set_catcode_ignore:n { "FEFF } \seq_new:N \g__xeCJK_class_seq \seq_new:N \g__xeCJK_new_class_seq \cs_new_protected_nopar:Npn \xeCJK_new_class:n #1 { \int_if_exist:cTF { \__xeCJK_class_csname:n {#1} } { \__xeCJK_error:nx { class-already-defined } {#1} } { \exp_args:Nc \newXeTeXintercharclass { \__xeCJK_class_csname:n {#1} } \clist_new:c { g__xeCJK_#1_range_clist } \seq_gput_right:Nn \g__xeCJK_class_seq {#1} \seq_gput_right:Nv \g__xeCJK_new_class_seq { \__xeCJK_class_csname:n {#1} } } } \cs_new_protected_nopar:Npn \xeCJK_save_class:nn #1#2 { \int_if_exist:cTF { \__xeCJK_class_csname:n {#1} } { \__xeCJK_error:nx { class-already-defined } {#1} } { \int_const:cn { \__xeCJK_class_csname:n {#1} } {#2} \clist_new:c { g__xeCJK_#1_range_clist } \seq_gput_right:Nn \g__xeCJK_class_seq {#1} } } \cs_new_nopar:Npn \__xeCJK_class_csname:n #1 { c__xeCJK_#1_class_int } \cs_new_eq:cN { \__xeCJK_class_csname:n { Others } } \l__xeCJK_tmp_int \__xeCJK_msg_new:nn { class-already-defined } { XeTeX~character~class~`#1'~has~been~already~defined.\\\\ Please~take~another~name. \\ } \xeCJK_save_class:nn { Default } { \c_zero } \tl_set:Nx \l__xeCJK_tmp_tl { \int_use:N \xetex_XeTeXversion:D \xetex_XeTeXrevision:D } \fp_compare:nNnTF { \l__xeCJK_tmp_tl } > { 0.99993 } { \xeCJK_save_class:nn { Boundary } { 4095 } } { \xeCJK_save_class:nn { Boundary } { \c_two_hundred_fifty_five } } \int_compare:nNnTF { \xetex_charclass:D "4E00 } = \c_one { \xeCJK_save_class:nn { CJK } { \c_one } \xeCJK_save_class:nn { FullLeft } { \c_two } \xeCJK_save_class:nn { FullRight } { \c_three } \int_const:Nn \c__xeCJK_class_begin_int { \c_three } } { \xeCJK_new_class:n { CJK } \xeCJK_new_class:n { FullLeft } \xeCJK_new_class:n { FullRight } \int_const:Nn \c__xeCJK_class_begin_int { \c_zero } } \xeCJK_new_class:n { HalfLeft } \xeCJK_new_class:n { HalfRight } \xeCJK_new_class:n { NormalSpace } \xeCJK_new_class:n { CM } \xeCJK_new_class:n { HangulJamo } \clist_const:Nn \c__xeCJK_HalfLeft_chars_clist { "28 , "5B , "60 , "7B , "2329 } \clist_const:Nn \c__xeCJK_HalfRight_chars_clist { "21 , "22 , "25 , "27 , "29 , "2C , "2E , "3A , "3B , "3F , "5D , "7D , "232A } \clist_const:Nn \c__xeCJK_NormalSpace_chars_clist { "2D , "2F , "5C } \clist_const:Nn \c__xeCJK_OP_chars_clist { "2018 , "201C , "3008 , "300A , "300C , "300E , "3010 , "3014 , "3016 , "3018 , "301A , "301D , "FE17 , "FE35 , "FE37 , "FE39 , "FE3B , "FE3D , "FE3F , "FE41 , "FE43 , "FE47 , "FE59 , "FE5B , "FE5D , "FF08 , "FF3B , "FF5B , "FF5F , "FF62 } \clist_const:Nn \c__xeCJK_PR_chars_clist { "FE69 , "FF04 , "FFE1 , "FFE5 , "FFE6 } \clist_const:Nx \c__xeCJK_FullLeft_chars_clist { \c__xeCJK_OP_chars_clist , \c__xeCJK_PR_chars_clist } \clist_const:Nn \c__xeCJK_CL_chars_clist { "00B7 , "2019 , "201D , "2013 , "2014 , "2025 , "2026 , "2027 , "3001 , "3002 , "3009 , "300B , "300D , "300F , "3011 , "3015 , "3017 , "3019 , "301B , "301E , "301F , "FE11 , "FE12 , "FE18 , "FE36 , "FE38 , "FE3A , "FE3C , "FE3E , "FE40 , "FE42 , "FE44 , "FE48 , "FE50 , "FE52 , "FE5A , "FE5C , "FE5E , "FF09 , "FF0C , "FF0E , "FF3D , "FF5D , "FF60 , "FF61 , "FF63 , "FF64 } \clist_const:Nn \c__xeCJK_hyphens_chars_clist { "301C , "30A0 } \clist_const:Nn \c__xeCJK_iteration_marks_chars_clist { "3005 , "303B , "309D , "309E , "30FD , "30FE } \clist_const:Nn \c__xeCJK_NS_chars_clist { "30FB , "FE54 , "FE55 , "FF1A , "FF1B , "FF65 , "16FE0 } \clist_const:Nn \c__xeCJK_EX_chars_clist { "FE15 , "FE16 , "FE56 , "FE57 , "FF01 , "FF1F } \clist_const:Nn \c__xeCJK_IS_chars_clist { "FE10 , "FE13 , "FE14 } \clist_const:Nn \c__xeCJK_CJ_chars_clist { "3041 , "3043 , "3045 , "3047 , "3049 , "3063 , "3083 , "3085 , "3087 , "308E , "3095 , "3096 , "30A1 , "30A3 , "30A5 , "30A7 , "30A9 , "30C3 , "30E3 , "30E5 , "30E7 , "30EE , "30F5 , "30F6 , "30FC , "31F0 , "31F1 , "31F2 , "31F3 , "31F4 , "31F5 , "31F6 , "31F7 , "31F8 , "31F9 , "31FA , "31FB , "31FC , "31FD , "31FE , "31FF , "FF67 , "FF68 , "FF69 , "FF6A , "FF6B , "FF6C , "FF6D , "FF6E , "FF6F , "FF70 } \clist_const:Nn \c__xeCJK_PO_chars_clist { "FE6A , "FF05 , "FFE0 } \clist_const:Nx \c__xeCJK_FullRight_chars_clist { \c__xeCJK_CL_chars_clist , \c__xeCJK_NS_chars_clist , \c__xeCJK_EX_chars_clist , \c__xeCJK_IS_chars_clist , \c__xeCJK_PO_chars_clist } \clist_const:Nn \c__xeCJK_CJK_chars_clist { "2E80 -> "2EFF , "2F00 -> "2FDF , "2FF0 -> "2FFF , "3000 -> "303F , "3040 -> "309F , "30A0 -> "30FF , "3100 -> "312F , "3130 -> "318F , "3190 -> "319F , "31A0 -> "31BF , "31C0 -> "31EF , "31F0 -> "31FF , "3200 -> "32FF , "3300 -> "33FF , "3400 -> "4DBF , "4DC0 -> "4DFF , "4E00 -> "9FFF , "A000 -> "A48F , "A490 -> "A4CF , "AC00 -> "D7AF , "F900 -> "FAFF , "FE10 -> "FE1F , "FE30 -> "FE4F , "FF00 -> "FFEF , "16FE0 -> "16FFF , "17000 -> "187FF , "18800 -> "18AFF , "1B000 -> "1B0FF , "1F200 -> "1F2FF , "20000 -> "2A6DF , "2A700 -> "2B73F , "2B740 -> "2B81F , "2B820 -> "2CEA1 , "2F800 -> "2FA1F } \clist_const:Nn \c__xeCJK_CM_chars_clist { "302A -> "302F , "3099 -> "309A , "FE00 -> "FE0F , "E0100 -> "E01EF } \clist_const:Nn \c__xeCJK_HangulJamo_chars_clist { "1100 -> "11FF , "A960 -> "A97F , "D7B0 -> "D7FF } \seq_new:N \g__xeCJK_base_class_seq \seq_gset_eq:NN \g__xeCJK_base_class_seq \g__xeCJK_class_seq \seq_new:N \g__xeCJK_non_CJK_class_seq \seq_gset_from_clist:Nn \g__xeCJK_non_CJK_class_seq { Default , HalfLeft , HalfRight , NormalSpace , Boundary } \seq_new:N \g__xeCJK_CJK_class_seq \cs_new_protected_nopar:Npn \__xeCJK_save_CJK_class:n #1 { \seq_gput_right:Nn \g__xeCJK_CJK_class_seq {#1} \tl_const:cn { \__xeCJK_CJK_class_tl:c { \__xeCJK_class_csname:n {#1} } } {#1} } \clist_map_function:nN { CJK , FullLeft , FullRight , CM , HangulJamo } \__xeCJK_save_CJK_class:n \cs_new_nopar:Npn \xeCJK_class_num:n #1 { \use:c { \__xeCJK_class_csname:n {#1} } } \NewDocumentCommand \xeCJKDeclareCharClass { s > { \TrimSpaces } m m } { \xeCJK_declare_char_class:nn {#2} {#3} \IfBooleanT {#1} { \xeCJKResetPunctClass } } \cs_new_protected_nopar:Npn \xeCJK_declare_char_class:nn #1#2 { \clist_set:Nx \l__xeCJK_tmp_clist {#2} \xeCJK_declare_char_class:nN {#1} \l__xeCJK_tmp_clist } \cs_new_protected_nopar:Npn \xeCJK_declare_char_class:nN #1#2 { \clist_gconcat:ccN { g__xeCJK_#1_range_clist } { g__xeCJK_#1_range_clist } #2 \clist_map_inline:Nn #2 { \str_if_eq:nnF {##1} { -> } { \__xeCJK_set_char_class_aux:Nnw \xeCJK_set_char_class:nnn {##1} { \xeCJK_class_num:n {#1} } } } \xeCJK_set_char_class:nnn { "3099 } { "309A } { \xeCJK_class_num:n { CM } } } \NewDocumentCommand \__xeCJK_set_char_class_aux:Nnw { m > { \SplitArgument { 1 } { -> } } m } { #1 #2 } \cs_generate_variant:Nn \clist_gconcat:NNN { cc } \cs_generate_variant:Nn \xeCJK_declare_char_class:nn { nc } \cs_new_protected_nopar:Npn \__xeCJK_check_num_range:nnNN #1#2#3#4 { \bool_if:nTF { \xeCJK_if_blank_x_p:n {#1} || \xeCJK_if_blank_x_p:n {#2} } { \int_set:Nn #3 { \xeCJK_if_blank_x:nTF {#1} {#2} {#1} } \int_set_eq:NN #3 #4 } { \int_set:Nn #3 { \int_min:nn {#1} { \IfNoValueTF {#2} {#1} {#2} } } \int_set:Nn #4 { \int_max:nn {#1} { \IfNoValueTF {#2} {#1} {#2} } } } } \token_if_letter:NF ^^^^ac00 { \int_set:Nn \l__xeCJK_begin_int { "AC00 } \int_set:Nn \l__xeCJK_end_int { "D7A3 } \xeCJK_int_until_do:nn { \l__xeCJK_begin_int > \l__xeCJK_end_int } { \char_set_catcode_letter:n { \l__xeCJK_begin_int } \int_incr:N \l__xeCJK_begin_int } } \cs_new_protected_nopar:Npn \xeCJK_set_char_class:nnn #1#2#3 { \__xeCJK_check_num_range:nnNN {#1} {#2} \l__xeCJK_begin_int \l__xeCJK_end_int \int_set:Nn \l__xeCJK_tmp_int {#3} \xeCJK_int_until_do:nn { \l__xeCJK_begin_int > \l__xeCJK_end_int } { \xetex_charclass:D \l__xeCJK_begin_int = \l__xeCJK_tmp_int \int_incr:N \l__xeCJK_begin_int } } \cs_new_protected_nopar:Npn \__xeCJK_set_char_class_eq:nn #1#2 { \int_set:Nn \l__xeCJK_tmp_int { \xeCJK_class_num:n {#2} } \clist_map_inline:cn { c__xeCJK_#1_chars_clist } { \xetex_charclass:D ##1 = \l__xeCJK_tmp_int } } \NewDocumentCommand \normalspacedchars { m } { \tl_map_inline:nn {#1} { \xetex_charclass:D `##1 = \xeCJK_class_num:n { NormalSpace } } } \NewDocumentCommand \xeCJKResetPunctClass { } { \clist_gclear:N \g__xeCJK_HalfLeft_range_clist \clist_gclear:N \g__xeCJK_HalfRight_range_clist \clist_gclear:N \g__xeCJK_FullLeft_range_clist \clist_gclear:N \g__xeCJK_FullRight_range_clist \xeCJK_declare_char_class:nN { HalfLeft } \c__xeCJK_HalfLeft_chars_clist \xeCJK_declare_char_class:nN { HalfRight } \c__xeCJK_HalfRight_chars_clist \xeCJK_declare_char_class:nN { FullLeft } \c__xeCJK_FullLeft_chars_clist \xeCJK_declare_char_class:nN { FullRight } \c__xeCJK_FullRight_chars_clist } \NewDocumentCommand \xeCJKResetCharClass { } { \clist_gclear:N \g__xeCJK_CJK_range_clist \clist_gclear:N \g__xeCJK_NormalSpace_range_clist \clist_gclear:N \g__xeCJK_CM_range_clist \clist_gclear:N \g__xeCJK_HangulJamo_range_clist \xeCJK_declare_char_class:nN { CJK } \c__xeCJK_CJK_chars_clist \xeCJK_declare_char_class:nN { NormalSpace } \c__xeCJK_NormalSpace_chars_clist \xeCJK_declare_char_class:nN { CM } \c__xeCJK_CM_chars_clist \xeCJK_declare_char_class:nN { HangulJamo } \c__xeCJK_HangulJamo_chars_clist \xeCJKResetPunctClass } \xeCJKResetCharClass \cs_new_protected_nopar:Npn \xeCJK_inter_class_toks:nnn #1#2#3 { \xetex_interchartoks:D \xeCJK_class_num:n {#1} ~ \xeCJK_class_num:n {#2} = {#3} } \cs_generate_variant:Nn \xeCJK_inter_class_toks:nnn { nnc , nnx } \cs_new_nopar:Npn \xeCJK_get_inter_class_toks:nn #1#2 { \tex_the:D \xetex_interchartoks:D \xeCJK_class_num:n {#1} ~ \xeCJK_class_num:n {#2} } \cs_new_protected_nopar:Npn \xeCJK_clear_inter_class_toks:nn #1#2 { \xeCJK_inter_class_toks:nnn {#1} {#2} { \prg_do_nothing: } } \cs_new_protected_nopar:Npn \xeCJK_pre_inter_class_toks:nnn #1#2#3 { \xeCJK_inter_class_toks:nnx {#1} {#2} { \exp_not:n {#3} \xeCJK_get_inter_class_toks:nn {#1} {#2} } } \cs_generate_variant:Nn \xeCJK_pre_inter_class_toks:nnn { nnx } \cs_new_protected_nopar:Npn \xeCJK_app_inter_class_toks:nnn #1#2#3 { \xeCJK_inter_class_toks:nnx {#1} {#2} { \xeCJK_get_inter_class_toks:nn {#1} {#2} \exp_not:n {#3} } } \cs_generate_variant:Nn \xeCJK_app_inter_class_toks:nnn { nnc , nnx } \cs_new_protected_nopar:Npn \xeCJK_copy_inter_class_toks:nnnn #1#2#3#4 { \tl_set:Nx \l__xeCJK_tmp_tl { \xeCJK_get_inter_class_toks:nn {#3} {#4} } \tl_if_empty:NTF \l__xeCJK_tmp_tl { \tl_set:Nx \l__xeCJK_tmp_tl { \xeCJK_get_inter_class_toks:nn {#1} {#2} } \tl_if_empty:NF \l__xeCJK_tmp_tl { \xeCJK_clear_inter_class_toks:nn {#1} {#2} } } { \xeCJK_inter_class_toks:nnx {#1} {#2} { \exp_not:o \l__xeCJK_tmp_tl } } } \cs_new_protected_nopar:Npn \xeCJK_replace_inter_class_toks:nnnn #1#2#3#4 { \tl_set:Nx \l__xeCJK_tmp_tl { \xeCJK_get_inter_class_toks:nn {#1} {#2} } \tl_if_empty:NF \l__xeCJK_tmp_tl { \tl_replace_all:Nnn \l__xeCJK_tmp_tl {#3} {#4} \xeCJK_inter_class_toks:nnx {#1} {#2} { \exp_not:o \l__xeCJK_tmp_tl } } } \cs_new_protected_nopar:Npn \xeCJK_clear_Boundary_and_CJK_toks: { \seq_map_function:NN \g__xeCJK_CJK_class_seq \__xeCJK_clear_Boundary_and_CJK_toks:n } \cs_new_protected_nopar:Npn \__xeCJK_clear_Boundary_and_CJK_toks:n #1 { \xeCJK_clear_inter_class_toks:nn { Boundary } {#1} } \cs_new_protected_nopar:Npn \xeCJK_class_group_begin: { \c_group_begin_token \bool_set_true:N \l__xeCJK_CJK_group_bool \int_gset_eq:NN \g__xeCJK_spacefactor_int \c_one_thousand } \bool_new:N \l__xeCJK_CJK_group_bool \cs_new_eq:NN \xeCJK_class_group_end: \c_group_end_token \AtEndOfPackage { \seq_map_inline:Nn \g__xeCJK_class_seq { \str_if_eq:nnTF {#1} { CM } { \xeCJK_copy_inter_class_toks:nnnn { CM } {#1} { CJK } { CJK } } { \xeCJK_copy_inter_class_toks:nnnn { CM } {#1} { CJK } {#1} \str_if_eq:nnF {#1} { CJK } { \xeCJK_copy_inter_class_toks:nnnn {#1} { CM } {#1} { CJK } } } } } \AtEndOfPackage { \seq_map_inline:Nn \g__xeCJK_class_seq { \str_if_eq:nnF {#1} { HangulJamo } { \xeCJK_copy_inter_class_toks:nnnn { HangulJamo } {#1} { CJK } {#1} \xeCJK_copy_inter_class_toks:nnnn {#1} { HangulJamo } {#1} { CJK } } } } \clist_map_inline:nn { Default , HalfLeft , HalfRight , NormalSpace } { \xeCJK_inter_class_toks:nnn {#1} { CJK } { \xeCJK_class_group_begin: \xeCJK_select_font: \xeCJK_clear_inter_class_toks:nn {#1} { CJK } \xeCJK_clear_Boundary_and_CJK_toks: \CJKsymbol } \xeCJK_inter_class_toks:nnn { CJK } {#1} { \xeCJK_class_group_end: } } \clist_map_inline:nn { Default , HalfLeft } { \xeCJK_inter_class_toks:nnn { Boundary } {#1} { \xeCJK_Boundary_and_Default: } \xeCJK_app_inter_class_toks:nnn { CJK } {#1} { \CJKecglue } } \cs_new_protected_nopar:Npn \xeCJK_Boundary_and_Default: { \xeCJK_check_for_ecglue: } \cs_new_protected_nopar:Npn \__xeCJK_check_for_xecglue: { \int_compare:nNnTF \etex_lastnodetype:D = \c_eleven { \__xeCJK_replace_space: } { \__xeCJK_check_for_ecglue: } } \cs_new_protected_nopar:Npn \__xeCJK_check_for_ecglue: { \bool_if:nTF { \xeCJK_if_last_node_p:n { CJK } || \xeCJK_if_last_node_p:n { CJK-widow } } { \xeCJK_remove_node: \CJKecglue } { \xeCJK_if_last_node:nT { CJK-space } { \xeCJK_remove_node: \xeCJK_space_or_xecglue: } } } \cs_new_eq:NN \xeCJK_check_for_ecglue: \__xeCJK_check_for_ecglue: \cs_new_protected_nopar:Npn \__xeCJK_replace_space: { \skip_set_eq:NN \l__xeCJK_last_skip \tex_lastskip:D \tex_unskip:D \xeCJK_if_last_node:nTF { CJK-space } { \xeCJK_remove_node: \CJKecglue } { \xeCJK_if_last_node:nTF { CJK } { \skip_if_eq:nnTF { \l__xeCJK_last_skip } { \c_xeCJK_space_skip_tl } { \xeCJK_remove_node: \CJKecglue } { \skip_horizontal:N \l__xeCJK_last_skip } } { \skip_horizontal:N \l__xeCJK_last_skip } } } \skip_new:N \l__xeCJK_last_skip \clist_map_inline:nn { Default , HalfRight } { \xeCJK_inter_class_toks:nnn {#1} { Boundary } { \int_gset_eq:NN \g__xeCJK_spacefactor_int \tex_spacefactor:D \peek_meaning_remove:NTF \tex_italiccorrection:D { \tex_italiccorrection:D { \xeCJK_make_node:n { default } } } { \token_if_space:NTF \l_peek_token { { \xeCJK_make_node:n { default-space } } } { { \xeCJK_make_node:n { default } } } } } \xeCJK_pre_inter_class_toks:nnn {#1} { CJK } { \CJKecglue } } \xeCJK_inter_class_toks:nnn { Boundary } { NormalSpace } { \xeCJK_Boundary_and_NormalSp: } \cs_new_protected_nopar:Npn \xeCJK_Boundary_and_NormalSp: { \xeCJK_check_for_ecglue_normalsp: } \cs_new_protected_nopar:Npn \__xeCJK_check_for_xecglue_normalsp: { \int_compare:nNnTF \etex_lastnodetype:D = \c_eleven { \__xeCJK_replace_space: } { \__xeCJK_check_for_ecglue_normalsp: } } \cs_new_protected_nopar:Npn \__xeCJK_check_for_ecglue_normalsp: { \xeCJK_if_last_node:nT { CJK-space } { \xeCJK_remove_node: \xeCJK_space_or_xecglue: } } \cs_new_eq:NN \xeCJK_check_for_ecglue_normalsp: \__xeCJK_check_for_ecglue_normalsp: \xeCJK_inter_class_toks:nnn { NormalSpace } { Boundary } { \int_gset_eq:NN \g__xeCJK_spacefactor_int \tex_spacefactor:D \peek_meaning_remove:NTF \tex_italiccorrection:D { \tex_italiccorrection:D { \xeCJK_make_node:n { normalspace } } } { \token_if_space:NTF \l_peek_token { { \xeCJK_make_node:n { default-space } } } { { \xeCJK_make_node:n { normalspace } } } } } \xeCJK_inter_class_toks:nnn { Boundary } { CJK } { \xeCJK_check_for_glue: \xeCJK_class_group_begin: \xeCJK_clear_Boundary_and_CJK_toks: \xeCJK_select_font: \CJKsymbol } \cs_new_protected_nopar:Npn \xeCJK_check_for_glue: { \bool_if:nTF { \xeCJK_if_last_node_p:n { CJK } || \xeCJK_if_last_node_p:n { CJK-space } } { \xeCJK_remove_node: \CJKglue } { \xeCJK_if_last_node:nTF { CJK-widow } { \xeCJK_remove_node: \xeCJK_widow_penalty: \CJKglue } { \bool_if:nTF { \xeCJK_if_last_node_p:n { default } || \int_compare_p:nNn \etex_lastnodetype:D = \c_ten } { \xeCJK_remove_node: \CJKecglue } { \xeCJK_check_for_xglue: } } } } \cs_new_eq:NN \xeCJK_check_for_xglue: \prg_do_nothing: \cs_new_protected_nopar:Npn \__xeCJK_check_for_xglue: { \int_compare:nNnT \etex_lastnodetype:D = \c_eleven { \skip_set_eq:NN \l__xeCJK_last_skip \tex_lastskip:D \tex_unskip:D \xeCJK_if_last_node:nTF { CJK-space } { \xeCJK_remove_node: \__xeCJK_ccglue_or_space: } { \xeCJK_if_last_node:nTF { default-space } { \xeCJK_remove_node: \CJKecglue } { \__xeCJK_check_for_xglue_aux: } } } } \cs_new_protected_nopar:Npn \__xeCJK_check_for_xglue_aux: { \skip_if_eq:nnTF { \l__xeCJK_last_skip } { \c_xeCJK_space_skip_tl } { \xeCJK_if_last_node:nTF { CJK } { \xeCJK_remove_node: \__xeCJK_ccglue_or_space: } { \xeCJK_if_last_node:nTF { default } { \xeCJK_remove_node: \CJKecglue } { \int_compare:nNnTF \etex_lastnodetype:D = \c_ten { \CJKecglue } { \skip_horizontal:N \l__xeCJK_last_skip } } } } { \skip_horizontal:N \l__xeCJK_last_skip } } \cs_new_protected_nopar:Npn \__xeCJK_ccglue_or_space: { \CJKglue } \prg_new_conditional:Npnn \xeCJK_if_last_node:n #1 { p , T , F , TF } { \if_dim:w \use:c { c__xeCJK_#1_node_dim } = \tex_lastkern:D \prg_return_true: \else: \prg_return_false: \fi: } \cs_new_protected_nopar:Npn \xeCJK_declare_node:n #1 { \int_gincr:N \g__xeCJK_node_int \dim_if_exist:cTF { c__xeCJK_#1_node_dim } { \dim_gset:cn } { \dim_const:cn } { c__xeCJK_#1_node_dim } { \g__xeCJK_node_int sp } } \int_new:N \g__xeCJK_node_int \int_gset_eq:NN \g__xeCJK_node_int \c_ten \cs_new_protected_nopar:Npn \xeCJK_make_node:n #1 { \exp_after:wN \__xeCJK_make_node:N \cs:w c__xeCJK_#1_node_dim \exp_after:wN \cs_end: \exp_after:wN \tex_spacefactor:D \int_use:N \tex_spacefactor:D \exp_stop_f: } \cs_new_protected_nopar:Npn \__xeCJK_make_node:N #1 { \tex_kern:D - #1 \tex_kern:D #1 } \cs_new_protected_nopar:Npn \xeCJK_remove_node: { \tex_unkern:D \tex_unkern:D } \xeCJK_declare_node:n { CJK } \xeCJK_declare_node:n { CJK-space } \xeCJK_declare_node:n { default } \xeCJK_declare_node:n { default-space } \xeCJK_declare_node:n { CJK-widow } \xeCJK_declare_node:n { normalspace } \keys_define:nn { xeCJK / options } { CJKglue .code:n = { \cs_set_protected_nopar:Npn \CJKglue {#1} \xeCJK_glue_to_skip:nN {#1} \l__xeCJK_ccglue_skip } } \skip_new:N \l__xeCJK_ccglue_skip \keys_define:nn { xeCJK / options } { CJKecglue .code:n = { \cs_set_protected_nopar:Npn \CJKecglue {#1} \xeCJK_glue_to_skip:nN {#1} \l__xeCJK_ecglue_skip } , xCJKecglue .choice: , xCJKecglue / true .code:n = { \bool_set_true:N \l__xeCJK_xecglue_bool \cs_set_eq:NN \xeCJK_space_or_xecglue: \CJKecglue \cs_set_eq:NN \xeCJK_check_for_xglue: \__xeCJK_check_for_xglue: \cs_set_eq:NN \xeCJK_check_for_ecglue: \__xeCJK_check_for_xecglue: \cs_set_eq:NN \xeCJK_check_for_ecglue_normalsp: \__xeCJK_check_for_xecglue_normalsp: } , xCJKecglue / false .code:n = { \bool_set_false:N \l__xeCJK_xecglue_bool \cs_set_eq:NN \xeCJK_space_or_xecglue: \xeCJK_space_glue: \xeCJK_cs_clear:N \xeCJK_check_for_xglue: \cs_set_eq:NN \xeCJK_check_for_ecglue: \__xeCJK_check_for_ecglue: \cs_set_eq:NN \xeCJK_check_for_ecglue_normalsp: \__xeCJK_check_for_ecglue_normalsp: } , xCJKecglue / unknown .code:n = { \bool_set_true:N \l__xeCJK_xecglue_bool \cs_set_protected_nopar:Npn \CJKecglue {#1} \xeCJK_glue_to_skip:nN {#1} \l__xeCJK_ecglue_skip \cs_set_eq:NN \xeCJK_space_or_xecglue: \CJKecglue \cs_set_eq:NN \xeCJK_check_for_xglue: \__xeCJK_check_for_xglue: \cs_set_eq:NN \xeCJK_check_for_ecglue: \__xeCJK_check_for_xecglue: \cs_set_eq:NN \xeCJK_check_for_ecglue_normalsp: \__xeCJK_check_for_xecglue_normalsp: } , xCJKecglue .default:n = { true } } \cs_new_eq:NN \xeCJK_space_glue: \c_space_tl \skip_new:N \l__xeCJK_ecglue_skip \bool_new:N \l__xeCJK_xecglue_bool \keys_define:nn { xeCJK / options } { CJKspace .choice: , CJKspace / true .code:n = { \bool_set_true:N \l__xeCJK_reserve_space_bool \cs_set_eq:NN \__xeCJK_ignore_space_end: \__xeCJK_maybe_reserve_space: \cs_set_eq:NN \__xeCJK_boundary_group_end_space: \__xeCJK_boundary_maybe_reserve_space: \cs_set_protected_nopar:Npn \__xeCJK_ccglue_or_space: { \xeCJK_space_glue: } } , CJKspace / false .code:n = { \bool_set_false:N \l__xeCJK_reserve_space_bool \cs_set_eq:NN \__xeCJK_ignore_space_end: \group_align_safe_end: \cs_set_eq:NN \__xeCJK_boundary_group_end_space: \__xeCJK_boundary_group_end_aux: \cs_set_protected_nopar:Npn \__xeCJK_ccglue_or_space: { \CJKglue } } , CJKspace .default:n = { true } , space .meta:n = { CJKspace = true } , nospace .meta:n = { CJKspace = false } } \bool_new:N \l__xeCJK_reserve_space_bool \xeCJK_inter_class_toks:nnn { CJK } { Boundary } { \xeCJK_CJK_and_Boundary:w } \cs_new_protected_nopar:Npn \xeCJK_CJK_and_Boundary:w { \xeCJK_peek_catcode_ignore_spaces:NTF \c_math_toggle_token { \bool_if:NTF \l__xeCJK_peek_ignore_spaces_bool { \xeCJK_class_group_end: \xeCJK_space_or_xecglue: } { \xeCJK_class_group_end: \CJKecglue } } { \group_align_safe_begin: \bool_if:NTF \l__xeCJK_peek_ignore_spaces_bool { \token_if_macro:NTF \l_peek_token { \__xeCJK_boundary_reserve_space: } { \__xeCJK_boundary_group_end_space: } } { \token_if_eq_meaning:NNTF \l_peek_token \scan_stop: { \__xeCJK_CJK_and_Boundary_relax:N } { \__xeCJK_boundary_group_end:n { CJK } } } } } \cs_new_protected_nopar:Npn \__xeCJK_boundary_reserve_space: { \__xeCJK_boundary_group_end_aux: \xeCJK_space_or_xecglue: } \cs_new_protected_nopar:Npn \__xeCJK_boundary_maybe_reserve_space: { \token_if_letter:NTF \l_peek_token { \__xeCJK_boundary_reserve_space: } { \__xeCJK_boundary_group_end_aux: } } \cs_new_protected_nopar:Npn \__xeCJK_boundary_group_end_aux: { \__xeCJK_boundary_group_end:n { CJK-space } } \cs_new_eq:NN \__xeCJK_boundary_group_end_space: \__xeCJK_boundary_group_end_aux: \cs_new_protected:Npn \__xeCJK_CJK_and_Boundary_relax:N #1 { \__xeCJK_boundary_group_end:n { CJK } \token_if_eq_meaning:NNTF #1 \scan_stop: {#1} { \cs_set_eq:NN #1 \scan_stop: #1 } } \cs_new_protected_nopar:Npn \__xeCJK_boundary_group_end:n #1 { \group_align_safe_end: \xeCJK_class_group_end: { \xeCJK_make_node:n {#1} } } \cs_new_protected_nopar:Npn \xeCJK_ignore_spaces:w { \xeCJK_peek_catcode_ignore_spaces:NTF \c_math_toggle_token { \bool_if:NTF \l__xeCJK_peek_ignore_spaces_bool { \xeCJK_space_or_xecglue: } { \CJKecglue } } { \bool_if:NT \l__xeCJK_peek_ignore_spaces_bool { \xeCJK_if_last_node:nT { CJK } { \xeCJK_remove_node: { \xeCJK_make_node:n { CJK-space } } } \group_align_safe_begin: \token_if_macro:NTF \l_peek_token { \__xeCJK_reserve_space_aux: } { \__xeCJK_ignore_space_end: } } } } \cs_new_protected:Npn \__xeCJK_reserve_space_aux: { \group_align_safe_end: \xeCJK_space_or_xecglue: } \cs_new_protected:Npn \__xeCJK_maybe_reserve_space: { \token_if_letter:NTF \l_peek_token { \__xeCJK_reserve_space_aux: } { \group_align_safe_end: } } \cs_new_eq:NN \__xeCJK_ignore_space_end: \group_align_safe_end: \xeCJK_inter_class_toks:nnn { CJK } { CJK } { \xeCJK_CJK_and_CJK:N } \cs_new_protected_nopar:Npn \xeCJK_CJK_and_CJK:N #1 { \CJKglue \CJKsymbol {#1} } \xeCJK_inter_class_toks:nnn { FullLeft } { CJK } { \xeCJK_FullLeft_and_CJK: \CJKsymbol } \xeCJK_inter_class_toks:nnn { FullRight } { CJK } { \xeCJK_FullRight_and_CJK: \CJKsymbol } \seq_map_inline:Nn \g__xeCJK_non_CJK_class_seq { \clist_map_inline:nn { FullLeft , FullRight } { \xeCJK_inter_class_toks:nnx {#1} {##1} { \exp_not:c { xeCJK_Default_and_##1:nN } {#1} } \xeCJK_inter_class_toks:nnc {##1} {#1} { xeCJK_##1_and_Default: } } } \xeCJK_inter_class_toks:nnn { Boundary } { FullLeft } { \xeCJK_Boundary_and_FullLeft:N } \xeCJK_inter_class_toks:nnn { Boundary } { FullRight } { \xeCJK_Boundary_and_FullRight:N } \xeCJK_app_inter_class_toks:nnn { FullLeft } { Boundary } { \tex_ignorespaces:D } \xeCJK_inter_class_toks:nnn { FullRight } { Boundary } { \xeCJK_FullRight_and_Boundary: } \cs_new_protected_nopar:Npn \xeCJK_FullRight_and_Boundary: { \xeCJK_FullRight_and_Default: \tex_ignorespaces:D } \clist_map_inline:nn { CJK , FullLeft , FullRight } { \clist_map_inline:nn { FullLeft , FullRight } { \xeCJK_inter_class_toks:nnc {#1} {##1} { xeCJK_#1_and_##1:N } } } \cs_new_protected_nopar:Npn \__xeCJK_punct_bound_rule:NN #1#2 { \tex_vrule:D width - \__xeCJK_use_punct_dim:nnn { bound } {#1} {#2} depth \c_zero_dim height \c_zero_dim \scan_stop: } \cs_new_protected_nopar:Npn \__xeCJK_punct_rule:NN #1#2 { \tex_vrule:D width \__xeCJK_use_punct_dim:nnn { rule } {#1} {#2} depth \c_zero_dim height \c_zero_dim \scan_stop: } \cs_new_protected_nopar:Npn \__xeCJK_punct_offset:NN #1#2 { \__xeCJK_punct_kern:n { - \__xeCJK_use_punct_dim:nnn { offset } {#1} {#2} } } \cs_new_protected_nopar:Npn \__xeCJK_punct_kern:n #1 { \dim_compare:nNnF {#1} = \c_zero_dim { \tex_kern:D #1 \exp_stop_f: } } \cs_new_protected_nopar:Npn \__xeCJK_punct_glue:NN #1#2 { \__xeCJK_punct_hskip:n { \__xeCJK_use_dim_or_skip:nnn { glue } {#1} {#2} } } \cs_new_eq:NN \__xeCJK_punct_hskip:n \skip_horizontal:n \cs_new_protected_nopar:Npn \__xeCJK_punct_kern:NN #1#2 { \__xeCJK_nobreak_hskip:n { \__xeCJK_use_dim_or_skip:nnn { kern } {#1} {#2} } } \tl_new:N \g__xeCJK_last_punct_tl \cs_new_protected_nopar:Npn \xeCJK_FullLeft_and_CJK: { \__xeCJK_punct_if_middle:NTF \g__xeCJK_last_punct_tl { \__xeCJK_punct_bound_rule:NN \c__xeCJK_right_tl \g__xeCJK_last_punct_tl \xeCJK_no_break: \__xeCJK_punct_glue:NN \c__xeCJK_left_tl \g__xeCJK_last_punct_tl } { \xeCJK_no_break: } } \cs_new_protected_nopar:Npn \xeCJK_FullLeft_and_Default: { \__xeCJK_punct_if_middle:NTF \g__xeCJK_last_punct_tl { \__xeCJK_punct_bound_rule:NN \c__xeCJK_right_tl \g__xeCJK_last_punct_tl \xeCJK_class_group_end: \xeCJK_no_break: \__xeCJK_punct_glue:NN \c__xeCJK_left_tl \g__xeCJK_last_punct_tl } { \xeCJK_class_group_end: \xeCJK_no_break: \__xeCJK_zero_glue: } } \cs_new_protected_nopar:Npn \__xeCJK_zero_glue: { \skip_horizontal:N \c_zero_skip } \cs_new_protected_nopar:Npn \xeCJK_FullRight_and_CJK: { \__xeCJK_punct_rule:NN \c__xeCJK_right_tl \g__xeCJK_last_punct_tl \__xeCJK_punct_offset:NN \c__xeCJK_right_tl \g__xeCJK_last_punct_tl \__xeCJK_punct_glue:NN \c__xeCJK_right_tl \g__xeCJK_last_punct_tl \CJKglue } \cs_new_protected_nopar:Npn \xeCJK_FullRight_and_Default: { \__xeCJK_punct_rule:NN \c__xeCJK_right_tl \g__xeCJK_last_punct_tl \xeCJK_class_group_end: \__xeCJK_punct_offset:NN \c__xeCJK_right_tl \g__xeCJK_last_punct_tl \__xeCJK_punct_glue:NN \c__xeCJK_right_tl \g__xeCJK_last_punct_tl } \cs_new_protected_nopar:Npn \xeCJK_Default_and_FullLeft:nN #1#2 { \xeCJK_get_punct_bounds:NN \c__xeCJK_left_tl {#2} \__xeCJK_Default_and_FullLeft_glue:N {#2} \xeCJK_class_group_begin: \xeCJK_select_font: \xeCJK_clear_inter_class_toks:nn {#1} { FullLeft } \xeCJK_clear_Boundary_and_CJK_toks: \tl_gset:Nx \g__xeCJK_last_punct_tl {#2} \__xeCJK_punct_rule:NN \c__xeCJK_left_tl {#2} \CJKpunctsymbol {#2} } \cs_new_protected_nopar:Npn \__xeCJK_Default_and_FullLeft_glue:N #1 { \__xeCJK_punct_glue:NN \c__xeCJK_left_tl {#1} \__xeCJK_punct_offset:NN \c__xeCJK_left_tl {#1} } \cs_new_protected_nopar:Npn \xeCJK_CJK_and_FullLeft:N #1 { \xeCJK_get_punct_bounds:NN \c__xeCJK_left_tl {#1} \__xeCJK_CJK_and_FullLeft_glue:N {#1} \tl_gset:Nx \g__xeCJK_last_punct_tl {#1} \__xeCJK_punct_rule:NN \c__xeCJK_left_tl {#1} \CJKpunctsymbol {#1} } \cs_new_protected_nopar:Npn \__xeCJK_CJK_and_FullLeft_glue:N #1 { \CJKglue \__xeCJK_punct_glue:NN \c__xeCJK_left_tl {#1} \__xeCJK_punct_offset:NN \c__xeCJK_left_tl {#1} } \cs_new_protected_nopar:Npn \xeCJK_Boundary_and_FullLeft:N #1 { \xeCJK_get_punct_bounds:NN \c__xeCJK_left_tl {#1} \__xeCJK_Boundary_and_FullLeft_glue:N {#1} \__xeCJK_punct_offset:NN \c__xeCJK_left_tl {#1} \xeCJK_class_group_begin: \xeCJK_select_font: \xeCJK_clear_Boundary_and_CJK_toks: \tl_gset:Nx \g__xeCJK_last_punct_tl {#1} \__xeCJK_punct_rule:NN \c__xeCJK_left_tl {#1} \CJKpunctsymbol {#1} } \cs_new_protected_nopar:Npn \__xeCJK_Boundary_and_FullLeft_glue:N #1 { \int_case:nnTF { \etex_lastnodetype:D } { { \c_one } { \box_set_to_last:N \l__xeCJK_tmp_box \bool_if:nTF { \int_compare_p:nNn \etex_lastnodetype:D = \c_minus_one && \dim_compare_p:nNn { \box_wd:N \l__xeCJK_tmp_box } = \tex_parindent:D } { \box_use_clear:N \l__xeCJK_tmp_box \use_none:n } { \box_use_clear:N \l__xeCJK_tmp_box \use:n } } { \c_minus_one } { \__xeCJK_zero_glue: \use_none:n } { \c_eleven } { \bool_if:nTF { ! ( \skip_if_finite_p:n { \tex_lastskip:D } ) || \skip_if_eq_p:nn { \tex_lastskip:D } { 1 sp } } { \__xeCJK_zero_glue: \use_none:n } { \skip_if_eq:nnTF { \tex_lastskip:D } { \labelsep } { \tex_unskip:D \bool_if:nTF { \int_compare_p:nNn \etex_lastnodetype:D = \c_thirteen && \int_compare_p:nNn \tex_lastpenalty:D = \c_zero } { \skip_horizontal:n { \labelsep } \use_none:n } { \skip_horizontal:n { \labelsep } \use:n } } { \use:n } } } { \c_thirteen } { \int_compare:nNnTF \tex_lastpenalty:D = \c_zero { \tex_unpenalty:D \int_compare:nNnTF \etex_lastnodetype:D = \c_one { \tex_penalty:D \c_zero \use_none:n } { \tex_penalty:D \c_zero \use:n } } { \use:n } } } { { \__xeCJK_punct_glue:NN \c__xeCJK_left_tl {#1} } } { \__xeCJK_punct_glue:NN \c__xeCJK_left_tl {#1} } } \cs_new_protected_nopar:Npn \xeCJK_Default_and_FullRight:nN #1#2 { \xeCJK_get_punct_bounds:NN \c__xeCJK_right_tl {#2} \__xeCJK_Default_and_FullRight_glue:N {#2} \xeCJK_class_group_begin: \xeCJK_select_font: \xeCJK_clear_inter_class_toks:nn {#1} { FullRight } \xeCJK_clear_Boundary_and_CJK_toks: \tl_gset:Nx \g__xeCJK_last_punct_tl {#2} \xeCJK_FullRight_symbol:N {#2} } \cs_new_protected_nopar:Npn \xeCJK_Boundary_and_FullRight:N #1 { \xeCJK_get_punct_bounds:NN \c__xeCJK_right_tl {#1} \__xeCJK_Default_and_FullRight_glue:N {#1} \xeCJK_class_group_begin: \xeCJK_select_font: \xeCJK_clear_Boundary_and_CJK_toks: \tl_gset:Nx \g__xeCJK_last_punct_tl {#1} \xeCJK_FullRight_symbol:N {#1} } \cs_new_protected_nopar:Npn \xeCJK_CJK_and_FullRight:N #1 { \xeCJK_get_punct_bounds:NN \c__xeCJK_right_tl {#1} \__xeCJK_CJK_and_FullRight_glue:N {#1} \tl_gset:Nx \g__xeCJK_last_punct_tl {#1} \xeCJK_FullRight_symbol:N {#1} } \cs_new_protected_nopar:Npn \__xeCJK_CJK_and_FullRight_glue:N #1 { \__xeCJK_punct_if_long:NTF {#1} { \CJKglue } { \__xeCJK_punct_if_middle:NTF {#1} { \xeCJK_no_break: \__xeCJK_punct_glue:NN \c__xeCJK_right_tl {#1} \__xeCJK_punct_bound_rule:NN \c__xeCJK_left_tl {#1} } { \xeCJK_no_break: } } } \cs_new_eq:NN \__xeCJK_Default_and_FullRight_glue:N \__xeCJK_CJK_and_FullRight_glue:N \cs_new_protected_nopar:Npn \xeCJK_FullLeft_and_FullLeft:N #1 { \xeCJK_no_break: \xeCJK_get_punct_bounds:NN \c__xeCJK_left_tl {#1} \xeCJK_get_punct_kerning:oN \g__xeCJK_last_punct_tl {#1} \__xeCJK_punct_kern:NN \g__xeCJK_last_punct_tl {#1} \tl_gset:Nx \g__xeCJK_last_punct_tl {#1} \CJKpunctsymbol {#1} } \cs_new_protected_nopar:Npn \xeCJK_FullLeft_and_FullRight:N #1 { \xeCJK_no_break: \xeCJK_get_punct_bounds:NN \c__xeCJK_right_tl {#1} \xeCJK_get_punct_kerning:oN \g__xeCJK_last_punct_tl {#1} \__xeCJK_punct_kern:NN \g__xeCJK_last_punct_tl {#1} \tl_gset:Nx \g__xeCJK_last_punct_tl {#1} \xeCJK_no_break: \xeCJK_FullRight_symbol:N {#1} } \cs_new_protected_nopar:Npn \xeCJK_FullRight_and_FullLeft:N #1 { \xeCJK_get_punct_bounds:NN \c__xeCJK_left_tl {#1} \xeCJK_get_punct_kerning:oN \g__xeCJK_last_punct_tl {#1} \xeCJK_punct_kern:NN \g__xeCJK_last_punct_tl {#1} \tl_gset:Nx \g__xeCJK_last_punct_tl {#1} \CJKpunctsymbol {#1} } \cs_new_protected_nopar:Npn \__xeCJK_punct_nobreak_kern:NN #1#2 { \__xeCJK_punct_kern:NN #1#2 \xeCJK_no_break: } \cs_new_eq:NN \xeCJK_punct_kern:NN \__xeCJK_punct_nobreak_kern:NN \cs_new_protected_nopar:Npn \__xeCJK_punct_breakable_kern:NN #1#2 { \__xeCJK_punct_rule:NN \c__xeCJK_right_tl #1 \__xeCJK_punct_breakable_kern:n { \__xeCJK_use_dim_or_skip:nnn { break_kern } {#1} {#2} } \__xeCJK_punct_rule:NN \c__xeCJK_left_tl #2 } \cs_new_eq:NN \__xeCJK_punct_breakable_kern:n \skip_horizontal:n \cs_new_protected_nopar:Npn \xeCJK_FullRight_and_FullRight:N #1 { \xeCJK_get_punct_bounds:NN \c__xeCJK_right_tl {#1} \xeCJK_get_punct_kerning:oN \g__xeCJK_last_punct_tl {#1} \__xeCJK_punct_kern:NN \g__xeCJK_last_punct_tl {#1} \tl_gset:Nx \g__xeCJK_last_punct_tl {#1} \xeCJK_no_break: \xeCJK_FullRight_symbol:N {#1} } \keys_define:nn { xeCJK / options } { CheckFullRight .choice: , CheckFullRight / true .code:n = { \cs_if_eq:NNF \xeCJK_FullRight_and_Boundary: \xeCJK_check_FullRight: { \cs_set_eq:NN \__xeCJK_save_FullRight_check: \xeCJK_FullRight_and_Boundary: \cs_set_eq:NN \__xeCJK_save_FullRight_symbol:N \xeCJK_FullRight_symbol:N \cs_set_eq:NN \xeCJK_FullRight_and_Boundary: \xeCJK_check_FullRight: \cs_set_eq:NN \xeCJK_FullRight_symbol:N \xeCJK_check_FullRight_symbol:Nw } } , CheckFullRight / false .code:n = { \cs_if_eq:NNT \xeCJK_FullRight_and_Boundary: \xeCJK_check_FullRight: { \cs_set_eq:NN \xeCJK_FullRight_and_Boundary: \__xeCJK_save_FullRight_check: \cs_set_eq:NN \xeCJK_FullRight_symbol:N \__xeCJK_save_FullRight_symbol:N } } , CheckFullRight .default:n = { true } } \cs_new_nopar:Npn \xeCJK_FullRight_symbol:N { \CJKpunctsymbol } \cs_new_protected_nopar:Npn \xeCJK_check_FullRight: { \xeCJK_get_punct_bounds:NN \c__xeCJK_right_tl \g__xeCJK_last_punct_tl \__xeCJK_punct_rule:NN \c__xeCJK_right_tl \g__xeCJK_last_punct_tl \__xeCJK_punct_offset:NN \c__xeCJK_right_tl \g__xeCJK_last_punct_tl \group_align_safe_begin: \tl_case:NoTF \l_peek_token { \l__xeCJK_no_break_cs_case_tl } { \group_align_safe_end: \xeCJK_no_break: } { \group_align_safe_end: } \__xeCJK_punct_glue:NN \c__xeCJK_right_tl \g__xeCJK_last_punct_tl \xeCJK_class_group_end: } \cs_generate_variant:Nn \tl_case:NnTF { No } \cs_new_protected_nopar:Npn \xeCJK_check_FullRight_symbol:Nw #1 { \xeCJK_peek_after_ignore_spaces:nw { \__xeCJK_save_FullRight_symbol:N {#1} } } \cs_new_protected:Npn \xeCJK_cs_case_keys_define:nNNnn #1#2#3#4#5 { \tl_new:N #2 \seq_new:N #3 \keys_define:nn { xeCJK / options } { #1 .code:n = { \seq_set_split:Nnn #3 { } {##1} \__xeCJK_update_cs_case_tl:NNnn #2#3 {#4} {#5} } , #1+ .code:n = { \tl_map_inline:nn {##1} { \seq_if_in:NnF #3 {####1} { \seq_put_right:Nn #3 {####1} } } \__xeCJK_update_cs_case_tl:NNnn #2#3 {#4} {#5} } , #1- .code:n = { \tl_map_inline:nn {##1} { \seq_remove_all:Nn #3 {####1} } \__xeCJK_update_cs_case_tl:NNnn #2#3 {#4} {#5} } } } \cs_new_protected:Npn \__xeCJK_update_cs_case_tl:NNnn #1#2#3#4 { \tl_clear:N #1 \seq_map_inline:Nn #2 { \tl_put_right:Nn #1 { {##1} {#3} } } #4 } \xeCJK_cs_case_keys_define:nNNnn { NoBreakCS } \l__xeCJK_no_break_cs_case_tl \l__xeCJK_no_break_cs_seq { } { } \NewDocumentCommand \xeCJKnobreak { } { \bool_set_true:N \l__xeCJK_tmp_bool \int_while_do:nNnn \etex_lastnodetype:D = \c_eleven { \bool_if:NTF \l__xeCJK_tmp_bool { \bool_set_false:N \l__xeCJK_tmp_bool \skip_set_eq:NN \l__xeCJK_tmp_skip \tex_lastskip:D } { \skip_add:Nn \l__xeCJK_tmp_skip \tex_lastskip:D } \tex_unskip:D } \xeCJK_no_break: \bool_if:NF \l__xeCJK_tmp_bool { \skip_horizontal:N \l__xeCJK_tmp_skip } } \keys_define:nn { xeCJK / options } { CheckSingle .choice: , CheckSingle / true .code:n = { \cs_if_eq:NNF \xeCJK_CJK_and_CJK:N \xeCJK_check_single:Nw { \cs_set_eq:NN \__xeCJK_check_single_save:N \xeCJK_CJK_and_CJK:N \cs_set_eq:NN \xeCJK_CJK_and_CJK:N \xeCJK_check_single:Nw } } , CheckSingle / false .code:n = { \cs_if_eq:NNT \xeCJK_CJK_and_CJK:N \xeCJK_check_single:Nw { \cs_set_eq:NN \xeCJK_CJK_and_CJK:N \__xeCJK_check_single_save:N } } , CheckSingle .default:n = { true } , CJKchecksingle .meta:n = { CheckSingle = true } } \keys_define:nn { xeCJK / options } { WidowPenalty .int_set:N = \l__xeCJK_widow_penalty_int , WidowPenalty .default:n = { \c_ten_thousand } } \cs_new_protected_nopar:Npn \xeCJK_widow_penalty: { \tex_penalty:D \l__xeCJK_widow_penalty_int } \cs_new_protected_nopar:Npn \xeCJK_check_single:Nw #1 { \peek_catcode:NTF \c_catcode_letter_token { \xeCJK_check_single:NNw #1 } { \group_align_safe_begin: \token_if_other:NTF \l_peek_token { \group_align_safe_end: \xeCJK_check_single:NNw #1 } { \group_align_safe_end: \bool_if:nTF { \str_if_eq_x_p:nn { \token_get_arg_spec:N \l_peek_token } { } && \exp_args:No \tl_if_single_token_p:n \l_peek_token && ( \exp_after:wN \token_if_other_p:N \l_peek_token || \exp_after:wN \token_if_letter_p:N \l_peek_token ) } { \exp_after:wN \xeCJK_check_single:NNw \exp_after:wN #1 } { \__xeCJK_check_single_save:N #1 } } } } \cs_new_protected_nopar:Npn \xeCJK_check_single:NNw #1#2 { \xeCJK_peek_catcode_ignore_spaces:NTF \c_catcode_letter_token { \bool_if:NTF \l__xeCJK_peek_ignore_spaces_bool { \bool_if:NTF \l__xeCJK_reserve_space_bool { \__xeCJK_check_single_save:N #1 #2 ~ } { \__xeCJK_check_single_space:NN #1#2 } } { \__xeCJK_check_single_save:N #1 #2 } } { \group_align_safe_begin: \token_if_other:NTF \l_peek_token { \group_align_safe_end: \bool_if:NTF \l__xeCJK_peek_ignore_spaces_bool { \__xeCJK_check_single_space:NN #1#2 } { \__xeCJK_check_single_save:N #1 #2 } } { \token_if_cs:NTF \l_peek_token { \group_align_safe_end: \bool_if:NTF \l__xeCJK_peek_ignore_spaces_bool { \xeCJK_check_single_cs:NNn #1#2 { ~ } } { \xeCJK_check_single_cs:NNn #1#2 { } } } { \group_align_safe_end: \bool_if:nTF { \l__xeCJK_plain_equation_bool && \token_if_math_toggle_p:N \l_peek_token } { \bool_if:NTF \l__xeCJK_peek_ignore_spaces_bool { \xeCJK_check_single_equation:NNnNw #1 #2 { ~ } } { \xeCJK_check_single_equation:NNnNw #1 #2 { } } } { \bool_if:NTF \l__xeCJK_peek_ignore_spaces_bool { \__xeCJK_check_single_save:N #1 #2 ~ } { \__xeCJK_check_single_save:N #1 #2 } } } } } } \cs_new_protected_nopar:Npn \__xeCJK_check_single_space:NN #1#2 { \xeCJK_if_CJK_class:NTF #2 { \xeCJK_if_CJK_class:NTF \l_peek_token { \__xeCJK_check_single_save:N #1 #2 } { \__xeCJK_check_single_save:N #1 #2 ~ } } { \__xeCJK_check_single_save:N #1 #2 ~ } } \cs_new_protected_nopar:Npn \xeCJK_check_single_equation:NNnNw #1#2#3#4 { \peek_catcode:NTF \c_math_toggle_token { \xeCJK_widow_penalty: \__xeCJK_check_single_save:N #1 \xeCJK_make_node:n { CJK-widow } #2 #4 } { \__xeCJK_check_single_save:N #1 #2#3#4 } } \cs_new_protected_nopar:Npn \xeCJK_check_single_cs:NNn #1#2#3 { \group_align_safe_begin: \tl_case:NoF \l_peek_token { \l__xeCJK_check_single_cs_case_tl } { \group_align_safe_end: \use_iii:nnn } { \xeCJK_check_single_env:nnNn } { \xeCJK_widow_penalty: \__xeCJK_check_single_save:N #1 \xeCJK_make_node:n { CJK-widow } #2#3 } { \__xeCJK_check_single_save:N #1 #2#3 } } \tl_new:N \l__xeCJK_check_single_cs_case_tl \cs_generate_variant:Nn \tl_case:NnF { No } \cs_new_protected_nopar:Npn \xeCJK_check_single_env:nnNn #1#2#3#4 { \group_align_safe_begin: \str_case_x:noTF {#4} { \l__xeCJK_inline_env_case_tl } { \group_align_safe_end: #2 } { \group_align_safe_end: #1 } #3 {#4} } \cs_generate_variant:Nn \str_case_x:nnTF { no } \xeCJK_cs_case_keys_define:nNNnn { NewLineCS } \l__xeCJK_new_line_cs_case_tl \l__xeCJK_new_line_cs_seq { \group_align_safe_end: \use_ii:nnn } { \tl_concat:NNN \l__xeCJK_check_single_cs_case_tl \l__xeCJK_new_line_cs_case_tl \l__xeCJK_env_cs_case_tl } \xeCJK_cs_case_keys_define:nNNnn { EnvCS } \l__xeCJK_env_cs_case_tl \l__xeCJK_env_cs_seq { \group_align_safe_end: \use:n } { \tl_concat:NNN \l__xeCJK_check_single_cs_case_tl \l__xeCJK_new_line_cs_case_tl \l__xeCJK_env_cs_case_tl } \keys_define:nn { xeCJK / options } { InlineEnv .code:n = { \seq_set_from_clist:Nn \l__xeCJK_inline_env_seq {#1} \__xeCJK_update_inline_env_case_tl: } , InlineEnv+ .code:n = { \clist_map_inline:nn {#1} { \seq_if_in:NnF \l__xeCJK_inline_env_seq {##1} { \seq_put_right:Nn \l__xeCJK_inline_env_seq {##1} } } \__xeCJK_update_inline_env_case_tl: } , InlineEnv- .code:n = { \clist_map_inline:nn {#1} { \seq_remove_all:Nn \l__xeCJK_inline_env_seq {##1} } \__xeCJK_update_inline_env_case_tl: } } \seq_new:N \l__xeCJK_inline_env_seq \cs_new_protected:Npn \__xeCJK_update_inline_env_case_tl: { \tl_clear:N \l__xeCJK_inline_env_case_tl \seq_map_inline:Nn \l__xeCJK_inline_env_seq { \tl_put_right:Nn \l__xeCJK_inline_env_case_tl { {##1} { } } } } \tl_new:N \l__xeCJK_inline_env_case_tl \keys_define:nn { xeCJK / options } { PlainEquation .bool_set:N = \l__xeCJK_plain_equation_bool } \seq_new:N \g__xeCJK_CJK_sub_class_seq \NewDocumentCommand \xeCJKDeclareSubCJKBlock { s > { \TrimSpaces } m m } { \xeCJK_declare_sub_char_class:nxn { CJK } {#2} {#3} \IfBooleanT {#1} { \xeCJKResetPunctClass } } \@onlypreamble \xeCJKDeclareSubCJKBlock \bool_new:N \l__xeCJK_sub_cancel_bool \NewDocumentCommand \xeCJKCancelSubCJKBlock { s m } { \bool_if:NF \l__xeCJK_sub_cancel_bool { \bool_set_true:N \l__xeCJK_sub_cancel_bool \__xeCJK_sub_restore_or_cancel:x {#2} \IfBooleanT {#1} { \xeCJKResetPunctClass } } } \NewDocumentCommand \xeCJKRestoreSubCJKBlock { s m } { \bool_if:NT \l__xeCJK_sub_cancel_bool { \bool_set_false:N \l__xeCJK_sub_cancel_bool \__xeCJK_sub_restore_or_cancel:x {#2} \IfBooleanT {#1} { \xeCJKResetPunctClass } } } \cs_new_protected_nopar:Npn \__xeCJK_sub_restore_or_cancel:n #1 { \clist_map_inline:nn {#1} { \int_if_exist:cTF { \__xeCJK_class_csname:n { CJK/##1 } } { \xeCJK_declare_char_class:nc { CJK \bool_if:NF \l__xeCJK_sub_cancel_bool { /##1 } } { g__xeCJK_CJK/##1_range_clist } } { \__xeCJK_error:nx { SubBlock-undefined } {##1} } } } \cs_generate_variant:Nn \__xeCJK_sub_restore_or_cancel:n { x } \__xeCJK_msg_new:nn { SubBlock-undefined } { The~CJK~sub~block~`#1'~is~undefined.\\\\ Try~to~use~\token_to_str:N \xeCJKDeclareSubCJKBlock \ to~declare~it. } \cs_new_protected_nopar:Npn \xeCJK_declare_sub_char_class:nnn #1#2#3 { \int_if_exist:cF { \__xeCJK_class_csname:n { #1/#2 } } { \xeCJK_new_class:n { #1/#2 } \__xeCJK_set_sub_class_toks:nn {#1} {#2} \xeCJK_new_sub_key:n {#2} } \xeCJK_declare_char_class:nn { #1/#2 } {#3} } \cs_generate_variant:Nn \xeCJK_declare_sub_char_class:nnn { nx } \cs_new_protected_nopar:Npn \__xeCJK_set_sub_class_toks:nn #1#2 { \seq_map_inline:Nn \g__xeCJK_base_class_seq { \xeCJK_copy_inter_class_toks:nnnn { #1/#2 } {##1} {#1} {##1} \xeCJK_copy_inter_class_toks:nnnn {##1} { #1/#2 } {##1} {#1} \str_if_eq:nnTF {##1} { CJK } { \xeCJK_pre_inter_class_toks:nnn {##1} { #1/#2 } { \__xeCJK_switch_font:nn {#1} {#2} } } { \xeCJK_replace_inter_class_toks:nnnn {##1} { #1/#2 } { \CJKsymbol } { \__xeCJK_switch_font:nn {#1} {#2} \CJKsymbol } } } \xeCJK_copy_inter_class_toks:nnnn { #1/#2 } { #1/#2 } {#1} {#1} \seq_map_inline:Nn \g__xeCJK_CJK_sub_class_seq { \xeCJK_copy_inter_class_toks:nnnn { #1/#2 } { #1/##1 } {#1} {#1} \xeCJK_copy_inter_class_toks:nnnn { #1/##1 } { #1/#2 } {#1} {#1} \xeCJK_pre_inter_class_toks:nnn { #1/#2 } { #1/##1 } { \__xeCJK_switch_font:nn {#2} {##1} } \xeCJK_pre_inter_class_toks:nnn { #1/##1 } { #1/#2 } { \__xeCJK_switch_font:nn {##1} {#2} } } \seq_gput_right:Nn \g__xeCJK_CJK_sub_class_seq {#2} \__xeCJK_save_CJK_class:n { #1/#2 } \clist_map_inline:nn { CJK , FullLeft , FullRight , HangulJamo } { \xeCJK_pre_inter_class_toks:nnn { #1/#2 } {##1} { \__xeCJK_switch_font:nn {#2} {#1} } } } \cs_if_exist:NF \xetex_glyphbounds:D { \__xeCJK_msg_new:nn { XeTeX-too-old } { \token_to_str:N \xetex_glyphbounds:D \ is~not~defined.\\ CJK~punctuation~kerning~will~not~be~available.\\\\ You~have~to~update~XeTeX~to~the~version~0.9995.0~or~later. } \__xeCJK_error:n { XeTeX-too-old } \AtEndOfPackage { \keys_define:nn { xeCJK / options } { PunctStyle / unknown .code:n = { \__xeCJK_error:nx { punct-style-unknown } { \l_keys_value_tl } } } \seq_gclear:N \g__xeCJK_punct_style_seq \keys_set:nn { xeCJK / options } { PunctStyle = plain } } } \NewDocumentCommand \xeCJKsetwidth { s m m } { \IfBooleanTF {#1} { \tl_map_inline:xn {#2} { \tl_gset:cn { g__xeCJK_punct_bound_width/##1/tl } {#3} } } { \tl_map_inline:xn {#2} { \tl_gset:cn { g__xeCJK_punct_width/##1/tl } {#3} } } } \@onlypreamble \xeCJKsetwidth \cs_generate_variant:Nn \tl_map_inline:nn { x } \NewDocumentCommand \xeCJKsetkern { m m m } { \tl_gset:cn { g__xeCJK_punct/kern/#1/#2/tl } {#3} } \@onlypreamble \xeCJKsetkern \tl_const:Nn \c__xeCJK_left_tl { left } \tl_const:Nn \c__xeCJK_right_tl { right } \keys_define:nn { xeCJK / options } { AllowBreakBetweenPuncts .choice: , AllowBreakBetweenPuncts / true .code:n = { \bool_set_true:N \l__xeCJK_punct_breakable_bool \cs_set_eq:NN \xeCJK_punct_kern:NN \__xeCJK_punct_breakable_kern:NN } , AllowBreakBetweenPuncts / false .code:n = { \bool_set_false:N \l__xeCJK_punct_breakable_bool \cs_set_eq:NN \xeCJK_punct_kern:NN \__xeCJK_punct_nobreak_kern:NN } , AllowBreakBetweenPuncts .default:n = { true } , KaiMingPunct .code:n = { \__xeCJK_set_special_punct:nn { mixed_width } {#1} } , KaiMingPunct+ .code:n = { \__xeCJK_add_special_punct:nn { mixed_width } {#1} } , KaiMingPunct- .code:n = { \__xeCJK_sub_special_punct:nn { mixed_width } {#1} } , LongPunct .code:n = { \__xeCJK_set_special_punct:nn { long } {#1} } , LongPunct+ .code:n = { \__xeCJK_add_special_punct:nn { long } {#1} } , LongPunct- .code:n = { \__xeCJK_sub_special_punct:nn { long } {#1} } , MiddlePunct .code:n = { \__xeCJK_set_special_punct:nn { middle } {#1} } , MiddlePunct+ .code:n = { \__xeCJK_add_special_punct:nn { middle } {#1} } , MiddlePunct- .code:n = { \__xeCJK_sub_special_punct:nn { middle } {#1} } , PunctWidth .tl_gset:N = \g__xeCJK_punct_width_tl , PunctBoundWidth .tl_gset:N = \g__xeCJK_punct_bound_width_tl , PunctWidth .value_required: , PunctBoundWidth .value_required: , RubberPunctSkip .choice: , RubberPunctSkip .default:n = { true } , RubberPunctSkip / true .code:n = { \cs_set_eq:NN \__xeCJK_use_dim_or_skip:nnn \__xeCJK_use_punct_skip:nnn } , RubberPunctSkip / plus .code:n = { \cs_set_eq:NN \__xeCJK_use_dim_or_skip:nnn \__xeCJK_use_punct_skip_plus:nnn } , RubberPunctSkip / minus .code:n = { \cs_set_eq:NN \__xeCJK_use_dim_or_skip:nnn \__xeCJK_use_punct_skip_minus:nnn } , RubberPunctSkip / false .code:n = { \cs_set_eq:NN \__xeCJK_use_dim_or_skip:nnn \__xeCJK_use_punct_dim:nnn } } \bool_new:N \l__xeCJK_punct_breakable_bool \clist_new:N \g__xeCJK_special_punct_clist \clist_gset:Nn \g__xeCJK_special_punct_clist { mixed_width , long , middle } \cs_new_nopar:Npn \__xeCJK_special_punct_seq:n #1 { g__xeCJK_special_punct_#1_seq } \cs_new_nopar:Npn \__xeCJK_special_punct_tl:nN #1#2 { g__xeCJK_special_punct_#1_#2_tl } \clist_map_inline:Nn \g__xeCJK_special_punct_clist { \seq_new:c { \__xeCJK_special_punct_seq:n {#1} } } \cs_new_protected_nopar:Npn \__xeCJK_set_special_punct:nn #1#2 { \seq_map_inline:cn { \__xeCJK_special_punct_seq:n {#1} } { \cs_undefine:c { \__xeCJK_special_punct_tl:nN {#1} {##1} } } \seq_gclear:c { \__xeCJK_special_punct_seq:n {#1} } \tl_map_inline:xn {#2} { \tl_new:c { \__xeCJK_special_punct_tl:nN {#1} {##1} } \seq_gput_right:cn { \__xeCJK_special_punct_seq:n {#1} } {##1} } } \cs_new_protected_nopar:Npn \__xeCJK_add_special_punct:nn #1#2 { \tl_map_inline:xn {#2} { \seq_if_in:cnF { \__xeCJK_special_punct_seq:n {#1} } {##1} { \tl_new:c { \__xeCJK_special_punct_tl:nN {#1} {##1} } \seq_gput_right:cn { \__xeCJK_special_punct_seq:n {#1} } {##1} } } } \cs_new_protected_nopar:Npn \__xeCJK_sub_special_punct:nn #1#2 { \tl_map_inline:xn {#2} { \cs_undefine:c { \__xeCJK_special_punct_tl:nN {#1} {##1} } \seq_gremove_all:cn { \__xeCJK_special_punct_seq:n {#1} } {##1} } } \prg_new_conditional:Npnn \__xeCJK_punct_if_right:N #1 { p , T , F , TF } { \if_int_compare:w \xeCJK_token_value_class:N #1 = \xeCJK_class_num:n { FullRight } \prg_return_true: \else: \prg_return_false: \fi: } \clist_map_inline:Nn \g__xeCJK_special_punct_clist { \exp_args:Nc \prg_new_conditional:Npnn { __xeCJK_punct_if_#1:N } ##1 { p , T , F , TF } { \if_cs_exist:w \__xeCJK_special_punct_tl:nN {#1} {##1} \cs_end: \prg_return_true: \else: \prg_return_false: \fi: } } \cs_new:Npn \__xeCJK_punct_csname:n #1 { c__xeCJK_\l_xeCJK_current_font_tl/\l_xeCJK_punct_style_tl/#1/tl } \cs_new:Npn \__xeCJK_use_punct_dim:nn #1#2 { \use:c { \__xeCJK_punct_csname:n { dim/#1/#2 } } } \cs_new:Npn \__xeCJK_use_punct_dim:nnn #1#2#3 { \use:c { \__xeCJK_punct_csname:n { dim/#1/#2/#3 } } } \cs_new:Npn \__xeCJK_use_punct_skip:nnn #1#2#3 { \use:c { \__xeCJK_punct_csname:n { skip/#1/#2/#3 } } } \cs_new:Npn \__xeCJK_use_punct_skip_plus:nnn #1#2#3 { \use:c { \__xeCJK_punct_csname:n { skip/plus/#1/#2/#3 } } } \cs_new:Npn \__xeCJK_use_punct_skip_minus:nnn #1#2#3 { \use:c { \__xeCJK_punct_csname:n { skip/minus/#1/#2/#3 } } } \cs_new_protected:Npn \__xeCJK_save_punct_dim:nnn #1#2 { \__xeCJK_save_punct_width_aux:nnn { dim } { #1/#2 } } \cs_new_protected:Npn \__xeCJK_save_punct_dim:nnnn #1#2#3 { \__xeCJK_save_punct_width_aux:nnn { dim } { #1/#2/#3 } } \cs_new_protected:Npn \__xeCJK_save_punct_skip:nnnn #1#2#3#4 { \__xeCJK_save_punct_width_aux:nnn { skip } { #1/#2/#3 } {#4} \__xeCJK_save_punct_width_aux:nnn { skip } { plus/#1/#2/#3 } {#4} \__xeCJK_save_punct_width_aux:nnn { skip } { minus/#1/#2/#3 } {#4} } \cs_new_protected:Npn \__xeCJK_save_punct_skip:nnnnnn #1#2#3#4#5#6 { \use:x { \__xeCJK_save_punct_skip_aux:nnnn { #1/#2/#3 } { \dim_eval:n {#4} } { \dim_max:nn { \c_zero_dim } {#5} } { \dim_max:nn { \c_zero_dim } {#6} } } } \cs_new_protected:Npn \__xeCJK_save_punct_skip_aux:nnnn #1#2#3#4 { \__xeCJK_save_punct_width_aux:nnn { skip } {#1} { #2 ~ plus ~ #3 ~ minus ~ #4 ~ } \__xeCJK_save_punct_width_aux:nnn { skip } { plus/#1 } { #2 ~ plus ~ #3 ~ } \__xeCJK_save_punct_width_aux:nnn { skip } { minus/#1 } { #2 ~ minus ~ #4 ~ } } \cs_new_protected:Npn \__xeCJK_save_punct_width_aux:nnn #1#2#3 { \tl_const:cx { \__xeCJK_punct_csname:n { #1/#2 } } { \use:c { #1_eval:n } {#3} } } \cs_new_eq:NN \__xeCJK_use_dim_or_skip:nnn \__xeCJK_use_punct_skip:nnn \DeclareObjectType { xeCJK / punctuation } { \c_zero } \DeclareTemplateInterface { xeCJK / punctuation } { basic } { \c_zero } { enabled-global-setting : boolean = true , fixed-punct-width : length = \c_max_dim , fixed-punct-ratio : real = \c_one_fp , mixed-punct-width : length = \KeyValue { fixed-punct-width } , mixed-punct-ratio : real = \KeyValue { fixed-punct-ratio } , middle-punct-width : length = \KeyValue { fixed-punct-width } , middle-punct-ratio : real = \KeyValue { fixed-punct-ratio } , fixed-margin-width : length = \c_max_dim , fixed-margin-ratio : real = \c_one_fp , mixed-margin-width : length = \KeyValue { fixed-margin-width } , mixed-margin-ratio : real = \KeyValue { fixed-margin-ratio } , middle-margin-width : length = \KeyValue { fixed-margin-width } , middle-margin-ratio : real = \KeyValue { fixed-margin-ratio } , bound-punct-width : length = \c_max_dim , bound-punct-ratio : real = \c_nan_fp , bound-margin-width : length = \c_max_dim , bound-margin-ratio : real = \c_zero_fp , enabled-hanging : boolean = false , add-min-bound-to-margin : boolean = false , optimize-margin : boolean = false , margin-minimum : length = \c_zero_dim , enabled-kerning : boolean = true , min-bound-to-kerning : boolean = false , kerning-total-width : length = \c_max_dim , kerning-total-ratio : real = 0.75 , optimize-kerning : boolean = false , same-align-margin : length = \c_max_dim , same-align-ratio : real = \c_nan_fp , different-align-margin : length = \c_max_dim , different-align-ratio : real = \c_nan_fp , kerning-margin-width : length = \c_max_dim , kerning-margin-ratio : real = \c_one_fp , kerning-margin-minimum : length = \c_zero_dim } \DeclareTemplateCode { xeCJK / punctuation } { basic } { \c_zero } { enabled-global-setting = \l__xeCJK_enabled_global_setting_bool , fixed-punct-width = \l__xeCJK_fixed_punct_width_dim , fixed-punct-ratio = \l__xeCJK_fixed_punct_ratio_fp , mixed-punct-width = \l__xeCJK_mixed_punct_width_dim , mixed-punct-ratio = \l__xeCJK_mixed_punct_ratio_fp , middle-punct-width = \l__xeCJK_middle_punct_width_dim , middle-punct-ratio = \l__xeCJK_middle_punct_ratio_fp , fixed-margin-width = \l__xeCJK_fixed_margin_width_dim , fixed-margin-ratio = \l__xeCJK_fixed_margin_ratio_fp , mixed-margin-width = \l__xeCJK_mixed_margin_width_dim , mixed-margin-ratio = \l__xeCJK_mixed_margin_ratio_fp , middle-margin-width = \l__xeCJK_middle_margin_width_dim , middle-margin-ratio = \l__xeCJK_middle_margin_ratio_fp , bound-punct-width = \l__xeCJK_bound_punct_width_dim , bound-punct-ratio = \l__xeCJK_bound_punct_ratio_fp , bound-margin-width = \l__xeCJK_bound_margin_width_dim , bound-margin-ratio = \l__xeCJK_bound_margin_ratio_fp , enabled-hanging = \l__xeCJK_enabled_hanging_bool , add-min-bound-to-margin = \l__xeCJK_add_min_bound_to_margin_bool , optimize-margin = \l__xeCJK_optimize_margin_bool , margin-minimum = \l__xeCJK_margin_minimum_dim , enabled-kerning = \l__xeCJK_enabled_kerning_bool , min-bound-to-kerning = \l__xeCJK_min_bound_to_kerning_bool , kerning-total-width = \l__xeCJK_kerning_total_width_dim , kerning-total-ratio = \l__xeCJK_kerning_total_ratio_fp , optimize-kerning = \l__xeCJK_optimize_kerning_bool , same-align-margin = \l__xeCJK_same_align_margin_dim , same-align-ratio = \l__xeCJK_same_align_ratio_fp , different-align-margin = \l__xeCJK_different_align_margin_dim , different-align-ratio = \l__xeCJK_different_align_ratio_fp , kerning-margin-width = \l__xeCJK_kerning_margin_width_dim , kerning-margin-ratio = \l__xeCJK_kerning_margin_ratio_fp , kerning-margin-minimum = \l__xeCJK_kerning_margin_minimum_dim } { \AssignTemplateKeys } \cs_new_protected_nopar:Npn \xeCJK_get_punct_bounds:NN #1#2 { \tl_if_exist:cF { \__xeCJK_punct_csname:n { dim/glue/#1/#2 } } { \tl_if_eq:NNTF \l_xeCJK_punct_style_tl \c__xeCJK_punct_style_plain_tl { \__xeCJK_save_punct_dim:nnnn { rule } {#1} {#2} { \c_zero_dim } \__xeCJK_save_punct_dim:nnnn { glue } {#1} {#2} { \c_zero_dim } \__xeCJK_save_punct_dim:nnnn { offset } {#1} {#2} { \c_zero_dim } \__xeCJK_save_punct_dim:nnnn { bound } \c__xeCJK_left_tl {#2} { \c_zero_dim } \__xeCJK_save_punct_dim:nnnn { bound } \c__xeCJK_right_tl {#2} { \c_zero_dim } \__xeCJK_save_punct_skip:nnnn { glue } {#1} {#2} { \c_zero_skip } } { { \xeCJK_select_font: \xeCJK_calc_punct_dimen:o {#2} } \dim_set:Nn \l__xeCJK_bound_dim { \__xeCJK_use_punct_dim:nnn { bound } {#1} {#2} } \dim_set:Nn \l__xeCJK_reverse_bound_dim { \__xeCJK_use_punct_dim:nnn { bound } { \xeCJK_reverse:nnn {#1} \c__xeCJK_left_tl \c__xeCJK_right_tl } {#2} } \UseInstance { xeCJK / punctuation } { \l_xeCJK_punct_style_tl } \xeCJK_punct_margin_process:NN {#1} {#2} \xeCJK_punct_offset_process:NN {#1} {#2} } } } \dim_new:N \l__xeCJK_bound_dim \dim_new:N \l__xeCJK_reverse_bound_dim \cs_new_protected_nopar:Npn \xeCJK_get_punct_kerning:NN #1#2 { \tl_if_exist:cF { \__xeCJK_punct_csname:n { dim/kern/#1/#2 } } { \tl_if_eq:NNTF \l_xeCJK_punct_style_tl \c__xeCJK_punct_style_plain_tl { \__xeCJK_save_punct_dim:nnnn { kern } {#1} {#2} { \c_zero_dim } \__xeCJK_save_punct_dim:nnnn { break_kern } {#1} {#2} { \c_zero_dim } \__xeCJK_save_punct_skip:nnnn { kern } {#1} {#2} { \c_zero_skip } \__xeCJK_save_punct_skip:nnnn { break_kern } {#1} {#2} { \c_zero_skip } } { \UseInstance { xeCJK / punctuation } { \l_xeCJK_punct_style_tl } \xeCJK_punct_kerning_process:NN {#1} {#2} } } } \cs_generate_variant:Nn \xeCJK_get_punct_kerning:NN { o } \cs_new_protected_nopar:Npn \xeCJK_punct_margin_process:NN #1#2 { \dim_set:Nn \l__xeCJK_tmp_dim { \bool_if:NTF \l__xeCJK_enabled_global_setting_bool { \cs_if_exist_use:cTF { g__xeCJK_punct_width/#2/tl } { \use_none:n } { \tl_if_empty:NTF \g__xeCJK_punct_width_tl { \use:n } { \g__xeCJK_punct_width_tl \use_none:n } } } { \use:n } { \__xeCJK_punct_if_middle:NTF {#2} { \__xeCJK_punct_width_or_ratio:nN { middle } {#2} } { \__xeCJK_punct_if_mixed_width:NTF {#2} { \__xeCJK_punct_width_or_ratio:nN { mixed } {#2} } { \__xeCJK_punct_width_or_ratio:nN { fixed } {#2} } } } } \dim_set:Nn \l__xeCJK_tmp_dim { \dim_max:nn { \l__xeCJK_margin_minimum_dim } { \dim_compare:nNnTF \l__xeCJK_tmp_dim < \c_max_dim { \__xeCJK_punct_if_middle:NTF {#2} { ( \l__xeCJK_tmp_dim - ( \__xeCJK_use_punct_dim:nn { dimen } {#2} ) ) / \c_two } { \bool_if:NTF \l__xeCJK_optimize_margin_bool { \dim_max:nn { \dim_min:nn \l__xeCJK_bound_dim \l__xeCJK_reverse_bound_dim } } { \use:n } { \l__xeCJK_tmp_dim - \l__xeCJK_reverse_bound_dim - ( \__xeCJK_use_punct_dim:nn { dimen } {#2} ) } } } { \bool_if:NTF \l__xeCJK_optimize_margin_bool { \dim_min:nn { \l__xeCJK_bound_dim } } { \use:n } { \__xeCJK_punct_if_middle:NTF {#2} { \dim_compare:nNnTF \l__xeCJK_middle_margin_width_dim < \c_max_dim { \l__xeCJK_middle_margin_width_dim } { \fp_use:N \l__xeCJK_middle_margin_ratio_fp \etex_dimexpr:D ( \l__xeCJK_bound_dim + \l__xeCJK_reverse_bound_dim ) / \c_two \scan_stop: } } { \__xeCJK_punct_if_mixed_width:NTF {#2} { \__xeCJK_margin_width_or_ratio:n { mixed } } { \__xeCJK_margin_width_or_ratio:n { fixed } } } } } } } \__xeCJK_save_punct_dim:nnnn { glue } {#1} {#2} { \l__xeCJK_tmp_dim } \__xeCJK_save_punct_skip:nnnnnn { glue } {#1} {#2} { \l__xeCJK_tmp_dim } { \__xeCJK_punct_if_middle:NTF {#2} { ( \__xeCJK_use_punct_dim:nn { width } {#2} - \__xeCJK_use_punct_dim:nn { dimen } {#2} ) / \c_two - \l__xeCJK_tmp_dim } { \l__xeCJK_bound_dim - \l__xeCJK_tmp_dim } } { \__xeCJK_punct_if_middle:NTF {#2} { .5 \l__xeCJK_tmp_dim } { \l__xeCJK_tmp_dim - \l__xeCJK_reverse_bound_dim } } } \cs_new_protected_nopar:Npn \xeCJK_punct_offset_process:NN #1#2 { \dim_set:Nn \l__xeCJK_tmp_dim { \bool_if:NTF \l__xeCJK_enabled_global_setting_bool { \cs_if_exist_use:cTF { g__xeCJK_punct_bound_width/#2/tl } { \use_none:n } { \tl_if_empty:NTF \g__xeCJK_punct_bound_width_tl { \use:n } { \g__xeCJK_punct_bound_width_tl \use_none:n } } } { \use:n } { \__xeCJK_punct_width_or_ratio:nN { bound } {#2} } } \dim_set:Nn \l__xeCJK_tmp_dim { \bool_if:NTF \l__xeCJK_enabled_hanging_bool { \use:n } { \dim_max:nn { \l__xeCJK_margin_minimum_dim } } { \dim_compare:nNnTF \l__xeCJK_tmp_dim < \c_max_dim { \__xeCJK_punct_if_middle:NTF {#2} { \l__xeCJK_tmp_dim - ( \__xeCJK_use_punct_dim:nnn { glue } {#1} {#2} ) - ( \__xeCJK_use_punct_dim:nn { dimen } {#2} ) } { \l__xeCJK_tmp_dim - \l__xeCJK_reverse_bound_dim - ( \__xeCJK_use_punct_dim:nn { dimen } {#2} ) } } { \bool_if:NTF \l__xeCJK_optimize_margin_bool { \dim_min:nn { \l__xeCJK_bound_dim } } { \use:n } { \__xeCJK_margin_width_or_ratio:n { bound } } } } } \__xeCJK_save_punct_dim:nnnn { offset } {#1} {#2} { \l__xeCJK_tmp_dim } \__xeCJK_save_punct_dim:nnnn { rule } {#1} {#2} { - \l__xeCJK_bound_dim + \l__xeCJK_tmp_dim } } \cs_new_nopar:Npn \__xeCJK_punct_width_or_ratio:nN #1#2 { \dim_compare:nNnTF { \use:c { l__xeCJK_#1_punct_width_dim } } < \c_max_dim { \use:c { l__xeCJK_#1_punct_width_dim } } { \fp_compare:nNnTF { \use:c { l__xeCJK_#1_punct_ratio_fp } } ? \c_zero_fp { \c_max_dim } { \fp_use:c { l__xeCJK_#1_punct_ratio_fp } \etex_dimexpr:D \__xeCJK_use_punct_dim:nn { width } {#2} \scan_stop: } } } \cs_new_nopar:Npn \__xeCJK_margin_width_or_ratio:n #1 { \dim_compare:nNnTF { \use:c { l__xeCJK_#1_margin_width_dim } } < \c_max_dim { \use:c { l__xeCJK_#1_margin_width_dim } } { \fp_use:c { l__xeCJK_#1_margin_ratio_fp } \etex_dimexpr:D \l__xeCJK_bound_dim \scan_stop: } \bool_if:NT \l__xeCJK_add_min_bound_to_margin_bool { + \dim_min:nn \l__xeCJK_bound_dim \l__xeCJK_reverse_bound_dim } } \cs_new_protected_nopar:Npn \xeCJK_punct_kerning_process:NN #1#2 { \dim_set:Nn \l__xeCJK_original_margin_dim { \__xeCJK_original_kerning_margin:NN {#1} {#2} } \dim_set:Nn \l__xeCJK_minimum_bound_dim { \__xeCJK_punct_min_bound:NN {#1} {#2} } \dim_set:Nn \l__xeCJK_kerning_margin_dim { \bool_if:nTF { \l__xeCJK_enabled_global_setting_bool && \tl_if_exist_p:c { g__xeCJK_punct/kern/#1/#2/tl } } { \use:c { g__xeCJK_punct/kern/#1/#2/tl } } { \bool_if:NTF \l__xeCJK_enabled_kerning_bool { \__xeCJK_calc_kerning_margin:NN {#1} {#2} } { \l__xeCJK_original_margin_dim } } } \__xeCJK_save_kerning:nnNN { kern } { bound } {#1} {#2} \__xeCJK_punct_if_right:NF {#2} { \__xeCJK_punct_if_right:NT {#1} { \__xeCJK_save_kerning:nnNN { break_kern } { offset } {#1} {#2} } } } \dim_new:N \l__xeCJK_minimum_bound_dim \dim_new:N \l__xeCJK_kerning_margin_dim \dim_new:N \l__xeCJK_original_margin_dim \cs_new_protected_nopar:Npn \__xeCJK_save_kerning:nnNN #1#2#3#4 { \dim_set:Nn \l__xeCJK_tmp_dim { \l__xeCJK_kerning_margin_dim - ( \__xeCJK_use_punct_dim:nnn {#2} \c__xeCJK_right_tl {#3} ) - ( \__xeCJK_use_punct_dim:nnn {#2} \c__xeCJK_left_tl {#4} ) } \__xeCJK_save_punct_dim:nnnn {#1} {#3} {#4} { \l__xeCJK_tmp_dim } \__xeCJK_save_punct_skip:nnnnnn {#1} {#3} {#4} { \l__xeCJK_tmp_dim } { \l__xeCJK_original_margin_dim - \l__xeCJK_kerning_margin_dim } { \l__xeCJK_kerning_margin_dim - \l__xeCJK_minimum_bound_dim } } \cs_new_nopar:Npn \__xeCJK_original_kerning_margin:NN #1#2 { \dim_eval:n { \__xeCJK_use_punct_dim:nnn { \__xeCJK_punct_if_right:NTF {#1} { glue } { bound } } { \c__xeCJK_right_tl } {#1} + \__xeCJK_use_punct_dim:nnn { \__xeCJK_punct_if_right:NTF {#2} { bound } { glue } } { \c__xeCJK_left_tl } {#2} } } \cs_new_nopar:Npn \__xeCJK_calc_kerning_margin:NN #1#2 { \dim_max:nn { \l__xeCJK_kerning_margin_minimum_dim } { \bool_if:NTF \l__xeCJK_min_bound_to_kerning_bool { \l__xeCJK_minimum_bound_dim } { \bool_if:NTF \l__xeCJK_optimize_kerning_bool { \dim_max:nn { \l__xeCJK_minimum_bound_dim } } { \use:n } { \dim_compare:nNnTF \l__xeCJK_kerning_total_width_dim < \c_max_dim { \__xeCJK_calc_kerning_margin:nNN \l__xeCJK_kerning_total_width_dim } { \fp_compare:nNnTF \l__xeCJK_kerning_total_ratio_fp ? \c_zero_fp { \xeCJK_if_same_class:NNTF {#1} {#2} { \__xeCJK_kerning_width_or_ratio:nNN { same } } { \__xeCJK_kerning_width_or_ratio:nNN { different } } } { \__xeCJK_calc_kerning_margin:nNN { \fp_use:N \l__xeCJK_kerning_total_ratio_fp \etex_dimexpr:D \__xeCJK_use_punct_dim:nn { width } {#1} + \__xeCJK_use_punct_dim:nn { width } {#2} \scan_stop: } } } {#1} {#2} } } } } \cs_new_nopar:Npn \__xeCJK_kerning_width_or_ratio:nNN #1#2#3 { \dim_compare:nNnTF { \use:c { l__xeCJK_#1_align_margin_dim } } < \c_max_dim { \use:c { l__xeCJK_#1_align_margin_dim } } { \fp_compare:nNnTF { \use:c { l__xeCJK_#1_align_ratio_fp } } ? \c_zero_fp { \dim_compare:nNnTF \l__xeCJK_kerning_margin_width_dim < \c_max_dim { \l__xeCJK_kerning_margin_width_dim \use_none:n } { \fp_use:N \l__xeCJK_kerning_margin_ratio_fp \use:n } } { \fp_use:c { l__xeCJK_#1_align_ratio_fp } \use:n } { \l__xeCJK_original_margin_dim } } } \cs_new_nopar:Npn \__xeCJK_punct_min_bound:NN #1#2 { \dim_max:nn { \dim_min:nn { \__xeCJK_use_punct_dim:nnn { bound } \c__xeCJK_left_tl {#1} } { \__xeCJK_use_punct_dim:nnn { bound } \c__xeCJK_right_tl {#1} } } { \dim_min:nn { \__xeCJK_use_punct_dim:nnn { bound } \c__xeCJK_left_tl {#2} } { \__xeCJK_use_punct_dim:nnn { bound } \c__xeCJK_right_tl {#2} } } } \cs_new_nopar:Npn \__xeCJK_calc_kerning_margin:nNN #1#2#3 { \dim_eval:n { (#1) - ( \__xeCJK_use_punct_dim:nnn { \__xeCJK_punct_if_right:NTF {#2} { bound } { glue } } { \c__xeCJK_left_tl } {#2} ) - ( \__xeCJK_use_punct_dim:nnn { \__xeCJK_punct_if_right:NTF {#3} { glue } { bound } } { \c__xeCJK_right_tl } {#3} ) - ( \__xeCJK_use_punct_dim:nn { dimen } {#2} ) - ( \__xeCJK_use_punct_dim:nn { dimen } {#3} ) } } \cs_new_protected_nopar:Npn \xeCJK_calc_punct_dimen:N #1 { \__xeCJK_save_punct_dim:nnnn { bound } \c__xeCJK_left_tl {#1} { \xeCJK_glyph_bounds:NN \c_one {#1} } \__xeCJK_save_punct_dim:nnnn { bound } \c__xeCJK_right_tl {#1} { \xeCJK_glyph_bounds:NN \c_three {#1} } \dim_set:Nn \l__xeCJK_tmp_dim { ( \__xeCJK_use_punct_dim:nnn { bound } \c__xeCJK_left_tl {#1} ) + ( \__xeCJK_use_punct_dim:nnn { bound } \c__xeCJK_right_tl {#1} ) } \__xeCJK_save_punct_dim:nnn { width } {#1} { \etex_fontcharwd:D \tex_font:D \xeCJK_token_value_charcode:N #1 } \__xeCJK_save_punct_dim:nnn { dimen } {#1} { \__xeCJK_use_punct_dim:nn { width } {#1} - \l__xeCJK_tmp_dim } \__xeCJK_punct_if_long:NT {#1} { \dim_set:Nn \l__xeCJK_tmp_dim { \str_case:nnTF {#1} { { ^^^^2025 } { } { ^^^^2026 } { } } { \c_zero_dim } { - \l__xeCJK_tmp_dim } } \__xeCJK_save_punct_dim:nnnn { kern } {#1} {#1} { \l__xeCJK_tmp_dim } \__xeCJK_save_punct_skip:nnnn { kern } {#1} {#1} { \l__xeCJK_tmp_dim } } } \cs_generate_variant:Nn \xeCJK_calc_punct_dimen:N { o } \cs_new_nopar:Npn \xeCJK_glyph_bounds:NN #1#2 { \dim_use:N \xetex_glyphbounds:D #1 ~ \xetex_charglyph:D \xeCJK_token_value_charcode:N #2 \exp_stop_f: } \keys_define:nn { xeCJK / options } { PunctStyle .choice: , PunctStyle .default:n = { quanjiao } , PunctStyle / halfwidth .meta:n = { PunctStyle = banjiao } , PunctStyle / fullwidth .meta:n = { PunctStyle = quanjiao } , PunctStyle / mixedwidth .meta:n = { PunctStyle = kaiming } , PunctStyle / marginkerning .meta:n = { PunctStyle = hangmobanjiao } , PunctStyle / plain .code:n = { \tl_set_eq:NN \l_xeCJK_punct_style_tl \c__xeCJK_punct_style_plain_tl } , PunctStyle / unknown .code:n = { \IfInstanceExistTF { xeCJK / punctuation } { \l_keys_value_tl } { \tl_set:Nx \l_xeCJK_punct_style_tl { \l_keys_value_tl } } { \__xeCJK_error:nx { punct-style-unknown } { \l_keys_value_tl } } } } \tl_new:N \l_xeCJK_punct_style_tl \tl_const:Nn \c__xeCJK_punct_style_plain_tl { plain } \__xeCJK_msg_new:nn { punct-style-unknown } { Punctuation~style~"#1"~is~unknown. \\\\ The~available~styles~are~listed~as~follow.\\\\ "plain,~\seq_use:Nnnn \g__xeCJK_punct_style_seq { ~and~ } { ,~ } { ,~and~ }".\\ } \NewDocumentCommand \xeCJKDeclarePunctStyle { > { \TrimSpaces } m m } { \IfInstanceExistTF { xeCJK / punctuation } {#1} { \__xeCJK_warning:nx { punct-style-already-defined } {#1} } { \seq_gput_right:Nx \g__xeCJK_punct_style_seq {#1} } \exp_args:Nnx \DeclareInstance { xeCJK / punctuation } {#1} { basic } {#2} } \seq_new:N \g__xeCJK_punct_style_seq \__xeCJK_msg_new:nn { punct-style-already-defined } { Punctuation~style~"#1"~is~already~defined!. \\\\ The~existing~style~of~"#1"~will~be~overwritten.\\ } \@onlypreamble \xeCJKDeclarePunctStyle \NewDocumentCommand \xeCJKEditPunctStyle { > { \TrimSpaces } m m } { \IfInstanceExistTF { xeCJK / punctuation } {#1} { \exp_args:Nnx \EditInstance { xeCJK / punctuation } {#1} {#2} } { \__xeCJK_error:nx { punct-style-unknown } {#1} } } \@onlypreamble \xeCJKEditPunctStyle \xeCJKDeclarePunctStyle { quanjiao } { } \xeCJKDeclarePunctStyle { hangmobanjiao } { enabled-kerning = false } \xeCJKDeclarePunctStyle { banjiao } { fixed-punct-ratio = 0.5 , optimize-margin = true , kerning-total-ratio = 0.5 , optimize-kerning = true } \xeCJKDeclarePunctStyle { kaiming } { fixed-punct-ratio = 0.5 , mixed-punct-ratio = 0.8 , optimize-margin = true , kerning-total-ratio = 0.5 , optimize-kerning = true } \xeCJKDeclarePunctStyle { CCT } { fixed-punct-ratio = 0.7 , optimize-margin = true , kerning-total-ratio = 0.6 , optimize-kerning = true } \keys_define:nn { xeCJK / options } { AutoFallBack .choice: , AutoFallBack / true .code:n = { \cs_if_eq:NNF \CJKsymbol \xeCJK_fallback_test_glyph:N { \cs_set_eq:NN \__xeCJK_fallback_save_CJKsymbol:N \CJKsymbol \cs_set_eq:NN \CJKsymbol \xeCJK_fallback_test_glyph:N } } , AutoFallBack / false .code:n = { \cs_if_eq:NNT \CJKsymbol \xeCJK_fallback_test_glyph:N { \cs_set_eq:NN \CJKsymbol \__xeCJK_fallback_save_CJKsymbol:N } } , AutoFallBack .default:n = { true } , fallback .meta:n = { AutoFallBack = true } } \cs_new_protected_nopar:Npn \xeCJK_fallback_test_glyph:N #1 { \xeCJK_glyph_if_exist:NTF {#1} { \__xeCJK_fallback_save_CJKsymbol:N {#1} } { \xeCJK_class_group_begin: \tl_set_eq:NN \l__xeCJK_fallback_family_tl \l_xeCJK_family_tl \xeCJK_fallback_loop:Nn {#1} { \l_xeCJK_family_tl/FallBack } \xeCJK_class_group_end: } } \cs_new_protected_nopar:Npn \xeCJK_fallback_loop:Nn #1#2 { \xeCJK_family_if_exist:xTF {#2} { \tl_set:Nx \l_xeCJK_family_tl {#2} \tl_set_eq:NN \CJK@family \l__xeCJK_fontspec_family_tl \xeCJK_select_font: \xeCJK_glyph_if_exist:NTF {#1} { \__xeCJK_fallback_save_CJKsymbol:N {#1} } { \xeCJK_fallback_loop:Nn {#1} { \l_xeCJK_family_tl/FallBack } } } { \str_if_eq_x:nnTF { \CJKfamilydefault } { \l__xeCJK_fallback_family_tl } { \__xeCJK_warning:nxxx { missing-glyph } { \l_xeCJK_family_tl } {#1} { \int_to_Hex:n { `#1 } } \__xeCJK_fallback_save_CJKsymbol:N {#1} } { \tl_set:Nx \l__xeCJK_fallback_family_tl { \CJKfamilydefault } \xeCJK_fallback_loop:Nn {#1} { \l__xeCJK_fallback_family_tl } } } } \__xeCJK_msg_new:nn { missing-glyph } { CJKfamily~`\__xeCJK_msg_family_map:n {#1}'~ ( \prop_item:Nn \g__xeCJK_family_font_name_prop {#1} )~ does~not~contain~glyph~`#2'~(U+#3).\\ } \NewDocumentCommand \setCJKfallbackfamilyfont { m O { } m } { \use:x { \xeCJK_set_family_fallback:nnn {#1} {#2} {#3} } } \cs_new_protected_nopar:Npn \xeCJK_set_family_fallback:nnn #1#2#3 { \group_begin: \tl_set:Nn \l__xeCJK_fallback_family_tl {#1} \prop_get:NVNF \g__xeCJK_family_font_name_prop \l__xeCJK_fallback_family_tl \l__xeCJK_font_name_tl { \tl_clear:N \l__xeCJK_font_name_tl } \clist_map_inline:nn {#3} { \tl_put_right:Nn \l__xeCJK_fallback_family_tl { /FallBack } \__xeCJK_get_sub_features:Vn \l__xeCJK_fallback_family_tl {##1} \clist_put_left:Nn \l__xeCJK_sub_font_options_clist {#2} \xeCJK_set_family:VVV \l__xeCJK_fallback_family_tl \l__xeCJK_sub_font_options_clist \l__xeCJK_sub_font_name_tl } \group_end: } \tl_new:N \l__xeCJK_fallback_family_tl \bool_new:N \g__xeCJK_auto_fake_bold_bool \bool_new:N \g__xeCJK_auto_fake_slant_bool \fp_new:N \g__xeCJK_embolden_factor_fp \fp_new:N \g__xeCJK_slant_factor_fp \keys_define:nn { xeCJK / options } { AutoFakeBold .choices:nn = { true , false } { \use:c { bool_gset_ \l_keys_choice_tl :N } \g__xeCJK_auto_fake_bold_bool } , AutoFakeBold / unknown .code:n = { \bool_gset_true:N \g__xeCJK_auto_fake_bold_bool \fp_gset:Nn \g__xeCJK_embolden_factor_fp { \l_keys_value_tl } } , AutoFakeBold .default:n = { true } , AutoFakeSlant .choices:nn = { true , false } { \use:c { bool_gset_ \l_keys_choice_tl :N } \g__xeCJK_auto_fake_slant_bool } , AutoFakeSlant / unknown .code:n = { \bool_gset_true:N \g__xeCJK_auto_fake_slant_bool \fp_gset:Nn \g__xeCJK_slant_factor_fp { \l_keys_value_tl } } , AutoFakeSlant .default:n = { true } , EmboldenFactor .fp_gset:N = \g__xeCJK_embolden_factor_fp , SlantFactor .fp_gset:N = \g__xeCJK_slant_factor_fp , BoldFont .meta:n = { AutoFakeBold = true } , boldfont .meta:n = { AutoFakeBold = true } , SlantFont .meta:n = { AutoFakeSlant = true } , slantfont .meta:n = { AutoFakeSlant = true } } \seq_new:N \g__xeCJK_sub_key_seq \cs_new_protected_nopar:Npn \xeCJK_new_sub_key:n #1 { \seq_gput_right:Nn \g__xeCJK_sub_key_seq {#1} \keys_define:nn { xeCJK / features } { #1 .code:n = { \tl_if_blank:nTF {##1} { \prop_clear:N \l__xeCJK_sub_key_prop \tl_put_right:Nn \l__xeCJK_family_name_tl { /#1 } \clist_remove_all:Nn \l__xeCJK_font_options_clist {#1} } { \str_if_eq:nnTF {##1} { * } { \prop_put:Nnn \l__xeCJK_sub_key_prop {#1} { \q_no_value } } { \__xeCJK_get_sub_features:nn {#1} {##1} } } } , #1 .default:n = { } } } \cs_new_protected_nopar:Npn \__xeCJK_get_sub_features:nn #1#2 { \tl_set:Nx \l__xeCJK_tmp_tl { \xeCJK_tl_remove_outer_braces:n {#2} } \clist_clear:N \l__xeCJK_sub_font_options_clist \exp_after:wN \__xeCJK_get_sub_features:w \l__xeCJK_tmp_tl \q_mark [ \q_nil ] \q_mark \q_stop \tl_if_empty:NTF \l__xeCJK_sub_font_name_tl { \tl_set_eq:NN \l__xeCJK_sub_font_name_tl \l__xeCJK_font_name_tl } { \tl_replace_all:NnV \l__xeCJK_sub_font_name_tl { * } \l__xeCJK_font_name_tl } \prop_put:Nnx \l__xeCJK_sub_key_prop {#1} { { \exp_not:V \l__xeCJK_sub_font_options_clist } { \exp_not:V \l__xeCJK_sub_font_name_tl } } } \cs_new_protected_nopar:Npn \__xeCJK_get_sub_features:w #1 [#2] #3 \q_mark #4 \q_stop { \quark_if_nil:nTF {#2} { \tl_set_eq:NN \l__xeCJK_sub_font_name_tl \l__xeCJK_tmp_tl } { \tl_set:Nx \l__xeCJK_sub_font_name_tl { \xeCJK_tl_remove_outer_braces:n {#3} } \tl_if_empty:NTF \l__xeCJK_sub_font_name_tl { \tl_set_eq:NN \l__xeCJK_sub_font_name_tl \l__xeCJK_tmp_tl } { \clist_set:Nn \l__xeCJK_sub_font_options_clist {#2} } } } \tl_new:N \l__xeCJK_sub_family_name_tl \tl_new:N \l__xeCJK_sub_font_name_tl \clist_new:N \l__xeCJK_sub_font_options_clist \cs_generate_variant:Nn \__xeCJK_get_sub_features:nn { V } \cs_generate_variant:Nn \tl_replace_all:Nnn { NnV } \xeCJK_new_sub_key:n { FallBack } \keys_define:nn { xeCJK / features } { BoldFont .tl_set:N = \l__xeCJK_font_name_bf_tl , ItalicFont .tl_set:N = \l__xeCJK_font_name_it_tl } \keys_define:nn { xeCJK / features } { AutoFakeBold .choice: , AutoFakeBold / true .code:n = { \bool_set_true:N \l__xeCJK_auto_fake_bold_bool \fp_set_eq:NN \l__xeCJK_embolden_factor_fp \g__xeCJK_embolden_factor_fp } , AutoFakeBold / false .code:n = { \bool_set_false:N \l__xeCJK_auto_fake_bold_bool } , AutoFakeBold / unknown .code:n = { \bool_set_true:N \l__xeCJK_auto_fake_bold_bool \fp_set:Nn \l__xeCJK_embolden_factor_fp { \l_keys_value_tl } } , AutoFakeBold .default:n = { true } , AutoFakeSlant .choice: , AutoFakeSlant / true .code:n = { \bool_set_true:N \l__xeCJK_auto_fake_slant_bool \fp_set_eq:NN \l__xeCJK_slant_factor_fp \g__xeCJK_slant_factor_fp } , AutoFakeSlant / false .code:n = { \bool_set_false:N \l__xeCJK_auto_fake_slant_bool } , AutoFakeSlant / unknown .code:n = { \bool_set_true:N \l__xeCJK_auto_fake_slant_bool \fp_set:Nn \l__xeCJK_slant_factor_fp { \l_keys_value_tl } } , AutoFakeSlant .default:n = { true } } \cs_new_protected_nopar:Npn \__xeCJK_set_family_initial: { \int_gincr:N \g__xeCJK_family_int \prop_clear:N \l__xeCJK_sub_key_prop \tl_clear:N \l__xeCJK_font_name_bf_tl \tl_clear:N \l__xeCJK_font_name_it_tl \clist_clear:N \l__xeCJK_fontspec_options_clist \bool_set_eq:NN \l__xeCJK_auto_fake_bold_bool \g__xeCJK_auto_fake_bold_bool \bool_set_eq:NN \l__xeCJK_auto_fake_slant_bool \g__xeCJK_auto_fake_slant_bool \fp_set_eq:NN \l__xeCJK_embolden_factor_fp \g__xeCJK_embolden_factor_fp \fp_set_eq:NN \l__xeCJK_slant_factor_fp \g__xeCJK_slant_factor_fp } \int_new:N \g__xeCJK_family_int \prop_new:N \l__xeCJK_sub_key_prop \clist_new:N \l__xeCJK_fontspec_options_clist \bool_new:N \l__xeCJK_auto_fake_bold_bool \bool_new:N \l__xeCJK_auto_fake_slant_bool \fp_new:N \l__xeCJK_embolden_factor_fp \fp_new:N \l__xeCJK_slant_factor_fp \cs_new_protected_nopar:Npn \xeCJK_set_family:nnn #1#2#3 { \group_begin: \__xeCJK_set_family_initial: \tl_set:Nn \l__xeCJK_family_name_tl {#1} \clist_set:Nn \l__xeCJK_font_options_clist {#2} \tl_set:Nn \l__xeCJK_font_name_tl {#3} \clist_concat:NNN \l__xeCJK_font_options_clist \g__xeCJK_default_features_clist \l__xeCJK_font_options_clist \__xeCJK_remove_duplicate_keys:N \l__xeCJK_font_options_clist \keys_set_known:nVN { xeCJK / features } \l__xeCJK_font_options_clist \l__xeCJK_fontspec_options_clist \__xeCJK_parse_font_shape: \__xeCJK_check_family:V \l__xeCJK_family_name_tl \__xeCJK_gset_family_cs:x { \l__xeCJK_family_name_tl } \__xeCJK_save_family_info: \__xeCJK_set_sub_block_family: \group_end: } \tl_new:N \l__xeCJK_family_name_tl \tl_new:N \l__xeCJK_font_name_tl \clist_new:N \l__xeCJK_font_options_clist \cs_generate_variant:Nn \xeCJK_set_family:nnn { Vnn , VVV , Voo } \cs_new_protected_nopar:Npn \xeCJK_set_family:xxx #1#2#3 { \use:x { \xeCJK_set_family:nnn {#1} {#2} {#3} } } \cs_new_protected_nopar:Npn \__xeCJK_remove_duplicate_keys:N #1 { \prop_clear:N \l__xeCJK_font_options_prop \keyval_parse:NNV \__xeCJK_prop_put_aux:n \__xeCJK_prop_put_aux:nn #1 \clist_clear:N #1 \prop_map_inline:Nn \l__xeCJK_font_options_prop { \tl_set:No \l__xeCJK_tmp_tl { \use_ii:nn ##2 } \tl_if_blank:VTF \l__xeCJK_tmp_tl { \clist_put_right:No #1 { \use_i:nn ##2 } } { \clist_put_right:Nx #1 { \exp_not:o { \use_i:nn ##2 } = { \exp_not:V \l__xeCJK_tmp_tl } } } } } \prop_new:N \l__xeCJK_font_options_prop \cs_generate_variant:Nn \keyval_parse:NNn { NNV } \cs_new_protected_nopar:Npn \__xeCJK_prop_put_aux:n #1 { \prop_put:Nnn \l__xeCJK_font_options_prop {#1} { {#1} { } } } \cs_new_protected_nopar:Npn \__xeCJK_prop_put_aux:nn #1#2 { \prop_put:Nnn \l__xeCJK_font_options_prop {#1} { {#1} {#2} } } \cs_new_protected_nopar:Npn \__xeCJK_gset_family_cs:x #1 { \cs_gset_protected_nopar:cpx { \__xeCJK_family_csname:n {#1} } { \group_begin: \exp_not:n { \cs_set_eq:NN \__xeCJK_update_family:nn \use_none:nn } \exp_not:n { \fontspec_set_family:Nnn \l__xeCJK_fontspec_family_tl } { \exp_not:V \l__xeCJK_fontspec_options_clist } { \exp_not:V \l__xeCJK_font_name_tl } \__xeCJK_gset_family_nfss_cs:xx {#1} { \exp_not:N \l__xeCJK_fontspec_family_tl } \exp_not:N \exp_args:NNNo \group_end: \tl_set:Nn \exp_not:N \l__xeCJK_fontspec_family_tl { \exp_not:N \l__xeCJK_fontspec_family_tl } } } \tl_new:N \l__xeCJK_fontspec_family_tl \cs_new_protected_nopar:Npn \__xeCJK_check_family:n #1 { \prop_gpop:NnNT \g__xeCJK_family_font_name_prop {#1} \l__xeCJK_tmp_tl { \prop_gpop:NnNT \g__xeCJK_family_name_prop {#1} \l__xeCJK_tmp_tl { \cs_undefine:c { \__xeCJK_family_csname:n {#1} } \cs_undefine:c { \__xeCJK_family_nfss_csname:n {#1} } } \__xeCJK_warning:nxx { CJKfamily-redef } {#1} { \l__xeCJK_tmp_tl } } } \cs_generate_variant:Nn \__xeCJK_check_family:n { V } \__xeCJK_msg_new:nn { CJKfamily-redef } { Redefining~CJKfamily~`\__xeCJK_msg_family_map:n {#1}'~(#2). } \cs_new_protected_nopar:Npn \__xeCJK_parse_font_shape: { \tl_if_blank:VTF \l__xeCJK_font_name_bf_tl { \bool_if:NT \l__xeCJK_auto_fake_bold_bool { \clist_put_right:Nx \l__xeCJK_fontspec_options_clist { AutoFakeBold = { \fp_use:N \l__xeCJK_embolden_factor_fp } } } } { \clist_put_right:Nx \l__xeCJK_fontspec_options_clist { BoldFont = { \exp_not:V \l__xeCJK_font_name_bf_tl } } } \tl_if_blank:VTF \l__xeCJK_font_name_it_tl { \bool_if:NT \l__xeCJK_auto_fake_slant_bool { \clist_put_right:Nx \l__xeCJK_fontspec_options_clist { AutoFakeSlant = { \fp_use:N \l__xeCJK_slant_factor_fp } } } } { \clist_put_right:Nx \l__xeCJK_fontspec_options_clist { ItalicFont = { \exp_not:V \l__xeCJK_font_name_it_tl } } } } \prop_new:N \g__xeCJK_family_name_prop \prop_new:N \g__xeCJK_family_font_name_prop \prop_new:N \g__xeCJK_family_font_options_prop \cs_new_protected_nopar:Npn \__xeCJK_save_family_info: { \prop_gput:NVV \g__xeCJK_family_font_name_prop \l__xeCJK_family_name_tl \l__xeCJK_font_name_tl \prop_gput:NVV \g__xeCJK_family_font_options_prop \l__xeCJK_family_name_tl \l__xeCJK_font_options_clist } \cs_new_protected_nopar:Npn \__xeCJK_set_sub_block_family: { \prop_map_inline:Nn \l__xeCJK_sub_key_prop { \tl_set:Nx \l__xeCJK_sub_family_name_tl { \l__xeCJK_family_name_tl/##1 } \quark_if_no_value:nTF {##2} { \__xeCJK_copy_sub_family:n {##1} } { \xeCJK_set_family:Voo \l__xeCJK_sub_family_name_tl { \use_i:nn ##2 } { \use_ii:nn ##2 } } } } \cs_new_protected_nopar:Npn \__xeCJK_copy_sub_family:n #1 { \__xeCJK_check_family:V \l__xeCJK_sub_family_name_tl \prop_get:NVNT \g__xeCJK_family_font_name_prop \l__xeCJK_family_name_tl \l__xeCJK_sub_font_name_tl { \prop_gput:NVV \g__xeCJK_family_font_name_prop \l__xeCJK_sub_family_name_tl \l__xeCJK_sub_font_name_tl } \prop_get:NVNT \g__xeCJK_family_font_options_prop \l__xeCJK_family_name_tl \l__xeCJK_sub_font_options_clist { \clist_remove_all:Nn \l__xeCJK_sub_font_options_clist { #1 = * } \prop_gput:NVV \g__xeCJK_family_font_options_prop \l__xeCJK_sub_family_name_tl \l__xeCJK_sub_font_options_clist } \cs_gset_protected_nopar:cpx { \__xeCJK_family_csname:n { \l__xeCJK_sub_family_name_tl } } { \xeCJK_family_if_exist:xT { \l__xeCJK_family_name_tl } { \__xeCJK_gset_family_nfss_cs:xx { \l__xeCJK_sub_family_name_tl } { \exp_not:N \l__xeCJK_fontspec_family_tl } } } } \cs_new_protected_nopar:Npn \__xeCJK_copy_family:nn #1#2 { \xeCJK_family_if_exist:nT {#2} { \prop_gput:NnV \g__xeCJK_family_name_prop {#1} \l__xeCJK_fontspec_family_tl \tl_map_inline:nn { \g__xeCJK_family_font_name_prop \g__xeCJK_family_font_options_prop } { \prop_get:NnNT ##1 {#2} \l__xeCJK_tmp_tl { \prop_gput:NnV ##1 {#1} \l__xeCJK_tmp_tl } } \cs_gset_eq:cc { \__xeCJK_family_nfss_csname:n {#1} } { \__xeCJK_family_nfss_csname:n {#2} } } } \cs_new_protected_nopar:Npn \__xeCJK_copy_family:xx #1#2 { \use:x { \__xeCJK_copy_family:nn {#1} {#2} } } \tl_new:N \l_xeCJK_current_font_tl \tl_set:Nn \l_xeCJK_current_font_tl { \__xeCJK_font_csname:n { \CJK@family } } \cs_new_nopar:Npn \__xeCJK_font_csname:n #1 { xeCJK/#1/\f@series/\f@shape/\f@size } \cs_new_protected_nopar:Npn \xeCJK_select_font: { \exp_args:Nc \cs_if_exist_use:NF { \l_xeCJK_current_font_tl } { \__xeCJK_family_use:x { \l_xeCJK_family_tl } \xeCJK_font_gset_to_current:c { \l_xeCJK_current_font_tl } } } \tl_new:N \l__xeCJK_current_coor_tl \cs_new_eq:NN \xeCJK@setfont \xeCJK_select_font: \cs_new_protected_nopar:Npn \__xeCJK_switch_font:nn #1#2 { \str_if_eq:nnF {#1} {#2} { \__xeCJK_info:nxx { CJK-block } {#1} {#2} \str_if_eq:nnTF {#2} { CJK } { \xeCJK_select_font: } { \xeCJK_select_font:n {#2} } } } \__xeCJK_msg_new:nn { CJK-block } { Switch~from~block~`#1'~to~`#2'. } \cs_new_protected_nopar:Npn \xeCJK_select_font:n #1 { \exp_args:Nc \cs_if_exist_use:NF { \__xeCJK_font_csname:n { \CJK@family/#1 } } { \xeCJK_block_family:nn { \l_xeCJK_family_tl } {#1} \__xeCJK_family_use:x { \l_xeCJK_family_tl/#1 } \xeCJK_font_gset_to_current:c { \__xeCJK_font_csname:n { \CJK@family/#1 } } } } \cs_new_protected_nopar:Npn \xeCJK_block_family:nn #1#2 { \xeCJK_family_if_exist:xF { #1/#2 } { \__xeCJK_copy_family:xx { #1/#2 } { \cs_if_exist:cTF { \__xeCJK_family_csname:n { \CJKfamilydefault/#2 } } { \CJKfamilydefault/#2 } {#1} } } } \cs_new_nopar:Npn \__xeCJK_family_csname:n #1 { xeCJK/family/#1 } \cs_new_nopar:Npn \__xeCJK_family_nfss_csname:n #1 { xeCJK/family/nfss/#1 } \cs_new_nopar:Npn \__xeCJK_family_use:x #1 { \use:c { \__xeCJK_family_nfss_csname:n {#1} } } \cs_new_protected_nopar:Npn \__xeCJK_gset_family_nfss_cs:xx #1#2 { \prop_gput:Nxx \g__xeCJK_family_name_prop {#1} {#2} \cs_gset_protected_nopar:cpx { \__xeCJK_family_nfss_csname:n {#1} } { \exp_not:N \fontencoding { \c__xeCJK_encoding_tl } \tl_set:Nx \exp_not:N \f@family {#2} \exp_not:N \selectfont } } \cs_generate_variant:Nn \prop_gput:Nnn { Nxx } \prg_new_protected_conditional:Npnn \xeCJK_family_if_exist:n #1 { T , F , TF } { \prop_get:NnNTF \g__xeCJK_family_name_prop {#1} \l__xeCJK_fontspec_family_tl { \prg_return_true: } { \exp_args:Nc \cs_if_exist_use:NTF { \__xeCJK_family_csname:n {#1} } { \prg_return_true: } { \prg_return_false: } } } \cs_generate_variant:Nn \xeCJK_family_if_exist:nT { x } \cs_generate_variant:Nn \xeCJK_family_if_exist:nF { x } \cs_generate_variant:Nn \xeCJK_family_if_exist:nTF { x } \NewDocumentCommand \CJKfamily { t+ t- m } { \xeCJK_if_blank_x:nTF {#3} { \IfBooleanF {#1} { \IfBooleanF {#2} { \use_none:nn } } \xeCJK_family_if_exist_use:x { \l_xeCJK_family_tl } } { \IfBooleanTF {#2} { \xeCJK_family_if_exist_use:x {#3} } { \xeCJK_family_if_exist:xTF {#3} { \tl_set:Nx \l_xeCJK_family_tl {#3} \tl_set_eq:NN \CJK@family \l__xeCJK_fontspec_family_tl \IfBooleanT {#1} { \__xeCJK_family_use:x {#3} } } { \__xeCJK_family_unknown_warning:x {#3} } } } \tex_ignorespaces:D } \cs_new_protected_nopar:Npn \xeCJK_switch_family:n #1 { \xeCJK_family_if_exist:xTF {#1} { \tl_set:Nx \l_xeCJK_family_tl {#1} \tl_set_eq:NN \CJK@family \l__xeCJK_fontspec_family_tl } { \__xeCJK_family_unknown_warning:x {#1} } } \tl_new:N \l_xeCJK_family_tl \tl_new:N \CJK@family \cs_new_protected_nopar:Npn \__xeCJK_gobble_CJKfamily: { \cs_set_eq:NN \CJKfamily \__xeCJK_gobble_CJKfamily:wn } \DeclareExpandableDocumentCommand \__xeCJK_gobble_CJKfamily:wn { t+ t- m } { } \cs_new_protected_nopar:Npn \xeCJK_family_if_exist_use:x #1 { \xeCJK_family_if_exist:xTF {#1} { \__xeCJK_family_use:x {#1} } { \__xeCJK_family_unknown_warning:x {#1} } } \cs_new_protected_nopar:Npn \__xeCJK_family_unknown_warning:n #1 { \prop_if_empty:NF \g__xeCJK_family_font_name_prop { \seq_if_in:NnF \g__xeCJK_unknown_family_seq {#1} { \seq_gput_right:Nn \g__xeCJK_unknown_family_seq {#1} \__xeCJK_warning:nx { CJKfamily-Unknown } {#1} } } } \cs_generate_variant:Nn \__xeCJK_family_unknown_warning:n { x } \seq_new:N \g__xeCJK_unknown_family_seq \__xeCJK_msg_new:nn { CJKfamily-Unknown } { Unknown~CJK~family~`\__xeCJK_msg_family_map:n {#1}'~is~being~ignored.\\\\ Try~to~use~`\__xeCJK_msg_def_family_map:n {#1}'~to~define~it. } \cs_new_nopar:Npn \__xeCJK_msg_def_family_map:n #1 { \str_case_x:nnF {#1} { \CJKrmdefault { \token_to_str:N \setCJKmainfont } \CJKsfdefault { \token_to_str:N \setCJKsansfont } \CJKttdefault { \token_to_str:N \setCJKmonofont } } { \token_to_str:N \setCJKfamilyfont \{ #1 \} } [...]\{...\} } \cs_new_nopar:Npn \__xeCJK_msg_family_map:n #1 { \str_case_x:nnF {#1} { \CJKrmdefault { \token_to_str:N \CJKrmdefault } \CJKsfdefault { \token_to_str:N \CJKsfdefault } \CJKttdefault { \token_to_str:N \CJKttdefault } } {#1} } \NewDocumentCommand \setCJKmainfont { O { } m } { \xeCJK_set_family:xxx { \CJKrmdefault } {#1} {#2} \normalfont } \cs_new_eq:NN \setCJKromanfont \setCJKmainfont \NewDocumentCommand \setCJKsansfont { O { } m } { \xeCJK_set_family:xxx { \CJKsfdefault } {#1} {#2} \normalfont } \NewDocumentCommand \setCJKmonofont { O { } m } { \xeCJK_set_family:xxx { \CJKttdefault } {#1} {#2} \normalfont } \@onlypreamble \setCJKmainfont \@onlypreamble \setCJKmathfont \@onlypreamble \setCJKsansfont \@onlypreamble \setCJKmonofont \@onlypreamble \setCJKromanfont \NewDocumentCommand \setCJKfamilyfont { m O { } m } { \xeCJK_set_family:xxx {#1} {#2} {#3} } \NewDocumentCommand \newCJKfontfamily { o m O { } m } { \tl_set:Nx \l__xeCJK_tmp_tl { \IfNoValueTF {#1} { \cs_to_str:N #2 } {#1} } \cs_new_protected_nopar:Npx #2 { \xeCJK_switch_family:n { \l__xeCJK_tmp_tl } } \xeCJK_set_family:xxx { \l__xeCJK_tmp_tl } {#3} {#4} } \NewDocumentCommand \CJKfontspec { O { } m } { \use:x { \xeCJK_fontspec:nn {#1} {#2} } \tex_ignorespaces:D } \cs_new_protected_nopar:Npn \xeCJK_fontspec:nn #1#2 { \prop_get:NnNTF \g__xeCJK_fontspec_prop { CJKfontspec/#1/#2/id } \l_xeCJK_family_tl { \xeCJK_switch_family:n { \l_xeCJK_family_tl } } { \__xeCJK_fontspec:xnn { CJKfontspec ( \int_eval:n { \g__xeCJK_family_int + \c_one } ) } {#1} {#2} } } \cs_new_protected_nopar:Npn \__xeCJK_fontspec:nnn #1#2#3 { \prop_gput:Nnn \g__xeCJK_fontspec_prop { CJKfontspec/#2/#3/id } {#1} \xeCJK_set_family:nnn {#1} {#2} {#3} \xeCJK_switch_family:n {#1} } \cs_generate_variant:Nn \xeCJK_fontspec:nn { VV } \cs_generate_variant:Nn \__xeCJK_fontspec:nnn { x } \prop_new:N \g__xeCJK_fontspec_prop \clist_new:N \g__xeCJK_default_features_clist \NewDocumentCommand \defaultCJKfontfeatures { m } { \clist_gset:Nn \g__xeCJK_default_features_clist {#1} } \@onlypreamble \defaultCJKfontfeatures \NewDocumentCommand \addCJKfontfeatures { s O { } m } { \xeCJK_add_font_features:Nxx #1 {#2} {#3} \tex_ignorespaces:D } \cs_new_eq:NN \addCJKfontfeature \addCJKfontfeatures \cs_new_protected_nopar:Npn \xeCJK_add_font_features:Nnn #1#2#3 { \prop_get:NVNTF \g__xeCJK_family_font_name_prop \l_xeCJK_family_tl \l__xeCJK_font_name_tl { \clist_set:Nn \l__xeCJK_add_font_features_clist {#3} \seq_map_inline:Nn \g__xeCJK_sub_key_seq { \clist_remove_all:Nn \l__xeCJK_add_font_features_clist {##1} } \seq_clear:N \l__xeCJK_sub_key_seq \clist_clear:N \l__xeCJK_add_block_features_clist \clist_map_inline:nn {#2} { \seq_if_in:NnTF \g__xeCJK_sub_key_seq {##1} { \seq_put_right:Nn \l__xeCJK_sub_key_seq {##1} \__xeCJK_add_sub_class_features:n {##1} } { \__xeCJK_warning:nx { SubBlock-undefined } {##1} } } \bool_if:nT { #1 && \seq_if_empty_p:N \l__xeCJK_sub_key_seq } { \seq_map_function:NN \g__xeCJK_sub_key_seq \__xeCJK_add_sub_class_features:n } \prop_get:NVNT \g__xeCJK_family_font_options_prop \l_xeCJK_family_tl \l__xeCJK_font_options_clist { \bool_if:nT { \seq_if_empty_p:N \l__xeCJK_sub_key_seq || #1 } { \clist_concat:NNN \l__xeCJK_font_options_clist \l__xeCJK_font_options_clist \l__xeCJK_add_font_features_clist } \clist_concat:NNN \l__xeCJK_font_options_clist \l__xeCJK_font_options_clist \l__xeCJK_add_block_features_clist } \xeCJK_fontspec:VV \l__xeCJK_font_options_clist \l__xeCJK_font_name_tl } { \__xeCJK_warning:n { addCJKfontfeature-ignored } } } \clist_new:N \l__xeCJK_add_font_features_clist \clist_new:N \l__xeCJK_add_block_features_clist \cs_generate_variant:Nn \xeCJK_add_font_features:Nnn { Nxx , Nnx } \__xeCJK_msg_new:nn { addCJKfontfeature-ignored } { \token_to_str:N \addCJKfontfeature (s)~ignored.\\\\ It~cannot~be~used~with~a~font~that~wasn't~selected~by~xeCJK. } \cs_new_protected_nopar:Npn \__xeCJK_add_sub_class_features:n #1 { \prop_get:NoNTF \g__xeCJK_family_font_name_prop { \l_xeCJK_family_tl/#1 } \l__xeCJK_sub_font_name_tl { \prop_get:NoN \g__xeCJK_family_font_options_prop { \l_xeCJK_family_tl/#1 } \l__xeCJK_sub_font_options_clist } { \prop_get:NxNTF \g__xeCJK_family_font_name_prop { \CJKfamilydefault/#1 } \l__xeCJK_sub_font_name_tl { \prop_get:NxN \g__xeCJK_family_font_options_prop { \CJKfamilydefault/#1 } \l__xeCJK_sub_font_options_clist } { \prop_get:NVN \g__xeCJK_family_font_options_prop \l_xeCJK_family_tl \l__xeCJK_sub_font_options_clist \tl_set_eq:NN \l__xeCJK_sub_font_name_tl \l__xeCJK_font_name_tl } } \clist_concat:NNN \l__xeCJK_sub_font_options_clist \l__xeCJK_sub_font_options_clist \l__xeCJK_add_font_features_clist \clist_put_right:Nx \l__xeCJK_add_block_features_clist { #1 = { [ \exp_not:V \l__xeCJK_sub_font_options_clist ] { \exp_not:V \l__xeCJK_sub_font_name_tl } } } } \cs_generate_variant:Nn \prop_get:NnN { Nx } \cs_generate_variant:Nn \prop_get:NnNTF { Nx } \keys_define:nn { xeCJK / options } { LoadFandol .bool_gset:N = \g__xeCJK_fandol_bool } \cs_new_protected_nopar:Npn \__xeCJK_load_fandol: { \setCJKmainfont [ Extension = .otf , BoldFont = FandolSong-Bold , ItalicFont = FandolKai-Regular ] { FandolSong-Regular } \setCJKsansfont [ Extension = .otf , BoldFont = FandolHei-Bold ] { FandolHei-Regular } \setCJKmonofont [ Extension = .otf ] { FandolFang-Regular } } \__xeCJK_at_end_preamble:n { \tl_if_eq:NNT \CJKfamilydefault \l__xeCJK_family_default_init_tl { \group_begin: \cs_set_eq:NN \__xeCJK_family_default_wrap:n \exp_not:n \tl_gset:Nx \CJKfamilydefault { \str_case:onF { \familydefault } { { \rmdefault } { \exp_not:N \CJKrmdefault } { \sfdefault } { \exp_not:N \CJKsfdefault } { \ttdefault } { \exp_not:N \CJKttdefault } } { \CJKfamilydefault } } \group_end: } \prop_if_empty:NTF \g__xeCJK_family_font_name_prop { \bool_if:NTF \g__xeCJK_fandol_bool { \__xeCJK_warning:n { fandol } \__xeCJK_load_fandol: \xeCJK_ensure_default_family: } { \__xeCJK_warning:nx { no-CJKfamily } { \CJKfamilydefault } } } { \xeCJK_ensure_default_family: } } \cs_new_protected_nopar:Npn \xeCJK_ensure_default_family: { \xeCJK_family_if_exist:xF { \CJKfamilydefault } { \tl_set_eq:NN \l__xeCJK_tmp_tl \CJKfamilydefault \str_if_eq_x:nnTF { \CJKfamilydefault } { \CJKrmdefault } { \use:n } { \xeCJK_family_if_exist:xTF { \CJKrmdefault } { \tl_gset:Nn \CJKfamilydefault { \CJKrmdefault } } } { \prop_map_inline:Nn \g__xeCJK_family_font_name_prop { \prop_map_break:n { \tl_gset_rescan:Nnn \CJKfamilydefault { } { ##1 } } } } \__xeCJK_warning:nxx { CJKfamilydefault-undefined } { \l__xeCJK_tmp_tl } { \CJKfamilydefault } } \xeCJK_switch_family:n { \CJKfamilydefault } \bool_if:NT \g__xeCJK_math_bool { \xeCJK_set_mathfont: } } \__xeCJK_msg_new:nn { no-CJKfamily } { It~seems~that~you~have~not~declare~a~CJKfamily.\\ If~you~want~to~use~xeCJK~in~the~right~way,~you~should~use\\\\ `\__xeCJK_msg_def_family_map:n {#1}'\\\\ in~the~preamble~to~declare~the~default~CJKfamily.\\ } \__xeCJK_msg_new:nn { CJKfamilydefault-undefined } { Undefined~CJK~default~family~`\__xeCJK_msg_family_map:n {#1}'~ has~been~replaced~by~`\__xeCJK_msg_family_map:n {#2}'.\\\\ Try~to~use~`\__xeCJK_msg_def_family_map:n {#1}'~to~define~it. } \__xeCJK_msg_new:nn { fandol } { Fandol~is~being~set~as~the~default~font~for~CJK~text.\\ Please~make~sure~it~has~been~properly~installed. } \keys_define:nn { xeCJK / options } { CJKmath .bool_gset:N = \g__xeCJK_math_bool } \NewDocumentCommand \setCJKmathfont { O { } m } { \xeCJK_set_family:xxx { \c__xeCJK_math_tl } {#1} {#2} } \tl_const:Nn \c__xeCJK_math_tl { CJKmath } \cs_new_protected_nopar:Npn \xeCJK_set_mathfont: { \xeCJK_family_if_exist:xTF { \c__xeCJK_math_tl } { \__xeCJK_set_mathfont_aux: } { \xeCJK_family_if_exist:xT { \CJKfamilydefault } { \__xeCJK_copy_family:xx { \c__xeCJK_math_tl } { \CJKfamilydefault } \__xeCJK_set_mathfont_aux: } } } \cs_new_protected_nopar:Npn \__xeCJK_set_mathfont_aux: { \tl_const:Nx \c__xeCJK_math_family_tl { \l__xeCJK_fontspec_family_tl } \xeCJK_declare_mathfont:nn { \c__xeCJK_math_tl } { \c__xeCJK_math_family_tl } \int_const:Nn \c_xeCJK_math_fam_int { \use:c { sym \c__xeCJK_math_tl } } \clist_concat:NNN \g__xeCJK_math_chars_clist \g__xeCJK_CJK_range_clist \g__xeCJK_FullLeft_range_clist \clist_concat:NNN \g__xeCJK_math_chars_clist \g__xeCJK_math_chars_clist \g__xeCJK_FullRight_range_clist \xeCJK_gset_mathcode:Nn \g__xeCJK_math_chars_clist { \c_xeCJK_math_fam_int } \xeCJK_set_mathfont_block: } \clist_new:N \g__xeCJK_math_chars_clist \prop_new:N \g__xeCJK_fam_prop \cs_new_protected_nopar:Npn \xeCJK_set_mathfont_block: { \seq_if_empty:NF \g__xeCJK_CJK_sub_class_seq { \seq_map_function:NN \g__xeCJK_CJK_sub_class_seq \xeCJK_set_mathfont_block:n } } \cs_new_protected_nopar:Npn \xeCJK_set_mathfont_block:n #1 { \xeCJK_block_family:nn { \c__xeCJK_math_tl } {#1} \prop_get:NoNTF \g__xeCJK_fam_prop { \l__xeCJK_fontspec_family_tl } \l__xeCJK_tmp_tl { \int_set:Nn \l__xeCJK_fam_int { \l__xeCJK_tmp_tl } } { \xeCJK_declare_mathfont:nn { \c__xeCJK_math_tl / #1 } { \l__xeCJK_fontspec_family_tl } \__xeCJK_set_mathfont_block_aux:cn { sym \c__xeCJK_math_tl / #1 } {#1} } \xeCJK_gset_mathcode:cn { g__xeCJK_CJK/#1_range_clist } { \l__xeCJK_fam_int } } \cs_new_protected_nopar:Npn \__xeCJK_set_mathfont_block_aux:Nn #1#2 { \int_set_eq:NN \l__xeCJK_fam_int #1 \prop_gput:Nnn \g__xeCJK_block_fam_prop {#2} {#1} } \int_new:N \l__xeCJK_fam_int \prop_new:N \g__xeCJK_block_fam_prop \cs_generate_variant:Nn \__xeCJK_set_mathfont_block_aux:Nn { c } \cs_new_protected_nopar:Npn \xeCJK_declare_mathfont:nn #1#2 { \xeCJK_declare_symbol_font:nnnnn {#1} { \c__xeCJK_encoding_tl } {#2} { \mddefault } { \updefault } \cs_if_free:cF { \c__xeCJK_encoding_tl/#2/\bfdefault/\updefault } { \SetSymbolFont {#1} { bold } { \c__xeCJK_encoding_tl } {#2} { \bfdefault } { \updefault } } \prop_gput:Nxx \g__xeCJK_fam_prop {#2} { \exp_not:c { sym #1 } } } \cs_new_protected:Npn \xeCJK_declare_symbol_font:nnnnn #1 { \__xeCJK_declare_symbol_font:cnnnn { sym #1 } } \cs_new_protected:Npn \__xeCJK_declare_symbol_font:Nnnnn #1 { \xeCJK_new_fam:N #1 \xeCJK_new_symbol_font:Nnnnn #1 } \cs_generate_variant:Nn \__xeCJK_declare_symbol_font:Nnnnn { c } \cs_new_protected:Npn \xeCJK_new_fam:N #1 { \int_compare:nNnTF { \g__xeCJK_fam_allocation_int } > { \g__xeCJK_fam_bottom_int } { \int_set_eq:NN \allocationnumber \g__xeCJK_fam_allocation_int \int_const:Nn #1 { \allocationnumber } \iow_log:x { \token_to_str:N #1 = \token_to_str:N \mathgroup \int_use:N \allocationnumber } \int_gdecr:N \g__xeCJK_fam_allocation_int } { \__xeCJK_error:n { fam-exhausted } } } \tex_countdef:D \g__xeCJK_fam_bottom_int = 18 ~ \int_new:N \g__xeCJK_fam_allocation_int \int_gset_eq:NN \g__xeCJK_fam_allocation_int \c_two_hundred_fifty_five \__xeCJK_msg_new:nn { fam-exhausted } { No~room~for~a~new~fam. } \cs_new_protected:Npn \xeCJK_new_symbol_font:Nnnnn #1#2#3#4#5 { \__xeCJK_new_symbol_font:Nc #1 { #2/#3/#4/#5 } } \cs_new_protected:Npn \__xeCJK_new_symbol_font:NN #1#2 { \tl_put_right:Nn \group@list { \group@elt #1 #2 } \cs_set_nopar:Npn \version@elt ##1 { \tl_put_right:Nn ##1 { \getanddefine@fonts #1 #2 } } \version@list } \cs_generate_variant:Nn \__xeCJK_new_symbol_font:NN { Nc } \cs_new_protected_nopar:Npn \xeCJK_gset_mathcode:Nn #1#2 { \clist_map_inline:Nn #1 { \__xeCJK_set_char_class_aux:Nnw \xeCJK_gset_mathcode:nnnn { ##1 } { \c_zero } {#2} } } \cs_generate_variant:Nn \xeCJK_gset_mathcode:Nn { c } \cs_new_protected_nopar:Npn \xeCJK_gset_mathcode:nnnn #1#2#3#4 { \__xeCJK_check_num_range:nnNN {#1} {#2} \l__xeCJK_begin_int \l__xeCJK_end_int \xeCJK_int_until_do:nn { \l__xeCJK_begin_int > \l__xeCJK_end_int } { \xeCJK_gset_mathcode:Nnn \l__xeCJK_begin_int {#3} {#4} \int_incr:N \l__xeCJK_begin_int } } \cs_new_protected_nopar:Npn \xeCJK_gset_mathcode:Nnn #1#2#3 { \tex_global:D \utex_mathcode:D #1 = #2 ~ #3 ~ #1 } \int_new:N \l__xeCJK_verb_case_int \keys_define:nn { xeCJK / options } { Verb .choices:nn = { true , env+ , env , false } { \int_set_eq:NN \l__xeCJK_verb_case_int \l_keys_choice_int } , Verb .default:n = { env } } \cs_new_protected_nopar:Npn \__xeCJK_verb_font_hook: { \if_case:w \l__xeCJK_verb_case_int \or: \__xeCJK_nobreak_skip_zero: \or: \int_compare:nNnTF \etex_currentgrouptype:D = \c_fourteen { \xeCJKVerbAddon } { \__xeCJK_nobreak_skip: } \or: \int_compare:nNnTF \etex_currentgrouptype:D = \c_fourteen { \xeCJKVerbAddon } { \__xeCJK_nobreak_skip_zero: } \fi: } \__xeCJK_after_preamble:n { \cs_set_protected_nopar:Npx \verbatim@font { \exp_not:o { \verbatim@font } \__xeCJK_verb_font_hook: } } \cs_new_protected_nopar:Npn \__xeCJK_nobreak_skip_zero: { \__xeCJK_reset_shipout_skip: \cs_set_eq:NN \__xeCJK_shipout_check_for_glue: \xeCJK_check_for_glue: \cs_set_eq:NN \__xeCJK_shipout_boundary:w \xeCJK_CJK_and_Boundary:w \tl_put_right:Nn \l__xeCJK_reset_shipout_skip_hook_tl { \cs_set_eq:NN \xeCJK_check_for_glue: \__xeCJK_shipout_check_for_glue: \cs_set_eq:NN \xeCJK_CJK_and_Boundary:w \__xeCJK_shipout_boundary:w } \xeCJK_cs_clear:N \CJKglue \xeCJK_cs_clear:N \CJKecglue \xeCJK_cs_clear:N \xeCJK_check_for_glue: \cs_set_eq:NN \xeCJK_CJK_and_Boundary:w \xeCJK_class_group_end: \cs_set_eq:NN \__xeCJK_punct_hskip:n \__xeCJK_nobreak_hskip:n \cs_set_eq:NN \__xeCJK_punct_breakable_kern:n \__xeCJK_nobreak_hskip:n } \cs_new_protected_nopar:Npn \__xeCJK_nobreak_skip: { \__xeCJK_reset_shipout_skip: \xeCJK_glue_to_skip:nN { \CJKglue } \l__xeCJK_ccglue_skip \skip_if_eq:nnTF { \l__xeCJK_ccglue_skip } { \c_zero_skip } { \xeCJK_cs_clear:N \CJKglue } { \cs_set_eq:NN \CJKglue \__xeCJK_nobreak_ccglue: } \xeCJK_glue_to_skip:nN { \CJKecglue } \l__xeCJK_ecglue_skip \skip_if_eq:nnTF { \l__xeCJK_ecglue_skip } { \c_zero_skip } { \xeCJK_cs_clear:N \CJKecglue } { \cs_set_eq:NN \CJKecglue \__xeCJK_nobreak_ecglue: } \cs_set_eq:NN \__xeCJK_punct_hskip:n \__xeCJK_nobreak_hskip:n \cs_set_eq:NN \__xeCJK_punct_breakable_kern:n \__xeCJK_nobreak_hskip:n } \cs_new_protected_nopar:Npn \__xeCJK_nobreak_ccglue: { \xeCJK_no_break: \skip_horizontal:N \l__xeCJK_ccglue_skip } \cs_new_protected_nopar:Npn \__xeCJK_nobreak_ecglue: { \xeCJK_no_break: \skip_horizontal:N \l__xeCJK_ecglue_skip } \cs_new_protected_nopar:Npn \__xeCJK_nobreak_hskip:n { \xeCJK_no_break: \skip_horizontal:n } \cs_new_protected_nopar:Npn \__xeCJK_reset_shipout_skip: { \cs_set_eq:NN \__xeCJK_shipout_CJKglue: \CJKglue \cs_set_eq:NN \__xeCJK_shipout_CJKecglue: \CJKecglue \cs_set_eq:NN \__xeCJK_shipout_punct_hskip:n \__xeCJK_punct_hskip:n \cs_set_eq:NN \__xeCJK_shipout_punct_breakable_kern:n \__xeCJK_punct_breakable_kern:n \tl_set:Nx \l__xeCJK_off_verb_addon_tl { \bool_if:NTF \l__xeCJK_xecglue_bool { \keys_set:nn { xeCJK / options } { xCJKecglue = true } } { \keys_set:nn { xeCJK / options } { xCJKecglue = false } } \exp_not:n { \cs_set_eq:NN \CJKglue \__xeCJK_shipout_CJKglue: \cs_set_eq:NN \CJKecglue \__xeCJK_shipout_CJKecglue: \cs_set_eq:NN \__xeCJK_punct_hskip:n \__xeCJK_shipout_punct_hskip:n \cs_set_eq:NN \__xeCJK_punct_breakable_kern:n \__xeCJK_shipout_punct_breakable_kern:n \l__xeCJK_reset_shipout_skip_hook_tl } } \xeCJK_add_to_shipout:n { \l__xeCJK_off_verb_addon_tl } \keys_set:nn { xeCJK / options } { xCJKecglue = false } } \tl_new:N \l__xeCJK_reset_shipout_skip_hook_tl \NewDocumentCommand \xeCJKVerbAddon { } { \int_compare:nNnF \etex_currentgrouplevel:D = \c_zero { \bool_if:NF \l__xeCJK_listings_env_bool { \dim_compare:nNnTF { \tex_fontdimen:D \c_two \tex_font:D } = { \etex_fontcharwd:D \tex_font:D \c__xeCJK_mono_letter_int } { \__xeCJK_set_verb_exspace: \__xeCJK_verb_addon: } { \int_if_odd:nTF { \l__xeCJK_verb_case_int } { \__xeCJK_nobreak_skip_zero: } { \__xeCJK_nobreak_skip: } } } } } \int_const:Nn \c__xeCJK_mono_letter_int { 77 } \bool_new:N \l__xeCJK_listings_env_bool \NewDocumentCommand \xeCJKOffVerbAddon { } { \tl_use:N \l__xeCJK_off_verb_addon_tl } \tl_new:N \l__xeCJK_off_verb_addon_tl \cs_new_protected_nopar:Npn \__xeCJK_verb_addon: { \bool_if:NF \l__xeCJK_verb_addon_bool { \bool_set_true:N \l__xeCJK_verb_addon_bool \__xeCJK_set_char_class_eq:nn { FullLeft } { CJK } \__xeCJK_set_char_class_eq:nn { FullRight } { CJK } \__xeCJK_set_char_class_eq:nn { HalfLeft } { Default } \__xeCJK_set_char_class_eq:nn { HalfRight } { Default } \__xeCJK_set_char_class_eq:nn { NormalSpace } { Default } \cs_set_eq:NN \__xeCJK_shipout_CJKglue: \CJKglue \cs_set_eq:NN \__xeCJK_shipout_CJKecglue: \CJKecglue \cs_set_eq:NN \__xeCJK_shipout_check_for_glue: \xeCJK_check_for_glue: \cs_set_eq:NN \__xeCJK_shipout_boundary:w \xeCJK_CJK_and_Boundary:w \cs_set_protected_nopar:Npx \xeCJKOffVerbAddon { \__xeCJK_reset_char_class:n { FullLeft } \__xeCJK_reset_char_class:n { FullRight } \__xeCJK_reset_char_class:n { HalfLeft } \__xeCJK_reset_char_class:n { HalfLeft } \__xeCJK_reset_char_class:n { NormalSpace } \bool_if:NTF \l__xeCJK_xecglue_bool { \keys_set:nn { xeCJK / options } { xCJKecglue = true } } { \keys_set:nn { xeCJK / options } { xCJKecglue = false } } \exp_not:n { \cs_set_eq:NN \CJKglue \__xeCJK_shipout_CJKglue: \cs_set_eq:NN \CJKecglue \__xeCJK_shipout_CJKecglue: \cs_set_eq:NN \xeCJK_check_for_glue: \__xeCJK_shipout_check_for_glue: \cs_set_eq:NN \xeCJK_CJK_and_Boundary:w \__xeCJK_shipout_boundary:w } } \xeCJK_add_to_shipout:n { \xeCJKOffVerbAddon } \keys_set:nn { xeCJK / options } { xCJKecglue = false } } \skip_if_eq:nnTF { \l__xeCJK_verb_exspace_skip } { \c_zero_skip } { \xeCJK_cs_clear:N \CJKglue \xeCJK_cs_clear:N \CJKecglue } { \skip_set_eq:NN \l__xeCJK_ccglue_skip \l__xeCJK_verb_exspace_skip \skip_set:Nn \l__xeCJK_ecglue_skip { .5 \l__xeCJK_verb_exspace_skip } \cs_set_eq:NN \CJKglue \__xeCJK_nobreak_ccglue: \cs_set_eq:NN \CJKecglue \__xeCJK_nobreak_ecglue: } \cs_set_eq:NN \xeCJK_check_for_glue: \CJKecglue \cs_set_eq:NN \xeCJK_CJK_and_Boundary:w \__xeCJK_verb_CJK_and_Boundary:w } \cs_new_protected_nopar:Npn \__xeCJK_verb_CJK_and_Boundary:w { \xeCJK_class_group_end: \CJKecglue } \cs_new_protected_nopar:Npn \__xeCJK_reset_char_class:n #1 { \int_set:Nn \l__xeCJK_tmp_int { \xeCJK_class_num:n {#1} } \clist_map_inline:cn { c__xeCJK_#1_chars_clist } { \xetex_charclass:D ##1 = \l__xeCJK_tmp_int } } \bool_new:N \l__xeCJK_verb_addon_bool \cs_new_eq:NN \CJKfixedspacing \xeCJKVerbAddon \cs_new_protected_nopar:Npn \__xeCJK_set_verb_exspace: { \tl_if_exist:cTF { xeCJK/verb/\CJK@family/\curr@fontshape/\f@size } { \skip_set:Nn \l__xeCJK_verb_exspace_skip { \use:c { xeCJK/verb/\CJK@family/\curr@fontshape/\f@size } } } { \tl_set:Nx \l__xeCJK_current_coor_tl { \CJK@family/\curr@fontshape } \prop_get:NVNTF \g__xeCJK_scale_family_prop \l__xeCJK_current_coor_tl \l_xeCJK_family_tl { \xeCJK_switch_family:n { \l_xeCJK_family_tl } \skip_zero:N \l__xeCJK_verb_exspace_skip } { \group_begin: \xeCJK_select_font: \exp_after:wN \group_end: \exp_after:wN \__xeCJK_set_verb_exspace:n \exp_after:wN { \dim_use:N \etex_fontcharwd:D \tex_font:D "4E00 } } } } \skip_new:N \l__xeCJK_verb_exspace_skip \cs_new_protected_nopar:Npn \__xeCJK_set_verb_exspace:n #1 { \skip_set:Nn \l__xeCJK_verb_exspace_skip { \c_two \tex_fontdimen:D \c_two \tex_font:D - #1 } \dim_compare:nNnTF \l__xeCJK_verb_exspace_skip < \c_zero_dim { \skip_zero:N \l__xeCJK_verb_exspace_skip \use:x { \__xeCJK_set_verb_scale:nn { \dim_to_fp:n { \c_two \tex_fontdimen:D \c_two \tex_font:D } } { \dim_to_fp:n {#1} } } } { \tl_const:cx { xeCJK/verb/\CJK@family/\curr@fontshape/\f@size } { \skip_use:N \l__xeCJK_verb_exspace_skip } } } \cs_new_protected_nopar:Npn \__xeCJK_set_verb_scale:nn #1#2 { \fp_set:Nn \l__xeCJK_scale_factor_fp { #1 / #2 } \__xeCJK_warning:nxx { scale-factor } { \fp_eval:n { trunc ( \l__xeCJK_scale_factor_fp , 4 ) } } { \fp_eval:n { ceil ( #2 / #1 , 4 ) } } \xeCJK_add_font_features:Nnx \c_true_bool { } { Scale = { \fp_use:N \l__xeCJK_scale_factor_fp } } \prop_gput:NVV \g__xeCJK_scale_family_prop \l__xeCJK_current_coor_tl \l_xeCJK_family_tl } \__xeCJK_msg_new:nn { scale-factor } { `\token_to_str:N \xeCJKVerbAddon'~may~not~work~properly.\\\\ You~may~set~`Scale=#1'~to~CJKfamily~ `\__xeCJK_msg_family_map:n { \l_xeCJK_family_tl }',\\ or~set~`Scale=#2'~to~family~ `\str_if_eq_x:nnTF \f@family \ttdefault { \token_to_str:N \ttdefault } { \f@family }'. } \fp_new:N \l__xeCJK_scale_factor_fp \prop_new:N \g__xeCJK_scale_family_prop \cs_new_protected_nopar:Npn \xeCJK_visible_space: { \bool_if:NT \l__xeCJK_CJK_group_bool { \scan_stop: } \xeCJK_glyph_if_exist:NTF { ^^^^2423 } { ^^^^2423 } { \int_compare:nNnTF { \xetex_fonttype:D \tex_font:D } = \c_zero { \str_if_eq_x:nnTF { \f@family } { \ttdefault } { \c_catcode_other_space_tl } { \textvisiblespace } } { \xeCJK_visible_space_fallback: } } } \AtEndOfPackage { \cs_gset_eq:NN \fontspec_visible_space: \xeCJK_visible_space: } \cs_new_protected_nopar:Npn \xeCJK_visible_space_fallback: { { \cs_if_exist_use:cF { xeCJK/space/\curr@fontshape/\f@size } { \xeCJK_set_visible_space_font: } ^^^^2423 } } \cs_new_protected_nopar:Npn \xeCJK_set_visible_space_font: { \tl_set:Nx \l__xeCJK_current_coor_tl { xeCJK/space/\curr@fontshape/\f@size } \exp_after:wN \__xeCJK_set_visible_space_size:n \exp_after:wN { \dim_use:N \tex_fontdimen:D \c_two \tex_font:D } \xeCJK_font_gset_to_current:c { \l__xeCJK_current_coor_tl } } \cs_new_protected_nopar:Npn \__xeCJK_set_visible_space_size:n #1 { \fontencoding { \g_fontspec_encoding_tl } \tl_set:Nx \f@family { lmtt } \selectfont \dim_compare:nNnF {#1} = { \tex_fontdimen:D \c_two \tex_font:D } { \fontsize { \dim_eval:n { \f@size pt * \dim_ratio:nn {#1} { \tex_fontdimen:D \c_two \tex_font:D } } } { \f@baselineskip } \selectfont } } \keys_define:nn { xeCJK / options } { LocalConfig .choice: , LocalConfig / false .code:n = { \bool_gset_false:N \g__xeCJK_config_bool } , LocalConfig / true .code:n = { \bool_gset_true:N \g__xeCJK_config_bool \tl_gset:Nn \g__xeCJK_config_name_tl { xeCJK } } , LocalConfig / unknown .code:n = { \bool_gset_true:N \g__xeCJK_config_bool \tl_gset:Nx \g__xeCJK_config_name_tl { xeCJK - \l_keys_value_tl } } , LocalConfig .default:n = { true } } \tl_new:N \g__xeCJK_config_name_tl \bool_new:N \g__xeCJK_config_bool \keys_define:nn { xeCJK / options } { CJKnumber .code:n = { \__xeCJK_warning:nxx { option-deprecated } { \l_keys_key_tl } { CJKnumb } } , indentfirst .code:n = { \__xeCJK_warning:nxx { option-deprecated } { \l_keys_key_tl } { indentfirst } } , normalindentfirst .code:n = { \__xeCJK_warning:nxx { option-deprecated } { \l_keys_key_tl } { } } } \__xeCJK_msg_new:nn { option-deprecated } { The~`#1'~option~is~deprecated.\\ \tl_if_empty:nF {#2} { You~may~load~the~package~`#2'~after~xeCJK~to~use~its~function.\\ } } \keys_define:nn { xeCJK / options } { quiet .code:n = { \msg_redirect_module:nnn { xeCJK } { warning } { info } \msg_redirect_module:nnn { xeCJK } { info } { none } \xeCJK_if_package_loaded:nF { fontspec } { \PassOptionsToPackage { quiet } { fontspec } } } , silent .code:n = { \msg_redirect_module:nnn { xeCJK } { warning } { none } \msg_redirect_module:nnn { xeCJK } { info } { none } \xeCJK_if_package_loaded:nF { fontspec } { \PassOptionsToPackage { silent } { fontspec } } } , unknown .code:n = { \xeCJK_if_package_loaded:nTF { fontspec } { \__xeCJK_error:nx { key-unknown } { \l_keys_key_tl } } { \PassOptionsToPackage { \l_keys_key_tl } { fontspec } } } } \__xeCJK_msg_new:nn { key-unknown } { Sorry,~but~\l__keys_module_tl \ does~not~have~a~key~called~`#1'.\\\\ The~key~`#1'~is~being~ignored. } \cs_new_nopar:Npn \CJKsymbol #1 {#1} \cs_new_nopar:Npn \CJKpunctsymbol #1 {#1} \keys_set:nn { xeCJK / options } { CJKglue = { \skip_horizontal:n { \c_zero_dim plus 0.08 \tex_baselineskip:D } } , CJKecglue = { ~ } , xCJKecglue = false , CheckSingle = false , PlainEquation = false , CheckFullRight = false , CJKspace = false , CJKmath = false , xeCJKactive = true , LocalConfig = true , LoadFandol = true , RubberPunctSkip = true , Verb = env , EmboldenFactor = 4 , SlantFactor = 0.167 , PunctStyle = quanjiao , NewLineCS = { \par \[ } , EnvCS = { \begin \end } , WidowPenalty = \c_ten_thousand , NoBreakCS = { \footnote \footnotemark \nobreak } , KaiMingPunct = { ^^^^3002 ^^^^ff0e ^^^^ff1f ^^^^ff01 } , LongPunct = { ^^^^2014 ^^^^2025 ^^^^2026 } , MiddlePunct = { ^^^^2013 ^^^^2014 ^^^^2027 ^^^^00b7 ^^^^30fb ^^^^ff65 } , AllowBreakBetweenPuncts = false } \defaultCJKfontfeatures { Script = CJK } \xeCJKsetwidth { ^^^^2013 } { 0.5 em } \ProcessKeysOptions { xeCJK / options } \RequirePackage { fontspec } [ 2012/05/01 ] \RequirePackage { xunicode-addon } \tl_const:Nx \c__xeCJK_encoding_tl { \g_fontspec_encoding_tl } \keys_define:nn { xeCJK / options } { LocalConfig .code:n = { \__xeCJK_warning:nx { option-invalid } { \l_keys_key_tl } } } \__xeCJK_msg_new:nn { option-invalid } { The~`#1'~option~only~can~be~set~in~the~optional~argument~to~the\\ \token_to_str:N \usepackage \ command~when~xeCJK~is~being~loaded.\\\\ Please~do~not~set~it~via~the~\token_to_str:N \xeCJKsetup \ command. } \tl_if_exist:NF \CJKrmdefault { \tl_gset:Nn \CJKrmdefault { rm } } \tl_if_exist:NF \CJKsfdefault { \tl_gset:Nn \CJKsfdefault { sf } } \tl_if_exist:NF \CJKttdefault { \tl_gset:Nn \CJKttdefault { tt } } \tl_new:N \l__xeCJK_family_default_init_tl \cs_new_eq:NN \__xeCJK_family_default_wrap:n \use:n \tl_set:Nx \l__xeCJK_family_default_init_tl { \exp_not:N \__xeCJK_family_default_wrap:n { \tl_if_exist:NTF \CJKfamilydefault { \exp_not:V \CJKfamilydefault } { \exp_not:N \CJKrmdefault } } } \tl_gset_eq:NN \CJKfamilydefault \l__xeCJK_family_default_init_tl \NewDocumentCommand \xeCJKsetup { +m } { \keys_set:nn { xeCJK / options } {#1} \tex_ignorespaces:D } \NewDocumentCommand \xeCJKsetemboldenfactor { m } { \xeCJKsetup { EmboldenFactor = {#1} } } \NewDocumentCommand \xeCJKsetslantfactor { m } { \xeCJKsetup { SlantFactor = {#1} } } \NewDocumentCommand \punctstyle { m } { \xeCJKsetup { PunctStyle = {#1} } } \NewDocumentCommand \xeCJKplainchr { } { \xeCJKsetup { PunctStyle = plain } } \NewDocumentCommand \CJKsetecglue { m } { \xeCJKsetup { CJKecglue = {#1} } } \cs_new_eq:NN \xeCJKsetecglue \CJKsetecglue \NewDocumentCommand \CJKspace { } { \xeCJKsetup { CJKspace = true } } \NewDocumentCommand \CJKnospace { } { \xeCJKsetup { CJKspace = false } } \NewDocumentCommand \xeCJKallowbreakbetweenpuncts { } { \xeCJKsetup { AllowBreakBetweenPuncts = true } } \NewDocumentCommand \xeCJKnobreakbetweenpuncts { } { \xeCJKsetup { AllowBreakBetweenPuncts = false } } \NewDocumentCommand \xeCJKenablefallback { } { \xeCJKsetup { AutoFallBack = true } } \NewDocumentCommand \xeCJKdisablefallback { } { \xeCJKsetup { AutoFallBack = false } } \NewDocumentCommand \xeCJKsetcharclass { m m m } { \xeCJK_set_char_class:nnn {#1} {#2} {#3} \xeCJKResetPunctClass } \cs_new_protected_nopar:Npn \xeCJK_fix_hbar: { \cs_if_free:NF \symlegacymaths { \group_begin: \cs_set_nopar:Npn \__xeCJK_tmp:w { { \mathchar '26 \mkern -9mu h } } \exp_after:wN \group_end: \if_meaning:w \__xeCJK_tmp:w \hbar \cs_set_protected_nopar:Npx \hbar { { \mathchar \int_eval:n { \symlegacymaths * \c_two_hundred_fifty_six + '26 } ~ \mkern -9mu h } } \fi: } } \cs_if_exist:NTF \fontspec_maybe_setup_maths: { \cs_gset_protected_nopar:Npx \fontspec_maybe_setup_maths: { \exp_not:o { \fontspec_maybe_setup_maths: } \xeCJK_fix_hbar: } } { \AtBeginDocument { \xeCJK_fix_hbar: } } \cs_new_protected_nopar:Npn \xeCJK@update@fam { \addto@hook \everymath { \__xeCJK_update_main_fam: \__xeCJK_update_block_fam: } } \cs_new_protected_nopar:Npn \__xeCJK_update_main_fam: { \group_begin: \xeCJK_select_font: \exp_after:wN \group_end: \exp_after:wN \tex_textfont:D \exp_after:wN \c_xeCJK_math_fam_int \tex_the:D \tex_font:D } \cs_new_protected_nopar:Npn \__xeCJK_update_block_fam: { \prop_if_empty:NF \g__xeCJK_block_fam_prop { \prop_map_function:NN \g__xeCJK_block_fam_prop \__xeCJK_update_block_fam:nn } } \cs_new_protected_nopar:Npn \__xeCJK_update_block_fam:nn #1#2 { \int_set:Nn \l__xeCJK_fam_int {#2} \group_begin: \xeCJK_select_font:n {#1} \exp_after:wN \group_end: \exp_after:wN \tex_textfont:D \exp_after:wN \l__xeCJK_fam_int \tex_the:D \tex_font:D } \__xeCJK_after_end_preamble:n { \bool_if:nT { \g__xeCJK_math_bool && \cs_if_exist_p:N \Url@MathSetup } { \tl_put_right:Nn \Url@MathSetup { \xeCJK@update@fam } } } \@ifpackagelater { fontspec } { 2014/06/21 } { } { \cs_gset_protected_nopar:Npx \fontspec_setup_maths: { \exp_not:o { \fontspec_setup_maths: \bool_if:nT { \tl_if_empty_p:N \g__fontspec_bfmathrm_tl || \tl_if_empty_p:N \g_fontspec_bfmathrm_tl } { \DeclareSymbolFontAlphabet \mathrm { operators } } } } } \cs_new_protected_nopar:Npn \__xeCJK_math_robust:N #1 { \exp_args:NNc \__xeCJK_math_robust_aux:NN #1 { \cs_to_str:N #1 ~ } } \cs_new_protected_nopar:Npn \__xeCJK_math_robust_aux:NN #1#2 { \exp_args:Nx \str_case:nnTF { \token_get_replacement_spec:N #1 } { { \x@protect #1 \protect #2 } { } { \protect #2 } { } } { \__xeCJK_math_robust:NN #1#2 } { \__xeCJK_math_robust:NN #1#1 } } \cs_new_protected_nopar:Npn \__xeCJK_math_robust:NN #1#2 { \str_if_eq_x:nnTF { \token_get_arg_spec:N #2 } { } { \exp_args:No \tl_if_head_eq_meaning:nNTF {#2} \scan_stop: { \cs_gset_protected_nopar:Npx #1 { \scan_align_safe_stop: \tl_tail:N #2 } } { \cs_if_eq:NNTF #1 \ensuremath { \cs_gset_protected_nopar:Npx #1 { \scan_align_safe_stop: \exp_not:o {#2} } } { \__xeCJK_warning:nxx { robust-failure } { \token_to_str:N #1 } { \token_to_meaning:N #2 } } } } { \__xeCJK_warning:nxx { robust-failure } { \token_to_str:N #1 } { \token_to_meaning:N #2 } } } \__xeCJK_msg_new:nnn { robust-failure } { xeCJK~can~not~make~`#1'~robust. } { The~current~meaning~of~`#1'~is:\\ \iow_indent:n {#2} } \cs_if_eq:NNTF \( \math { \__xeCJK_math_robust:N \( \cs_set_eq:NN \math \( } { \__xeCJK_math_robust:N \( \__xeCJK_math_robust:N \math } \cs_if_eq:NNTF \) \endmath { \__xeCJK_math_robust:N \) \cs_set_eq:NN \endmath \) } { \__xeCJK_math_robust:N \) \__xeCJK_math_robust:N \endmath } \__xeCJK_math_robust:N \ensuremath \UndeclareTextCommand \nobreakspace { \UTFencname } \RenewDocumentCommand \nobreakspace { } { \leavevmode \nobreak \ } \AtBeginUTFCommand { \bool_if:NT \l__xeCJK_CJK_group_bool { \scan_stop: } } \__xeCJK_msg_new:nn { conflict-package } { The~`#1'~package~is~too~old. \\ Please~update~an~up~to~date~version~of~it\\ using~your~TeX~package~manager~or~from~CTAN. } \xeCJK_if_package_loaded:nTF { realscripts } { \@ifpackagelater { realscripts } { 2010/10/10 } { } { \__xeCJK_error:nx { conflict-package } { \xeCJK_if_package_loaded:nTF { xltxtra } { xltxtra } { realscripts } } } } { \cs_new_eq:NN \__xeCJK_dim_max:nn \dim_max:nn \cs_new_eq:NN \__xeCJK_dim_min:nn \dim_min:nn \__xeCJK_at_end_preamble:n { \xeCJK_if_package_loaded:nT { realscripts } { \@ifpackagelater { realscripts } { 2010/10/10 } { } { \cs_gset_eq:NN \dim_max:nn \__xeCJK_dim_max:nn \cs_gset_eq:NN \dim_min:nn \__xeCJK_dim_min:nn } } \cs_undefine:N \__xeCJK_dim_max:nn \cs_undefine:N \__xeCJK_dim_min:nn } } \RenewDocumentCommand \fontfamily { m } { \tl_set:Nx \f@family {#1} \__xeCJK_update_family:nn {#1} { { \rmdefault } { \xeCJK_switch_family:n { \CJKrmdefault } } { \sfdefault } { \xeCJK_switch_family:n { \CJKsfdefault } } { \ttdefault } { \xeCJK_switch_family:n { \CJKttdefault } } { \familydefault } { \xeCJK_switch_family:n { \CJKfamilydefault } } } } \cs_new_eq:NN \__xeCJK_update_family:nn \str_case:nn \cs_new_eq:NN \xeCJK@fix@penalty \fix@penalty \tl_replace_once:Nnn \xeCJK@fix@penalty { \@@italiccorr } { \xeCJK@italiccorr } \tl_replace_once:Nnn \sw@slant { \fix@penalty } { \xeCJK@fix@penalty } \cs_new_protected_nopar:Npn \xeCJK@italiccorr { \int_compare:nNnTF \xetex_interchartokenstate:D > \c_zero { \xeCJK_if_last_node:nTF { default } { \xeCJK_remove_node: \@@italiccorr { \xeCJK_make_node:n { default } } } { \xeCJK_if_last_node:nTF { CJK } { \xeCJK_remove_node: \@@italiccorr { \xeCJK_make_node:n { CJK } } \use:n } { \xeCJK_if_last_node:nTF { CJK-space } { \xeCJK_remove_node: \@@italiccorr { \xeCJK_make_node:n { CJK-space } } \use:n } { \@@italiccorr \use_none:n } } { \exp_after:wN \exp_after:wN \exp_after:wN \exp_after:wN \exp_after:wN \exp_after:wN \exp_after:wN \exp_after:wN \exp_after:wN \exp_after:wN \exp_after:wN \exp_after:wN \exp_after:wN \exp_after:wN \exp_after:wN \xeCJK_ignore_spaces:w } } } { \@@italiccorr } } \cs_new_eq:NN \g__xeCJK_xetex_allocator_int \xe@alloc@intercharclass \__xeCJK_after_end_preamble:n { \int_compare:nNnF { \c__xeCJK_class_begin_int + \seq_count:N \g__xeCJK_new_class_seq } = { \g__xeCJK_xetex_allocator_int } { \int_step_inline:nnnn { \c__xeCJK_class_begin_int + \c_one } \c_one \g__xeCJK_xetex_allocator_int { \seq_if_in:NnF \g__xeCJK_new_class_seq {#1} { \__xeCJK_set_others_toks:n {#1} } } } } \cs_new_protected_nopar:Npn \__xeCJK_set_others_toks:n #1 { \int_set:cn { \__xeCJK_class_csname:n { Others } } {#1} \seq_map_inline:Nn \g__xeCJK_CJK_class_seq { \xeCJK_copy_inter_class_toks:nnnn {##1} { Others } {##1} { NormalSpace } \xeCJK_copy_inter_class_toks:nnnn { Others } {##1} { NormalSpace } {##1} \xeCJK_app_inter_class_toks:nnx {##1} { Others } { \xeCJK_get_inter_class_toks:nn { Default } { Others } } \xeCJK_pre_inter_class_toks:nnx { Others } {##1} { \xeCJK_get_inter_class_toks:nn { Others } { Default } } \xeCJK_if_blank_x:nT { \xeCJK_get_inter_class_toks:nn { Others } { Boundary } } { \xeCJK_copy_inter_class_toks:nnnn { Others } { Boundary } { Default } { Boundary } } \xeCJK_if_blank_x:nT { \xeCJK_get_inter_class_toks:nn { Boundary } { Others } } { \xeCJK_copy_inter_class_toks:nnnn { Boundary } { Others } { Boundary } { Default } } } } \cs_new_eq:NN \__xeCJK_group_begin: \group_begin: \cs_new_eq:NN \__xeCJK_group_end: \group_end: \tl_map_inline:nn { \textellipsis \textendash \textemdash \textperiodcentered \textcentereddot \textquoteleft \textquoteright \textquotedblleft \textquotedblright \textcdot \textgrq \textgrqq } { \AtBeginUTFCommand [#1] { \__xeCJK_group_begin: \makexeCJKinactive } \AtEndUTFCommand [#1] { \__xeCJK_group_end: } } \__xeCJK_after_end_preamble:n { \l__xeCJK_patch_Bxii_tl } \tl_new:N \l__xeCJK_patch_Bxii_tl \cs_new_protected_nopar:Npn \__xeCJK_patch_Bxii:nN #1#2 { \tl_put_right:Nx \l__xeCJK_patch_Bxii_tl { \__xeCJK_patch_Bxii:n { #1 \token_to_str:N #2 } } } \group_begin: \cs_set:Npn \__xeCJK_tmp:w #1 { \group_end: \cs_new_protected_nopar:Npn \__xeCJK_patch_Bxii:nNN ##1##2##3 { \tl_put_right:Nx \l__xeCJK_patch_Bxii_tl { \__xeCJK_patch_Bxii:Nnn #1 { ##1 \token_to_str:N ##2 } { \token_to_str:N ##3 } } } } \use:n { \char_set_catcode_other:N \\ \__xeCJK_tmp:w } { \ } \cs_new_protected_nopar:Npn \__xeCJK_patch_Bxii:n #1 { \cs_if_free:cF {#1} { \cs_gset_eq:cN {#1} \__xeCJK_Default_Bxii: } } \cs_new_protected_nopar:Npn \__xeCJK_patch_Bxii:Nnn #1#2#3 { \cs_if_free:cF {#2} { \cs_gset_eq:cN { #1#2 - #3 } \__xeCJK_Default_Bxii: } } \group_begin: \char_set_catcode_other:n { 183 } \cs_new_protected_nopar:Npn \__xeCJK_Default_Bxii: { \int_compare:nNnTF \xetex_interchartokenstate:D > \c_zero { \__xeCJK_group_begin: \makexeCJKinactive ^^b7 \__xeCJK_group_end: } { ^^b7 } } \group_end: \clist_map_inline:nn { { T3 } \textvibyy , { T2A } \cyrchvcrs , { T2B } \cyrchldsc , { T2C } \cyrabhha , { X2 } \cyrchldsc , { TS1 } \textperiodcentered , { LY1 } \textperiodcentered } { \__xeCJK_patch_Bxii:nN #1 } \clist_map_inline:nn { { T1 } \r u , { T4 } \B t , { T5 } \` \ecircumflex , { LGR } \accpsilivaria w } { \__xeCJK_patch_Bxii:nNN #1 } \tl_put_right:Nx \l__xeCJK_patch_Bxii_tl { \__xeCJK_patch_Bxii:n { \token_to_str:N \T 5 \token_to_str:N \` - \token_to_str:N \^ - e } } \__xeCJK_after_end_preamble:n { \xeCJK_if_package_loaded:nT { pifont } { \RenewDocumentCommand \Pifont { m } { \makexeCJKinactive \usefont { U } {#1} { m } { n } } } } \__xeCJK_after_end_preamble:n { \xeCJK_if_package_loaded:nT { hyperref } { \pdfstringdefDisableCommands { \__xeCJK_gobble_CJKfamily: \xeCJK_cs_clear:N \makexeCJKinactive \xeCJK_cs_clear:N \__xeCJK_group_begin: \xeCJK_cs_clear:N \__xeCJK_group_end: } } } \__xeCJK_after_end_preamble:n { \bool_if:nT { \xeCJK_if_package_loaded_p:n { cprotect } && \cs_if_exist_p:N \icprotect } { \exp_after:wN \tex_let:D \cs:w cprotect \cs_end: \icprotect } } \cs_if_eq:NNTF \ifCTEX@fntef \tex_iftrue:D { \AtEndOfPackage { \RequirePackage { xeCJKfntef } } } { \__xeCJK_at_end_preamble:n { \xeCJK_if_package_loaded:nF { xeCJKfntef } { \xeCJK_if_package_loaded:nTF { CJKfntef } { \RequirePackage { xeCJKfntef } } { \xeCJK_if_package_loaded:nT { ulem } { \RequirePackage { xeCJKfntef } } } } } } \__xeCJK_at_end_preamble:n { \xeCJK_if_package_loaded:nT { listings } { \RequirePackage { xeCJK-listings } } } \__xeCJK_at_end_preamble:n { \clist_map_inline:nn { everysel , microtype } { \xeCJK_if_package_loaded:nT {#1} { \cs_undefine:c { ver@CJK . \c__xeCJK_package_ext_tl } \clist_map_break: } } } \cs_new_protected:Npn \CJKaddEncHook #1#2 { \str_if_eq:nnT {#1} { \CJK@UnicodeEnc } { \group_begin: \cs_set_eq:NN \Unicode \__xeCJK_calc_unicode:nn \cs_set_eq:NN \def \xeCJK_char_from_charcode:Nn #2 \group_end: \tl_gset:Nn \CJK@tenthousand { ^^^^4e07 } \tl_gset:Nn \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 \__xeCJK_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 \__xeCJK_calc_unicode:nn {#1} {#2} \scan_stop: } \bool_if:NT \g__xeCJK_config_bool { \ExplSyntaxOff \file_input:n { \g__xeCJK_config_name_tl .cfg } \ExplSyntaxOn } %% %% This package consists of the files xeCJK.dtx, %% full-stop.map, %% fullwidth-stop.map, %% han-simp.map, %% han-trad.map, %% and the derived files xeCJK.pdf, %% xeCJK.sty, %% xeCJK.cfg, %% xeCJK.ins, %% xeCJKfntef.sty, %% xeCJK-listings.sty, %% xunicode-addon.sty, %% xunicode-extra.def, %% xeCJK-example-autofake.tex, %% xeCJK-example-fallback.tex, %% xeCJK-example-subCJKblock.tex, %% xeCJK-example-CJKecglue.tex, %% xeCJK-example-checksingle.tex, %% xeCJK-example-CJKfntef.tex, %% xeCJK-example-punctstyle.tex, %% xeCJK-example-verbatim.tex, %% xeCJK-example-CM.tex, %% xeCJK-example-listings.tex, %% xeCJK-example-mathblock.tex, %% xunicode-symbols.tex, %% xunicode-commands.tex, %% xunicode-combine-marks.tex, %% xunicode-symbols.pdf, %% full-stop.tec, %% fullwidth-stop.tec, %% han-simp.tec, %% han-trad.tec, and %% README.md. %% %% End of file `xeCJK.sty'.