summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/xelatex/xecjk
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2012-11-23 22:46:32 +0000
committerKarl Berry <karl@freefriends.org>2012-11-23 22:46:32 +0000
commit4472c1a09891d886ecdc6dd3fbfa39e66ef55ff7 (patch)
tree0235845fbcfde75dc2d3b817a8cf2a7a047e201c /Master/texmf-dist/source/xelatex/xecjk
parente59dc86d50620df70414da4bd434219b46137fc9 (diff)
xecjk (23nov12)
git-svn-id: svn://tug.org/texlive/trunk@28348 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/xelatex/xecjk')
-rw-r--r--Master/texmf-dist/source/xelatex/xecjk/xeCJK.dtx4717
-rw-r--r--Master/texmf-dist/source/xelatex/xecjk/xeCJK.ins32
2 files changed, 2855 insertions, 1894 deletions
diff --git a/Master/texmf-dist/source/xelatex/xecjk/xeCJK.dtx b/Master/texmf-dist/source/xelatex/xecjk/xeCJK.dtx
index 7db4de8d136..4bdcdb2f7bc 100644
--- a/Master/texmf-dist/source/xelatex/xecjk/xeCJK.dtx
+++ b/Master/texmf-dist/source/xelatex/xecjk/xeCJK.dtx
@@ -20,13 +20,17 @@ This package is licensed in LPPL.
This package consists of the file xeCJK.dtx
and the derived files xeCJK.pdf,
xeCJK.sty,
+ xeCJK.cfg,
xeCJK.ins,
xeCJK-example-autofake.tex,
xeCJK-example-fallback.tex,
xeCJK-example-subCJKblock.tex,
xeCJK-example-CJKecglue.tex,
- xeCJK-example-checksingle.tex and
- README.txt (this file).
+ xeCJK-example-checksingle.tex,
+ xeCJK-example-CJKfntef.tex,
+ xeCJK-example-punctstyle.tex,
+ xeCJK-example-verbatim.tex, and
+ README.txt. (this file).
If you are interested in the process of development you may observe
@@ -52,7 +56,8 @@ 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).
+packages online may be necessary). Both of xpatch and etoolbox packages
+are required. They are also available on CTAN.
To compile the documentation without error, you will need some specific
CJK scripts fonts (TrueType or OpenType).
@@ -64,13 +69,9 @@ CJK scripts fonts (TrueType or OpenType).
\edef\tempb{plain}
\ifx\tempa\tempb
\endgroup
- \expandafter\let\csname ifxeCJKplainTeX\expandafter\endcsname\csname iftrue\endcsname
+ \def\xeCJKMaybeStopHere{\endbatchfile}
\else
- \endgroup
- \expandafter\let\csname ifxeCJKplainTeX\expandafter\endcsname\csname iffalse\endcsname
-\fi
-\ifxeCJKplainTeX \else
- \expandafter\begingroup
+ \let\xeCJKMaybeStopHere\endgroup
\fi
%</internal>
%<*batchfile>
@@ -80,7 +81,7 @@ CJK scripts fonts (TrueType or OpenType).
\askforoverwritefalse
\preamble
-$Id: xeCJK.dtx 358 2012-10-27 11:52:01Z sobenlee $
+$Id: xeCJK.dtx 368 2012-11-23 04:55:23Z sobenlee $
$URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
-----------------------------------------------------------------
Author:
@@ -109,23 +110,41 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
This package consists of the file xeCJK.dtx
and the derived files xeCJK.pdf,
xeCJK.sty,
+ xeCJK.cfg,
xeCJK.ins,
xeCJK-example-autofake.tex,
xeCJK-example-fallback.tex,
xeCJK-example-subCJKblock.tex,
xeCJK-example-CJKecglue.tex,
- xeCJK-example-checksingle.tex and
+ xeCJK-example-checksingle.tex,
+ xeCJK-example-CJKfntef.tex,
+ xeCJK-example-punctstyle.tex,
+ xeCJK-example-verbatim.tex, and
README.txt.
\endpostamble
+\declarepreamble\emptypreamble
+\endpreamble
+\declarepostamble\emptypostamble
+\endpostamble
\usedir{tex/xelatex/xecjk}
\generate{\file{\jobname.sty}{\from{\jobname.dtx}{package}}}
+\usedir{tex/xelatex/xecjk/config}
+\generate{
+ \usepreamble\emptypreamble
+ \usepostamble\emptypostamble
+ \file{\jobname.cfg}{\from{\jobname.dtx}{config}}}
\usedir{doc/xelatex/xecjk/example}
\generate{
+ \usepreamble\emptypreamble
+ \usepostamble\emptypostamble
\file{\jobname-example-autofake.tex}{\from{\jobname.dtx}{ex-autofake}}
\file{\jobname-example-fallback.tex}{\from{\jobname.dtx}{ex-fallback}}
\file{\jobname-example-subCJKblock.tex}{\from{\jobname.dtx}{ex-block}}
\file{\jobname-example-CJKecglue.tex}{\from{\jobname.dtx}{ex-ecglue}}
- \file{\jobname-example-checksingle.tex}{\from{\jobname.dtx}{ex-single}}}
+ \file{\jobname-example-checksingle.tex}{\from{\jobname.dtx}{ex-single}}
+ \file{\jobname-example-CJKfntef.tex}{\from{\jobname.dtx}{ex-fntef}}
+ \file{\jobname-example-punctstyle.tex}{\from{\jobname.dtx}{ex-punctstyle}}
+ \file{\jobname-example-verbatim.tex}{\from{\jobname.dtx}{ex-verb}}}
%</batchfile>
%<batchfile>\endbatchfile
%<*internal>
@@ -134,37 +153,50 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
\nopreamble\nopostamble
\usedir{doc/xelatex/xecjk}
\generate{\file{README.txt}{\from{\jobname.dtx}{readme}}}
-\ifxeCJKplainTeX
- \expandafter\endbatchfile
-\else
- \expandafter\endgroup
-\fi
+\xeCJKMaybeStopHere
%</internal>
%
-%<*driver|package>
+%<*driver|package|config>
\NeedsTeXFormat{LaTeX2e}
+%<*!config>
\RequirePackage{expl3}
-\GetIdInfo$Id: xeCJK.dtx 358 2012-10-27 11:52:01Z sobenlee $
- {package for typesetting CJK scripts with XeLaTeX}
-%<*driver>
+%</!config>
+\GetIdInfo$Id: xeCJK.dtx 368 2012-11-23 04:55:23Z sobenlee $
+%<*!config>
+ {Typesetting CJK scripts with XeLaTeX}
+%</!config>
+%<config> {Configuration file for xeCJK package}
+%<*!package>
\ProvidesExplFile
+%</!package>
+%<*driver>
{\ExplFileName.\ExplFileExtension}
%</driver>
+%<config> {\ExplFileName.cfg}
%<package>\ProvidesExplPackage
%<package> {\ExplFileName}
- {\ExplFileDate}{3.0.10}{\ExplFileDescription}
+ {\ExplFileDate}{3.1.0}{\ExplFileDescription}
%<*driver>
+\let\xeCJKrevnum\ExplFileVersion
\ExplSyntaxOff
%</driver>
-%</driver|package>
+%</driver|package|config>
%
%<*driver>
-\documentclass[full]{l3doc}
+\expandafter\let\csname ver@thumbpdf.sty\endcsname\empty
+\documentclass[numbered,a4paper,full]{l3doc}
\hypersetup{pdfstartview=FitH}
\usepackage{xeCJK}
-\fvset{formatcom=\CJKfixedspacing}
+\usepackage{CJKfntef}
+\usepackage{geometry}
+\usepackage[toc]{multitoc}
+\normalem
+\fvset{formatcom=\xeCJKVerbAddon}
\linespread{1.1}
-\setlist{nosep}
+\setlist{noitemsep,topsep=1ex}
+\newlist{optiondesc}{description}{3}
+\setlist[optiondesc]{font=\mdseries\ttfamily,align=right,labelsep=.5em,leftmargin=4.5em}
+\def\PSKeyVal#1#2{\item[#1]\makebox[4em][l]{\meta{#2}}\ignorespaces}
\setmainfont[Ligatures=TeX]{TeX Gyre Pagella}
\setmonofont{Inconsolata}
\setCJKmainfont[BoldFont=Adobe Heiti Std,ItalicFont=Adobe Kaiti Std]{Adobe Song Std}
@@ -176,19 +208,41 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
\setCJKmainfont[Ext-B]{SimSun-ExtB}
\setCJKmainfont[Hangul]{Adobe Myungjo Std}
\xeCJKsetup{PunctStyle=kaiming,KaiMingPunct+={:;}}
-\def\MacroFont{\small\normalfont\ttfamily\punctstyle{plain}}
+\def\MacroFont{\small\normalfont\ttfamily\xeCJKVerbAddon}
\def\XeTeX{\hologo{XeTeX}}
\def\XeLaTeX{\hologo{XeLaTeX}}
\def\LaTeX{\hologo{LaTeX}}
+\def\LaTeXe{\hologo{LaTeX2e}}
\parindent=2em
\AtBeginDocument{\DeleteShortVerb{\"}\MakeShortVerb{\|}}
\def\contentsname{目录}
\DeclareUrlCommand\email{\def\UrlLeft##1\UrlRight{\href{mailto:##1}{##1}}}
-\addtolength{\voffset}{-5\baselineskip}
-\addtolength\textheight{8\baselineskip}
+\def\ctexkit{\href{http://code.google.com/p/ctex-kit/}{\texttt{ctex-kit}}}
+\def\ctexkitrev#1{%
+ \href{http://code.google.com/p/ctex-kit/source/detail?r=#1}
+ {\texttt{ctex-kit} rev#1}}
+\ExplSyntaxOn
+\cs_new_nopar:Npn \package #1
+ {
+ \href
+ {
+ http://mirrors.ctan.org/help/Catalogue/entries/
+ \tl_expandable_lowercase:n {#1} .html
+ }
+ { \pkg {#1} }
+ }
+\ExplSyntaxOff
+\geometry{includemp,hmargin={0mm,15mm},vmargin=15mm,footskip=7mm}
\makeatletter
+\appto\GlossaryParms{%
+ \def\@idxitem{\par\hangindent 2em}%
+ \def\subitem{\@idxitem\hspace*{1em}}%
+ \def\subsubitem{\@idxitem\hspace*{2em}}}
+\patchcmd\changes@{\space}{\lbrack}{}{}
+\patchcmd\@wrglossary{hdpindex}{hdclindex{\the\c@HD@hypercount}}{}{}
\let\orig@meta\meta
-\def\meta#1{\orig@meta{\mbox{\normalfont\itshape\CJKfixedspacing#1}}}
+\def\meta#1{%
+ \orig@meta{\mbox{\normalfont\itshape\xeCJKsetup{PunctStyle=plain,CJKecglue}#1}}}
\def\TF{true\orvar{}false}
\def\TTF{\defaultvar{true}\orvar{}false}
\def\TFF{true\orvar\defaultvar{false}}
@@ -199,49 +253,58 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
\def\tokslink#1{\hyperlink{#1}{\ding{51}}}
\makeatother
\def\indexname{代码索引}
+\def\glossaryname{版本历史}
+\GlossaryPrologue{%
+ \addtocounter{secnumdepth}{-10}%
+ \section{\glossaryname}}
\IndexPrologue{%
- \section*{\indexname}
- \markboth{\indexname}{\indexname}
+ \section{\indexname}%
斜体的数字表示对应项说明所在的页码,下划线的数字表示定义所在的代码行号,而直立体的
数字表示对应项使用时所在的行号。}
\begin{document}
\DocInput{\jobname.dtx}
+ \newgeometry{margin=15mm,footskip=7mm}
+ \PrintChanges
+ \PrintIndex
\end{document}
%</driver>
% \fi
%
-% \CheckSum{3129}
-% \DoNotIndex{\T,\F,\C,\J,\K,\O,\U,\Z,\E,\R,\M,\A,\Y,\R,\;,\t,\c,\:,\\,\@}
+% \CheckSum{3035}
+% \changes{v3.1.0}{2012/11/13}{放弃对 \cs{outer} 宏的特殊处理。}
+%
% \GetFileInfo{\jobname.dtx}
%
% \title{\bfseries\pkg{xeCJK} 宏包}
% \author{\href{http://www.ctex.org}{ctex.org}}
-% \date{\filedate\qquad\fileversion}
+% \date{\filedate\qquad\fileversion\thanks{\ctexkitrev{\xeCJKrevnum}.}}
% \maketitle
%
% \tableofcontents
+% \vspace{\baselineskip}
%
% \begin{documentation}
%
% \section{简介}
%
% \pkg{xeCJK} 是一个 \XeLaTeX 宏包,用于排版中日韩(CJK)文字。主要功能:
-% \begin{enumerate}
+% \begin{enumerate}[labelindent=\parindent,leftmargin=*]
% \item 分别设置 CJK 和英文字体;
% \item 自动忽略 CJK 文字间的空格而保留其它空格,允许在非标点汉字和英文
-% 字母 (a--z, A--Z) 间断行;
+% 字母 (a -- z, A -- Z) 间断行;
% \item 提供多种标点处理方式: 全角式、半角式、开明式、行末半角式和 CCT 式;
% \item 自动调整中英文间空白。
% \end{enumerate}
%
% \pkg{xeCJK} 使用了 \XeTeX 的一些最新特性,需要 \XeTeX{} |0.9995.0 [2009/06/29]| 以
-% 后的版本。\pkg{xeCJK} 依赖 \LaTeX~3 项目的 \pkg{expl3},\pkg{xparse} 和
-% \pkg{l3keys2e} 宏包。\pkg{xeCJK} 还通过 \pkg{fontspec}^^A
-% \footnote{\url{http://mirrors.ctan.org/macros/latex/contrib/fontspec/}}
-% 宏包来调用系统字体。个别兼容性功能需要 \pkg{CJK} 宏包的支持。
-%
-% \pkg{xeCJK} 的原始作者是孙文昌,2009 年 5 月起宏包被收入
-% \texttt{ctex-kit}\footnote{\url{http://code.google.com/p/ctex-kit/}} 项目进行
+% 后的版本。\pkg{xeCJK} 依赖 \hologo{LaTeX3} 项目的宏包套件 \package{l3kernel} 和
+% \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\ 项目进行
% 维护,目前主要维护者是刘海洋\footnote{\email{leoliu.pku@gmail.com}} 和
% 李清\footnote{\email{sobenlee@gmail.com}}。
%
@@ -268,14 +331,14 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
% 源文件用 UTF-8 编码保存,使用 \XeLaTeX{} 编译。
%
% \pkg{xeCJK} 只提供了字体和标点控制等基本 CJK 语言支持。对于中文文档,可以使
-% 用更为高层的 \pkg{ctex} 宏包或文档类,它将自动调用 \pkg{xeCJK} 并设置好中文
-% 字体,同时提供了进一步的本地化支持。详细内容参看 \pkg{ctex} 宏包^^A
-% \footnote{\url{http://mirrors.ctan.org/language/chinese/ctex/}}的说明。
+% 用更为高层的 \package{ctex} 宏包或文档类,它将自动调用 \pkg{xeCJK} 并设置好中文
+% 字体,同时提供了进一步的本地化支持。详细内容参看 \package{ctex} 宏包套件的说明。
%
% \pkg{xeCJK} 提供了大量选项,可以在宏包调用时作为宏包选项或用 \cs{xeCJKsetup}
% 命令进行设置,详见 \ref{subsec:opts}~节。除了 \cs{setCJKmainfont} 命令,
% \pkg{xeCJK} 还提供了许多其他命令设置和选择中文字体,详见
-% \ref{subsec:fontset}~节。其他更详细的功能也都将在下面详细说明。
+% \ref{subsec:fontset}~节。其他更详细的功能也都将在下面详细说明。在本文档所在的
+% 文件夹的 |example| 目录下面也有一些例子可以参考。
%
% \section{用户手册}
%
@@ -284,13 +347,14 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
%
% \pkg{xeCJK} 以 \meta{key}|=|\meta{var} 的形式提供宏包选项,你可以在调用宏包
% 的时候直接设置这些选项,也可以在调用宏包之后使用 \cs{xeCJKsetup} 来设置这些选
-% 项。
+% 项。\pkg{xeCJK} 内部调用 \pkg{fontspec} 宏包,可以在调用 \pkg{xeCJK} 的时候,
+% 使用它的宏包选项。\pkg{xeCJK} 会将 \pkg{fontspec} 的选项传递给它。
%
% \begin{function}{\xeCJKsetup}
% \begin{syntax}
-% \cs{xeCJKsetup} \argbrace{\meta{key1}=\meta{var1}, \meta{key2}=\meta{var2}, ...}
+% \cs{xeCJKsetup} \argbrace{\meta{key_1}=\meta{var_1}, \meta{key_2}=\meta{var_2}, ...}
% \end{syntax}
-% 其中 \meta{key1}, \meta{key2} 是设置选项,而 \meta{val1}, \meta{val2} 则是对应选项的
+% 其中 \meta{key_1}, \meta{key_2} 是设置选项,而 \meta{val_1}, \meta{val_2} 则是对应选项的
% 设置内容。多个选项可以在一个语句中完成设置。例如
% \begin{verbatim}
% \usepackage[PunctStyle=kaiming]{xeCJK}
@@ -310,29 +374,47 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
%
% 下列选项使用加粗的形式来表示 \pkg{xeCJK} 的默认设置。
%
-% \begin{function}{xeCJKactive}
+% \begin{function}[EXP]{LocalConfig}
% \begin{syntax}
-% xeCJKactive = \meta{\TTF}
+% LocalConfig = \marg{\TTF\orvar{}name}
% \end{syntax}
-% 打开/关闭对中文的特殊处理。
+% 是否使用本地配置文件 \texttt{xeCJK-\meta{name}.cfg}。\meta{name} 可以是不包含
+% 空格的任意使文件名合法的字符串。如果设置为 |true|,则使用的是 \texttt{xeCJK.cfg};
+% 设置为 |false| 则不载入配置文件。可以把将要在下文介绍到的对 \pkg{xeCJK} 的一些
+% 设置(例如设置常用 CJK 字体、修改字符范围和定义新的标点输出格式等)保存到文件
+% \texttt{xeCJK-\meta{name}.cfg}。然后把这个文件放在本地的 |TDS| 目录下的适当
+% 位置。使用 \TeX Live 的用户,可以新建下列目录,然后再把
+% \texttt{xeCJK-\meta{name}.cfg} 放在里面:
+% \begin{verbatim}
+% texlive/texmf-local/tex/xelatex/xecjk
+% \end{verbatim}
+% 最后还需要在命令行下执行 |mktexlsr|,刷新文件名数据库以便 \TeX 系统能够找到它。
% \end{function}
%
% \begin{function}[EXP]{CJKnumber}
% \begin{syntax}
% CJKnumber = \meta{\TFF}
% \end{syntax}
-% 是否使用 \pkg{CJKnumb} 宏包。请注意,为了与 \pkg{CJKnumb} 兼容,\pkg{xeCJK} 修改了
-% 它的一些内部命令,所以这个选项需要在调用 \pkg{xeCJK} 时设置,而不能通过 \cs{xeCJKsetup}
-% 来设置它。
+% 为了与 \pkg{CJKnumb} 宏包兼容,\pkg{xeCJK} 作了一些特别处理。因此,如果需要使用
+% 到 \pkg{CJKnumb},请通过这个选项调用它。
% \end{function}
%
% \begin{function}[EXP]{indentfirst}
% \begin{syntax}
% indentfirst = \meta{\TTF}
% \end{syntax}
-% 跟在章节标题后面的第一段首行是否缩进。这个选项需要在调用 \pkg{xeCJK} 时设置,不能
-% 通过 \cs{xeCJKsetup} 来设置它。\pkg{xeCJK} 宏包中只有 |indentfirst| 和 |CJKnumber|
-% 这两个选项,不能通过 \cs{xeCJKsetup} 来设置。
+% 是否使用 \pkg{indentfirst} 宏包,使得跟在章节标题后面的第一段首行也缩进。\bigskip
+% \end{function}
+%
+% 请注意,\pkg{xeCJK} 宏包中只有上述 |LocalConfig|、|CJKnumber| 和 |indentfirst|
+% 这三个选项需要在调用 \pkg{xeCJK} 时设置,而不能通过 \cs{xeCJKsetup} 来设置。
+%
+% \begin{function}{xeCJKactive}
+% \begin{syntax}
+% xeCJKactive = \meta{\TTF}
+% \end{syntax}
+% 打开/关闭对中文的特殊处理。事实上,这个选项会打开/关闭 \XeTeX 的整个字符类机制,依赖
+% 这个机制的宏包都会受到影响。
% \end{function}
%
% \begin{function}{CJKspace}
@@ -390,7 +472,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
% InlineEnv = \argbrace{env1, env2, env3, ...}
% \end{syntax}
% 在使用 |CheckSingle| 选项的时候,\pkg{xeCJK} 会将 CJK 文字后接着的 \LaTeX 环境的
-% 开始 \cs{begin{...}} 和结束 \cs{end{...}} 视为断行的地方,如果有某些特殊
+% 开始 |\begin{...}| 和结束 |\end{...}| 视为断行的地方,如果有某些特殊
% 的 \LaTeX 环境没有造成断行,可以使用这个选项来声明它,以便 |CheckSingle| 能正确识别。
% \end{function}
%
@@ -434,17 +516,19 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
%
% \begin{function}{PunctStyle}
% \begin{syntax}
-% PunctStyle = \marg{\defaultvar{quanjiao}\orvar{}banjiao\orvar{}kaiming\orvar{}hangmobanjiao\orvar{}CCT\orvar{}plain}
+% PunctStyle = \marg{\defaultvar{quanjiao}\orvar{}banjiao\orvar{}kaiming\orvar{}hangmobanjiao\orvar{}CCT\orvar{}plain\orvar{}...}
% \end{syntax}
-% 设置标点处理格式,有效值分别为
-% \begin{itemize}[font=\ttfamily,labelsep=1em]
+% 设置标点处理格式。\pkg{xeCJK} 中预先定义好的格式为
+% \begin{description}[font=\mdseries\ttfamily,align=right,labelsep=1em,labelindent=2em,leftmargin=*]
% \item[quanjiao] 全角式:所有标点占一个汉字宽度,相邻两个标点占 1.5 汉字宽度;
% \item[banjiao] 半角式:所有标点占半个汉字宽度;
% \item[kaiming] 开明式:句末点号用全角,其他半角;
% \item[hangmobanjiao] 行末半角式:所有标点占一个汉字宽度,行首行末对齐;
% \item[CCT] CCT 格式;
% \item[plain] 原样(不调整标点间距)。
-% \end{itemize}
+% \end{description}
+% 可以使用 \ref{subsec:punctstyle} 中介绍的 \cs{xeCJKDeclarePunctStyle} 定义新的标点
+% 格式。
% \end{function}
%
% \begin{function}[EXP]{KaiMingPunct,KaiMingPunct+,KaiMingPunct-}
@@ -474,13 +558,13 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
%
% \begin{function}[EXP]{PunctWidth}
% \begin{syntax}
-% PunctWidth = \Arg{dimen}
+% PunctWidth = \Arg{length}
% \end{syntax}
% 缺省状态下,\pkg{xeCJK} 会根据所选择的标点处理格式自动计算标点所占的宽度,如果对缺
% 省设置不满意,可以通过这一选项来改变它。为了使得标点所占的宽度能够适应字体大小的变化,
-% 这里设置的 |dimen| 的单位最好用 |em| 等相对距离单位,而不建议使用诸如 |pt| 之类的
-% 绝对距离单位。这里的设置对除了 |plain| 以外的所有标点处理格式都有效。同时,这里的
-% 设置对所有的 CJK 标点都生效,如果只要设置部分标点,请使用 \ref{subsec:punct} 节的
+% 这里设置的 |length| 的单位最好用 |em| 等相对距离单位,而不建议使用诸如 |pt| 之类的
+% 绝对距离单位。这里的设置可用于除了 |plain| 以外的所有标点处理格式。同时,这里的
+% 设置对所有的 CJK 标点都生效,如果只要设置部分标点,请使用 \ref{subsec:punct}~节的
% \cs{xeCJKsetwidth}。
% \end{function}
%
@@ -526,37 +610,21 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
% \begin{syntax}
% \cs{setCJKmonofont} \oarg{font features} \Arg{font name}
% \end{syntax}
-% 设置正文等宽族的 CJK 字体,影响 \cs{ttfamily} 和 \cs{texttt} 的字体。为了有利于等宽
-% 字体的代码对齐等情形,\pkg{xeCJK} 在 \meta{font features} 里增加了 |Mono| 这个选项。
+% 设置正文等宽族的 CJK 字体,影响 \cs{ttfamily} 和 \cs{texttt} 的字体。
% \end{function}
%
-% \begin{function}{Mono}
+% \begin{function}{\xeCJKVerbAddon}
% \begin{syntax}
-% Mono = \meta{Scale\orvar{}Exspace}
+% \cs{xeCJKVerbAddon}
% \end{syntax}
-% 有效值仅为 |Scale| 或 |Exspace|。分别表示使用放缩的方式或改变间距的方式,让 CJK
-% 字符的宽度等于西文字体中两个空格的宽度。
-% \end{function}
-%
-% \begin{function}{\CJKfixedspacing,\CJKflexiblespacing}
-% \begin{syntax}
-% \cs{CJKfixedspacing}
-% \cs{CJKflexiblespacing}
-% \end{syntax}
-% \cs{CJKfixedspacing} 命令设置固定字距和不压缩标点格式,符合上面 |Mono=Exspace| 选
-% 项的意义。\cs{CJKflexiblespacing} 命令恢复可伸缩的字距和标点压缩。抄录 |(verbatim)|
-% 环境将自动使用 \cs{CJKfixedspacing} 的效果。
-% \end{function}
-%
-% \begin{function}{\setCJKmonoscale,\setCJKmonoexspace}
-% \begin{syntax}
-% \cs{setCJKmonoscale}
-% \cs{setCJKmonoexspace}
-% \end{syntax}
-% \cs{setCJKmonoscale} 和 \cs{setCJKmonoexspace} 命令分别计算并设置当前字号下西文等宽
-% 字体与 CJK 字体的放缩比例和字距,以符合上面所说的 |Mono=Scale| 与 |Mono=Exspace|
-% 选项的意义。在字号改变时,应该使用两个命令之一,重新计算相关参数;但注意两个命令不
-% 能同时使用。
+% 调整文字间距以便于让 CJK 字符占的宽度等于西文等宽字体中两个空格的宽度。这有利于
+% 等宽字体的代码对齐等情形。抄录 |(verbatim)| 环境将自动使用 \cs{xeCJKVerbAddon}
+% 的效果。需要注意的是,\cs{xeCJKVerbAddon} 对 \pkg{xeCJK} 的内部进行了比较大的
+% 修改,使用它之后,关于标点符号的禁则将会丢失。所以不能单独使用,应该放在分组里
+% 限制其作用域,否则是无效的。当然它可以和其它关于代码抄录的宏包配合使用。例如,
+% 可以使用于 \package{fancyvrb} 宏包的 |formatcom| 选项。此时设置的西文字体应该
+% 确实是等宽的以保证对齐。若西文等宽字体发生变动(包括字体大小),则需要在其后面
+% 使用 \cs{xeCJKVerbAddon},重新计算间距的宽度。
% \end{function}
%
% \begin{function}[EXP]{\setCJKfamilyfont}
@@ -692,11 +760,11 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
% \begin{function}[EXP]{\setCJKfallbackfamilyfont}
% \begin{syntax}
% \cs{setCJKfallbackfamilyfont} \Arg{family} \oarg{common font features}
-% \ \char`\{
+% \ \{
% \ \argbrace{\oarg{font features 1} \Arg{font name 1}} ,
% \ \argbrace{\oarg{font features 2} \Arg{font name 2}} ,
% \ ......
-% \ \char`\}
+% \ \}
% \end{syntax}
% \cs{setCJKfallbackfamilyfont} 还可以用于设置多层的备用字体。例如,使用
% \begin{verbatim}
@@ -725,7 +793,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
%
% |fc-list| 命令列出的信息很多,而且在安装字体较多的 Windows 系统上的输出将非
% 常庞大,如其中可能包含:
-% \begin{verbatim}[formatcom=\fontspec{CMU Typewriter Text}\CJKfixedspacing]
+% \begin{verbatim}[formatcom=\fontspec{CMU Typewriter Text}\xeCJKVerbAddon]
% Times New Roman:style=cursiva,kurzíva,kursiv,Πλάγια,Italic,
% Kursivoitu,Italique,Dőlt,Corsivo,Cursief,kursywa,Itálico,Курсив,
% İtalik,Poševno,nghiêng,Etzana
@@ -855,6 +923,13 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
% 命令除了设置字符类别以外,为了确保标点处理的正确性,还重置标点符号所属的字符类。
% \end{function}
%
+% \begin{function}[EXP]{\xeCJKResetCharClass}
+% \begin{syntax}
+% \cs{xeCJKResetCharClass}
+% \end{syntax}
+% 用于重置 \pkg{xeCJK} 对各个字符类别的设置。
+% \end{function}
+%
% \begin{function}[EXP]{\xeCJKResetPunctClass}
% \begin{syntax}
% \cs{xeCJKResetPunctClass}
@@ -869,45 +944,231 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
% 在 \meta{char list} 中出现的字符两端不自动添加空格,默认设置是 |/|。
% \end{function}
%
-% \subsection{设置标点宽度和间距}
+% \subsection{标点符号的处理}
+%
+% \pkg{xeCJK} 对标点符号的输出宽度的调整是通过调整其左边或右边的空白宽度来实现的。
+% 按照目前的处理方式,对于位于左边的标点符号(如左引号),\pkg{xeCJK} 只能调整它
+% 左边的空白;对于位于右边的标点符号(如右引号),\pkg{xeCJK} 只能调整它右边的空
+% 白;对于居中的标点符号,则调整其左右空白,以保证其居中。
+%
+% \subsubsection{设置特定标点符号的宽度和间距}
% \label{subsec:punct}
%
-% 这里的设置对除了 |plain| 以外的所有标点处理格式都有效。
+% 这里的设置可用于除 |plain| 以外的所有标点处理格式。
%
% \begin{function}[EXP]{\xeCJKsetwidth}
% \begin{syntax}
-% \cs{xeCJKsetwidth} \Arg{标点列表} \Arg{dimen}
+% \cs{xeCJKsetwidth} \Arg{标点列表} \Arg{length}
% \end{syntax}
% \meta{标点列表}可以是单个标点,也可以是多个标点。例如,
% \begin{verbatim}
% \xeCJKsetwidth{。?}{0.7em}
% \end{verbatim}
-% 将设置句号和问号所占的宽度为 |0.7em|。
+% 将设置句号和问号所占的宽度为 |0.7 em|。
% \end{function}
%
% \begin{function}[EXP]{\xeCJKsetkern}
% \begin{syntax}
-% \cs{xeCJKsetkern} \Arg{标点1} \Arg{标点2} \Arg{dimen}
+% \cs{xeCJKsetkern} \Arg{前标点} \Arg{后标点} \Arg{length}
% \end{syntax}
-% \pkg{xeCJK} 会根据选定的标点处理格式自动调整相邻两个 |CJK| 标点的距离。如果对缺省
-% 配置不满意,可以使用此命令设置两个标点之间的距离。例如,
+% \pkg{xeCJK} 会根据选定的标点处理格式自动调整相邻的前后两个 |CJK| 标点符号的
+% 空白宽度。如果需要对个别情况进行特殊调整,可以使用这个命令。例如,
% \begin{verbatim}
% \xeCJKsetkern{:}{“}{0.3em}
% \end{verbatim}
+% 将设置冒号与左双引号之间的空白宽度为 |0.3 em|。
+% \end{function}
+%
+% \subsubsection{定义标点符号处理格式}
+% \label{subsec:punctstyle}
+%
+% \begin{function}[EXP]{\xeCJKDeclarePunctStyle}
+% \begin{syntax}
+% \cs{xeCJKDeclarePunctStyle} \Arg{style} \Arg{options}
+% \end{syntax}
+% 定义新的标点符号处理格式,已经存在的同名格式将被覆盖。可以设置的选项将在下面介绍。
% \end{function}
%
+% \begin{function}[EXP]{\xeCJKEditPunctStyle}
+% \begin{syntax}
+% \cs{xeCJKEditPunctStyle} \Arg{style} \Arg{options}
+% \end{syntax}
+% 修改已有的标点符号处理格式。\strut
+% \end{function}
+%
+% 下面是可以设置的标点符号格式选项。其中左边一栏是选项名称,中间是选项的输入值类
+% 型,右边则是相关说明。某些选项之间是互斥的,具有优先级关系。要使下一级的选项有
+% 效,则需要先禁用上一级的设置:对于 \meta{boolean} 类型的选项,将其设置为 |false|,
+% 对于 \meta{length} 类型的选项,将其设置为 \cs{maxdimen},而对于 \meta{real} 类型
+% 的选项,将其设置为 |0|。
+%
+% \begin{optiondesc}
+% \PSKeyVal{enabled-global-setting}{boolean}
+% 是否使用 \cs{xeCJKsetup} 的 |PunctWidth| 选项和 \cs{xeCJKsetwidth}、
+% \cs{xeCJKsetkern} 的设置。默认值是 |true|。
+% \end{optiondesc}
+%
+% \begin{optiondesc}
+% \PSKeyVal{fixed-punct-width}{length}
+% 设置单个标点符号的宽度。默认值是 \cs{maxdimen}。
+% \PSKeyVal{fixed-punct-ratio}{real}
+% 设置单个标点符号的输出宽度与实际宽度的比例。默认值是 |1.0|。
+% \PSKeyVal{mixed-punct-width}{length}
+% 设置句末标点符号的宽度。其中句末标点符号通过 \cs{xeCJKsetup} 的 |KaiMingPunct|
+% 来设置。默认值是与 |fixed-punct-width| 选项的值相同。
+% \PSKeyVal{mixed-punct-width}{real}
+% 设置句末标点符号的宽度比例。默认值是与 |fixed-punct-ratio| 选项的值相同。
+% \PSKeyVal{middle-punct-width}{length}
+% 设置居中标点符号的宽度。其中居中标点符号通过 \cs{xeCJKsetup} 的 |MiddlePunct|
+% 来设置。默认值是与 |fixed-punct-width| 选项的值相同。
+% \PSKeyVal{middle-punct-width}{real}
+% 设置居中标点符号的宽度比例。默认值是与 |fixed-punct-ratio| 选项的值相同。
+% \end{optiondesc}
+%
+% 以上三个选项设置的是标点的固定宽度或比例,\pkg{xeCJK} 会根据设定的选项计算标点符号
+% 左/右的空白宽度。下面的选项设置的是标点符号左/右的空白宽度或比例,因此不同标点符号
+% 的宽度可能会不同。为了使下面的选项生效,需要先禁用上面的相应选项。优先级自上而下。
+%
+% \begin{optiondesc}
+% \PSKeyVal{fixed-margin-width}{length}
+% 设置标点的左/右空白宽度。默认值是 \cs{maxdimen}。
+% \PSKeyVal{fixed-margin-ratio}{real}
+% 设置标点的左/右空白宽度与字体中该标点的相应实际边界宽度的比例。默认值是 |1.0|。
+% \PSKeyVal{mixed-margin-width}{length}
+% 设置句末标点的左/右空白宽度。默认值是与 |fixed-margin-width| 的值相同。
+% \PSKeyVal{mixed-margin-ratio}{real}
+% 设置句末标点的左/右空白宽度的比例。默认值是与 |fixed-margin-ratio| 的值相同。
+% \PSKeyVal{middle-margin-width}{length}
+% 设置居中标点的两边空白宽度。默认值是与 |fixed-margin-width| 的值相同。
+% \PSKeyVal{middle-margin-ratio}{real}
+% 设置居中标点的两边空白宽度之和与两边实际两边边界宽度之和的比例。
+% 默认值是与 |fixed-margin-ratio| 的值相同。
+% \end{optiondesc}
+%
+% \begin{optiondesc}
+% \PSKeyVal{add-min-bound-to-margin}{boolean}
+% 是否在以上计算结果的基础上再加上标点的左右实际边界宽度中的最小值。这个选项
+% 对居中的标点无效。默认值是 |false|。
+% \end{optiondesc}
+%
+% \begin{optiondesc}
+% \PSKeyVal{optimize-margin}{boolean}
+% 使用以上设置空白宽度或比例的选项时,最终输出的标点符号左/右的空白宽度可能大
+% 于原来的实际边界宽度。若此时本选项被设置为 |true|,则使用原来的实际边界宽度。
+% 而使用 |fixed-punct-width| 选项计算得出的左/右宽度可能小于该标点的另一侧宽
+% 度,若此时本选项被启用,则使用该标点的另一侧宽度。默认值为 |false|。
+% \end{optiondesc}
+%
+% \begin{optiondesc}
+% \PSKeyVal{margin-minimum}{length}
+% 指定标点符号左/右的最小空白宽度。当经过以上选项设置的空白宽度小于这个选项的值
+% 时,则使用这个选项的值。默认值是 |0 pt|。
+% \end{optiondesc}
+%
+% 下面的选项处理的是前后相邻的两个标点符号之间的空白宽度。这些选项是互斥的,优先级
+% 自上而下。
+%
+% \begin{optiondesc}
+% \PSKeyVal{enabled-kerning}{boolean}
+% 是否调整前后相邻的两个标点之间的空白宽度。如果设置为 |false|,则每个标点都按
+% 原来的输出宽度输出。默认值是 |true|。
+% \PSKeyVal{min-bound-to-kerning}{boolean}
+% 是否使用当前字体中前面标点实际左右边界的最小值与后面标点实际左右边界的最小值
+% 中的最大值作为两个标点之间的空白宽度。默认值是 |false|。
+% \PSKeyVal{kerning-total-width}{length}
+% 设置两个标点的总共宽度。此时 \pkg{xeCJK} 会自动计算两个标点之间的空白宽度。
+% 默认值是 \cs{maxdimen}。
+% \PSKeyVal{kerning-total-ratio}{real}
+% 设置两个标点的总共输出宽度与实际宽度的比例。默认值是 |0.75|。
+% \PSKeyVal{same-align-margin}{length}
+% 当前后两个标点位于同侧时,它们之间的空白宽度。默认值是 \cs{maxdimen}。
+% \PSKeyVal{same-align-ratio}{real}
+% 当前后两个标点位于同侧时,它们之间的空白宽度与实际输出宽度的比例。默认值是 |0|。
+% \PSKeyVal{different-align-margin}{length}
+% 当前后两个标点位于异侧时,它们之间的空白宽度。默认值是 \cs{maxdimen}。
+% \PSKeyVal{different-align-ratio}{real}
+% 当前后两个标点位于异侧时,它们之间的空白宽度与实际输出宽度的比例。默认值是 |0|。
+% \PSKeyVal{kerning-margin-width}{length}
+% 设置前后两个标点之间的空白宽度。默认值是 \cs{maxdimen}。
+% \PSKeyVal{kerning-margin-ratio}{real}
+% 设置前后两个标点之间的空白宽度与实际输出空白的比例。默认值是 |1.0|。
+% \end{optiondesc}
+%
+% \begin{optiondesc}
+% \PSKeyVal{optimize-kerning}{boolean}
+% 使用以上选项计算出两个标点之间的空白宽度可能小于通过 |min-bound-to-kerning|
+% 选项得出的结果。当出现这一情况时,若此选项被设置为 |true|,则使用该选项的空
+% 白宽度。默认值为 |false|。
+% \end{optiondesc}
+%
+% \begin{optiondesc}
+% \PSKeyVal{kerning-margin-minimum}{length}
+% 指定两个标点之间的最小空白宽度。当经过以上选项设置的空白宽度小于这个选项的值
+% 时,则使用这个选项的值。默认值是 |0 pt|。
+% \end{optiondesc}
+%
+% 事实上,\pkg{xeCJK} 的默认设置就相当于中文全角(|quanjiao|)格式。可以使用上面
+% 说明的选项定义新的标点处理格式。例如,使用
+% \begin{verbatim}
+% \xeCJKDeclarePunctStyle { mine }
+% {
+% fixed-punct-ratio = 0 ,
+% fixed-margin-width = 0 pt ,
+% mixed-margin-width = \maxdimen ,
+% mixed-margin-ratio = 0.5 ,
+% middle-margin-width = \maxdimen ,
+% middle-margin-ratio = 0.5 ,
+% add-min-bound-to-margin = true ,
+% min-bound-to-kerning = true ,
+% kerning-margin-minimum = 0.1 em
+% }
+% \end{verbatim}
+% 就定义了一个名为 |mine| 的标点处理格式。可以在通过
+% \begin{verbatim}
+% \xeCJKsetup{PunctStyle=mine}
+% \end{verbatim}
+% 在文档中使用这个格式。它的意义是:使用标点符号的实际左右边界中的最小值作为其左/右
+% 空白的宽度,对于句末标点和居中标点,再加上实际边界空白的一半;使用相邻两个标点的
+% 实际边界中的较小值作为它们之间的空白宽度,并且最小的空白宽度是 |0.1 em|。
+% 再例如,使用
+% \begin{verbatim}
+% \xeCJKEditPunctStyle { hangmobanjiao } { enabled-global-setting = false }
+% \end{verbatim}
+% 将使得 \cs{xeCJKsetkern} 等的设置对 |hangmobanjiao| 这一格式无效。
+%
% \section{已知问题和兼容性}
%
-% 为了与 \pkg{CJKnumb} 和 \pkg{CJKulem} 宏包兼容,\pkg{xeCJK} 使用并重新定义了
+% 为了与 \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{CJKfntef} 宏包,以实现汉字加点等。
+% 可以在 \pkg{xeCJK} 之后载入 \pkg{CJKfntef} 宏包,以实现\CJKunderdot{汉字加点}
+% 和\CJKunderwave{可断行的下划线}等。
+%
+% 新版本(\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
+% \end{verbatim}
+% 的错误。目前已知的有 \pkg{cprotect} 宏包提供的 \cs{cprotect}。它的定义是
+% \begin{verbatim}
+% \outer\long\def\cprotect{\icprotect}
+% \end{verbatim}
+% 因此,这时可以暂时用 \cs{icprotect} 代替 \cs{cprotect}。事实上,当 \pkg{cprotect}
+% 被引入时,\pkg{xeCJK} 将使用
+% \begin{verbatim}
+% \let\cprotect\icprotect
+% \end{verbatim}
+% 来取消 \cs{cprotect} 的外部宏限制。但由于 \cs{cprotect} 的特殊性,应该只在外部
+% 使用它,即不要让它出现在任何宏的参数中。其它 \cs{outer} 宏的情况,可以在它前面
+% 加上 \cs{relax} 来回避上面的错误。
%
% \pkg{xeCJK} 依赖 \XeTeX 的 \cs{XeTeXinterchartoks} 机制,与使用相同机制的宏包(例如
-% \pkg{polyglossia})会存在大小不一的冲突。\pkg{xeCJK} 虽然为此作了一些处理,但与它们
-% 共同使用时应该小心。
+% \pkg{polyglossia})可能会存在大小不一的冲突。\pkg{xeCJK} 虽然为此作了一些处理,但与
+% 它们共同使用时应该小心。
%
%\end{documentation}
%
@@ -945,160 +1206,210 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
% \begin{macrocode}
\msg_new:nnn { xeCJK } { l3-too-old }
{
- Support~package~'expl3'~too~old. \\\\
+ Support~package~'#1'~too~old. \\\\
Please~update~an~up~to~date~version~of~the~bundles\\\\
'l3kernel'~and~'l3packages'\\\\
using~your~TeX~package~manager~or~from~CTAN.\\
- Loading~xeCJK~will~abort!
+ \str_if_eq:nnT {#1} { expl3 } { Loading~xeCJK~will~abort! }
}
-\@ifpackagelater { expl3 } { 2012/09/10 } { }
- { \msg_critical:nn { xeCJK } { l3-too-old } }
+\@ifpackagelater { expl3 } { 2012/11/10 } { }
+ { \msg_critical:nnn { xeCJK } { l3-too-old } { expl3 } }
% \end{macrocode}
%
+% 以下日期以前的 \pkg{xtemplate} 宏包关于 \cs{KeyValue} 的 Bug 会影响到后面
+% 标点符号的处理。
% \begin{macrocode}
-\RequirePackage{xparse}
-\RequirePackage{l3keys2e}
+\RequirePackage { xtemplate }
+\@ifpackagelater { xtemplate } { 2012/11/10 } { }
+ { \msg_error:nnn { xeCJK } { l3-too-old } { xtemplate } }
% \end{macrocode}
%
-% \cs{XeTeXglyphbouds} 可以得到一个字符的左右边距,用于标点压缩。
% \begin{macrocode}
-\msg_new:nnn { xeCJK } { XeTeX-too-old }
- {
- \token_to_str:N \XeTeXglyphbounds \ is~not~defined.\\\\
- You~have~to~update~XeTeX~to~the~version~0.9995.0~or~later.
- }
-\cs_if_free:NT \XeTeXglyphbounds
- {
- \msg_error:nn { xeCJK } { XeTeX-too-old }
- \AtEndOfPackage { \@@_AfterPreamble:n { \punctstyle { plain } } }
- }
+\RequirePackage { xparse , l3keys2e }
+\RequirePackage { xpatch }
% \end{macrocode}
%
% \subsection{内部工具}
%
% 分配临时变量。
-% \begin{macro}[internal,var]{\l_@@_tmpa_int,\l_@@_tmpb_int,\l_@@_tmpc_int}
% \begin{macrocode}
+\tl_new:N \l_@@_tmpa_tl
+\tl_new:N \l_@@_tmpb_tl
\int_new:N \l_@@_tmpa_int
\int_new:N \l_@@_tmpb_int
\int_new:N \l_@@_tmpc_int
+\box_new:N \l_@@_tmp_box
+\dim_new:N \l_@@_tmp_dim
+\skip_new:N \g_@@_tmp_skip
+\prop_new:N \l_@@_tmp_prop
+\clist_new:N \l_@@_tmpa_clist
+\clist_new:N \l_@@_tmpb_clist
% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal,var]{\l_@@_tmpa_dim,\l_@@_tmpb_dim,\l_@@_tmpc_dim}
-% \begin{macrocode}
-\dim_new:N \l_@@_tmpa_dim
-\dim_new:N \l_@@_tmpb_dim
-\dim_new:N \l_@@_tmpc_dim
-% \end{macrocode}
-% \end{macro}
%
-% \begin{macro}[internal,var]{\l_@@_tmpa_tl,\l_@@_tmpb_tl}
-% \begin{macrocode}
-\tl_new:N \l_@@_tmpa_tl
-\tl_new:N \l_@@_tmpb_tl
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal,var]{\l_@@_tmpa_clist,\l_@@_tmpb_clist,\l_@@_tmpc_clist}
+% \begin{macro}[internal]
+% {\@@_msg_new:nn ,\@@_error:n,\@@_error:nx,\@@_warning:nx,\@@_info:nx,\@@_info:nxx}
+% 各种信息函数的缩略形式。
% \begin{macrocode}
-\clist_new:N \l_@@_tmpa_clist
-\clist_new:N \l_@@_tmpb_clist
-\clist_new:N \l_@@_tmpc_clist
+\cs_new_protected_nopar:Npn \@@_msg_new:nn { \msg_new:nnn { xeCJK } }
+\cs_new_protected_nopar:Npn \@@_error:n { \msg_error:nn { xeCJK } }
+\cs_new_protected_nopar:Npn \@@_error:nx { \msg_error:nnx { xeCJK } }
+\cs_new_protected_nopar:Npn \@@_warning:n { \msg_warning:nn { xeCJK } }
+\cs_new_protected_nopar:Npn \@@_warning:nx { \msg_warning:nnx { xeCJK } }
+\cs_new_protected_nopar:Npn \@@_warning:nxx { \msg_warning:nnxx { xeCJK } }
+\cs_new_protected_nopar:Npn \@@_info:nx { \msg_info:nnx { xeCJK } }
+\cs_new_protected_nopar:Npn \@@_info:nxx { \msg_info:nnxx { xeCJK } }
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\xeCJK_no_break:}
+% \begin{macro}[internal]{\xeCJK_allow_break:,\xeCJK_no_break:}
% \begin{macrocode}
+\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 }
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]
-% {\@@_AtEndPreamble:n,\@@_AfterPreamble:n,\@@_AfterEndPreamble:n}
+% {\@@_at_end_preamble:n,\@@_after_preamble:n,\@@_after_end_preamble:n}
% 在 \cs{document} 前后加上各种钩子。
% \begin{macrocode}
\tl_new:N \g_@@_at_end_preamble_hook_tl
\tl_new:N \g_@@_after_preamble_hook_tl
\tl_new:N \g_@@_after_end_preamble_hook_tl
-\cs_new_protected:Npn \@@_AtEndPreamble:n #1
+\cs_new_protected:Npn \@@_at_end_preamble:n #1
{ \tl_gput_right:Nn \g_@@_at_end_preamble_hook_tl {#1} }
-\cs_new_protected:Npn \@@_AfterPreamble:n #1
+\cs_new_protected:Npn \@@_after_preamble:n #1
{ \tl_gput_right:Nn \g_@@_after_preamble_hook_tl {#1} }
-\cs_new_protected:Npn \@@_AfterEndPreamble:n #1
+\cs_new_protected:Npn \@@_after_end_preamble:n #1
{ \tl_gput_right:Nn \g_@@_after_end_preamble_hook_tl {#1} }
-\AtBeginDocument { \g_@@_after_preamble_hook_tl }
-\tl_put_left:Nn \document { \group_end: \g_@@_at_end_preamble_hook_tl \group_begin: }
-\tl_put_right:Nn \document { \g_@@_after_end_preamble_hook_tl \tex_ignorespaces:D }
+\AtEndPreamble { \g_@@_at_end_preamble_hook_tl }
+\AfterPreamble { \g_@@_after_preamble_hook_tl }
+\AfterEndPreamble { \g_@@_after_end_preamble_hook_tl }
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[pTF,internal]{\xeCJK_if_outer_macro:c}
-% 判断是否是 \cs{outer} 宏,输入的是控制序列的名字。
+% \begin{macro}[internal]{\xeCJK_reverse:nnn}
+% |#1| 为 |#2| 或 |#3|,若 |#1| 和 |#2| 相等,则返回 |#3|,否则返回 |#2|。
+% \begin{macrocode}
+\cs_new_nopar:Npn \xeCJK_reverse:nnn #1#2#3
+ { \str_if_eq_x:nnTF {#1} {#2} {#3} {#2} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]
+% {\xeCJK_tl_remove_outer_braces:N,\xeCJK_tl_remove_outer_braces:n}
+% 去掉 |#1| 外层的分组括号。
% \begin{macrocode}
-\group_begin:
-\char_set_lccode:nn { `\Z } { `\t }
-\char_set_lccode:nn { `\Y } { `\c }
-\char_set_lccode:nn { `\; } { `\: }
-\char_set_lccode:nn { `\/ } { `\\ }
-\tl_map_inline:nn { \T \F \C \J \K } { \char_set_lccode:nn { `#1 } { `#1 } }
-\tl_map_function:nN { \O \U \Z \E \R \M \A \Y \R \; \/ } \char_set_catcode_other:N
-\tl_to_lowercase:n
+\cs_new_protected_nopar:Npn \xeCJK_tl_remove_outer_braces:N #1
+ { \tl_set:Nx #1 { \exp_args:NV \xeCJK_tl_remove_outer_braces:n #1 } }
+\cs_new:Npn \xeCJK_tl_remove_outer_braces:n #1
+ { \@@_tl_remove_outer_braces:w #1 \q_stop }
+\cs_new:Npn \@@_tl_remove_outer_braces:w #1 \q_stop
{
- \group_end:
- \prg_new_conditional:Npnn \xeCJK_if_outer_macro:c #1 { p , T , F , TF }
- {
- \exp_last_unbraced:Nf \@@_if_outer_macro_aux:w
- { \cs_meaning:c {#1} } OUZER ~ MAYRO ; \q_stop
- }
- \cs_new_nopar:Npn \@@_if_outer_macro_aux:w #1 OUZER ~ MAYRO ; #2 \q_stop
+ \bool_if:nTF { \tl_if_single_p:n {#1} && \tl_if_head_is_group_p:n {#1} }
+ { \@@_tl_remove_outer_braces:w #1 \q_stop }
+ { \tl_trim_spaces:n {#1} }
+ }
+% \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} } }
{
- \if_cs_exist:w c_@@_prefix_#1_aux_tl \cs_end:
- \prg_return_true: \else: \prg_return_false: \fi:
+ \tl_if_empty:nTF {#2} { \xapptocmd {#1} {#3} }
+ { \xpretocmd {#1} {#2} { \xapptocmd {#1} {#3} } { \use_ii:nn } }
}
- \tl_new:c { c_@@_prefix_/_aux_tl }
- \tl_new:c { c_@@_prefix_/long/_aux_tl }
- \tl_new:c { c_@@_prefix_/protected/_aux_tl }
- \tl_new:c { c_@@_prefix_/protected/long/_aux_tl }
+ { \@@_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}
+\cs_new_eq:NN \xeCJK_cs_clear:N \tl_clear:N
+\cs_new_eq:NN \xeCJK_cs_gclear:N \tl_gclear:N
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[TF,internal]{\xeCJK_peek_catcode_ignore_spaces:N}
-% 对 \pkg{l3token} 打的补丁,使 \cs{xeCJK_peek_catcode_ignore_spaces:NTF} 等可
-% 用于 \cs{outer} 宏。
+% \begin{macro}[internal]{\xeCJK_swap_cs:NN}
+% 交换 |#1| 和 |#2| 的意义。
% \begin{macrocode}
-\token_new:Nn \l_@@_peek_search_token { ? }
-\cs_new_protected:Npn \xeCJK_peek_catcode_ignore_spaces:NTF #1#2#3
+\cs_new_protected:Npn \xeCJK_swap_cs:NN #1#2
{
- \cs_set_eq:NN \l_@@_peek_search_token #1 \prg_do_nothing:
- \tl_set:Nn \@@_peek_true:w { \group_align_safe_end: #2 }
- \tl_set:Nn \@@_peek_false:w { \group_align_safe_end: #3 }
- \group_align_safe_begin:
- \peek_after:Nw \@@_peek_ignore_spaces_execute_branches:
+ \cs_set_eq:NN \@@_swap_cs_aux:w #1
+ \cs_set_eq:NN #1 #2
+ \cs_set_eq:NN #2 \@@_swap_cs_aux:w
+ \cs_undefine:N \@@_swap_cs_aux:w
}
-\cs_new_protected:Npn \xeCJK_peek_catcode_ignore_spaces:NT #1#2
- { \xeCJK_peek_catcode_ignore_spaces:NTF #1 {#2} { } }
-\cs_new_protected:Npn \xeCJK_peek_catcode_ignore_spaces:NF #1#2
- { \xeCJK_peek_catcode_ignore_spaces:NTF #1 { } {#2} }
-\cs_new_nopar:Npn \@@_peek_ignore_spaces_execute_branches:
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\xeCJK_font_gset_to_current:c}
+% |#1| 是控制序列的名字,令它等于当前字体命令。
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \xeCJK_font_gset_to_current:c #1
{
- \if_meaning:w \l_peek_token \c_space_token
- \tex_afterassignment:D \@@_peek_ignore_spaces_execute_branches_aux:
- \exp_after:wN \cs_set_eq:NN \exp_after:wN \@@_peek_tmp:w
- \else:
- \exp_after:wN \@@_peek_execute_branches_catcode:
- \fi:
+ \exp_after:wN \cs_gset_eq:NN
+ \cs:w #1 \exp_after:wN \cs_end: \tex_the:D \tex_font:D
}
-\cs_new_protected_nopar:Npn \@@_peek_ignore_spaces_execute_branches_aux:
- { \peek_after:Nw \@@_peek_ignore_spaces_execute_branches: }
-\cs_new_nopar:Npn \@@_peek_execute_branches_catcode:
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal,pTF]{\xeCJK_glyph_if_exist:N}
+% \changes{v3.1.0}{2012/11/19}{改进 \pkg{fontspec} 宏包中定义的
+% \cs{font_glyph_if_exist:NnTF}。}
+% 判断当前字体中是否含有字符 |#1|。\pkg{fontspec} 中的类似函数在判断为真的时候,
+% 会留有一个 \cs{scan_stop:},造成不必要的边界,同时也不完全可展。因此,我们重新
+% 定义它。
+% \begin{macrocode}
+\prg_new_conditional:Npnn \xeCJK_glyph_if_exist:N #1 { p , T , F , TF }
{
- \if_catcode:w \exp_not:N \l_peek_token \exp_not:N \l_@@_peek_search_token
- \exp_after:wN \@@_peek_true:w
- \else:
- \exp_after:wN \@@_peek_false:w
- \fi:
+ \etex_iffontchar:D \tex_font:D `#1 \exp_stop_f:
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal,var]{\c_xeCJK_space_skip_tl}
+% \changes{v3.1.0}{2012/11/18}{字间空格考虑 \cs{spaceskip} 不为零的情况。}
+% 当前字体状态下,一个字间空格产生的 |glue| 的长度,包括伸展和收缩部分。
+% 没有考虑到 \cs{xspaceskip} 和 \cs{spacefactor} 的情况。
+% \begin{macrocode}
+\tl_const:Nn \c_xeCJK_space_skip_tl
+ {
+ \skip_if_eq:nnTF \tex_spaceskip:D \c_zero_skip
+ {
+ \tex_fontdimen:D \c_two \tex_font:D
+ plus \tex_fontdimen:D \c_three \tex_font:D
+ minus \tex_fontdimen:D \c_four \tex_font:D
+ }
+ { \tex_spaceskip:D }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\xeCJK_glue_to_skip:nN}
+% 取得一个 |glue| 的长度,包括伸展和收缩部分。
+% \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
}
% \end{macrocode}
% \end{macro}
@@ -1119,42 +1430,39 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
% \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_@@_pkg_extension_tl }
- { \prg_return_true: } { \prg_return_false: }
+ \tl_if_exist:cTF { ver@ #1 . \c_@@_package_ext_tl }
+ { \prg_return_true: }
+ { \prg_return_false: }
}
-\tl_const:Nx \c_@@_pkg_extension_tl { \@pkgextension }
+\tl_const:Nx \c_@@_package_ext_tl { \@pkgextension }
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]
-% {\@@_msg_new:nn ,\@@_error:n,\@@_error:nx,\@@_warning:nx,\@@_info:nx,\@@_info:nxx}
-% 各种信息函数的缩略形式。
+% \begin{macro}[internal]{\xeCJK_int_until_do:nn,\@@_int_until_do:wn}
+% 由于定义较为简单,可以比 \cs{int_until_do:nNnn} 稍微快一点点。
% \begin{macrocode}
-\cs_new_nopar:Npn \@@_msg_new:nn { \msg_new:nnn { xeCJK } }
-\cs_new_nopar:Npn \@@_error:n { \msg_error:nn { xeCJK } }
-\cs_new_nopar:Npn \@@_error:nx { \msg_error:nnx { xeCJK } }
-\cs_new_nopar:Npn \@@_warning:n { \msg_warning:nn { xeCJK } }
-\cs_new_nopar:Npn \@@_warning:nx { \msg_warning:nnx { xeCJK } }
-\cs_new_nopar:Npn \@@_warning:nxx { \msg_warning:nnxx { xeCJK } }
-\cs_new_nopar:Npn \@@_info:nx { \msg_info:nnx { xeCJK } }
-\cs_new_nopar:Npn \@@_info:nxx { \msg_info:nnxx { xeCJK } }
+\cs_new_protected:Npn \xeCJK_int_until_do:nn #1#2
+ { \@@_int_until_do:wn \use_none:n { \reverse_if:N \if_int_compare:w #1#2 } }
+\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}
%
% \subsection{功能开关}
%
% \begin{macro}{xeCJKactive}
+% 事实上,将开启或关闭 \XeTeX 的整个字符类机制。
% \begin{macrocode}
\keys_define:nn { xeCJK / options }
{
- xeCJKactive .choice:,
+ xeCJKactive .choice: ,
xeCJKactive / true .code:n = { \makexeCJKactive } ,
xeCJKactive / false .code:n = { \makexeCJKinactive } ,
- xeCJKactive .default:n = { true },
+ xeCJKactive .default:n = { true }
}
% \end{macrocode}
% \end{macro}
@@ -1179,7 +1487,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
% \begin{center}\punctstyle{plain}
% \begin{tabular}{cll}
% \toprule
-% 类别 & 说明 & 例子 \\ \midrule
+% 类别 & 说明 & 例子 \\ \midrule
% |Default| & 西文一般符号 & abc123 \\
% |CJK| & CJK 表意符号 & 汉字ぁぃぅ \\
% |FullLeft| & 全角左标点 & (《:“ \\
@@ -1187,28 +1495,26 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
% |HalfLeft| & 半角左标点 & ( [ \{ \\
% |HalfRight| & 半角右标点 & , . ? ) ] \} \\
% |NormalSpace| & 前后原始间距的符号 & / \\
-% |Boundary| & 边界 & 空格 \\
+% |Boundary| & 边界 & 空格 \\
% \bottomrule
% \end{tabular}
% \end{center}
%
-% \begin{macro}[internal,var]
-% { \c_@@_Default_class_int, \c_@@_CJK_class_int, \c_@@_FullLeft_class_int,
-% \c_@@_FullRight_class_int, \c_@@_Boundary_class_int }
+% \begin{macro}[internal,var]{Default,CJK,FullLeft,FullRight,Boundary}
% 这五类是 \XeTeX\ 预定义的类别。
% \begin{macrocode}
-\int_const:Nn \c_@@_Default_class_int { 0 }
-\int_const:Nn \c_@@_CJK_class_int { 1 }
-\int_const:Nn \c_@@_FullLeft_class_int { 2 }
-\int_const:Nn \c_@@_FullRight_class_int { 3 }
-\int_const:Nn \c_@@_Boundary_class_int { 255 }
+\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 }
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\@@_new_class:n,\g_@@_class_seq}
+% \begin{macro}[internal]{\xeCJK_new_class:n,\g_@@_class_seq}
% 新建一个字符类别。
% \begin{macrocode}
-\cs_new_protected_nopar:Npn \@@_new_class:n #1
+\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 }
@@ -1218,397 +1524,453 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal,var]
-% { \c_@@_HalfLeft_class_int, \c_@@_HalfRight_class_int, \c_@@_NormalSpace_class_int }
+% \begin{macro}[internal,var]{HalfLeft,HalfRight,NormalSpace}
% 新增西文半角左/右标点和前后原始间距的符号类。
% \begin{macrocode}
-\@@_new_class:n { HalfLeft }
-\@@_new_class:n { HalfRight }
-\@@_new_class:n { NormalSpace }
+\xeCJK_new_class:n { HalfLeft }
+\xeCJK_new_class:n { HalfRight }
+\xeCJK_new_class:n { NormalSpace }
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal,var]
-% {\g_@@_base_class_clist,\g_@@_CJK_class_clist,\g_@@_CJK_class_prop}
+% \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} 设置的各个字符类的默认范围。}
% \begin{macrocode}
-\clist_set:Nn \g_@@_base_class_clist
+\clist_const:Nn \c_@@_HalfLeft_chars_clist
+ { "28 , "2D , "5B , "60 , "7B }
+\clist_const:Nn \c_@@_HalfRight_chars_clist
+ { "21 , "22 , "25 , "27 , "29 , "2C , "2E , "3A , "3B , "3F , "5D , "7D }
+\clist_const:Nn \c_@@_NormalSpace_chars_clist { "2F }
+\clist_const:Nn \c_@@_FullLeft_chars_clist
{
- Default, CJK, FullLeft, FullRight, Boundary,
- HalfLeft, HalfRight, NormalSpace
+ "2018 , "201C , "2116 , "3008 , "300A , "300C , "300E , "3010 , "3012 ,
+ "3014 , "3016 , "3018 , "301A , "301D , "3036 , "E76C , "FE59 , "FE5B ,
+ "FE5D , "FE5F , "FE60 , "FE69 , "FE6B , "FF03 , "FF04 , "FF08 , "FF20 ,
+ "FF3B , "FF5B , "FFE0 , "FFE1 , "FFE5 , "FFE6
}
-\clist_map_inline:Nn \g_@@_base_class_clist
- { \clist_gclear_new:c { g_@@_#1_range_clist } }
-\clist_new:N \g_@@_CJK_class_clist
-\prop_new:N \g_@@_CJK_class_prop
-\cs_new_protected_nopar:Npn \@@_save_CJK_class:n #1
- {
- \clist_gput_right:Nx \g_@@_CJK_class_clist {#1}
- \prop_gput:Nvx \g_@@_CJK_class_prop { c_@@_#1_class_int } {#1}
- }
-\cs_generate_variant:Nn \prop_gput:Nnn { Nvx }
-\clist_map_function:nN { CJK, FullLeft, FullRight } \@@_save_CJK_class:n
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\@@_class_num:n}
-% |#1| 为字符类别名称,用于取得字符类别对应的编号。
-% \begin{macrocode}
-\cs_new_nopar:Npn \@@_class_num:n #1 { \tl_use:c { c_@@_#1_class_int } }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\xeCJKDeclareCharClass}
-% \begin{macro}[aux]{\@@_set_char_class_aux:Nn}
-% 用于设置字符所属的类别,|#1| 为类别名称,|#2| 为字符的 |Unicode|,相邻字符用
-% 半角逗号隔开,支持类似 |"1100 -> "11FF| 起止范围的使用方式。
-% \begin{macrocode}
-\NewDocumentCommand \xeCJKDeclareCharClass { s > { \TrimSpaces } m m }
+\clist_const:Nn \c_@@_FullRight_chars_clist
{
- \@@_declare_char_class:nn {#2} {#3}
- \IfBooleanT {#1} { \xeCJKResetPunctClass }
+ "00B7 , "2019 , "201D , "2014 , "2015 , "2025 , "2026 , "2030 , "2500 ,
+ "3001 , "3002 , "3005 , "3006 , "3009 , "300B , "300D , "300F , "3011 ,
+ "3015 , "3017 , "3019 , "301B , "301E , "301F , "3041 , "3043 , "3045 ,
+ "3047 , "3049 , "3063 , "3083 , "3085 , "3087 , "308E , "309B , "309C ,
+ "309D , "309E , "30A1 , "30A3 , "30A5 , "30A7 , "30A9 , "30C3 , "30E3 ,
+ "30E5 , "30E7 , "30EE , "30F5 , "30F6 , "30FB , "30FC , "30FD , "30FE ,
+ "FE50 , "FE51 , "FE52 , "FE54 , "FE55 , "FE56 , "FE57 , "FE5A , "FE5C ,
+ "FE5E , "FE6A , "FF01 , "FF05 , "FF09 , "FF0C , "FF0E , "FF1A , "FF1B ,
+ "FF1F , "FF3D , "FF5D , "FF61 , "FF63 , "FF64 , "FF65 , "FF67 , "FF68 ,
+ "FF69 , "FF6A , "FF6B , "FF6C , "FF6D , "FF6E , "FF6F , "FF70 , "FF9E ,
+ "FF9F
}
-\cs_new_protected_nopar:Npn \@@_declare_char_class:nn #1#2
+\clist_const:Nn \c_@@_CJK_chars_clist
{
- \clist_gput_right:cx { g_@@_#1_range_clist } {#2}
- \clist_map_inline:xn {#2}
- {
- \str_if_eq_x:nnF {##1} { -> }
- {
- \@@_set_char_class_aux:Nn \@@_set_char_class:nnn {##1}
- { \@@_class_num:n {#1} }
- }
- }
- }
-\NewDocumentCommand \@@_set_char_class_aux:Nn
- { m > { \SplitArgument { 1 } { -> } } m } { #1 #2 }
-\cs_generate_variant:Nn \clist_map_inline:nn { x }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}[internal]{\xeCJKsetcharclass}
-% |#1| 和 |#2| 为字符类别起止的 |Unicode|,|#3| 为类别名称对应编号。
-% \begin{macrocode}
-\NewDocumentCommand \xeCJKsetcharclass { s m m m }
- {
- \@@_set_char_class:nnn {#2} {#3} {#4}
- \IfBooleanF {#1} { \xeCJKResetPunctClass }
- }
-\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}
- \prop_if_in:NVTF \g_@@_CJK_class_prop \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 }
- {
- \@@_set_char_catcode:n { \l_@@_tmpa_int }
- \XeTeXcharclass \l_@@_tmpa_int = \l_@@_tmpc_int
- \int_incr:N \l_@@_tmpa_int
- }
- }
% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\xeCJK_int_until_do:nn}
-% \begin{macro}[aux]{\@@_int_until_do_aux:wn}
-% \begin{macrocode}
-\cs_new_protected:Npn \xeCJK_int_until_do:nn #1#2
- {
- \@@_int_until_do_aux:wn \use_none:n
- { \reverse_if:N \if_int_compare:w #1#2 }
- }
-\cs_new_protected:Npn \@@_int_until_do_aux:wn \use_none:n #1
- {
- #1 \exp_after:wN \@@_int_until_do_aux:wn \fi:
- \use_none:n {#1}
- }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}[internal]{\@@_check_num_range:nnNN}
-% \begin{macrocode}
-\cs_new_protected_nopar:Npn \@@_check_num_range:nnNN #1#2#3#4
- {
- \bool_if:nTF { \xeCJK_if_blank_x_p:n {#1} || \xeCJK_if_blank_x_p:n {#2} }
- {
- \int_set:Nn #3 { \xeCJK_if_blank_x:nTF {#1} {#2} {#1} }
- \int_set_eq:NN #3 #4
- }
- {
- \int_set:Nn #3 { \int_min:nn {#1} { \IfNoValueTF {#2} {#1} {#2} } }
- \int_set:Nn #4 { \int_max:nn {#1} { \IfNoValueTF {#2} {#1} {#2} } }
- }
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\xeCJKResetPunctClass}
-% 用于重置标点符号所属的字符类。
-% \begin{macrocode}
-\NewDocumentCommand \xeCJKResetPunctClass { }
- {
- \@@_declare_char_class:nn { HalfLeft }
- { "28 , "2D , "5B , "60 , "7B }
- \@@_declare_char_class:nn { HalfRight }
- { "21 , "22 , "25 , "27 , "29 , "2C , "2E , "3A , "3B , "3F , "5D , "7D , }
- \@@_declare_char_class:nn { FullLeft }
- {
- "2018 , "201C , "2116 , "3008 , "300A , "300C , "300E , "3010 , "3012 ,
- "3014 , "3016 , "3018 , "301A , "301D , "3036 , "E76C , "FE59 , "FE5B ,
- "FE5D , "FE5F , "FE60 , "FE69 , "FE6B , "FF03 , "FF04 , "FF08 , "FF20 ,
- "FF3B , "FF5B , "FFE0 , "FFE1 , "FFE5 , "FFE6 ,
- }
- \@@_declare_char_class:nn { FullRight }
- {
- "00B7 , "2019 , "201D , "2014 , "2015 , "2025 , "2026 , "2030 , "2500 ,
- "3001 , "3002 , "3005 , "3006 , "3009 , "300B , "300D , "300F , "3011 ,
- "3015 , "3017 , "3019 , "301B , "301E , "301F , "3041 , "3043 , "3045 ,
- "3047 , "3049 , "3063 , "3083 , "3085 , "3087 , "308E , "309B , "309C ,
- "309D , "309E , "30A1 , "30A3 , "30A5 , "30A7 , "30A9 , "30C3 , "30E3 ,
- "30E5 , "30E7 , "30EE , "30F5 , "30F6 , "30FB , "30FC , "30FD , "30FE ,
- "FE50 , "FE51 , "FE52 , "FE54 , "FE55 , "FE56 , "FE57 , "FE5A , "FE5C ,
- "FE5E , "FE6A , "FF01 , "FF05 , "FF09 , "FF0C , "FF0E , "FF1A , "FF1B ,
- "FF1F , "FF3D , "FF5D , "FF61 , "FF63 , "FF64 , "FF65 , "FF67 , "FF68 ,
- "FF69 , "FF6A , "FF6B , "FF6C , "FF6D , "FF6E , "FF6F , "FF70 , "FF9E ,
- "FF9F ,
- }
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \hypertarget{CJKcharclass}{设置 CJK 文字的范围}。
-% \begin{macrocode}
-\@@_declare_char_class:nn { CJK }
- {
-% \end{macrocode}
-% \begin{itemize}
+% \begin{itemize}[nosep,leftmargin=0pt]
% \item Hangul Jamo (谚文字母)
% \begin{macrocode}
- "1100 -> "11FF ,
+ "1100 -> "11FF ,
% \end{macrocode}
% \item CJK Radicals Supplement (中日韩部首补充)
% \begin{macrocode}
- "2E80 -> "2EFF ,
+ "2E80 -> "2EFF ,
% \end{macrocode}
% \item Kangxi Radicals (康熙部首)
% \begin{macrocode}
- "2F00 -> "2FDF ,
+ "2F00 -> "2FDF ,
% \end{macrocode}
% \item Ideographic Description Characters (表意文字描述符)
% \begin{macrocode}
- "2FF0 -> "2FFF ,
+ "2FF0 -> "2FFF ,
% \end{macrocode}
% \item CJK Symbols and Punctuation (中日韩符号和标点)
% \begin{macrocode}
- "3000 -> "303F ,
+ "3000 -> "303F ,
% \end{macrocode}
% \item Hiragana (日文平假名)
% \begin{macrocode}
- "3040 -> "309F ,
+ "3040 -> "309F ,
% \end{macrocode}
% \item Katakana (日文片假名)
% \begin{macrocode}
- "30A0 -> "30FF ,
+ "30A0 -> "30FF ,
% \end{macrocode}
% \item Bopomofo (注音字母)
% \begin{macrocode}
- "3100 -> "312F ,
+ "3100 -> "312F ,
% \end{macrocode}
% \item Hangul Compatibility Jamo (谚文兼容字母)
% \begin{macrocode}
- "3130 -> "318F ,
+ "3130 -> "318F ,
% \end{macrocode}
% \item Kanbun (象形字注释标志)
% \begin{macrocode}
- "3190 -> "319F ,
+ "3190 -> "319F ,
% \end{macrocode}
% \item Bopomofo Extended (注音字母扩展)
% \begin{macrocode}
- "31A0 -> "31BF ,
+ "31A0 -> "31BF ,
% \end{macrocode}
% \item CJK Strokes (中日韩笔画)
% \begin{macrocode}
- "31C0 -> "31EF ,
+ "31C0 -> "31EF ,
% \end{macrocode}
% \item Katakana Phonetic Extensions (日文片假名语音扩展)
% \begin{macrocode}
- "31F0 -> "31FF ,
+ "31F0 -> "31FF ,
% \end{macrocode}
% \item Enclosed CJK Letters and Months (带圈中日韩字母和月份)
% \begin{macrocode}
- "3200 -> "32FF ,
+ "3200 -> "32FF ,
% \end{macrocode}
% \item CJK Compatibility (中日韩兼容)
% \begin{macrocode}
- "3300 -> "33FF ,
+ "3300 -> "33FF ,
% \end{macrocode}
% \item CJK Unified Ideographs Extension-A (中日韩统一表意文字扩展 A)
% \begin{macrocode}
- "3400 -> "4DBF ,
+ "3400 -> "4DBF ,
% \end{macrocode}
% \item Yijing Hexagrams Symbols (易经六十四卦符号)
% \begin{macrocode}
- "4DC0 -> "4DFF ,
+ "4DC0 -> "4DFF ,
% \end{macrocode}
% \item CJK Unified Ideographs (中日韩统一表意文字)
% \begin{macrocode}
- "4E00 -> "9FFF ,
+ "4E00 -> "9FFF ,
% \end{macrocode}
% \item Yi Syllables (彝文音节)
% \begin{macrocode}
- "A000 -> "A48F ,
+ "A000 -> "A48F ,
% \end{macrocode}
% \item Yi Radicals (彝文字根)
% \begin{macrocode}
- "A490 -> "A4CF ,
+ "A490 -> "A4CF ,
% \end{macrocode}
% \item Hangul Jamo Extended-A (谚文扩展 A)
% \begin{macrocode}
- "A960 -> "A97F ,
+ "A960 -> "A97F ,
% \end{macrocode}
% \item Hangul Syllables (谚文音节)
% \begin{macrocode}
- "AC00 -> "D7AF ,
+ "AC00 -> "D7AF ,
% \end{macrocode}
% \item Kana Supplement (日文假名增补)
% \begin{macrocode}
- "B000 -> "B0FF ,
+ "B000 -> "B0FF ,
% \end{macrocode}
% \item Hangul Jamo Extended-B (谚文扩展 B)
% \begin{macrocode}
- "D7B0 -> "D7FF ,
+ "D7B0 -> "D7FF ,
% \end{macrocode}
% \item CJK Compatibility Ideographs (中日韩兼容表意文字)
% \begin{macrocode}
- "F900 -> "FAFF ,
+ "F900 -> "FAFF ,
% \end{macrocode}
% \item CJK Compatibility Forms (中日韩兼容形式)
% \begin{macrocode}
- "FE30 -> "FE4F ,
+ "FE30 -> "FE4F ,
% \end{macrocode}
% \item Halfwidth and Fullwidth Forms (半角及全角形式)
% \begin{macrocode}
- "FF00 -> "FFEF ,
+ "FF00 -> "FFEF ,
% \end{macrocode}
% \item CJK Unified Ideographs Extension-B (中日韩统一表意文字扩展 B)
% \begin{macrocode}
- "20000 -> "2A6DF ,
+ "20000 -> "2A6DF ,
% \end{macrocode}
% \item CJK Unified Ideographs Extension-C (中日韩统一表意文字扩展 C)
% \begin{macrocode}
- "2A700 -> "2B73F ,
+ "2A700 -> "2B73F ,
% \end{macrocode}
% \item CJK Unified Ideographs Extension-D (中日韩统一表意文字扩展 D)
% \begin{macrocode}
- "2B740 -> "2B81F ,
+ "2B740 -> "2B81F ,
% \end{macrocode}
% \item CJK Compatibility Ideographs Supplement (中日韩兼容表意文字增补)
% \begin{macrocode}
- "2F800 -> "2FA1F ,
+ "2F800 -> "2FA1F
% \end{macrocode}
% \end{itemize}
% \begin{macrocode}
}
% \end{macrocode}
+% \end{macro}
+%
+% \subsection{字符类别处理}
+%
+% \begin{macro}[internal,var]
+% {\g_@@_base_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_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}
+ }
+\cs_generate_variant:Nn \prop_gput:Nnn { Nvn }
+\clist_map_function:nN { CJK , FullLeft , FullRight } \@@_save_CJK_class:n
+% \end{macrocode}
+% \end{macro}
+%
+% \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:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\xeCJKDeclareCharClass}
+% \begin{macrocode}
+\NewDocumentCommand \xeCJKDeclareCharClass { s > { \TrimSpaces } m m }
+ {
+ \xeCJK_declare_char_class:nx {#2} {#3}
+ \IfBooleanT {#1} { \xeCJKResetPunctClass }
+ }
+% \end{macrocode}
+% \end{macro}
%
-% 重置标点符号的字符类。
+% \begin{macro}[internal]{\xeCJK_declare_char_class:nn,\@@_set_char_class_aux:Nnw}
+% 用于设置字符所属的类别,|#1| 为类别名称,|#2| 为字符的 |Unicode|,相邻字符用
+% 半角逗号隔开,支持类似 |"1100 -> "11FF| 起止范围的使用方式。
% \begin{macrocode}
-\xeCJKResetPunctClass
+\cs_new_protected_nopar:Npn \xeCJK_declare_char_class:nn #1#2
+ {
+ \clist_set:Nn \l_@@_tmpa_clist {#2}
+ \clist_gconcat:ccN
+ { g_@@_#1_range_clist } { g_@@_#1_range_clist } \l_@@_tmpa_clist
+ \clist_map_inline:Nn \l_@@_tmpa_clist
+ {
+ \str_if_eq:nnF {##1} { -> }
+ {
+ \@@_set_char_class_aux:Nnw \xeCJK_set_char_class:nnn {##1}
+ { \xeCJK_class_num:n {#1} }
+ }
+ }
+ }
+\NewDocumentCommand \@@_set_char_class_aux:Nnw
+ { m > { \SplitArgument { 1 } { -> } } m } { #1 #2 }
+\cs_generate_variant:Nn \clist_gconcat:NNN { cc }
+\cs_generate_variant:Nn \xeCJK_declare_char_class:nn { nx , nV }
% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\xeCJK_set_char_class:nnn}
+% |#1| 和 |#2| 为字符类别起止的 |Unicode|,|#3| 为类别名称对应编号。
+% \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
+ {
+ \@@_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
+ { \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 }
+ {
+ \@@_set_char_catcode:n { \l_@@_tmpa_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
+ {
+ \bool_if:nTF { \xeCJK_if_blank_x_p:n {#1} || \xeCJK_if_blank_x_p:n {#2} }
+ {
+ \int_set:Nn #3 { \xeCJK_if_blank_x:nTF {#1} {#2} {#1} }
+ \int_set_eq:NN #3 #4
+ }
+ {
+ \int_set:Nn #3 { \int_min:nn {#1} { \IfNoValueTF {#2} {#1} {#2} } }
+ \int_set:Nn #4 { \int_max:nn {#1} { \IfNoValueTF {#2} {#1} {#2} } }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\@@_set_char_class_eq:nn}
+% 将字符类 |#2| 中的字符全部设置成字符类 |#1|。只使用于 |#2| 的字符类范围为离散的
+% 逗号列表的情况。
+% \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 }
+ { \XeTeXcharclass ##1 = \l_@@_tmpa_int }
+ }
+% \end{macrocode}
+% \end{macro}
%
% \begin{macro}{\normalspacedchars}
% 声明前后不加间距的字符。
% \begin{macrocode}
\NewDocumentCommand \normalspacedchars { m }
{
- \tl_map_inline:nn {#1}
- { \XeTeXcharclass `##1 = \@@_class_num:n { NormalSpace } }
+ \tl_map_inline:xn {#1}
+ { \XeTeXcharclass `##1 = \xeCJK_class_num:n { NormalSpace } }
}
-\normalspacedchars{/}
+\cs_generate_variant:Nn \tl_map_inline:nn { x }
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]
-% {\@@_inter_class_toks:nnn,\@@_inter_class_toks:nnc,\@@_inter_class_toks:nnx}
+% \begin{macro}{\xeCJKResetPunctClass}
+% 用于重置标点符号所属的字符类。
+% \begin{macrocode}
+\NewDocumentCommand \xeCJKResetPunctClass { }
+ {
+ \xeCJK_declare_char_class:nV { HalfLeft } \c_@@_HalfLeft_chars_clist
+ \xeCJK_declare_char_class:nV { HalfRight } \c_@@_HalfRight_chars_clist
+ \xeCJK_declare_char_class:nV { FullLeft } \c_@@_FullLeft_chars_clist
+ \xeCJK_declare_char_class:nV { FullRight } \c_@@_FullRight_chars_clist
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\xeCJKResetCharClass}
+% 用于恢复 \pkg{xeCJK} 对字符类别的设置。
+% \begin{macrocode}
+\NewDocumentCommand \xeCJKResetCharClass { }
+ {
+ \xeCJK_declare_char_class:nV { CJK } \c_@@_CJK_chars_clist
+ \xeCJK_declare_char_class:nV { NormalSpace } \c_@@_NormalSpace_chars_clist
+ \xeCJKResetPunctClass
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% 设置字符类别。
+% \begin{macrocode}
+\xeCJKResetCharClass
+% \end{macrocode}
+%
+% \begin{macro}[internal]{\xeCJK_inter_class_toks:nnn}
% 在相邻类别之间插入内容。
% \begin{macrocode}
-\cs_new_protected_nopar:Npn \@@_inter_class_toks:nnn #1#2#3
- { \XeTeXinterchartoks \@@_class_num:n {#1} \@@_class_num:n {#2} = {#3} }
-\cs_generate_variant:Nn \@@_inter_class_toks:nnn { nnc , nnx }
+\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 }
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\@@_get_inter_class_toks:nn}
+% \begin{macro}[internal]{\xeCJK_get_inter_class_toks:nn}
% 取出相邻类别之间的内容。
% \begin{macrocode}
-\cs_new_nopar:Npn \@@_get_inter_class_toks:nn #1#2
- { \tex_the:D \XeTeXinterchartoks \@@_class_num:n {#1} \@@_class_num:n {#2} }
+\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} }
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\@@_clear_inter_class_toks:nn}
+% \begin{macro}[internal]{\xeCJK_clear_inter_class_toks:nn}
% 清除相邻类别之间的内容。
% \begin{macrocode}
-\cs_new_protected_nopar:Npn \@@_clear_inter_class_toks:nn #1#2
- { \@@_inter_class_toks:nnn {#1} {#2} { \c_empty_tl } }
+\cs_new_protected_nopar:Npn \xeCJK_clear_inter_class_toks:nn #1#2
+ { \xeCJK_inter_class_toks:nnn {#1} {#2} { \prg_do_nothing: } }
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\@@_pre_inter_class_toks:nnn}
+% \begin{macro}[internal]{\xeCJK_pre_inter_class_toks:nnn}
% 在相邻类别之间已有的内容前增加内容。
% \begin{macrocode}
-\cs_new_protected_nopar:Npn \@@_pre_inter_class_toks:nnn #1#2#3
+\cs_new_protected_nopar:Npn \xeCJK_pre_inter_class_toks:nnn #1#2#3
{
- \@@_inter_class_toks:nnx {#1} {#2}
- { \exp_not:n {#3} \@@_get_inter_class_toks:nn {#1} {#2} }
+ \xeCJK_inter_class_toks:nnx {#1} {#2}
+ { \exp_not:n {#3} \xeCJK_get_inter_class_toks:nn {#1} {#2} }
}
+\cs_generate_variant:Nn \xeCJK_pre_inter_class_toks:nnn { nnx }
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\@@_app_inter_class_toks:nnn,\@@_app_inter_class_toks:nnc}
+% \begin{macro}[internal]{\xeCJK_app_inter_class_toks:nnn}
% 在相邻类别之间已有的内容后追加内容。
% \begin{macrocode}
-\cs_new_protected_nopar:Npn \@@_app_inter_class_toks:nnn #1#2#3
+\cs_new_protected_nopar:Npn \xeCJK_app_inter_class_toks:nnn #1#2#3
{
- \@@_inter_class_toks:nnx {#1} {#2}
- { \@@_get_inter_class_toks:nn {#1} {#2} \exp_not:n {#3} }
+ \xeCJK_inter_class_toks:nnx {#1} {#2}
+ { \xeCJK_get_inter_class_toks:nn {#1} {#2} \exp_not:n {#3} }
}
-\cs_generate_variant:Nn \@@_app_inter_class_toks:nnn { nnc }
+\cs_generate_variant:Nn \xeCJK_app_inter_class_toks:nnn { nnc , nnx }
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\@@_copy_inter_class_toks:nnnn}
+% \begin{macro}[internal]{\xeCJK_copy_inter_class_toks:nnnn}
% 将 |#3| 和 |#4| 之间的内容复制到 |#1| 和 |#2| 之间。
% \begin{macrocode}
-\cs_new_protected_nopar:Npn \@@_copy_inter_class_toks:nnnn #1#2#3#4
+\cs_new_protected_nopar:Npn \xeCJK_copy_inter_class_toks:nnnn #1#2#3#4
{
- \@@_inter_class_toks:nnx {#1} {#2}
- { \@@_get_inter_class_toks:nn {#3} {#4} }
+ \xeCJK_inter_class_toks:nnx {#1} {#2}
+ { \xeCJK_get_inter_class_toks:nn {#3} {#4} }
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\@@_clear_CJK_toks:}
-% 清除边界与 CJK 文字、全角左右标点之间的内容。
+% \begin{macro}[internal]{\xeCJK_replace_inter_class_toks:nnnn}
+% 将 |#1| 和 |#2| 之间出现的 |#3| 用 |#4| 替换。
% \begin{macrocode}
-\cs_new_protected_nopar:Npn \@@_clear_CJK_toks:
+\cs_new_protected_nopar:Npn \xeCJK_replace_inter_class_toks:nnnn #1#2#3#4
{
- \clist_map_inline:Nn \g_@@_CJK_class_clist
- { \@@_clear_inter_class_toks:nn { Boundary } {##1} }
+ \tl_set:Nx \l_@@_tmpa_tl { \xeCJK_get_inter_class_toks:nn {#1} {#2} }
+ \tl_replace_all:Nnn \l_@@_tmpa_tl {#3} {#4}
+ \xeCJK_inter_class_toks:nnx {#1} {#2} { \exp_not:V \l_@@_tmpa_tl }
}
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}[internal]{\xeCJK_clear_Boundary_and_CJK_toks:}
+% 清除边界与 CJK 文字、全角左右标点之间的内容。
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \xeCJK_clear_Boundary_and_CJK_toks:
+ { \seq_map_function:NN \g_@@_CJK_class_seq \@@_clear_Boundary_and_CJK_toks:n }
+\cs_new_protected_nopar:Npn \@@_clear_Boundary_and_CJK_toks:n #1
+ { \xeCJK_clear_inter_class_toks:nn { Boundary } {#1} }
+% \end{macrocode}
+% \end{macro}
+%
% \subsection{字符输出规则}
%
-% \hspace*{-.8\marginparwidth}
+% \begin{center}
% \begin{tabular}{l*8c}
% \toprule
-% & |Default| & |CJK| & |FullLeft| & |FullRight| & |HalfLeft|
-% & |HalfRight| & |NormalSpace| & |Boundary| \\ \midrule
+% & |Default| & |CJK| & |FullL| & |FullR| & |HalfL|
+% & |HalfR| & |Normal| & |Bound| \\ \midrule
% |Default|
% &
% & \tokslink{def-cjk}
@@ -1629,22 +1991,22 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
% & \tokslink{cjk-bound}\\
% |FullLeft|
% & \tokslink{def-cjk}
-% & \tokslink{fl-fr-bound-cjk}
+% & \tokslink{fl-fr-others}
% & \tokslink{cjk-fl-fr}
% & \tokslink{cjk-fl-fr}
% & \tokslink{def-cjk}
% & \tokslink{def-cjk}
% & \tokslink{def-cjk}
-% & \tokslink{fl-fr-bound-cjk}\\
+% & \tokslink{fl-fr-others}\\
% |FullRight|
% & \tokslink{def-cjk}
-% & \tokslink{fl-fr-bound-cjk}
+% & \tokslink{fl-fr-others}
% & \tokslink{cjk-fl-fr}
% & \tokslink{cjk-fl-fr}
% & \tokslink{def-cjk}
% & \tokslink{def-cjk}
% & \tokslink{def-cjk}
-% & \tokslink{fl-fr-bound-cjk}\\
+% & \tokslink{fl-fr-others}\\
% |HalfLeft|
% &
% & \tokslink{def-cjk}
@@ -1671,159 +2033,281 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
% |Boundary|
% & \tokslink{bound-def}
% & \tokslink{bound-cjk}
-% & \tokslink{fl-fr-bound-cjk}
-% & \tokslink{fl-fr-bound-cjk}
+% & \tokslink{bound-fl-fr}
+% & \tokslink{bound-fl-fr}
% & \tokslink{bound-def}
% &
% & \tokslink{bound-def}\\
% \bottomrule
% \end{tabular}
+% \end{center}
+%
+% \begin{macro}[internal]{\xeCJK_class_group_begin:,\xeCJK_class_group_end:}
+% \begin{macrocode}
+\cs_new_eq:NN \xeCJK_class_group_begin: \c_group_begin_token
+\cs_new_eq:NN \xeCJK_class_group_end: \c_group_end_token
+% \end{macrocode}
+% \end{macro}
%
% \hypertarget{def-cjk}{}
% \begin{macrocode}
-\clist_map_inline:nn { Default, HalfLeft, HalfRight, NormalSpace }
+\clist_map_inline:nn { Default , HalfLeft , HalfRight , NormalSpace }
{
- \clist_map_inline:nn { CJK, FullLeft, FullRight }
+ \clist_map_inline:nn { CJK , FullLeft , FullRight }
{
- \@@_inter_class_toks:nnn {#1} {##1}
+ \xeCJK_inter_class_toks:nnn {#1} {##1}
{
- \c_group_begin_token
+ \xeCJK_class_group_begin:
\xeCJK_select_font:
- \@@_clear_inter_class_toks:nn {#1} {##1}
- \@@_clear_CJK_toks:
+ \xeCJK_clear_inter_class_toks:nn {#1} {##1}
+ \xeCJK_clear_Boundary_and_CJK_toks:
}
- \@@_inter_class_toks:nnn {##1} {#1} { \c_group_end_token }
+ \xeCJK_inter_class_toks:nnn {##1} {#1} { \xeCJK_class_group_end: }
}
- \@@_app_inter_class_toks:nnn {#1} { CJK } { \CJKsymbol }
- \clist_map_inline:nn { FullLeft, FullRight }
- { \@@_app_inter_class_toks:nnc {#1} {##1} { xeCJK_CJK_and_##1:N } }
+ \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 } }
}
% \end{macrocode}
%
% \hypertarget{bound-def}{}
% \begin{macrocode}
-\clist_map_inline:nn { Default, HalfLeft, NormalSpace }
+\clist_map_inline:nn { Default , HalfLeft , NormalSpace }
{
- \@@_inter_class_toks:nnn { Boundary } {#1}
+ \xeCJK_inter_class_toks:nnn { Boundary } {#1}
{
\bool_if:nTF
{
\l_@@_xecglue_bool &&
- \int_compare_p:nNn \etex_lastnodetype:D = \c_eleven &&
- \skip_if_eq_p:nn \tex_lastskip:D \l_@@_space_glue_tl
+ \skip_if_eq_p:nn \tex_lastskip:D \c_xeCJK_space_skip_tl
}
{
\tex_unskip:D
\bool_if:nTF
- { \xeCJK_if_last_node_p:n { CJK } || \xeCJK_if_last_node_p:n { CJK_space } }
+ {
+ \xeCJK_if_last_node_p:n { CJK } ||
+ \xeCJK_if_last_node_p:n { CJK-space }
+ }
{ \CJKecglue } { \c_space_token }
}
{
\xeCJK_if_last_node:nTF { CJK } { \CJKecglue }
- { \xeCJK_if_last_node:nT { CJK_space } { \@@_space_or_xecglue: } }
+ { \xeCJK_if_last_node:nT { CJK-space } { \@@_space_or_xecglue: } }
}
}
- \str_if_eq_x:nnF {#1} { NormalSpace }
- { \@@_app_inter_class_toks:nnn { CJK } {#1} { \CJKecglue } }
+ \str_if_eq:nnF {#1} { NormalSpace }
+ { \xeCJK_app_inter_class_toks:nnn { CJK } {#1} { \CJKecglue } }
}
% \end{macrocode}
%
% \hypertarget{def-bound}{}
% \begin{macrocode}
-\clist_map_inline:nn { Default, HalfRight, NormalSpace }
+\clist_map_inline:nn { Default , HalfRight , NormalSpace }
{
- \@@_inter_class_toks:nnn {#1} { Boundary }
+ \xeCJK_inter_class_toks:nnn {#1} { Boundary }
{
- \peek_catcode:NTF \c_space_token
- { { \xeCJK_make_node:n { default_space } } }
- { { \xeCJK_make_node:n { default } } }
+ \peek_meaning_remove:NTF \/
+ { \/ { \xeCJK_make_node:n { default } } }
+ {
+ \token_if_space:NTF \l_peek_token
+ { { \xeCJK_make_node:n { default-space } } }
+ { { \xeCJK_make_node:n { default } } }
+ }
}
- \str_if_eq_x:nnF {#1} { NormalSpace }
- { \@@_pre_inter_class_toks:nnn {#1} { CJK } { \CJKecglue } }
+ \str_if_eq:nnF {#1} { NormalSpace }
+ { \xeCJK_pre_inter_class_toks:nnn {#1} { CJK } { \CJKecglue } }
}
% \end{macrocode}
%
% \hypertarget{bound-cjk}{}
% \begin{macrocode}
-\@@_inter_class_toks:nnn { Boundary } { CJK } { \xeCJK_Boundary_and_CJK: }
-% \end{macrocode}
-%
-% \begin{macro}[internal]{\xeCJK_Boundary_and_CJK:,\@@_check_for_glue:}
-% \begin{macrocode}
-\cs_new_protected_nopar:Npn \xeCJK_Boundary_and_CJK:
+\xeCJK_inter_class_toks:nnn { Boundary } { CJK }
{
- { \@@_check_for_glue: }
- \c_group_begin_token
- \@@_clear_CJK_toks:
+ { \xeCJK_check_for_glue: }
+ \xeCJK_class_group_begin:
+ \xeCJK_clear_Boundary_and_CJK_toks:
\xeCJK_select_font:
\CJKsymbol
}
-\cs_new_protected_nopar:Npn \@@_check_for_glue:
+% \end{macrocode}
+%
+% \begin{macro}[internal]{\xeCJK_check_for_glue:}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \xeCJK_check_for_glue:
{
\bool_if:nTF
- { \xeCJK_if_last_node_p:n { CJK } || \xeCJK_if_last_node_p:n { CJK_space } }
+ { \xeCJK_if_last_node_p:n { CJK } || \xeCJK_if_last_node_p:n { CJK-space } }
{ \CJKglue }
{
\bool_if:nTF
{
\xeCJK_if_last_node_p:n { default } ||
- \int_compare_p:nNn \etex_lastnodetype:D = \c_ten ||
- \xeCJK_if_last_node_p:n { default_itcorr }
+ \int_compare_p:nNn \etex_lastnodetype:D = \c_ten
}
{ \CJKecglue }
{
\bool_if:nT
{
\l_@@_xecglue_bool &&
- \int_compare_p:nNn \etex_lastnodetype:D = \c_eleven &&
- ( \skip_if_eq_p:nn \tex_lastskip:D \l_@@_space_glue_tl ||
- \dim_compare_p:nNn \tex_lastskip:D = \l_@@_ecglue_dim )
+ ( \skip_if_eq_p:nn \tex_lastskip:D \c_xeCJK_space_skip_tl ||
+ \skip_if_eq_p:nn \tex_lastskip:D \l_@@_ecglue_skip )
}
{
\tex_unskip:D
\bool_if:nTF
{
- \xeCJK_if_last_node_p:n { default_space } ||
+ \xeCJK_if_last_node_p:n { default-space } ||
\int_compare_p:nNn \etex_lastnodetype:D = \c_ten ||
- \xeCJK_if_last_node_p:n { default } ||
- \xeCJK_if_last_node_p:n { default_itcorr }
+ \xeCJK_if_last_node_p:n { default }
}
{ \CJKecglue }
{
\bool_if:nTF
{
\xeCJK_if_last_node_p:n { CJK } ||
- \xeCJK_if_last_node_p:n { CJK_space }
+ \xeCJK_if_last_node_p:n { CJK-space }
}
- { \bool_if:NTF \l_@@_space_bool \c_space_token \CJKglue }
+ { \bool_if:NTF \l_@@_reserve_space_bool \c_space_token \CJKglue }
{ \c_space_token }
}
}
}
}
}
-\tl_set:Nn \l_@@_space_glue_tl
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF,internal]{\xeCJK_if_last_node:n}
+% \begin{macrocode}
+ \prg_new_conditional:Npnn \xeCJK_if_last_node:n #1 { p , T , F , TF }
+ {
+ \if_dim:w \use:c { c_@@_#1_node_dim } = \tex_lastkern:D
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \changes{v3.1.0}{2012/11/14}{删除多余的 \texttt{default-itcorr} 结点。}
+%
+% \begin{macro}[internal]{\xeCJK_def_node:nn,\xeCJK_make_node:n}
+% 用于判断插入的各种 |kern|。
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \xeCJK_def_node:nn #1#2
+ {
+ \dim_if_exist:cTF { c_@@_#1_node_dim }
+ { \dim_gset:cn } { \dim_const:cn }
+ { c_@@_#1_node_dim } {#2}
+ }
+\cs_new_protected_nopar:Npn \xeCJK_make_node:n #1
{
- \tex_fontdimen:D \c_two \tex_font:D
- \@plus \tex_fontdimen:D \c_three \tex_font:D
- \@minus \tex_fontdimen:D \c_four \tex_font:D
+ \tex_kern:D - \use:c { c_@@_#1_node_dim }
+ \tex_kern:D \use:c { c_@@_#1_node_dim }
+ }
+\xeCJK_def_node:nn { CJK } { 11 sp }
+\xeCJK_def_node:nn { CJK-space } { 12 sp }
+\xeCJK_def_node:nn { default } { 13 sp }
+\xeCJK_def_node:nn { default-space } { 14 sp }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{CJKglue}
+% CJK 文字之间插入的 |glue|。
+% \begin{macrocode}
+\keys_define:nn { xeCJK / options }
+ { CJKglue .code:n = { \cs_set_protected:Npn \CJKglue {#1} } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{CJKecglue,xCJKecglue}
+% CJK 与西文和数学行内数学公式之间自动添加的空白。
+% \begin{macrocode}
+\keys_define:nn { xeCJK / options }
+ {
+ CJKecglue .code:n =
+ {
+ \cs_set_protected:Npn \CJKecglue {#1}
+ \xeCJK_glue_to_skip:nN \CJKecglue \l_@@_ecglue_skip
+ } ,
+ xCJKecglue .choice: ,
+ xCJKecglue / true .code:n =
+ {
+ \bool_set_true:N \l_@@_xecglue_bool
+ \cs_set_eq:NN \@@_space_or_xecglue: \CJKecglue
+ } ,
+ xCJKecglue / false .code:n =
+ {
+ \bool_set_false:N \l_@@_xecglue_bool
+ \cs_set_eq:NN \@@_space_or_xecglue: \c_space_token
+ } ,
+ 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_eq:NN \@@_space_or_xecglue: \CJKecglue
+ } ,
+ xCJKecglue .default:n = { true }
+ }
+\skip_new:N \l_@@_ecglue_skip
+\bool_new:N \l_@@_xecglue_bool
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{CJKspace}
+% 是否保留 CJK 文字间的空白,默认不保留。
+% \begin{macrocode}
+\keys_define:nn { xeCJK / options }
+ {
+ CJKspace .bool_set:N = \l_@@_reserve_space_bool ,
+ space .meta:n = { CJKspace = true } ,
+ nospace .meta:n = { CJKspace = false }
}
% \end{macrocode}
% \end{macro}
%
% \hypertarget{cjk-bound}{}
% \begin{macrocode}
-\@@_inter_class_toks:nnn { CJK } { Boundary }
+\xeCJK_inter_class_toks:nnn { CJK } { Boundary }
{
- \c_group_end_token
+ \xeCJK_class_group_end:
{ \xeCJK_make_node:n { CJK } }
- \xeCJK_ignorespaces:
+ \xeCJK_ignore_spaces:w
}
% \end{macrocode}
%
+% \begin{macro}[internal]{\xeCJK_ignore_spaces:w}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \xeCJK_ignore_spaces:w
+ {
+ \peek_catcode:NTF \c_space_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:nT
+ {
+ \token_if_macro_p:N \l_peek_token ||
+ ( \l_@@_reserve_space_bool &&
+ \token_if_other_p:N \l_peek_token )
+ }
+ { \@@_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}
+%
% \hypertarget{cjk-cjk}{}
% \begin{macrocode}
-\@@_inter_class_toks:nnn { CJK } { CJK } { \xeCJK_CJK_and_CJK:N }
+\xeCJK_inter_class_toks:nnn { CJK } { CJK } { \xeCJK_CJK_and_CJK:N }
% \end{macrocode}
%
% \begin{macro}[internal]{\xeCJK_CJK_and_CJK:N}
@@ -1832,92 +2316,102 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
% \end{macrocode}
% \end{macro}
%
-% \hypertarget{fl-fr-bound-cjk}{}
+% \hypertarget{bound-fl-fr}{}
% \begin{macrocode}
-\clist_map_inline:nn { FullLeft, FullRight }
+\clist_map_inline:nn { FullLeft , FullRight }
{
- \@@_inter_class_toks:nnn { Boundary } {#1}
+ \xeCJK_inter_class_toks:nnn { Boundary } {#1}
{
- \c_group_begin_token
- \@@_clear_CJK_toks:
+ \xeCJK_class_group_begin:
+ \xeCJK_clear_Boundary_and_CJK_toks:
\xeCJK_select_font:
\use:c { xeCJK_CJK_and_#1:N }
}
- \@@_inter_class_toks:nnn {#1} { CJK } { \CJKsymbol }
- \@@_inter_class_toks:nnn {#1} { Boundary } { \c_group_end_token \tex_ignorespaces:D }
}
+\xeCJK_inter_class_toks:nnn { FullLeft } { Boundary }
+ { \xeCJK_class_group_end: \tex_ignorespaces:D }
+\xeCJK_inter_class_toks:nnn { FullRight } { Boundary }
+ { \xeCJK_class_group_end: \CJKglue \tex_ignorespaces:D }
% \end{macrocode}
%
+% \hypertarget{fl-fr-others}{}
% \begin{macrocode}
-\clist_map_inline:Nn \g_@@_base_class_clist
+\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_x_p:nn {#1} { FullLeft } || \str_if_eq_x_p:nn {#1} { FullRight } }
+ { \str_if_eq_p:nn {#1} { FullLeft } || \str_if_eq_p:nn {#1} { FullRight } }
{
- \@@_pre_inter_class_toks:nnn { FullLeft } {#1} { \xeCJK_no_break: }
- \@@_pre_inter_class_toks:nnn { FullRight } {#1} { \xeCJK_after_FullRight: }
+ \xeCJK_pre_inter_class_toks:nnn { FullLeft } {#1} { \xeCJK_after_FullLeft: }
+ \xeCJK_pre_inter_class_toks:nnn { FullRight } {#1} { \xeCJK_after_FullRight: }
}
}
% \end{macrocode}
%
% \hypertarget{cjk-fl-fr}{}
% \begin{macrocode}
-\clist_map_inline:nn { CJK, FullLeft, FullRight }
+\clist_map_inline:nn { CJK , FullLeft , FullRight }
{
- \clist_map_inline:nn { FullLeft, FullRight }
- { \@@_inter_class_toks:nnc {#1} {##1} { xeCJK_#1_and_##1:N } }
+ \clist_map_inline:nn { FullLeft , FullRight }
+ { \xeCJK_inter_class_toks:nnc {#1} {##1} { xeCJK_#1_and_##1:N } }
}
% \end{macrocode}
%
-% \begin{macro}[internal]{\@@_punct_rule:n}
+% \begin{macro}[internal]{\@@_punct_rule:NN}
% 用于抹去标点符号的左/右空白。
% \begin{macrocode}
-\cs_new_protected_nopar:Npn \@@_punct_rule:n #1
+\cs_new_protected_nopar:Npn \@@_punct_rule:NN #1#2
{
\tex_vrule:D
- \@width \dim_eval:c { \l_@@_punct_coor_tl/rule/#1 }
- \@depth \c_zero_dim
- \@height \c_zero_dim \scan_stop:
+ width - \@@_use_punct_dim:nnn { bound } {#1} {#2}
+ depth \c_zero_dim
+ height \c_zero_dim \scan_stop:
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\@@_punct_glue:n}
+% \begin{macro}[internal]{\@@_punct_glue:NN}
% 根据所选的标点处理方式在标点符号左/右增加的空白。
% \begin{macrocode}
-\cs_new_protected_nopar:Npn \@@_punct_glue:n #1
+\cs_new_protected_nopar:Npn \@@_punct_glue:NN #1#2
{
\skip_horizontal:n
{
- \dim_eval:c { \l_@@_punct_coor_tl/glue/#1 }
- \@plus \dim_eval:n { ( \tl_use:c { \l_@@_punct_coor_tl/glue/#1 } ) /4 }
- \@minus \dim_eval:n { ( \tl_use:c { \l_@@_punct_coor_tl/glue/#1 } ) /2 }
+ \@@_use_punct_dim:nnn { glue } {#1} {#2}
+ minus \dim_eval:n { ( \@@_use_punct_dim:nnn { glue } {#1} {#2} ) / \c_two }
}
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\@@_punct_kern:n}
+% \begin{macro}[internal]{\@@_punct_kern:NN}
% 相邻两个标点之间的间距。
% \begin{macrocode}
-\cs_new_protected_nopar:Npn \@@_punct_kern:n #1
- { \tex_kern:D \dim_eval:c { \l_@@_punct_coor_tl/kern/#1 } }
+\cs_new_protected_nopar:Npn \@@_punct_kern:NN #1#2
+ { \tex_kern:D \@@_use_punct_dim:nnn { kern } {#1} {#2} }
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\dim_eval:c}
+% \begin{macro}[internal,var]{\g_@@_last_punct_tl}
+% 用于记录当前的标点符号。
% \begin{macrocode}
-\cs_generate_variant:Nn \dim_eval:n { c }
+\tl_new:N \g_@@_last_punct_tl
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\xeCJK_before_FullLeft:N}
+% \begin{macro}[internal]{\xeCJK_after_FullLeft:}
% \begin{macrocode}
-\cs_new_protected_nopar:Npn \xeCJK_before_FullLeft:N #1
+\cs_new_protected_nopar:Npn \xeCJK_after_FullLeft:
{
- \tl_set:Nx \l_@@_lastpunct_tl {#1}
- \@@_punct_rule:n { l/#1 }
- \CJKpunctsymbol {#1}
+ \xeCJK_no_break:
+ \@@_punct_if_middle:NT \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:
+ }
}
% \end{macrocode}
% \end{macro}
@@ -1926,9 +2420,9 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
% \begin{macrocode}
\cs_new_protected_nopar:Npn \xeCJK_after_FullRight:
{
- \xeCJK_get_punct_bounds:nV { r } \l_@@_lastpunct_tl
- \@@_punct_rule:n { r/\l_@@_lastpunct_tl }
- \@@_punct_glue:n { r/\l_@@_lastpunct_tl }
+ \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
}
% \end{macrocode}
% \end{macro}
@@ -1937,16 +2431,14 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
% \begin{macrocode}
\cs_new_protected_nopar:Npn \xeCJK_CJK_and_FullLeft:N #1
{
- \xeCJK_get_punct_bounds:nN { l } {#1}
+ \xeCJK_get_punct_bounds:NN \c_@@_left_tl {#1}
\int_compare:nNnF \etex_lastnodetype:D = \c_one
- { \@@_punct_glue:n { l/#1 } }
- \xeCJK_before_FullLeft:N {#1}
- \@@_punct_if_middle:NT {#1}
- {
- \@@_punct_rule:n { lr/#1 }
- \@@_punct_glue:n { l/#1 }
- }
+ { \@@_CJK_FullLeft_glue: \@@_punct_glue:NN \c_@@_left_tl {#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 }
% \end{macrocode}
% \end{macro}
%
@@ -1954,17 +2446,18 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
% \begin{macrocode}
\cs_new_protected_nopar:Npn \xeCJK_CJK_and_FullRight:N #1
{
- \xeCJK_get_punct_bounds:nN { r } {#1}
- \@@_punct_if_long:NTF {#1} \CJKglue
+ \xeCJK_get_punct_bounds:NN \c_@@_right_tl {#1}
+ \@@_punct_if_long:NTF {#1}
+ { \CJKglue }
{
\xeCJK_no_break:
\@@_punct_if_middle:NT {#1}
{
- \@@_punct_glue:n { r/#1 }
- \@@_punct_rule:n { lr/#1 }
+ \@@_punct_glue:NN \c_@@_right_tl {#1}
+ \@@_punct_rule:NN \c_@@_left_tl {#1}
}
}
- \tl_gset:Nx \l_@@_lastpunct_tl {#1}
+ \tl_gset:Nx \g_@@_last_punct_tl {#1}
\CJKpunctsymbol {#1}
}
% \end{macrocode}
@@ -1975,10 +2468,11 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
\cs_new_protected_nopar:Npn \xeCJK_FullLeft_and_FullLeft:N #1
{
\xeCJK_no_break:
- \xeCJK_get_punct_bounds:nN { l } {#1}
- \xeCJK_calc_kern:VN \l_@@_lastpunct_tl {#1}
- \@@_punct_kern:n { \l_@@_lastpunct_tl - #1 }
- \xeCJK_before_FullLeft:N {#1}
+ \xeCJK_get_punct_bounds:NN \c_@@_left_tl {#1}
+ \xeCJK_get_punct_kerning:oN \g_@@_last_punct_tl {#1}
+ \@@_punct_kern:NN \g_@@_last_punct_tl {#1}
+ \tl_gset:Nx \g_@@_last_punct_tl {#1}
+ \CJKpunctsymbol {#1}
}
% \end{macrocode}
% \end{macro}
@@ -1988,11 +2482,11 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
\cs_new_protected_nopar:Npn \xeCJK_FullLeft_and_FullRight:N #1
{
\xeCJK_no_break:
- \xeCJK_get_punct_bounds:nN { r } {#1}
- \xeCJK_calc_kern:VN \l_@@_lastpunct_tl {#1}
- \@@_punct_kern:n { \l_@@_lastpunct_tl - #1 }
+ \xeCJK_get_punct_bounds:NN \c_@@_right_tl {#1}
+ \xeCJK_get_punct_kerning:oN \g_@@_last_punct_tl {#1}
+ \@@_punct_kern:NN \g_@@_last_punct_tl {#1}
+ \tl_gset:Nx \g_@@_last_punct_tl {#1}
\xeCJK_no_break:
- \tl_set:Nx \l_@@_lastpunct_tl {#1}
\CJKpunctsymbol {#1}
}
% \end{macrocode}
@@ -2002,13 +2496,13 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
% \begin{macrocode}
\cs_new_protected_nopar:Npn \xeCJK_FullRight_and_FullLeft:N #1
{
- \@@_punct_rule:n { r/\l_@@_lastpunct_tl }
- \xeCJK_get_punct_bounds:nN { l } {#1}
- \xeCJK_calc_kern:VN \l_@@_lastpunct_tl {#1}
- \@@_punct_kern:n { \l_@@_lastpunct_tl - #1 }
- \@@_punct_nobreak:
- \xeCJK_before_FullLeft:N {#1}
- }
+ \xeCJK_get_punct_bounds:NN \c_@@_left_tl {#1}
+ \xeCJK_get_punct_kerning:oN \g_@@_last_punct_tl {#1}
+ \@@_punct_kern:NN \g_@@_last_punct_tl {#1}
+ \tl_gset:Nx \g_@@_last_punct_tl {#1}
+ \@@_punct_break:
+ \CJKpunctsymbol {#1}
+ }
% \end{macrocode}
% \end{macro}
%
@@ -2016,170 +2510,16 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
% \begin{macrocode}
\cs_new_protected_nopar:Npn \xeCJK_FullRight_and_FullRight:N #1
{
- \@@_punct_rule:n { r/\l_@@_lastpunct_tl }
- \xeCJK_get_punct_bounds:nN { r } {#1}
- \xeCJK_calc_kern:VN \l_@@_lastpunct_tl {#1}
- \@@_punct_kern:n { \l_@@_lastpunct_tl - #1 }
+ \xeCJK_get_punct_bounds:NN \c_@@_right_tl {#1}
+ \xeCJK_get_punct_kerning:oN \g_@@_last_punct_tl {#1}
+ \@@_punct_kern:NN \g_@@_last_punct_tl {#1}
+ \tl_gset:Nx \g_@@_last_punct_tl {#1}
\xeCJK_no_break:
- \tl_set:Nx \l_@@_lastpunct_tl {#1}
\CJKpunctsymbol {#1}
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[pTF,internal]{\xeCJK_if_last_node:n}
-% \begin{macrocode}
- \prg_new_conditional:Npnn \xeCJK_if_last_node:n #1 { p , T , F , TF }
- {
- \if_dim:w \dim_use:c { c_@@_#1_node_dim } = \tex_lastkern:D
- \prg_return_true: \else: \prg_return_false: \fi:
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\xeCJK_def_node:nn,\xeCJK_make_node:n}
-% 用于判断插入的各种 |kern|。
-% \begin{macrocode}
-\cs_new_protected_nopar:Npn \xeCJK_def_node:nn #1#2
- {
- \dim_if_exist:cTF { c_@@_#1_node_dim }
- { \dim_gset:cn } { \dim_const:cn }
- { c_@@_#1_node_dim } {#2}
- }
-\cs_new_protected_nopar:Npn \xeCJK_make_node:n #1
- {
- \tex_kern:D - \dim_use:c { c_@@_#1_node_dim }
- \tex_kern:D \dim_use:c { c_@@_#1_node_dim }
- }
-\xeCJK_def_node:nn { CJK } { 11 sp }
-\xeCJK_def_node:nn { CJK_space } { 12 sp }
-\xeCJK_def_node:nn { default } { 13 sp }
-\xeCJK_def_node:nn { default_space } { 14 sp }
-\xeCJK_def_node:nn { default_itcorr } { 15 sp }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{CJKglue}
-% CJK 文字之间插入的 |glue|。
-% \begin{macrocode}
-\keys_define:nn { xeCJK / options }
- { CJKglue .code:n = { \cs_set_protected:Npn \CJKglue {#1} } }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{CJKecglue,xCJKecglue}
-% CJK 与西文和数学行内数学公式之间自动添加的空白。
-% \begin{macrocode}
-\keys_define:nn { xeCJK / options }
- {
- CJKecglue .code:n =
- {
- \cs_set_protected:Npn \CJKecglue {#1}
- \settowidth \l_@@_ecglue_dim \CJKecglue
- },
- xCJKecglue .choice:,
- xCJKecglue / true .code:n =
- {
- \bool_set_true:N \l_@@_xecglue_bool
- \cs_set_eq:NN \@@_space_or_xecglue: \CJKecglue
- },
- xCJKecglue / false .code:n =
- {
- \bool_set_false:N \l_@@_xecglue_bool
- \cs_set_eq:NN \@@_space_or_xecglue: \c_space_token
- },
- xCJKecglue / unknown .code:n =
- {
- \bool_set_true:N \l_@@_xecglue_bool
- \cs_set_protected:Npn \CJKecglue {#1}
- \settowidth \l_@@_ecglue_dim \CJKecglue
- \cs_set_eq:NN \@@_space_or_xecglue: \CJKecglue
- },
- xCJKecglue .default:n = { true } ,
- }
-\dim_new:N \l_@@_ecglue_dim
-\bool_new:N \l_@@_xecglue_bool
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{CJKspace}
-% 是否保留 CJK 文字间的空白,默认不保留。
-% \begin{macrocode}
-\keys_define:nn { xeCJK / options }
- {
- CJKspace .choice:,
- CJKspace / true .code:n = { \CJKspace },
- CJKspace / false .code:n = { \CJKnospace },
- CJKspace .default:n = { true },
- space .meta:n = { CJKspace = true },
- nospace .meta:n = { CJKspace = false },
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\CJKspace,\CJKnospace}
-% 是否保留 CJK 文字间的空白,默认不保留。
-% \begin{macrocode}
-\NewDocumentCommand \CJKspace { }
- {
- \bool_set_true:N \l_@@_space_bool
- \cs_set_eq:NN \xeCJK_ignorespaces: \@@_peek_math:
- }
-\NewDocumentCommand \CJKnospace { }
- {
- \bool_set_false:N \l_@@_space_bool
- \cs_set_eq:NN \xeCJK_ignorespaces: \@@_ignore_spaces:
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\@@_ignore_spaces:,\@@_peek_math:}
-% \begin{macrocode}
-\cs_new_protected_nopar:Npn \@@_ignore_spaces:
- {
- \peek_catcode:NTF \c_space_token
- {
- \xeCJK_if_last_node:nT { CJK }
- { \tex_unkern:D \tex_unkern:D { \xeCJK_make_node:n { CJK_space } } }
- \xeCJK_peek_catcode_ignore_spaces:NTF \c_math_toggle_token
- { \@@_space_or_xecglue: }
- {
- \bool_if:nT
- {
- \xeCJK_if_outer_macro_p:c { l_peek_token } ||
- \token_if_cs_p:c { l_peek_token }
- }
- { \@@_space_or_xecglue: }
- }
- }
- {
- \xeCJK_if_outer_macro:cF { l_peek_token }
- {
- \token_if_math_toggle:cTF { l_peek_token } \CJKecglue
- { \cs_if_exist:cF { l_peek_token } \exp_not:N }
- }
- }
- }
-\cs_new_protected_nopar:Npn \@@_peek_math:
- {
- \peek_catcode:NTF \c_space_token
- {
- \xeCJK_if_last_node:nT { CJK }
- { \tex_unkern:D \tex_unkern:D { \xeCJK_make_node:n { CJK_space } } }
- \xeCJK_peek_catcode_ignore_spaces:NF \c_space_token
- { \@@_space_or_xecglue: }
- }
- {
- \xeCJK_if_outer_macro:cF { l_peek_token }
- {
- \token_if_math_toggle:cTF { l_peek_token } \CJKecglue
- { \cs_if_exist:cF { l_peek_token } \exp_not:N }
- }
- }
- }
-% \end{macrocode}
-% \end{macro}
-%
% \subsection{段末孤字处理}
%
% \begin{macro}{CheckSingle}
@@ -2187,11 +2527,11 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
% \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 } ,
+ CheckSingle .choice: ,
+ CheckSingle / true .code:n = { \xeCJKenablechecksingle } ,
+ CheckSingle / false .code:n = { \xeCJKdisablechecksingle } ,
+ CheckSingle .default:n = { true } ,
+ CJKchecksingle .meta:n = { CheckSingle = true }
}
% \end{macrocode}
% \end{macro}
@@ -2199,79 +2539,77 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
% \begin{macro}[internal]{\xeCJKenablechecksingle,\xeCJKdisablechecksingle}
% 孤字处理功能开关。
% \begin{macrocode}
-\bool_new:N \l_@@_checksingle_bool
+\bool_new:N \l_@@_check_single_bool
\NewDocumentCommand \xeCJKenablechecksingle { }
{
- \bool_if:NF \l_@@_checksingle_bool
+ \bool_if:NF \l_@@_check_single_bool
{
- \bool_set_true:N \l_@@_checksingle_bool
- \cs_set_eq:NN \@@_checksingle_save_CJKsymbol:N \xeCJK_CJK_and_CJK:N
- \cs_set_eq:NN \xeCJK_CJK_and_CJK:N \xeCJK_checksingle:N
+ \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
}
}
\NewDocumentCommand \xeCJKdisablechecksingle { }
{
- \bool_if:NT \l_@@_checksingle_bool
+ \bool_if:NT \l_@@_check_single_bool
{
- \bool_set_false:N \l_@@_checksingle_bool
- \cs_set_eq:NN \xeCJK_CJK_and_CJK:N \@@_checksingle_save_CJKsymbol:N
+ \bool_set_false:N \l_@@_check_single_bool
+ \cs_set_eq:NN \xeCJK_CJK_and_CJK:N \@@_check_single_save:N
}
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\xeCJK_checksingle:N,\xeCJK_checksingle:NN,\xeCJK_checksingle:NNN}
+% \begin{macro}[internal]
+% {\xeCJK_check_single:Nw,\xeCJK_check_single:NNw,\xeCJK_check_single:NNNw}
% \begin{macrocode}
-\cs_new_protected_nopar:Npn \xeCJK_checksingle:N #1
+\cs_new_protected_nopar:Npn \xeCJK_check_single:Nw #1
{
\peek_catcode:NTF \c_catcode_other_token
- { \xeCJK_checksingle:NN {#1} }
+ { \xeCJK_check_single:NNw {#1} }
{
\bool_if:nTF
{
- ! ( \xeCJK_if_outer_macro_p:c { l_peek_token } ) &&
- \xeCJK_if_blank_x_p:n { \token_get_arg_spec:c { l_peek_token } } &&
- \exp_args:NNc \exp_args:No \tl_if_single_token_p:n { l_peek_token } &&
- \exp_args:NNc \exp_after:wN \token_if_other_p:N { l_peek_token }
+ \xeCJK_if_blank_x_p:n { \token_get_arg_spec:N \l_peek_token } &&
+ \exp_args:No \tl_if_single_token_p:n \l_peek_token &&
+ \exp_after:wN \token_if_other_p:N \l_peek_token
}
- { \xeCJK_checksingle:NN {#1} }
- { \@@_checksingle_save_CJKsymbol:N {#1} }
+ { \xeCJK_check_single:NNw {#1} }
+ { \@@_check_single_save:N {#1} }
}
}
-\cs_new_protected_nopar:Npn \xeCJK_checksingle:NN #1#2
+\cs_new_protected_nopar:Npn \xeCJK_check_single:NNw #1#2
{
\peek_catcode:NTF \c_catcode_other_token
- { \@@_checksingle_save_CJKsymbol:N {#1} #2 }
+ { \@@_check_single_save:N {#1} #2 }
{
\bool_if:nTF
{
- ! ( \xeCJK_if_outer_macro_p:c { l_peek_token } ) &&
- ( \token_if_space_p:c { l_peek_token } ||
- \token_if_math_toggle_p:c { l_peek_token } ||
- \token_if_cs_p:c { 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
}
{
- \bool_if:nTF { \token_if_space_p:c { l_peek_token } }
+ \bool_if:nTF { \token_if_space_p:N \l_peek_token }
{
- \xeCJK_peek_catcode_ignore_spaces:NTF \c_catcode_other_token
- { \@@_checksingle_save_CJKsymbol:N {#1} #2 \c_space_token }
+ \peek_catcode_ignore_spaces:NTF \c_catcode_other_token
+ { \@@_check_single_save:N {#1} #2 \c_space_token }
{
\bool_if:nTF
{
- ! ( \xeCJK_if_outer_macro_p:c { l_peek_token } ) &&
- ( \token_if_math_toggle_p:c { l_peek_token } ||
- \token_if_cs_p:c { l_peek_token } )
+ \token_if_math_toggle_p:N \l_peek_token ||
+ \token_if_cs_p:N \l_peek_token
}
- { \xeCJK_checksingle:NNN {#1} {#2} \c_space_token }
- { \@@_checksingle_save_CJKsymbol:N {#1} #2 \c_space_token }
+ { \xeCJK_check_single:NNNw {#1} {#2} \c_space_token }
+ { \@@_check_single_save:N {#1} #2 \c_space_token }
}
}
- { \xeCJK_checksingle:NNN {#1} {#2} { } }
+ { \xeCJK_check_single:NNNw {#1} {#2} { } }
}
- { \@@_checksingle_save_CJKsymbol:N {#1} #2 }
+ { \@@_check_single_save:N {#1} #2 }
}
}
-\cs_new_protected_nopar:Npn \xeCJK_checksingle:NNN #1#2#3
+\cs_new_protected_nopar:Npn \xeCJK_check_single:NNNw #1#2#3
{
\bool_if:nTF
{
@@ -2279,35 +2617,36 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
\token_if_eq_meaning_p:NN \l_peek_token \[ % \]
}
{ \CJKsymbol {#1} \xeCJK_no_break: #2 }
- { \xeCJK_checksingle_env:NNN {#1} {#2} {#3} }
+ { \xeCJK_check_single_env:NNNw {#1} {#2} {#3} }
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\xeCJK_checksingle_env:NNN,\xeCJK_checksingle_env:NNNNn}
+% \begin{macro}[internal]
+% {\xeCJK_check_single_env:NNNw,\xeCJK_check_single_env:NNNNn}
% \begin{macrocode}
-\cs_new_protected_nopar:Npn \xeCJK_checksingle_env:NNN #1#2#3
+\cs_new_protected_nopar:Npn \xeCJK_check_single_env:NNNw #1#2#3
{
\peek_catcode_remove:NTF \c_math_toggle_token
{
\peek_catcode:NTF \c_math_toggle_token
{ \CJKsymbol {#1} \xeCJK_no_break: #2 \c_math_toggle_token }
- { \@@_checksingle_save_CJKsymbol:N {#1} #2#3 \c_math_toggle_token }
+ { \@@_check_single_save:N {#1} #2#3 \c_math_toggle_token }
}
{
\peek_meaning_remove:NTF \begin
- { \xeCJK_checksingle_env:NNNNn {#1} {#2} {#3} \begin }
+ { \xeCJK_check_single_env:NNNNn {#1} {#2} {#3} \begin }
{
\peek_meaning_remove:NTF \end
- { \xeCJK_checksingle_env:NNNNn {#1} {#2} {#3} \end }
- { \@@_checksingle_save_CJKsymbol:N {#1} #2#3 }
+ { \xeCJK_check_single_env:NNNNn {#1} {#2} {#3} \end }
+ { \@@_check_single_save:N {#1} #2#3 }
}
}
}
-\cs_new_protected_nopar:Npn \xeCJK_checksingle_env:NNNNn #1#2#3#4#5
+\cs_new_protected_nopar:Npn \xeCJK_check_single_env:NNNNn #1#2#3#4#5
{
\clist_if_in:NnTF \g_@@_inline_env_clist {#5}
- { \@@_checksingle_save_CJKsymbol:N {#1} #2#3 }
+ { \@@_check_single_save:N {#1} #2#3 }
{ \CJKsymbol {#1} \xeCJK_no_break: #2 }
\scan_stop: #4 {#5}
}
@@ -2323,54 +2662,32 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
{
\clist_gput_right:Nx \g_@@_inline_env_clist {#1}
\clist_gremove_duplicates:N \g_@@_inline_env_clist
- },
+ } ,
InlineEnv- .code:n =
{
\clist_map_inline:xn {#1}
{ \clist_gremove_all:Nn \g_@@_inline_env_clist {##1} }
- },
+ }
}
+\cs_generate_variant:Nn \clist_map_inline:nn { x }
% \end{macrocode}
% \end{macro}
%
-% \begin{macrocode}
-\cs_generate_variant:Nn \token_if_cs_p:N { c }
-\cs_generate_variant:Nn \token_if_space_p:N { c }
-\cs_generate_variant:Nn \token_get_arg_spec:N { c }
-\cs_generate_variant:Nn \token_if_math_toggle_p:N { c }
-\cs_generate_variant:Nn \token_if_math_toggle:NTF { c }
-% \end{macrocode}
-%
% \subsection{增加 CJK 子分区}
%
-% \begin{macro}[internal]{\@@_UL_subclass_patch_tl,\g_@@_CJK_subclass_clist}
-% \begin{macrocode}
-\tl_new:N \@@_UL_subclass_patch_tl
-\clist_new:N \g_@@_CJK_subclass_clist
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\@@_erase_CJKsymbol:, \@@_restore_CJKsymbol:}
+% \begin{macro}[internal]{\g_@@_CJK_sub_class_seq}
% \begin{macrocode}
-\cs_new_protected_nopar:Npn \@@_erase_CJKsymbol:
- {
- \cs_gset_eq:NN \CJKsymbol_Block \CJKsymbol
- \cs_gset_eq:NN \CJKsymbol \prg_do_nothing:
- }
-\cs_new_protected_nopar:Npn \@@_restore_CJKsymbol:
- {
- \cs_gset_eq:NN \CJKsymbol \CJKsymbol_Block
- \CJKsymbol
- }
+\seq_new:N \g_@@_CJK_sub_class_seq
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\xeCJKDeclareSubCJKBlock}
% 声明 CJK 子区范围,|#1| 为自定义名称,|#2| 为子区的 |Unicode| 范围。
% \begin{macrocode}
-\NewDocumentCommand \xeCJKDeclareSubCJKBlock { s m m }
+\NewDocumentCommand \xeCJKDeclareSubCJKBlock
+ { s > { \TrimSpaces } m > { \TrimSpaces } m }
{
- \xeCJKDeclareSubCharClass { CJK } {#2} {#3}
+ \xeCJK_declare_sub_char_class:nxx { CJK } {#2} {#3}
\IfBooleanT {#1} { \xeCJKResetPunctClass }
}
\@onlypreamble \xeCJKDeclareSubCJKBlock
@@ -2386,7 +2703,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
\bool_if:NF \l_@@_sub_cancel_bool
{
\bool_set_true:N \l_@@_sub_cancel_bool
- \@@_sub_restore_or_cancel:n {#2}
+ \@@_sub_restore_or_cancel:x {#2}
\IfBooleanT {#1} { \xeCJKResetPunctClass }
}
}
@@ -2395,23 +2712,29 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
\bool_if:NT \l_@@_sub_cancel_bool
{
\bool_set_false:N \l_@@_sub_cancel_bool
- \@@_sub_restore_or_cancel:n {#2}
+ \@@_sub_restore_or_cancel:x {#2}
\IfBooleanT {#1} { \xeCJKResetPunctClass }
}
}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\@@_sub_restore_or_cancel:n}
+% \begin{macrocode}
\cs_new_protected_nopar:Npn \@@_sub_restore_or_cancel:n #1
{
- \clist_map_inline:xn {#1}
+ \clist_map_inline:nn {#1}
{
\int_if_exist:cTF { c_@@_ CJK/##1 _class_int }
{
- \@@_declare_char_class:nn
+ \xeCJK_declare_char_class:nx
{ CJK \bool_if:NF \l_@@_sub_cancel_bool { /##1 } }
{ \tl_use:c { g_@@_CJK/##1_range_clist } }
}
{ \@@_error:nx { SubBlock-undefined } {##1} }
}
}
+\cs_generate_variant:Nn \@@_sub_restore_or_cancel:n { x }
\@@_msg_new:nn { SubBlock-undefined }
{
The~CJK~sub~block~'#1'~is~undefined.\\\\
@@ -2421,21 +2744,19 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\xeCJKDeclareSubCharClass}
+% \begin{macro}[internal]{\xeCJK_declare_sub_char_class:nnn}
% \begin{macrocode}
-\NewDocumentCommand \xeCJKDeclareSubCharClass
- { > { \TrimSpaces } m > { \TrimSpaces } m m }
+\cs_new_protected_nopar:Npn \xeCJK_declare_sub_char_class:nnn #1#2#3
{
\int_if_exist:cF { c_@@_ #1/#2 _class_int }
{
- \@@_new_class:n { #1/#2 }
+ \xeCJK_new_class:n { #1/#2 }
\@@_set_sub_class_toks:nn {#1} {#2}
\@@_new_sub_key:n {#2}
- \@@_UL_subclass_patch:nn {#1} {#2}
}
- \@@_declare_char_class:nn { #1/#2 } {#3}
+ \xeCJK_declare_char_class:nn { #1/#2 } {#3}
}
-\@onlypreamble \xeCJKDeclareSubCharClass
+\cs_generate_variant:Nn \xeCJK_declare_sub_char_class:nnn { nxx }
% \end{macrocode}
% \end{macro}
%
@@ -2443,117 +2764,80 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
% \begin{macrocode}
\cs_new_protected_nopar:Npn \@@_set_sub_class_toks:nn #1#2
{
- \clist_map_inline:Nn \g_@@_base_class_clist
+ \seq_map_inline:Nn \g_@@_base_class_seq
{
- \@@_copy_inter_class_toks:nnnn { #1/#2 } {##1} {#1} {##1}
- \@@_copy_inter_class_toks:nnnn {##1} { #1/#2 } {##1} {#1}
- \str_if_eq_x:nnTF {##1} { CJK }
+ \xeCJK_copy_inter_class_toks:nnnn { #1/#2 } {##1} {#1} {##1}
+ \xeCJK_copy_inter_class_toks:nnnn {##1} { #1/#2 } {##1} {#1}
+ \str_if_eq:nnTF {##1} { CJK }
{
- \@@_pre_inter_class_toks:nnn {##1} { #1/#2 }
+ \xeCJK_pre_inter_class_toks:nnn {##1} { #1/#2 }
{ \@@_switch_font:nn {#1} {#2} }
}
{
- \@@_pre_inter_class_toks:nnn {##1} { #1/#2 }
- { \@@_erase_CJKsymbol: }
- \@@_app_inter_class_toks:nnn {##1} { #1/#2 }
- { \@@_switch_font:nn {#1} {#2} \@@_restore_CJKsymbol: }
+ \xeCJK_replace_inter_class_toks:nnnn {##1} { #1/#2 }
+ { \CJKsymbol }
+ { \@@_switch_font:nn {#1} {#2} \CJKsymbol }
}
}
- \@@_copy_inter_class_toks:nnnn { #1/#2 } { #1/#2 } {#1} {#1}
- \clist_if_empty:NF \g_@@_CJK_subclass_clist
+ \xeCJK_copy_inter_class_toks:nnnn { #1/#2 } { #1/#2 } {#1} {#1}
+ \seq_map_inline:Nn \g_@@_CJK_sub_class_seq
{
- \clist_map_inline:Nn \g_@@_CJK_subclass_clist
- {
- \@@_copy_inter_class_toks:nnnn { #1/#2 } { #1/##1 } {#1} {#1}
- \@@_copy_inter_class_toks:nnnn { #1/##1 } { #1/#2 } {#1} {#1}
- \@@_pre_inter_class_toks:nnn { #1/#2 } { #1/##1 }
- { \@@_switch_font:nn {#2} {##1} }
- \@@_pre_inter_class_toks:nnn { #1/##1 } { #1/#2 }
- { \@@_switch_font:nn {##1} {#2} }
- }
+ \xeCJK_copy_inter_class_toks:nnnn { #1/#2 } { #1/##1 } {#1} {#1}
+ \xeCJK_copy_inter_class_toks:nnnn { #1/##1 } { #1/#2 } {#1} {#1}
+ \xeCJK_pre_inter_class_toks:nnn { #1/#2 } { #1/##1 }
+ { \@@_switch_font:nn {#2} {##1} }
+ \xeCJK_pre_inter_class_toks:nnn { #1/##1 } { #1/#2 }
+ { \@@_switch_font:nn {##1} {#2} }
}
- \clist_gput_right:Nn \g_@@_CJK_subclass_clist {#2}
+ \seq_gput_right:Nn \g_@@_CJK_sub_class_seq {#2}
\@@_save_CJK_class:n { #1/#2 }
- \clist_map_inline:nn { CJK, FullLeft, FullRight }
+ \clist_map_inline:nn { CJK , FullLeft , FullRight }
{
- \@@_pre_inter_class_toks:nnn { #1/#2 } {##1}
+ \xeCJK_pre_inter_class_toks:nnn { #1/#2 } {##1}
{ \@@_switch_font:nn {#2} {#1} }
}
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\@@_UL_subclass_patch:nn}
+% \subsection{标点处理}
+%
+% \cs{XeTeXglyphbouds} 可以得到一个字符的左右边距,用于标点压缩。如果它不可用,则
+% 在文档中只能使用 |plain| 这一标点格式原样输出标点。
% \begin{macrocode}
-\cs_new_protected_nopar:Npn \@@_UL_subclass_patch:nn #1#2
+\@@_msg_new:nn { XeTeX-too-old }
{
- \tl_put_right:Nn \@@_UL_subclass_patch_tl
- {
- \clist_map_inline:nn { Default, HalfLeft, HalfRight }
- {
- \str_if_eq_x:nnTF {##1} { HalfLeft }
- { \@@_inter_class_toks:nnn {#1} { #1/#2 } { \CJKecglue \CJKsymbol } }
- { \@@_inter_class_toks:nnn {#1} { #1/#2 } { \CJKsymbol } }
- \@@_inter_class_toks:nnn { Boundary } { #1/#2 }
- {
- \@@_erase_CJKsymbol:
- \xeCJK_Boundary_and_CJK:
- \@@_switch_font:nn {#1} {#2}
- \@@_restore_CJKsymbol:
- }
- }
- }
+ \token_to_str:N \XeTeXglyphbounds \ is~not~defined.\\
+ CJK~punctuation~kerning~will~not~be~available.\\\\
+ You~have~to~update~XeTeX~to~the~version~0.9995.0~or~later.
+ }
+\cs_if_exist:NF \XeTeXglyphbounds
+ {
+ \@@_error:n { XeTeX-too-old }
+ \@@_after_end_preamble:n { \xeCJKsetup { PunctStyle = plain } }
}
% \end{macrocode}
-% \end{macro}
%
-% \subsection{标点处理}
-%
-% \begin{macro}[internal,var]{\g_@@_punctstyle_clist}
-% 标点处理方式。
+% \begin{macro}{\xeCJKsetwidth}
+% 手动设置参数中的标点符号的宽度。
% \begin{macrocode}
-\clist_new:N \g_@@_punctstyle_clist
-\clist_set:Nn \g_@@_punctstyle_clist
- { CCT , halfwidth , fullwidth , marginkerning , mixedwidth , plain }
-\clist_map_inline:Nn \g_@@_punctstyle_clist
- { \tl_const:cn { c_@@_ps_#1_tl } {#1} }
+\NewDocumentCommand \xeCJKsetwidth { m m }
+ { \tl_map_inline:xn {#1} { \tl_gset:cn { g_@@_punct_width/##1/tl } {#2} } }
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\keys_define:nx}
+% \begin{macro}{\xeCJKsetkern}
+% 手动设置相邻标点的距离。
% \begin{macrocode}
-\cs_generate_variant:Nn \keys_define:nn { nx }
+\NewDocumentCommand \xeCJKsetkern { m m m }
+ { \tl_gset:cn { g_@@_punct/kern/#1/#2/tl } {#3} }
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{PunctStyle}
+% \begin{macro}[internal,var]{\c_@@_left_tl,\c_@@_right_tl}
% \begin{macrocode}
-\keys_define:nn { xeCJK / options }
- {
- PunctStyle .choice_code:n =
- {
- \tl_set:Nx \l_xeCJK_punctstyle_tl { \l_keys_choice_tl }
- \tl_if_eq:NNT \l_xeCJK_punctstyle_tl \c_@@_ps_plain_tl
- { \xeCJKallowbreakbetweenpuncts }
- },
- }
-\keys_define:nx { xeCJK / options }
- { PunctStyle .generate_choices:n = { \exp_not:V \g_@@_punctstyle_clist } }
-\keys_define:nn { xeCJK / options }
- {
- PunctStyle / banjiao .meta:n = { PunctStyle = halfwidth },
- PunctStyle / quanjiao .meta:n = { PunctStyle = fullwidth },
- PunctStyle / kaiming .meta:n = { PunctStyle = mixedwidth },
- PunctStyle / hangmobanjiao .meta:n = { PunctStyle = marginkerning },
- PunctStyle / unknown .code:n =
- { \@@_error:nx { PunctStyle-undefined } \l_keys_value_tl },
- }
-\@@_msg_new:nn { PunctStyle-undefined }
- {
- Punctstyle~"#1"~is~not~available. \\\\
- You~can~only~use~one~of\\\\
- "\g_@@_punctstyle_clist".\\
- }
+\tl_const:Nn \c_@@_left_tl { left }
+\tl_const:Nn \c_@@_right_tl { right }
% \end{macrocode}
% \end{macro}
%
@@ -2563,421 +2847,659 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
% \begin{macrocode}
\keys_define:nn { xeCJK / options }
{
- AllowBreakBetweenPuncts .choice:,
- AllowBreakBetweenPuncts / true .code:n = { \xeCJKallowbreakbetweenpuncts },
- AllowBreakBetweenPuncts / false .code:n = { \xeCJKnobreakbetweenpuncts },
- AllowBreakBetweenPuncts .default:n = { true },
- KaiMingPunct .code:n = { \@@_set_special_punct:nn { mixedwidth } {#1} },
- KaiMingPunct+ .code:n = { \@@_add_special_punct:nn { mixedwidth } {#1} },
- KaiMingPunct- .code:n = { \@@_sub_special_punct:nn { mixedwidth } {#1} },
- LongPunct .code:n = { \@@_set_special_punct:nn { long } {#1} },
- LongPunct+ .code:n = { \@@_add_special_punct:nn { long } {#1} },
- LongPunct- .code:n = { \@@_sub_special_punct:nn { long } {#1} },
- MiddlePunct+ .code:n = { \@@_add_special_punct:nn { middle } {#1} },
- MiddlePunct .code:n = { \@@_set_special_punct:nn { middle } {#1} },
- MiddlePunct- .code:n = { \@@_sub_special_punct:nn { middle } {#1} },
- PunctWidth .tl_gset:N = \g_@@_punct_width_tl ,
+ AllowBreakBetweenPuncts .choice: ,
+ AllowBreakBetweenPuncts / true .code:n =
+ { \cs_set_eq:NN \@@_punct_break: \xeCJK_allow_break: } ,
+ AllowBreakBetweenPuncts / false .code:n =
+ { \cs_set_eq:NN \@@_punct_break: \xeCJK_no_break: } ,
+ AllowBreakBetweenPuncts .default:n = { true } ,
+ KaiMingPunct .code:n = { \@@_set_special_punct:nn { mixed_width } {#1} } ,
+ KaiMingPunct+ .code:n = { \@@_add_special_punct:nn { mixed_width } {#1} } ,
+ KaiMingPunct- .code:n = { \@@_sub_special_punct:nn { mixed_width } {#1} } ,
+ LongPunct .code:n = { \@@_set_special_punct:nn { long } {#1} } ,
+ LongPunct+ .code:n = { \@@_add_special_punct:nn { long } {#1} } ,
+ LongPunct- .code:n = { \@@_sub_special_punct:nn { long } {#1} } ,
+ MiddlePunct .code:n = { \@@_set_special_punct:nn { middle } {#1} } ,
+ MiddlePunct+ .code:n = { \@@_add_special_punct:nn { middle } {#1} } ,
+ MiddlePunct- .code:n = { \@@_sub_special_punct:nn { middle } {#1} } ,
+ PunctWidth .tl_gset:N = \g_@@_punct_width_tl
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\xeCJKallowbreakbetweenpuncts, \xeCJKnobreakbetweenpuncts}
-% \begin{macrocode}
-\NewDocumentCommand \xeCJKallowbreakbetweenpuncts { }
- { \cs_set_eq:NN \@@_punct_nobreak: \@@_zero_glue: }
-\NewDocumentCommand \xeCJKnobreakbetweenpuncts { }
- { \cs_set_eq:NN \@@_punct_nobreak: \xeCJK_no_break: }
-\cs_new_protected_nopar:Npn \@@_zero_glue: { \skip_horizontal:N \c_zero_skip }
-% \end{macrocode}
-% \end{macro}
-%
% \begin{macro}[internal]
-% {\g_@@_special_ps_clist, \@@_set_special_punct:nn,
+% {\g_@@_special_punct_clist,\@@_set_special_punct:nn,
% \@@_add_special_punct:nn, \@@_sub_special_punct:nn}
% \begin{macrocode}
-\clist_set:Nn \g_@@_special_ps_clist { mixedwidth , long , middle }
-\clist_map_inline:Nn \g_@@_special_ps_clist
- {
- \tl_new:c { l_@@_#1_punct_tl }
- \prop_new:c { l_@@_#1_punct_prop }
- }
+\clist_new:N \g_@@_special_punct_clist
+\clist_gset:Nn \g_@@_special_punct_clist { mixed_width , long , middle }
+\cs_new_nopar:Npn \@@_special_punct_seq:n #1 { g_@@_special_punct_#1_seq }
+\cs_new_nopar:Npn \@@_special_punct_tl:nN #1#2 { g_@@_special_punct_#1_#2_tl }
+\clist_map_inline:Nn \g_@@_special_punct_clist
+ { \seq_new:c { \@@_special_punct_seq:n {#1} } }
\cs_new_protected_nopar:Npn \@@_set_special_punct:nn #1#2
{
- \tl_set:cx { l_@@_#1_punct_tl } {#2}
- \prop_clear:c { l_@@_#1_punct_prop }
- \tl_map_inline:cn { l_@@_#1_punct_tl }
- { \prop_put:cnn { l_@@_#1_punct_prop } {##1} { } }
+ \seq_map_inline:cn { \@@_special_punct_seq:n {#1} }
+ { \cs_undefine:c { \@@_special_punct_tl:nN {#1} {##1} } }
+ \seq_gclear:c { \@@_special_punct_seq:n {#1} }
+ \tl_map_inline:xn {#2}
+ {
+ \tl_new:c { \@@_special_punct_tl:nN {#1} {##1} }
+ \seq_gput_right:cn { \@@_special_punct_seq:n {#1} } {##1}
+ }
}
\cs_new_protected_nopar:Npn \@@_add_special_punct:nn #1#2
{
- \tl_put_right:cx { l_@@_#1_punct_tl } {#2}
- \tl_map_inline:cn { l_@@_#1_punct_tl }
- { \prop_put:cnn { l_@@_#1_punct_prop } {##1} { } }
+ \tl_map_inline:xn {#2}
+ {
+ \seq_if_in:cnF { \@@_special_punct_seq:n {#1} } {##1}
+ {
+ \tl_new:c { \@@_special_punct_tl:nN {#1} {##1} }
+ \seq_gput_right:cn { \@@_special_punct_seq:n {#1} } {##1}
+ }
+ }
}
\cs_new_protected_nopar:Npn \@@_sub_special_punct:nn #1#2
{
\tl_map_inline:xn {#2}
{
- \tl_remove_all:cn { l_@@_#1_punct_tl } {##1}
- \prop_remove:cn { l_@@_#1_punct_prop } {##1}
+ \cs_undefine:c { \@@_special_punct_tl:nN {#1} {##1} }
+ \seq_gremove_all:cn { \@@_special_punct_seq:n {#1} } {##1}
}
}
-\cs_generate_variant:Nn \tl_map_inline:nn { x }
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\dim_set:Nc,\dim_add:Nc,\dim_min:cc}
-% \begin{macrocode}
-\cs_generate_variant:Nn \dim_set:Nn { Nc }
-\cs_generate_variant:Nn \dim_add:Nn { Nc }
-\cs_generate_variant:Nn \dim_min:nn { cc }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\xeCJK_dim_set_max:Nn,\xeCJK_dim_set_min:Nn}
-% \begin{macrocode}
-\cs_new_protected_nopar:Npn \xeCJK_dim_set_max:Nn #1#2
- { \dim_set:Nn #1 { \dim_max:nn {#1} {#2} } }
-\cs_new_protected_nopar:Npn \xeCJK_dim_set_min:Nn #1#2
- { \dim_set:Nn #1 { \dim_min:nn {#1} {#2} } }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal,var]{\l_@@_punct_coor_tl}
-% 记录当前字体状态下的标点处理方式。
+% \begin{macro}[pTF,internal]
+% {\@@_punct_if_right:N,\@@_punct_if_long:N,
+% \@@_punct_if_middle:N,\@@_punct_if_mixed_width:N}
% \begin{macrocode}
-\tl_set:Nn \l_@@_punct_coor_tl { \l_xeCJK_font_coor_tl/\l_xeCJK_punctstyle_tl }
+\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 }
+ \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 }
+ {
+ \if_cs_exist:w \@@_special_punct_tl:nN {#1} {##1} \cs_end:
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+ }
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\xeCJK_get_punct_bounds:nN}
-% |#1| 为 |l/r|,|#2| 为标点字符,返回标点的实际左/右空白的负值和根据标点处理方式
-% 决定添加的左/右空白。全角方式直接添加标点的实际左/右空白;半角方式添加标点左右空白
-% 中的最小值;开明方式与半角相同,只在开明标点再增加实际左/右空白的一半。
-% \begin{macrocode}
-\cs_new_protected_nopar:Npn \xeCJK_get_punct_bounds:nN #1#2
- {
- \tl_if_exist:cF { \l_@@_punct_coor_tl/rule/#1/#2 }
+% \begin{macro}[internal]
+% {\@@_punct_dim_csname:nn,\@@_punct_dim_csname:nnn,\@@_punct_dim_csname:nnnn,
+% \@@_use_punct_dim:nnn,\@@_use_punct_dim:nn,
+% \@@_gset_punct_dim:nnx,\@@_gset_punct_dim:nnnx,\@@_gset_punct_dim:nnnnx}
+% 一些用于记录的辅助函数。
+% \begin{macrocode}
+\cs_new_nopar:Npn \@@_punct_dim_csname:nn #1#2
+ { g__\l_xeCJK_current_font_tl/\l_xeCJK_punct_style_tl/#1/#2/tl }
+\cs_new_nopar:Npn \@@_punct_dim_csname:nnn
+ { \@@_punct_dim_csname:nnnn { \l_xeCJK_punct_style_tl } }
+\cs_new_nopar:Npn \@@_punct_dim_csname:nnnn #1#2#3#4
+ { g__\l_xeCJK_current_font_tl/#1/#2/#3/#4/tl }
+\cs_new_nopar:Npn \@@_use_punct_dim:nn #1#2
+ { \tl_use:c { \@@_punct_dim_csname:nn {#1} {#2} } }
+\cs_new_nopar:Npn \@@_use_punct_dim:nnn #1#2#3
+ { \tl_use:c { \@@_punct_dim_csname:nnn {#1} {#2} {#3} } }
+\cs_new_protected_nopar:Npn \@@_gset_punct_dim:nnx #1#2#3
+ { \tl_gset:cx { \@@_punct_dim_csname:nn {#1} {#2} } {#3} }
+\cs_new_protected_nopar:Npn \@@_gset_punct_dim:nnnx #1#2#3#4
+ { \tl_gset:cx { \@@_punct_dim_csname:nnn {#1} {#2} {#3} } {#4} }
+\cs_new_protected_nopar:Npn \@@_gset_punct_dim:nnnnx #1#2#3#4#5
+ { \tl_gset:cx { \@@_punct_dim_csname:nnnn {#1} {#2} {#3} {#4} } {#5} }
+% \end{macrocode}
+% \end{macro}
+%
+% \changes{v3.1.0}{2012/11/14}{使用 \pkg{xtemplate} 宏包的机制来组织标点符号的处理。}
+%
+% 定义标点处理模板。
+% \begin{macrocode}
+\DeclareObjectType { xeCJK / punctuation } { 3 }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\DeclareTemplateInterface { xeCJK / punctuation } { basic } { 3 }
+ {
+ enabled-global-setting : boolean = true ,
+ fixed-punct-width : length = \c_max_dim ,
+ fixed-punct-ratio : real = \c_one_fp ,
+ mixed-punct-width : length = \KeyValue { fixed-punct-width } ,
+ mixed-punct-ratio : real = \KeyValue { fixed-punct-ratio } ,
+ middle-punct-width : length = \KeyValue { fixed-punct-width } ,
+ middle-punct-ratio : real = \KeyValue { fixed-punct-ratio } ,
+ fixed-margin-width : length = \c_max_dim ,
+ fixed-margin-ratio : real = \c_one_fp ,
+ mixed-margin-width : length = \KeyValue { fixed-margin-width } ,
+ mixed-margin-ratio : real = \KeyValue { fixed-margin-ratio } ,
+ middle-margin-width : length = \KeyValue { fixed-margin-width } ,
+ middle-margin-ratio : real = \KeyValue { fixed-margin-ratio } ,
+ add-min-bound-to-margin : boolean = false ,
+ optimize-margin : boolean = false ,
+ margin-minimum : length = \c_zero_dim ,
+ enabled-kerning : boolean = true ,
+ min-bound-to-kerning : boolean = false ,
+ kerning-total-width : length = \c_max_dim ,
+ kerning-total-ratio : real = 0.75 ,
+ optimize-kerning : boolean = false ,
+ same-align-margin : length = \c_max_dim ,
+ same-align-ratio : real = \c_zero_fp ,
+ different-align-margin : length = \c_max_dim ,
+ different-align-ratio : real = \c_zero_fp ,
+ kerning-margin-width : length = \c_max_dim ,
+ kerning-margin-ratio : real = \c_one_fp ,
+ kerning-margin-minimum : length = \c_zero_dim
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\DeclareTemplateCode { xeCJK / punctuation } { basic } { 3 }
+ {
+ enabled-global-setting = \l_@@_enabled_global_setting_bool ,
+ fixed-punct-width = \l_@@_fixed_punct_width_dim ,
+ fixed-punct-ratio = \l_@@_fixed_punct_ratio_fp ,
+ mixed-punct-width = \l_@@_mixed_punct_width_dim ,
+ mixed-punct-ratio = \l_@@_mixed_punct_ratio_fp ,
+ middle-punct-width = \l_@@_middle_punct_width_dim ,
+ middle-punct-ratio = \l_@@_middle_punct_ratio_fp ,
+ fixed-margin-width = \l_@@_fixed_margin_width_dim ,
+ fixed-margin-ratio = \l_@@_fixed_margin_ratio_fp ,
+ mixed-margin-width = \l_@@_mixed_margin_width_dim ,
+ mixed-margin-ratio = \l_@@_mixed_margin_ratio_fp ,
+ middle-margin-width = \l_@@_middle_margin_width_dim ,
+ middle-margin-ratio = \l_@@_middle_margin_ratio_fp ,
+ add-min-bound-to-margin = \l_@@_add_min_bound_to_margin_bool ,
+ optimize-margin = \l_@@_optimize_margin_bool ,
+ margin-minimum = \l_@@_margin_minimum_dim ,
+ enabled-kerning = \l_@@_enabled_kerning_bool ,
+ min-bound-to-kerning = \l_@@_min_bound_to_kerning_bool ,
+ kerning-total-width = \l_@@_kerning_total_width_dim ,
+ kerning-total-ratio = \l_@@_kerning_total_ratio_fp ,
+ optimize-kerning = \l_@@_optimize_kerning_bool ,
+ same-align-margin = \l_@@_same_align_margin_dim ,
+ same-align-ratio = \l_@@_same_align_ratio_fp ,
+ different-align-margin = \l_@@_different_align_margin_dim ,
+ different-align-ratio = \l_@@_different_align_ratio_fp ,
+ kerning-margin-width = \l_@@_kerning_margin_width_dim ,
+ kerning-margin-ratio = \l_@@_kerning_margin_ratio_fp ,
+ kerning-margin-minimum = \l_@@_kerning_margin_minimum_dim
+ }
+ {
+ \AssignTemplateKeys
+ \tl_if_blank:nTF {#3}
+ { \xeCJK_punct_margin_process:NN {#1} {#2} }
+ { \xeCJK_punct_kerning_process:NN {#2} {#3} }
+ }
+% \end{macrocode}
+%
+% \begin{macro}[internal]{\xeCJK_punct_margin_process:NN}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \xeCJK_punct_margin_process:NN #1#2
+ {
+ \tl_set:Nx \l_@@_tmpa_tl { \@@_use_punct_dim:nnn { bound } {#1} {#2} }
+ \tl_set:Nx \l_@@_tmpb_tl
{
- \tl_if_eq:NNTF \l_xeCJK_punctstyle_tl \c_@@_ps_plain_tl
+ \@@_use_punct_dim:nnn { bound }
+ { \xeCJK_reverse:nnn {#1} \c_@@_left_tl \c_@@_right_tl } {#2}
+ }
+ \dim_set:Nn \l_@@_tmp_dim
+ {
+ \bool_if:NTF \l_@@_enabled_global_setting_bool
{
- \tl_set:NV \l_@@_tmpa_tl \c_zero_dim
- \tl_gset_eq:cN { \l_@@_punct_coor_tl/glue/#1/#2 } \l_@@_tmpa_tl
- \tl_gset_eq:cN { \l_@@_punct_coor_tl/rule/#1/#2 } \l_@@_tmpa_tl
- \tl_gset_eq:cN { \l_@@_punct_coor_tl/rule/lr/#2 } \l_@@_tmpa_tl
- \tl_gset_eq:cN { \l_@@_punct_coor_tl/bound/#1/#2 } \l_@@_tmpa_tl
- \tl_gset_eq:cN { \l_@@_punct_coor_tl/bound/lr/#2 } \l_@@_tmpa_tl
+ \cs_if_exist_use:cTF { g_@@_punct_width/#2/tl }
+ { \use_none:n }
+ {
+ \xeCJK_if_blank_x:nTF \g_@@_punct_width_tl
+ { \use:n }
+ { \g_@@_punct_width_tl \use_none:n }
+ }
}
+ { \use:n }
{
- \tl_if_exist:cF { \l_@@_punct_coor_tl/bound/#1/#2 }
- { { \xeCJK_select_font: \xeCJK_calc_punct_dimen:N {#2} } }
- \@@_punct_if_long:NTF {#2}
+ \@@_punct_if_middle:NTF {#2}
+ { \@@_punct_width_or_ratio:nN { middle } {#2} }
{
- \dim_zero:N \l_@@_tmpa_dim
- \dim_zero:N \l_@@_tmpb_dim
- \dim_zero:N \l_@@_tmpc_dim
+ \@@_punct_if_mixed_width:NTF {#2}
+ { \@@_punct_width_or_ratio:nN { mixed } {#2} }
+ { \@@_punct_width_or_ratio:nN { fixed } {#2} }
}
+ }
+ }
+ \@@_gset_punct_dim:nnnx { glue } {#1} {#2}
+ {
+ \dim_max:nn
+ { \l_@@_margin_minimum_dim }
+ {
+ \dim_compare:nNnTF \l_@@_tmp_dim < \c_max_dim
{
- \dim_set:Nc \l_@@_tmpa_dim { \l_@@_punct_coor_tl/bound/#1/#2 }
- \dim_set:Nc \l_@@_tmpb_dim
- { \l_@@_punct_coor_tl/bound/\str_if_eq_x:nnTF {#1} lrl/#2 }
- \dim_set:Nn \l_@@_tmpc_dim
+ \@@_punct_if_middle:NTF {#2}
{
- \cs_if_exist_use:cF { g_@@_punct_width/#2 }
- {
- \xeCJK_if_blank_x:nTF \g_@@_punct_width_tl
- { \c_zero_dim } { \g_@@_punct_width_tl }
- }
+ (
+ \l_@@_tmp_dim - ( \@@_use_punct_dim:nn { dimen } {#2} )
+ ) / \c_two
}
- \@@_punct_if_middle:NTF {#2}
{
- \dim_set:Nn \l_@@_tmpc_dim
+ \bool_if:NTF \l_@@_optimize_margin_bool
+ { \dim_max:nn { \dim_min:nn \l_@@_tmpa_tl \l_@@_tmpb_tl } }
+ { \use:n }
{
- \dim_compare:nNnTF \l_@@_tmpc_dim > \c_zero_dim
- { \l_@@_tmpc_dim }
- {
- \tl_case:Nnn \l_xeCJK_punctstyle_tl
- {
- \c_@@_ps_halfwidth_tl { .5 em }
- \c_@@_ps_mixedwidth_tl { .5 em }
- \c_@@_ps_CCT_tl { .7 em }
- \c_@@_ps_fullwidth_tl { 1 em }
- }
- { 1 em }
- }
- - ( \tl_use:c { \l_@@_punct_coor_tl/dimen/#2 } )
- }
- \dim_compare:nNnTF \l_@@_tmpc_dim > \c_zero_dim
- { \dim_set:Nn \l_@@_tmpc_dim { .5 \l_@@_tmpc_dim } }
- {
- \dim_set:Nn \l_@@_tmpc_dim
- { \dim_min:nn \l_@@_tmpa_dim \l_@@_tmpb_dim }
+ \l_@@_tmp_dim - ( \l_@@_tmpb_tl )
+ - ( \@@_use_punct_dim:nn { dimen } {#2} )
}
}
+ }
+ {
+ \bool_if:NTF \l_@@_optimize_margin_bool
+ { \dim_min:nn { \l_@@_tmpa_tl } }
+ { \use:n }
{
- \dim_compare:nNnTF \l_@@_tmpc_dim > \c_zero_dim
+ \@@_punct_if_middle:NTF {#2}
{
- \dim_set:Nn \l_@@_tmpc_dim
+ \dim_compare:nNnTF \l_@@_middle_margin_width_dim < \c_max_dim
+ { \l_@@_middle_margin_width_dim }
{
- \l_@@_tmpc_dim - \l_@@_tmpb_dim
- - ( \tl_use:c { \l_@@_punct_coor_tl/dimen/#2 } )
+ \fp_use:N \l_@@_middle_margin_ratio_fp
+ \etex_dimexpr:D
+ ( \l_@@_tmpa_tl + \l_@@_tmpb_tl ) / \c_two
+ \scan_stop:
}
}
{
- \dim_set:Nn \l_@@_tmpc_dim
- { \dim_min:nn \l_@@_tmpa_dim \l_@@_tmpb_dim }
- \tl_case:Nnn \l_xeCJK_punctstyle_tl
- {
- \c_@@_ps_halfwidth_tl { \prg_do_nothing: }
- \c_@@_ps_mixedwidth_tl
- {
- \@@_punct_if_mixedwidth:NT {#2}
- {
- \dim_add:Nn \l_@@_tmpc_dim { .5 \l_@@_tmpa_dim }
- \xeCJK_dim_set_min:Nn \l_@@_tmpc_dim \l_@@_tmpa_dim
- }
- }
- \c_@@_ps_CCT_tl
- {
- \@@_punct_if_mixedwidth:NTF {#2}
- { \dim_add:Nn \l_@@_tmpc_dim { .5 \l_@@_tmpa_dim } }
- { \dim_add:Nn \l_@@_tmpc_dim { .3 \l_@@_tmpa_dim } }
- \xeCJK_dim_set_min:Nn \l_@@_tmpc_dim \l_@@_tmpa_dim
- }
- }
- { \dim_set_eq:NN \l_@@_tmpc_dim \l_@@_tmpa_dim }
+ \@@_punct_if_mixed_width:NTF {#2}
+ { \@@_margin_width_or_ratio:n { mixed } }
+ { \@@_margin_width_or_ratio:n { fixed } }
}
}
- \xeCJK_dim_set_max:Nn \l_@@_tmpc_dim \c_zero_dim
}
- \tl_gset:cx { \l_@@_punct_coor_tl/rule/#1/#2 }
- { - \dim_use:N \l_@@_tmpa_dim }
- \tl_gset:cx { \l_@@_punct_coor_tl/rule/lr/#2 }
- { - \dim_use:N \l_@@_tmpb_dim }
- \tl_gset:cV { \l_@@_punct_coor_tl/glue/#1/#2 } \l_@@_tmpc_dim
}
}
}
-\cs_generate_variant:Nn \xeCJK_get_punct_bounds:nN { nV }
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\xeCJKsetwidth}
+% \begin{macro}[internal]{\@@_punct_width_or_ratio:nN}
% \begin{macrocode}
-\NewDocumentCommand \xeCJKsetwidth { m m }
- { \tl_map_inline:xn {#1} { \tl_gset:cn { g_@@_punct_width/##1 } {#2} } }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[pTF,internal]
-% {\@@_punct_if_right:N,\@@_punct_if_both_left_right:NN,
-% \@@_punct_if_long:N,\@@_punct_if_middle:N,
-% \@@_punct_if_mixedwidth:N}
-% \begin{macrocode}
-\prg_new_conditional:Npnn \@@_punct_if_right:N #1 { p , T , F , TF }
+\cs_new_nopar:Npn \@@_punct_width_or_ratio:nN #1#2
{
- \tl_if_exist:cTF { \l_@@_punct_coor_tl/glue/r/#1 }
- \prg_return_true: \prg_return_false:
- }
-\prg_new_conditional:Npnn \@@_punct_if_both_left_right:NN #1#2 { p , T , F , TF }
- {
- \bool_if:nTF
+ \dim_compare:nNnTF { \use:c { l_@@_#1_punct_width_dim } } < \c_max_dim
+ { \use:c { l_@@_#1_punct_width_dim } }
{
- ( \tl_if_exist_p:c { \l_@@_punct_coor_tl/glue/r/#1 } &&
- \tl_if_exist_p:c { \l_@@_punct_coor_tl/glue/r/#2 } ) ||
- ( \tl_if_exist_p:c { \l_@@_punct_coor_tl/glue/l/#1 } &&
- \tl_if_exist_p:c { \l_@@_punct_coor_tl/glue/l/#2 } )
+ \fp_compare:nNnTF { \use:c { l_@@_#1_punct_ratio_fp } } = \c_zero_fp
+ { \c_max_dim }
+ {
+ \fp_use:c { l_@@_#1_punct_ratio_fp }
+ \etex_dimexpr:D \@@_use_punct_dim:nn { width } {#2} \scan_stop:
+ }
}
- \prg_return_true: \prg_return_false:
}
-\cs_generate_variant:Nn \prg_new_conditional:Npnn { c }
-\clist_map_inline:Nn \g_@@_special_ps_clist
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\@@_margin_width_or_ratio:n}
+% \begin{macrocode}
+\cs_new_nopar:Npn \@@_margin_width_or_ratio:n #1
{
- \prg_new_conditional:cpnn { @@_punct_if_#1:N } ##1 { p , T , F , TF }
+ \dim_compare:nNnTF { \use:c { l_@@_#1_margin_width_dim } } < \c_max_dim
+ { \use:c { l_@@_#1_margin_width_dim } }
{
- \prop_if_in:cnTF { l_@@_#1_punct_prop } {##1}
- \prg_return_true: \prg_return_false:
+ \fp_use:c { l_@@_#1_margin_ratio_fp }
+ \etex_dimexpr:D \l_@@_tmpa_tl \scan_stop:
}
+ \bool_if:NT \l_@@_add_min_bound_to_margin_bool
+ { + \dim_min:nn \l_@@_tmpa_tl \l_@@_tmpb_tl }
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\xeCJK_calc_kern:NN,\@@_calc_kern:NNN}
-% 标点挤压。行末半角方式,相邻标点不挤压;全角方式,相邻两个标点占 1.5 汉字宽度,
-% 半角、开明和 CCT 方式相邻标点占一个汉字宽度。
+% \begin{macro}[internal]{\xeCJK_punct_kerning_process:NN}
% \begin{macrocode}
-\cs_new_protected_nopar:Npn \xeCJK_calc_kern:NN #1#2
+\cs_new_protected_nopar:Npn \xeCJK_punct_kerning_process:NN #1#2
{
- \tl_if_exist:cF { \l_@@_punct_coor_tl/kern/#1-#2 }
+ \@@_gset_punct_dim:nnnx { kern } {#1} {#2}
{
- \dim_zero:N \l_@@_tmpa_dim
- \tl_if_eq:NNF \l_xeCJK_punctstyle_tl \c_@@_ps_plain_tl
+ \dim_eval:n
{
- \tl_if_exist:cTF { g_@@_punct/kern/#1-#2 }
- { \dim_set:Nc \l_@@_tmpa_dim { g_@@_punct/kern/#1-#2 } }
- { \@@_calc_kern:NNN \l_@@_tmpa_dim {#1} {#2} }
+ \bool_if:nTF
+ {
+ \l_@@_enabled_global_setting_bool &&
+ \tl_if_exist_p:c { g_@@_punct/kern/#1/#2/tl }
+ }
+ { \tl_use:c { g_@@_punct/kern/#1/#2/tl } }
+ {
+ \bool_if:NTF \l_@@_enabled_kerning_bool
+ { \@@_calc_kerning_margin:NN {#1} {#2} }
+ { \@@_original_kerning_margin:NN {#1} {#2} }
+ }
+ - ( \@@_use_punct_dim:nnn { bound } \c_@@_right_tl {#1} )
+ - ( \@@_use_punct_dim:nnn { bound } \c_@@_left_tl {#2} )
}
- \tl_gset:cV { \l_@@_punct_coor_tl/kern/#1-#2 } \l_@@_tmpa_dim
}
}
-\cs_new_protected_nopar:Npn \@@_calc_kern:NNN #1#2#3
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\@@_original_kerning_margin:NN}
+% 相邻两个标点符号之间的本来空白宽度。
+% \begin{macrocode}
+\cs_new_nopar:Npn \@@_original_kerning_margin:NN #1#2
{
- \tl_if_eq:NNTF \l_xeCJK_punctstyle_tl \c_@@_ps_marginkerning_tl
+ \dim_eval:n
{
- \dim_zero:N #1
- \@@_punct_if_right:NT {#2}
- { \dim_add:Nc #1 { \l_@@_punct_coor_tl/bound/r/#2 } }
- \@@_punct_if_right:NF {#3}
- { \dim_add:Nc #1 { \l_@@_punct_coor_tl/bound/l/#3 } }
+ \@@_use_punct_dim:nnn
+ { \@@_punct_if_right:NTF {#1} { glue } { bound } }
+ { \c_@@_right_tl } {#1} +
+ \@@_use_punct_dim:nnn
+ { \@@_punct_if_right:NTF {#2} { bound } { glue } }
+ { \c_@@_left_tl } {#2}
}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\@@_calc_kerning_margin:NN}
+% \begin{macrocode}
+\cs_new_nopar:Npn \@@_calc_kerning_margin:NN #1#2
+ {
+ \dim_max:nn
+ { \l_@@_kerning_margin_minimum_dim }
{
- \tl_if_eq:NNTF \l_xeCJK_punctstyle_tl \c_@@_ps_fullwidth_tl
- { \dim_set:Nn #1 { \xeCJK_calc_kern:nNN { 1.5 em } {#2} {#3} } }
+ \bool_if:NTF \l_@@_min_bound_to_kerning_bool
+ { \@@_punct_min_bound:NN {#1} {#2} }
{
- \@@_punct_if_both_left_right:NNTF {#2} {#3}
- {
- \@@_punct_if_mixedwidth:NT {#2}
- {
- \dim_set:Nn #1 { \xeCJK_calc_kern:nNN { 1 em } {#2} {#3} }
- \dim_compare:nNnT #1 < { .1 em }
- { \dim_set:Nc #1 { \l_@@_punct_coor_tl/bound/l/#2 } }
- }
- }
+ \bool_if:NTF \l_@@_optimize_kerning_bool
+ { \dim_max:nn { \@@_punct_min_bound:NN {#1} {#2} } }
+ { \use:n }
{
- \bool_if:nTF
- {
- \@@_punct_if_mixedwidth_p:N {#2} &&
- ! ( \tl_if_eq_p:NN \l_xeCJK_punctstyle_tl \c_@@_ps_halfwidth_tl )
- }
- {
- \dim_set:Nn #1 { \tl_use:c { \l_@@_punct_coor_tl/glue/r/#2 } }
- \dim_set:Nn #1 { .7 #1 }
- }
+ \dim_compare:nNnTF \l_@@_kerning_total_width_dim < \c_max_dim
+ { \@@_calc_kerning_margin:nNN \l_@@_kerning_total_width_dim }
{
- \dim_set:Nn #1 { \xeCJK_calc_kern:nNN { 1 em } {#2} {#3} }
- \dim_compare:nNnT #1 < { .1 em }
+ \fp_compare:nNnTF \l_@@_kerning_total_ratio_fp = \c_zero_fp
{
- \dim_set:Nn #1
+ \xeCJK_if_same_class:NNTF {#1} {#2}
+ { \@@_kerning_width_or_ratio:nNN { same } }
+ { \@@_kerning_width_or_ratio:nNN { different } }
+ }
+ {
+ \@@_calc_kerning_margin:nNN
{
- \dim_max:nn
- {
- \dim_min:cc
- { \l_@@_punct_coor_tl/bound/l/#2 }
- { \l_@@_punct_coor_tl/bound/r/#2 }
- }
- {
- \dim_min:cc
- { \l_@@_punct_coor_tl/bound/l/#3 }
- { \l_@@_punct_coor_tl/bound/r/#3 }
- }
+ \fp_use:N \l_@@_kerning_total_ratio_fp
+ \etex_dimexpr:D
+ \@@_use_punct_dim:nn { width } {#1} +
+ \@@_use_punct_dim:nn { width } {#2}
+ \scan_stop:
}
}
}
+ {#1} {#2}
}
}
- \bool_if:nT
- { \@@_punct_if_long_p:N {#2} || \@@_punct_if_long_p:N {#3} }
- { \xeCJK_dim_set_max:Nn #1 { .1 em } }
}
- \xeCJK_dim_set_max:Nn #1 \c_zero_dim
}
-\cs_generate_variant:Nn \xeCJK_calc_kern:NN { V }
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\xeCJK_calc_kern:nNN}
+% \begin{macro}[internal]{\@@_kerning_width_or_ratio:nNN}
+% \begin{macrocode}
+\cs_new_nopar:Npn \@@_kerning_width_or_ratio:nNN #1#2#3
+ {
+ \dim_compare:nNnTF { \use:c { l_@@_#1_align_margin_dim } } < \c_max_dim
+ { \use:c { l_@@_#1_align_margin_dim } \use_none:nn }
+ {
+ \fp_compare:nNnTF { \use:c { l_@@_#1_align_ratio_fp } } = \c_zero_fp
+ { \use:n }
+ { \fp_use:c { l_@@_#1_align_ratio_fp } \use_ii:nn }
+ }
+ {
+ \dim_compare:nNnTF \l_@@_kerning_margin_width_dim < \c_max_dim
+ { \l_@@_kerning_margin_width_dim \use_none:n }
+ { \fp_use:N \l_@@_kerning_margin_ratio_fp \use:n }
+ }
+ { \etex_dimexpr:D \@@_original_kerning_margin:NN {#2} {#3} \scan_stop: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\@@_punct_min_bound:NN}
+% \begin{macrocode}
+\cs_new_nopar:Npn \@@_punct_min_bound:NN #1#2
+ {
+ \dim_max:nn
+ {
+ \dim_min:nn
+ { \@@_use_punct_dim:nnn { bound } \c_@@_left_tl {#1} }
+ { \@@_use_punct_dim:nnn { bound } \c_@@_right_tl {#1} }
+ }
+ {
+ \dim_min:nn
+ { \@@_use_punct_dim:nnn { bound } \c_@@_left_tl {#2} }
+ { \@@_use_punct_dim:nnn { bound } \c_@@_right_tl {#2} }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\@@_calc_kerning_margin:nNN}
% |#2| 和 |#3| 为相邻的两个标点,|#1| 为要确定的相邻两个标点总共占的宽度。
% \begin{macrocode}
-\cs_new_protected_nopar:Npn \xeCJK_calc_kern:nNN #1#2#3
+\cs_new_nopar:Npn \@@_calc_kerning_margin:nNN #1#2#3
{
\dim_eval:n
{
- #1
- - \tl_use:c { \l_@@_punct_coor_tl/
- \@@_punct_if_right:NTF {#2} { bound } { glue } /l/#2 }
- - \tl_use:c { \l_@@_punct_coor_tl/
- \@@_punct_if_right:NTF {#3} { glue } { bound } /r/#3 }
- - \tl_use:c { \l_@@_punct_coor_tl/dimen/#2 }
- - \tl_use:c { \l_@@_punct_coor_tl/dimen/#3 }
- \@@_punct_if_both_left_right:NNT {#2} {#3}
- { + \tl_use:c { \l_@@_punct_coor_tl/rule/lr/#3 } }
+ (#1)
+ - ( \@@_use_punct_dim:nnn
+ { \@@_punct_if_right:NTF {#2} { bound } { glue } }
+ { \c_@@_left_tl } {#2} )
+ - ( \@@_use_punct_dim:nnn
+ { \@@_punct_if_right:NTF {#3} { glue } { bound } }
+ { \c_@@_right_tl } {#3} )
+ - ( \@@_use_punct_dim:nn { dimen } {#2} )
+ - ( \@@_use_punct_dim:nn { dimen } {#3} )
}
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\xeCJK_calc_punct_dimen:N}
-% 返回标点的左右空白和实际尺寸。对于破折号,计算两标点之间的空白,保证它中间不被断开。
+% \begin{macro}[internal]{\xeCJK_get_punct_bounds:NN}
+% |#1| 为 \cs{c_@@_left_tl} 或 \cs{c_@@_right_tl},|#2| 为标点符号。
% \begin{macrocode}
-\cs_new_protected_nopar:Npn \xeCJK_calc_punct_dimen:N #1
+\cs_new_protected_nopar:Npn \xeCJK_get_punct_bounds:NN #1#2
{
- \tl_gset:cx { \l_@@_punct_coor_tl/bound/l/#1 }
- { \xeCJK_glyph_bounds:nN { left } {#1} }
- \tl_gset:cx { \l_@@_punct_coor_tl/bound/r/#1 }
- { \xeCJK_glyph_bounds:nN { right } {#1} }
- \tl_gset:cx { \l_@@_punct_coor_tl/bound/lr/#1 }
+ \tl_if_exist:cF { \@@_punct_dim_csname:nnn { glue } {#1} {#2} }
{
- \dim_eval:n
+ \tl_if_eq:NNTF \l_xeCJK_punct_style_tl \c_@@_punct_style_plain_tl
{
- ( \tl_use:c { \l_@@_punct_coor_tl/bound/l/#1 } ) +
- ( \tl_use:c { \l_@@_punct_coor_tl/bound/r/#1 } )
+ \@@_gset_punct_dim:nnnx { glue } {#1} {#2} { \c_zero_dim }
+ \@@_gset_punct_dim:nnnx { bound } \c_@@_left_tl {#2} { \c_zero_dim }
+ \@@_gset_punct_dim:nnnx { bound } \c_@@_right_tl {#2} { \c_zero_dim }
}
- }
- \tl_gset:cx { \l_@@_punct_coor_tl/dimen/#1 }
- {
- \dim_eval:n
{
- ( \etex_fontcharwd:D \tex_font:D `#1 ) -
- ( \tl_use:c { \l_@@_punct_coor_tl/bound/lr/#1 } )
+ { \xeCJK_select_font: \xeCJK_calc_punct_dimen:f {#2} }
+ \@@_punct_if_long:NTF {#2}
+ { \@@_gset_punct_dim:nnnx { glue } {#1} {#2} { \c_zero_dim } }
+ {
+ \UseInstance { xeCJK / punctuation }
+ { \l_xeCJK_punct_style_tl } {#1} {#2} { }
+ }
}
}
- \bool_if:nT
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\xeCJK_calc_punct_dimen:N}
+% 计算标点的左右实际边距和实际尺寸。对于破折号,计算两标点之间的空白,保证它中间
+% 不被断开。
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \xeCJK_calc_punct_dimen:N #1
+ {
+ \@@_gset_punct_dim:nnnx { bound } \c_@@_left_tl {#1}
+ { \xeCJK_glyph_bounds:NN \c_one {#1} }
+ \@@_gset_punct_dim:nnnx { bound } \c_@@_right_tl {#1}
+ { \xeCJK_glyph_bounds:NN \c_three {#1} }
+ \dim_set:Nn \l_@@_tmp_dim
{
- \@@_punct_if_long_p:N {#1} &&
- ! ( \str_if_eq_x_p:nn {#1} { ^^^^2025 } || \str_if_eq_x_p:nn {#1} { ^^^^2026 } )
+ ( \@@_use_punct_dim:nnn { bound } \c_@@_left_tl {#1} ) +
+ ( \@@_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 }
+ \@@_gset_punct_dim:nnx { dimen } {#1}
+ { \dim_eval:n { \@@_use_punct_dim:nn { width } {#1} - \l_@@_tmp_dim } }
+ \@@_punct_if_long:NT {#1}
{
- \clist_map_inline:Nn \g_@@_punctstyle_clist
+ \seq_map_inline:Nn \g_@@_punct_style_seq
{
- \str_if_eq_x:nnF \c_@@_ps_plain_tl {##1}
+ \@@_gset_punct_dim:nnnnx {##1} { kern } {#1} {#1}
{
- \tl_gset:cx { \l_xeCJK_font_coor_tl/##1/kern/#1-#1 }
- { - \tl_use:c { \l_@@_punct_coor_tl/bound/lr/#1 } }
+ \bool_if:nTF
+ {
+ \str_if_eq_p:nn {#1} { ^^^^2025 } ||
+ \str_if_eq_p:nn {#1} { ^^^^2026 }
+ }
+ { \c_zero_dim }
+ { - \dim_use:N \l_@@_tmp_dim }
}
}
}
}
+\cs_generate_variant:Nn \xeCJK_calc_punct_dimen:N { f }
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\xeCJK_glyph_bounds:nN}
-% 用 \cs{XeTeXglyphbounds} 计算标点的上下左右空白。
+% \begin{macro}[internal]{\xeCJK_glyph_bounds:NN}
+% 用 \cs{XeTeXglyphbounds} 取得标点符号的上下左右空白。
% \begin{macrocode}
-\cs_new_protected_nopar:Npn \xeCJK_glyph_bounds:nN #1#2
+\cs_new_nopar:Npn \xeCJK_glyph_bounds:NN #1#2
+ { \dim_use:N \XeTeXglyphbounds #1 ~ \XeTeXcharglyph `#2 \exp_stop_f: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\xeCJK_get_punct_kerning:NN}
+% 标点挤压。
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \xeCJK_get_punct_kerning:NN #1#2
{
- \dim_eval:n
+ \tl_if_exist:cF { \@@_punct_dim_csname:nnn { kern } {#1} {#2} }
{
- \XeTeXglyphbounds
- \str_case_x:nnn {#1}
- {
- { left } { \c_one } { top } { \c_two }
- { right } { \c_three } { bottom } { \c_four }
- }
- { \c_three }
- \int_eval:n { \XeTeXcharglyph `#2 }
+ \tl_if_eq:NNTF \l_xeCJK_punct_style_tl \c_@@_punct_style_plain_tl
+ { \@@_gset_punct_dim:nnnx { kern } {#1} {#2} { \c_zero_dim } }
+ {
+ \UseInstance { xeCJK / punctuation }
+ { \l_xeCJK_punct_style_tl } { } {#1} {#2}
+ }
}
}
+\cs_generate_variant:Nn \xeCJK_get_punct_kerning:NN { o }
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\xeCJKsetkern}
-% 手动设置相邻标点的距离,仅在当前字体状态下有效。
+% \begin{macro}{PunctStyle}
% \begin{macrocode}
-\NewDocumentCommand \xeCJKsetkern { m m m }
- { \tl_gset:cn { g_@@_punct/kern/#1-#2 } {#3} }
+\keys_define:nn { xeCJK / options }
+ {
+ PunctStyle .choice: ,
+ PunctStyle .default:n = { quanjiao } ,
+ PunctStyle / halfwidth .meta:n = { PunctStyle = banjiao } ,
+ PunctStyle / fullwidth .meta:n = { PunctStyle = quanjiao } ,
+ PunctStyle / mixedwidth .meta:n = { PunctStyle = kaiming } ,
+ PunctStyle / marginkerning .meta:n = { PunctStyle = hangmobanjiao } ,
+ PunctStyle / plain .code:n =
+ { \tl_set_eq:NN \l_xeCJK_punct_style_tl \c_@@_punct_style_plain_tl } ,
+ PunctStyle / unknown .code:n =
+ {
+ \IfInstanceExistTF { xeCJK / punctuation } { \l_keys_value_tl }
+ { \tl_set:Nx \l_xeCJK_punct_style_tl { \l_keys_value_tl } }
+ { \@@_error:nx { punct-style-unknown } { \l_keys_value_tl } }
+ }
+ }
+\tl_const:Nn \c_@@_punct_style_plain_tl { plain }
+\@@_msg_new:nn { punct-style-unknown }
+ {
+ Punctuation~style~"#1"~is~unknown. \\\\
+ The~available~styles~are~listed~as~follow.\\\\
+ "plain,~\seq_use:Nnnn \g_@@_punct_style_seq { ~and~ } { ,~ } { ,~and~ }".\\
+ }
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}{\xeCJKDeclarePunctStyle}
+% 定义新的标点处理风格,已经存在的同名风格将被覆盖。
+% \begin{macrocode}
+\NewDocumentCommand \xeCJKDeclarePunctStyle { > { \TrimSpaces } m m }
+ {
+ \IfInstanceExistTF { xeCJK / punctuation } {#1}
+ { \@@_warning:nx { punct-style-already-defined } {#1} }
+ { \seq_gput_right:Nn \g_@@_punct_style_seq {#1} }
+ \DeclareInstance { xeCJK / punctuation } {#1} { basic } {#2}
+ }
+\seq_new:N \g_@@_punct_style_seq
+\@@_msg_new:nn { punct-style-already-defined }
+ {
+ Punctuation~style~"#1"~is~already~defined!. \\\\
+ The~existing~style~of~"#1"~will~be~overwritten.\\
+ }
+\@onlypreamble \xeCJKDeclarePunctStyle
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\xeCJKEditPunctStyle}
+% 对已有的标点处理风格进行修改。
+% \begin{macrocode}
+\NewDocumentCommand \xeCJKEditPunctStyle { > { \TrimSpaces } m m }
+ {
+ \IfInstanceExistTF { xeCJK / punctuation } {#1}
+ { \EditInstance { xeCJK / punctuation } {#1} {#2} }
+ { \@@_error:nx { punct-style-unknown } {#1} }
+ }
+\@onlypreamble \xeCJKEditPunctStyle
+% \end{macrocode}
+% \end{macro}
+%
+% 默认设置即为全角格式。
+% \begin{macrocode}
+\xeCJKDeclarePunctStyle { quanjiao } { }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\xeCJKDeclarePunctStyle { hangmobanjiao } { enabled-kerning = false }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\xeCJKDeclarePunctStyle { banjiao }
+ {
+ fixed-punct-ratio = 0.5 ,
+ optimize-margin = true ,
+ kerning-total-ratio = 0.5 ,
+ optimize-kerning = true
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\xeCJKDeclarePunctStyle { kaiming }
+ {
+ fixed-punct-ratio = 0.5 ,
+ mixed-punct-ratio = 0.8 ,
+ optimize-margin = true ,
+ kerning-total-ratio = 0.5 ,
+ optimize-kerning = true
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\xeCJKDeclarePunctStyle { CCT }
+ {
+ fixed-punct-ratio = 0.7 ,
+ optimize-margin = true ,
+ kerning-total-ratio = 0.6 ,
+ optimize-kerning = true
+ }
+% \end{macrocode}
+%
% \subsection{后备字体}
%
% \begin{macro}{AutoFallBack}
@@ -2985,11 +3507,11 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
% \begin{macrocode}
\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 },
+ 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}
@@ -2997,14 +3519,13 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
% \begin{macro}[internal]{\xeCJKenablefallback, \xeCJKdisablefallback}
% 后备字体的启用开关,默认关闭。
% \begin{macrocode}
-\bool_new:N \l_@@_fallback_bool
\NewDocumentCommand \xeCJKenablefallback { }
{
\bool_if:NF \l_@@_fallback_bool
{
\bool_set_true:N \l_@@_fallback_bool
\cs_set_eq:NN \@@_fallback_save_CJKsymbol:N \CJKsymbol
- \cs_set_eq:NN \CJKsymbol \xeCJK_fallback_testsymbol:N
+ \cs_set_eq:NN \CJKsymbol \xeCJK_fallback_test_glyph:N
}
}
\NewDocumentCommand \xeCJKdisablefallback { }
@@ -3015,76 +3536,96 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
\cs_set_eq:NN \CJKsymbol \@@_fallback_save_CJKsymbol:N
}
}
+\bool_new:N \l_@@_fallback_bool
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\xeCJK_fallback_testsymbol:N}
+% \begin{macro}[internal]{\xeCJK_fallback_test_glyph:N}
% 测试当前字体中是否存在当前字符,如存在则直接输出,否则启用后备字体。
% \begin{macrocode}
-\cs_new_protected_nopar:Npn \xeCJK_fallback_testsymbol:N #1
+\cs_new_protected_nopar:Npn \xeCJK_fallback_test_glyph:N #1
{
- \font_glyph_if_exist:NnTF \tex_font:D {`#1}
+ \xeCJK_glyph_if_exist:NTF {#1}
{ \@@_fallback_save_CJKsymbol:N {#1} }
+ { { \xeCJK_fallback_loop:Nn {#1} { \l_xeCJK_family_tl/FallBack } } }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\xeCJK_fallback_loop:Nn}
+% \changes{v3.1.0}{2012/11/19}{调整备用字体的循环方式。}
+% 循环测试后备字体是否包含字符 |#1|。若后备字体中存在该字符或者再没有后备字体,则
+% 结束循环。
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \xeCJK_fallback_loop:Nn #1#2
+ {
+ \xeCJK_family_if_exist:xTF {#2}
{
- \xeCJK_family_if_exist:xTF { \l_xeCJK_family_tl/FallBack }
- { {
- \tl_put_right:Nn \l_xeCJK_family_tl { /FallBack }
- \xeCJK_select_font:
- \xeCJK_fallback_testsymbol:N {#1}
- } }
- {
- \@@_warning:nx { fallback } {#1}
- \@@_fallback_save_CJKsymbol:N {#1}
- }
+ \xeCJK_select_font:x {#2}
+ \xeCJK_glyph_if_exist:NTF {#1}
+ { \@@_fallback_save_CJKsymbol:N {#1} }
+ { \xeCJK_fallback_loop:Nn {#1} { #2/FallBack } }
+ }
+ {
+ \@@_warning:nxx { fallback } {#1} {#2}
+ \@@_fallback_save_CJKsymbol:N {#1}
}
}
\@@_msg_new:nn { fallback }
{
- CJKfamily~'\l_xeCJK_family_tl'~
- ( \prop_get:NV \g_@@_family_prop \l_xeCJK_family_tl )~
+ CJKfamily~'#2'~
+ ( \prop_get:No \g_@@_family_font_name_prop {#2} )~
does~not~contain~glyph~'#1'~(U+\int_to_hexadecimal:n {`#1}).\\
}
+\cs_generate_variant:Nn \prop_get:Nn { No }
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\setCJKfallbackfamilyfont}
-% \begin{macro}[internal]{\xeCJK_set_family_fallback:xnn}
% \begin{macrocode}
\NewDocumentCommand \setCJKfallbackfamilyfont { m O{} m }
{
- \exp_args:Nx \tl_if_in:nnTF {#3} { , }
- { \xeCJK_set_family_fallback:xnn {#1} {#2} {#3} }
- { \xeCJK_set_family:xnn { #1/FallBack } {#2} {#3} }
+ \clist_set:Nx \l_@@_tmpa_clist {#3}
+ \int_compare:nNnTF { \clist_count:N \l_@@_tmpa_clist } > \c_one
+ { \xeCJK_set_family_fallback:xxN {#1} {#2} \l_@@_tmpa_clist }
+ { \xeCJK_set_family:xxx { #1/FallBack } {#2} {#3} }
}
-\cs_new_protected_nopar:Npn \xeCJK_set_family_fallback:xnn #1#2#3
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\xeCJK_set_family_fallback:nnN}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \xeCJK_set_family_fallback:nnN #1#2#3
{
\group_begin:
- \tl_set:Nx \l_@@_family_fb_tl {#1}
- \prop_get:NVNF \g_@@_family_prop \l_@@_family_fb_tl \l_@@_fontname_tl
- { \tl_clear:N \l_@@_fontname_tl }
- \clist_map_inline:xn {#3}
+ \tl_set:Nn \l_@@_fallback_family_tl {#1}
+ \prop_get:NVNF \g_@@_family_font_name_prop
+ \l_@@_fallback_family_tl \l_@@_font_name_tl
+ { \tl_clear:N \l_@@_font_name_tl }
+ \clist_map_inline:Nn #3
{
- \tl_put_right:Nn \l_@@_family_fb_tl { /FallBack }
- \@@_get_sub_features:nn \l_@@_family_fb_tl {##1}
- \clist_put_left:cx { l_@@_ \l_@@_family_fb_tl _fontfeat_clist } {#2}
- \xeCJK_set_family:xcc \l_@@_family_fb_tl
- { l_@@_ \l_@@_family_fb_tl _fontfeat_clist }
- { l_@@_ \l_@@_family_fb_tl _fontname_tl }
+ \tl_put_right:Nn \l_@@_fallback_family_tl { /FallBack }
+ \@@_get_sub_features:Vn \l_@@_fallback_family_tl {##1}
+ \clist_put_left:cn
+ { l_@@_ \l_@@_fallback_family_tl _font_options_clist } {#2}
+ \xeCJK_set_family:Vvv \l_@@_fallback_family_tl
+ { l_@@_ \l_@@_fallback_family_tl _font_options_clist }
+ { l_@@_ \l_@@_fallback_family_tl _font_name_tl }
}
\group_end:
}
+\cs_generate_variant:Nn \xeCJK_set_family_fallback:nnN { xx }
% \end{macrocode}
% \end{macro}
-% \end{macro}
%
%
% \subsection{CJK 字体族声明方式}
%
% \begin{macrocode}
-\bool_new:N \g_@@_AutoFakeBold_bool
-\bool_new:N \g_@@_AutoFakeSlant_bool
-\fp_new:N \g_@@_EmboldenFactor_fp
-\fp_new:N \g_@@_SlantFactor_fp
+\bool_new:N \g_@@_auto_fake_bold_bool
+\bool_new:N \g_@@_auto_fake_slant_bool
+\fp_new:N \g_@@_embolden_factor_fp
+\fp_new:N \g_@@_slant_factor_fp
% \end{macrocode}
%
% \begin{macro}{AutoFakeBold, AutoFakeSlant,EmboldenFactor,SlantFactor}
@@ -3092,64 +3633,52 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
% \begin{macrocode}
\keys_define:nn { xeCJK / options }
{
- AutoFakeBold .choice:,
- AutoFakeBold / true .code:n =
- { \bool_set_true:N \g_@@_AutoFakeBold_bool },
- AutoFakeBold / false .code:n =
- { \bool_set_false:N \g_@@_AutoFakeBold_bool },
+ AutoFakeBold .choices:nn = { true , false }
+ { \use:c { bool_gset_ \l_keys_choice_tl :N } \g_@@_auto_fake_bold_bool } ,
AutoFakeBold / unknown .code:n =
{
- \bool_set_true:N \g_@@_AutoFakeBold_bool
- \fp_set:Nn \g_@@_EmboldenFactor_fp { \l_keys_value_tl }
- },
- AutoFakeBold .default:n = { true },
- AutoFakeSlant .choice:,
- AutoFakeSlant / true .code:n =
- { \bool_set_true:N \g_@@_AutoFakeSlant_bool },
- AutoFakeSlant / false .code:n =
- { \bool_set_false:N \g_@@_AutoFakeSlant_bool },
+ \bool_gset_true:N \g_@@_auto_fake_bold_bool
+ \fp_gset:Nn \g_@@_embolden_factor_fp { \l_keys_value_tl }
+ } ,
+ AutoFakeBold .default:n = { true } ,
+ AutoFakeSlant .choices:nn = { true , false }
+ { \use:c { bool_gset_ \l_keys_choice_tl :N } \g_@@_auto_fake_slant_bool } ,
AutoFakeSlant / unknown .code:n =
{
- \bool_set_true:N \g_@@_AutoFakeSlant_bool
- \fp_set:Nn \g_@@_SlantFactor_fp { \l_keys_value_tl }
- },
- AutoFakeSlant .default:n = { true },
- EmboldenFactor .fp_set:N = \g_@@_EmboldenFactor_fp,
- SlantFactor .fp_set:N = \g_@@_SlantFactor_fp,
- BoldFont .meta:n = { AutoFakeBold = true },
- boldfont .meta:n = { AutoFakeBold = true },
- SlantFont .meta:n = { AutoFakeSlant = true },
- slantfont .meta:n = { AutoFakeSlant = true },
+ \bool_gset_true:N \g_@@_auto_fake_slant_bool
+ \fp_gset:Nn \g_@@_slant_factor_fp { \l_keys_value_tl }
+ } ,
+ AutoFakeSlant .default:n = { true } ,
+ EmboldenFactor .fp_gset:N = \g_@@_embolden_factor_fp ,
+ SlantFactor .fp_gset:N = \g_@@_slant_factor_fp ,
+ BoldFont .meta:n = { AutoFakeBold = true } ,
+ boldfont .meta:n = { AutoFakeBold = true } ,
+ SlantFont .meta:n = { AutoFakeSlant = true } ,
+ slantfont .meta:n = { AutoFakeSlant = true }
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\keys_set_known:nxN}
-% \begin{macrocode}
-\cs_generate_variant:Nn \keys_set_known:nnN { nx }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\@@_new_sub_key:n,\g_@@_sub_key_clist}
+% \begin{macro}[internal]{\@@_new_sub_key:n,\g_@@_sub_key_seq}
% 用于定义 CJK 子区字体和备用字体的选项。
% \begin{macrocode}
-\clist_new:N \g_@@_sub_key_clist
+\seq_new:N \g_@@_sub_key_seq
\cs_new_protected_nopar:Npn \@@_new_sub_key:n #1
{
- \clist_gput_right:Nx \g_@@_sub_key_clist {#1}
+ \seq_gput_right:Nn \g_@@_sub_key_seq {#1}
\keys_define:nn { xeCJK / features }
{
#1 .code:n =
{
- \xeCJK_if_blank_x:nTF {##1}
+ \tl_if_blank:nTF {##1}
{
\bool_set_false:c { l_@@_copy_#1_bool }
\bool_set_false:c { l_@@_add_#1_bool }
- \tl_put_right:Nx \l_@@_family_aux_tl { /#1 }
+ \tl_put_right:Nn \l_@@_family_name_tl { /#1 }
}
{
- \clist_put_right:Nx \l_@@_sub_key_clist {#1}
- \str_if_eq_x:nnTF {##1} *
+ \seq_put_right:Nn \l_@@_sub_key_seq {#1}
+ \str_if_eq:nnTF {##1} { * }
{
\bool_set_true:c { l_@@_copy_#1_bool }
\bool_set_false:c { l_@@_add_#1_bool }
@@ -3160,51 +3689,46 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
\@@_get_sub_features:nn {#1} {##1}
}
}
- },
- #1 .default:n = \c_empty_tl,
+ } ,
+ #1 .default:n = { }
}
}
\cs_generate_variant:Nn \@@_new_sub_key:n { x }
-\cs_new_protected_nopar:Npn \@@_get_sub_features:nn #1#2
- {
- \tl_set:Nx \l_@@_tmpa_tl {#2}
- \clist_clear:N \l_@@_sub_fontfeat_clist
- \@@_gobble_brace:N \l_@@_tmpa_tl
- \exp_args:No \tl_if_head_eq_charcode:nNTF \l_@@_tmpa_tl [ % ]
- {
- \exp_after:wN \@@_get_sub_features_aux:n \l_@@_tmpa_tl \c_empty_tl
- \xeCJK_if_blank_x:nT \l_@@_sub_fontname_tl
- {
- \tl_set:Nx \l_@@_sub_fontname_tl \l_@@_tmpa_tl
- \clist_clear:N \l_@@_sub_fontfeat_clist
- }
- }
- { \tl_set:Nx \l_@@_sub_fontname_tl \l_@@_tmpa_tl }
- \xeCJK_if_blank_x:nTF \l_@@_sub_fontname_tl
- { \tl_set:Nx \l_@@_sub_fontname_tl \l_@@_fontname_tl }
- { \tl_replace_all:Nnx \l_@@_sub_fontname_tl * \l_@@_fontname_tl }
- \clist_set:cx { l_@@_#1_fontfeat_clist } \l_@@_sub_fontfeat_clist
- \tl_set:cx { l_@@_#1_fontname_tl } \l_@@_sub_fontname_tl
- }
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[aux]
-% {\@@_gobble_brace:N,\@@_get_sub_features:nn,\@@_get_sub_features_aux:n}
+% \begin{macro}[internal]{\@@_get_sub_features:nn,\@@_get_sub_features:wn}
% \begin{macrocode}
-\cs_new_protected_nopar:Npn \@@_gobble_brace:N #1
+\cs_new_protected_nopar:Npn \@@_get_sub_features:nn #1#2
{
- \exp_args:No \tl_if_head_is_group:nT #1
+ \tl_set:Nx \l_@@_tmpa_tl { \xeCJK_tl_remove_outer_braces:n {#2} }
+ \clist_clear:N \l_@@_sub_font_options_clist
+ \tl_if_head_eq_meaning:VNTF \l_@@_tmpa_tl [ % ]
{
- \exp_last_unbraced:NNo \tl_set:Nn #1 #1
- \@@_gobble_brace:N #1
+ \exp_after:wN \@@_get_sub_features:wn \l_@@_tmpa_tl \c_empty_tl
+ \tl_if_blank:VT \l_@@_sub_font_name_tl
+ {
+ \tl_set_eq:NN \l_@@_sub_font_name_tl \l_@@_tmpa_tl
+ \clist_clear:N \l_@@_sub_font_options_clist
+ }
}
+ { \tl_set_eq:NN \l_@@_sub_font_name_tl \l_@@_tmpa_tl }
+ \tl_if_blank:VTF \l_@@_sub_font_name_tl
+ { \tl_set_eq:NN \l_@@_sub_font_name_tl \l_@@_font_name_tl }
+ { \tl_replace_all:NnV \l_@@_sub_font_name_tl { * } \l_@@_font_name_tl }
+ \clist_set_eq:cN { l_@@_#1_font_options_clist } \l_@@_sub_font_options_clist
+ \tl_set_eq:cN { l_@@_#1_font_name_tl } \l_@@_sub_font_name_tl
}
-\cs_new_protected_nopar:Npn \@@_get_sub_features_aux:n [#1] #2
+\cs_new_protected_nopar:Npn \@@_get_sub_features:wn [#1] #2
{
- \clist_set:Nx \l_@@_sub_fontfeat_clist {#1}
- \tl_set:Nx \l_@@_sub_fontname_tl {#2}
+ \clist_set:Nn \l_@@_sub_font_options_clist {#1}
+ \str_if_eq:nnTF {#2} { \c_empty_tl }
+ { \tl_set_eq:NN \l_@@_sub_font_name_tl \c_empty_tl }
+ { \tl_set:Nn \l_@@_sub_font_name_tl {#2} }
}
+\cs_generate_variant:Nn \@@_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 }
% \end{macrocode}
% \end{macro}
%
@@ -3214,13 +3738,12 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\g_@@_features_id_prop, BoldFont, ItalicFont, BoldItalicFont,
-% SlantedFont, BoldSlantedFont,BoldFeatures, ItalicFeatures, BoldItalicFeatures,
-% SlantedFeatures, BoldSlantedFeatures}
+% \begin{macro}[internal]
+% {\g_@@_features_id_prop, BoldFont, ItalicFont, BoldItalicFont,
+% SlantedFont, BoldSlantedFont,BoldFeatures, ItalicFeatures,
+% BoldItalicFeatures, SlantedFeatures, BoldSlantedFeatures}
% 调用字体的属性声明,同 \pkg{fontspec} 宏包。
% \begin{macrocode}
-\cs_new_nopar:Npn \@@_map_features_id:n #1
- { \prop_get:Nn \g_@@_features_id_prop {#1} }
\prop_new:N \g_@@_features_id_prop
\prop_put:Nnn \g_@@_features_id_prop { bf } { Bold }
\prop_put:Nnn \g_@@_features_id_prop { it } { Italic }
@@ -3231,115 +3754,131 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
{
\keys_define:nn { xeCJK / features }
{
- #2Font .tl_set_x:c = { l_@@_fontname_#1_tl },
- #2Features .tl_set_x:c = { l_@@_fontfeat_#1_clist } ,
+ #2Font .tl_set:c = { l_@@_font_name_#1_tl } ,
+ #2Features .clist_set:c = { l_@@_font_feat_#1_clist }
}
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{AutoFakeBold, AutoFakeSlant, Mono}
+% \begin{macro}[internal]{AutoFakeBold, AutoFakeSlant}
% \begin{macrocode}
\keys_define:nn { xeCJK / features }
{
- AutoFakeBold .choice:,
+ AutoFakeBold .choice: ,
AutoFakeBold / false .code:n =
- { \bool_set_false:N \l_@@_AutoFakeBold_bool },
+ { \bool_set_false:N \l_@@_auto_fake_bold_bool } ,
AutoFakeBold / unknown .code:n =
{
- \bool_set_true:N \l_@@_AutoFakeBold_bool
- \fp_set:Nn \l_@@_EmboldenFactor_fp { \l_keys_value_tl }
- },
- AutoFakeBold .default:n = { \g_@@_EmboldenFactor_fp },
- AutoFakeSlant .choice:,
+ \bool_set_true:N \l_@@_auto_fake_bold_bool
+ \fp_set:Nn \l_@@_embolden_factor_fp { \l_keys_value_tl }
+ } ,
+ AutoFakeBold .default:n = { \g_@@_embolden_factor_fp } ,
+ AutoFakeSlant .choice: ,
AutoFakeSlant / false .code:n =
- { \bool_set_false:N \l_@@_AutoFakeSlant_bool },
+ { \bool_set_false:N \l_@@_auto_fake_slant_bool } ,
AutoFakeSlant / unknown .code:n =
{
- \bool_set_true:N \l_@@_AutoFakeSlant_bool
- \fp_set:Nn \l_@@_SlantFactor_fp { \l_keys_value_tl }
- },
- AutoFakeSlant .default:n = { \g_@@_SlantFactor_fp },
- Mono .choice:,
- Mono / Exspace .code:n =
- {
- \xeCJK_set_monoexspace:
- \tl_clear:N \l_@@_monoscale_tl
- },
- Mono / Scale .code:n =
- {
- \xeCJK_set_monoscale:
- \tl_set:Nx \l_@@_monoscale_tl { Scale = { \fp_use:N \g_@@_monoscale_fp } }
- }
+ \bool_set_true:N \l_@@_auto_fake_slant_bool
+ \fp_set:Nn \l_@@_slant_factor_fp { \l_keys_value_tl }
+ } ,
+ AutoFakeSlant .default:n = { \g_@@_slant_factor_fp }
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\@@_set_init:}
+% \begin{macro}[internal]{\@@_set_family_initial:}
% \begin{macrocode}
-\cs_new_protected_nopar:Npn \@@_set_init:
+\cs_new_protected_nopar:Npn \@@_set_family_initial:
{
- \cs_set_eq:NN \CJKfamily \use_none:n
- \tl_clear:N \l_@@_monoscale_tl
- \int_gincr:N \g_@@_fontspec_int
+ \@@_gobble_CJKfamily:
+ \int_gincr:N \g_@@_family_int
\prop_clear:N \l_@@_add_font_prop
\prop_map_inline:Nn \g_@@_features_id_prop
{
- \tl_clear:c { l_@@_fontname_##1_tl }
- \clist_clear:c { l_@@_fontfeat_##1_clist }
+ \tl_clear:c { l_@@_font_name_##1_tl }
+ \clist_clear:c { l_@@_font_feat_##1_clist }
}
- \clist_clear:N \l_@@_pass_features_clist
- \clist_clear:N \l_@@_sub_key_clist
- \clist_map_inline:Nn \g_@@_sub_key_clist
+ \clist_clear:N \l_@@_fontspec_options_clist
+ \seq_clear:N \l_@@_sub_key_seq
+ \seq_map_inline:Nn \g_@@_sub_key_seq
{
\bool_set_false:c { l_@@_copy_##1_bool }
\bool_set_false:c { l_@@_add_##1_bool }
}
- \bool_set_eq:NN \l_@@_AutoFakeBold_bool \g_@@_AutoFakeBold_bool
- \bool_set_eq:NN \l_@@_AutoFakeSlant_bool \g_@@_AutoFakeSlant_bool
- \fp_set_eq:NN \l_@@_EmboldenFactor_fp \g_@@_EmboldenFactor_fp
- \fp_set_eq:NN \l_@@_SlantFactor_fp \g_@@_SlantFactor_fp
+ \bool_set_eq:NN \l_@@_auto_fake_bold_bool \g_@@_auto_fake_bold_bool
+ \bool_set_eq:NN \l_@@_auto_fake_slant_bool \g_@@_auto_fake_slant_bool
+ \fp_set_eq:NN \l_@@_embolden_factor_fp \g_@@_embolden_factor_fp
+ \fp_set_eq:NN \l_@@_slant_factor_fp \g_@@_slant_factor_fp
}
+\int_new:N \g_@@_family_int
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\xeCJK_set_family:xnn}
+% \begin{macro}[internal]{\xeCJK_set_family:nnn}
% 设置一个 CJK 新字体族,与 \cs{newfontfamily} 类似,增加 |FallBack| 选项。
% \begin{macrocode}
-\cs_new_protected_nopar:Npn \xeCJK_set_family:xnn #1#2#3
+\cs_new_protected_nopar:Npn \xeCJK_set_family:nnn #1#2#3
{
\group_begin:
- \@@_set_init:
- \tl_set:Nx \l_@@_family_aux_tl {#1}
- \clist_set:Nx \l_@@_fontoptions_clist {#2}
- \tl_set:Nx \l_@@_fontname_tl {#3}
- \keys_set_known:nxN { xeCJK / features }
- { \g_@@_default_features_clist, #2 } \l_@@_pass_features_clist
+ \@@_set_family_initial:
+ \tl_set:Nn \l_@@_family_name_tl {#1}
+ \clist_set:Nn \l_@@_font_options_clist {#2}
+ \tl_set:Nn \l_@@_font_name_tl {#3}
+ \clist_concat:NNN \l_@@_font_features_clist
+ \g_@@_default_features_clist \l_@@_font_options_clist
+ \@@_remove_duplicate_keys:N \l_@@_font_features_clist
+ \keys_set_known:nVN { xeCJK / features }
+ \l_@@_font_features_clist \l_@@_fontspec_options_clist
\@@_parse_features:
\@@_pass_features:
- \@@_check_family:V \l_@@_family_aux_tl
- \cs_gset_protected_nopar:cpx { @@/family/\l_@@_family_aux_tl }
+ \@@_check_family:V \l_@@_family_name_tl
+ \@@_gset_family_cs:x { \l_@@_family_name_tl }
+ \@@_save_family_info:
+ \@@_set_sub_block_family:
+ \group_end:
+ }
+\cs_generate_variant:Nn \xeCJK_set_family:nnn { Vnn , xxx , Vvv }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\@@_remove_duplicate_keys:N}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_remove_duplicate_keys:N #1
+ {
+ \prop_clear:N \l_@@_tmp_prop
+ \keyval_parse:NNV \@@_prop_put_aux:n \@@_prop_put_aux:nn #1
+ \clist_clear:N #1
+ \prop_map_inline:Nn \l_@@_tmp_prop
+ {
+ \tl_if_blank:nTF {##2}
+ { \clist_put_right:Nn #1 {##1} }
+ { \clist_put_right:Nn #1 { ##1 = {##2} } }
+ }
+ }
+\cs_generate_variant:Nn \keyval_parse:NNn { NNV }
+\cs_new_protected_nopar:Npn \@@_prop_put_aux:n #1
+ { \prop_put:Nnn \l_@@_tmp_prop {#1} { } }
+\cs_new_protected_nopar:Npn \@@_prop_put_aux:nn #1#2
+ { \prop_put:Nnn \l_@@_tmp_prop {#1} {#2} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\@@_gset_family_cs:x}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_gset_family_cs:x #1
+ {
+ \cs_gset_protected_nopar:cpx { \@@_family_csname:n {#1} }
{
\group_begin:
- \exp_not:n { \cs_set_eq:NN \CJKfamily \use_none:n }
+ \@@_gobble_CJKfamily:
\exp_not:n { \fontspec_set_family:Nnn \l_@@_fontspec_family_tl }
- { \l_@@_pass_features_clist } { \l_@@_fontname_tl }
- \prop_gput:NnV \exp_not:N \g_@@_family_name_prop
- { \l_@@_family_aux_tl } \exp_not:N \l_@@_fontspec_family_tl
- \cs_gset_protected_nopar:cpx { @@/family/\l_@@_family_aux_tl }
- \exp_not:n
- { {
- \exp_not:N \fontencoding { \c_@@_encoding_tl }
- \exp_not:N \fontfamily { \l_@@_fontspec_family_tl }
- \exp_not:N \selectfont
- } }
+ { \exp_not:V \l_@@_fontspec_options_clist }
+ { \exp_not:V \l_@@_font_name_tl }
+ \@@_gset_family_nfss_cs:xx {#1} { \exp_not:N \l_@@_fontspec_family_tl }
\group_end:
}
- \@@_save_family_info:
- \@@_add_sub_block:
- \group_end:
}
-\cs_generate_variant:Nn \xeCJK_set_family:xnn { xcc }
% \end{macrocode}
% \end{macro}
%
@@ -3347,140 +3886,131 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
% \begin{macrocode}
\cs_new_protected_nopar:Npn \@@_check_family:n #1
{
- \prop_get:NnNT \g_@@_family_prop {#1} \l_@@_tmpa_tl
+ \prop_get:NnNT \g_@@_family_font_name_prop {#1} \l_@@_tmpa_tl
{
- \prop_gpop:NnNT \g_@@_family_name_prop {#1} \l_@@_tmpa_tl { }
- \@@_warning:nxx { CJKfamily-redef } {#1} \l_@@_tmpa_tl
+ \prop_gpop:NnNT \g_@@_family_name_prop {#1} \l_@@_tmpa_tl
+ { \cs_undefine:c { \@@_family_nfss_csname:n {#1} } }
+ \@@_warning:nxx { CJKfamily-redef } {#1} { \l_@@_tmpa_tl }
}
}
\cs_generate_variant:Nn \@@_check_family:n { V }
-\@@_msg_new:nn { CJKfamily-redef } { Redefining~CJKfamily~`#1'~(#2). }
+\@@_msg_new:nn { CJKfamily-redef }
+ { Redefining~CJKfamily~`\@@_msg_family_map:n {#1}'~(#2). }
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\@@_add_font:nn,\@@_add_font_if_new:nn}
% \begin{macrocode}
\cs_new_protected_nopar:Npn \@@_add_font:nn #1#2
- {
- \prop_put:Nxx \l_@@_add_font_prop
- { \@@_map_features_id:n {#1} Font } {#2}
- }
+ { \prop_put:Nnn \l_@@_add_font_prop { #1 Font } {#2} }
\cs_new_protected_nopar:Npn \@@_add_font_if_new:nn #1#2
- {
- \prop_put_if_new:Nxx \l_@@_add_font_prop
- { \@@_map_features_id:n {#1} Font } {#2}
- }
-\cs_generate_variant:Nn \@@_add_font:nn { nx, nc, nV, nv }
-\cs_generate_variant:Nn \@@_add_font_if_new:nn { nx, nc, nV, nv }
+ { \prop_put_if_new:Nnn \l_@@_add_font_prop { #1 Font } {#2} }
+\cs_generate_variant:Nn \@@_add_font:nn { nx , nV , nv }
+\cs_generate_variant:Nn \@@_add_font_if_new:nn { nx , nV , nv }
% \end{macrocode}
% \end{macro}
%
-% \begin{macrocode}
-\cs_generate_variant:Nn \prop_put:Nnn { Nxx }
-\cs_generate_variant:Nn \prop_get:Nn { NV }
-\cs_generate_variant:Nn \prop_get:NnNF { Nx }
-\cs_generate_variant:Nn \prop_if_in:NnF { Nx }
-\cs_generate_variant:Nn \prop_put_if_new:Nnn { Nxx }
-% \end{macrocode}
-%
% \begin{macro}[internal]{\@@_add_fake_bold:n,\@@_add_fake_slant:n}
% \begin{macrocode}
\cs_new_protected_nopar:Npn \@@_add_fake_bold:n #1
{
- \clist_put_left:cx { l_@@_fontfeat_#1_clist }
- { FakeBold = { \fp_use:N \l_@@_EmboldenFactor_fp } }
+ \clist_put_left:cx { l_@@_font_feat_#1_clist }
+ { FakeBold = { \fp_use:N \l_@@_embolden_factor_fp } }
}
\cs_new_protected_nopar:Npn \@@_add_fake_slant:n #1
{
- \clist_put_left:cx { l_@@_fontfeat_#1_clist }
- { FakeSlant = { \fp_use:N \l_@@_SlantFactor_fp } }
+ \clist_put_left:cx { l_@@_font_feat_#1_clist }
+ { FakeSlant = { \fp_use:N \l_@@_slant_factor_fp } }
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\@@_parse_features:,\@@_parse_features:n}
+% \begin{macro}[internal]{\@@_parse_features:,\@@_parse_features:nn}
% \begin{macrocode}
\cs_new_protected_nopar:Npn \@@_parse_features:
- { \prop_map_inline:Nn \g_@@_features_id_prop { \@@_parse_features:n {##1} } }
-\cs_new_protected_nopar:Npn \@@_parse_features:n #1
+ { \prop_map_function:NN \g_@@_features_id_prop \@@_parse_features:nn }
+\cs_new_protected_nopar:Npn \@@_parse_features:nn #1#2
{
\@@_if_font_select:nTF {#1}
{
- \@@_add_font:nv {#1} { l_@@_fontname_#1_tl }
+ \@@_add_font:nv {#2} { l_@@_font_name_#1_tl }
\@@_if_it_or_sl:nTF {#1}
{
- \@@_if_font_select:nF {bf#1}
- { \@@_add_font_if_new:nv {bf#1} { l_@@_fontname_#1_tl } }
+ \@@_if_font_select:nF { bf #1 }
+ { \@@_add_font_if_new:nv {#2} { l_@@_font_name_#1_tl } }
}
{
- \str_if_eq_x:nnT {#1} {bf}
+ \str_if_eq:nnT {#1} { bf }
{
- \clist_map_inline:nn { it , sl }
- {
- \@@_if_font_select:nF {bf##1}
- { \@@_add_font:nV {bf##1} \l_@@_fontname_bf_tl }
- }
+ \@@_if_font_select:nF { bfit }
+ { \@@_add_font:nV { BoldItalic } \l_@@_font_name_bf_tl }
+ \@@_if_font_select:nF { bfsl }
+ { \@@_add_font:nV { BoldSlanted } \l_@@_font_name_bf_tl }
}
}
}
- { \@@_set_fake:n {#1} }
+ { \@@_set_fake_font:nn {#1} {#2} }
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[pTF,internal]{\@@_if_font_select:n,\@@_if_it_or_sl:n}
% \begin{macrocode}
-\prg_new_conditional:Npnn \@@_if_font_select:n #1 { p, T, F, TF }
+\prg_new_conditional:Npnn \@@_if_font_select:n #1 { p , T , F , TF }
{
- \exp_args:Nc \xeCJK_if_blank_x:nTF { l_@@_fontname_#1_tl }
- \prg_return_false: \prg_return_true:
+ \tl_if_blank:vTF { l_@@_font_name_#1_tl }
+ { \prg_return_false: } { \prg_return_true: }
}
-\prg_new_conditional:Npnn \@@_if_it_or_sl:n #1 { p, T, F, TF }
+\prg_new_conditional:Npnn \@@_if_it_or_sl:n #1 { p , T , F , TF }
{
- \bool_if:nTF { \str_if_eq_x_p:nn { it } {#1} || \str_if_eq_x_p:nn { sl } {#1} }
- \prg_return_true: \prg_return_false:
+ \if_predicate:w
+ \bool_if_p:n { \str_if_eq_p:nn { it } {#1} || \str_if_eq_p:nn { sl } {#1} }
+ \prg_return_true: \else: \prg_return_false: \fi:
}
+\cs_generate_variant:Nn \tl_if_blank:nTF { v }
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\@@_set_fake:n}
+% \begin{macro}[internal]{\@@_set_fake_font:nn}
% \begin{macrocode}
-\cs_new_protected_nopar:Npn \@@_set_fake:n #1
+\cs_new_protected_nopar:Npn \@@_set_fake_font:nn #1#2
{
- \str_if_eq_x:nnTF {#1} { bf }
- { \bool_if:NT \l_@@_AutoFakeBold_bool { \@@_add_fake_bold:n {#1} } }
+ \str_if_eq:nnTF {#1} { bf }
+ { \bool_if:NT \l_@@_auto_fake_bold_bool { \@@_add_fake_bold:n {#1} } }
{
- \bool_if:NTF \l_@@_AutoFakeSlant_bool
+ \bool_if:NTF \l_@@_auto_fake_slant_bool
{
\bool_if:nT
- { \@@_if_it_or_sl_p:n {#1} ||
- ( \str_if_eq_x_p:nn {#1} {bfit} && ! ( \@@_if_font_select_p:n {it} ) ) ||
- ( \str_if_eq_x_p:nn {#1} {bfsl} && ! ( \@@_if_font_select_p:n {sl} ) )
+ { \@@_if_it_or_sl_p:n {#1}
+ || ( \str_if_eq_p:nn {#1} { bfit }
+ && ! ( \@@_if_font_select_p:n { it } ) )
+ || ( \str_if_eq_p:nn {#1} { bfsl }
+ && ! ( \@@_if_font_select_p:n { sl } ) )
}
{ \@@_add_fake_slant:n {#1} }
}
- { \@@_if_it_or_sl:nT {#1} { \@@_map_it_sl:n {#1} } }
+ { \@@_if_it_or_sl:nT {#1} { \@@_map_it_sl:nn {#1} {#2} } }
\bool_if:nT
- { \l_@@_AutoFakeBold_bool
+ { \l_@@_auto_fake_bold_bool
&& ! ( \@@_if_it_or_sl_p:n {#1} )
- && ! ( \@@_if_font_select_p:n {bf} )
+ && ! ( \@@_if_font_select_p:n { bf } )
}
{ \@@_add_fake_bold:n {#1} }
}
- \@@_add_font_if_new:nn {#1} *
+ \@@_add_font_if_new:nn {#2} { * }
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\@@_map_it_sl:n}
% \begin{macrocode}
-\cs_new_protected_nopar:Npn \@@_map_it_sl:n #1
+\cs_new_protected_nopar:Npn \@@_map_it_sl:nn #1#2
{
\@@_if_map_font_select:nT {#1}
{
- \@@_add_font:nx {#1} { \@@_get_map_font:n {#1} }
- \@@_if_font_select:nF {bf#1}
- { \@@_add_font_if_new:nx {bf#1} { \@@_get_map_font:n {#1} } }
+ \@@_add_font:nx {#2} { \@@_get_map_font:n {#1} }
+ \@@_if_font_select:nF { bf #1 }
+ { \@@_add_font_if_new:nx { Bold #2 } { \@@_get_map_font:n {#1} } }
}
}
% \end{macrocode}
@@ -3489,16 +4019,16 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
% \begin{macro}[internal]{\@@_get_map_font:n}
% \begin{macrocode}
\cs_new_nopar:Npn \@@_get_map_font:n #1
- { \tl_use:c { l_@@_fontname_\str_if_eq_x:nnTF {#1} {it} {sl} {it} _tl } }
+ { \exp_not:v { l_@@_font_name_ \xeCJK_reverse:nnn {#1} { it } { sl } _tl } }
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[pTF,internal]{\@@_if_map_font_select:n}
% \begin{macrocode}
-\prg_new_conditional:Npnn \@@_if_map_font_select:n #1 { p, T, F, TF }
+\prg_new_conditional:Npnn \@@_if_map_font_select:n #1 { p , T , F , TF }
{
\xeCJK_if_blank_x:nTF { \@@_get_map_font:n {#1} }
- \prg_return_false: \prg_return_true:
+ { \prg_return_false: } { \prg_return_true: }
}
% \end{macrocode}
% \end{macro}
@@ -3509,26 +4039,24 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
{
\prop_map_inline:Nn \g_@@_features_id_prop
{
- \clist_if_empty:cF { l_@@_fontfeat_##1_clist }
+ \clist_if_empty:cF { l_@@_font_feat_##1_clist }
{
- \clist_put_right:Nx \l_@@_pass_features_clist
- { ##2Features = { \tl_use:c { l_@@_fontfeat_##1_clist } } }
+ \clist_put_right:Nx \l_@@_fontspec_options_clist
+ { ##2Features = { \exp_not:v { l_@@_font_feat_##1_clist } } }
}
}
\prop_map_inline:Nn \l_@@_add_font_prop
- { \clist_put_right:Nx \l_@@_pass_features_clist { ##1 = { ##2 } } }
- \xeCJK_if_blank_x:nF \l_@@_monoscale_tl
- { \clist_put_left:Nx \l_@@_pass_features_clist \l_@@_monoscale_tl }
+ { \clist_put_right:Nn \l_@@_fontspec_options_clist { ##1 = { ##2 } } }
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal,var]
-% {\g_@@_family_prop,\g_@@_family_name_prop,\g_@@_family_options_prop}
+% {\g_@@_family_name_prop,\g_@@_family_font_name_prop,\g_@@_family_font_options_prop}
% \begin{macrocode}
-\prop_new:N \g_@@_family_prop
\prop_new:N \g_@@_family_name_prop
-\prop_new:N \g_@@_family_options_prop
+\prop_new:N \g_@@_family_font_name_prop
+\prop_new:N \g_@@_family_font_options_prop
% \end{macrocode}
% \end{macro}
%
@@ -3537,60 +4065,58 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
\cs_new_protected_nopar:Npn \@@_save_family_info:
{
\group_begin:
- \clist_map_inline:Nn \g_@@_CJK_subclass_clist
- {
- \clist_remove_all:Nn \l_@@_fontoptions_clist {##1}
- \clist_remove_all:Nn \l_@@_fontoptions_clist { ##1 = }
- }
- \prop_gput:NVV \g_@@_family_prop \l_@@_family_aux_tl \l_@@_fontname_tl
- \prop_gput:NVV \g_@@_family_options_prop \l_@@_family_aux_tl \l_@@_fontoptions_clist
+ \seq_map_inline:Nn \g_@@_CJK_sub_class_seq
+ { \clist_remove_all:Nn \l_@@_font_options_clist {##1} }
+ \prop_gput:NVV \g_@@_family_font_name_prop
+ \l_@@_family_name_tl \l_@@_font_name_tl
+ \prop_gput:NVV \g_@@_family_font_options_prop
+ \l_@@_family_name_tl \l_@@_font_options_clist
\group_end:
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\@@_add_sub_block:}
+% \begin{macro}[internal]{\@@_set_sub_block_family:}
% \begin{macrocode}
-\cs_new_protected_nopar:Npn \@@_add_sub_block:
+\cs_new_protected_nopar:Npn \@@_set_sub_block_family:
{
- \clist_remove_duplicates:N \l_@@_sub_key_clist
- \clist_map_inline:Nn \l_@@_sub_key_clist
+ \seq_map_inline:Nn \l_@@_sub_key_seq
{
- \tl_set:Nx \l_@@_sub_family_tl { \l_@@_family_aux_tl/##1 }
- \bool_if:cT { l_@@_copy_##1_bool }
+ \tl_set:Nx \l_@@_sub_family_tl { \l_@@_family_name_tl/##1 }
+ \bool_if:cT { l_@@_copy_##1_bool } { \@@_copy_sub_family:n {##1} }
+ \bool_if:cT { l_@@_add_##1_bool }
{
- \@@_check_family:V \l_@@_sub_family_tl
- \prop_get:NVNT \g_@@_family_prop \l_@@_family_aux_tl \l_@@_tmpa_tl
- { \prop_gput:NVV \g_@@_family_prop \l_@@_sub_family_tl \l_@@_tmpa_tl }
- \prop_get:NVNT \g_@@_family_options_prop \l_@@_family_aux_tl \l_@@_tmpa_clist
- {
- \clist_remove_all:Nn \l_@@_tmpa_clist { ##1 = * }
- \prop_gput:NVV \g_@@_family_options_prop \l_@@_sub_family_tl \l_@@_tmpa_clist
- }
- \cs_gset_protected_nopar:cpx { @@/family/\l_@@_sub_family_tl }
- {
- \xeCJK_family_if_exist:xT { \l_@@_family_aux_tl }
- {
- \prop_get:NnNT \exp_not:N \g_@@_family_name_prop
- { \l_@@_family_aux_tl } \exp_not:N \l_@@_tmpa_tl
- {
- \prop_gput:NnV \exp_not:N \g_@@_family_name_prop
- { \l_@@_sub_family_tl } \exp_not:N \l_@@_tmpa_tl
- \cs_gset_protected_nopar:cpx { @@/family/\l_@@_sub_family_tl }
- \exp_not:n
- { {
- \exp_not:N \fontencoding { \c_@@_encoding_tl }
- \exp_not:N \fontfamily { \l_@@_tmpa_tl }
- \exp_not:N \selectfont
- } }
- }
- }
- }
+ \xeCJK_set_family:Vvv \l_@@_sub_family_tl
+ { l_@@_##1_font_options_clist } { l_@@_##1_font_name_tl }
}
- \bool_if:cT { l_@@_add_##1_bool }
+ }
+ }
+\cs_new_protected_nopar:Npn \@@_copy_sub_family:n #1
+ {
+ \@@_check_family:V \l_@@_sub_family_tl
+ \prop_get:NVNT \g_@@_family_font_name_prop
+ \l_@@_family_name_tl \l_@@_tmpa_tl
+ {
+ \prop_gput:NVV \g_@@_family_font_name_prop
+ \l_@@_sub_family_tl \l_@@_tmpa_tl
+ }
+ \prop_get:NVNT \g_@@_family_font_options_prop
+ \l_@@_family_name_tl \l_@@_tmpa_clist
+ {
+ \clist_remove_all:Nn \l_@@_tmpa_clist { #1 = * }
+ \prop_gput:NVV \g_@@_family_font_options_prop
+ \l_@@_sub_family_tl \l_@@_tmpa_clist
+ }
+ \cs_gset_protected_nopar:cpx { \@@_family_csname:n { \l_@@_sub_family_tl } }
+ {
+ \xeCJK_family_if_exist:xT { \l_@@_family_name_tl }
{
- \xeCJK_set_family:xcc \l_@@_sub_family_tl
- { l_@@_##1_fontfeat_clist } { l_@@_##1_fontname_tl }
+ \prop_get:NnNT \exp_not:N \g_@@_family_name_prop
+ { \l_@@_family_name_tl } \exp_not:N \l_@@_tmpa_tl
+ {
+ \@@_gset_family_nfss_cs:xx
+ { \l_@@_sub_family_tl } { \exp_not:N \l_@@_tmpa_tl }
+ }
}
}
}
@@ -3604,9 +4130,18 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
\xeCJK_family_if_exist:xT {#2}
{
\tl_map_inline:nn
- { \g_@@_family_prop \g_@@_family_options_prop \g_@@_family_name_prop }
- { \prop_get:NnNT ##1 {#2} \l_@@_tmpa_tl { \prop_gput:NnV ##1 {#1} \l_@@_tmpa_tl } }
- \cs_gset_eq:cc { @@/family/#1 } { @@/family/#2 }
+ {
+ \g_@@_family_name_prop
+ \g_@@_family_font_name_prop
+ \g_@@_family_font_options_prop
+ }
+ {
+ \prop_get:NnNT ##1 {#2} \l_@@_tmpa_tl
+ { \prop_gput:NnV ##1 {#1} \l_@@_tmpa_tl }
+ }
+ \cs_gset_eq:cc
+ { \@@_family_nfss_csname:n {#1} }
+ { \@@_family_nfss_csname:n {#2} }
}
}
\cs_generate_variant:Nn \@@_copy_family:nn { xx }
@@ -3615,57 +4150,108 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
%
% \subsection{字体切换}
%
-% \begin{macro}[internal]{\l_xeCJK_font_coor_tl,\xeCJK_select_font:,\@@_switch_font:nn}
+% \begin{macro}[internal]{\l_xeCJK_current_font_tl,\xeCJK_select_font:,\xeCJK_select_font:x}
% 缓存当前字体的原始格式,以加速编译。
% \begin{macrocode}
-\tl_set:Nn \l_xeCJK_font_coor_tl { @@/\l_xeCJK_family_tl/\f@series/\f@shape/\f@size }
+\tl_new:N \l_xeCJK_current_font_tl
+\tl_set:Nn \l_xeCJK_current_font_tl { \@@_font_csname:n { \l_xeCJK_family_tl } }
+\cs_new_nopar:Npn \@@_font_csname:n #1 { xeCJK/#1/\f@series/\f@shape/\f@size }
\cs_new_protected_nopar:Npn \xeCJK_select_font:
{
- \cs_if_exist_use:cF { \l_xeCJK_font_coor_tl }
+ \cs_if_exist_use:cF { \l_xeCJK_current_font_tl }
{
- \tl_set:Nx \l_@@_current_coor_tl \l_xeCJK_font_coor_tl
- \cs_if_exist_use:cT { @@/family/\l_xeCJK_family_tl }
- { \exp_last_unbraced:NNV \cs_gset_eq:cN \l_@@_current_coor_tl \tex_font:D }
+ \tl_set:Nx \l_@@_current_coor_tl { \l_xeCJK_current_font_tl }
+ \@@_family_use:x { \l_xeCJK_family_tl }
+ \xeCJK_font_gset_to_current:c { \l_@@_current_coor_tl }
+ }
+ }
+\cs_new_protected_nopar:Npn \xeCJK_select_font:x #1
+ {
+ \cs_if_exist_use:cF { \@@_font_csname:n {#1} }
+ {
+ \tl_set:Nx \l_@@_current_coor_tl { \@@_font_csname:n {#1} }
+ \@@_family_use:x {#1}
+ \xeCJK_font_gset_to_current:c { \l_@@_current_coor_tl }
}
}
\cs_new_eq:NN \xeCJK@setfont \xeCJK_select_font:
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\@@_switch_font:nn}
+% \changes{v3.1.0}{2012/11/18}{改进 \cs{@@_switch_font:nn} 的定义。}
+% 两个 CJK 分区之间的字体切换。
+% \begin{macrocode}
\cs_new_protected_nopar:Npn \@@_switch_font:nn #1#2
{
- \str_if_eq_x:nnF {#1} {#2}
+ \str_if_eq:nnF {#1} {#2}
{
\@@_info:nxx { CJK-block } {#1} {#2}
- \tl_remove_all:Nn \l_xeCJK_family_tl { /#1 }
- \str_if_eq_x:nnF {#2} { CJK }
+ \str_if_eq:nnTF {#2} { CJK }
+ { \xeCJK_select_font: }
+ { \@@_block_select_font:n {#2} }
+ }
+ }
+\@@_msg_new:nn { CJK-block } { Switch~from~block~'#1'~to~'#2'. }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\@@_block_select_font:n}
+% 若当前 CJK 字体族没有定义子分区 |#1| 的字体,则使用 \cs{CJKfamilydefault} 的对应
+% 分区字体;若 \cs{CJKfamilydefault} 也没有定义该分区字体,则使用当前 CJK 字体族的
+% 主分区字体。
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_block_select_font:n #1
+ {
+ \cs_if_exist_use:cF { \@@_font_csname:n { \l_xeCJK_family_tl/#1 } }
+ {
+ \tl_set:Nx \l_@@_current_coor_tl
+ { \@@_font_csname:n { \l_xeCJK_family_tl/#1 } }
+ \xeCJK_family_if_exist:xF { \l_xeCJK_family_tl/#1 }
{
- \tl_set:Nx \l_@@_tmpa_tl \l_xeCJK_family_tl
- \tl_put_right:Nx \l_xeCJK_family_tl { /#2 }
- \xeCJK_family_if_exist:xF \l_xeCJK_family_tl
+ \@@_copy_family:xx { \l_xeCJK_family_tl/#1 }
{
- \xeCJK_family_if_exist:xTF { \CJKfamilydefault/#2 }
- { \@@_copy_family:xx \l_xeCJK_family_tl { \CJKfamilydefault/#2 } }
- { \@@_copy_family:xx \l_xeCJK_family_tl \l_@@_tmpa_tl }
+ \cs_if_exist:cTF { \@@_family_csname:n { \CJKfamilydefault/#1 } }
+ { \CJKfamilydefault/#1 } { \l_xeCJK_family_tl }
}
}
+ \@@_family_use:x { \l_xeCJK_family_tl/#1 }
+ \xeCJK_font_gset_to_current:c { \l_@@_current_coor_tl }
}
- \xeCJK_select_font:
}
-\@@_msg_new:nn { CJK-block } { Switch~from~block~'#1'~to~'#2'. }
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[TF,internal]{\xeCJK_family_if_exist:x}
+% \begin{macro}[internal]
+% {\@@_family_csname:n,\@@_family_nfss_csname:n,
+% \@@_family_use:x,\@@_gset_family_nfss_cs:xx}
% \begin{macrocode}
-\prg_new_protected_conditional:Npnn \xeCJK_family_if_exist:x #1 { T, F, TF }
+\cs_new_nopar:Npn \@@_family_csname:n #1 { xeCJK/family/#1 }
+\cs_new_nopar:Npn \@@_family_nfss_csname:n #1 { xeCJK/family/nfss/#1 }
+\cs_new_nopar:Npn \@@_family_use:x #1 { \use:c { \@@_family_nfss_csname:n {#1} } }
+\cs_new_protected_nopar:Npn \@@_gset_family_nfss_cs:xx #1#2
{
- \cs_if_free:cTF { @@/family/#1 }
- { \prg_return_false: }
+ \prop_gput:Nxx \g_@@_family_name_prop {#1} {#2}
+ \cs_gset_protected_nopar:cpx { \@@_family_nfss_csname:n {#1} }
{
- \prop_get:NxNF \g_@@_family_name_prop {#1} \l_@@_family_name_tl
- { \use:c { @@/family/#1 } }
- \prg_return_true:
+ \exp_not:N \fontencoding { \c_@@_encoding_tl }
+ \exp_not:N \fontfamily {#2}
+ \exp_not:N \selectfont
}
}
-\cs_generate_variant:Nn \prop_get:NnNTF { Nx }
+\cs_generate_variant:Nn \prop_gput:Nnn { Nxx }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[TF,internal]{\xeCJK_family_if_exist:x}
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn \xeCJK_family_if_exist:x #1 { T , F , TF }
+ {
+ \cs_if_exist:cTF { \@@_family_nfss_csname:n {#1} }
+ { \use_i:nn }
+ { \cs_if_exist_use:cTF { \@@_family_csname:n {#1} } }
+ { \prg_return_true: } { \prg_return_false: }
+ }
% \end{macrocode}
% \end{macro}
%
@@ -3686,7 +4272,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
{
\tl_set:Nx \l_xeCJK_family_tl {#3}
\tl_set_eq:NN \xeCJK@family \l_xeCJK_family_tl
- \IfBooleanT {#1} { \use:c { @@/family/#3 } }
+ \IfBooleanT {#1} { \@@_family_use:x {#3} }
}
{ \@@_family_unknown_warning:x {#3} }
}
@@ -3696,35 +4282,44 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}
-% {\xeCJK_family_if_exist_use:x,\@@_family_unknown_warning:x,\g_@@_unknown_family_seq}
+% \begin{macro}[var,internal]{\l_xeCJK_family_tl}
+% 用于保存文档当前正在使用的 CJK 字体族。
+% \begin{macrocode}
+\tl_new:N \l_xeCJK_family_tl
+\tl_set:Nn \l_xeCJK_family_tl { \CJKfamilydefault }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\@@_gobble_CJKfamily:}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_gobble_CJKfamily:
+ { \cs_set_eq:NN \CJKfamily \@@_gobble_CJKfamily:wn }
+\DeclareExpandableDocumentCommand \@@_gobble_CJKfamily:wn { t+ t- m } { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]
+% {\xeCJK_family_if_exist_use:x,\@@_family_unknown_warning:n}
% \begin{macrocode}
\cs_new_protected_nopar:Npn \xeCJK_family_if_exist_use:x #1
{
\xeCJK_family_if_exist:xTF {#1}
- { \use:c { @@/family/#1 } }
+ { \@@_family_use:x {#1} }
{ \@@_family_unknown_warning:x {#1} }
}
-\cs_new_protected_nopar:Npn \@@_family_unknown_warning:x #1
+\cs_new_protected_nopar:Npn \@@_family_unknown_warning:n #1
{
- \seq_if_in:NxF \g_@@_unknown_family_seq {#1}
+ \seq_if_in:NnF \g_@@_unknown_family_seq {#1}
{
- \seq_gput_right:Nx \g_@@_unknown_family_seq {#1}
+ \seq_gput_right:Nn \g_@@_unknown_family_seq {#1}
\@@_warning:nx { CJKfamily-Unknown } {#1}
}
}
+\cs_generate_variant:Nn \@@_family_unknown_warning:n { x }
\seq_new:N \g_@@_unknown_family_seq
\@@_msg_new:nn { CJKfamily-Unknown }
{
- Unknown~CJK~family~'
- \str_case_x:nnn {#1}
- {
- \CJKrmdefault { \token_to_str:N \CJKrmdefault }
- \CJKsfdefault { \token_to_str:N \CJKsfdefault }
- \CJKttdefault { \token_to_str:N \CJKttdefault }
- }
- {#1}
- '~is~ignored.\\\\
+ Unknown~CJK~family~`\@@_msg_family_map:n {#1}'~is~being~ignored.\\\\
Try~to~use~
\str_case_x:nnn {#1}
{
@@ -3735,36 +4330,74 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
{ \token_to_str:N \setCJKfamilyfont {#1} }
[...]{...}~to~define~it.
}
+\cs_new_nopar:Npn \@@_msg_family_map:n #1
+ {
+ \str_case_x:nnn {#1}
+ {
+ \CJKrmdefault { \token_to_str:N \CJKrmdefault }
+ \CJKsfdefault { \token_to_str:N \CJKsfdefault }
+ \CJKttdefault { \token_to_str:N \CJKttdefault }
+ }
+ {#1}
+ }
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}{\setCJKmainfont,\setCJKsansfont,\setCJKmonofont}
+% 设置文档的 CJK 普通字体、无衬线和等宽字体。
+% \begin{macrocode}
+\NewDocumentCommand \setCJKmainfont { O{} m }
+ { \xeCJK_set_family:xxx { \CJKrmdefault } {#1} {#2} }
+\cs_new_eq:NN \setCJKromanfont \setCJKmainfont
+\NewDocumentCommand \setCJKsansfont { O{} m }
+ { \xeCJK_set_family:xxx { \CJKsfdefault } {#1} {#2} }
+\NewDocumentCommand \setCJKmonofont { O{} m }
+ { \xeCJK_set_family:xxx { \CJKttdefault } {#1} {#2} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\@onlypreamble \setCJKmainfont
+\@onlypreamble \setCJKmathfont
+\@onlypreamble \setCJKsansfont
+\@onlypreamble \setCJKmonofont
+\@onlypreamble \setCJKromanfont
+% \end{macrocode}
+%
% \begin{macro}{\setCJKfamilyfont, \newCJKfontfamily, \CJKfontspec}
% 分别用于预声明 CJK 字体和随机调用 CJK 字体。
% \begin{macrocode}
\NewDocumentCommand \setCJKfamilyfont { m O{} m }
- { \xeCJK_set_family:xnn {#1} {#2} {#3} }
+ { \xeCJK_set_family:xxx {#1} {#2} {#3} }
\NewDocumentCommand \newCJKfontfamily { o m O{} m }
{
- \tl_set:Nx \l_@@_family_aux_tl { \IfNoValueTF {#1} { \cs_to_str:N #2 } {#1} }
- \xeCJK_set_family:xnn \l_@@_family_aux_tl {#3} {#4}
- \cs_new_protected_nopar:Npx #2 { \exp_not:N \CJKfamily { \l_@@_family_aux_tl } }
+ \tl_set:Nx \l_@@_tmpa_tl { \IfNoValueTF {#1} { \cs_to_str:N #2 } {#1} }
+ \cs_new_protected_nopar:Npx #2 { \CJKfamily { \l_@@_tmpa_tl } }
+ \xeCJK_set_family:xxx { \l_@@_tmpa_tl } {#3} {#4}
}
-\int_new:N \g_@@_fontspec_int
-\int_gdecr:N \g_@@_fontspec_int
\NewDocumentCommand \CJKfontspec { O{} m }
{
- \tl_set:Nx \l_@@_CJKfontspec_id_tl { CJKfontspec/#1/#2/id }
- \cs_if_free:cT \l_@@_CJKfontspec_id_tl
+ \xeCJK_fontspec:xx {#1} {#2}
+ \tex_ignorespaces:D
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\xeCJK_fontspec:nn}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \xeCJK_fontspec:nn #1#2
+ {
+ \tl_set:Nx \l_@@_tmpa_tl { \tl_to_str:n { CJKfontspec/#1/#2/id } }
+ \tl_if_exist:cF { \l_@@_tmpa_tl }
{
- \int_gincr:N \g_@@_fontspec_int
- \tl_gset:Nx \g_@@_family_spec_tl
- { CJKfontspec ( \int_use:N \g_@@_fontspec_int ) }
- \xeCJK_set_family:xnn \g_@@_family_spec_tl {#1} {#2}
- \tl_gset:cx \l_@@_CJKfontspec_id_tl \g_@@_family_spec_tl
+ \tl_set:Nx \l_@@_tmpb_tl
+ { CJKfontspec ( \int_eval:n { \g_@@_family_int + \c_one } ) }
+ \tl_gset_eq:cN { \l_@@_tmpa_tl } \l_@@_tmpb_tl
+ \xeCJK_set_family:Vnn \l_@@_tmpb_tl {#1} {#2}
}
- \exp_args:Nv \CJKfamily \l_@@_CJKfontspec_id_tl
- \tex_ignorespaces:D
+ \exp_args:Nc \CJKfamily { \l_@@_tmpa_tl }
}
+\cs_generate_variant:Nn \xeCJK_fontspec:nn { VV , xx }
% \end{macrocode}
% \end{macro}
%
@@ -3774,47 +4407,36 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
\clist_new:N \g_@@_default_features_clist
\NewDocumentCommand \defaultCJKfontfeatures { m }
{ \clist_gset:Nn \g_@@_default_features_clist {#1} }
-\defaultCJKfontfeatures { Script = CJK }
\@onlypreamble \defaultCJKfontfeatures
\NewDocumentCommand \addCJKfontfeatures { m }
{
- \prop_if_in:NVTF \g_@@_family_prop \l_xeCJK_family_tl
+ \xeCJK_add_font_features:x {#1}
+ \tex_ignorespaces:D
+ }
+\cs_new_eq:NN \addCJKfontfeature \addCJKfontfeatures
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\xeCJK_add_font_features:n}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \xeCJK_add_font_features:n #1
+ {
+ \prop_get:NVNTF \g_@@_family_font_name_prop \l_xeCJK_family_tl \l_@@_tmpa_tl
{
- \group_begin:
- \clist_set:Nx \l_@@_tmpa_clist {#1}
- \prop_get:NVN \g_@@_family_prop \l_xeCJK_family_tl \l_@@_tmpa_tl
- \clist_map_inline:Nn \g_@@_CJK_subclass_clist
+ \clist_set:Nn \l_@@_tmpa_clist {#1}
+ \seq_map_function:NN
+ \g_@@_CJK_sub_class_seq \@@_parse_sub_class_features:n
+ \prop_get:NVNT \g_@@_family_font_options_prop
+ \l_xeCJK_family_tl \l_@@_tmpb_clist
{
- \clist_if_in:NnT \l_@@_tmpa_clist {##1}
- {
- \clist_remove_all:Nn \l_@@_tmpa_clist {##1}
- \prop_get:NxNF \g_@@_family_prop { \l_xeCJK_family_tl/##1 } \l_@@_tmpb_tl
- {
- \prop_get:NxNF \g_@@_family_prop
- { \CJKfamilydefault/##1 } \l_@@_tmpb_tl
- { \tl_set:Nx \l_@@_tmpb_tl \l_@@_tmpa_tl }
- }
- \clist_set:Nx \l_@@_tmpa_clist
- { ##1 = { [ \l_@@_tmpa_clist ] { \l_@@_tmpb_tl } } }
- \clist_map_break:
- }
- }
- \prop_get:NVNF \g_@@_family_options_prop \l_xeCJK_family_tl \l_@@_tmpb_clist
- { \clist_clear:N \l_@@_tmpb_clist }
- \clist_clear:N \l_@@_tmpc_clist
- \clist_map_inline:Nn \l_@@_tmpb_clist
- {
- \clist_if_in:NnF \l_@@_tmpa_clist {##1}
- { \clist_put_right:Nn \l_@@_tmpc_clist {##1} }
+ \clist_concat:NNN
+ \l_@@_tmpa_clist \l_@@_tmpb_clist \l_@@_tmpa_clist
}
- \clist_put_left:NV \l_@@_tmpa_clist \l_@@_tmpc_clist
- \use:x
- { \group_end: \CJKfontspec [ \l_@@_tmpa_clist ] { \l_@@_tmpa_tl } }
+ \xeCJK_fontspec:VV \l_@@_tmpa_clist \l_@@_tmpa_tl
}
{ \@@_warning:n { addCJKfontfeature-ignored } }
- \tex_ignorespaces:D
}
-\cs_new_eq:NN \addCJKfontfeature \addCJKfontfeatures
+\cs_generate_variant:Nn \xeCJK_add_font_features:n { x }
\@@_msg_new:nn { addCJKfontfeature-ignored }
{
\token_to_str:N \addCJKfontfeature (s)~ignored.\\\\
@@ -3823,267 +4445,310 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\setCJKmainfont,\setCJKsansfont}
-% 设置文档的 CJK 普通字体、无衬线字体。
+% \begin{macro}[internal]{\@@_parse_sub_class_features:n}
% \begin{macrocode}
-\NewDocumentCommand \setCJKmainfont { O{} m }
- { \xeCJK_set_family:xnn \CJKrmdefault {#1} {#2} }
-\cs_new_eq:NN \setCJKromanfont \setCJKmainfont
-\NewDocumentCommand \setCJKsansfont { O{} m }
- { \xeCJK_set_family:xnn \CJKsfdefault {#1} {#2} }
+\cs_new_protected_nopar:Npn \@@_parse_sub_class_features:n #1
+ {
+ \clist_if_in:NnT \l_@@_tmpa_clist {#1}
+ {
+ \clist_remove_all:Nn \l_@@_tmpa_clist {#1}
+ \prop_get:NoNF \g_@@_family_font_name_prop
+ { \l_xeCJK_family_tl/#1 } \l_@@_tmpb_tl
+ {
+ \prop_get:NxNF \g_@@_family_font_name_prop
+ { \CJKfamilydefault/#1 } \l_@@_tmpb_tl
+ { \tl_set_eq:NN \l_@@_tmpb_tl \l_@@_tmpa_tl }
+ }
+ \clist_set:Nx \l_@@_tmpa_clist
+ { #1 = { [ \exp_not:V \l_@@_tmpa_clist ] { \exp_not:V \l_@@_tmpb_tl } } }
+ \clist_map_break:
+ }
+ }
+\cs_generate_variant:Nn \prop_get:NnNF { Nx }
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\CJKrmdefault,\CJKsfdefault,\CJKttdefault,\CJKfamilydefault}
+% 在导言区结束的时候,若没有声明 CJK 字体,则给出一个警告。并在此时设置数学字体。
% \begin{macrocode}
-\tl_if_exist:NF \CJKrmdefault { \tl_set:Nn \CJKrmdefault { rm } }
-\tl_if_exist:NF \CJKsfdefault { \tl_set:Nn \CJKsfdefault { sf } }
-\tl_if_exist:NF \CJKttdefault { \tl_set:Nn \CJKttdefault { tt } }
-\tl_if_exist:NF \CJKfamilydefault { \tl_set:Nn \CJKfamilydefault { \CJKrmdefault } }
-\tl_new:c { @@/family/\CJKfamilydefault }
-% \end{macrocode}
-% \end{macro}
-%
-% 补丁 \cs{normalfont},\cs{rmfamily},\cs{n\sffamily} 和 \cs{ttfamily},使其同时对
-% CJK 字体族有效。
-% \begin{macrocode}
-\AtEndOfPackage
+\@@_at_end_preamble:n
{
- \etex_protected:D \tl_put_right:Nn \normalfont { \CJKfamily \CJKfamilydefault }
- \etex_protected:D \tl_put_right:Nn \rmfamily { \CJKfamily \CJKrmdefault }
- \etex_protected:D \tl_put_right:Nn \sffamily { \CJKfamily \CJKsfdefault }
- \etex_protected:D \tl_put_right:Nn \ttfamily { \CJKfamily \CJKttdefault }
- \cs_set_eq:NN \reset@font \normalfont
+ \prop_if_empty:NTF \g_@@_family_font_name_prop
+ { \@@_warning:n { no-CJKfamily } }
+ {
+ \CJKfamily { \CJKfamilydefault }
+ \bool_if:NT \g_@@_math_bool { \xeCJK_set_mathfont: }
+ }
+ }
+\@@_msg_new:nn { no-CJKfamily }
+ {
+ It~seems~that~you~have~not~declare~a~CJKfamily.\\
+ If~you~want~to~use~xeCJK~in~the~right~way,~you~should~use\\\\
+ \token_to_str:N \xeCJKmainfont[...]{...}\\\\
+ in~the~preamble~to~declare~the~main~CJKfamily.\\
}
% \end{macrocode}
%
-% 为了保证 CJK 数学字体的正确设置,应在导言区内设置 CJK 字体。
-% \begin{macrocode}
-\@onlypreamble \setCJKmainfont
-\@onlypreamble \setCJKmathfont
-\@onlypreamble \setCJKsansfont
-\@onlypreamble \setCJKmonofont
-\@onlypreamble \setCJKromanfont
-% \end{macrocode}
%
% \subsection{数学字体设置}
%
+% \begin{macro}{CJKmath}
+% 是否启用 CJK 数学字体的宏包选项。
+% \begin{macrocode}
+\keys_define:nn { xeCJK / options } { CJKmath .bool_gset:N = \g_@@_math_bool }
+% \end{macrocode}
+% \end{macro}
+%
% \begin{macro}{\setCJKmathfont}
% 设置 CJK 数学字体。
% \begin{macrocode}
\NewDocumentCommand \setCJKmathfont { O{} m }
- { \xeCJK_set_family:xnn \c_@@_math_tl {#1} {#2} }
+ { \xeCJK_set_family:xxx { \c_@@_math_tl } {#1} {#2} }
+\tl_const:Nn \c_@@_math_tl { CJKmath }
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{CJKmath}
-% 数学公式内的 CJK 字体。
+% \begin{macro}[internal]{\xeCJK_set_mathfont:}
+% 当没有设置 CJK 数学字体时,使用 \cs{CJKfamilydefault} 作为数学字体。
% \begin{macrocode}
-\tl_const:Nn \c_@@_math_tl { CJKmath }
-\keys_define:nn { xeCJK / options } { CJKmath .bool_gset:N = \g_@@_math_bool }
+\cs_new_protected_nopar:Npn \xeCJK_set_mathfont:
+ {
+ \xeCJK_family_if_exist:xTF { \c_@@_math_tl }
+ { \tl_set:Nx \l_@@_tmpa_tl { \c_@@_math_tl } }
+ {
+ \xeCJK_family_if_exist:xTF { \CJKfamilydefault }
+ { \tl_set:Nx \l_@@_tmpa_tl { \CJKfamilydefault } }
+ { \use_none:nnnnn }
+ }
+ \prop_get:NVNT \g_@@_family_name_prop \l_@@_tmpa_tl \l_@@_tmpb_tl
+ {
+ \tl_const:Nx \c_@@_math_family_tl { \l_@@_tmpb_tl }
+ \DeclareSymbolFont \c_@@_math_tl
+ \c_@@_encoding_tl \c_@@_math_family_tl \mddefault \shapedefault
+ \SetSymbolFont \c_@@_math_tl { bold }
+ \c_@@_encoding_tl \c_@@_math_family_tl \bfdefault \shapedefault
+ \int_const:Nn \c_xeCJK_math_fam_int { \use:c { sym \c_@@_math_tl } }
+ \clist_concat:NNN
+ \l_@@_tmpa_clist \c_@@_CJK_chars_clist \c_@@_FullLeft_chars_clist
+ \clist_concat:NNN
+ \l_@@_tmpa_clist \l_@@_tmpa_clist \c_@@_FullRight_chars_clist
+ \clist_map_inline:Nn \l_@@_tmpa_clist
+ {
+ \@@_set_char_class_aux:Nnw \xeCJK_gset_mathcode:nnnn {##1}
+ { \c_seven } { \c_xeCJK_math_fam_int }
+ }
+ }
+ }
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\xeCJKsetmathcode}
+% \begin{macro}[internal]{\xeCJK_gset_mathcode:nnnn}
% \begin{macrocode}
-\NewDocumentCommand \xeCJKsetmathcode { m m m m }
+\cs_new_protected_nopar:Npn \xeCJK_gset_mathcode:nnnn #1#2#3#4
{
\@@_check_num_range:nnNN {#1} {#2} \l_@@_tmpa_int \l_@@_tmpb_int
- \int_set:Nn \l_@@_tmpc_int { \@@_math_type:n {#3} }
- \int_set:Nn \l_tmpa_int { \use:c { sym #4 } }
\xeCJK_int_until_do:nn { \l_@@_tmpa_int > \l_@@_tmpb_int }
{
- \XeTeXmathcode \l_@@_tmpa_int = \l_@@_tmpc_int \l_tmpa_int \l_@@_tmpa_int
+ \tex_global:D \XeTeXmathcode \l_@@_tmpa_int = #3 ~ #4 \l_@@_tmpa_int
\int_incr:N \l_@@_tmpa_int
}
}
-\cs_new_eq:NN \@@_math_type:n \mathchar@type
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\xeCJK_set_mathfont:}
+%
+% \subsection{抄录环境中的间距调整}
+%
+% \changes{v3.1.0}{2012/11/19}{放弃使用放缩字体大小的方式,而只采用调整间距的方式
+% 与西文等宽字体对齐。并且只适用于与抄录环境下。}
+%
+% \begin{macro}{\xeCJKVerbAddon}
+% \changes{v3.1.0}{2012/11/19}{新增 \cs{xeCJKVerbAddon} 用于抄录环境中的间距调整。}
+% \cs{xeCJKVerbAddon} 进行了比较大的调整,应该只在分组环境里使用。为了方便调整间距
+% 以利于对齐,这里只把字符分成了两类,并且在 CJK 类与边界(空格)之间也插入
+% \cs{CJKecglue}。当然,这样做之后,关于标点符号的禁则就没有了。
% \begin{macrocode}
-\cs_new_protected_nopar:Npn \xeCJK_set_mathfont:
+\NewDocumentCommand \xeCJKVerbAddon { }
{
- \xeCJK_family_if_exist:xTF \c_@@_math_tl
- { \tl_set:Nx \l_@@_tmpa_tl \c_@@_math_tl }
- {
- \xeCJK_family_if_exist:xTF \CJKfamilydefault
- { \tl_set:Nx \l_@@_tmpa_tl \CJKfamilydefault }
- { \tl_set_eq:NN \l_@@_tmpa_tl \q_no_value }
- }
- \prop_get:NVNT \g_@@_family_name_prop \l_@@_tmpa_tl \l_@@_math_family_tl
+ \int_compare:nNnF \etex_currentgrouplevel:D = \c_zero
{
- \DeclareSymbolFont \c_@@_math_tl \c_@@_encoding_tl
- \l_@@_math_family_tl \mddefault \shapedefault
- \SetSymbolFont \c_@@_math_tl { bold } \c_@@_encoding_tl
- \l_@@_math_family_tl \bfdefault \shapedefault
- \clist_map_inline:nn { CJK, FullLeft, FullRight }
+ \@@_set_verb_exspace:
+ \bool_if:NF \l_@@_verb_addon_bool
{
- \clist_map_inline:cn { g_@@_##1_range_clist }
- {
- \@@_set_char_class_aux:Nn \xeCJKsetmathcode {####1}
- \mathalpha \c_@@_math_tl
- }
+ \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 }
+ \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 }
+ \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 }
}
}
}
+\bool_new:N \l_@@_verb_addon_bool
+\cs_new_eq:NN \CJKfixedspacing \xeCJKVerbAddon
% \end{macrocode}
% \end{macro}
%
-% 当没有设置 CJK 数学字体时,使用 \cs{CJKfamilydefault} 作为数学字体。
-% \begin{macrocode}
-\@@_AtEndPreamble:n
- {
- \normalfont
- \prop_if_empty:NTF \g_@@_family_prop
- { \@@_warning:n { no-CJKfamily } }
- { \bool_if:NT \g_@@_math_bool { \xeCJK_set_mathfont: } }
- }
-\@@_msg_new:nn { no-CJKfamily }
- {
- It~seems~that~you~have~not~declare~a~CJKfamily.\\
- If~you~want~to~use~xeCJK~in~the~right~way,~you~should~use\\\\
- \token_to_str:N \xeCJKmainfont[...]{...}\\\\
- in~the~preamble~to~declare~the~main~CJKfamily.\\
- }
-% \end{macrocode}
-%
-% \subsection{处理等宽字体和抄录环境}
-%
-% \begin{macro}[internal,var]{\g_@@_monoscale_fp,\g_@@_exspace_dim}
+% 总是在 \LaTeX 的抄录环境(包括 \cs{verb})里使用 \cs{xeCJKVerbAddon},以保证代码
+% 的对齐。
% \begin{macrocode}
-\fp_new:N \g_@@_monoscale_fp
-\fp_set_eq:NN \g_@@_monoscale_fp \c_one_fp
-\dim_new:N \g_@@_exspace_dim
+\@@_after_preamble:n
+ { \xeCJK_cs_add:Nnn \verbatim@font { } { \xeCJKVerbAddon } }
% \end{macrocode}
-% \end{macro}
%
-% \begin{macro}{\setCJKmonoscale}
+% \begin{macro}[internal]{\@@_set_verb_exspace:}
+% 在抄录环境中,CJK 文字之间的间距为当前西文字体两个空格的宽度与当前字体大小之差,
+% 而与西文和空格的间距为 CJK 文字之间的间距的一半。这里的问题是,
+% \cs{g_@@_verb_exspace_skip} 有可能为负么?现在的处理是保证它非负。如果真的出现
+% 负间距的情况,也可以像下面对后备可视空格符号一样,在 \cs{xeCJK_select_font:} 里
+% 对 CJK 文字的字体大小做调整,并让间距为零。
% \begin{macrocode}
-\NewDocumentCommand \setCJKmonoscale { }
- {
- \CJKflexiblespacing
- \xeCJK_set_monoscale:
- \addCJKfontfeatures { Scale = \fp_use:N \g_@@_monoscale_fp }
- }
-\cs_new_protected_nopar:Npn \xeCJK_set_monoscale:
+\cs_new_protected_nopar:Npn \@@_set_verb_exspace:
{
- \group_begin:
- \fontfamily \ttdefault \selectfont
- \fp_gset:Nn \g_@@_monoscale_fp
- { \dim_to_fp:n { \c_two \tex_fontdimen:D \c_two \tex_font:D } / ( \f@size ) }
- \group_end:
+ \tl_if_exist:cTF { xeCJK/verb/\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
+ {
+ \dim_max:nn
+ { \c_zero_dim }
+ { \c_two \tex_fontdimen:D \c_two \tex_font:D - \f@size pt }
+ }
+ \tl_gset:cV { xeCJK/verb/\curr@fontshape/\f@size } \g_@@_verb_exspace_skip
+ }
}
+\skip_new:N \g_@@_verb_exspace_skip
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\setCJKmonoexspace}
+% \begin{macro}[internal]{\xeCJK_visible_space_fallback:}
+% \changes{v3.1.0}{2012/11/19}{调整 \pkg{fontspec} 的后备可视空格符号,以便于使用
+% 时对齐。}
+% \pkg{fontspec} 使用 |lmtt| 字体中的可视空格符号(|U+2423|)作为当前字体中相应符号
+% 的后备。但是 |lmtt| 的字体大小未必与当前字体匹配。因此,我们在这里做一些调整,以
+% 保证使用后备可视空格符号时,也能保证对齐。这里加入 \cs{scan_stop:} 的目的是强制
+% 发生状态转移。这样当空格出现在 CJK 文字后面时,使字体回到西文,以便让
+% \pkg{fontspec} 在当前西文字体而不是在 CJK 字体中检查有没有 |U+2423|。
% \begin{macrocode}
-\NewDocumentCommand \setCJKmonoexspace { } { \xeCJK_set_monoexspace: }
-\cs_new_protected_nopar:Npn \xeCJK_set_monoexspace:
+\cs_new_protected_nopar:Npn \xeCJK_visible_space_fallback:
+ { {
+ \cs_if_exist_use:cF { xeCJK/space/\curr@fontshape/\f@size }
+ { \xeCJK_set_visible_space_font: }
+ \textvisiblespace
+ } }
+\AtEndOfPackage
{
- \group_begin:
- \fontfamily \ttdefault \selectfont
- \dim_gset:Nn \g_@@_exspace_dim
- {
- \c_two \tex_fontdimen:D \c_two \tex_font:D
- - \fp_to_dim:n { \g_@@_monoscale_fp * ( \f@size ) }
- }
- \group_end:
+ \xeCJK_cs_add:Nnn \fontspec_visible_space: { \scan_stop: } { }
+ \cs_gset_eq:NN \fontspec_visible_space_fallback: \xeCJK_visible_space_fallback:
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\CJKfixedspacing,\CJKflexiblespacing}
+% \begin{macro}[internal]{\xeCJK_set_visible_space_font:}
+% 当前字体空格的宽度与后备字体 |lmtt| 不一样时,就对 \cs{textvisiblespace} 的字体尺寸
+% 按相应的比例放缩。
% \begin{macrocode}
-\NewDocumentCommand \CJKfixedspacing { }
+\cs_new_protected_nopar:Npn \xeCJK_set_visible_space_font:
{
- \bool_if:NF \l_@@_fixed_spacing_bool
+ \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 }
+ \selectfont
+ \dim_compare:nNnF \l_@@_tmp_dim = { \tex_fontdimen:D \c_two \tex_font:D }
{
- \bool_set_true:N \l_@@_fixed_spacing_bool
- \tl_set_eq:NN \l_@@_flexible_punctstyle_tl \l_xeCJK_punctstyle_tl
- \bool_set_eq:NN \l_@@_fixed_xecglue_bool \l_@@_xecglue_bool
- \cs_set_eq:NN \@@_flexible_ecglue: \CJKecglue
- \cs_set_eq:NN \@@_flexible_cjkglue: \CJKglue
- \xeCJK_set_monoexspace:
- \xeCJKsetup
+ \fontsize
{
- PunctStyle = plain ,
- CJKglue = { \skip_horizontal:N \g_@@_exspace_dim } ,
- CJKecglue = { \skip_horizontal:n { .5\g_@@_exspace_dim } } ,
- xCJKecglue = false ,
+ \dim_eval:n
+ {
+ \f@size pt * \dim_ratio:nn
+ { \l_@@_tmp_dim } { \tex_fontdimen:D \c_two \tex_font:D }
+ }
}
+ { \f@baselineskip }
+ \selectfont
}
+ \xeCJK_font_gset_to_current:c { \l_@@_current_coor_tl }
}
-\NewDocumentCommand \CJKflexiblespacing { }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{\pkg{xeCJK} 其它选项}
+%
+% \begin{macro}{LocalConfig}
+% \changes{v3.1.0}{2012/11/20}{增加 \texttt{LocalConfig} 选项用于载入本地配置文件。}
+% 声明载入本地配置文件的选项。
+% \begin{macrocode}
+\keys_define:nn { xeCJK / options }
{
- \bool_if:NT \l_@@_fixed_spacing_bool
+ LocalConfig .choice: ,
+ LocalConfig / false .code:n =
+ { \bool_gset_false:N \g_@@_config_bool } ,
+ LocalConfig / true .code:n =
{
- \bool_set_false:N \l_@@_fixed_spacing_bool
- \exp_args:Nx \xeCJKsetup
- {
- PunctStyle = { \l_@@_flexible_punctstyle_tl } ,
- CJKglue = { \exp_not:o { \@@_flexible_cjkglue: } } ,
- CJKecglue = { \exp_not:o { \@@_flexible_ecglue: } } ,
- xCJKecglue = { \bool_if:NTF \l_@@_fixed_xecglue_bool { true } { false } } ,
- }
- }
+ \bool_gset_true:N \g_@@_config_bool
+ \tl_gset:Nn \g_@@_config_name_tl { xeCJK }
+ } ,
+ LocalConfig / unknown .code:n =
+ {
+ \bool_gset_true:N \g_@@_config_bool
+ \tl_gset:Nx \g_@@_config_name_tl { xeCJK - \l_keys_value_tl }
+ } ,
+ LocalConfig .default:n = { true }
}
-\bool_new:N \l_@@_fixed_spacing_bool
-\@@_AfterPreamble:n { \tl_put_right:Nn \verbatim@font \CJKfixedspacing }
+\tl_new:N \g_@@_config_name_tl
+\bool_new:N \g_@@_config_bool
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\setCJKmonofont}
-% 设置文档的 CJK 等宽字体族。
+% \begin{macro}{CJKnumber,indentfirst}
+% 是否启用 \pkg{CJKnumb} 宏包和首行是否缩进。
% \begin{macrocode}
-\NewDocumentCommand \setCJKmonofont { s t+ O{} m }
+\keys_define:nn { xeCJK / options }
{
- \IfBooleanTF {#1}
- { \xeCJK_set_family:xnn \CJKttdefault { Mono = Scale, #3 } {#4} }
- {
- \IfBooleanTF {#2}
- { \xeCJK_set_family:xnn \CJKttdefault { Mono = Exspace, #3 } {#4} }
- { \xeCJK_set_family:xnn \CJKttdefault {#3} {#4} }
- }
+ CJKnumber .bool_gset:N = \g_@@_number_bool ,
+ indentfirst .bool_gset:N = \g_@@_indent_bool ,
+ normalindentfirst .meta:n = { indentfirst = false }
}
% \end{macrocode}
% \end{macro}
%
-% \subsection{\pkg{xeCJK} 其它选项}
-%
-% \begin{macro}{CJKnumber,indentfirst}
-% 是否启用 \pkg{CJKnumber} 宏包和首行是否缩进,其中 |CJKnumber| 选项仅
-% 在 \pkg{xeCJK} 宏包调用的时候有效。并将 \pkg{xeCJK} 中未知的选项传递给
-% \pkg{fontspec} 宏包。
+% \begin{macro}{quiet,silent}
+% 将调用 \pkg{xeCJK} 时使用的未知的选项传递给 \pkg{fontspec} 宏包。
+% 对 \pkg{fontspec} 的 |quiet| 和 |silent| 选项进行修改,使其适用于 \pkg{xeCJK}。
% \begin{macrocode}
-\bool_new:N \g_@@_indent_bool
\keys_define:nn { xeCJK / options }
{
- CJKnumber .bool_set:N = \g_@@_number_bool ,
- indentfirst .bool_set:N = \g_@@_indent_bool ,
- normalindentfirst .meta:n = { indentfirst = false } ,
quiet .code:n =
{
\msg_redirect_module:nnn { xeCJK } { warning } { info }
\msg_redirect_module:nnn { xeCJK } { info } { none }
\xeCJK_if_package_loaded:nF { fontspec }
{ \PassOptionsToPackage { quiet } { fontspec } }
- },
+ } ,
silent .code:n =
{
\msg_redirect_module:nnn { xeCJK } { warning } { none }
\msg_redirect_module:nnn { xeCJK } { info } { none }
\xeCJK_if_package_loaded:nF { fontspec }
{ \PassOptionsToPackage { silent } { fontspec } }
- },
+ } ,
unknown .code:n =
{
\xeCJK_if_package_loaded:nTF { fontspec }
{ \@@_error:nx { key-unknown } { \l_keys_key_tl } }
{ \PassOptionsToPackage { \l_keys_key_tl } { fontspec } }
- },
+ }
}
\@@_msg_new:nn { key-unknown }
{
@@ -4095,54 +4760,83 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
%
% \subsection{\pkg{xeCJK} 初始化设置}
%
+% \begin{macro}[internal]{\CJKsymbol, \CJKpunctsymbol}
+% \begin{macrocode}
+\cs_new_nopar:Npn \CJKsymbol #1 {#1}
+\cs_new_nopar:Npn \CJKpunctsymbol #1 {#1}
+% \end{macrocode}
+% \end{macro}
+%
% \pkg{xeCJK} 宏包的初始化设置。
+%
% \begin{macrocode}
\keys_set:nn { xeCJK / options }
{
- CJKglue = { \skip_horizontal:n { \c_zero_skip \@plus .08\baselineskip } } ,
+ CJKglue = { \skip_horizontal:n { \c_zero_dim plus 0.08 \tex_baselineskip:D } } ,
CJKecglue = \c_space_token ,
xCJKecglue = false ,
CheckSingle = false ,
CJKspace = false ,
CJKmath = false ,
+ CJKnumber = false ,
xeCJKactive = true ,
+ LocalConfig = true ,
indentfirst = true ,
- EmboldenFactor = 4 ,
- SlantFactor = .167 ,
+ EmboldenFactor = 4 ,
+ SlantFactor = 0.167 ,
PunctStyle = quanjiao ,
KaiMingPunct = { ^^^^3002 ^^^^ff0e ^^^^ff1f ^^^^ff01 } ,
LongPunct = { ^^^^2014 ^^^^2015 ^^^^2500 ^^^^2025 ^^^^2026 } ,
MiddlePunct = { ^^^^2014 ^^^^2015 ^^^^2500 ^^^^00b7 ^^^^30fb ^^^^ff65 } ,
- AllowBreakBetweenPuncts = false ,
+ AllowBreakBetweenPuncts = false
}
+\defaultCJKfontfeatures { Script = CJK }
% \end{macrocode}
%
-% \begin{macro}[internal]{\CJKsymbol, \CJKpunctsymbol}
-% \begin{macrocode}
-\cs_new_nopar:Npn \CJKsymbol #1 {#1}
-\cs_new_nopar:Npn \CJKpunctsymbol #1 {#1}
-% \end{macrocode}
-% \end{macro}
-%
% 执行宏包选项,并载入 \pkg{fontspec} 宏包。
% \begin{macrocode}
\ProcessKeysOptions { xeCJK / options }
\RequirePackage { fontspec } [ 2011/09/13 ]
% \end{macrocode}
%
-% \begin{macro}[internal]{\c_@@_encoding_tl}
+% \begin{macro}[internal,var]{\c_@@_encoding_tl}
+% 保存 \pkg{fontspec} 声明字体时使用的字体编码。
% \begin{macrocode}
\tl_const:Nx \c_@@_encoding_tl { \g_fontspec_encoding_tl }
% \end{macrocode}
% \end{macro}
%
+% 章节标题后面的首个段落的首行是否缩进。
+% \changes{v3.1.0}{2012/11/21}{改用 \pkg{indentfirst} 宏包处理缩进的问题。}
% \begin{macrocode}
-\bool_if:NT \g_@@_indent_bool
+\bool_if:NT \g_@@_indent_bool { \RequirePackage { indentfirst } }
+% \end{macrocode}
+%
+% 对不能通过 \cs{xeCJKsetup} 设置的选项给出警告。
+% \begin{macrocode}
+\keys_define:nn { xeCJK / options }
{
- \cs_set_eq:NN \@afterindentfalse \@afterindenttrue
- \@afterindenttrue
+ LocalConfig .code:n = { \@@_warning:nx { option-invalid } { \l_keys_key_tl } } ,
+ CJKnumber .code:n = { \@@_warning:nx { option-invalid } { \l_keys_key_tl } } ,
+ indentfirst .code:n = { \@@_warning:nx { option-invalid } { \l_keys_key_tl } }
}
+\@@_msg_new:nn { option-invalid }
+ {
+ The~`#1'~option~only~can~be~set~in~the~optional~argument~to~the\\
+ \token_to_str:N \usepackage \ command~when~xeCJK~is~being~loaded.\\\\
+ Please~do~not~set~it~via~the~\token_to_str:N \xeCJKsetup \ command.
+ }
+% \end{macrocode}
+%
+% \begin{macro}[var]{\CJKrmdefault,\CJKsfdefault,\CJKttdefault,\CJKfamilydefault}
+% \begin{macrocode}
+\tl_if_exist:NF \CJKrmdefault { \tl_gset:Nn \CJKrmdefault { rm } }
+\tl_if_exist:NF \CJKsfdefault { \tl_gset:Nn \CJKsfdefault { sf } }
+\tl_if_exist:NF \CJKttdefault { \tl_gset:Nn \CJKttdefault { tt } }
+\tl_if_exist:NF \CJKfamilydefault { \tl_gset:Nn \CJKfamilydefault { \CJKrmdefault } }
+\tl_new:c { \@@_family_csname:n { \CJKfamilydefault } }
% \end{macrocode}
+% \end{macro}
%
% \begin{macro}{\xeCJKsetup}
% 在导言区或文档中设置 \pkg{xeCJK} 的接口。
@@ -4167,7 +4861,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
% \begin{macro}[internal]{\punctstyle, \xeCJKplainchr}
% \begin{macrocode}
\NewDocumentCommand \punctstyle { m } { \xeCJKsetup { PunctStyle = {#1} } }
-\NewDocumentCommand \xeCJKplainchr { } { \punctstyle { plain } }
+\NewDocumentCommand \xeCJKplainchr { } { \xeCJKsetup { PunctStyle = plain } }
% \end{macrocode}
% \end{macro}
%
@@ -4178,47 +4872,120 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}[internal]{\CJKspace,\CJKnospace}
+% \begin{macrocode}
+\NewDocumentCommand \CJKspace { } { \xeCJKsetup { CJKspace = true } }
+\NewDocumentCommand \CJKnospace { } { \xeCJKsetup { CJKspace = false } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\xeCJKallowbreakbetweenpuncts, \xeCJKnobreakbetweenpuncts}
+% \begin{macrocode}
+\NewDocumentCommand \xeCJKallowbreakbetweenpuncts { }
+ { \xeCJKsetup { AllowBreakBetweenPuncts = true } }
+\NewDocumentCommand \xeCJKnobreakbetweenpuncts { }
+ { \xeCJKsetup { AllowBreakBetweenPuncts = false } }
+% \end{macrocode}
+% \end{macro}
+%
% \subsection{兼容性修补}
%
-% \begin{macro}[internal]{\@@_fix_itcorr:}
-% 修复倾斜校正。
+% 补丁 \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
+% \end{macrocode}
+%
+% 因为我们在上面把 \cs{CJKfamily} 加在了 \cs{rmfamily} 里面,而 \pkg{fontspec} 在
+% 调用字体时,某些选项要使用它。为减少影响,下面使 \cs{CJKfamily} 在通过
+% \pkg{fontspec} 来实际调用字体时无效。
% \begin{macrocode}
-\cs_new_protected_nopar:Npn \@@_fix_itcorr:
- {
- \scan_stop:
- \xeCJK_if_last_node:nTF { default }
- {
- \tex_unkern:D \tex_unkern:D
- \@@_itcorr_aux
- { \xeCJK_make_node:n { default_itcorr } }
- }
- { \@@_itcorr_aux }
- }
-\cs_new_eq:NN \@@_itcorr_aux \/
-\cs_set_protected_nopar:Npn \/
- {
- \int_compare:nNnTF \XeTeXinterchartokenstate > \c_zero
- { \@@_fix_itcorr: } { \@@_itcorr_aux }
- }
+\xeCJK_cs_add:Nnn \fontspec_init: { \@@_gobble_CJKfamily: } { }
% \end{macrocode}
%
+% \newbox\xeCJKtmpbox
+% \setbox\xeCJKtmpbox\vbox\bgroup
% \begin{macrocode}
%<@@=>
-% \end{macrocode}
+% \end{macrocode}\egroup
%
+% \begin{macro}[internal]{\xeCJK@fix@penalty}
+% \changes{v3.1.0}{2012/11/13}{采用通过不修改原语 \cs{/} 的方式对修复倾斜校正。}
+% 对 \LaTeXe 内核中的 \cs{fix@penalty} 被用于诸如 \cs{textit} 之类的文档
+% 字体转换命令的定义之中。这里对它进行补丁的目的是修复其中的倾斜校正,并使得这些
+% 文档命令与紧随其后的汉字之间可以正确的插入 \cs{CJKecglue} 或者忽略其中的空格。
+% 例如 \verb*|这是 \emph{强调} 文本|,第二个空格可以被忽略掉。如果使用 |xCJKecglue|
+% 选项,第一个空格也可以被省略。事实上,在 \cs{sw@slant} 的定义中,\cs{@@italiccorr}
+% 前面的 \cs{lastskip} 和 \cs{lastpenalty} 有四种情况,这里只对它们都为零的情况进行
+% 处理。
% \begin{macrocode}
-\cs_set_eq:NN \@@italiccorr \/
+\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
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}[internal]{\xeCJK@patch@italiccorr}
+% 修复倾斜校正,并处理汉字后面的空格。
% \begin{macrocode}
-%<@@=xeCJK>
+\cs_new_protected_nopar:Npn \xeCJK@patch@italiccorr
+ {
+ \int_compare:nNnTF \XeTeXinterchartokenstate > \c_zero
+ {
+ \xeCJK_if_last_node:nTF { default }
+ {
+ \tex_unkern:D \tex_unkern:D \@@italiccorr
+ { \xeCJK_make_node:n { default } }
+ }
+ {
+ \xeCJK_if_last_node:nTF { CJK }
+ {
+ \tex_unkern:D \tex_unkern:D \@@italiccorr
+ { \xeCJK_make_node:n { CJK } } \use:n
+ }
+ {
+ \xeCJK_if_last_node:nTF { CJK-space }
+ {
+ \tex_unkern:D \tex_unkern:D \@@italiccorr
+ { \xeCJK_make_node:n { CJK-space } } \use:n
+ }
+ { \@@italiccorr \use_none:n }
+ }
+% \end{macrocode}
+% \cs{xeCJK_ignore_spaces:w} 里面用到 |peek| 函数来判断后面是不是空格,而此时它
+% 后面还有 $4$ 个 \cs{fi} 或者 |\else...\fi| 没有被展开,将影响 |peek| 函数的
+% 判断。因此我们需要用 $2^4-1=15$ 个 \cs{exp_after:wN} 来展开它们。
+% 显然,这里用 \cs{exp_last_unbraced:Nf} 会比较方便,但是它会吃掉
+% \verb*|\textit{...} | 等后面原来存在的空格作为完全展开的结束。要正确使用它还
+% 需要另外的处理(使用 \cs{exp_stop_f:})。
+% \begin{macrocode}
+ {
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_after:wN \exp_after:wN \exp_after:wN
+ \xeCJK_ignore_spaces:w
+ }
+ }
+ }
+ { \@@italiccorr }
+ }
% \end{macrocode}
% \end{macro}
%
+% \setbox\xeCJKtmpbox\vbox\bgroup
+% \begin{macrocode}
+%<@@=xeCJK>
+% \end{macrocode}\egroup
+%
% \begin{macro}[internal]{\@@_set_others_toks:n,\c_@@_Others_class_int}
% 简单处理与同样使用 \cs{XeTeXinterchartoks} 机制的宏包的兼容问题。
-% \begin{macrocode}
-\@@_AfterEndPreamble:n
+% \begin{macrocode}
+\@@_after_end_preamble:n
{
\int_compare:nNnF
{ \c_three + ( \seq_count:N \g_@@_class_seq ) } = \xe@alloc@intercharclass
@@ -4233,44 +5000,36 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
\cs_new_protected_nopar:Npn \@@_set_others_toks:n #1
{
\int_set:Nn \c_@@_Others_class_int {#1}
- \clist_map_inline:Nn \g_@@_CJK_class_clist
+ \seq_map_inline:Nn \g_@@_CJK_class_seq
{
- \@@_copy_inter_class_toks:nnnn {##1} { Others } {##1} { NormalSpace }
- \@@_copy_inter_class_toks:nnnn { Others } {##1} { NormalSpace } {##1}
- \exp_args:Nnnx \@@_app_inter_class_toks:nnn {##1} { Others }
- { \@@_get_inter_class_toks:nn { Default } { Others } }
- \exp_args:Nnnx \@@_pre_inter_class_toks:nnn { Others } {##1}
- { \@@_get_inter_class_toks:nn { Others } { Default } }
+ \xeCJK_copy_inter_class_toks:nnnn {##1} { Others } {##1} { NormalSpace }
+ \xeCJK_copy_inter_class_toks:nnnn { Others } {##1} { NormalSpace } {##1}
+ \xeCJK_app_inter_class_toks:nnx {##1} { Others }
+ { \xeCJK_get_inter_class_toks:nn { Default } { Others } }
+ \xeCJK_pre_inter_class_toks:nnx { Others } {##1}
+ { \xeCJK_get_inter_class_toks:nn { Others } { Default } }
\xeCJK_if_blank_x:nT
- { \@@_get_inter_class_toks:nn { Others } { Boundary } }
+ { \xeCJK_get_inter_class_toks:nn { Others } { Boundary } }
{
- \@@_copy_inter_class_toks:nnnn
+ \xeCJK_copy_inter_class_toks:nnnn
{ Others } { Boundary } { Default } { Boundary }
}
\xeCJK_if_blank_x:nT
- { \@@_get_inter_class_toks:nn { Boundary } { Others } }
+ { \xeCJK_get_inter_class_toks:nn { Boundary } { Others } }
{
- \@@_copy_inter_class_toks:nnnn
+ \xeCJK_copy_inter_class_toks:nnnn
{ Boundary } { Others } { Boundary } { Default }
}
}
}
-\int_new:N \c_@@_Others_class_int
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[internal]{\@@_patch:Nnn}
-% 给已有宏内容前后附加补丁。
-% \begin{macrocode}
-\cs_new_protected_nopar:Npn \@@_patch:Nnn #1#2#3
- { \tl_put_left:Nn #1 {#2} \tl_put_right:Nn #1 {#3} }
+\cs_new_eq:NN \c_@@_Others_class_int \l_@@_tmpa_int
% \end{macrocode}
% \end{macro}
%
% 单独处理宽度有分歧的几个标点:包括省略号、破折号、间隔号、引号等中西文混用的
% 符号, 保证其命令形式输出的是西文字体。并对一些编码的符号宏包做特殊处理。
% \begin{macrocode}
-\@@_AfterPreamble:n
+\@@_after_preamble:n
{
\tl_map_inline:nn
{
@@ -4278,18 +5037,14 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
\textquoteleft \textquoteright \textquotedblleft \textquotedblright
}
{
- \@@_patch:Nnn #1
- { \@@_group_begin: \makexeCJKinactive }
- { \@@_group_end: }
+ \xeCJK_cs_add:Nnn #1
+ { \@@_group_begin: \makexeCJKinactive } { \@@_group_end: }
}
- \@@_patch:Nnn \tipaencoding { \makexeCJKinactive } { }
- \cs_set_eq:NN \@@_aux_r \r
- \cs_set_protected_nopar:Npn \r #1 { { \makexeCJKinactive \@@_aux_r {#1} } }
+ \xeCJK_cs_add:Nnn \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 }
- {
- \RenewDocumentCommand \Pifont { m }
- { \makexeCJKinactive \usefont {U} {#1} {m} {n} }
- }
+ { \xeCJK_cs_add:Nnn \Pifont { \makexeCJKinactive } { } }
}
\cs_new_eq:NN \@@_group_begin: \group_begin:
\cs_new_eq:NN \@@_group_end: \group_end:
@@ -4297,121 +5052,134 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
%
% 简单处理与 \pkg{hyperref} 宏包的兼容问题。
% \begin{macrocode}
-\@@_AfterEndPreamble:n
+\@@_after_end_preamble:n
{
- \bool_if:nT
- {
- \xeCJK_if_package_loaded_p:n { hyperref } &&
- \tl_if_exist_p:N \pdfstringdefPreHook
- }
+ \xeCJK_if_package_loaded:nT { hyperref }
{
\tl_gput_right:Nn \pdfstringdefPreHook
{
- \cs_set_eq:NN \makexeCJKinactive \prg_do_nothing:
- \cs_set_eq:NN \@@_group_begin: \prg_do_nothing:
- \cs_set_eq:NN \@@_group_end: \prg_do_nothing:
- \cs_set_eq:NN \CJKfamily \use_none:n
+ \@@_gobble_CJKfamily:
+ \xeCJK_cs_clear:N \makexeCJKinactive
+ \xeCJK_cs_clear:N \@@_group_begin:
+ \xeCJK_cs_clear:N \@@_group_end:
}
}
}
% \end{macrocode}
%
-% 禁止在 \pkg{xeCJK} 宏包后再载入 \pkg{CJK} 宏包。
+% \changes{v3.1.0}{2012/11/13}{取消 \cs{cprotect} 的外部宏限制。}
+% 当探测到 \pkg{cprotect} 宏包被引入时,则取消 \cs{cprotect} 宏的 \cs{outer} 定义。
% \begin{macrocode}
-\tl_set:cn { ver@CJK.sty } { 2100/01/01 }
+\@@_after_end_preamble:n
+ {
+ \bool_if:nT
+ { \xeCJK_if_package_loaded_p:n { cprotect } && \cs_if_exist_p:N \icprotect }
+ { \exp_after:wN \tex_let:D \cs:w cprotect \cs_end: \icprotect }
+ }
+% \end{macrocode}
+%
+% 禁止在 \pkg{xeCJK} 宏包后再载入 \pkg{CJK} 宏包,并使得
+% \pkg{CJKnumb} 和 \pkg{CJKfntef} 宏包可以使用。
+% \begin{macrocode}
+\tl_set:cn { ver@CJK.sty } { 9999/99/99 }
+\tl_set_eq:cc { ver@CJKpunct.sty } { ver@CJK.sty }
% \end{macrocode}
%
% \begin{macro}[internal]{\xeCJKcaption}
% 可以使用 \pkg{CJK} 宏包中的 |.cpx| 文件。
% \begin{macrocode}
-\cs_if_free:NT \CJK@ifundefined
+\cs_if_exist:NF \CJK@ifundefined
{ \cs_set_eq:NN \CJK@ifundefined \cs_if_free:NTF }
\NewDocumentCommand \xeCJKcaption { o m }
{
\IfNoValueF {#1} { \XeTeXdefaultencoding "#1" }
- \cs_set_nopar:Npx \@@_reset_at_catcode:
+ \use:x
{
- \exp_not:n { \char_set_catcode:nn { `\@ } }
- { \char_value_catcode:n { `\@ } }
+ \char_set_catcode_letter:n { 64 }
+ \file_input:n { #2.cpx }
+ \char_set_catcode:nn { 64 } { \char_value_catcode:n { 64 } }
}
- \char_set_catcode_letter:N \@
- \file_input:n { #2.cpx }
- \@@_reset_at_catcode:
\XeTeXdefaultencoding "UTF-8"
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]
-% {\xeCJK_ULprepunctchar:n, \xeCJK_ULpostpunctchar:n, \xeCJK_ULroutines:}
+% \begin{macro}[internal]{\xeCJK_hook_for_ulem:}
+% \changes{v3.1.0}{2012/11/16}{简化对 \pkg{ulem} 宏包的兼容补丁。}
+% 对 \pkg{ulem} 宏包打补丁,以支持 \pkg{CJKfntef} 宏包。目前的问题是,在下划线状态
+% 下,相邻两个标点之间的空白不能压缩。
% \begin{macrocode}
-\cs_new_protected_nopar:Npn \xeCJK_ULprepunctchar:n #1
- {
- { \makexeCJKinactive \CJKpunctsymbol {#1} \xeCJK_no_break: }
- \tex_ignorespaces:D
- }
-\cs_new_protected_nopar:Npn \xeCJK_ULpostpunctchar:n #1
+\cs_new_protected_nopar:Npn \xeCJK_hook_for_ulem:
{
- { \makexeCJKinactive \CJKpunctsymbol {#1} }
- \xeCJK_ignorespaces:
+ \bool_if:NF \l_@@_ulem_hook_used_bool
+ {
+ \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
+ }
}
-\cs_new_protected_nopar:Npn \xeCJK_ULroutines:
+\bool_new:N \l_@@_ulem_hook_used_bool
+\@@_after_preamble:n
{
- \@@_inter_class_toks:nnn { Default } { CJK } { \CJKecglue \CJKsymbol }
- \@@_inter_class_toks:nnn { HalfLeft } { CJK } { \CJKsymbol }
- \@@_inter_class_toks:nnn { HalfRight } { CJK } { \CJKecglue \CJKsymbol }
- \@@_inter_class_toks:nnn { Boundary } { CJK } { \xeCJK_Boundary_and_CJK: }
- \clist_map_inline:nn { Default, HalfLeft, HalfRight, Boundary }
+ \xeCJK_if_package_loaded:nT { ulem }
{
- \@@_inter_class_toks:nnn {##1} { FullLeft } { \xeCJK_ULprepunctchar:n }
- \@@_inter_class_toks:nnn {##1} { FullRight } { \xeCJK_ULpostpunctchar:n }
+ \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_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 }
+ }
+ { \RequirePackage { CJKulem } }
+ \addto@hook \UL@hook { \xeCJK_hook_for_ulem: }
}
- \@@_UL_subclass_patch_tl
}
% \end{macrocode}
% \end{macro}
%
-% 对 \pkg{ulem} 宏包打补丁,以支持 \pkg{CJKfntef} 宏包。
-% \begin{macrocode}
-\@@_AfterPreamble:n
+% \begin{macro}[internal]{\@@_ulem_CJKsymbol:N,\@@_ulem_CJKpunctsymbol:N}
+% 这两个宏定义里面的分组记号都是必须的,否则会出现分组不匹配的情况。
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_ulem_CJKsymbol:N #1
{
- \cs_if_exist:NT \UL@hook
- {
- \addto@hook \UL@hook
- {
- \cs_set_eq:NN \@@_UL_CJKsymbol \CJKsymbol
- \cs_set_eq:NN \@@_UL_CJKpunctsymbol \CJKpunctsymbol
- \cs_set_protected_nopar:Npn \CJKsymbol #1
- {
- { \xeCJK_select_font: \@@_UL_CJKsymbol {#1} }
- { \xeCJK_make_node:n { CJK } } \xeCJK_ignorespaces:
- }
- \cs_set_protected_nopar:Npn \CJKpunctsymbol #1
- { { \xeCJK_select_font: \@@_UL_CJKpunctsymbol {#1} } }
- \xeCJK_ULroutines:
- }
- }
- \cs_if_exist:NT \XeTeX@CJKfntef@hook
- {
- \cs_set_nopar:Npn \XeTeX@CJKfntef@hook
- { \xeCJK_select_font: \makexeCJKinactive }
- }
+ { \@@_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} 宏包而作一些处理。另外 \pkg{CJKnumb} 使用的是传统汉字“萬”
+% 和“億”,我们在这里把它们修正为简体字。
% \begin{macrocode}
\bool_if:NT \g_@@_number_bool
{
\tl_set:Nn \CJK@UnicodeEnc { UTF8 }
- \cs_set_protected_nopar:Npn \CJKaddEncHook #1#2
- { \cs_set_nopar:cpn { @@_enc_#1 } {#2} }
+ \cs_set_protected:Npn \CJKaddEncHook #1#2
+ { \cs_set:cpn { @@_enc_#1_hook: } {#2} }
\cs_set_protected_nopar:Npn \Unicode #1#2
- { \tex_char:D \int_eval:n { (#1) * \c_two_hundred_fifty_six + (#2) } }
+ { \tex_char:D \etex_numexpr:D (#1) * \c_two_hundred_fifty_six + (#2) \scan_stop: }
\RequirePackage { CJKnumb }
- \cs_if_exist_use:cT { @@_enc_\CJK@UnicodeEnc } { }
- \tl_set:Nx \CJK@tenthousand { ^^^^4e07 }
- \tl_set:Nx \CJK@hundredmillion { ^^^^4ebf }
+ \cs_if_exist_use:c { @@_enc_ \CJK@UnicodeEnc _hook: }
+ \tl_set:Nn \CJK@tenthousand { \Unicode { 78 } { 7 } }
+ \tl_set:Nn \CJK@hundredmillion { \Unicode { 78 } { 191 } }
+ }
+% \end{macrocode}
+%
+% 最后引入本地配置文件。
+% \begin{macrocode}
+\bool_if:NT \g_@@_config_bool
+ {
+ \tl_const:Nn \c_@@_config_ext_tl { cfg }
+ \@onefilewithoptions
+ { \g_@@_config_name_tl } [ ] [ ] { \c_@@_config_ext_tl }
}
% \end{macrocode}
%
@@ -4419,6 +5187,24 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
%</package>
% \end{macrocode}
%
+% \subsection{\pkg{xeCJK.cfg}}
+%
+% \begin{macrocode}
+%<*config>
+% \end{macrocode}
+%
+% 预设的配置文件 \file{xeCJK.cfg} 为一个空文件。可以在里面增加设置,然后保存到
+% 本地目录下面。
+% \begin{macrocode}
+
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</config>
+% \end{macrocode}
+%
+% \iffalse
+%
% \makeatletter
% \let\special@index\@gobble
% \makeatother
@@ -4431,7 +5217,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
%<*ex-autofake>
% \end{macrocode}
%
-% \begin{macrocode}
+% \begin{macrocode}
\documentclass{article}
\usepackage[AutoFakeBold,AutoFakeSlant]{xeCJK}
\setCJKmainfont[BoldFont=simhei.ttf, ItalicFont=simkai.ttf]{simsun.ttc}
@@ -4492,7 +5278,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
%<*ex-fallback>
% \end{macrocode}
%
-% \begin{macrocode}
+% \begin{macrocode}
\documentclass{article}
\usepackage[AutoFallBack]{xeCJK}
\usepackage{CJKfntef}
@@ -4544,7 +5330,7 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
%<*ex-block>
% \end{macrocode}
%
-% \begin{macrocode}
+% \begin{macrocode}
\documentclass{article}
\usepackage{xeCJK}
\usepackage{array}
@@ -4606,7 +5392,6 @@ CJK統合漢字(シージェーケーとうごうかんじ、CJK Unified Ideog
%</ex-block>
% \end{macrocode}
%
-% \CJKfixedspacing
%
% \subsection{\pkg{xeCJK-example-CJKecglue.tex}}
%
@@ -4674,9 +5459,163 @@ x^2+y^2
%</ex-single>
% \end{macrocode}
%
+% \subsection{\pkg{xeCJK-example-CJKfntef.tex}}
+%
+% \begin{macrocode}
+%<*ex-fntef>
+% \end{macrocode}
+%
+% \begin{macrocode}
+\documentclass{article}
+\usepackage{xeCJK}
+\usepackage{xcolor}
+\usepackage{CJKfntef}
+\setCJKmainfont{SimSun}
+
+\begin{document}
+
+\CJKunderline{汉字}\CJKunderline{加下划线加下划线加下划线加下划线
+加下划线加下划线加下划线加下划线加下划线加下划线加下划线}
+
+\CJKunderwave{波浪线}
+
+\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$}{汉字加点}
+
+\end{document}
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</ex-fntef>
+% \end{macrocode}
+%
+% \subsection{\pkg{xeCJK-example-punctstyle.tex}}
+%
+% \begin{macrocode}
+%<*ex-punctstyle>
+% \end{macrocode}
+%
+% \begin{macrocode}
+\documentclass{article}
+\usepackage{xeCJK}
+\setCJKmainfont{SimSun}
+\xeCJKDeclarePunctStyle { mine }
+ {
+ fixed-punct-ratio = 0 ,
+ fixed-margin-width = 0 pt ,
+ mixed-margin-width = \maxdimen ,
+ mixed-margin-ratio = 0.5 ,
+ middle-margin-width = \maxdimen ,
+ middle-margin-ratio = 0.5 ,
+ add-min-bound-to-margin = true ,
+ min-bound-to-kerning = true ,
+ kerning-margin-minimum = 0.1 em
+ }
+
+\begin{document}
+\setlength\parindent{2em}
+\newcommand\showexample[1]{%
+ \texttt{------ #1 ------}\par\xeCJKsetup{PunctStyle=#1}\showtexts\par}
+
+\newcommand\showtexts{%
+列位看官:你道此书从何而来?说起根由,虽近荒唐,细按则深有趣味。待在下将此来历注明,方使阅者了然不惑。
+
+原来女娲氏炼石补天之时,于大荒山无稽崖炼成高经十二丈、方经二十四丈顽石三万六千五百零一块。娲皇氏只用了三万六千五百块,只单单剩了一块未用,便弃在此山青埂峰下。谁知此石自经煆炼之后,灵性已通,因见众石俱得补天,独自己无材不堪入选,遂自怨自叹,日夜悲号惭愧。
+
+一日,正当嗟悼之际,俄见一僧一道远远而来,生得骨格不凡,丰神迥别,说说笑笑,来至峰下,坐于石边,高谈快论:先是说些云山雾海、神仙玄幻之事,后便说到红尘中荣华富贵。此石听了,不觉打动凡心,也想要到人间去享一享这荣华富贵,但自恨粗蠢,不得已,便口吐人言,向那僧道说道:“大师,弟子蠢物,不能见礼了!适闻二位谈那人世间荣耀繁华,心切慕之。弟子质虽粗蠢,性却稍通,况见二师仙形道体,定非凡品,必有补天济世之材,利物济人之德。如蒙发一点慈心,携带弟子得入红尘,在那富贵场中,温柔乡里受享几年,自当永佩洪恩,万劫不忘也!”二仙师听毕,齐憨笑道:“善哉,善哉!那红尘中有却有些乐事,但不能永远依恃;况又有‘美中不足,好事多磨’八个字紧相连属,瞬息间则又乐极悲生,人非物换,究竟是到头一梦,万境归空,倒不如不去的好。”这石凡心已炽,那里听得进这话去,乃复苦求再四。二仙知不可强制,乃叹道:“此亦静极思动,无中生有之数也!既如此,我们便携你去受享受享,只是到不得意时,切莫后悔!”石道:“自然,自然。”那僧又道:“若说你性灵,却又如此质蠢,并更无奇贵之处。如此也只好踮脚而已。也罢!我如今大施佛法,助你助,待劫终之日,复还本质,以了此案。你道好否?”石头听了,感谢不尽。那僧便念咒书符,大展幻术,将一块大石登时变成一块鲜明莹洁的美玉,且又缩成扇坠大小的可佩可拿。那僧托于掌上,笑道:“形体倒也是个宝物了!还只没有实在的好处,须得再镌上数字,使人一见便知是奇物方妙。然后好携你到那昌明隆盛之邦、诗礼簪缨之族、花柳繁华地、温柔富贵乡去安身乐业。”石头听了,喜不能禁,乃问:“不知赐了弟子那哪几件奇处?又不知携了弟子到何地方?望乞明示,使弟子不惑。”那僧笑道:“你且莫问,日后自然明白的。”说着,便袖了这石,同那道人飘然而去,竟不知投奔何方何舍。
+
+\hfill
+——曹雪芹《红楼梦》}
+
+
+\showexample{mine}
+\showexample{quanjiao}
+\showexample{banjiao}
+\showexample{CCT}
+\showexample{kaiming}
+\showexample{hangmobanjiao}
+\showexample{plain}
+
+\end{document}
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</ex-punctstyle>
+% \end{macrocode}
+%
+% \subsection{\pkg{xeCJK-example-verbatim.tex}}
+%
+% \begin{macrocode}
+%<*ex-verb>
+% \end{macrocode}
+%
+% \begin{macrocode}
+\documentclass[a4paper]{article}
+\usepackage{xeCJK}
+\usepackage{fullpage}
+\xeCJKDeclareSubCJKBlock{Hangul}
+ { "1100 -> "11FF, "3130 -> "318F, "A960 -> "A97F, "AC00 -> "D7AF }
+\setCJKmainfont{Adobe Song Std}
+\setCJKmainfont[Hangul]{Adobe Myungjo Std}
+%%\setmonofont{Inconsolata}
+%%\setmonofont{Source Code Pro}
+%%\setCJKmonofont{Adobe Kaiti Std}
+\setmonofont{TeX Gyre Cursor}
+\setCJKmonofont{Adobe Fangsong Std}
+\begin{document}
+
+\begin{verbatim}
+*************************************************************
+* *
+* 精致甲版红楼梦 - 精致工作室特别奉献(2010年9月) *
+* *
+* GBK简体、GBK繁体、Big5繁体、PDF简体、PDF繁体 *
+* *
+* 为 GBK、Big5 特别度身订制,并经反复修订,方便纯文本阅读 *
+* *
+* 精致甲、乙版红楼梦下载专页 *
+* http://www.speedy7.com/cn/stguru/gb2312/redmansions.htm *
+* http://www.speedy7.com/cn/stguru/big5/redmansions.htm *
+* *
+* 此电子文件可随意传播、发布、下载。 *
+* 传播时建议保留此版本说明供查阅与识别。 *
+* 未经修订者同意,不得将此版本用于商业用途。 *
+* 如您对红楼梦不具深入了解,请勿随便修改其中的内容。 *
+* *
+*************************************************************
+\end{verbatim}
+
+\verb|a 汉 字 b|
+
+\verb*|a 汉 字 b|
+
+\begin{verbatim}
+lang_set = {
+ ["English"] = lang.en,
+ ["Français"] = lang.fr,
+ ["Español"] = lang.es,
+ ["中文"] = lang.zh,
+ ["日本語"] = lang.ja,
+ ["한국어"] = lang.ko,
+}
+\end{verbatim}
+
+\end{document}
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</ex-verb>
+% \end{macrocode}
+%
+% \fi
+%
% \end{implementation}
%
-% \PrintIndex
+%
% \Finale
%
\endinput
diff --git a/Master/texmf-dist/source/xelatex/xecjk/xeCJK.ins b/Master/texmf-dist/source/xelatex/xecjk/xeCJK.ins
index ff9493f666f..d6dda519368 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 358 2012-10-27 11:52:01Z sobenlee $
+%% $Id: xeCJK.dtx 368 2012-11-23 04:55:23Z sobenlee $
%% $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
%% -----------------------------------------------------------------
%% Author:
@@ -35,7 +35,7 @@
\askforoverwritefalse
\preamble
-$Id: xeCJK.dtx 358 2012-10-27 11:52:01Z sobenlee $
+$Id: xeCJK.dtx 368 2012-11-23 04:55:23Z sobenlee $
$URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
-----------------------------------------------------------------
Author:
@@ -64,34 +64,56 @@ $URL: https://ctex-kit.googlecode.com/svn/trunk/xeCJK/xeCJK.dtx $
This package consists of the file xeCJK.dtx
and the derived files xeCJK.pdf,
xeCJK.sty,
+ xeCJK.cfg,
xeCJK.ins,
xeCJK-example-autofake.tex,
xeCJK-example-fallback.tex,
xeCJK-example-subCJKblock.tex,
xeCJK-example-CJKecglue.tex,
- xeCJK-example-checksingle.tex and
+ xeCJK-example-checksingle.tex,
+ xeCJK-example-CJKfntef.tex,
+ xeCJK-example-punctstyle.tex,
+ xeCJK-example-verbatim.tex, and
README.txt.
\endpostamble
+\declarepreamble\emptypreamble
+\endpreamble
+\declarepostamble\emptypostamble
+\endpostamble
\usedir{tex/xelatex/xecjk}
\generate{\file{\jobname.sty}{\from{\jobname.dtx}{package}}}
+\usedir{tex/xelatex/xecjk/config}
+\generate{
+ \usepreamble\emptypreamble
+ \usepostamble\emptypostamble
+ \file{\jobname.cfg}{\from{\jobname.dtx}{config}}}
\usedir{doc/xelatex/xecjk/example}
\generate{
+ \usepreamble\emptypreamble
+ \usepostamble\emptypostamble
\file{\jobname-example-autofake.tex}{\from{\jobname.dtx}{ex-autofake}}
\file{\jobname-example-fallback.tex}{\from{\jobname.dtx}{ex-fallback}}
\file{\jobname-example-subCJKblock.tex}{\from{\jobname.dtx}{ex-block}}
\file{\jobname-example-CJKecglue.tex}{\from{\jobname.dtx}{ex-ecglue}}
- \file{\jobname-example-checksingle.tex}{\from{\jobname.dtx}{ex-single}}}
+ \file{\jobname-example-checksingle.tex}{\from{\jobname.dtx}{ex-single}}
+ \file{\jobname-example-CJKfntef.tex}{\from{\jobname.dtx}{ex-fntef}}
+ \file{\jobname-example-punctstyle.tex}{\from{\jobname.dtx}{ex-punctstyle}}
+ \file{\jobname-example-verbatim.tex}{\from{\jobname.dtx}{ex-verb}}}
\endbatchfile
%%
%% This package consists of the file xeCJK.dtx
%% and the derived files xeCJK.pdf,
%% xeCJK.sty,
+%% xeCJK.cfg,
%% xeCJK.ins,
%% xeCJK-example-autofake.tex,
%% xeCJK-example-fallback.tex,
%% xeCJK-example-subCJKblock.tex,
%% xeCJK-example-CJKecglue.tex,
-%% xeCJK-example-checksingle.tex and
+%% xeCJK-example-checksingle.tex,
+%% xeCJK-example-CJKfntef.tex,
+%% xeCJK-example-punctstyle.tex,
+%% xeCJK-example-verbatim.tex, and
%% README.txt.
%%
%% End of file `xeCJK.ins'.