diff options
author | Karl Berry <karl@freefriends.org> | 2012-12-14 00:12:28 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2012-12-14 00:12:28 +0000 |
commit | 54b3f2d277e2a2359cd249de2055ae706214c4be (patch) | |
tree | fc68d2f1ccad6b178993d9040b1ca0bb1d4fc11e | |
parent | ad47ef91d24fc1c34e67a07db6a1e860d3b0253d (diff) |
xecjk (13dec12)
git-svn-id: svn://tug.org/texlive/trunk@28528 c570f23f-e606-0410-a88d-b1316a301751
-rw-r--r-- | Master/texmf-dist/doc/xelatex/xecjk/README | 4 | ||||
-rw-r--r-- | Master/texmf-dist/doc/xelatex/xecjk/example/xeCJK-example-CJKfntef.tex | 43 | ||||
-rw-r--r-- | Master/texmf-dist/doc/xelatex/xecjk/example/xeCJK-example-checksingle.tex | 7 | ||||
-rw-r--r-- | Master/texmf-dist/doc/xelatex/xecjk/example/xeCJK-example-fallback.tex | 2 | ||||
-rw-r--r-- | Master/texmf-dist/doc/xelatex/xecjk/xeCJK.pdf | bin | 655056 -> 752103 bytes | |||
-rw-r--r-- | Master/texmf-dist/source/xelatex/xecjk/xeCJK.dtx | 2037 | ||||
-rw-r--r-- | Master/texmf-dist/source/xelatex/xecjk/xeCJK.ins | 10 | ||||
-rw-r--r-- | Master/texmf-dist/tex/xelatex/xecjk/config/xeCJK.cfg | 5 | ||||
-rw-r--r-- | Master/texmf-dist/tex/xelatex/xecjk/xeCJK.sty | 996 | ||||
-rw-r--r-- | Master/texmf-dist/tex/xelatex/xecjk/xeCJKfntef.sty | 339 |
10 files changed, 2581 insertions, 862 deletions
diff --git a/Master/texmf-dist/doc/xelatex/xecjk/README b/Master/texmf-dist/doc/xelatex/xecjk/README index 94a9f709aab..721c1572864 100644 --- a/Master/texmf-dist/doc/xelatex/xecjk/README +++ b/Master/texmf-dist/doc/xelatex/xecjk/README @@ -14,6 +14,7 @@ This package consists of the file xeCJK.dtx xeCJK.sty, xeCJK.cfg, xeCJK.ins, + xeCJKfntef.sty, xeCJK-example-autofake.tex, xeCJK-example-fallback.tex, xeCJK-example-subCJKblock.tex, @@ -47,8 +48,7 @@ The package requires LaTeX3 support as provided in the l3kernel and l3packages bundles and the fontspec package. All of these are available on CTAN as ready-to-install zip files. Suitable versions are available in the latest version of MiKTeX and TeX Live (updating the relevant -packages online may be necessary). Both of xpatch and etoolbox packages -are required. They are also available on CTAN. +packages online may be necessary). To compile the documentation without error, you will need some specific CJK scripts fonts (TrueType or OpenType). diff --git a/Master/texmf-dist/doc/xelatex/xecjk/example/xeCJK-example-CJKfntef.tex b/Master/texmf-dist/doc/xelatex/xecjk/example/xeCJK-example-CJKfntef.tex index 700f3d0d3a6..0e0e39b5033 100644 --- a/Master/texmf-dist/doc/xelatex/xecjk/example/xeCJK-example-CJKfntef.tex +++ b/Master/texmf-dist/doc/xelatex/xecjk/example/xeCJK-example-CJKfntef.tex @@ -9,22 +9,47 @@ \documentclass{article} \usepackage{xeCJK} \usepackage{xcolor} -\usepackage{CJKfntef} -\setCJKmainfont{SimSun} +\usepackage{xeCJKfntef} +\xeCJKDeclareSubCJKBlock{test}{ `殆 , `已 } +\setCJKmainfont[test=SimHei]{SimSun} -\begin{document} - -\CJKunderline{汉字}\CJKunderline{加下划线加下划线加下划线加下划线 -加下划线加下划线加下划线加下划线加下划线加下划线加下划线} +\def\showtext{% + 庄子曰:“吾生也有涯,而知也无涯。以有涯随无涯,殆已!已而为知者,殆而已矣!% + 为善无近名,为恶无近刑,缘督以为经,可以保身,可以全生,可以养亲,可以尽年。”} +\newcommand\CJKfntef[1]{% + \csname#1\endcsname{\showtext}\par + \csname#1\endcsname*{\showtext}\par + \CJKunderdot{\showtext\csname#1\endcsname{\showtext}}\par + \CJKunderdot{\showtext\csname#1\endcsname*{\showtext}}\par + \csname#1\endcsname{\showtext\CJKunderdot{\showtext}}\par + \csname#1\endcsname*{\showtext\CJKunderdot{\showtext}}\par\bigskip} -\CJKunderwave{波浪线} +\begin{document} +\CJKunderline{汉 字}\CJKunderline{加下划线} +\varCJKunderline{汉字}\varCJKunderline{加下划线} \CJKunderanyline{0.5em}{\sixly \kern-.021em\char58 \kern-.021em}{自定义下划线} - \CJKunderanyline{0.2em}{\kern-.03em\vtop{\kern.2ex\hrule width.2em\kern 0.11em \hrule height 0.1em}\kern-.03em}{自定义下划线} -\CJKunderanysymbol{0.5em}{$\cdot$}{汉字加点} +\CJKunderanyline{0.5em}{-}{\showtext} + +\CJKunderanysymbol{0.2em}{-}{\showtext} + +\CJKunderdot{\showtext} + +\begin{CJKfilltwosides}{40mm} +两端分散对齐\\ +分散对齐\\ +\CJKunderdot{汉字可加点}\\ +\CJKunderline{汉字可加下划线} +\end{CJKfilltwosides} + +\CJKfntef{CJKunderline} +\CJKfntef{CJKunderwave} +\CJKfntef{CJKunderdblline} +\CJKfntef{CJKsout} +\CJKfntef{CJKxout} \end{document} %% diff --git a/Master/texmf-dist/doc/xelatex/xecjk/example/xeCJK-example-checksingle.tex b/Master/texmf-dist/doc/xelatex/xecjk/example/xeCJK-example-checksingle.tex index 16f4a034420..3735d4a76e7 100644 --- a/Master/texmf-dist/doc/xelatex/xecjk/example/xeCJK-example-checksingle.tex +++ b/Master/texmf-dist/doc/xelatex/xecjk/example/xeCJK-example-checksingle.tex @@ -13,6 +13,8 @@ \def。{.} \def\foo{一} \long\def\showtext{一二三四五六七八九十一二三四五六七八九十一二三四五六七八九十。 +\[x^2+y^2\] +一二三四五六七八九十一二三四五六七八九十一二三四五六七八九十\foo $$x^2+y^2$$ 一二三四五六七八九十一二三四五六七八九十一二三四五六七八九十\foo \begin{equation} @@ -28,6 +30,11 @@ x^2+y^2 \xeCJKsetup{CheckSingle} \showtext + +\hrulefill\bigskip + +\xeCJKsetup{PlainEquation} +\showtext \end{document} %% %% diff --git a/Master/texmf-dist/doc/xelatex/xecjk/example/xeCJK-example-fallback.tex b/Master/texmf-dist/doc/xelatex/xecjk/example/xeCJK-example-fallback.tex index 53e64190a31..473abf793cb 100644 --- a/Master/texmf-dist/doc/xelatex/xecjk/example/xeCJK-example-fallback.tex +++ b/Master/texmf-dist/doc/xelatex/xecjk/example/xeCJK-example-fallback.tex @@ -8,7 +8,7 @@ %% \documentclass{article} \usepackage[AutoFallBack]{xeCJK} -\usepackage{CJKfntef} +\usepackage{xeCJKfntef} \usepackage{array} \setCJKmainfont[AutoFakeBold,AutoFakeSlant]{KaiTi_GB2312} \setCJKfallbackfamilyfont{\CJKrmdefault}[BoldFont=SimHei] diff --git a/Master/texmf-dist/doc/xelatex/xecjk/xeCJK.pdf b/Master/texmf-dist/doc/xelatex/xecjk/xeCJK.pdf Binary files differindex 39ed5e3552e..2a30603cac8 100644 --- a/Master/texmf-dist/doc/xelatex/xecjk/xeCJK.pdf +++ b/Master/texmf-dist/doc/xelatex/xecjk/xeCJK.pdf diff --git a/Master/texmf-dist/source/xelatex/xecjk/xeCJK.dtx b/Master/texmf-dist/source/xelatex/xecjk/xeCJK.dtx index 4bdcdb2f7bc..bc8118b51a7 100644 --- a/Master/texmf-dist/source/xelatex/xecjk/xeCJK.dtx +++ b/Master/texmf-dist/source/xelatex/xecjk/xeCJK.dtx @@ -22,6 +22,7 @@ This package consists of the file xeCJK.dtx xeCJK.sty, xeCJK.cfg, xeCJK.ins, + xeCJKfntef.sty, xeCJK-example-autofake.tex, xeCJK-example-fallback.tex, xeCJK-example-subCJKblock.tex, @@ -56,8 +57,7 @@ The package requires LaTeX3 support as provided in the l3kernel and l3packages bundles and the fontspec package. All of these are available on CTAN as ready-to-install zip files. Suitable versions are available in the latest version of MiKTeX and TeX Live (updating the relevant -packages online may be necessary). Both of xpatch and etoolbox packages -are required. They are also available on CTAN. +packages online may be necessary). To compile the documentation without error, you will need some specific CJK scripts fonts (TrueType or OpenType). @@ -81,7 +81,7 @@ CJK scripts fonts (TrueType or OpenType). \askforoverwritefalse \preamble -$Id: xeCJK.dtx 368 2012-11-23 04:55:23Z sobenlee $ +$Id: xeCJK.dtx 382 2012-12-13 04:58:22Z sobenlee $ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ ----------------------------------------------------------------- Author: @@ -112,6 +112,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ xeCJK.sty, xeCJK.cfg, xeCJK.ins, + xeCJKfntef.sty, xeCJK-example-autofake.tex, xeCJK-example-fallback.tex, xeCJK-example-subCJKblock.tex, @@ -127,7 +128,9 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ \declarepostamble\emptypostamble \endpostamble \usedir{tex/xelatex/xecjk} -\generate{\file{\jobname.sty}{\from{\jobname.dtx}{package}}} +\generate{ + \file{\jobname.sty}{\from{\jobname.dtx}{package}} + \file{xeCJKfntef.sty}{\from{\jobname.dtx}{fntef}}} \usedir{tex/xelatex/xecjk/config} \generate{ \usepreamble\emptypreamble @@ -156,41 +159,44 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ \xeCJKMaybeStopHere %</internal> % -%<*driver|package|config> -\NeedsTeXFormat{LaTeX2e} +%<*driver|package|config|fntef> %<*!config> +\NeedsTeXFormat{LaTeX2e} \RequirePackage{expl3} %</!config> -\GetIdInfo$Id: xeCJK.dtx 368 2012-11-23 04:55:23Z sobenlee $ -%<*!config> +\GetIdInfo$Id: xeCJK.dtx 382 2012-12-13 04:58:22Z sobenlee $ +%<*!config&!fntef> {Typesetting CJK scripts with XeLaTeX} -%</!config> +%</!config&!fntef> %<config> {Configuration file for xeCJK package} -%<*!package> +%<fntef> {xeCJK patch file for ulem/CJKfntef} +%<*!package&!fntef> \ProvidesExplFile -%</!package> +%</!package&!fntef> %<*driver> {\ExplFileName.\ExplFileExtension} %</driver> %<config> {\ExplFileName.cfg} -%<package>\ProvidesExplPackage +%<package|fntef>\ProvidesExplPackage %<package> {\ExplFileName} - {\ExplFileDate}{3.1.0}{\ExplFileDescription} +%<fntef> {xeCJKfntef} + {\ExplFileDate}{3.1.1}{\ExplFileDescription} %<*driver> +\def\xeCJKversion{3.1.1} +\let\xeCJKdate\ExplFileDate \let\xeCJKrevnum\ExplFileVersion \ExplSyntaxOff %</driver> -%</driver|package|config> +%</driver|package|config|fntef> % %<*driver> \expandafter\let\csname ver@thumbpdf.sty\endcsname\empty \documentclass[numbered,a4paper,full]{l3doc} \hypersetup{pdfstartview=FitH} \usepackage{xeCJK} -\usepackage{CJKfntef} +\usepackage{xeCJKfntef} \usepackage{geometry} \usepackage[toc]{multitoc} -\normalem \fvset{formatcom=\xeCJKVerbAddon} \linespread{1.1} \setlist{noitemsep,topsep=1ex} @@ -246,9 +252,8 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ \def\TF{true\orvar{}false} \def\TTF{\defaultvar{true}\orvar{}false} \def\TFF{true\orvar\defaultvar{false}} -\def\orvar{\char`\|} +\chardef\orvar`\| \let\defaultvar\textbf -\def\argbrace#1{\{#1\}} \@addtoreset{CodelineNo}{section} \def\tokslink#1{\hyperlink{#1}{\ding{51}}} \makeatother @@ -270,14 +275,14 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ %</driver> % \fi % -% \CheckSum{3035} +% \CheckSum{3762} % \changes{v3.1.0}{2012/11/13}{放弃对 \cs{outer} 宏的特殊处理。} +% \changes{v3.1.1}{2012/12/07}{不再依赖 \pkg{xpatch} 宏包。} % -% \GetFileInfo{\jobname.dtx} % % \title{\bfseries\pkg{xeCJK} 宏包} % \author{\href{http://www.ctex.org}{ctex.org}} -% \date{\filedate\qquad\fileversion\thanks{\ctexkitrev{\xeCJKrevnum}.}} +% \date{\xeCJKdate\qquad\xeCJKversion\thanks{\ctexkitrev{\xeCJKrevnum}.}} % \maketitle % % \tableofcontents @@ -301,7 +306,6 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \package{l3packages}。\pkg{xeCJK} 还需要通过 \package{fontspec} 宏包来调用系统字 % 体。将在 \ref{subsec:opts}~节介绍的功能选项 |CJKnumber| 需要 \package{CJK} 宏包套 % 件中的 \pkg{CJKnumb} 的支持;|indentfirst| 选项需要 \package{indentfirst} 宏包。 -% 此外还需要 \package{xpatch} 和 \package{etoolbox} 宏包。 % \pkg{xeCJK} 会自动根据需要载入这些宏包。 % % \pkg{xeCJK} 的原始作者是孙文昌,2009 年 5 月起宏包被收入 \ctexkit\ 项目进行 @@ -352,7 +356,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % % \begin{function}{\xeCJKsetup} % \begin{syntax} -% \cs{xeCJKsetup} \argbrace{\meta{key_1}=\meta{var_1}, \meta{key_2}=\meta{var_2}, ...} +% \cs{xeCJKsetup} \{\meta{key_1}=\meta{var_1}, \meta{key_2}=\meta{var_2}, ...\} % \end{syntax} % 其中 \meta{key_1}, \meta{key_2} 是设置选项,而 \meta{val_1}, \meta{val_2} 则是对应选项的 % 设置内容。多个选项可以在一个语句中完成设置。例如 @@ -370,11 +374,10 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % 有些选项或命令后面带有 \hypertarget{expstar}{\hyperlink{expstar}{$\star$}} 号,这表示这 % 个选项或命令只能在导言区中使用,而 \hypertarget{rexpstar}{\hyperlink{rexpstar}{\ding{73}}} % 号则表示这个选项或命令只能在导言区使用,并且只影响随后定义的 CJK 字体。其余不带特殊标记的 -% 选项或命令,如果没有特别说明,可以在导言区或正文中使用。 -% -% 下列选项使用加粗的形式来表示 \pkg{xeCJK} 的默认设置。 +% 选项或命令,如果没有特别说明,可以在导言区或正文中使用。% +% 使用粗体来表示 \pkg{xeCJK} 的默认设置。 % -% \begin{function}[EXP]{LocalConfig} +% \begin{function}[EXP,added=2012-11-22]{LocalConfig} % \begin{syntax} % LocalConfig = \marg{\TTF\orvar{}name} % \end{syntax} @@ -399,7 +402,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % 到 \pkg{CJKnumb},请通过这个选项调用它。 % \end{function} % -% \begin{function}[EXP]{indentfirst} +% \begin{function}[EXP,updated=2012-11-22]{indentfirst} % \begin{syntax} % indentfirst = \meta{\TTF} % \end{syntax} @@ -434,7 +437,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % % \begin{function}{CJKglue} % \begin{syntax} -% CJKglue = \argbrace{\cs{hspace}\argbrace{0pt plus .08\cs{baselineskip}}} +% CJKglue = \{\cs{hskip} 0pt plus 0.08\cs{baselineskip}\} % \end{syntax} % 设置 CJK 文字之间插入的 |glue|,上边是 \pkg{xeCJK} 的默认值。一般来说,除非有 % 特殊需要(例如,改变文字间距等),否则不需要设置这个选项,使用默认值即可。如果要设置 @@ -460,16 +463,43 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % 入的 CJK 文字与西文之间的空格。 % \end{function} % -% \begin{function}{CheckSingle} +% \begin{function}[updated=2012-12-06]{CheckSingle} % \begin{syntax} % CheckSingle = \meta{\TFF} % \end{syntax} -% 是否避免单个 CJK 文字单独占一个段落的最后一行。 +% 是否避免单个 CJK 文字单独占一个段落的最后一行。需要说明的是,这个选项只有在 +% 段末的最后一个字是 CJK 文字或者标点符号,并且倒数第二和第三个字都是文字才能 +% 正确处理处理孤字的问题。如果这倒数三个字有作为控制序列的参数的情况,那么一般 +% 来说也不能正确处理。 +% \end{function} +% +% \begin{function}[added=2012-12-06]{PlainEquation} +% \begin{syntax} +% PlainEquation = \meta{\TFF} +% \end{syntax} +% 如果使用了 |$$...$$| 的形式来输入行间数学公式,就需要启用本选项,以便 +% |CheckSingle| 选项能够正确识别。推荐使用 |\[...\]| 的形式来输入行间数学公式。 +% \end{function} +% +% \begin{function}[added=2012-12-04]{NewLineCS,NewLineCS+,NewLineCS-} +% \begin{syntax} +% NewLineCS = \{ \cs{par} \cs{[} \} +% \end{syntax} +% 设置造成断行的控制序列,以便 |CheckSingle| 选项能够正确识别。 +% 以上是 \pkg{xeCJK} 的初始设置。 % \end{function} % -% \begin{function}{InlineEnv,InlineEnv+,InlineEnv-} +% \begin{function}[added=2012-12-04]{EnvCS,EnvCS+,EnvCS-} % \begin{syntax} -% InlineEnv = \argbrace{env1, env2, env3, ...} +% EnvCS = \{ \cs{begin} \cs{end} \} +% \end{syntax} +% 设置 \LaTeX 环境开始和结束的控制序列,以便 |CheckSingle| 选项能够正确识别。 +% 以上是 \pkg{xeCJK} 的初始设置。 +% \end{function} +% +% \begin{function}[updated=2012-12-06]{InlineEnv,InlineEnv+,InlineEnv-} +% \begin{syntax} +% InlineEnv = \{\meta{env_1}, \meta{env_2}, \meta{env_3}, ...\} % \end{syntax} % 在使用 |CheckSingle| 选项的时候,\pkg{xeCJK} 会将 CJK 文字后接着的 \LaTeX 环境的 % 开始 |\begin{...}| 和结束 |\end{...}| 视为断行的地方,如果有某些特殊 @@ -514,7 +544,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % 设置伪斜体的粗细程度,范围是 $-0.999 \sim 0.999$。 % \end{function} % -% \begin{function}{PunctStyle} +% \begin{function}[updated=2012-11-10]{PunctStyle} % \begin{syntax} % PunctStyle = \marg{\defaultvar{quanjiao}\orvar{}banjiao\orvar{}kaiming\orvar{}hangmobanjiao\orvar{}CCT\orvar{}plain\orvar{}...} % \end{syntax} @@ -576,6 +606,24 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % 这一选项改变这一设置。 % \end{function} % +% \begin{function}[added=2012-12-02]{CheckFullRight} +% \begin{syntax} +% CheckFullRight = \meta{\TFF} +% \end{syntax} +% 某些控制序列要求不能在它的前面断行。但是在缺省状态下,单个全角右标点的后面总是 +% 可以断行的。因此当这些控制序列出现在全角右标点后面时,可能出现了意料之外的断行。 +% 此时可以使用这个选项来避免这个情况。 +% \end{function} +% +% \begin{function}[added=2012-12-02]{NoBreakCS,NoBreakCS+,NoBreakCS-} +% \begin{syntax} +% NoBreakCS = \{ \cs{footnote} \cs{footnotemark} \cs{nobreak} \} +% \end{syntax} +% 设置不能在全角右标点后断行的控制序列。以上是 \pkg{xeCJK} 的默认设置。如果这些 +% 控制序列在文档中只出现少量几次,也可以不必使用 |CheckFullRight| 选项,而是手工 +% 在这些控制序列前面加上 \ref{subsec:others}~节介绍的 \cs{xeCJKnobreak}。 +% \end{function} +% % \subsection{字体设置与选择} % \label{subsec:fontset} % @@ -613,20 +661,6 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % 设置正文等宽族的 CJK 字体,影响 \cs{ttfamily} 和 \cs{texttt} 的字体。 % \end{function} % -% \begin{function}{\xeCJKVerbAddon} -% \begin{syntax} -% \cs{xeCJKVerbAddon} -% \end{syntax} -% 调整文字间距以便于让 CJK 字符占的宽度等于西文等宽字体中两个空格的宽度。这有利于 -% 等宽字体的代码对齐等情形。抄录 |(verbatim)| 环境将自动使用 \cs{xeCJKVerbAddon} -% 的效果。需要注意的是,\cs{xeCJKVerbAddon} 对 \pkg{xeCJK} 的内部进行了比较大的 -% 修改,使用它之后,关于标点符号的禁则将会丢失。所以不能单独使用,应该放在分组里 -% 限制其作用域,否则是无效的。当然它可以和其它关于代码抄录的宏包配合使用。例如, -% 可以使用于 \package{fancyvrb} 宏包的 |formatcom| 选项。此时设置的西文字体应该 -% 确实是等宽的以保证对齐。若西文等宽字体发生变动(包括字体大小),则需要在其后面 -% 使用 \cs{xeCJKVerbAddon},重新计算间距的宽度。 -% \end{function} -% % \begin{function}[EXP]{\setCJKfamilyfont} % \begin{syntax} % \cs{setCJKfamilyfont} \Arg{family} \oarg{font features} \Arg{font name} @@ -634,7 +668,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % 声明新的 CJK 字体族 \meta{family} 并指定字体。 % \end{function} % -% \begin{function}{\CJKfamily} +% \begin{function}[updated=2012-10-27]{\CJKfamily} % \begin{syntax} % \cs{CJKfamily} \Arg{family} % \cs{CJKfamily+} \Arg{family} @@ -709,12 +743,12 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % % \begin{function}{\CJKfamilydefault} % 保存 \cs{normalfont} 所使用的 CJK 字体族,默认值是 \cs{CJKrmdefault}。类似西文字 -% 体的 \cs{familydefault}。可以通过更改它来改变文档的默认 CJK 字体族。例如,使用 +% 体的 \cs{familydefault}。\pkg{xeCJK} 会在导言区结束的时候根据西文字体的情况自动 +% 更新 \cs{CJKfamilydefault}。例如,在导言区里使用 % \begin{verbatim} % \renewcommand\familydefault{\sfdefault} -% \renewcommand\CJKfamilydefault{\CJKsfdefault} % \end{verbatim} -% 可以将全文的 CJK 和西文默认字体改为无衬线字体族。 +% 就可以将全文的 CJK 和西文默认字体都改为无衬线字体族。 % \end{function} % % \begin{function}[EXP]{\setCJKmathfont} @@ -740,7 +774,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % % \begin{function}{FallBack} % \begin{syntax} -% FallBack = \argbrace{\oarg{font features}\Arg{font name}} +% FallBack = \{\oarg{font features}\Arg{font name}\} % \end{syntax} % \pkg{xeCJK} 在 \meta{font features} 里增加了 |FallBack| 这个选项。用来在声明主 % 字体的时候,同时设置备用字体。例如,上面的例子等价于: @@ -761,8 +795,8 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \begin{syntax} % \cs{setCJKfallbackfamilyfont} \Arg{family} \oarg{common font features} % \ \{ -% \ \argbrace{\oarg{font features 1} \Arg{font name 1}} , -% \ \argbrace{\oarg{font features 2} \Arg{font name 2}} , +% \ \{\oarg{font features 1} \Arg{font name 1}\} , +% \ \{\oarg{font features 2} \Arg{font name 2}\} , % \ ...... % \ \} % \end{syntax} @@ -927,7 +961,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \begin{syntax} % \cs{xeCJKResetCharClass} % \end{syntax} -% 用于重置 \pkg{xeCJK} 对各个字符类别的设置。 +% 用于恢复 \pkg{xeCJK} 对各个字符类别的初始化设置。 % \end{function} % % \begin{function}[EXP]{\xeCJKResetPunctClass} @@ -941,7 +975,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \begin{syntax} % \cs{normalspacedchars} \Arg{char list} % \end{syntax} -% 在 \meta{char list} 中出现的字符两端不自动添加空格,默认设置是 |/|。 +% 在 \meta{char list} 中出现的字符两端不自动添加空格,初始设置是 |/|。 % \end{function} % % \subsection{标点符号的处理} @@ -982,14 +1016,14 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \subsubsection{定义标点符号处理格式} % \label{subsec:punctstyle} % -% \begin{function}[EXP]{\xeCJKDeclarePunctStyle} +% \begin{function}[EXP,added=2012-11-10]{\xeCJKDeclarePunctStyle} % \begin{syntax} % \cs{xeCJKDeclarePunctStyle} \Arg{style} \Arg{options} % \end{syntax} % 定义新的标点符号处理格式,已经存在的同名格式将被覆盖。可以设置的选项将在下面介绍。 % \end{function} % -% \begin{function}[EXP]{\xeCJKEditPunctStyle} +% \begin{function}[EXP,added=2012-11-10]{\xeCJKEditPunctStyle} % \begin{syntax} % \cs{xeCJKEditPunctStyle} \Arg{style} \Arg{options} % \end{syntax} @@ -1136,22 +1170,48 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \end{verbatim} % 将使得 \cs{xeCJKsetkern} 等的设置对 |hangmobanjiao| 这一格式无效。 % +% \subsection{其它} +% \label{subsec:others} +% +% \begin{function}[added=2012-11-19]{\xeCJKVerbAddon} +% \begin{syntax} +% \cs{xeCJKVerbAddon} +% \end{syntax} +% 调整文字间距以便于让 CJK 字符占的宽度等于西文等宽字体中两个空格的宽度。这有利于 +% 等宽字体的代码对齐等情形。抄录 |(verbatim)| 环境将自动使用 \cs{xeCJKVerbAddon} +% 的效果。需要注意的是,\cs{xeCJKVerbAddon} 对 \pkg{xeCJK} 的内部进行了比较大的 +% 修改,使用它之后,关于标点符号的禁则将会丢失。所以不能单独使用,应该放在分组里 +% 限制其作用域,否则是无效的。当然它可以和其它关于代码抄录的宏包配合使用。例如, +% 可以使用于 \package{fancyvrb} 宏包的 |formatcom| 选项。此时设置的西文字体应该 +% 确实是等宽的以保证对齐。若西文等宽字体发生变动(包括字体大小),则需要在其后面 +% 使用 \cs{xeCJKVerbAddon},重新计算间距的宽度。 +% \end{function} +% +% \begin{function}[added=2012-12-03]{\xeCJKnobreak} +% \begin{syntax} +% ……汉字。\cs{xeCJKnobreak}\cs{footnote}\{脚注\} +% \end{syntax} +% \cs{xeCJKnobreak} 用在全角标点符号后面,目的是确保不能在此处断行。如果已经启用了 +% 前面介绍的 |CheckFullRight| 选项,则不需要再用此命令。 +% \end{function} +% % \section{已知问题和兼容性} % -% 为了与 \pkg{CJKnumb} 和 \pkg{CJKfntef} 宏包兼容,\pkg{xeCJK} 使用并重新定义了 -% \pkg{CJK} 宏包的部分宏命令,如 \cs{CJKfamily}、\cs{CJKsymbol} 和 \cs{CJKpunctsymbol} 等。 -% 需要指出,\pkg{xeCJK} 不需要 \pkg{CJK} 的支持,并且 \pkg{xeCJK} 自动禁止在它之后载入 -% \pkg{CJK} 宏包。 +% \pkg{xeCJK} 使用并重新定义了 \pkg{CJK} 宏包的部分宏命令,如 \cs{CJKfamily}、 +% \cs{CJKsymbol} 和 \cs{CJKglue} 等。需要指出,\pkg{xeCJK} 不需要 \pkg{CJK} +% 的支持,并且 \pkg{xeCJK} 自动禁止在它之后载入 \pkg{CJK} 宏包。 % -% 可以在 \pkg{xeCJK} 之后载入 \pkg{CJKfntef} 宏包,以实现\CJKunderdot{汉字加点} -% 和\CJKunderwave{可断行的下划线}等。 +% \CJKunderline{\pkg{xeCJK} 包含有一个子宏包 \pkg{xeCJKfntef},可以用它来实现% +% \CJKunderdot{汉字加点}和可断行的下划线等。它是 \pkg{CJKfntef} 宏包在在 \XeLaTeX +% 下的替换版本,基本用法完全一致,在 \pkg{CJKfntef} 的源文件\ \file{CJKfntef.sty} +% 的注解部分里有说明。} % % 新版本(\texttt{3.x})的 \pkg{xeCJK} 完全使用 \hologo{LaTeX3} 的语法来编写。 % \hologo{LaTeX3} 放弃了 \cs{outer} 宏的概念,因此相关工具(例如 |peek| 类函数)在 % 遇到 \cs{outer} 宏时可能会存在问题。按照目前 \pkg{xeCJK} 的实现方式,在 CJK 文字 % 后面遇到 \cs{outer} 宏时会出现类似 % \begin{verbatim} -% ! Forbidden control sequence found while scanning use of \token_if_eq_meaning:NNTF +% ! Forbidden control sequence found while scanning use of \use_i:nn % \end{verbatim} % 的错误。目前已知的有 \pkg{cprotect} 宏包提供的 \cs{cprotect}。它的定义是 % \begin{verbatim} @@ -1170,6 +1230,13 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \pkg{polyglossia})可能会存在大小不一的冲突。\pkg{xeCJK} 虽然为此作了一些处理,但与 % 它们共同使用时应该小心。 % +% 基于历史原因,\pkg{xltxtra} 宏包引入的 \pkg{realscripts} 定义了 \cs{dim_max:nn} +% 和 \cs{dim_min:nn} 这两个已经在当前版本的 \pkg{expl3} 中定义了的函数。 +% \pkg{realscripts} 中的定义并不好,并且了覆盖 \pkg{expl3} 中的定义,因此破坏了 +% \pkg{xeCJK} 中的相关计算。\pkg{xltxtra} 并没有什么实际功能,完全可以不使用它。 +% 如果原来通过 \pkg{xltxtra} 得到 \XeLaTeX 这个 Logo,现在可以改用更完善的 \pkg{hologo}。 +% 如果坚持使用它,请把它放在 \pkg{xeCJK} 之后载入。 +% %\end{documentation} % % @@ -1226,7 +1293,6 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % % \begin{macrocode} \RequirePackage { xparse , l3keys2e } -\RequirePackage { xpatch } % \end{macrocode} % % \subsection{内部工具} @@ -1240,7 +1306,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ \int_new:N \l_@@_tmpc_int \box_new:N \l_@@_tmp_box \dim_new:N \l_@@_tmp_dim -\skip_new:N \g_@@_tmp_skip +\skip_new:N \l_@@_tmp_skip \prop_new:N \l_@@_tmp_prop \clist_new:N \l_@@_tmpa_clist \clist_new:N \l_@@_tmpb_clist @@ -1268,6 +1334,18 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \end{macrocode} % \end{macro} % +% \begin{macro}[pTF,internal]{\xeCJK_if_package_loaded:n} +% 判断宏包是否被引入,可用于文档正文中。 +% \begin{macrocode} +\prg_new_conditional:Npnn \xeCJK_if_package_loaded:n #1 { p , T , F , TF } + { + \tl_if_exist:cTF { ver@ #1 . \c_@@_package_ext_tl } + { \prg_return_true: } { \prg_return_false: } + } +\tl_const:Nx \c_@@_package_ext_tl { \@pkgextension } +% \end{macrocode} +% \end{macro} +% % \begin{macro}[internal] % {\@@_at_end_preamble:n,\@@_after_preamble:n,\@@_after_end_preamble:n} % 在 \cs{document} 前后加上各种钩子。 @@ -1281,9 +1359,25 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ { \tl_gput_right:Nn \g_@@_after_preamble_hook_tl {#1} } \cs_new_protected:Npn \@@_after_end_preamble:n #1 { \tl_gput_right:Nn \g_@@_after_end_preamble_hook_tl {#1} } -\AtEndPreamble { \g_@@_at_end_preamble_hook_tl } -\AfterPreamble { \g_@@_after_preamble_hook_tl } -\AfterEndPreamble { \g_@@_after_end_preamble_hook_tl } +\xeCJK_if_package_loaded:nTF { etoolbox } + { + \AtEndPreamble { \g_@@_at_end_preamble_hook_tl } + \AfterPreamble { \g_@@_after_preamble_hook_tl } + \AfterEndPreamble { \g_@@_after_end_preamble_hook_tl } + } + { + \AtBeginDocument { \g_@@_after_preamble_hook_tl } + \cs_new_protected_nopar:Npn \@@_document_left_hook: + { \group_end: \g_@@_at_end_preamble_hook_tl \group_begin: } + \cs_new_protected_nopar:Npn \@@_document_right_hook: + { \scan_stop: \g_@@_after_end_preamble_hook_tl \tex_ignorespaces:D } + \cs_gset_nopar:Npx \document + { + \@@_document_left_hook: + \exp_not:o { \document } + \@@_document_right_hook: + } + } % \end{macrocode} % \end{macro} % @@ -1312,31 +1406,6 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \end{macrocode} % \end{macro} % -% \begin{macro}[internal]{\xeCJK_cs_add:Nnn,\xeCJK_cs_patch:Nnn} -% 在已有宏内容打补丁:在其前后附加内容或者替换掉它的某些内容,只替换掉第一次匹配 -% 的内容。 -% \begin{macrocode} -\cs_new_protected:Npn \xeCJK_cs_add:Nnn #1#2#3 - { - \tl_if_empty:nTF {#3} - { \tl_if_empty:nTF {#2} { \use_ii:nn } { \xpretocmd {#1} {#2} } } - { - \tl_if_empty:nTF {#2} { \xapptocmd {#1} {#3} } - { \xpretocmd {#1} {#2} { \xapptocmd {#1} {#3} } { \use_ii:nn } } - } - { \@@_info:nxx { patch-cmd } { \token_to_str:N #1 } { succeeded } } - { \@@_warning:nxx { patch-cmd } { \token_to_str:N #1 } { failed } } - } -\cs_new_protected:Npn \xeCJK_cs_patch:Nnn #1#2#3 - { - \xpatchcmd {#1} {#2} {#3} - { \@@_info:nxx { patch-cmd } { \token_to_str:N #1 } { succeeded } } - { \@@_warning:nxx { patch-cmd } { \token_to_str:N #1 } { failed } } - } -\@@_msg_new:nn { patch-cmd } { Patching~'#1'~#2! } -% \end{macrocode} -% \end{macro} -% % \begin{macro}[internal]{\xeCJK_cs_clear:N,\xeCJK_cs_gclear:N} % 让控制序列的意义为空。 % \begin{macrocode} @@ -1407,9 +1476,8 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \begin{macrocode} \cs_new_protected_nopar:Npn \xeCJK_glue_to_skip:nN #1#2 { - \hbox_set:Nn \l_@@_tmp_box - { #1 \skip_gset_eq:NN \g_@@_tmp_skip \tex_lastskip:D } - \skip_set_eq:NN #2 \g_@@_tmp_skip + \hbox_set:Nn \l_@@_tmp_box { #1 \scan_stop: \exp_after:wN } \exp_after:wN + \skip_set:Nn \exp_after:wN #2 \exp_after:wN { \skip_use:N \tex_lastskip:D } } % \end{macrocode} % \end{macro} @@ -1419,29 +1487,16 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \begin{macrocode} \prg_new_conditional:Npnn \xeCJK_if_blank_x:n #1 { p , T , F , TF } { - \if_int_compare:w \pdftex_strcmp:D { \c_empty_tl } {#1} = \c_zero + \if_case:w \pdftex_strcmp:D { } {#1} \exp_stop_f: \prg_return_true: \else: - \if_int_compare:w \pdftex_strcmp:D { \c_space_tl } {#1} = \c_zero + \if_case:w \pdftex_strcmp:D { ~ } {#1} \exp_stop_f: \prg_return_true: \else: \prg_return_false: \fi: \fi: } % \end{macrocode} % \end{macro} % -% \begin{macro}[pTF,internal]{\xeCJK_if_package_loaded:n} -% 判断宏包是否被引入,可用于文档正文中。 -% \begin{macrocode} -\prg_new_conditional:Npnn \xeCJK_if_package_loaded:n #1 { p , T , F , TF } - { - \tl_if_exist:cTF { ver@ #1 . \c_@@_package_ext_tl } - { \prg_return_true: } - { \prg_return_false: } - } -\tl_const:Nx \c_@@_package_ext_tl { \@pkgextension } -% \end{macrocode} -% \end{macro} -% % \begin{macro}[internal]{\xeCJK_int_until_do:nn,\@@_int_until_do:wn} % 由于定义较为简单,可以比 \cs{int_until_do:nNnn} 稍微快一点点。 % \begin{macrocode} @@ -1450,6 +1505,89 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ \cs_new_protected:Npn \@@_int_until_do:wn \use_none:n #1 { #1 \exp_after:wN \@@_int_until_do:wn \fi: \use_none:n {#1} } % \end{macrocode} +% +% \end{macro} +% +% \begin{macro}[internal]{\xeCJK_peek_catcode_ignore_spaces:NTF} +% \changes{v3.1.1}{2012/12/04}{新增有省略空格标识的 \texttt{peek} 函数。} +% 我们在里面设置了一个变量 \cs{l_@@_peek_ignore_spaces_bool} 用于标识后面的空格 +% 是否被省略掉了。 +% \begin{macrocode} +\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 \@@_peek_catcode_true:w { \group_align_safe_end: #2 } + \tl_set:Nn \@@_peek_catcode_false:w { \group_align_safe_end: #3 } + \bool_set_false:N \l_@@_peek_ignore_spaces_bool + \group_align_safe_begin: + \peek_after:Nw \@@_peek_catcode_ignore_spaces_branches:w + } +\cs_new_protected_nopar:Npn \@@_peek_catcode_ignore_spaces_branches:w + { + \if_meaning:w \l_peek_token \c_space_token + \bool_set_true:N \l_@@_peek_ignore_spaces_bool + \exp_after:wN \peek_after:Nw + \exp_after:wN \@@_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 \@@_peek_catcode_true:w + \else: + \exp_after:wN \exp_after:wN + \exp_after:wN \@@_peek_catcode_false:w + \fi: + \fi: + } +\bool_new:N \l_@@_peek_ignore_spaces_bool +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\xeCJK_peek_after_ignore_spaces:nw} +% 与 \cs{@ifnextchar} 和 \cs{futurenonspacelet} 类似,会省略掉后面的空格。 +% \begin{macrocode} +\cs_new_protected:Npn \xeCJK_peek_after_ignore_spaces:nw #1 + { + \tl_set:Nn \@@_peek_after_do:w { \group_align_safe_end: #1 } + \group_align_safe_begin: + \peek_after:Nw \@@_peek_ignore_spaces_branches:w + } +\cs_new_protected_nopar:Npn \@@_peek_ignore_spaces_branches:w + { + \if_meaning:w \l_peek_token \c_space_token + \exp_after:wN \peek_after:Nw + \exp_after:wN \@@_peek_ignore_spaces_branches:w + \tex_romannumeral:D 0 + \else: + \exp_after:wN \@@_peek_after_do:w + \fi: + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\xeCJK_token_value_class:N} +% 用于取得记号 |#1| 所在的 \XeTeX 字符类。|#1| 应为 \cs{catcode} 为 |11| 或 |12| +% 的显性或隐性记号。 +% \begin{macrocode} +\cs_new_nopar:Npn \xeCJK_token_value_class:N #1 + { \XeTeXcharclass \xeCJK_token_value_charcode:N #1 } +\cs_new_nopar:Npn \xeCJK_token_value_charcode:N #1 + { \exp_after:wN \@@_token_value_charcode:w \token_to_meaning:N #1 \q_stop } +\cs_new_nopar:Npn \@@_token_value_charcode:w #1 ~ #2 ~ #3 \q_stop { `#3 } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[pTF,internal]{\xeCJK_if_same_class:NN} +% 判断两个字符是否同属于一个字符类。 +% \begin{macrocode} +\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: + } +% \end{macrocode} % \end{macro} % % \subsection{功能开关} @@ -1481,10 +1619,66 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % % \subsection{字符类别设定}\label{sec:xeCJK-class-set} % +% \begin{macro}[internal,var]{\g_@@_class_seq,\g_@@_new_class_seq} +% 分别用于记录在 \pkg{xeCJK} 中使用的字符类别名称和新建的字符类别的编号。 +% \begin{macrocode} +\seq_new:N \g_@@_class_seq +\seq_new:N \g_@@_new_class_seq +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\xeCJK_new_class:n} +% 新建一个字符类别。|#1| 是自定义名称。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \xeCJK_new_class:n #1 + { + \int_if_exist:cTF { \@@_class_csname:n {#1} } + { \@@_error:nx { class-already-defined } {#1} } + { + \exp_args:Nc \newXeTeXintercharclass { \@@_class_csname:n {#1} } + \clist_new:c { g_@@_#1_range_clist } + \seq_gput_right:Nn \g_@@_class_seq {#1} + \seq_gput_right:Nv \g_@@_new_class_seq { \@@_class_csname:n {#1} } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\xeCJK_save_class:nn} +% \changes{v3.1.1}{2012/12/06} +% {使用 \cs{xeCJK_save_class:nn} 保存 \XeTeX 预定义的字符类别。} +% 保存 \XeTeX 预定义的字符类别。|#1| 是自定义名称,|#2| 是编号。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \xeCJK_save_class:nn #1#2 + { + \int_if_exist:cTF { \@@_class_csname:n {#1} } + { \@@_error:nx { class-already-defined } {#1} } + { + \int_const:cn { \@@_class_csname:n {#1} } {#2} + \clist_new:c { g_@@_#1_range_clist } + \seq_gput_right:Nn \g_@@_class_seq {#1} + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\@@_class_csname:n} +% 字符类名称对应的控制序列名字。 +% \begin{macrocode} +\cs_new_nopar:Npn \@@_class_csname:n #1 { c_@@_#1_class_int } +\cs_new_eq:cN { \@@_class_csname:n { Others } } \l_@@_tmpa_int +\@@_msg_new:nn { class-already-defined } + { + XeTeX~character~class~`#1'~has~been~already~defined.\\\\ + Please~take~another~name. \\ + } +% \end{macrocode} +% \end{macro} +% % \pkg{xeCJK} 需要以下字符类别用于字符输出。其中 |Default|、|CJK|、|FullLeft|、 % |FullRight|、|Boundary| 为 \XeTeX\ 中预定义的类别,\pkg{xeCJK} 新增加了\ % |HalfLeft|、|HalfRight|、|NormalSpace|。 -% \begin{center}\punctstyle{plain} +% \begin{center}\xeCJKsetup{PunctStyle=plain} % \begin{tabular}{cll} % \toprule % 类别 & 说明 & 例子 \\ \midrule @@ -1500,31 +1694,18 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \end{tabular} % \end{center} % -% \begin{macro}[internal,var]{Default,CJK,FullLeft,FullRight,Boundary} +% \begin{macro}[internal]{Default,CJK,FullLeft,FullRight,Boundary} % 这五类是 \XeTeX\ 预定义的类别。 % \begin{macrocode} -\int_const:Nn \c_@@_Default_class_int { \c_zero } -\int_const:Nn \c_@@_CJK_class_int { \c_one } -\int_const:Nn \c_@@_FullLeft_class_int { \c_two } -\int_const:Nn \c_@@_FullRight_class_int { \c_three } -\int_const:Nn \c_@@_Boundary_class_int { \c_two_hundred_fifty_five } +\xeCJK_save_class:nn { Default } { \c_zero } +\xeCJK_save_class:nn { CJK } { \c_one } +\xeCJK_save_class:nn { FullLeft } { \c_two } +\xeCJK_save_class:nn { FullRight } { \c_three } +\xeCJK_save_class:nn { Boundary } { \c_two_hundred_fifty_five } % \end{macrocode} % \end{macro} % -% \begin{macro}[internal]{\xeCJK_new_class:n,\g_@@_class_seq} -% 新建一个字符类别。 -% \begin{macrocode} -\cs_new_protected_nopar:Npn \xeCJK_new_class:n #1 - { - \exp_args:Nc \newXeTeXintercharclass { c_@@_#1_class_int } - \clist_gclear_new:c { g_@@_#1_range_clist } - \seq_gput_right:Nv \g_@@_class_seq { c_@@_#1_class_int } - } -\seq_new:N \g_@@_class_seq -% \end{macrocode} -% \end{macro} -% -% \begin{macro}[internal,var]{HalfLeft,HalfRight,NormalSpace} +% \begin{macro}[internal]{HalfLeft,HalfRight,NormalSpace} % 新增西文半角左/右标点和前后原始间距的符号类。 % \begin{macrocode} \xeCJK_new_class:n { HalfLeft } @@ -1536,7 +1717,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \begin{macro}[var,internal] % {\c_@@_HalfLeft_chars_clist,\c_@@_HalfRight_chars_clist,\c_@@_NormalSpace_chars_clist, % \c_@@_FullLeft_chars_clist,\c_@@_FullRight_chars_clist,\c_@@_CJK_chars_clist} -% \hypertarget{CJKcharclass}{\pkg{xeCJK} 设置的各个字符类的默认范围。} +% \hypertarget{CJKcharclass}{\pkg{xeCJK} 设置的基本字符类的默认范围。} % \begin{macrocode} \clist_const:Nn \c_@@_HalfLeft_chars_clist { "28 , "2D , "5B , "60 , "7B } @@ -1701,23 +1882,24 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \subsection{字符类别处理} % % \begin{macro}[internal,var] -% {\g_@@_base_class_seq,\g_@@_CJK_class_seq,\g_@@_CJK_class_prop} +% {\g_@@_base_class_seq,\g_@@_non_CJK_class_seq, +% \g_@@_CJK_class_seq,\g_@@_CJK_class_prop} % \begin{macrocode} \seq_new:N \g_@@_base_class_seq -\seq_gset_split:Nnn \g_@@_base_class_seq { , } - { - Default , CJK , FullLeft , FullRight , Boundary , - HalfLeft , HalfRight , NormalSpace - } -\seq_map_inline:Nn \g_@@_base_class_seq - { \clist_gclear_new:c { g_@@_#1_range_clist } } +\seq_gset_eq:NN \g_@@_base_class_seq \g_@@_class_seq +\seq_new:N \g_@@_non_CJK_class_seq +\seq_gset_from_clist:Nn \g_@@_non_CJK_class_seq + { Default , HalfLeft , HalfRight , NormalSpace , Boundary } \seq_new:N \g_@@_CJK_class_seq \prop_new:N \g_@@_CJK_class_prop \cs_new_protected_nopar:Npn \@@_save_CJK_class:n #1 { \seq_gput_right:Nn \g_@@_CJK_class_seq {#1} - \prop_gput:Nvn \g_@@_CJK_class_prop { c_@@_#1_class_int } {#1} + \prop_gput:Nvn \g_@@_CJK_class_prop { \@@_class_csname:n {#1} } {#1} + \tl_gput_right:Nx \g_@@_check_single_CJK_case_tl + { { \exp_not:c { \@@_class_csname:n {#1} } } { \exp_not:N \use_ii:nn } } } +\tl_new:N \g_@@_check_single_CJK_case_tl \cs_generate_variant:Nn \prop_gput:Nnn { Nvn } \clist_map_function:nN { CJK , FullLeft , FullRight } \@@_save_CJK_class:n % \end{macrocode} @@ -1726,26 +1908,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \begin{macro}[internal]{\xeCJK_class_num:n} % |#1| 为字符类别名称,用于取得字符类别对应的编号。 % \begin{macrocode} -\cs_new_nopar:Npn \xeCJK_class_num:n #1 { \use:c { c_@@_#1_class_int } } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}[internal]{\xeCJK_value_class:n} -% |#1| 为字符的 |Unicode|,用于取得该字符所在的字符类。 -% \begin{macrocode} -\cs_new_nopar:Npn \xeCJK_value_class:n #1 - { \XeTeXcharclass \etex_numexpr:D #1 \scan_stop: } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}[pTF,internal]{\xeCJK_if_same_class:NN} -% 判断两个字符是否同属于一个字符类。 -% \begin{macrocode} -\prg_new_conditional:Npnn \xeCJK_if_same_class:NN #1#2 { p , T , F , TF } - { - \if_int_compare:w \xeCJK_value_class:n {`#1} = \xeCJK_value_class:n {`#2} - \prg_return_true: \else: \prg_return_false: \fi: - } +\cs_new_nopar:Npn \xeCJK_class_num:n #1 { \use:c { \@@_class_csname:n {#1} } } % \end{macrocode} % \end{macro} % @@ -1784,19 +1947,19 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \end{macrocode} % \end{macro} % -% \begin{macro}[internal]{\xeCJK_set_char_class:nnn} -% |#1| 和 |#2| 为字符类别起止的 |Unicode|,|#3| 为类别名称对应编号。 +% \begin{macro}[internal]{\@@_set_char_class_catcode:nnn} +% 设置字符类别的同时,设置所有 |CJK| 字符的 \cs{catcode} 为 |12|。\XeTeX 的配置文件 +% \file{unicode-letters.tex} 将所有 |CJK| 表意文字的 \cs{catcode} 设置为 |11|。我们 +% 在作出改变的目的是方便 |CheckSingle| 的判断。事实上,|CheckSingle| 的判断也可以不 +% 依赖 \cs{catcode},而改为判断 \cs{XeTeXcharclass}。但是判读一个隐性记号 +% (\cs{l_peek_token})的 \cs{XeTeXcharclass} 比直接判断它的 \cs{catcode} 要低效得多。 % \begin{macrocode} -\NewDocumentCommand \xeCJKsetcharclass { s m m m } - { - \xeCJK_set_char_class:nnn {#2} {#3} {#4} - \IfBooleanF {#1} { \xeCJKResetPunctClass } - } -\cs_new_protected_nopar:Npn \xeCJK_set_char_class:nnn #1#2#3 +\cs_new_protected_nopar:Npn \@@_set_char_class_catcode:nnn #1#2#3 { \@@_check_num_range:nnNN {#1} {#2} \l_@@_tmpa_int \l_@@_tmpb_int \int_set:Nn \l_@@_tmpc_int {#3} - \prop_get:NVNTF \g_@@_CJK_class_prop \l_@@_tmpc_int \l_@@_tmpa_tl + \int_compare:nNnTF + { \use:c { \@@_class_csname:n { CJK } } } = \l_@@_tmpc_int { \cs_set_eq:NN \@@_set_char_catcode:n \char_set_catcode_other:n } { \cs_set_eq:NN \@@_set_char_catcode:n \use_none:n } \xeCJK_int_until_do:nn { \l_@@_tmpa_int > \l_@@_tmpb_int } @@ -1809,6 +1972,22 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \end{macrocode} % \end{macro} % +% \begin{macro}[internal]{\@@_set_char_class:nnn} +% 只设置字符类别,而不改变 \cs{catcode}。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_set_char_class:nnn #1#2#3 + { + \@@_check_num_range:nnNN {#1} {#2} \l_@@_tmpa_int \l_@@_tmpb_int + \int_set:Nn \l_@@_tmpc_int {#3} + \xeCJK_int_until_do:nn { \l_@@_tmpa_int > \l_@@_tmpb_int } + { + \XeTeXcharclass \l_@@_tmpa_int = \l_@@_tmpc_int + \int_incr:N \l_@@_tmpa_int + } + } +% \end{macrocode} +% \end{macro} +% % \begin{macro}[internal]{\@@_check_num_range:nnNN} % \begin{macrocode} \cs_new_protected_nopar:Npn \@@_check_num_range:nnNN #1#2#3#4 @@ -1826,14 +2005,26 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \end{macrocode} % \end{macro} % +% \begin{macro}[internal]{\xeCJK_set_char_class:nnn} +% \changes{v3.1.1}{2012/12/05}{在文档中设置字符类别时不重复设置 \cs{catcode}。} +% |#1| 和 |#2| 为字符类别起止的 |Unicode|,|#3| 为类别名称对应编号。在宏包内部使用 +% 时,设置 |CJK| 字符的 \cs{catcode},而在文档中使用时不设置。 +% \begin{macrocode} +\cs_new_eq:NN \xeCJK_set_char_class:nnn \@@_set_char_class_catcode:nnn +\AtEndOfPackage + { \cs_set_eq:NN \xeCJK_set_char_class:nnn \@@_set_char_class:nnn } +% \end{macrocode} +% \end{macro} +% % \begin{macro}[internal]{\@@_set_char_class_eq:nn} -% 将字符类 |#2| 中的字符全部设置成字符类 |#1|。只使用于 |#2| 的字符类范围为离散的 +% \changes{v3.1.1}{2012/12/06}{交换参数的顺序。} +% 将字符类 |#1| 中的字符全部设置成字符类 |#2|。只适用于 |#1| 的字符类范围为离散的 % 逗号列表的情况。 % \begin{macrocode} \cs_new_protected_nopar:Npn \@@_set_char_class_eq:nn #1#2 { - \int_set:Nn \l_@@_tmpa_int { \xeCJK_class_num:n {#1} } - \clist_map_inline:cn { c_@@_#2_chars_clist } + \int_set:Nn \l_@@_tmpa_int { \xeCJK_class_num:n {#2} } + \clist_map_inline:cn { c_@@_#1_chars_clist } { \XeTeXcharclass ##1 = \l_@@_tmpa_int } } % \end{macrocode} @@ -1844,10 +2035,9 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \begin{macrocode} \NewDocumentCommand \normalspacedchars { m } { - \tl_map_inline:xn {#1} + \tl_map_inline:nn {#1} { \XeTeXcharclass `##1 = \xeCJK_class_num:n { NormalSpace } } } -\cs_generate_variant:Nn \tl_map_inline:nn { x } % \end{macrocode} % \end{macro} % @@ -1887,7 +2077,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \begin{macrocode} \cs_new_protected_nopar:Npn \xeCJK_inter_class_toks:nnn #1#2#3 { \XeTeXinterchartoks \xeCJK_class_num:n {#1} ~ \xeCJK_class_num:n {#2} = {#3} } -\cs_generate_variant:Nn \xeCJK_inter_class_toks:nnn { nnc , nnx } +\cs_generate_variant:Nn \xeCJK_inter_class_toks:nnn { nnc , nnv , nnx } % \end{macrocode} % \end{macro} % @@ -1997,7 +2187,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % & \tokslink{def-cjk} % & \tokslink{def-cjk} % & \tokslink{def-cjk} -% & \tokslink{fl-fr-others}\\ +% & \tokslink{fl-fr-bound}\\ % |FullRight| % & \tokslink{def-cjk} % & \tokslink{fl-fr-others} @@ -2006,7 +2196,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % & \tokslink{def-cjk} % & \tokslink{def-cjk} % & \tokslink{def-cjk} -% & \tokslink{fl-fr-others}\\ +% & \tokslink{fl-fr-bound}\\ % |HalfLeft| % & % & \tokslink{def-cjk} @@ -2053,20 +2243,15 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \begin{macrocode} \clist_map_inline:nn { Default , HalfLeft , HalfRight , NormalSpace } { - \clist_map_inline:nn { CJK , FullLeft , FullRight } + \xeCJK_inter_class_toks:nnn {#1} { CJK } { - \xeCJK_inter_class_toks:nnn {#1} {##1} - { - \xeCJK_class_group_begin: - \xeCJK_select_font: - \xeCJK_clear_inter_class_toks:nn {#1} {##1} - \xeCJK_clear_Boundary_and_CJK_toks: - } - \xeCJK_inter_class_toks:nnn {##1} {#1} { \xeCJK_class_group_end: } + \xeCJK_class_group_begin: + \xeCJK_select_font: + \xeCJK_clear_inter_class_toks:nn {#1} { CJK } + \xeCJK_clear_Boundary_and_CJK_toks: + \CJKsymbol } - \xeCJK_app_inter_class_toks:nnn {#1} { CJK } { \CJKsymbol } - \clist_map_inline:nn { FullLeft , FullRight } - { \xeCJK_app_inter_class_toks:nnc {#1} {##1} { xeCJK_CJK_and_##1:N } } + \xeCJK_inter_class_toks:nnn { CJK } {#1} { \xeCJK_class_group_end: } } % \end{macrocode} % @@ -2088,7 +2273,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ \xeCJK_if_last_node_p:n { CJK } || \xeCJK_if_last_node_p:n { CJK-space } } - { \CJKecglue } { \c_space_token } + { \CJKecglue } { ~ } } { \xeCJK_if_last_node:nTF { CJK } { \CJKecglue } @@ -2106,8 +2291,8 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ { \xeCJK_inter_class_toks:nnn {#1} { Boundary } { - \peek_meaning_remove:NTF \/ - { \/ { \xeCJK_make_node:n { default } } } + \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 } } } @@ -2123,7 +2308,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \begin{macrocode} \xeCJK_inter_class_toks:nnn { Boundary } { CJK } { - { \xeCJK_check_for_glue: } + \xeCJK_check_for_glue: \xeCJK_class_group_begin: \xeCJK_clear_Boundary_and_CJK_toks: \xeCJK_select_font: @@ -2167,8 +2352,8 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ \xeCJK_if_last_node_p:n { CJK } || \xeCJK_if_last_node_p:n { CJK-space } } - { \bool_if:NTF \l_@@_reserve_space_bool \c_space_token \CJKglue } - { \c_space_token } + { \bool_if:NTF \l_@@_reserve_space_bool { ~ } { \CJKglue } } + { ~ } } } } @@ -2214,7 +2399,14 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % CJK 文字之间插入的 |glue|。 % \begin{macrocode} \keys_define:nn { xeCJK / options } - { CJKglue .code:n = { \cs_set_protected:Npn \CJKglue {#1} } } + { + CJKglue .code:n = + { + \cs_set_protected_nopar:Npn \CJKglue {#1} + \xeCJK_glue_to_skip:nN {#1} \l_@@_ccglue_skip + } + } +\skip_new:N \l_@@_ccglue_skip % \end{macrocode} % \end{macro} % @@ -2225,8 +2417,8 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ { CJKecglue .code:n = { - \cs_set_protected:Npn \CJKecglue {#1} - \xeCJK_glue_to_skip:nN \CJKecglue \l_@@_ecglue_skip + \cs_set_protected_nopar:Npn \CJKecglue {#1} + \xeCJK_glue_to_skip:nN {#1} \l_@@_ecglue_skip } , xCJKecglue .choice: , xCJKecglue / true .code:n = @@ -2237,13 +2429,13 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ xCJKecglue / false .code:n = { \bool_set_false:N \l_@@_xecglue_bool - \cs_set_eq:NN \@@_space_or_xecglue: \c_space_token + \cs_set_eq:NN \@@_space_or_xecglue: \c_space_tl } , xCJKecglue / unknown .code:n = { \bool_set_true:N \l_@@_xecglue_bool - \cs_set_protected:Npn \CJKecglue {#1} - \xeCJK_glue_to_skip:nN \CJKecglue \l_@@_ecglue_skip + \cs_set_protected_nopar:Npn \CJKecglue {#1} + \xeCJK_glue_to_skip:nN {#1} \l_@@_ecglue_skip \cs_set_eq:NN \@@_space_or_xecglue: \CJKecglue } , xCJKecglue .default:n = { true } @@ -2279,13 +2471,16 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \begin{macrocode} \cs_new_protected_nopar:Npn \xeCJK_ignore_spaces:w { - \peek_catcode:NTF \c_space_token + \xeCJK_peek_catcode_ignore_spaces:NTF \c_math_toggle_token { - \xeCJK_if_last_node:nT { CJK } - { \tex_unkern:D \tex_unkern:D { \xeCJK_make_node:n { CJK-space } } } - \peek_catcode_ignore_spaces:NTF \c_math_toggle_token - { \@@_space_or_xecglue: } + \bool_if:NTF \l_@@_peek_ignore_spaces_bool + { \@@_space_or_xecglue: } { \CJKecglue } + } + { + \bool_if:NTF \l_@@_peek_ignore_spaces_bool { + \tex_unkern:D \tex_unkern:D + { \xeCJK_make_node:n { CJK-space } } \bool_if:nT { \token_if_macro_p:N \l_peek_token || @@ -2294,14 +2489,9 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ } { \@@_space_or_xecglue: } } - } - { - \token_if_math_toggle:NTF \l_peek_token - { \CJKecglue } { \cs_if_exist:NF \l_peek_token \exp_not:N } } } -\cs_new_eq:NN \xeCJK_ignorespaces: \xeCJK_ignore_spaces:w % \end{macrocode} % \end{macro} % @@ -2316,38 +2506,46 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \end{macrocode} % \end{macro} % -% \hypertarget{bound-fl-fr}{} +% \hypertarget{fl-fr-others}{} % \begin{macrocode} -\clist_map_inline:nn { FullLeft , FullRight } +\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_@@_non_CJK_class_seq { - \xeCJK_inter_class_toks:nnn { Boundary } {#1} + \clist_map_inline:nn { FullLeft , FullRight } { - \xeCJK_class_group_begin: - \xeCJK_clear_Boundary_and_CJK_toks: - \xeCJK_select_font: - \use:c { xeCJK_CJK_and_#1:N } + \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 { FullLeft } { Boundary } - { \xeCJK_class_group_end: \tex_ignorespaces:D } +% \end{macrocode} +% +% \hypertarget{bound-fl-fr}{} +% \begin{macrocode} +\xeCJK_inter_class_toks:nnn { Boundary } { FullLeft } + { \xeCJK_Boundary_and_FullLeft:N } +\xeCJK_inter_class_toks:nnn { Boundary } { FullRight } + { \xeCJK_Boundary_and_FullRight:N } +% \end{macrocode} +% +% \begin{macro}[internal]{\xeCJK_FullRight_and_Boundary:} +% \hypertarget{fl-fr-bound}{} +% \begin{macrocode} +\xeCJK_app_inter_class_toks:nnn { FullLeft } { Boundary } { \tex_ignorespaces:D } \xeCJK_inter_class_toks:nnn { FullRight } { Boundary } - { \xeCJK_class_group_end: \CJKglue \tex_ignorespaces:D } + { \xeCJK_FullRight_and_Boundary: } % \end{macrocode} +% \end{macro} % -% \hypertarget{fl-fr-others}{} +% \begin{macro}[internal]{\xeCJK_FullRight_and_Boundary:} % \begin{macrocode} -\xeCJK_inter_class_toks:nnn { FullLeft } { CJK } { \CJKsymbol } -\xeCJK_inter_class_toks:nnn { FullRight } { CJK } { \CJKglue \CJKsymbol } -\seq_map_inline:Nn \g_@@_base_class_seq - { - \bool_if:nF - { \str_if_eq_p:nn {#1} { FullLeft } || \str_if_eq_p:nn {#1} { FullRight } } - { - \xeCJK_pre_inter_class_toks:nnn { FullLeft } {#1} { \xeCJK_after_FullLeft: } - \xeCJK_pre_inter_class_toks:nnn { FullRight } {#1} { \xeCJK_after_FullRight: } - } - } +\cs_new_protected_nopar:Npn \xeCJK_FullRight_and_Boundary: + { \xeCJK_FullRight_and_Default: \tex_ignorespaces:D } % \end{macrocode} +% \end{macro} % % \hypertarget{cjk-fl-fr}{} % \begin{macrocode} @@ -2376,12 +2574,13 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \begin{macrocode} \cs_new_protected_nopar:Npn \@@_punct_glue:NN #1#2 { - \skip_horizontal:n + \@@_punct_hskip:n { \@@_use_punct_dim:nnn { glue } {#1} {#2} minus \dim_eval:n { ( \@@_use_punct_dim:nnn { glue } {#1} {#2} ) / \c_two } } } +\cs_new_eq:NN \@@_punct_hskip:n \skip_horizontal:n % \end{macrocode} % \end{macro} % @@ -2400,45 +2599,145 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \end{macrocode} % \end{macro} % -% \begin{macro}[internal]{\xeCJK_after_FullLeft:} +% \begin{macro}[internal]{\xeCJK_FullLeft_and_CJK:} % \begin{macrocode} -\cs_new_protected_nopar:Npn \xeCJK_after_FullLeft: +\cs_new_protected_nopar:Npn \xeCJK_FullLeft_and_CJK: { - \xeCJK_no_break: - \@@_punct_if_middle:NT \g_@@_last_punct_tl + \@@_punct_if_middle:NTF \g_@@_last_punct_tl { - \xeCJK_get_punct_bounds:NN \c_@@_left_tl \g_@@_last_punct_tl - \@@_punct_glue:NN \c_@@_left_tl \g_@@_last_punct_tl \@@_punct_rule:NN \c_@@_right_tl \g_@@_last_punct_tl \xeCJK_no_break: + \@@_punct_glue:NN \c_@@_left_tl \g_@@_last_punct_tl } + { \xeCJK_no_break: } } % \end{macrocode} % \end{macro} % -% \begin{macro}[internal]{\xeCJK_after_FullRight:} +% \begin{macro}[internal]{\xeCJK_FullLeft_and_Default:} % \begin{macrocode} -\cs_new_protected_nopar:Npn \xeCJK_after_FullRight: +\cs_new_protected_nopar:Npn \xeCJK_FullLeft_and_Default: + { + \@@_punct_if_middle:NTF \g_@@_last_punct_tl + { + \@@_punct_rule:NN \c_@@_right_tl \g_@@_last_punct_tl + \xeCJK_class_group_end: \xeCJK_no_break: + \@@_punct_glue:NN \c_@@_left_tl \g_@@_last_punct_tl + } + { \xeCJK_class_group_end: \xeCJK_no_break: } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\xeCJK_FullRight_and_CJK:} +% \begin{macrocode} +\cs_new_protected_nopar:Npn \xeCJK_FullRight_and_CJK: { - \xeCJK_get_punct_bounds:NN \c_@@_right_tl \g_@@_last_punct_tl \@@_punct_rule:NN \c_@@_right_tl \g_@@_last_punct_tl \@@_punct_glue:NN \c_@@_right_tl \g_@@_last_punct_tl + \CJKglue } % \end{macrocode} % \end{macro} % +% \begin{macro}[internal]{\xeCJK_FullRight_and_Default:} +% \begin{macrocode} +\cs_new_protected_nopar:Npn \xeCJK_FullRight_and_Default: + { + \@@_punct_rule:NN \c_@@_right_tl \g_@@_last_punct_tl + \xeCJK_class_group_end: + \@@_punct_glue:NN \c_@@_right_tl \g_@@_last_punct_tl + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\xeCJK_Default_and_FullLeft:nN} +% \begin{macrocode} +\cs_new_protected_nopar:Npn \xeCJK_Default_and_FullLeft:nN #1#2 + { + \xeCJK_get_punct_bounds:NN \c_@@_left_tl {#2} + \@@_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_@@_last_punct_tl {#2} + \@@_punct_rule:NN \c_@@_left_tl {#2} + \CJKpunctsymbol {#2} + } +\cs_new_protected_nopar:Npn \@@_Default_and_FullLeft_glue:N #1 + { \@@_punct_glue:NN \c_@@_left_tl {#1} } +% \end{macrocode} +% \end{macro} +% % \begin{macro}[internal]{\xeCJK_CJK_and_FullLeft:N} % \begin{macrocode} \cs_new_protected_nopar:Npn \xeCJK_CJK_and_FullLeft:N #1 { \xeCJK_get_punct_bounds:NN \c_@@_left_tl {#1} - \int_compare:nNnF \etex_lastnodetype:D = \c_one - { \@@_CJK_FullLeft_glue: \@@_punct_glue:NN \c_@@_left_tl {#1} } + \@@_CJK_and_FullLeft_glue:N {#1} \tl_gset:Nx \g_@@_last_punct_tl {#1} \@@_punct_rule:NN \c_@@_left_tl {#1} \CJKpunctsymbol {#1} } -\cs_new_protected_nopar:Npn \@@_CJK_FullLeft_glue: { \CJKglue } +\cs_new_protected_nopar:Npn \@@_CJK_and_FullLeft_glue:N #1 + { \CJKglue \@@_punct_glue:NN \c_@@_left_tl {#1} } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\xeCJK_Boundary_and_FullLeft:N} +% \begin{macrocode} +\cs_new_protected_nopar:Npn \xeCJK_Boundary_and_FullLeft:N #1 + { + \xeCJK_get_punct_bounds:NN \c_@@_left_tl {#1} + \@@_Boundary_and_FullLeft_glue:N {#1} + \xeCJK_class_group_begin: + \xeCJK_select_font: + \xeCJK_clear_Boundary_and_CJK_toks: + \tl_gset:Nx \g_@@_last_punct_tl {#1} + \@@_punct_rule:NN \c_@@_left_tl {#1} + \CJKpunctsymbol {#1} + } +\cs_new_protected_nopar:Npn \@@_Boundary_and_FullLeft_glue:N #1 + { + \int_compare:nNnF \etex_lastnodetype:D = \c_one + { \@@_punct_glue:NN \c_@@_left_tl {#1} } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\xeCJK_Default_and_FullRight:nN} +% \begin{macrocode} +\cs_new_protected_nopar:Npn \xeCJK_Default_and_FullRight:nN #1#2 + { + \xeCJK_get_punct_bounds:NN \c_@@_right_tl {#2} + \@@_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_@@_last_punct_tl {#2} + \@@_punct_if_middle:NT {#2} + { \@@_punct_rule:NN \c_@@_left_tl {#2} } + \xeCJK_FullRight_symbol:N {#2} + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\xeCJK_Boundary_and_FullRight:N} +% \begin{macrocode} +\cs_new_protected_nopar:Npn \xeCJK_Boundary_and_FullRight:N #1 + { + \xeCJK_get_punct_bounds:NN \c_@@_right_tl {#1} + \@@_Default_and_FullRight_glue:N {#1} + \xeCJK_class_group_begin: + \xeCJK_select_font: + \xeCJK_clear_Boundary_and_CJK_toks: + \tl_gset:Nx \g_@@_last_punct_tl {#1} + \@@_punct_if_middle:NT {#1} + { \@@_punct_rule:NN \c_@@_left_tl {#1} } + \xeCJK_FullRight_symbol:N {#1} + } % \end{macrocode} % \end{macro} % @@ -2447,19 +2746,29 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ \cs_new_protected_nopar:Npn \xeCJK_CJK_and_FullRight:N #1 { \xeCJK_get_punct_bounds:NN \c_@@_right_tl {#1} + \@@_CJK_and_FullRight_glue:N {#1} + \tl_gset:Nx \g_@@_last_punct_tl {#1} + \@@_punct_if_middle:NT {#1} + { \@@_punct_rule:NN \c_@@_left_tl {#1} } + \xeCJK_FullRight_symbol:N {#1} + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal] +% {\@@_CJK_and_FullRight_glue:N,\@@_Default_and_FullRight_glue:N} +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_CJK_and_FullRight_glue:N #1 + { \@@_punct_if_long:NTF {#1} { \CJKglue } { - \xeCJK_no_break: - \@@_punct_if_middle:NT {#1} - { - \@@_punct_glue:NN \c_@@_right_tl {#1} - \@@_punct_rule:NN \c_@@_left_tl {#1} - } + \@@_punct_if_middle:NTF {#1} + { \xeCJK_no_break: \@@_punct_glue:NN \c_@@_right_tl {#1} } + { \xeCJK_no_break: } } - \tl_gset:Nx \g_@@_last_punct_tl {#1} - \CJKpunctsymbol {#1} } +\cs_new_eq:NN \@@_Default_and_FullRight_glue:N \@@_CJK_and_FullRight_glue:N % \end{macrocode} % \end{macro} % @@ -2487,7 +2796,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ \@@_punct_kern:NN \g_@@_last_punct_tl {#1} \tl_gset:Nx \g_@@_last_punct_tl {#1} \xeCJK_no_break: - \CJKpunctsymbol {#1} + \xeCJK_FullRight_symbol:N {#1} } % \end{macrocode} % \end{macro} @@ -2515,58 +2824,170 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ \@@_punct_kern:NN \g_@@_last_punct_tl {#1} \tl_gset:Nx \g_@@_last_punct_tl {#1} \xeCJK_no_break: - \CJKpunctsymbol {#1} + \xeCJK_FullRight_symbol:N {#1} } % \end{macrocode} % \end{macro} % -% \subsection{段末孤字处理} +% \subsection{全角右标点后的断行} % -% \begin{macro}{CheckSingle} -% 孤字处理功能选项。 +% \begin{macro}{CheckFullRight} +% \changes{v3.1.1}{2012/12/02}{处理全角右标点之后的断行问题。} +% 选项设置。 % \begin{macrocode} \keys_define:nn { xeCJK / options } { - CheckSingle .choice: , - CheckSingle / true .code:n = { \xeCJKenablechecksingle } , - CheckSingle / false .code:n = { \xeCJKdisablechecksingle } , - CheckSingle .default:n = { true } , - CJKchecksingle .meta:n = { CheckSingle = true } + CheckFullRight .choice: , + CheckFullRight / true .code:n = + { + \cs_if_eq:NNF \xeCJK_FullRight_and_Boundary: \xeCJK_check_FullRight: + { + \cs_set_eq:NN \@@_save_FullRight_check: \xeCJK_FullRight_and_Boundary: + \cs_set_eq:NN \@@_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: \@@_save_FullRight_check: + \cs_set_eq:NN \xeCJK_FullRight_symbol:N \@@_save_FullRight_symbol:N + } + } , + CheckFullRight .default:n = { true } } % \end{macrocode} % \end{macro} % -% \begin{macro}[internal]{\xeCJKenablechecksingle,\xeCJKdisablechecksingle} -% 孤字处理功能开关。 +% \begin{macro}[internal]{\xeCJK_FullRight_symbol:N} +% \begin{macrocode} +\cs_new_nopar:Npn \xeCJK_FullRight_symbol:N { \CJKpunctsymbol } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\xeCJK_check_FullRight:} % \begin{macrocode} -\bool_new:N \l_@@_check_single_bool -\NewDocumentCommand \xeCJKenablechecksingle { } +\cs_new_protected_nopar:Npn \xeCJK_check_FullRight: { - \bool_if:NF \l_@@_check_single_bool + \xeCJK_get_punct_bounds:NN \c_@@_right_tl \g_@@_last_punct_tl + \@@_punct_rule:NN \c_@@_right_tl \g_@@_last_punct_tl + \tl_case:Non \l_peek_token { \l_@@_no_break_cs_case_tl } { } + \@@_punct_glue:NN \c_@@_right_tl \g_@@_last_punct_tl + \xeCJK_class_group_end: + } +\cs_generate_variant:Nn \tl_case:Nnn { No } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\xeCJK_check_FullRight_symbol:Nw} +% \begin{macrocode} +\cs_new_protected_nopar:Npn \xeCJK_check_FullRight_symbol:Nw #1 + { \xeCJK_peek_after_ignore_spaces:nw { \@@_save_FullRight_symbol:N {#1} } } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\xeCJK_cs_case_keys_define:nNNnn} +% \begin{macrocode} +\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 } { - \bool_set_true:N \l_@@_check_single_bool - \cs_set_eq:NN \@@_check_single_save:N \xeCJK_CJK_and_CJK:N - \cs_set_eq:NN \xeCJK_CJK_and_CJK:N \xeCJK_check_single:Nw + #1 .code:n = + { + \seq_set_split:Nnn #3 { } {##1} + \@@_update_cs_case_tl:NNnn #2#3 {#4} {#5} + } , + #1+ .code:n = + { + \tl_map_inline:nn {##1} + { \seq_if_in:NnF #2 {####1} { \seq_put_right:Nn #3 {####1} } } + \@@_update_cs_case_tl:NNnn #2#3 {#4} {#5} + } , + #1- .code:n = + { + \tl_map_inline:nn {##1} { \seq_remove_all:Nn #3 {####1} } + \@@_update_cs_case_tl:NNnn #2#3 {#4} {#5} + } } } -\NewDocumentCommand \xeCJKdisablechecksingle { } +\cs_new_protected:Npn \@@_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 + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{NoBreakCS} +% 设置不能在全角右标点之后断行的控制序列。 +% \begin{macrocode} +\xeCJK_cs_case_keys_define:nNNnn { NoBreakCS } + \l_@@_no_break_cs_case_tl \l_@@_no_break_cs_seq { \xeCJK_no_break: } { } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\xeCJKnobreak} +% \changes{v3.1.1}{2012/12/03}{增加 \cs{nobreak} 的 \pkg{xeCJK} 版本。} +% 为保险起见,我们在这里用了一个循环。 +% \begin{macrocode} +\NewDocumentCommand \xeCJKnobreak { } { - \bool_if:NT \l_@@_check_single_bool + \int_zero:N \l_@@_tmpa_int + \int_while_do:nNnn \etex_lastnodetype:D = \c_eleven { - \bool_set_false:N \l_@@_check_single_bool - \cs_set_eq:NN \xeCJK_CJK_and_CJK:N \@@_check_single_save:N + \int_if_even:nTF \l_@@_tmpa_int + { + \int_incr:N \l_@@_tmpa_int + \skip_set_eq:NN \l_@@_tmp_skip \tex_lastskip:D + } + { \skip_add:Nn \l_@@_tmp_skip \tex_lastskip:D } + \tex_unskip:D } + \xeCJK_no_break: + \int_if_even:nF \l_@@_tmpa_int + { \skip_horizontal:N \l_@@_tmp_skip } } % \end{macrocode} % \end{macro} % -% \begin{macro}[internal] -% {\xeCJK_check_single:Nw,\xeCJK_check_single:NNw,\xeCJK_check_single:NNNw} +% \subsection{段末孤字处理} +% +% \begin{macro}{CheckSingle} +% 孤字处理功能选项。 +% \begin{macrocode} +\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 \@@_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 \@@_check_single_save:N } + } , + CheckSingle .default:n = { true } , + CJKchecksingle .meta:n = { CheckSingle = true } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\xeCJK_check_single:Nw} % \begin{macrocode} \cs_new_protected_nopar:Npn \xeCJK_check_single:Nw #1 { \peek_catcode:NTF \c_catcode_other_token - { \xeCJK_check_single:NNw {#1} } + { \xeCJK_check_single:NNw #1 } { \bool_if:nTF { @@ -2574,102 +2995,198 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ \exp_args:No \tl_if_single_token_p:n \l_peek_token && \exp_after:wN \token_if_other_p:N \l_peek_token } - { \xeCJK_check_single:NNw {#1} } - { \@@_check_single_save:N {#1} } + { \exp_after:wN \xeCJK_check_single:NNw \exp_after:wN #1 } + { \@@_check_single_save:N #1 } } } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\xeCJK_check_single:NNw} +% \changes{v3.1.1}{2012/12/04}{改进定义,减少使用 \texttt{peek} 函数的次数。} +% 使用 \cs{group_align_safe_begin:} 和 \cs{group_align_safe_end:} 是为了防止在表格 +% 里面报错。 +% \begin{macrocode} \cs_new_protected_nopar:Npn \xeCJK_check_single:NNw #1#2 { - \peek_catcode:NTF \c_catcode_other_token - { \@@_check_single_save:N {#1} #2 } + \xeCJK_peek_catcode_ignore_spaces:NTF \c_catcode_other_token { - \bool_if:nTF + \bool_if:NTF \l_@@_peek_ignore_spaces_bool + { \@@_check_single_space:NN #1#2 } + { \@@_check_single_save:N #1 #2 } + } + { + \group_align_safe_begin: + \token_if_cs:NTF \l_peek_token { - \token_if_space_p:N \l_peek_token || - \token_if_math_toggle_p:N \l_peek_token || - \token_if_cs_p:N \l_peek_token + \group_align_safe_end: + \bool_if:NTF \l_@@_peek_ignore_spaces_bool + { \xeCJK_check_single_cs:NNn #1#2 { ~ } } + { \xeCJK_check_single_cs:NNn #1#2 { } } } { - \bool_if:nTF { \token_if_space_p:N \l_peek_token } + \group_align_safe_end: + \bool_if:nTF { - \peek_catcode_ignore_spaces:NTF \c_catcode_other_token - { \@@_check_single_save:N {#1} #2 \c_space_token } - { - \bool_if:nTF - { - \token_if_math_toggle_p:N \l_peek_token || - \token_if_cs_p:N \l_peek_token - } - { \xeCJK_check_single:NNNw {#1} {#2} \c_space_token } - { \@@_check_single_save:N {#1} #2 \c_space_token } - } + \l_@@_plain_equation_bool && + \token_if_math_toggle_p:N \l_peek_token + } + { + \bool_if:NTF \l_@@_peek_ignore_spaces_bool + { \xeCJK_check_single_equation:NNnNw #1 #2 { ~ } } + { \xeCJK_check_single_equation:NNnNw #1 #2 { } } + } + { + \bool_if:NTF \l_@@_peek_ignore_spaces_bool + { \@@_check_single_save:N #1 #2 ~ } + { \@@_check_single_save:N #1 #2 } } - { \xeCJK_check_single:NNNw {#1} {#2} { } } } - { \@@_check_single_save:N {#1} #2 } } } -\cs_new_protected_nopar:Npn \xeCJK_check_single:NNNw #1#2#3 +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\@@_check_single_space:NN} +% \changes{v3.1.1}{2012/12/13} +% {\texttt{CheckSingle} 支持段末“汉字$+$汉字$+$空格$+$汉字/标点”的形式。} +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_check_single_space:NN #1#2 { - \bool_if:nTF + \int_case:non { \xeCJK_token_value_class:N #2 } + { \g_@@_check_single_CJK_case_tl } + { \use_i:nn } + { \@@_check_single_save:N #1 #2 ~ } { - \token_if_eq_meaning_p:NN \l_peek_token \par || - \token_if_eq_meaning_p:NN \l_peek_token \[ % \] + \int_case:non { \xeCJK_token_value_class:N \l_peek_token } + { \g_@@_check_single_CJK_case_tl } + { \use_i:nn } + { \@@_check_single_save:N #1 #2 ~ } + { \@@_check_single_save:N #1 #2 } } - { \CJKsymbol {#1} \xeCJK_no_break: #2 } - { \xeCJK_check_single_env:NNNw {#1} {#2} {#3} } } +\cs_generate_variant:Nn \int_case:nnn { no } % \end{macrocode} % \end{macro} % -% \begin{macro}[internal] -% {\xeCJK_check_single_env:NNNw,\xeCJK_check_single_env:NNNNn} +% \begin{macro}[internal]{\xeCJK_check_single_equation:NNnNw} % \begin{macrocode} -\cs_new_protected_nopar:Npn \xeCJK_check_single_env:NNNw #1#2#3 +\cs_new_protected_nopar:Npn \xeCJK_check_single_equation:NNnNw #1#2#3#4 { - \peek_catcode_remove:NTF \c_math_toggle_token + \peek_catcode:NTF \c_math_toggle_token { - \peek_catcode:NTF \c_math_toggle_token - { \CJKsymbol {#1} \xeCJK_no_break: #2 \c_math_toggle_token } - { \@@_check_single_save:N {#1} #2#3 \c_math_toggle_token } + \xeCJK_no_break: \@@_check_single_save:N #1 + \xeCJK_no_break: #2 #4 } + { \@@_check_single_save:N #1 #2#3#4 } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\xeCJK_check_single_cs:NNn} +% \begin{macrocode} +\cs_new_protected_nopar:Npn \xeCJK_check_single_cs:NNn #1#2#3 + { + \tl_case:Non \l_peek_token + { \l_@@_check_single_cs_case_tl } + { \use_iii:nnn } + { \xeCJK_check_single_env:nnNn } { - \peek_meaning_remove:NTF \begin - { \xeCJK_check_single_env:NNNNn {#1} {#2} {#3} \begin } - { - \peek_meaning_remove:NTF \end - { \xeCJK_check_single_env:NNNNn {#1} {#2} {#3} \end } - { \@@_check_single_save:N {#1} #2#3 } - } + \xeCJK_no_break: \@@_check_single_save:N #1 + \xeCJK_no_break: #2 } + { \@@_check_single_save:N #1 #2#3 } } -\cs_new_protected_nopar:Npn \xeCJK_check_single_env:NNNNn #1#2#3#4#5 +\tl_new:N \l_@@_check_single_cs_case_tl +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\xeCJK_check_single_env:nnNn} +% \begin{macrocode} +\cs_new_protected_nopar:Npn \xeCJK_check_single_env:nnNn #1#2#3#4 { - \clist_if_in:NnTF \g_@@_inline_env_clist {#5} - { \@@_check_single_save:N {#1} #2#3 } - { \CJKsymbol {#1} \xeCJK_no_break: #2 } - \scan_stop: #4 {#5} + \str_case_x:non {#4} + { \l_@@_inline_env_case_tl } + { \use_i:nn } + {#1} {#2} + \scan_stop: #3 {#4} } +\cs_generate_variant:Nn \str_case_x:nnn { no } % \end{macrocode} % \end{macro} % -% \begin{macro}{InlineEnv,InlineEnv+,InlineEnv-} +% \changes{v3.1.1}{2012/12/04}{增加 \texttt{NewLineCS} 和 \texttt{EnvCS} 选项。} +% +% \begin{macro}{NewLineCS} +% \begin{macrocode} +\xeCJK_cs_case_keys_define:nNNnn { NewLineCS } + \l_@@_new_line_cs_case_tl \l_@@_new_line_cs_seq { \use_ii:nnn } + { + \tl_concat:NNN \l_@@_check_single_cs_case_tl + \l_@@_new_line_cs_case_tl \l_@@_env_cs_case_tl + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{EnvCS} +% \begin{macrocode} +\xeCJK_cs_case_keys_define:nNNnn { EnvCS } + \l_@@_env_cs_case_tl \l_@@_env_cs_seq { \use:n } + { + \tl_concat:NNN \l_@@_check_single_cs_case_tl + \l_@@_new_line_cs_case_tl \l_@@_env_cs_case_tl + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{InlineEnv} +% \changes{v3.1.1}{2012/12/05}{改变行内环境的设置方式,从而使用 \cs{str_case_x:nnn} +% 代替原来的 \cs{clist_if_in:NnTF} 来判断是否是行内环境。} % \begin{macrocode} \keys_define:nn { xeCJK / options } { - InlineEnv .clist_gset:N = \g_@@_inline_env_clist , + InlineEnv .code:n = + { + \seq_set_from_clist:Nn \l_@@_inline_env_seq {#1} + \@@_update_inline_env_case_tl: + } , InlineEnv+ .code:n = { - \clist_gput_right:Nx \g_@@_inline_env_clist {#1} - \clist_gremove_duplicates:N \g_@@_inline_env_clist + \clist_map_inline:nn {#1} + { + \seq_if_in:NnF \l_@@_inline_env_seq {##1} + { \seq_put_right:Nn \l_@@_inline_env_seq {##1} } + } + \@@_update_inline_env_case_tl: } , InlineEnv- .code:n = { - \clist_map_inline:xn {#1} - { \clist_gremove_all:Nn \g_@@_inline_env_clist {##1} } + \clist_map_inline:nn {#1} + { \seq_remove_all:Nn \l_@@_inline_env_seq {##1} } + \@@_update_inline_env_case_tl: } } -\cs_generate_variant:Nn \clist_map_inline:nn { x } +\seq_new:N \l_@@_inline_env_seq +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_update_inline_env_case_tl:} +% \begin{macrocode} +\cs_new_protected:Npn \@@_update_inline_env_case_tl: + { + \tl_clear:N \l_@@_inline_env_case_tl + \seq_map_inline:Nn \l_@@_inline_env_seq + { \tl_put_right:Nn \l_@@_inline_env_case_tl { {##1} { \use_ii:nn } } } + } +\tl_new:N \l_@@_inline_env_case_tl +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{PlainEquation} +% \changes{v3.1.1}{2012/12/06}{增加 \texttt{PlainEquation} 选项。} +% \begin{macrocode} +\keys_define:nn { xeCJK / options } + { PlainEquation .bool_set:N = \l_@@_plain_equation_bool } % \end{macrocode} % \end{macro} % @@ -2725,7 +3242,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ { \clist_map_inline:nn {#1} { - \int_if_exist:cTF { c_@@_ CJK/##1 _class_int } + \int_if_exist:cTF { \@@_class_csname:n { CJK/##1 } } { \xeCJK_declare_char_class:nx { CJK \bool_if:NF \l_@@_sub_cancel_bool { /##1 } } @@ -2748,11 +3265,11 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \begin{macrocode} \cs_new_protected_nopar:Npn \xeCJK_declare_sub_char_class:nnn #1#2#3 { - \int_if_exist:cF { c_@@_ #1/#2 _class_int } + \int_if_exist:cF { \@@_class_csname:n { #1/#2 } } { \xeCJK_new_class:n { #1/#2 } \@@_set_sub_class_toks:nn {#1} {#2} - \@@_new_sub_key:n {#2} + \xeCJK_new_sub_key:n {#2} } \xeCJK_declare_char_class:nn { #1/#2 } {#3} } @@ -2823,6 +3340,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \begin{macrocode} \NewDocumentCommand \xeCJKsetwidth { m m } { \tl_map_inline:xn {#1} { \tl_gset:cn { g_@@_punct_width/##1/tl } {#2} } } +\cs_generate_variant:Nn \tl_map_inline:nn { x } % \end{macrocode} % \end{macro} % @@ -2916,13 +3434,13 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \begin{macrocode} \prg_new_conditional:Npnn \@@_punct_if_right:N #1 { p , T , F , TF } { - \if_int_compare:w \xeCJK_value_class:n {`#1} = \xeCJK_class_num:n { FullRight } + \if_int_compare:w \xeCJK_token_value_class:N #1 = \xeCJK_class_num:n { FullRight } \prg_return_true: \else: \prg_return_false: \fi: } -\cs_generate_variant:Nn \prg_new_conditional:Npnn { c } \clist_map_inline:Nn \g_@@_special_punct_clist { - \prg_new_conditional:cpnn { @@_punct_if_#1:N } ##1 { p , T , F , TF } + \exp_args:Nc + \prg_new_conditional:Npnn { @@_punct_if_#1:N } ##1 { p , T , F , TF } { \if_cs_exist:w \@@_special_punct_tl:nN {#1} {##1} \cs_end: \prg_return_true: \else: \prg_return_false: \fi: @@ -2960,11 +3478,11 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % % 定义标点处理模板。 % \begin{macrocode} -\DeclareObjectType { xeCJK / punctuation } { 3 } +\DeclareObjectType { xeCJK / punctuation } { \c_three } % \end{macrocode} % % \begin{macrocode} -\DeclareTemplateInterface { xeCJK / punctuation } { basic } { 3 } +\DeclareTemplateInterface { xeCJK / punctuation } { basic } { \c_three } { enabled-global-setting : boolean = true , fixed-punct-width : length = \c_max_dim , @@ -2998,7 +3516,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \end{macrocode} % % \begin{macrocode} -\DeclareTemplateCode { xeCJK / punctuation } { basic } { 3 } +\DeclareTemplateCode { xeCJK / punctuation } { basic } { \c_three } { enabled-global-setting = \l_@@_enabled_global_setting_bool , fixed-punct-width = \l_@@_fixed_punct_width_dim , @@ -3347,7 +3865,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ ( \@@_use_punct_dim:nnn { bound } \c_@@_right_tl {#1} ) } \@@_gset_punct_dim:nnx { width } {#1} - { \dim_use:N \etex_fontcharwd:D \tex_font:D `#1 } + { \dim_use:N \etex_fontcharwd:D \tex_font:D \xeCJK_token_value_charcode:N #1 } \@@_gset_punct_dim:nnx { dimen } {#1} { \dim_eval:n { \@@_use_punct_dim:nn { width } {#1} - \l_@@_tmp_dim } } \@@_punct_if_long:NT {#1} @@ -3375,7 +3893,10 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % 用 \cs{XeTeXglyphbounds} 取得标点符号的上下左右空白。 % \begin{macrocode} \cs_new_nopar:Npn \xeCJK_glyph_bounds:NN #1#2 - { \dim_use:N \XeTeXglyphbounds #1 ~ \XeTeXcharglyph `#2 \exp_stop_f: } + { + \dim_use:N \XeTeXglyphbounds #1 ~ + \XeTeXcharglyph \xeCJK_token_value_charcode:N #2 \exp_stop_f: + } % \end{macrocode} % \end{macro} % @@ -3508,35 +4029,22 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ \keys_define:nn { xeCJK / options } { AutoFallBack .choice: , - AutoFallBack / true .code:n = { \xeCJKenablefallback } , - AutoFallBack / false .code:n = { \xeCJKdisablefallback } , - AutoFallBack .default:n = { true } , - fallback .meta:n = { AutoFallBack = true } - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}[internal]{\xeCJKenablefallback, \xeCJKdisablefallback} -% 后备字体的启用开关,默认关闭。 -% \begin{macrocode} -\NewDocumentCommand \xeCJKenablefallback { } - { - \bool_if:NF \l_@@_fallback_bool + AutoFallBack / true .code:n = { - \bool_set_true:N \l_@@_fallback_bool - \cs_set_eq:NN \@@_fallback_save_CJKsymbol:N \CJKsymbol - \cs_set_eq:NN \CJKsymbol \xeCJK_fallback_test_glyph:N - } - } -\NewDocumentCommand \xeCJKdisablefallback { } - { - \bool_if:NT \l_@@_fallback_bool + \cs_if_eq:NNF \CJKsymbol \xeCJK_fallback_test_glyph:N + { + \cs_set_eq:NN \@@_fallback_save_CJKsymbol:N \CJKsymbol + \cs_set_eq:NN \CJKsymbol \xeCJK_fallback_test_glyph:N + } + } , + AutoFallBack / false .code:n = { - \bool_set_false:N \l_@@_fallback_bool - \cs_set_eq:NN \CJKsymbol \@@_fallback_save_CJKsymbol:N - } + \cs_if_eq:NNT \CJKsymbol \xeCJK_fallback_test_glyph:N + { \cs_set_eq:NN \CJKsymbol \@@_fallback_save_CJKsymbol:N } + } , + AutoFallBack .default:n = { true } , + fallback .meta:n = { AutoFallBack = true } } -\bool_new:N \l_@@_fallback_bool % \end{macrocode} % \end{macro} % @@ -3554,6 +4062,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % % \begin{macro}[internal]{\xeCJK_fallback_loop:Nn} % \changes{v3.1.0}{2012/11/19}{调整备用字体的循环方式。} +% \changes{v3.1.1}{2012/12/02}{修正备用字体的不正确警告。} % 循环测试后备字体是否包含字符 |#1|。若后备字体中存在该字符或者再没有后备字体,则 % 结束循环。 % \begin{macrocode} @@ -3567,7 +4076,8 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ { \xeCJK_fallback_loop:Nn {#1} { #2/FallBack } } } { - \@@_warning:nxx { fallback } {#1} {#2} + \xeCJK_family_if_exist:xT { \l_xeCJK_family_tl/FallBack } + { \@@_warning:nxx { fallback } {#1} {#2} } \@@_fallback_save_CJKsymbol:N {#1} } } @@ -3577,6 +4087,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ ( \prop_get:No \g_@@_family_font_name_prop {#2} )~ does~not~contain~glyph~'#1'~(U+\int_to_hexadecimal:n {`#1}).\\ } +\bool_new:N \l_@@_fallback_first_bool \cs_generate_variant:Nn \prop_get:Nn { No } % \end{macrocode} % \end{macro} @@ -3659,11 +4170,11 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \end{macrocode} % \end{macro} % -% \begin{macro}[internal]{\@@_new_sub_key:n,\g_@@_sub_key_seq} +% \begin{macro}[internal]{\xeCJK_new_sub_key:n,\g_@@_sub_key_seq} % 用于定义 CJK 子区字体和备用字体的选项。 % \begin{macrocode} \seq_new:N \g_@@_sub_key_seq -\cs_new_protected_nopar:Npn \@@_new_sub_key:n #1 +\cs_new_protected_nopar:Npn \xeCJK_new_sub_key:n #1 { \seq_gput_right:Nn \g_@@_sub_key_seq {#1} \keys_define:nn { xeCJK / features } @@ -3693,7 +4204,6 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ #1 .default:n = { } } } -\cs_generate_variant:Nn \@@_new_sub_key:n { x } % \end{macrocode} % \end{macro} % @@ -3734,7 +4244,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % % \begin{macro}{FallBack} % \begin{macrocode} -\@@_new_sub_key:n { FallBack } +\xeCJK_new_sub_key:n { FallBack } % \end{macrocode} % \end{macro} % @@ -3791,7 +4301,6 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \begin{macrocode} \cs_new_protected_nopar:Npn \@@_set_family_initial: { - \@@_gobble_CJKfamily: \int_gincr:N \g_@@_family_int \prop_clear:N \l_@@_add_font_prop \prop_map_inline:Nn \g_@@_features_id_prop @@ -3871,7 +4380,8 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ \cs_gset_protected_nopar:cpx { \@@_family_csname:n {#1} } { \group_begin: - \@@_gobble_CJKfamily: + \cs_set_eq:NN + \exp_not:n { \@@_update_family:n \use_none:n } \exp_not:n { \fontspec_set_family:Nnn \l_@@_fontspec_family_tl } { \exp_not:V \l_@@_fontspec_options_clist } { \exp_not:V \l_@@_font_name_tl } @@ -4046,7 +4556,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ } } \prop_map_inline:Nn \l_@@_add_font_prop - { \clist_put_right:Nn \l_@@_fontspec_options_clist { ##1 = { ##2 } } } + { \clist_put_right:Nn \l_@@_fontspec_options_clist { ##1 = {##2} } } } % \end{macrocode} % \end{macro} @@ -4179,7 +4689,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \end{macro} % % \begin{macro}[internal]{\@@_switch_font:nn} -% \changes{v3.1.0}{2012/11/18}{改进 \cs{@@_switch_font:nn} 的定义。} +% \changes{v3.1.0}{2012/11/18}{改进定义,加快切换速度。} % 两个 CJK 分区之间的字体切换。 % \begin{macrocode} \cs_new_protected_nopar:Npn \@@_switch_font:nn #1#2 @@ -4211,7 +4721,8 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ { \@@_copy_family:xx { \l_xeCJK_family_tl/#1 } { - \cs_if_exist:cTF { \@@_family_csname:n { \CJKfamilydefault/#1 } } + \cs_if_exist:cTF + { \@@_family_csname:n { \CJKfamilydefault/#1 } } { \CJKfamilydefault/#1 } { \l_xeCJK_family_tl } } } @@ -4234,8 +4745,8 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ \prop_gput:Nxx \g_@@_family_name_prop {#1} {#2} \cs_gset_protected_nopar:cpx { \@@_family_nfss_csname:n {#1} } { - \exp_not:N \fontencoding { \c_@@_encoding_tl } - \exp_not:N \fontfamily {#2} + \tl_set:Nx \exp_not:N \f@encoding { \c_@@_encoding_tl } + \tl_set:Nx \exp_not:N \f@family {#2} \exp_not:N \selectfont } } @@ -4468,13 +4979,24 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \end{macrocode} % \end{macro} % -% 在导言区结束的时候,若没有声明 CJK 字体,则给出一个警告。并在此时设置数学字体。 +% 在导言区结束的时候,若没有声明 CJK 字体,则给出一个警告。并在此时根据西文字体的 +% 情况更新 \cs{CJKfamilydefault} 和设置数学字体。 % \begin{macrocode} \@@_at_end_preamble:n { \prop_if_empty:NTF \g_@@_family_font_name_prop { \@@_warning:n { no-CJKfamily } } { + \tl_gset:Nx \CJKfamilydefault + { + \str_case_x:nnn { \familydefault } + { + { \rmdefault } { \CJKrmdefault } + { \sfdefault } { \CJKsfdefault } + { \ttdefault } { \CJKttdefault } + } + { \CJKfamilydefault } + } \CJKfamily { \CJKfamilydefault } \bool_if:NT \g_@@_math_bool { \xeCJK_set_mathfont: } } @@ -4488,7 +5010,6 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ } % \end{macrocode} % -% % \subsection{数学字体设置} % % \begin{macro}{CJKmath} @@ -4575,16 +5096,16 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ \bool_if:NF \l_@@_verb_addon_bool { \bool_set_true:N \l_@@_verb_addon_bool - \@@_set_char_class_eq:nn { CJK } { FullLeft } - \@@_set_char_class_eq:nn { CJK } { FullRight } - \@@_set_char_class_eq:nn { Default } { HalfLeft } - \@@_set_char_class_eq:nn { Default } { HalfRight } - \@@_set_char_class_eq:nn { Default } { NormalSpace } + \@@_set_char_class_eq:nn { FullLeft } { CJK } + \@@_set_char_class_eq:nn { FullRight } { CJK } + \@@_set_char_class_eq:nn { HalfLeft } { Default } + \@@_set_char_class_eq:nn { HalfRight } { Default } + \@@_set_char_class_eq:nn { NormalSpace } { Default } \xeCJKsetup { xCJKecglue = false } \cs_set_protected_nopar:Npn \CJKglue { \skip_horizontal:N \g_@@_verb_exspace_skip } \cs_set_protected_nopar:Npn \CJKecglue - { \skip_horizontal:N 0.5 \g_@@_verb_exspace_skip } + { \skip_horizontal:n { 0.5 \g_@@_verb_exspace_skip } } \cs_set_eq:NN \xeCJK_check_for_glue: \CJKecglue \cs_set_eq:NN \xeCJK_ignore_spaces:w \CJKecglue \skip_set:Nn \tex_rightskip:D { \c_zero_dim plus 1 fil } @@ -4599,11 +5120,11 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % 总是在 \LaTeX 的抄录环境(包括 \cs{verb})里使用 \cs{xeCJKVerbAddon},以保证代码 % 的对齐。 % \begin{macrocode} -\@@_after_preamble:n - { \xeCJK_cs_add:Nnn \verbatim@font { } { \xeCJKVerbAddon } } +\@@_after_preamble:n { \tl_put_right:Nn \verbatim@font { \xeCJKVerbAddon } } % \end{macrocode} % % \begin{macro}[internal]{\@@_set_verb_exspace:} +% \changes{v3.1.1}{2012/12/08}{调整间距的计算方法。} % 在抄录环境中,CJK 文字之间的间距为当前西文字体两个空格的宽度与当前字体大小之差, % 而与西文和空格的间距为 CJK 文字之间的间距的一半。这里的问题是, % \cs{g_@@_verb_exspace_skip} 有可能为负么?现在的处理是保证它非负。如果真的出现 @@ -4612,20 +5133,26 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \begin{macrocode} \cs_new_protected_nopar:Npn \@@_set_verb_exspace: { - \tl_if_exist:cTF { xeCJK/verb/\curr@fontshape/\f@size } + \tl_if_exist:cF { xeCJK/verb/\l_xeCJK_family_tl/\curr@fontshape/\f@size } { - \skip_gset:Nn \g_@@_verb_exspace_skip - { \tl_use:c { xeCJK/verb/\curr@fontshape/\f@size } } - } - { - \skip_gset:Nn \g_@@_verb_exspace_skip + \group_begin: + \xeCJK_select_font: + \use:x { - \dim_max:nn - { \c_zero_dim } - { \c_two \tex_fontdimen:D \c_two \tex_font:D - \f@size pt } + \group_end: + \tl_gset:cx + \exp_not:n { { xeCJK/verb/\l_xeCJK_family_tl/\curr@fontshape/\f@size } } + { + \exp_not:N \dim_max:nn { \c_zero_dim } + { + \c_two \tex_fontdimen:D \c_two \tex_font:D - + \dim_use:N \etex_fontcharwd:D \tex_font:D "4E00 + } + } } - \tl_gset:cV { xeCJK/verb/\curr@fontshape/\f@size } \g_@@_verb_exspace_skip } + \skip_gset:Nn \g_@@_verb_exspace_skip + { \use:c { xeCJK/verb/\l_xeCJK_family_tl/\curr@fontshape/\f@size } } } \skip_new:N \g_@@_verb_exspace_skip % \end{macrocode} @@ -4648,7 +5175,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ } } \AtEndOfPackage { - \xeCJK_cs_add:Nnn \fontspec_visible_space: { \scan_stop: } { } + \tl_put_left:Nn \fontspec_visible_space: { \scan_stop: } \cs_gset_eq:NN \fontspec_visible_space_fallback: \xeCJK_visible_space_fallback: } % \end{macrocode} @@ -4661,24 +5188,28 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ \cs_new_protected_nopar:Npn \xeCJK_set_visible_space_font: { \tl_set:Nx \l_@@_current_coor_tl { xeCJK/space/\curr@fontshape/\f@size } - \dim_set:Nn \l_@@_tmp_dim { \tex_fontdimen:D \c_two \tex_font:D } - \fontencoding { \g_fontspec_encoding_tl } - \fontfamily { lmtt } + \exp_after:wN \@@_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_@@_current_coor_tl } + } +\cs_new_protected_nopar:Npn \@@_set_visible_space_size:n #1 + { + \tl_set:Nx \f@encoding { \g_fontspec_encoding_tl } + \tl_set:Nx \f@family { lmtt } \selectfont - \dim_compare:nNnF \l_@@_tmp_dim = { \tex_fontdimen:D \c_two \tex_font:D } + \dim_compare:nNnF {#1} = { \tex_fontdimen:D \c_two \tex_font:D } { \fontsize { \dim_eval:n { - \f@size pt * \dim_ratio:nn - { \l_@@_tmp_dim } { \tex_fontdimen:D \c_two \tex_font:D } + \f@size pt * + \dim_ratio:nn {#1} { \tex_fontdimen:D \c_two \tex_font:D } } } { \f@baselineskip } \selectfont } - \xeCJK_font_gset_to_current:c { \l_@@_current_coor_tl } } % \end{macrocode} % \end{macro} @@ -4723,7 +5254,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \end{macrocode} % \end{macro} % -% \begin{macro}{quiet,silent} +% \begin{macro}[internal]{quiet,silent} % 将调用 \pkg{xeCJK} 时使用的未知的选项传递给 \pkg{fontspec} 宏包。 % 对 \pkg{fontspec} 的 |quiet| 和 |silent| 选项进行修改,使其适用于 \pkg{xeCJK}。 % \begin{macrocode} @@ -4773,9 +5304,11 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ \keys_set:nn { xeCJK / options } { CJKglue = { \skip_horizontal:n { \c_zero_dim plus 0.08 \tex_baselineskip:D } } , - CJKecglue = \c_space_token , + CJKecglue = { ~ } , xCJKecglue = false , CheckSingle = false , + PlainEquation = false , + CheckFullRight = false , CJKspace = false , CJKmath = false , CJKnumber = false , @@ -4785,6 +5318,9 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ EmboldenFactor = 4 , SlantFactor = 0.167 , PunctStyle = quanjiao , + NewLineCS = { \par \[ } , + EnvCS = { \begin \end } , + NoBreakCS = { \footnote \footnotemark \nobreak } , KaiMingPunct = { ^^^^3002 ^^^^ff0e ^^^^ff1f ^^^^ff01 } , LongPunct = { ^^^^2014 ^^^^2015 ^^^^2500 ^^^^2025 ^^^^2026 } , MiddlePunct = { ^^^^2014 ^^^^2015 ^^^^2500 ^^^^00b7 ^^^^30fb ^^^^ff65 } , @@ -4841,7 +5377,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \begin{macro}{\xeCJKsetup} % 在导言区或文档中设置 \pkg{xeCJK} 的接口。 % \begin{macrocode} -\NewDocumentCommand \xeCJKsetup { m } +\NewDocumentCommand \xeCJKsetup { +m } { \keys_set:nn { xeCJK / options } {#1} \tex_ignorespaces:D @@ -4888,24 +5424,80 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \end{macrocode} % \end{macro} % +% \begin{macro}[internal]{\xeCJKenablefallback, \xeCJKdisablefallback} +% \begin{macrocode} +\NewDocumentCommand \xeCJKenablefallback { } + { \xeCJKsetup { AutoFallBack = true } } +\NewDocumentCommand \xeCJKdisablefallback { } + { \xeCJKsetup { AutoFallBack = false } } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\xeCJKsetcharclass} +% \begin{macrocode} +\NewDocumentCommand \xeCJKsetcharclass { m m m } + { + \xeCJK_set_char_class:nnn {#1} {#2} {#3} + \xeCJKResetPunctClass + } +% \end{macrocode} +% \end{macro} +% % \subsection{兼容性修补} % -% 补丁 \cs{normalfont},\cs{rmfamily},\cs{sffamily} 和 \cs{ttfamily},使其同时对 -% CJK 字体族有效。 -% \begin{macrocode} -\xeCJK_cs_add:Nnn \rmfamily { \CJKfamily { \CJKrmdefault } } { } -\xeCJK_cs_add:Nnn \sffamily { \CJKfamily { \CJKsfdefault } } { } -\xeCJK_cs_add:Nnn \ttfamily { \CJKfamily { \CJKttdefault } } { } -\xeCJK_cs_add:Nnn \normalfont { \CJKfamily { \CJKfamilydefault } } { } -\cs_set_eq:NN \reset@font \normalfont +% \changes{v3.1.1}{2012/12/13}{对于与 \pkg{xltxtra} 的冲突给出错误警告。} +% \begin{macrocode} +\@@_msg_new:nn { conflict-package } + { + The~`#1'~package~is~in~conflict~with~xeCJK. \\ + Please~do~not~use~it~or~load~it~after~xeCJK. + } +\xeCJK_if_package_loaded:nTF { realscripts } + { + \@ifpackagelater { realscripts } { 2010/10/10 } { } + { \@@_error:nx { conflict-package } { xltxtra } } + } + { + \cs_new_eq:NN \@@_dim_max:nn \dim_max:nn + \cs_new_eq:NN \@@_dim_min:nn \dim_min:nn + \@@_at_end_preamble:n + { + \xeCJK_if_package_loaded:nT { realscripts } + { + \@ifpackagelater { realscripts } { 2010/10/10 } { } + { + \cs_gset_eq:NN \dim_max:nn \@@_dim_max:nn + \cs_gset_eq:NN \dim_min:nn \@@_dim_min:nn + } + } + \cs_undefine:N \@@_dim_max:nn + \cs_undefine:N \@@_dim_min:nn + } + } % \end{macrocode} % -% 因为我们在上面把 \cs{CJKfamily} 加在了 \cs{rmfamily} 里面,而 \pkg{fontspec} 在 -% 调用字体时,某些选项要使用它。为减少影响,下面使 \cs{CJKfamily} 在通过 -% \pkg{fontspec} 来实际调用字体时无效。 +% \begin{macro}[internal]{\fontfamily} +% \changes{v3.1.1}{2012/12/06}{修改主要 \texttt{CJK} 字体族的自动更新方式。} +% 修改 \cs{fontfamily},使主要 |CJK| 字体族能随西文主要字体更新。 % \begin{macrocode} -\xeCJK_cs_add:Nnn \fontspec_init: { \@@_gobble_CJKfamily: } { } +\RenewDocumentCommand \fontfamily { m } + { + \tl_set:Nx \f@family {#1} + \@@_update_family:n + { + \str_case_x:nnn {#1} + { + { \rmdefault } { \CJKfamily { \CJKrmdefault } } + { \sfdefault } { \CJKfamily { \CJKsfdefault } } + { \ttdefault } { \CJKfamily { \CJKttdefault } } + { \familydefault } { \CJKfamily { \CJKfamilydefault } } + } + { } + } + } +\cs_new_eq:NN \@@_update_family:n \use:n % \end{macrocode} +% \end{macro} % % \newbox\xeCJKtmpbox % \setbox\xeCJKtmpbox\vbox\bgroup @@ -4924,15 +5516,15 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % 处理。 % \begin{macrocode} \cs_new_eq:NN \xeCJK@fix@penalty \fix@penalty -\xeCJK_cs_patch:Nnn \xeCJK@fix@penalty \@@italiccorr \xeCJK@patch@italiccorr -\xeCJK_cs_patch:Nnn \sw@slant \fix@penalty \xeCJK@fix@penalty +\tl_replace_once:Nnn \xeCJK@fix@penalty { \@@italiccorr } { \xeCJK@italiccorr } +\tl_replace_once:Nnn \sw@slant { \fix@penalty } { \xeCJK@fix@penalty } % \end{macrocode} % \end{macro} % -% \begin{macro}[internal]{\xeCJK@patch@italiccorr} +% \begin{macro}[internal]{\xeCJK@italiccorr} % 修复倾斜校正,并处理汉字后面的空格。 % \begin{macrocode} -\cs_new_protected_nopar:Npn \xeCJK@patch@italiccorr +\cs_new_protected_nopar:Npn \xeCJK@italiccorr { \int_compare:nNnTF \XeTeXinterchartokenstate > \c_zero { @@ -4982,24 +5574,24 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ %<@@=xeCJK> % \end{macrocode}\egroup % -% \begin{macro}[internal]{\@@_set_others_toks:n,\c_@@_Others_class_int} +% \begin{macro}[internal]{\@@_set_others_toks:n} % 简单处理与同样使用 \cs{XeTeXinterchartoks} 机制的宏包的兼容问题。 % \begin{macrocode} \@@_after_end_preamble:n { \int_compare:nNnF - { \c_three + ( \seq_count:N \g_@@_class_seq ) } = \xe@alloc@intercharclass + { \c_three + \seq_count:N \g_@@_new_class_seq } = \xe@alloc@intercharclass { \int_step_inline:nnnn \c_four \c_one \xe@alloc@intercharclass { - \seq_if_in:NnF \g_@@_class_seq {#1} + \seq_if_in:NnF \g_@@_new_class_seq {#1} { \@@_set_others_toks:n {#1} } } } } \cs_new_protected_nopar:Npn \@@_set_others_toks:n #1 { - \int_set:Nn \c_@@_Others_class_int {#1} + \int_set:cn { \@@_class_csname:n { Others } } {#1} \seq_map_inline:Nn \g_@@_CJK_class_seq { \xeCJK_copy_inter_class_toks:nnnn {##1} { Others } {##1} { NormalSpace } @@ -5022,13 +5614,12 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ } } } -\cs_new_eq:NN \c_@@_Others_class_int \l_@@_tmpa_int % \end{macrocode} % \end{macro} % % 单独处理宽度有分歧的几个标点:包括省略号、破折号、间隔号、引号等中西文混用的 % 符号, 保证其命令形式输出的是西文字体。并对一些编码的符号宏包做特殊处理。 -% \begin{macrocode} +% \begin{macrocode} \@@_after_preamble:n { \tl_map_inline:nn @@ -5036,18 +5627,16 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ \textellipsis \textemdash \textperiodcentered \textcentereddot \textquoteleft \textquoteright \textquotedblleft \textquotedblright } - { - \xeCJK_cs_add:Nnn #1 - { \@@_group_begin: \makexeCJKinactive } { \@@_group_end: } - } - \xeCJK_cs_add:Nnn \tipaencoding { \makexeCJKinactive } { } + { \cs_gset_nopar:Npx #1 { { \makexeCJKinactive \exp_not:o {#1} } } } + \tl_put_left:Nn \tipaencoding { \makexeCJKinactive } \cs_new_eq:NN \@@_aux_r:n \r \cs_set_nopar:Npn \r #1 { { \makexeCJKinactive \@@_aux_r:n {#1} } } \xeCJK_if_package_loaded:nT { pifont } - { \xeCJK_cs_add:Nnn \Pifont { \makexeCJKinactive } { } } + { + \RenewDocumentCommand \Pifont { m } + { \makexeCJKinactive \usefont { U } {#1} { m } { n } } + } } -\cs_new_eq:NN \@@_group_begin: \group_begin: -\cs_new_eq:NN \@@_group_end: \group_end: % \end{macrocode} % % 简单处理与 \pkg{hyperref} 宏包的兼容问题。 @@ -5060,8 +5649,6 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ { \@@_gobble_CJKfamily: \xeCJK_cs_clear:N \makexeCJKinactive - \xeCJK_cs_clear:N \@@_group_begin: - \xeCJK_cs_clear:N \@@_group_end: } } } @@ -5082,6 +5669,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \pkg{CJKnumb} 和 \pkg{CJKfntef} 宏包可以使用。 % \begin{macrocode} \tl_set:cn { ver@CJK.sty } { 9999/99/99 } +\tl_set_eq:cc { ver@CJKulem.sty } { ver@CJK.sty } \tl_set_eq:cc { ver@CJKpunct.sty } { ver@CJK.sty } % \end{macrocode} % @@ -5104,57 +5692,27 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \end{macrocode} % \end{macro} % -% \begin{macro}[internal]{\xeCJK_hook_for_ulem:} -% \changes{v3.1.0}{2012/11/16}{简化对 \pkg{ulem} 宏包的兼容补丁。} -% 对 \pkg{ulem} 宏包打补丁,以支持 \pkg{CJKfntef} 宏包。目前的问题是,在下划线状态 -% 下,相邻两个标点之间的空白不能压缩。 +% 由于 \pkg{xeCJK} 禁止 \pkg{CJKulem} 的载入,因此当使用 \pkg{ctex} 宏包的 |fntef| +% 选项时,就会出现 \cs{normalem} 没有定义的问题。此时改用 \pkg{xeCJKfntef} 以便 +% 载入 \pkg{ulem}。 % \begin{macrocode} -\cs_new_protected_nopar:Npn \xeCJK_hook_for_ulem: +\cs_if_eq:NNTF \ifCTEX@fntef \tex_iftrue:D + { \RequirePackage { xeCJKfntef } } { - \bool_if:NF \l_@@_ulem_hook_used_bool + \@@_at_end_preamble:n { - \bool_set_true:N \l_@@_ulem_hook_used_bool - \xeCJK_cs_clear:N \@@_CJK_FullLeft_glue: - \cs_set_protected_nopar:Npn \@@_FullLeft_ulem_hook: { { \CJKglue } } - \xeCJK_swap_cs:NN \CJKsymbol \@@_ulem_CJKsymbol:N - \xeCJK_swap_cs:NN \CJKpunctsymbol \@@_ulem_CJKpunctsymbol:N - } - } -\bool_new:N \l_@@_ulem_hook_used_bool -\@@_after_preamble:n - { - \xeCJK_if_package_loaded:nT { ulem } - { - \xeCJK_cs_gclear:N \@@_FullLeft_ulem_hook: - \xeCJK_pre_inter_class_toks:nnn { Boundary } { FullLeft } - { \@@_FullLeft_ulem_hook: } - \cs_if_exist:NTF \XeTeX@CJKfntef@hook + \xeCJK_if_package_loaded:nF { xeCJKfntef } { - \xeCJK_cs_gclear:N \CJKf@global - \AtBeginEnvironment - { CJKfilltwosides } { \cs_set_eq:NN \CJKglue \tex_hfil:D } - \cs_set_protected_nopar:Npn \XeTeX@CJKfntef@hook - { \xeCJK_select_font: \makexeCJKinactive } + \xeCJK_if_package_loaded:nTF { CJKfntef } + { \RequirePackage { xeCJKfntef } } + { + \xeCJK_if_package_loaded:nT { ulem } + { \RequirePackage { xeCJKfntef } } + } } - { \RequirePackage { CJKulem } } - \addto@hook \UL@hook { \xeCJK_hook_for_ulem: } } } % \end{macrocode} -% \end{macro} -% -% \begin{macro}[internal]{\@@_ulem_CJKsymbol:N,\@@_ulem_CJKpunctsymbol:N} -% 这两个宏定义里面的分组记号都是必须的,否则会出现分组不匹配的情况。 -% \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_ulem_CJKsymbol:N #1 - { - { \@@_ulem_CJKsymbol:N {#1} } - { \xeCJK_make_node:n { CJK } } \xeCJK_ignore_spaces:w - } -\cs_new_protected_nopar:Npn \@@_ulem_CJKpunctsymbol:N #1 - { { \@@_ulem_CJKpunctsymbol:N {#1} } \tex_ignorespaces:D } -% \end{macrocode} -% \end{macro} % % 为使用 \pkg{CJKnumb} 宏包而作一些处理。另外 \pkg{CJKnumb} 使用的是传统汉字“萬” % 和“億”,我们在这里把它们修正为简体字。 @@ -5187,6 +5745,447 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ %</package> % \end{macrocode} % +% \subsection{\pkg{xeCJKfntef}} +% +% \changes{v3.1.1}{2012/12/08}{增加小宏包 \pkg{xeCJKfntef},用于处理下划线的问题。} +% +% \begin{macrocode} +%<*fntef> +% \end{macrocode} +% +% \pkg{xeCJKfntef} 不需要 \pkg{CJKulem} 宏包的支持,因此当使用 \pkg{CJKfntef} 时,% +% 需要另行载入 \pkg{ulem}。 +% \begin{macrocode} +\PassOptionsToPackage { normalem } { ulem } +\DeclareOption* { \PassOptionsToPackage { \CurrentOption } { ulem } } +\ProcessOptions \scan_stop: +% \end{macrocode} +% +% \begin{macrocode} +\@ifpackageloaded { xeCJK } + { } + { \RequirePackage { xeCJK } } +\RequirePackage { ulem } +\RequirePackage { CJKfntef } +% \end{macrocode} +% +% \begin{macrocode} +\addto@hook \UL@hook { \xeCJK_hook_for_ulem: } +% \end{macrocode} +% +% \begin{macro}[internal]{\xeCJK_hook_for_ulem:} +% \changes{v3.1.0}{2012/11/16}{简化对 \pkg{ulem} 宏包的兼容补丁。} +% \changes{v3.1.1}{2012/12/08}{完全处理下划线里的标点符号的有关问题。} +% \begin{macrocode} +\cs_new_protected_nopar:Npn \xeCJK_hook_for_ulem: + { + \bool_if:NF \l_@@_ulem_hook_used_bool + { + \bool_set_true:N \l_@@_ulem_hook_used_bool + \xeCJKsetup { CheckFullRight = false } + \bool_if:NTF \l_@@_ulem_skip_punct_bool + { \cs_set_eq:NN \@@_ulem_leader_type: \UL@leadtype } + { + \xeCJK_cs_clear:N \@@_ulem_skip_punct_begin: + \xeCJK_cs_clear:N \@@_ulem_skip_punct_end: + } + \@@_ulem_initial: + \xeCJK_glue_to_skip:nN + { + \cs_set_eq:NN \ \tex_space:D + \cs_set_eq:NN \penalty \tex_penalty:D + \cs_set_eq:NN \hskip \skip_horizontal:N + \CJKglue + } \l_@@_ccglue_skip + \xeCJK_glue_to_skip:nN + { + \cs_set_eq:NN \ \tex_space:D + \cs_set_eq:NN \penalty \tex_penalty:D + \cs_set_eq:NN \hskip \skip_horizontal:N + \CJKecglue + } \l_@@_ecglue_skip + \cs_set_protected_nopar:Npn \CJKglue + { \@@_ulem_glue:n \l_@@_ccglue_skip } + \cs_set_protected_nopar:Npn \CJKecglue + { \@@_ulem_glue:n \l_@@_ecglue_skip } + } + } +\bool_new:N \l_@@_ulem_hook_used_bool +% \end{macrocode} +% \end{macro} +% +% \setbox\xeCJKtmpbox\vbox\bgroup +% \begin{macrocode} +%<@@=> +% \end{macrocode}\egroup +% +% \begin{macro}[internal]{\CJK@UL,\CJK@@UL} +% 修改 \pkg{CJKfntef} 中的 \cs{CJK@UL} 和 \cs{CJK@@UL} 以适应下面的修改。 +% \begin{macrocode} +\cs_set_eq:NN \CJK@UL \CJK@@UL +\tl_replace_once:Nnn \CJK@UL { \ULon } + { \bool_set_true:N \l__xeCJK_ulem_skip_punct_bool \ULon } +\tl_replace_once:Nnn \CJK@@UL { \ULon } + { \bool_set_false:N \l__xeCJK_ulem_skip_punct_bool \ULon } +\bool_new:N \l__xeCJK_ulem_skip_punct_bool +% \end{macrocode} +% \end{macro} +% +% \setbox\xeCJKtmpbox\vbox\bgroup +% \begin{macrocode} +%<@@=xeCJK> +% \end{macrocode}\egroup +% +% \begin{macro}[internal]{\@@_ulem_skip_punct_begin:,\@@_ulem_skip_punct_end:} +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_ulem_skip_punct_begin: + { \xeCJK_cs_clear:N \UL@leadtype } +\cs_new_protected_nopar:Npn \@@_ulem_skip_punct_end: + { \cs_set_eq:NN \UL@leadtype \@@_ulem_leader_type: } +\xeCJK_cs_clear:N \@@_ulem_leader_type: +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\@@_ulem_initial:} +% 这里的设置是为了在下划线状态下,下划线可以自动跳过全角标点符号和正确的在它们 +% 前/后断行,并且与行首行末对齐。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_ulem_initial: + { + \cs_set_eq:NN \@@_punct_hskip:n \@@_ulem_hskip:n + \cs_set_eq:NN + \@@_Default_and_FullLeft_glue:N \@@_ulem_Default_and_FullLeft_glue:N + \cs_set_eq:NN + \@@_Default_and_FullRight_glue:N \@@_ulem_Default_and_FullRight_glue:N + \cs_set_eq:NN + \@@_CJK_and_FullLeft_glue:N \@@_ulem_CJK_and_FullLeft_glue:N + \cs_set_eq:NN + \@@_CJK_and_FullRight_glue:N \@@_ulem_CJK_and_FullRight_glue:N + \cs_set_eq:NN + \@@_Boundary_and_FullLeft_glue:N \@@_ulem_Boundary_and_FullLeft_glue:N + \cs_set_eq:NN \xeCJK_FullLeft_and_Default: \@@_ulem_FullLeft_and_Default: + \cs_set_eq:NN \xeCJK_FullLeft_and_CJK: \@@_ulem_FullLeft_and_CJK: + \cs_set_eq:NN \xeCJK_FullRight_and_Default: \@@_ulem_FullRight_and_Default: + \cs_set_eq:NN \xeCJK_FullRight_and_CJK: \@@_ulem_FullRight_and_CJK: + \cs_set_eq:NN \xeCJK_CJK_and_CJK:N \@@_ulem_CJK_and_CJK:N + \seq_map_inline:Nn \g_@@_CJK_sub_class_seq + { + \seq_map_inline:Nn \g_@@_CJK_sub_class_seq + { + \str_if_eq:nnTF {##1} {####1} + { + \xeCJK_inter_class_toks:nnn { CJK } { CJK/##1 } + { \@@_ulem_between_CJK_blocks:nnN { CJK } {##1} } + \xeCJK_inter_class_toks:nnn { CJK/##1 } { CJK/##1 } + { \@@_ulem_between_CJK_blocks:nnN { CJK } {##1} } + } + { + \xeCJK_inter_class_toks:nnn { CJK/##1 } { CJK/####1 } + { \@@_ulem_between_CJK_blocks:nnN {##1} {####1} } + } + } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\@@_ulem_CJK_and_CJK:N} +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_ulem_CJK_and_CJK:N + { + \xeCJK_class_group_end: + \UL@stop \@@_ulem_ccglue: \UL@start + \@@_ulem_class_group_begin: + \CJKsymbol + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\@@_ulem_class_group_begin:} +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_ulem_class_group_begin: + { + \xeCJK_class_group_begin: + \xeCJK_clear_Boundary_and_CJK_toks: + \xeCJK_select_font: + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\@@_ulem_between_CJK_blocks:nnN} +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_ulem_between_CJK_blocks:nnN #1#2 + { + \xeCJK_class_group_end: + \UL@stop \@@_ulem_ccglue: \UL@start + \xeCJK_class_group_begin: + \xeCJK_clear_Boundary_and_CJK_toks: + \@@_switch_font:nn {#1} {#2} + \CJKsymbol + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\@@_ulem_Default_and_FullLeft_glue:N} +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_ulem_Default_and_FullLeft_glue:N #1 + { + \UL@stop + \@@_ulem_skip_punct_begin: + \@@_punct_glue:NN \c_@@_left_tl {#1} + \UL@start + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\@@_ulem_Boundary_and_FullLeft_glue:N} +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_ulem_Boundary_and_FullLeft_glue:N #1 + { + \UL@stop + \@@_ulem_skip_punct_begin: + \int_compare:nNnF \etex_lastnodetype:D = \c_one + { \@@_punct_glue:NN \c_@@_left_tl {#1} } + \UL@start + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\@@_ulem_CJK_and_FullLeft_glue:N} +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_ulem_CJK_and_FullLeft_glue:N #1 + { + \xeCJK_class_group_end: + \UL@stop + \@@_ulem_skip_punct_begin: + \@@_ulem_ccglue: + \@@_punct_glue:NN \c_@@_left_tl {#1} + \UL@start + \@@_ulem_class_group_begin: + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\@@_ulem_Default_and_FullRight_glue:N} +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_ulem_Default_and_FullRight_glue:N #1 + { + \UL@stop + \@@_ulem_skip_punct_begin: + \@@_punct_if_long:NTF {#1} + { \@@_ulem_ccglue: } + { + \@@_punct_if_middle:NT {#1} + { + \xeCJK_no_break: + \@@_punct_glue:NN \c_@@_right_tl {#1} + } + \xeCJK_no_break: + } + \UL@start + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\@@_ulem_CJK_and_FullRight_glue:N} +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_ulem_CJK_and_FullRight_glue:N #1 + { + \xeCJK_class_group_end: + \@@_ulem_Default_and_FullRight_glue:N {#1} + \@@_ulem_class_group_begin: + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\@@_ulem_FullLeft_and_Default:} +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_ulem_FullLeft_and_Default: + { + \@@_punct_if_middle:NTF \g_@@_last_punct_tl + { + \xeCJK_get_punct_bounds:NN \c_@@_left_tl \g_@@_last_punct_tl + \@@_punct_rule:NN \c_@@_right_tl \g_@@_last_punct_tl + \xeCJK_class_group_end: \UL@stop \xeCJK_no_break: + \@@_punct_glue:NN \c_@@_left_tl \g_@@_last_punct_tl + } + { \xeCJK_class_group_end: \UL@stop } + \@@_ulem_skip_punct_end: + \xeCJK_no_break: + \UL@start + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\@@_ulem_FullLeft_and_CJK:} +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_ulem_FullLeft_and_CJK: + { + \@@_ulem_FullLeft_and_Default: + \@@_ulem_class_group_begin: + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\@@_ulem_FullRight_and_Default:} +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_ulem_FullRight_and_Default: + { + \@@_punct_rule:NN \c_@@_right_tl \g_@@_last_punct_tl + \xeCJK_class_group_end: + \UL@stop + \@@_punct_glue:NN \c_@@_right_tl \g_@@_last_punct_tl + \@@_ulem_skip_punct_end: + \UL@start + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\@@_ulem_FullRight_and_CJK:} +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_ulem_FullRight_and_CJK: + { + \@@_punct_rule:NN \c_@@_right_tl \g_@@_last_punct_tl + \xeCJK_class_group_end: + \UL@stop + \@@_punct_glue:NN \c_@@_right_tl \g_@@_last_punct_tl + \@@_ulem_ccglue: + \@@_ulem_skip_punct_end: + \UL@start + \@@_ulem_class_group_begin: + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\@@_ulem_glue:n,\@@_ulem_ccglue:,\@@_ulem_hskip:n} +% 在下划线状态下的分别代替 \cs{CJKglue} 等。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_ulem_glue:n #1 + { + \cs_if_eq:NNTF \ \LA@space + { \skip_horizontal:n {#1} } + { \UL@stop \@@_ulem_hskip:n {#1} \UL@start } + } +\cs_new_protected_nopar:Npn \@@_ulem_ccglue: + { \skip_set_eq:NN \UL@skip \l_@@_ccglue_skip \UL@leaders } +\cs_new_protected_nopar:Npn \@@_ulem_hskip:n #1 + { + \int_compare:nNnTF \tex_lastkern:D = \c_three + { \skip_horizontal:n {#1} } + { \skip_set:Nn \UL@skip {#1} \UL@leaders } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\CJKunderdot} +% 使用 \pkg{xeCJK} 时,\pkg{CJKfntef} 中的 \cs{CJKunderdot} 和 \cs{CJKunderanysymbol} +% 在汉字之间不能断行。因此需要我们在这里修改它们。 +% \begin{macrocode} +\RenewDocumentCommand \CJKunderdot { m } + { + \bool_if:NT \l_@@_ulem_hook_used_bool { \UL@stop } + \CJK@preUnderdot + \@@_make_under_symbol:n { \CJK@underdotSkip } + \cs_gset_eq:NN \@@_save_under_dot_CJKsymbol:N \CJKsymbol + \cs_set_eq:NN \CJKsymbol \@@_under_CJKsymbol:N + \bool_if:NT \l_@@_ulem_hook_used_bool { \UL@start } + #1 + \bool_if:NT \l_@@_ulem_hook_used_bool { \UL@stop } + \cs_set_eq:NN \CJKsymbol \@@_save_under_dot_CJKsymbol:N + \CJK@postUnderdot + \bool_if:NT \l_@@_ulem_hook_used_bool { \UL@start } + \tex_ignorespaces:D + } +\box_new:N \g_@@_under_symbol_box +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\CJKunderanysymbol} +% \begin{macrocode} +\RenewDocumentCommand \CJKunderanysymbol { m m m } + { + \group_begin: + \hbox_set:Nn \CJK@underdotBox {#2} + \@@_make_under_symbol:n {#1} + \cs_gset_eq:NN \@@_save_under_dot_CJKsymbol:N \CJKsymbol + \cs_set_eq:NN \CJKsymbol \@@_under_CJKsymbol:N + #3 + \group_end: + \tex_ignorespaces:D + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\@@_make_under_symbol:n} +% \begin{macrocode} +\cs_new_protected:Npn \@@_make_under_symbol:n #1 + { + \hbox_set:Nn \l_@@_tmp_box { ^^^^4e00 } + \vbox_gset_to_ht:Nnn \g_@@_under_symbol_box \c_zero_dim + { + \skip_vertical:n {#1} + \hbox_to_zero:n + { + \tex_kern:D - \box_wd:N \l_@@_tmp_box + \tex_hss:D \box_use:N \CJK@underdotBox \tex_hss:D + } + \tex_vss:D + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\@@_under_CJKsymbol:N} +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_under_CJKsymbol:N #1 + { + \@@_save_under_dot_CJKsymbol:N {#1} + \hbox_overlap_left:n { \box_use:N \g_@@_under_symbol_box } + { \xeCJK_make_node:n { CJK } } + \xeCJK_ignore_spaces:w + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{CJKfilltwosides} +% 修改 |CJKfilltwosides| 环境,使其不必重定义 \cs{CJKsymbol}。 +% \begin{macrocode} +\RenewDocumentEnvironment { CJKfilltwosides } { m } + { + \dim_set:Nn \l_@@_fill_width_dim {#1} + \cs_set_eq:NN \CJKglue \tex_hfil:D + \cs_set_eq:NN \\ \@@_fill_newline: + \mode_if_vertical:T { \tex_indent:D } + \tex_vbox:D \c_group_begin_token + \tex_hbox:D to \l_@@_fill_width_dim \c_group_begin_token + \tex_ignorespaces:D + } + { + \tex_unskip:D + \c_group_end_token + \c_group_end_token + } +\dim_new:N \l_@@_fill_width_dim +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\@@_fill_newline:} +% |CJKfilltwosides| 环境里的断行命令 |\\|。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_fill_newline: + { + \tex_unskip:D + \c_group_end_token + \tex_hbox:D to \l_@@_fill_width_dim \c_group_begin_token + \tex_ignorespaces:D + } +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%</fntef> +% \end{macrocode} +% % \subsection{\pkg{xeCJK.cfg}} % % \begin{macrocode} @@ -5281,7 +6280,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ % \begin{macrocode} \documentclass{article} \usepackage[AutoFallBack]{xeCJK} -\usepackage{CJKfntef} +\usepackage{xeCJKfntef} \usepackage{array} \setCJKmainfont[AutoFakeBold,AutoFakeSlant]{KaiTi_GB2312} \setCJKfallbackfamilyfont{\CJKrmdefault}[BoldFont=SimHei] @@ -5437,6 +6436,8 @@ This is an example. 这是一个例子} \def。{.} \def\foo{一} \long\def\showtext{一二三四五六七八九十一二三四五六七八九十一二三四五六七八九十。 +\[x^2+y^2\] +一二三四五六七八九十一二三四五六七八九十一二三四五六七八九十\foo $$x^2+y^2$$ 一二三四五六七八九十一二三四五六七八九十一二三四五六七八九十\foo \begin{equation} @@ -5452,6 +6453,11 @@ x^2+y^2 \xeCJKsetup{CheckSingle} \showtext + +\hrulefill\bigskip + +\xeCJKsetup{PlainEquation} +\showtext \end{document} % \end{macrocode} % @@ -5469,22 +6475,47 @@ x^2+y^2 \documentclass{article} \usepackage{xeCJK} \usepackage{xcolor} -\usepackage{CJKfntef} -\setCJKmainfont{SimSun} - -\begin{document} +\usepackage{xeCJKfntef} +\xeCJKDeclareSubCJKBlock{test}{ `殆 , `已 } +\setCJKmainfont[test=SimHei]{SimSun} -\CJKunderline{汉字}\CJKunderline{加下划线加下划线加下划线加下划线 -加下划线加下划线加下划线加下划线加下划线加下划线加下划线} +\def\showtext{% + 庄子曰:“吾生也有涯,而知也无涯。以有涯随无涯,殆已!已而为知者,殆而已矣!% + 为善无近名,为恶无近刑,缘督以为经,可以保身,可以全生,可以养亲,可以尽年。”} +\newcommand\CJKfntef[1]{% + \csname#1\endcsname{\showtext}\par + \csname#1\endcsname*{\showtext}\par + \CJKunderdot{\showtext\csname#1\endcsname{\showtext}}\par + \CJKunderdot{\showtext\csname#1\endcsname*{\showtext}}\par + \csname#1\endcsname{\showtext\CJKunderdot{\showtext}}\par + \csname#1\endcsname*{\showtext\CJKunderdot{\showtext}}\par\bigskip} -\CJKunderwave{波浪线} +\begin{document} +\CJKunderline{汉 字}\CJKunderline{加下划线} +\varCJKunderline{汉字}\varCJKunderline{加下划线} \CJKunderanyline{0.5em}{\sixly \kern-.021em\char58 \kern-.021em}{自定义下划线} - \CJKunderanyline{0.2em}{\kern-.03em\vtop{\kern.2ex\hrule width.2em\kern 0.11em \hrule height 0.1em}\kern-.03em}{自定义下划线} -\CJKunderanysymbol{0.5em}{$\cdot$}{汉字加点} +\CJKunderanyline{0.5em}{-}{\showtext} + +\CJKunderanysymbol{0.2em}{-}{\showtext} + +\CJKunderdot{\showtext} + +\begin{CJKfilltwosides}{40mm} +两端分散对齐\\ +分散对齐\\ +\CJKunderdot{汉字可加点}\\ +\CJKunderline{汉字可加下划线} +\end{CJKfilltwosides} + +\CJKfntef{CJKunderline} +\CJKfntef{CJKunderwave} +\CJKfntef{CJKunderdblline} +\CJKfntef{CJKsout} +\CJKfntef{CJKxout} \end{document} % \end{macrocode} diff --git a/Master/texmf-dist/source/xelatex/xecjk/xeCJK.ins b/Master/texmf-dist/source/xelatex/xecjk/xeCJK.ins index d6dda519368..9a689cc6ba9 100644 --- a/Master/texmf-dist/source/xelatex/xecjk/xeCJK.ins +++ b/Master/texmf-dist/source/xelatex/xecjk/xeCJK.ins @@ -6,7 +6,7 @@ %% %% xeCJK.dtx (with options: `batchfile') %% -%% $Id: xeCJK.dtx 368 2012-11-23 04:55:23Z sobenlee $ +%% $Id: xeCJK.dtx 382 2012-12-13 04:58:22Z sobenlee $ %% $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ %% ----------------------------------------------------------------- %% Author: @@ -35,7 +35,7 @@ \askforoverwritefalse \preamble -$Id: xeCJK.dtx 368 2012-11-23 04:55:23Z sobenlee $ +$Id: xeCJK.dtx 382 2012-12-13 04:58:22Z sobenlee $ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ ----------------------------------------------------------------- Author: @@ -66,6 +66,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ xeCJK.sty, xeCJK.cfg, xeCJK.ins, + xeCJKfntef.sty, xeCJK-example-autofake.tex, xeCJK-example-fallback.tex, xeCJK-example-subCJKblock.tex, @@ -81,7 +82,9 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ \declarepostamble\emptypostamble \endpostamble \usedir{tex/xelatex/xecjk} -\generate{\file{\jobname.sty}{\from{\jobname.dtx}{package}}} +\generate{ + \file{\jobname.sty}{\from{\jobname.dtx}{package}} + \file{xeCJKfntef.sty}{\from{\jobname.dtx}{fntef}}} \usedir{tex/xelatex/xecjk/config} \generate{ \usepreamble\emptypreamble @@ -106,6 +109,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ %% xeCJK.sty, %% xeCJK.cfg, %% xeCJK.ins, +%% xeCJKfntef.sty, %% xeCJK-example-autofake.tex, %% xeCJK-example-fallback.tex, %% xeCJK-example-subCJKblock.tex, diff --git a/Master/texmf-dist/tex/xelatex/xecjk/config/xeCJK.cfg b/Master/texmf-dist/tex/xelatex/xecjk/config/xeCJK.cfg index cf9c3189a7f..4c34f1a2179 100644 --- a/Master/texmf-dist/tex/xelatex/xecjk/config/xeCJK.cfg +++ b/Master/texmf-dist/tex/xelatex/xecjk/config/xeCJK.cfg @@ -6,12 +6,11 @@ %% %% xeCJK.dtx (with options: `config') %% -\NeedsTeXFormat{LaTeX2e} -\GetIdInfo$Id: xeCJK.dtx 368 2012-11-23 04:55:23Z sobenlee $ +\GetIdInfo$Id: xeCJK.dtx 382 2012-12-13 04:58:22Z sobenlee $ {Configuration file for xeCJK package} \ProvidesExplFile {\ExplFileName.cfg} - {\ExplFileDate}{3.1.0}{\ExplFileDescription} + {\ExplFileDate}{3.1.1}{\ExplFileDescription} %% %% diff --git a/Master/texmf-dist/tex/xelatex/xecjk/xeCJK.sty b/Master/texmf-dist/tex/xelatex/xecjk/xeCJK.sty index f6876df0358..6678f7cc805 100644 --- a/Master/texmf-dist/tex/xelatex/xecjk/xeCJK.sty +++ b/Master/texmf-dist/tex/xelatex/xecjk/xeCJK.sty @@ -6,7 +6,7 @@ %% %% xeCJK.dtx (with options: `package') %% -%% $Id: xeCJK.dtx 368 2012-11-23 04:55:23Z sobenlee $ +%% $Id: xeCJK.dtx 382 2012-12-13 04:58:22Z sobenlee $ %% $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ %% ----------------------------------------------------------------- %% Author: @@ -31,11 +31,11 @@ %% \NeedsTeXFormat{LaTeX2e} \RequirePackage{expl3} -\GetIdInfo$Id: xeCJK.dtx 368 2012-11-23 04:55:23Z sobenlee $ +\GetIdInfo$Id: xeCJK.dtx 382 2012-12-13 04:58:22Z sobenlee $ {Typesetting CJK scripts with XeLaTeX} \ProvidesExplPackage {\ExplFileName} - {\ExplFileDate}{3.1.0}{\ExplFileDescription} + {\ExplFileDate}{3.1.1}{\ExplFileDescription} \msg_new:nnn { xeCJK } { Require-XeTeX } { The~xeCJK~package~requires~XeTeX~to~function.\\\\ @@ -58,7 +58,6 @@ \@ifpackagelater { xtemplate } { 2012/11/10 } { } { \msg_error:nnn { xeCJK } { l3-too-old } { xtemplate } } \RequirePackage { xparse , l3keys2e } -\RequirePackage { xpatch } \tl_new:N \l__xeCJK_tmpa_tl \tl_new:N \l__xeCJK_tmpb_tl \int_new:N \l__xeCJK_tmpa_int @@ -66,7 +65,7 @@ \int_new:N \l__xeCJK_tmpc_int \box_new:N \l__xeCJK_tmp_box \dim_new:N \l__xeCJK_tmp_dim -\skip_new:N \g__xeCJK_tmp_skip +\skip_new:N \l__xeCJK_tmp_skip \prop_new:N \l__xeCJK_tmp_prop \clist_new:N \l__xeCJK_tmpa_clist \clist_new:N \l__xeCJK_tmpb_clist @@ -80,6 +79,12 @@ \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 } +\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 } \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 @@ -89,9 +94,25 @@ { \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} } -\AtEndPreamble { \g__xeCJK_at_end_preamble_hook_tl } -\AfterPreamble { \g__xeCJK_after_preamble_hook_tl } -\AfterEndPreamble { \g__xeCJK_after_end_preamble_hook_tl } +\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: + } + } \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 @@ -104,24 +125,6 @@ { \__xeCJK_tl_remove_outer_braces:w #1 \q_stop } { \tl_trim_spaces:n {#1} } } -\cs_new_protected:Npn \xeCJK_cs_add:Nnn #1#2#3 - { - \tl_if_empty:nTF {#3} - { \tl_if_empty:nTF {#2} { \use_ii:nn } { \xpretocmd {#1} {#2} } } - { - \tl_if_empty:nTF {#2} { \xapptocmd {#1} {#3} } - { \xpretocmd {#1} {#2} { \xapptocmd {#1} {#3} } { \use_ii:nn } } - } - { \__xeCJK_info:nxx { patch-cmd } { \token_to_str:N #1 } { succeeded } } - { \__xeCJK_warning:nxx { patch-cmd } { \token_to_str:N #1 } { failed } } - } -\cs_new_protected:Npn \xeCJK_cs_patch:Nnn #1#2#3 - { - \xpatchcmd {#1} {#2} {#3} - { \__xeCJK_info:nxx { patch-cmd } { \token_to_str:N #1 } { succeeded } } - { \__xeCJK_warning:nxx { patch-cmd } { \token_to_str:N #1 } { failed } } - } -\__xeCJK_msg_new:nn { patch-cmd } { Patching~'#1'~#2! } \cs_new_eq:NN \xeCJK_cs_clear:N \tl_clear:N \cs_new_eq:NN \xeCJK_cs_gclear:N \tl_gclear:N \cs_new_protected:Npn \xeCJK_swap_cs:NN #1#2 @@ -153,30 +156,77 @@ } \cs_new_protected_nopar:Npn \xeCJK_glue_to_skip:nN #1#2 { - \hbox_set:Nn \l__xeCJK_tmp_box - { #1 \skip_gset_eq:NN \g__xeCJK_tmp_skip \tex_lastskip:D } - \skip_set_eq:NN #2 \g__xeCJK_tmp_skip + \hbox_set:Nn \l__xeCJK_tmp_box { #1 \scan_stop: \exp_after:wN } \exp_after:wN + \skip_set:Nn \exp_after:wN #2 \exp_after:wN { \skip_use:N \tex_lastskip:D } } \prg_new_conditional:Npnn \xeCJK_if_blank_x:n #1 { p , T , F , TF } { - \if_int_compare:w \pdftex_strcmp:D { \c_empty_tl } {#1} = \c_zero + \if_case:w \pdftex_strcmp:D { } {#1} \exp_stop_f: \prg_return_true: \else: - \if_int_compare:w \pdftex_strcmp:D { \c_space_tl } {#1} = \c_zero + \if_case:w \pdftex_strcmp:D { ~ } {#1} \exp_stop_f: \prg_return_true: \else: \prg_return_false: \fi: \fi: } -\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 } \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} } +\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: + } +\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 + { \XeTeXcharclass \xeCJK_token_value_charcode:N #1 } +\cs_new_nopar:Npn \xeCJK_token_value_charcode:N #1 + { \exp_after:wN \__xeCJK_token_value_charcode:w \token_to_meaning:N #1 \q_stop } +\cs_new_nopar:Npn \__xeCJK_token_value_charcode:w #1 ~ #2 ~ #3 \q_stop { `#3 } +\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: , @@ -187,18 +237,41 @@ \NewDocumentCommand \makexeCJKactive { } { \XeTeXinterchartokenstate = \c_one } \NewDocumentCommand \makexeCJKinactive { } { \XeTeXinterchartokenstate = \c_zero } \char_set_catcode_ignore:n { "FEFF } -\int_const:Nn \c__xeCJK_Default_class_int { \c_zero } -\int_const:Nn \c__xeCJK_CJK_class_int { \c_one } -\int_const:Nn \c__xeCJK_FullLeft_class_int { \c_two } -\int_const:Nn \c__xeCJK_FullRight_class_int { \c_three } -\int_const:Nn \c__xeCJK_Boundary_class_int { \c_two_hundred_fifty_five } +\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 { - \exp_args:Nc \newXeTeXintercharclass { c__xeCJK_#1_class_int } - \clist_gclear_new:c { g__xeCJK_#1_range_clist } - \seq_gput_right:Nv \g__xeCJK_class_seq { c__xeCJK_#1_class_int } + \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} } + } } -\seq_new:N \g__xeCJK_class_seq +\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_tmpa_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 } +\xeCJK_save_class:nn { CJK } { \c_one } +\xeCJK_save_class:nn { FullLeft } { \c_two } +\xeCJK_save_class:nn { FullRight } { \c_three } +\xeCJK_save_class:nn { Boundary } { \c_two_hundred_fifty_five } \xeCJK_new_class:n { HalfLeft } \xeCJK_new_class:n { HalfRight } \xeCJK_new_class:n { NormalSpace } @@ -263,30 +336,23 @@ "2F800 -> "2FA1F } \seq_new:N \g__xeCJK_base_class_seq -\seq_gset_split:Nnn \g__xeCJK_base_class_seq { , } - { - Default , CJK , FullLeft , FullRight , Boundary , - HalfLeft , HalfRight , NormalSpace - } -\seq_map_inline:Nn \g__xeCJK_base_class_seq - { \clist_gclear_new:c { g__xeCJK_#1_range_clist } } +\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 \prop_new:N \g__xeCJK_CJK_class_prop \cs_new_protected_nopar:Npn \__xeCJK_save_CJK_class:n #1 { \seq_gput_right:Nn \g__xeCJK_CJK_class_seq {#1} - \prop_gput:Nvn \g__xeCJK_CJK_class_prop { c__xeCJK_#1_class_int } {#1} + \prop_gput:Nvn \g__xeCJK_CJK_class_prop { \__xeCJK_class_csname:n {#1} } {#1} + \tl_gput_right:Nx \g__xeCJK_check_single_CJK_case_tl + { { \exp_not:c { \__xeCJK_class_csname:n {#1} } } { \exp_not:N \use_ii:nn } } } +\tl_new:N \g__xeCJK_check_single_CJK_case_tl \cs_generate_variant:Nn \prop_gput:Nnn { Nvn } \clist_map_function:nN { CJK , FullLeft , FullRight } \__xeCJK_save_CJK_class:n -\cs_new_nopar:Npn \xeCJK_class_num:n #1 { \use:c { c__xeCJK_#1_class_int } } -\cs_new_nopar:Npn \xeCJK_value_class:n #1 - { \XeTeXcharclass \etex_numexpr:D #1 \scan_stop: } -\prg_new_conditional:Npnn \xeCJK_if_same_class:NN #1#2 { p , T , F , TF } - { - \if_int_compare:w \xeCJK_value_class:n {`#1} = \xeCJK_value_class:n {`#2} - \prg_return_true: \else: \prg_return_false: \fi: - } +\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:nx {#2} {#3} @@ -310,16 +376,12 @@ { m > { \SplitArgument { 1 } { -> } } m } { #1 #2 } \cs_generate_variant:Nn \clist_gconcat:NNN { cc } \cs_generate_variant:Nn \xeCJK_declare_char_class:nn { nx , nV } -\NewDocumentCommand \xeCJKsetcharclass { s m m m } - { - \xeCJK_set_char_class:nnn {#2} {#3} {#4} - \IfBooleanF {#1} { \xeCJKResetPunctClass } - } -\cs_new_protected_nopar:Npn \xeCJK_set_char_class:nnn #1#2#3 +\cs_new_protected_nopar:Npn \__xeCJK_set_char_class_catcode:nnn #1#2#3 { \__xeCJK_check_num_range:nnNN {#1} {#2} \l__xeCJK_tmpa_int \l__xeCJK_tmpb_int \int_set:Nn \l__xeCJK_tmpc_int {#3} - \prop_get:NVNTF \g__xeCJK_CJK_class_prop \l__xeCJK_tmpc_int \l__xeCJK_tmpa_tl + \int_compare:nNnTF + { \use:c { \__xeCJK_class_csname:n { CJK } } } = \l__xeCJK_tmpc_int { \cs_set_eq:NN \__xeCJK_set_char_catcode:n \char_set_catcode_other:n } { \cs_set_eq:NN \__xeCJK_set_char_catcode:n \use_none:n } \xeCJK_int_until_do:nn { \l__xeCJK_tmpa_int > \l__xeCJK_tmpb_int } @@ -329,6 +391,16 @@ \int_incr:N \l__xeCJK_tmpa_int } } +\cs_new_protected_nopar:Npn \__xeCJK_set_char_class:nnn #1#2#3 + { + \__xeCJK_check_num_range:nnNN {#1} {#2} \l__xeCJK_tmpa_int \l__xeCJK_tmpb_int + \int_set:Nn \l__xeCJK_tmpc_int {#3} + \xeCJK_int_until_do:nn { \l__xeCJK_tmpa_int > \l__xeCJK_tmpb_int } + { + \XeTeXcharclass \l__xeCJK_tmpa_int = \l__xeCJK_tmpc_int + \int_incr:N \l__xeCJK_tmpa_int + } + } \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} } @@ -341,18 +413,20 @@ \int_set:Nn #4 { \int_max:nn {#1} { \IfNoValueTF {#2} {#1} {#2} } } } } +\cs_new_eq:NN \xeCJK_set_char_class:nnn \__xeCJK_set_char_class_catcode:nnn +\AtEndOfPackage + { \cs_set_eq:NN \xeCJK_set_char_class:nnn \__xeCJK_set_char_class:nnn } \cs_new_protected_nopar:Npn \__xeCJK_set_char_class_eq:nn #1#2 { - \int_set:Nn \l__xeCJK_tmpa_int { \xeCJK_class_num:n {#1} } - \clist_map_inline:cn { c__xeCJK_#2_chars_clist } + \int_set:Nn \l__xeCJK_tmpa_int { \xeCJK_class_num:n {#2} } + \clist_map_inline:cn { c__xeCJK_#1_chars_clist } { \XeTeXcharclass ##1 = \l__xeCJK_tmpa_int } } \NewDocumentCommand \normalspacedchars { m } { - \tl_map_inline:xn {#1} + \tl_map_inline:nn {#1} { \XeTeXcharclass `##1 = \xeCJK_class_num:n { NormalSpace } } } -\cs_generate_variant:Nn \tl_map_inline:nn { x } \NewDocumentCommand \xeCJKResetPunctClass { } { \xeCJK_declare_char_class:nV { HalfLeft } \c__xeCJK_HalfLeft_chars_clist @@ -369,7 +443,7 @@ \xeCJKResetCharClass \cs_new_protected_nopar:Npn \xeCJK_inter_class_toks:nnn #1#2#3 { \XeTeXinterchartoks \xeCJK_class_num:n {#1} ~ \xeCJK_class_num:n {#2} = {#3} } -\cs_generate_variant:Nn \xeCJK_inter_class_toks:nnn { nnc , nnx } +\cs_generate_variant:Nn \xeCJK_inter_class_toks:nnn { nnc , nnv , nnx } \cs_new_nopar:Npn \xeCJK_get_inter_class_toks:nn #1#2 { \tex_the:D \XeTeXinterchartoks \xeCJK_class_num:n {#1} ~ \xeCJK_class_num:n {#2} } \cs_new_protected_nopar:Npn \xeCJK_clear_inter_class_toks:nn #1#2 @@ -405,20 +479,15 @@ \cs_new_eq:NN \xeCJK_class_group_end: \c_group_end_token \clist_map_inline:nn { Default , HalfLeft , HalfRight , NormalSpace } { - \clist_map_inline:nn { CJK , FullLeft , FullRight } + \xeCJK_inter_class_toks:nnn {#1} { CJK } { - \xeCJK_inter_class_toks:nnn {#1} {##1} - { - \xeCJK_class_group_begin: - \xeCJK_select_font: - \xeCJK_clear_inter_class_toks:nn {#1} {##1} - \xeCJK_clear_Boundary_and_CJK_toks: - } - \xeCJK_inter_class_toks:nnn {##1} {#1} { \xeCJK_class_group_end: } + \xeCJK_class_group_begin: + \xeCJK_select_font: + \xeCJK_clear_inter_class_toks:nn {#1} { CJK } + \xeCJK_clear_Boundary_and_CJK_toks: + \CJKsymbol } - \xeCJK_app_inter_class_toks:nnn {#1} { CJK } { \CJKsymbol } - \clist_map_inline:nn { FullLeft , FullRight } - { \xeCJK_app_inter_class_toks:nnc {#1} {##1} { xeCJK_CJK_and_##1:N } } + \xeCJK_inter_class_toks:nnn { CJK } {#1} { \xeCJK_class_group_end: } } \clist_map_inline:nn { Default , HalfLeft , NormalSpace } { @@ -436,7 +505,7 @@ \xeCJK_if_last_node_p:n { CJK } || \xeCJK_if_last_node_p:n { CJK-space } } - { \CJKecglue } { \c_space_token } + { \CJKecglue } { ~ } } { \xeCJK_if_last_node:nTF { CJK } { \CJKecglue } @@ -450,8 +519,8 @@ { \xeCJK_inter_class_toks:nnn {#1} { Boundary } { - \peek_meaning_remove:NTF \/ - { \/ { \xeCJK_make_node:n { default } } } + \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 } } } @@ -463,7 +532,7 @@ } \xeCJK_inter_class_toks:nnn { Boundary } { CJK } { - { \xeCJK_check_for_glue: } + \xeCJK_check_for_glue: \xeCJK_class_group_begin: \xeCJK_clear_Boundary_and_CJK_toks: \xeCJK_select_font: @@ -503,8 +572,8 @@ \xeCJK_if_last_node_p:n { CJK } || \xeCJK_if_last_node_p:n { CJK-space } } - { \bool_if:NTF \l__xeCJK_reserve_space_bool \c_space_token \CJKglue } - { \c_space_token } + { \bool_if:NTF \l__xeCJK_reserve_space_bool { ~ } { \CJKglue } } + { ~ } } } } @@ -531,13 +600,20 @@ \xeCJK_def_node:nn { default } { 13 sp } \xeCJK_def_node:nn { default-space } { 14 sp } \keys_define:nn { xeCJK / options } - { CJKglue .code:n = { \cs_set_protected:Npn \CJKglue {#1} } } + { + 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:Npn \CJKecglue {#1} - \xeCJK_glue_to_skip:nN \CJKecglue \l__xeCJK_ecglue_skip + \cs_set_protected_nopar:Npn \CJKecglue {#1} + \xeCJK_glue_to_skip:nN {#1} \l__xeCJK_ecglue_skip } , xCJKecglue .choice: , xCJKecglue / true .code:n = @@ -548,13 +624,13 @@ xCJKecglue / false .code:n = { \bool_set_false:N \l__xeCJK_xecglue_bool - \cs_set_eq:NN \__xeCJK_space_or_xecglue: \c_space_token + \cs_set_eq:NN \__xeCJK_space_or_xecglue: \c_space_tl } , xCJKecglue / unknown .code:n = { \bool_set_true:N \l__xeCJK_xecglue_bool - \cs_set_protected:Npn \CJKecglue {#1} - \xeCJK_glue_to_skip:nN \CJKecglue \l__xeCJK_ecglue_skip + \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 } , xCJKecglue .default:n = { true } @@ -575,13 +651,16 @@ } \cs_new_protected_nopar:Npn \xeCJK_ignore_spaces:w { - \peek_catcode:NTF \c_space_token + \xeCJK_peek_catcode_ignore_spaces:NTF \c_math_toggle_token + { + \bool_if:NTF \l__xeCJK_peek_ignore_spaces_bool + { \__xeCJK_space_or_xecglue: } { \CJKecglue } + } { - \xeCJK_if_last_node:nT { CJK } - { \tex_unkern:D \tex_unkern:D { \xeCJK_make_node:n { CJK-space } } } - \peek_catcode_ignore_spaces:NTF \c_math_toggle_token - { \__xeCJK_space_or_xecglue: } + \bool_if:NTF \l__xeCJK_peek_ignore_spaces_bool { + \tex_unkern:D \tex_unkern:D + { \xeCJK_make_node:n { CJK-space } } \bool_if:nT { \token_if_macro_p:N \l_peek_token || @@ -590,41 +669,33 @@ } { \__xeCJK_space_or_xecglue: } } - } - { - \token_if_math_toggle:NTF \l_peek_token - { \CJKecglue } { \cs_if_exist:NF \l_peek_token \exp_not:N } } } -\cs_new_eq:NN \xeCJK_ignorespaces: \xeCJK_ignore_spaces:w \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} } -\clist_map_inline:nn { FullLeft , FullRight } +\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 { - \xeCJK_inter_class_toks:nnn { Boundary } {#1} + \clist_map_inline:nn { FullLeft , FullRight } { - \xeCJK_class_group_begin: - \xeCJK_clear_Boundary_and_CJK_toks: - \xeCJK_select_font: - \use:c { xeCJK_CJK_and_#1:N } + \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 { FullLeft } { Boundary } - { \xeCJK_class_group_end: \tex_ignorespaces:D } +\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_class_group_end: \CJKglue \tex_ignorespaces:D } -\xeCJK_inter_class_toks:nnn { FullLeft } { CJK } { \CJKsymbol } -\xeCJK_inter_class_toks:nnn { FullRight } { CJK } { \CJKglue \CJKsymbol } -\seq_map_inline:Nn \g__xeCJK_base_class_seq - { - \bool_if:nF - { \str_if_eq_p:nn {#1} { FullLeft } || \str_if_eq_p:nn {#1} { FullRight } } - { - \xeCJK_pre_inter_class_toks:nnn { FullLeft } {#1} { \xeCJK_after_FullLeft: } - \xeCJK_pre_inter_class_toks:nnn { FullRight } {#1} { \xeCJK_after_FullRight: } - } - } + { \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 } @@ -639,58 +710,133 @@ } \cs_new_protected_nopar:Npn \__xeCJK_punct_glue:NN #1#2 { - \skip_horizontal:n + \__xeCJK_punct_hskip:n { \__xeCJK_use_punct_dim:nnn { glue } {#1} {#2} minus \dim_eval:n { ( \__xeCJK_use_punct_dim:nnn { glue } {#1} {#2} ) / \c_two } } } +\cs_new_eq:NN \__xeCJK_punct_hskip:n \skip_horizontal:n \cs_new_protected_nopar:Npn \__xeCJK_punct_kern:NN #1#2 { \tex_kern:D \__xeCJK_use_punct_dim:nnn { kern } {#1} {#2} } \tl_new:N \g__xeCJK_last_punct_tl -\cs_new_protected_nopar:Npn \xeCJK_after_FullLeft: +\cs_new_protected_nopar:Npn \xeCJK_FullLeft_and_CJK: { - \xeCJK_no_break: - \__xeCJK_punct_if_middle:NT \g__xeCJK_last_punct_tl + \__xeCJK_punct_if_middle:NTF \g__xeCJK_last_punct_tl { - \xeCJK_get_punct_bounds:NN \c__xeCJK_left_tl \g__xeCJK_last_punct_tl - \__xeCJK_punct_glue:NN \c__xeCJK_left_tl \g__xeCJK_last_punct_tl \__xeCJK_punct_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_after_FullRight: +\cs_new_protected_nopar:Npn \xeCJK_FullLeft_and_Default: + { + \__xeCJK_punct_if_middle:NTF \g__xeCJK_last_punct_tl + { + \__xeCJK_punct_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: } + } +\cs_new_protected_nopar:Npn \xeCJK_FullRight_and_CJK: { - \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_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_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} } \cs_new_protected_nopar:Npn \xeCJK_CJK_and_FullLeft:N #1 { \xeCJK_get_punct_bounds:NN \c__xeCJK_left_tl {#1} - \int_compare:nNnF \etex_lastnodetype:D = \c_one - { \__xeCJK_CJK_FullLeft_glue: \__xeCJK_punct_glue: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} } +\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_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_CJK_FullLeft_glue: { \CJKglue } +\cs_new_protected_nopar:Npn \__xeCJK_Boundary_and_FullLeft_glue:N #1 + { + \int_compare:nNnF \etex_lastnodetype:D = \c_one + { \__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_punct_if_middle:NT {#2} + { \__xeCJK_punct_rule:NN \c__xeCJK_left_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_punct_if_middle:NT {#1} + { \__xeCJK_punct_rule:NN \c__xeCJK_left_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_punct_if_middle:NT {#1} + { \__xeCJK_punct_rule:NN \c__xeCJK_left_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_no_break: - \__xeCJK_punct_if_middle:NT {#1} - { - \__xeCJK_punct_glue:NN \c__xeCJK_right_tl {#1} - \__xeCJK_punct_rule:NN \c__xeCJK_left_tl {#1} - } + \__xeCJK_punct_if_middle:NTF {#1} + { \xeCJK_no_break: \__xeCJK_punct_glue:NN \c__xeCJK_right_tl {#1} } + { \xeCJK_no_break: } } - \tl_gset:Nx \g__xeCJK_last_punct_tl {#1} - \CJKpunctsymbol {#1} } +\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: @@ -708,7 +854,7 @@ \__xeCJK_punct_kern:NN \g__xeCJK_last_punct_tl {#1} \tl_gset:Nx \g__xeCJK_last_punct_tl {#1} \xeCJK_no_break: - \CJKpunctsymbol {#1} + \xeCJK_FullRight_symbol:N {#1} } \cs_new_protected_nopar:Npn \xeCJK_FullRight_and_FullLeft:N #1 { @@ -726,38 +872,115 @@ \__xeCJK_punct_kern:NN \g__xeCJK_last_punct_tl {#1} \tl_gset:Nx \g__xeCJK_last_punct_tl {#1} \xeCJK_no_break: - \CJKpunctsymbol {#1} + \xeCJK_FullRight_symbol:N {#1} } \keys_define:nn { xeCJK / options } { - CheckSingle .choice: , - CheckSingle / true .code:n = { \xeCJKenablechecksingle } , - CheckSingle / false .code:n = { \xeCJKdisablechecksingle } , - CheckSingle .default:n = { true } , - CJKchecksingle .meta:n = { CheckSingle = true } + 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 } } -\bool_new:N \l__xeCJK_check_single_bool -\NewDocumentCommand \xeCJKenablechecksingle { } +\cs_new_nopar:Npn \xeCJK_FullRight_symbol:N { \CJKpunctsymbol } +\cs_new_protected_nopar:Npn \xeCJK_check_FullRight: { - \bool_if:NF \l__xeCJK_check_single_bool + \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 + \tl_case:Non \l_peek_token { \l__xeCJK_no_break_cs_case_tl } { } + \__xeCJK_punct_glue:NN \c__xeCJK_right_tl \g__xeCJK_last_punct_tl + \xeCJK_class_group_end: + } +\cs_generate_variant:Nn \tl_case:Nnn { 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 } { - \bool_set_true:N \l__xeCJK_check_single_bool - \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 + #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 #2 {####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} + } } } -\NewDocumentCommand \xeCJKdisablechecksingle { } +\cs_new_protected:Npn \__xeCJK_update_cs_case_tl:NNnn #1#2#3#4 { - \bool_if:NT \l__xeCJK_check_single_bool + \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 { \xeCJK_no_break: } { } +\NewDocumentCommand \xeCJKnobreak { } + { + \int_zero:N \l__xeCJK_tmpa_int + \int_while_do:nNnn \etex_lastnodetype:D = \c_eleven { - \bool_set_false:N \l__xeCJK_check_single_bool - \cs_set_eq:NN \xeCJK_CJK_and_CJK:N \__xeCJK_check_single_save:N + \int_if_even:nTF \l__xeCJK_tmpa_int + { + \int_incr:N \l__xeCJK_tmpa_int + \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: + \int_if_even:nF \l__xeCJK_tmpa_int + { \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 } } \cs_new_protected_nopar:Npn \xeCJK_check_single:Nw #1 { \peek_catcode:NTF \c_catcode_other_token - { \xeCJK_check_single:NNw {#1} } + { \xeCJK_check_single:NNw #1 } { \bool_if:nTF { @@ -765,91 +988,138 @@ \exp_args:No \tl_if_single_token_p:n \l_peek_token && \exp_after:wN \token_if_other_p:N \l_peek_token } - { \xeCJK_check_single:NNw {#1} } - { \__xeCJK_check_single_save:N {#1} } + { \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 { - \peek_catcode:NTF \c_catcode_other_token - { \__xeCJK_check_single_save:N {#1} #2 } + \xeCJK_peek_catcode_ignore_spaces:NTF \c_catcode_other_token { - \bool_if:nTF + \bool_if:NTF \l__xeCJK_peek_ignore_spaces_bool + { \__xeCJK_check_single_space:NN #1#2 } + { \__xeCJK_check_single_save:N #1 #2 } + } + { + \group_align_safe_begin: + \token_if_cs:NTF \l_peek_token { - \token_if_space_p:N \l_peek_token || - \token_if_math_toggle_p:N \l_peek_token || - \token_if_cs_p:N \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 { } } } { - \bool_if:nTF { \token_if_space_p:N \l_peek_token } + \group_align_safe_end: + \bool_if:nTF { - \peek_catcode_ignore_spaces:NTF \c_catcode_other_token - { \__xeCJK_check_single_save:N {#1} #2 \c_space_token } - { - \bool_if:nTF - { - \token_if_math_toggle_p:N \l_peek_token || - \token_if_cs_p:N \l_peek_token - } - { \xeCJK_check_single:NNNw {#1} {#2} \c_space_token } - { \__xeCJK_check_single_save:N {#1} #2 \c_space_token } - } + \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 } } - { \xeCJK_check_single:NNNw {#1} {#2} { } } } - { \__xeCJK_check_single_save:N {#1} #2 } } } -\cs_new_protected_nopar:Npn \xeCJK_check_single:NNNw #1#2#3 +\cs_new_protected_nopar:Npn \__xeCJK_check_single_space:NN #1#2 { - \bool_if:nTF + \int_case:non { \xeCJK_token_value_class:N #2 } + { \g__xeCJK_check_single_CJK_case_tl } + { \use_i:nn } + { \__xeCJK_check_single_save:N #1 #2 ~ } { - \token_if_eq_meaning_p:NN \l_peek_token \par || - \token_if_eq_meaning_p:NN \l_peek_token \[ % \] + \int_case:non { \xeCJK_token_value_class:N \l_peek_token } + { \g__xeCJK_check_single_CJK_case_tl } + { \use_i:nn } + { \__xeCJK_check_single_save:N #1 #2 ~ } + { \__xeCJK_check_single_save:N #1 #2 } } - { \CJKsymbol {#1} \xeCJK_no_break: #2 } - { \xeCJK_check_single_env:NNNw {#1} {#2} {#3} } } -\cs_new_protected_nopar:Npn \xeCJK_check_single_env:NNNw #1#2#3 +\cs_generate_variant:Nn \int_case:nnn { no } +\cs_new_protected_nopar:Npn \xeCJK_check_single_equation:NNnNw #1#2#3#4 { - \peek_catcode_remove:NTF \c_math_toggle_token + \peek_catcode:NTF \c_math_toggle_token { - \peek_catcode:NTF \c_math_toggle_token - { \CJKsymbol {#1} \xeCJK_no_break: #2 \c_math_toggle_token } - { \__xeCJK_check_single_save:N {#1} #2#3 \c_math_toggle_token } + \xeCJK_no_break: \__xeCJK_check_single_save:N #1 + \xeCJK_no_break: #2 #4 } + { \__xeCJK_check_single_save:N #1 #2#3#4 } + } +\cs_new_protected_nopar:Npn \xeCJK_check_single_cs:NNn #1#2#3 + { + \tl_case:Non \l_peek_token + { \l__xeCJK_check_single_cs_case_tl } + { \use_iii:nnn } + { \xeCJK_check_single_env:nnNn } { - \peek_meaning_remove:NTF \begin - { \xeCJK_check_single_env:NNNNn {#1} {#2} {#3} \begin } - { - \peek_meaning_remove:NTF \end - { \xeCJK_check_single_env:NNNNn {#1} {#2} {#3} \end } - { \__xeCJK_check_single_save:N {#1} #2#3 } - } + \xeCJK_no_break: \__xeCJK_check_single_save:N #1 + \xeCJK_no_break: #2 } + { \__xeCJK_check_single_save:N #1 #2#3 } + } +\tl_new:N \l__xeCJK_check_single_cs_case_tl +\cs_new_protected_nopar:Npn \xeCJK_check_single_env:nnNn #1#2#3#4 + { + \str_case_x:non {#4} + { \l__xeCJK_inline_env_case_tl } + { \use_i:nn } + {#1} {#2} + \scan_stop: #3 {#4} } -\cs_new_protected_nopar:Npn \xeCJK_check_single_env:NNNNn #1#2#3#4#5 +\cs_generate_variant:Nn \str_case_x:nnn { no } +\xeCJK_cs_case_keys_define:nNNnn { NewLineCS } + \l__xeCJK_new_line_cs_case_tl \l__xeCJK_new_line_cs_seq { \use_ii:nnn } { - \clist_if_in:NnTF \g__xeCJK_inline_env_clist {#5} - { \__xeCJK_check_single_save:N {#1} #2#3 } - { \CJKsymbol {#1} \xeCJK_no_break: #2 } - \scan_stop: #4 {#5} + \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 { \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 .clist_gset:N = \g__xeCJK_inline_env_clist , + InlineEnv .code:n = + { + \seq_set_from_clist:Nn \l__xeCJK_inline_env_seq {#1} + \__xeCJK_update_inline_env_case_tl: + } , InlineEnv+ .code:n = { - \clist_gput_right:Nx \g__xeCJK_inline_env_clist {#1} - \clist_gremove_duplicates:N \g__xeCJK_inline_env_clist + \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:xn {#1} - { \clist_gremove_all:Nn \g__xeCJK_inline_env_clist {##1} } + \clist_map_inline:nn {#1} + { \seq_remove_all:Nn \l__xeCJK_inline_env_seq {##1} } + \__xeCJK_update_inline_env_case_tl: } } -\cs_generate_variant:Nn \clist_map_inline:nn { x } +\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} { \use_ii:nn } } } + } +\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 > { \TrimSpaces } m } @@ -881,7 +1151,7 @@ { \clist_map_inline:nn {#1} { - \int_if_exist:cTF { c__xeCJK_ CJK/##1 _class_int } + \int_if_exist:cTF { \__xeCJK_class_csname:n { CJK/##1 } } { \xeCJK_declare_char_class:nx { CJK \bool_if:NF \l__xeCJK_sub_cancel_bool { /##1 } } @@ -899,11 +1169,11 @@ } \cs_new_protected_nopar:Npn \xeCJK_declare_sub_char_class:nnn #1#2#3 { - \int_if_exist:cF { c__xeCJK_ #1/#2 _class_int } + \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_new_sub_key:n {#2} } \xeCJK_declare_char_class:nn { #1/#2 } {#3} } @@ -956,6 +1226,7 @@ } \NewDocumentCommand \xeCJKsetwidth { m m } { \tl_map_inline:xn {#1} { \tl_gset:cn { g__xeCJK_punct_width/##1/tl } {#2} } } +\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} } \tl_const:Nn \c__xeCJK_left_tl { left } @@ -1017,13 +1288,13 @@ } \prg_new_conditional:Npnn \__xeCJK_punct_if_right:N #1 { p , T , F , TF } { - \if_int_compare:w \xeCJK_value_class:n {`#1} = \xeCJK_class_num:n { FullRight } + \if_int_compare:w \xeCJK_token_value_class:N #1 = \xeCJK_class_num:n { FullRight } \prg_return_true: \else: \prg_return_false: \fi: } -\cs_generate_variant:Nn \prg_new_conditional:Npnn { c } \clist_map_inline:Nn \g__xeCJK_special_punct_clist { - \prg_new_conditional:cpnn { __xeCJK_punct_if_#1:N } ##1 { p , T , F , TF } + \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: @@ -1045,8 +1316,8 @@ { \tl_gset:cx { \__xeCJK_punct_dim_csname:nnn {#1} {#2} {#3} } {#4} } \cs_new_protected_nopar:Npn \__xeCJK_gset_punct_dim:nnnnx #1#2#3#4#5 { \tl_gset:cx { \__xeCJK_punct_dim_csname:nnnn {#1} {#2} {#3} {#4} } {#5} } -\DeclareObjectType { xeCJK / punctuation } { 3 } -\DeclareTemplateInterface { xeCJK / punctuation } { basic } { 3 } +\DeclareObjectType { xeCJK / punctuation } { \c_three } +\DeclareTemplateInterface { xeCJK / punctuation } { basic } { \c_three } { enabled-global-setting : boolean = true , fixed-punct-width : length = \c_max_dim , @@ -1077,7 +1348,7 @@ kerning-margin-ratio : real = \c_one_fp , kerning-margin-minimum : length = \c_zero_dim } -\DeclareTemplateCode { xeCJK / punctuation } { basic } { 3 } +\DeclareTemplateCode { xeCJK / punctuation } { basic } { \c_three } { enabled-global-setting = \l__xeCJK_enabled_global_setting_bool , fixed-punct-width = \l__xeCJK_fixed_punct_width_dim , @@ -1367,7 +1638,7 @@ ( \__xeCJK_use_punct_dim:nnn { bound } \c__xeCJK_right_tl {#1} ) } \__xeCJK_gset_punct_dim:nnx { width } {#1} - { \dim_use:N \etex_fontcharwd:D \tex_font:D `#1 } + { \dim_use:N \etex_fontcharwd:D \tex_font:D \xeCJK_token_value_charcode:N #1 } \__xeCJK_gset_punct_dim:nnx { dimen } {#1} { \dim_eval:n { \__xeCJK_use_punct_dim:nn { width } {#1} - \l__xeCJK_tmp_dim } } \__xeCJK_punct_if_long:NT {#1} @@ -1389,7 +1660,10 @@ } \cs_generate_variant:Nn \xeCJK_calc_punct_dimen:N { f } \cs_new_nopar:Npn \xeCJK_glyph_bounds:NN #1#2 - { \dim_use:N \XeTeXglyphbounds #1 ~ \XeTeXcharglyph `#2 \exp_stop_f: } + { + \dim_use:N \XeTeXglyphbounds #1 ~ + \XeTeXcharglyph \xeCJK_token_value_charcode:N #2 \exp_stop_f: + } \cs_new_protected_nopar:Npn \xeCJK_get_punct_kerning:NN #1#2 { \tl_if_exist:cF { \__xeCJK_punct_dim_csname:nnn { kern } {#1} {#2} } @@ -1475,29 +1749,22 @@ \keys_define:nn { xeCJK / options } { AutoFallBack .choice: , - AutoFallBack / true .code:n = { \xeCJKenablefallback } , - AutoFallBack / false .code:n = { \xeCJKdisablefallback } , - AutoFallBack .default:n = { true } , - fallback .meta:n = { AutoFallBack = true } - } -\NewDocumentCommand \xeCJKenablefallback { } - { - \bool_if:NF \l__xeCJK_fallback_bool + AutoFallBack / true .code:n = { - \bool_set_true:N \l__xeCJK_fallback_bool - \cs_set_eq:NN \__xeCJK_fallback_save_CJKsymbol:N \CJKsymbol - \cs_set_eq:NN \CJKsymbol \xeCJK_fallback_test_glyph:N - } - } -\NewDocumentCommand \xeCJKdisablefallback { } - { - \bool_if:NT \l__xeCJK_fallback_bool + \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 = { - \bool_set_false:N \l__xeCJK_fallback_bool - \cs_set_eq:NN \CJKsymbol \__xeCJK_fallback_save_CJKsymbol: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 } } -\bool_new:N \l__xeCJK_fallback_bool \cs_new_protected_nopar:Npn \xeCJK_fallback_test_glyph:N #1 { \xeCJK_glyph_if_exist:NTF {#1} @@ -1514,7 +1781,8 @@ { \xeCJK_fallback_loop:Nn {#1} { #2/FallBack } } } { - \__xeCJK_warning:nxx { fallback } {#1} {#2} + \xeCJK_family_if_exist:xT { \l_xeCJK_family_tl/FallBack } + { \__xeCJK_warning:nxx { fallback } {#1} {#2} } \__xeCJK_fallback_save_CJKsymbol:N {#1} } } @@ -1524,6 +1792,7 @@ ( \prop_get:No \g__xeCJK_family_font_name_prop {#2} )~ does~not~contain~glyph~'#1'~(U+\int_to_hexadecimal:n {`#1}).\\ } +\bool_new:N \l__xeCJK_fallback_first_bool \cs_generate_variant:Nn \prop_get:Nn { No } \NewDocumentCommand \setCJKfallbackfamilyfont { m O{} m } { @@ -1582,7 +1851,7 @@ slantfont .meta:n = { AutoFakeSlant = true } } \seq_new:N \g__xeCJK_sub_key_seq -\cs_new_protected_nopar:Npn \__xeCJK_new_sub_key:n #1 +\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 } @@ -1612,7 +1881,6 @@ #1 .default:n = { } } } -\cs_generate_variant:Nn \__xeCJK_new_sub_key:n { x } \cs_new_protected_nopar:Npn \__xeCJK_get_sub_features:nn #1#2 { \tl_set:Nx \l__xeCJK_tmpa_tl { \xeCJK_tl_remove_outer_braces:n {#2} } @@ -1643,7 +1911,7 @@ \cs_generate_variant:Nn \__xeCJK_get_sub_features:nn { V } \cs_generate_variant:Nn \tl_if_head_eq_meaning:nNTF { V } \cs_generate_variant:Nn \tl_replace_all:Nnn { NnV } -\__xeCJK_new_sub_key:n { FallBack } +\xeCJK_new_sub_key:n { FallBack } \prop_new:N \g__xeCJK_features_id_prop \prop_put:Nnn \g__xeCJK_features_id_prop { bf } { Bold } \prop_put:Nnn \g__xeCJK_features_id_prop { it } { Italic } @@ -1681,7 +1949,6 @@ } \cs_new_protected_nopar:Npn \__xeCJK_set_family_initial: { - \__xeCJK_gobble_CJKfamily: \int_gincr:N \g__xeCJK_family_int \prop_clear:N \l__xeCJK_add_font_prop \prop_map_inline:Nn \g__xeCJK_features_id_prop @@ -1745,7 +2012,8 @@ \cs_gset_protected_nopar:cpx { \__xeCJK_family_csname:n {#1} } { \group_begin: - \__xeCJK_gobble_CJKfamily: + \cs_set_eq:NN + \exp_not:n { \__xeCJK_update_family:n \use_none:n } \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 } @@ -1870,7 +2138,7 @@ } } \prop_map_inline:Nn \l__xeCJK_add_font_prop - { \clist_put_right:Nn \l__xeCJK_fontspec_options_clist { ##1 = { ##2 } } } + { \clist_put_right:Nn \l__xeCJK_fontspec_options_clist { ##1 = {##2} } } } \prop_new:N \g__xeCJK_family_name_prop \prop_new:N \g__xeCJK_family_font_name_prop @@ -1991,7 +2259,8 @@ { \__xeCJK_copy_family:xx { \l_xeCJK_family_tl/#1 } { - \cs_if_exist:cTF { \__xeCJK_family_csname:n { \CJKfamilydefault/#1 } } + \cs_if_exist:cTF + { \__xeCJK_family_csname:n { \CJKfamilydefault/#1 } } { \CJKfamilydefault/#1 } { \l_xeCJK_family_tl } } } @@ -2007,8 +2276,8 @@ \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 } - \exp_not:N \fontfamily {#2} + \tl_set:Nx \exp_not:N \f@encoding { \c__xeCJK_encoding_tl } + \tl_set:Nx \exp_not:N \f@family {#2} \exp_not:N \selectfont } } @@ -2179,6 +2448,16 @@ \prop_if_empty:NTF \g__xeCJK_family_font_name_prop { \__xeCJK_warning:n { no-CJKfamily } } { + \tl_gset:Nx \CJKfamilydefault + { + \str_case_x:nnn { \familydefault } + { + { \rmdefault } { \CJKrmdefault } + { \sfdefault } { \CJKsfdefault } + { \ttdefault } { \CJKttdefault } + } + { \CJKfamilydefault } + } \CJKfamily { \CJKfamilydefault } \bool_if:NT \g__xeCJK_math_bool { \xeCJK_set_mathfont: } } @@ -2239,16 +2518,16 @@ \bool_if:NF \l__xeCJK_verb_addon_bool { \bool_set_true:N \l__xeCJK_verb_addon_bool - \__xeCJK_set_char_class_eq:nn { CJK } { FullLeft } - \__xeCJK_set_char_class_eq:nn { CJK } { FullRight } - \__xeCJK_set_char_class_eq:nn { Default } { HalfLeft } - \__xeCJK_set_char_class_eq:nn { Default } { HalfRight } - \__xeCJK_set_char_class_eq:nn { Default } { NormalSpace } + \__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 } \xeCJKsetup { xCJKecglue = false } \cs_set_protected_nopar:Npn \CJKglue { \skip_horizontal:N \g__xeCJK_verb_exspace_skip } \cs_set_protected_nopar:Npn \CJKecglue - { \skip_horizontal:N 0.5 \g__xeCJK_verb_exspace_skip } + { \skip_horizontal:n { 0.5 \g__xeCJK_verb_exspace_skip } } \cs_set_eq:NN \xeCJK_check_for_glue: \CJKecglue \cs_set_eq:NN \xeCJK_ignore_spaces:w \CJKecglue \skip_set:Nn \tex_rightskip:D { \c_zero_dim plus 1 fil } @@ -2257,24 +2536,29 @@ } \bool_new:N \l__xeCJK_verb_addon_bool \cs_new_eq:NN \CJKfixedspacing \xeCJKVerbAddon -\__xeCJK_after_preamble:n - { \xeCJK_cs_add:Nnn \verbatim@font { } { \xeCJKVerbAddon } } +\__xeCJK_after_preamble:n { \tl_put_right:Nn \verbatim@font { \xeCJKVerbAddon } } \cs_new_protected_nopar:Npn \__xeCJK_set_verb_exspace: { - \tl_if_exist:cTF { xeCJK/verb/\curr@fontshape/\f@size } - { - \skip_gset:Nn \g__xeCJK_verb_exspace_skip - { \tl_use:c { xeCJK/verb/\curr@fontshape/\f@size } } - } + \tl_if_exist:cF { xeCJK/verb/\l_xeCJK_family_tl/\curr@fontshape/\f@size } { - \skip_gset:Nn \g__xeCJK_verb_exspace_skip + \group_begin: + \xeCJK_select_font: + \use:x { - \dim_max:nn - { \c_zero_dim } - { \c_two \tex_fontdimen:D \c_two \tex_font:D - \f@size pt } + \group_end: + \tl_gset:cx + \exp_not:n { { xeCJK/verb/\l_xeCJK_family_tl/\curr@fontshape/\f@size } } + { + \exp_not:N \dim_max:nn { \c_zero_dim } + { + \c_two \tex_fontdimen:D \c_two \tex_font:D - + \dim_use:N \etex_fontcharwd:D \tex_font:D "4E00 + } + } } - \tl_gset:cV { xeCJK/verb/\curr@fontshape/\f@size } \g__xeCJK_verb_exspace_skip } + \skip_gset:Nn \g__xeCJK_verb_exspace_skip + { \use:c { xeCJK/verb/\l_xeCJK_family_tl/\curr@fontshape/\f@size } } } \skip_new:N \g__xeCJK_verb_exspace_skip \cs_new_protected_nopar:Npn \xeCJK_visible_space_fallback: @@ -2285,30 +2569,34 @@ } } \AtEndOfPackage { - \xeCJK_cs_add:Nnn \fontspec_visible_space: { \scan_stop: } { } + \tl_put_left:Nn \fontspec_visible_space: { \scan_stop: } \cs_gset_eq:NN \fontspec_visible_space_fallback: \xeCJK_visible_space_fallback: } \cs_new_protected_nopar:Npn \xeCJK_set_visible_space_font: { \tl_set:Nx \l__xeCJK_current_coor_tl { xeCJK/space/\curr@fontshape/\f@size } - \dim_set:Nn \l__xeCJK_tmp_dim { \tex_fontdimen:D \c_two \tex_font:D } - \fontencoding { \g_fontspec_encoding_tl } - \fontfamily { lmtt } + \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 + { + \tl_set:Nx \f@encoding { \g_fontspec_encoding_tl } + \tl_set:Nx \f@family { lmtt } \selectfont - \dim_compare:nNnF \l__xeCJK_tmp_dim = { \tex_fontdimen:D \c_two \tex_font:D } + \dim_compare:nNnF {#1} = { \tex_fontdimen:D \c_two \tex_font:D } { \fontsize { \dim_eval:n { - \f@size pt * \dim_ratio:nn - { \l__xeCJK_tmp_dim } { \tex_fontdimen:D \c_two \tex_font:D } + \f@size pt * + \dim_ratio:nn {#1} { \tex_fontdimen:D \c_two \tex_font:D } } } { \f@baselineskip } \selectfont } - \xeCJK_font_gset_to_current:c { \l__xeCJK_current_coor_tl } } \keys_define:nn { xeCJK / options } { @@ -2368,9 +2656,11 @@ \keys_set:nn { xeCJK / options } { CJKglue = { \skip_horizontal:n { \c_zero_dim plus 0.08 \tex_baselineskip:D } } , - CJKecglue = \c_space_token , + CJKecglue = { ~ } , xCJKecglue = false , CheckSingle = false , + PlainEquation = false , + CheckFullRight = false , CJKspace = false , CJKmath = false , CJKnumber = false , @@ -2380,6 +2670,9 @@ EmboldenFactor = 4 , SlantFactor = 0.167 , PunctStyle = quanjiao , + NewLineCS = { \par \[ } , + EnvCS = { \begin \end } , + NoBreakCS = { \footnote \footnotemark \nobreak } , KaiMingPunct = { ^^^^3002 ^^^^ff0e ^^^^ff1f ^^^^ff01 } , LongPunct = { ^^^^2014 ^^^^2015 ^^^^2500 ^^^^2025 ^^^^2026 } , MiddlePunct = { ^^^^2014 ^^^^2015 ^^^^2500 ^^^^00b7 ^^^^30fb ^^^^ff65 } , @@ -2407,7 +2700,7 @@ \tl_if_exist:NF \CJKttdefault { \tl_gset:Nn \CJKttdefault { tt } } \tl_if_exist:NF \CJKfamilydefault { \tl_gset:Nn \CJKfamilydefault { \CJKrmdefault } } \tl_new:c { \__xeCJK_family_csname:n { \CJKfamilydefault } } -\NewDocumentCommand \xeCJKsetup { m } +\NewDocumentCommand \xeCJKsetup { +m } { \keys_set:nn { xeCJK / options } {#1} \tex_ignorespaces:D @@ -2426,16 +2719,62 @@ { \xeCJKsetup { AllowBreakBetweenPuncts = true } } \NewDocumentCommand \xeCJKnobreakbetweenpuncts { } { \xeCJKsetup { AllowBreakBetweenPuncts = false } } -\xeCJK_cs_add:Nnn \rmfamily { \CJKfamily { \CJKrmdefault } } { } -\xeCJK_cs_add:Nnn \sffamily { \CJKfamily { \CJKsfdefault } } { } -\xeCJK_cs_add:Nnn \ttfamily { \CJKfamily { \CJKttdefault } } { } -\xeCJK_cs_add:Nnn \normalfont { \CJKfamily { \CJKfamilydefault } } { } -\cs_set_eq:NN \reset@font \normalfont -\xeCJK_cs_add:Nnn \fontspec_init: { \__xeCJK_gobble_CJKfamily: } { } +\NewDocumentCommand \xeCJKenablefallback { } + { \xeCJKsetup { AutoFallBack = true } } +\NewDocumentCommand \xeCJKdisablefallback { } + { \xeCJKsetup { AutoFallBack = false } } +\NewDocumentCommand \xeCJKsetcharclass { m m m } + { + \xeCJK_set_char_class:nnn {#1} {#2} {#3} + \xeCJKResetPunctClass + } +\__xeCJK_msg_new:nn { conflict-package } + { + The~`#1'~package~is~in~conflict~with~xeCJK. \\ + Please~do~not~use~it~or~load~it~after~xeCJK. + } +\xeCJK_if_package_loaded:nTF { realscripts } + { + \@ifpackagelater { realscripts } { 2010/10/10 } { } + { \__xeCJK_error:nx { conflict-package } { xltxtra } } + } + { + \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:n + { + \str_case_x:nnn {#1} + { + { \rmdefault } { \CJKfamily { \CJKrmdefault } } + { \sfdefault } { \CJKfamily { \CJKsfdefault } } + { \ttdefault } { \CJKfamily { \CJKttdefault } } + { \familydefault } { \CJKfamily { \CJKfamilydefault } } + } + { } + } + } +\cs_new_eq:NN \__xeCJK_update_family:n \use:n \cs_new_eq:NN \xeCJK@fix@penalty \fix@penalty -\xeCJK_cs_patch:Nnn \xeCJK@fix@penalty \@@italiccorr \xeCJK@patch@italiccorr -\xeCJK_cs_patch:Nnn \sw@slant \fix@penalty \xeCJK@fix@penalty -\cs_new_protected_nopar:Npn \xeCJK@patch@italiccorr +\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 \XeTeXinterchartokenstate > \c_zero { @@ -2472,18 +2811,18 @@ \__xeCJK_after_end_preamble:n { \int_compare:nNnF - { \c_three + ( \seq_count:N \g__xeCJK_class_seq ) } = \xe@alloc@intercharclass + { \c_three + \seq_count:N \g__xeCJK_new_class_seq } = \xe@alloc@intercharclass { \int_step_inline:nnnn \c_four \c_one \xe@alloc@intercharclass { - \seq_if_in:NnF \g__xeCJK_class_seq {#1} + \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:Nn \c__xeCJK_Others_class_int {#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 } @@ -2506,7 +2845,6 @@ } } } -\cs_new_eq:NN \c__xeCJK_Others_class_int \l__xeCJK_tmpa_int \__xeCJK_after_preamble:n { \tl_map_inline:nn @@ -2514,18 +2852,16 @@ \textellipsis \textemdash \textperiodcentered \textcentereddot \textquoteleft \textquoteright \textquotedblleft \textquotedblright } - { - \xeCJK_cs_add:Nnn #1 - { \__xeCJK_group_begin: \makexeCJKinactive } { \__xeCJK_group_end: } - } - \xeCJK_cs_add:Nnn \tipaencoding { \makexeCJKinactive } { } + { \cs_gset_nopar:Npx #1 { { \makexeCJKinactive \exp_not:o {#1} } } } + \tl_put_left:Nn \tipaencoding { \makexeCJKinactive } \cs_new_eq:NN \__xeCJK_aux_r:n \r \cs_set_nopar:Npn \r #1 { { \makexeCJKinactive \__xeCJK_aux_r:n {#1} } } \xeCJK_if_package_loaded:nT { pifont } - { \xeCJK_cs_add:Nnn \Pifont { \makexeCJKinactive } { } } + { + \RenewDocumentCommand \Pifont { m } + { \makexeCJKinactive \usefont { U } {#1} { m } { n } } + } } -\cs_new_eq:NN \__xeCJK_group_begin: \group_begin: -\cs_new_eq:NN \__xeCJK_group_end: \group_end: \__xeCJK_after_end_preamble:n { \xeCJK_if_package_loaded:nT { hyperref } @@ -2534,8 +2870,6 @@ { \__xeCJK_gobble_CJKfamily: \xeCJK_cs_clear:N \makexeCJKinactive - \xeCJK_cs_clear:N \__xeCJK_group_begin: - \xeCJK_cs_clear:N \__xeCJK_group_end: } } } @@ -2546,6 +2880,7 @@ { \exp_after:wN \tex_let:D \cs:w cprotect \cs_end: \icprotect } } \tl_set:cn { ver@CJK.sty } { 9999/99/99 } +\tl_set_eq:cc { ver@CJKulem.sty } { ver@CJK.sty } \tl_set_eq:cc { ver@CJKpunct.sty } { ver@CJK.sty } \cs_if_exist:NF \CJK@ifundefined { \cs_set_eq:NN \CJK@ifundefined \cs_if_free:NTF } @@ -2560,44 +2895,22 @@ } \XeTeXdefaultencoding "UTF-8" } -\cs_new_protected_nopar:Npn \xeCJK_hook_for_ulem: +\cs_if_eq:NNTF \ifCTEX@fntef \tex_iftrue:D + { \RequirePackage { xeCJKfntef } } { - \bool_if:NF \l__xeCJK_ulem_hook_used_bool + \__xeCJK_at_end_preamble:n { - \bool_set_true:N \l__xeCJK_ulem_hook_used_bool - \xeCJK_cs_clear:N \__xeCJK_CJK_FullLeft_glue: - \cs_set_protected_nopar:Npn \__xeCJK_FullLeft_ulem_hook: { { \CJKglue } } - \xeCJK_swap_cs:NN \CJKsymbol \__xeCJK_ulem_CJKsymbol:N - \xeCJK_swap_cs:NN \CJKpunctsymbol \__xeCJK_ulem_CJKpunctsymbol:N - } - } -\bool_new:N \l__xeCJK_ulem_hook_used_bool -\__xeCJK_after_preamble:n - { - \xeCJK_if_package_loaded:nT { ulem } - { - \xeCJK_cs_gclear:N \__xeCJK_FullLeft_ulem_hook: - \xeCJK_pre_inter_class_toks:nnn { Boundary } { FullLeft } - { \__xeCJK_FullLeft_ulem_hook: } - \cs_if_exist:NTF \XeTeX@CJKfntef@hook + \xeCJK_if_package_loaded:nF { xeCJKfntef } { - \xeCJK_cs_gclear:N \CJKf@global - \AtBeginEnvironment - { CJKfilltwosides } { \cs_set_eq:NN \CJKglue \tex_hfil:D } - \cs_set_protected_nopar:Npn \XeTeX@CJKfntef@hook - { \xeCJK_select_font: \makexeCJKinactive } + \xeCJK_if_package_loaded:nTF { CJKfntef } + { \RequirePackage { xeCJKfntef } } + { + \xeCJK_if_package_loaded:nT { ulem } + { \RequirePackage { xeCJKfntef } } + } } - { \RequirePackage { CJKulem } } - \addto@hook \UL@hook { \xeCJK_hook_for_ulem: } } } -\cs_new_protected_nopar:Npn \__xeCJK_ulem_CJKsymbol:N #1 - { - { \__xeCJK_ulem_CJKsymbol:N {#1} } - { \xeCJK_make_node:n { CJK } } \xeCJK_ignore_spaces:w - } -\cs_new_protected_nopar:Npn \__xeCJK_ulem_CJKpunctsymbol:N #1 - { { \__xeCJK_ulem_CJKpunctsymbol:N {#1} } \tex_ignorespaces:D } \bool_if:NT \g__xeCJK_number_bool { \tl_set:Nn \CJK@UnicodeEnc { UTF8 } @@ -2622,6 +2935,7 @@ %% xeCJK.sty, %% xeCJK.cfg, %% xeCJK.ins, +%% xeCJKfntef.sty, %% xeCJK-example-autofake.tex, %% xeCJK-example-fallback.tex, %% xeCJK-example-subCJKblock.tex, diff --git a/Master/texmf-dist/tex/xelatex/xecjk/xeCJKfntef.sty b/Master/texmf-dist/tex/xelatex/xecjk/xeCJKfntef.sty new file mode 100644 index 00000000000..6d3e152a498 --- /dev/null +++ b/Master/texmf-dist/tex/xelatex/xecjk/xeCJKfntef.sty @@ -0,0 +1,339 @@ +%% +%% This is file `xeCJKfntef.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% xeCJK.dtx (with options: `fntef') +%% +%% $Id: xeCJK.dtx 382 2012-12-13 04:58:22Z sobenlee $ +%% $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $ +%% ----------------------------------------------------------------- +%% Author: +%% Wenchang Sun <sunwch@nankai.edu.cn> +%% Current Maintainers: +%% Leo Liu <leoliu.pku@gmail.com> +%% Qing Lee <sobenlee@gmail.com> +%% +%% Copyright (C) 2007--2012 Wenchang Sun +%% +%% This file may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either version 1.3 +%% of this license or (at your option) any later version. +%% 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 Maintainer of this work are Leo Liu and Qing Lee. +%% ----------------------------------------------------------------- +%% +\NeedsTeXFormat{LaTeX2e} +\RequirePackage{expl3} +\GetIdInfo$Id: xeCJK.dtx 382 2012-12-13 04:58:22Z sobenlee $ + {xeCJK patch file for ulem/CJKfntef} +\ProvidesExplPackage + {xeCJKfntef} + {\ExplFileDate}{3.1.1}{\ExplFileDescription} +\PassOptionsToPackage { normalem } { ulem } +\DeclareOption* { \PassOptionsToPackage { \CurrentOption } { ulem } } +\ProcessOptions \scan_stop: +\@ifpackageloaded { xeCJK } + { } + { \RequirePackage { xeCJK } } +\RequirePackage { ulem } +\RequirePackage { CJKfntef } +\addto@hook \UL@hook { \xeCJK_hook_for_ulem: } +\cs_new_protected_nopar:Npn \xeCJK_hook_for_ulem: + { + \bool_if:NF \l__xeCJK_ulem_hook_used_bool + { + \bool_set_true:N \l__xeCJK_ulem_hook_used_bool + \xeCJKsetup { CheckFullRight = false } + \bool_if:NTF \l__xeCJK_ulem_skip_punct_bool + { \cs_set_eq:NN \__xeCJK_ulem_leader_type: \UL@leadtype } + { + \xeCJK_cs_clear:N \__xeCJK_ulem_skip_punct_begin: + \xeCJK_cs_clear:N \__xeCJK_ulem_skip_punct_end: + } + \__xeCJK_ulem_initial: + \xeCJK_glue_to_skip:nN + { + \cs_set_eq:NN \ \tex_space:D + \cs_set_eq:NN \penalty \tex_penalty:D + \cs_set_eq:NN \hskip \skip_horizontal:N + \CJKglue + } \l__xeCJK_ccglue_skip + \xeCJK_glue_to_skip:nN + { + \cs_set_eq:NN \ \tex_space:D + \cs_set_eq:NN \penalty \tex_penalty:D + \cs_set_eq:NN \hskip \skip_horizontal:N + \CJKecglue + } \l__xeCJK_ecglue_skip + \cs_set_protected_nopar:Npn \CJKglue + { \__xeCJK_ulem_glue:n \l__xeCJK_ccglue_skip } + \cs_set_protected_nopar:Npn \CJKecglue + { \__xeCJK_ulem_glue:n \l__xeCJK_ecglue_skip } + } + } +\bool_new:N \l__xeCJK_ulem_hook_used_bool +\cs_set_eq:NN \CJK@UL \CJK@@UL +\tl_replace_once:Nnn \CJK@UL { \ULon } + { \bool_set_true:N \l__xeCJK_ulem_skip_punct_bool \ULon } +\tl_replace_once:Nnn \CJK@@UL { \ULon } + { \bool_set_false:N \l__xeCJK_ulem_skip_punct_bool \ULon } +\bool_new:N \l__xeCJK_ulem_skip_punct_bool +\cs_new_protected_nopar:Npn \__xeCJK_ulem_skip_punct_begin: + { \xeCJK_cs_clear:N \UL@leadtype } +\cs_new_protected_nopar:Npn \__xeCJK_ulem_skip_punct_end: + { \cs_set_eq:NN \UL@leadtype \__xeCJK_ulem_leader_type: } +\xeCJK_cs_clear:N \__xeCJK_ulem_leader_type: +\cs_new_protected_nopar:Npn \__xeCJK_ulem_initial: + { + \cs_set_eq:NN \__xeCJK_punct_hskip:n \__xeCJK_ulem_hskip:n + \cs_set_eq:NN + \__xeCJK_Default_and_FullLeft_glue:N \__xeCJK_ulem_Default_and_FullLeft_glue:N + \cs_set_eq:NN + \__xeCJK_Default_and_FullRight_glue:N \__xeCJK_ulem_Default_and_FullRight_glue:N + \cs_set_eq:NN + \__xeCJK_CJK_and_FullLeft_glue:N \__xeCJK_ulem_CJK_and_FullLeft_glue:N + \cs_set_eq:NN + \__xeCJK_CJK_and_FullRight_glue:N \__xeCJK_ulem_CJK_and_FullRight_glue:N + \cs_set_eq:NN + \__xeCJK_Boundary_and_FullLeft_glue:N \__xeCJK_ulem_Boundary_and_FullLeft_glue:N + \cs_set_eq:NN \xeCJK_FullLeft_and_Default: \__xeCJK_ulem_FullLeft_and_Default: + \cs_set_eq:NN \xeCJK_FullLeft_and_CJK: \__xeCJK_ulem_FullLeft_and_CJK: + \cs_set_eq:NN \xeCJK_FullRight_and_Default: \__xeCJK_ulem_FullRight_and_Default: + \cs_set_eq:NN \xeCJK_FullRight_and_CJK: \__xeCJK_ulem_FullRight_and_CJK: + \cs_set_eq:NN \xeCJK_CJK_and_CJK:N \__xeCJK_ulem_CJK_and_CJK:N + \seq_map_inline:Nn \g__xeCJK_CJK_sub_class_seq + { + \seq_map_inline:Nn \g__xeCJK_CJK_sub_class_seq + { + \str_if_eq:nnTF {##1} {####1} + { + \xeCJK_inter_class_toks:nnn { CJK } { CJK/##1 } + { \__xeCJK_ulem_between_CJK_blocks:nnN { CJK } {##1} } + \xeCJK_inter_class_toks:nnn { CJK/##1 } { CJK/##1 } + { \__xeCJK_ulem_between_CJK_blocks:nnN { CJK } {##1} } + } + { + \xeCJK_inter_class_toks:nnn { CJK/##1 } { CJK/####1 } + { \__xeCJK_ulem_between_CJK_blocks:nnN {##1} {####1} } + } + } + } + } +\cs_new_protected_nopar:Npn \__xeCJK_ulem_CJK_and_CJK:N + { + \xeCJK_class_group_end: + \UL@stop \__xeCJK_ulem_ccglue: \UL@start + \__xeCJK_ulem_class_group_begin: + \CJKsymbol + } +\cs_new_protected_nopar:Npn \__xeCJK_ulem_class_group_begin: + { + \xeCJK_class_group_begin: + \xeCJK_clear_Boundary_and_CJK_toks: + \xeCJK_select_font: + } +\cs_new_protected_nopar:Npn \__xeCJK_ulem_between_CJK_blocks:nnN #1#2 + { + \xeCJK_class_group_end: + \UL@stop \__xeCJK_ulem_ccglue: \UL@start + \xeCJK_class_group_begin: + \xeCJK_clear_Boundary_and_CJK_toks: + \__xeCJK_switch_font:nn {#1} {#2} + \CJKsymbol + } +\cs_new_protected_nopar:Npn \__xeCJK_ulem_Default_and_FullLeft_glue:N #1 + { + \UL@stop + \__xeCJK_ulem_skip_punct_begin: + \__xeCJK_punct_glue:NN \c__xeCJK_left_tl {#1} + \UL@start + } +\cs_new_protected_nopar:Npn \__xeCJK_ulem_Boundary_and_FullLeft_glue:N #1 + { + \UL@stop + \__xeCJK_ulem_skip_punct_begin: + \int_compare:nNnF \etex_lastnodetype:D = \c_one + { \__xeCJK_punct_glue:NN \c__xeCJK_left_tl {#1} } + \UL@start + } +\cs_new_protected_nopar:Npn \__xeCJK_ulem_CJK_and_FullLeft_glue:N #1 + { + \xeCJK_class_group_end: + \UL@stop + \__xeCJK_ulem_skip_punct_begin: + \__xeCJK_ulem_ccglue: + \__xeCJK_punct_glue:NN \c__xeCJK_left_tl {#1} + \UL@start + \__xeCJK_ulem_class_group_begin: + } +\cs_new_protected_nopar:Npn \__xeCJK_ulem_Default_and_FullRight_glue:N #1 + { + \UL@stop + \__xeCJK_ulem_skip_punct_begin: + \__xeCJK_punct_if_long:NTF {#1} + { \__xeCJK_ulem_ccglue: } + { + \__xeCJK_punct_if_middle:NT {#1} + { + \xeCJK_no_break: + \__xeCJK_punct_glue:NN \c__xeCJK_right_tl {#1} + } + \xeCJK_no_break: + } + \UL@start + } +\cs_new_protected_nopar:Npn \__xeCJK_ulem_CJK_and_FullRight_glue:N #1 + { + \xeCJK_class_group_end: + \__xeCJK_ulem_Default_and_FullRight_glue:N {#1} + \__xeCJK_ulem_class_group_begin: + } +\cs_new_protected_nopar:Npn \__xeCJK_ulem_FullLeft_and_Default: + { + \__xeCJK_punct_if_middle:NTF \g__xeCJK_last_punct_tl + { + \xeCJK_get_punct_bounds:NN \c__xeCJK_left_tl \g__xeCJK_last_punct_tl + \__xeCJK_punct_rule:NN \c__xeCJK_right_tl \g__xeCJK_last_punct_tl + \xeCJK_class_group_end: \UL@stop \xeCJK_no_break: + \__xeCJK_punct_glue:NN \c__xeCJK_left_tl \g__xeCJK_last_punct_tl + } + { \xeCJK_class_group_end: \UL@stop } + \__xeCJK_ulem_skip_punct_end: + \xeCJK_no_break: + \UL@start + } +\cs_new_protected_nopar:Npn \__xeCJK_ulem_FullLeft_and_CJK: + { + \__xeCJK_ulem_FullLeft_and_Default: + \__xeCJK_ulem_class_group_begin: + } +\cs_new_protected_nopar:Npn \__xeCJK_ulem_FullRight_and_Default: + { + \__xeCJK_punct_rule:NN \c__xeCJK_right_tl \g__xeCJK_last_punct_tl + \xeCJK_class_group_end: + \UL@stop + \__xeCJK_punct_glue:NN \c__xeCJK_right_tl \g__xeCJK_last_punct_tl + \__xeCJK_ulem_skip_punct_end: + \UL@start + } +\cs_new_protected_nopar:Npn \__xeCJK_ulem_FullRight_and_CJK: + { + \__xeCJK_punct_rule:NN \c__xeCJK_right_tl \g__xeCJK_last_punct_tl + \xeCJK_class_group_end: + \UL@stop + \__xeCJK_punct_glue:NN \c__xeCJK_right_tl \g__xeCJK_last_punct_tl + \__xeCJK_ulem_ccglue: + \__xeCJK_ulem_skip_punct_end: + \UL@start + \__xeCJK_ulem_class_group_begin: + } +\cs_new_protected_nopar:Npn \__xeCJK_ulem_glue:n #1 + { + \cs_if_eq:NNTF \ \LA@space + { \skip_horizontal:n {#1} } + { \UL@stop \__xeCJK_ulem_hskip:n {#1} \UL@start } + } +\cs_new_protected_nopar:Npn \__xeCJK_ulem_ccglue: + { \skip_set_eq:NN \UL@skip \l__xeCJK_ccglue_skip \UL@leaders } +\cs_new_protected_nopar:Npn \__xeCJK_ulem_hskip:n #1 + { + \int_compare:nNnTF \tex_lastkern:D = \c_three + { \skip_horizontal:n {#1} } + { \skip_set:Nn \UL@skip {#1} \UL@leaders } + } +\RenewDocumentCommand \CJKunderdot { m } + { + \bool_if:NT \l__xeCJK_ulem_hook_used_bool { \UL@stop } + \CJK@preUnderdot + \__xeCJK_make_under_symbol:n { \CJK@underdotSkip } + \cs_gset_eq:NN \__xeCJK_save_under_dot_CJKsymbol:N \CJKsymbol + \cs_set_eq:NN \CJKsymbol \__xeCJK_under_CJKsymbol:N + \bool_if:NT \l__xeCJK_ulem_hook_used_bool { \UL@start } + #1 + \bool_if:NT \l__xeCJK_ulem_hook_used_bool { \UL@stop } + \cs_set_eq:NN \CJKsymbol \__xeCJK_save_under_dot_CJKsymbol:N + \CJK@postUnderdot + \bool_if:NT \l__xeCJK_ulem_hook_used_bool { \UL@start } + \tex_ignorespaces:D + } +\box_new:N \g__xeCJK_under_symbol_box +\RenewDocumentCommand \CJKunderanysymbol { m m m } + { + \group_begin: + \hbox_set:Nn \CJK@underdotBox {#2} + \__xeCJK_make_under_symbol:n {#1} + \cs_gset_eq:NN \__xeCJK_save_under_dot_CJKsymbol:N \CJKsymbol + \cs_set_eq:NN \CJKsymbol \__xeCJK_under_CJKsymbol:N + #3 + \group_end: + \tex_ignorespaces:D + } +\cs_new_protected:Npn \__xeCJK_make_under_symbol:n #1 + { + \hbox_set:Nn \l__xeCJK_tmp_box { ^^^^4e00 } + \vbox_gset_to_ht:Nnn \g__xeCJK_under_symbol_box \c_zero_dim + { + \skip_vertical:n {#1} + \hbox_to_zero:n + { + \tex_kern:D - \box_wd:N \l__xeCJK_tmp_box + \tex_hss:D \box_use:N \CJK@underdotBox \tex_hss:D + } + \tex_vss:D + } + } +\cs_new_protected_nopar:Npn \__xeCJK_under_CJKsymbol:N #1 + { + \__xeCJK_save_under_dot_CJKsymbol:N {#1} + \hbox_overlap_left:n { \box_use:N \g__xeCJK_under_symbol_box } + { \xeCJK_make_node:n { CJK } } + \xeCJK_ignore_spaces:w + } +\RenewDocumentEnvironment { CJKfilltwosides } { m } + { + \dim_set:Nn \l__xeCJK_fill_width_dim {#1} + \cs_set_eq:NN \CJKglue \tex_hfil:D + \cs_set_eq:NN \\ \__xeCJK_fill_newline: + \mode_if_vertical:T { \tex_indent:D } + \tex_vbox:D \c_group_begin_token + \tex_hbox:D to \l__xeCJK_fill_width_dim \c_group_begin_token + \tex_ignorespaces:D + } + { + \tex_unskip:D + \c_group_end_token + \c_group_end_token + } +\dim_new:N \l__xeCJK_fill_width_dim +\cs_new_protected_nopar:Npn \__xeCJK_fill_newline: + { + \tex_unskip:D + \c_group_end_token + \tex_hbox:D to \l__xeCJK_fill_width_dim \c_group_begin_token + \tex_ignorespaces:D + } +%% +%% This package consists of the file xeCJK.dtx +%% and the derived files xeCJK.pdf, +%% xeCJK.sty, +%% xeCJK.cfg, +%% xeCJK.ins, +%% xeCJKfntef.sty, +%% 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, and +%% README.txt. +%% +%% End of file `xeCJKfntef.sty'. |