% \iffalse
%<*internal>
\iffalse
%</internal>
%<*readme>

xeCJK is a package written for XeLaTeX which allows users to typeset
CJK scripts easily.


 - different default fonts for CJK and other characters;
 - spaces automatically ignored between CJK characters;
 - special effects on full-width CJK punctuation; and
 - automatic adjustment of the space between CJK and other characters.


This package is licensed in LPPL.

If you are interested in the process of development you
may observe

    http://code.google.com/p/ctex-kit/updates/list

- Sun Wenchang <sunwch@hotmail.com>

%</readme>
%<*internal>
\fi
%</internal>
%
%<*internal>
\begingroup
%</internal>
%<*batchfile>
\input docstrip.tex
\keepsilent
\preamble

 Version 2.4.4 (17-Sep-2011)

 Copyright (C) Wenchang Sun <sunwch@hotmail.com>

 This file may be distributed and/or modified under the
 conditions of the LaTeX Project Public License, either version 1.3
 of this license or (at your option) any later version.
 The latest version of this license is in
   http://www.latex-project.org/lppl.txt
 and version 1.3 or later is part of all distributions of LaTeX
 version 2005/12/01 or later.

\endpreamble
\askforoverwritefalse
\generate{\file{xeCJK.sty}{\from{xeCJK.dtx}{xeCJK}}}
\generate{\file{example-addspaces.tex}{\from{xeCJK.dtx}{example-addspaces}}}
\generate{\file{example-CJKchecksingle.tex}{\from{xeCJK.dtx}{example-CJKchecksingle}}}
\generate{\file{example-CJKfntef.tex}{\from{xeCJK.dtx}{example-CJKfntef}}}
\generate{\file{example-fallback.tex}{\from{xeCJK.dtx}{example-fallback}}}
%</batchfile>
%<batchfile>\endbatchfile
%<*internal>
\generate{\file{xeCJK.ins}{\from{xeCJK.dtx}{batchfile}}}
\nopreamble\nopostamble
\generate{\file{README.txt}{\from{\jobname.dtx}{readme}}}
\endgroup
%</internal>
%
%<*driver>
\documentclass[12pt]{ltxdoc}
\usepackage{xcolor}
\usepackage[bookmarks=true,bookmarksopen=true,pdfstartview=FitH]{hyperref}
\usepackage[BoldFont,SlantFont,CJKnumber]{xeCJK}
\textheight 210mm
\textwidth 150mm
\oddsidemargin 0pt
\evensidemargin 0pt
\defaultfontfeatures{Ligatures=TeX}
\ifcsname CJKmainfont\endcsname
\else
  \def\CJKmainfont{AR PLBaosong2GBK Light}
\fi
\setCJKmainfont{\CJKmainfont}% 设置缺省中文字体
\setCJKmonofont*{\CJKmainfont}% 设置 中文字体
\setCJKfamilyfont{song}{\CJKmainfont}% 设置 中文字体
\def\xeCJK{{\textcolor{blue}{\texttt{xeCJK}}}}
% macros
{\catcode`\|=0 \catcode`\\=12
 |gdef|bslash{\}}

\newcommand{\defmacro}[1]{%                   % Define a macro.
 \textcolor{macrocolor}{\string#1}\index{\string\verb+\string#1+}%
}

\newcommand{\usemacro}[1]{%                   % Define a macro.
  \textcolor{macrocolor}{\string#1}%
  #1\index{\string\verb+\string#1+}%
}

\definecolor{parametercolor}{rgb}{1,0,1}
\definecolor{optioncolor}{rgb}{0,0,1}
\definecolor{macrocolor}{rgb}{0,0,0.63}

\newcommand{\usepmacro}[3][]{%
  \edef\tempa{#1}%
  \textcolor{macrocolor}{\string#2}%
  \string{\textcolor{parametercolor}{#3}\string}%
  \ifx\tempa\@empty\else (#1)\fi%
  #2{#3}\index{\string\verb+\string#2+}%
}

\newenvironment{decl}[1][]%
    {\par\small\addvspace{4.5ex plus 1ex}%
     \vskip -\parskip
     \ifx\relax#1\relax
        \def\@decl@date{}%
     \else
        \def\@decl@date{\NEWfeature{#1}}%
     \fi
     \noindent\hspace{-\leftmargini}%
     \begin{tabular}{|l|}\hline\ignorespaces}%
    {\\\hline\end{tabular}\nobreak\@decl@date\par\nobreak
     \vspace{2.3ex}\vskip -\parskip}

\renewcommand{\arg}[1]{{\ttfamily\string{}\meta{#1}{\ttfamily\string}}}
\renewcommand{\meta}[1]{\mbox{\color{parametercolor}$\langle$\itshape #1\/$\rangle$}}

\EnableCrossrefs
\CodelineIndex
\RecordChanges
\begin{document}
\ifxetex
  \DocInput{xeCJK.dtx}
  \makeatletter
  \c@IndexColumns = 2
  \PrintIndex
\else
  \makeatletter
  \@latex@error{Use XeLaTeX to compile this file.}
\fi
\end{document}
%</driver>
%
%<*xeCJK>
\def\fileversion{2.4.4}
\def\filedate{2011/09/17}
\ProvidesPackage{xeCJK}[\filedate\space\fileversion\space package for typesetting CJK scripts with XeLaTeX]
%</xeCJK>
%
% \fi
%
% \makeatletter                         ^^A% To document @-cmds
% \errorcontextlines=999                ^^A% Show up all my mistakes
%
% \GetFileInfo{xeCJK.sty}
%
% \title{\hypertarget{Chinese}{xeCJK 宏包}
%    \hbox to 0pt{\hskip 40mm\hyperlink{English}{\normalsize\texttt{English Version}}}
%    \\[1ex]
%    \normalsize 版本：\fileversion}
% \author{孙文昌}
% \date{\filedate}
% \maketitle
%
% \newpage
%
% \section{简介}
% \parindent 2em
% \parskip 5pt
%
% \xeCJK\  是一个 XeLaTeX 宏包，用于排版 CJK 文字，包括字体选择和标点控制等。主要特点：
% \begin{enumerate}
% \item 分别设置CJK和英文字体；
% \item 自动忽略CJK文字间的空格而保留其它空格，允许在非标点汉字和英文字母 (a-z, A-Z) 间断行；
% \item  提供多种标点处理方式： 全角式、半角式、开明式、行末半角式；
% \item 自动调整中英文间空白。
% \end{enumerate}
%
% \long\def\sometextsa{\xeCJK\ 是在CCT和CJK包基础上发展起来的，
% 支持多种标点格式。例如，“标点挤压”。\xeCJK\ 是在CCT和CJK包基础上
% 发展起来的，支持多种标点格式。例如，“标点挤压”。}
%
%
%  \usepmacro[全角式]{\punctstyle}{quanjiao}
%
%   \sometextsa
%
%  \usepmacro[半角式]{\punctstyle}{banjiao}
%
%   \sometextsa
%
%
%  \usepmacro[开明式]{\punctstyle}{kaiming}
%
%   \sometextsa
%
%  \usepmacro[行末半角式]{\punctstyle}{hangmobanjiao}
%
%   \sometextsa
%
% {\usepmacro[plain]{\punctstyle}{plain}
%
% \sometextsa}
%
% \punctstyle{kaiming}
%
% \section{使用方法}
%
% \xeCJK\  使用了 XeTeX 的一些最新特性， 需要 XeTeX 0.9995.0 [2009/06/29] 以后的版本。
%
%
%
% \begin{decl}
%    \defmacro{\usepackage}[\textcolor{optioncolor}{Options}]
%       \{\textcolor{parametercolor}{xeCJK}\}
% \end{decl}
%
% \begin{tabular}{ll}
%    宏包选项 & \\
%    BoldFont:&     启用CJK\textbf{粗体字}\\
%    SlantFont:&    启用 \textsl{斜体字slshape}\\
%    fallback: &    启用备用字体功能 \\
%    CJKnumber: &   调用CJKnumb宏包\\
%    CJKchecksingle: &避免单个汉字单独占一行\\
%    nospace: &     忽略 CJK 文字之间的空格（默认行为）\\
%    space: &       保留 CJK 文字之间的空格\\
% \end{tabular}
%
%
% \begin{decl}
%      \defmacro{\setCJKmainfont} [\textcolor{optioncolor}{<font features>}]\arg{font name}\\
%      \defmacro{\setCJKsansfont} [\textcolor{optioncolor}{<font features>}]\arg{font name}\\
%      \defmacro{\setCJKmonofont} [\textcolor{optioncolor}{<font features>}]\arg{font name}\\
%      \defmacro{\setCJKmonofont*} [\textcolor{optioncolor}{<font features>}]\arg{font name}\\
%      \defmacro{\setCJKmonofont+} [\textcolor{optioncolor}{<font features>}]\arg{font name}\\
%      \defmacro{\setCJKfamilyfont} \arg{family name}[\textcolor{optioncolor}
%                               {<font features>}]\arg{font name}\\
%      \defmacro{\setCJKfallbackfamilyfont} \arg{family name}
%        [\textcolor{optioncolor}{<font features>}]\arg{font name}
% \end{decl}
% 分别设置缺省 CJK 普通字体族、CJK 无衬线字体族、CJK 打字机字体族的各自所对应
% 中文字体，以及某个 CJK 族所对应的备用字体（通常用于生僻字）。其中最后两个参
% 数的意义请参考 \verb+fontspec+ 宏包。
%
% 定义CJK字体时指定的\texttt{ItalicFont=\{...\}}比宏包的
% \texttt{SlantFont}选项有更高的优先级。
% 类似地，可以指定\texttt{BoldFont=\{font name\}}以抑制
% \texttt{BoldFont}选项。
%
% 可以重定义 \defmacro{\CJKfamilydefault} 来修改普通字体的 CJK 字体族。其默认
% 值是默认的普通字体族 \defmacro{\CJKrmdefault}，即 \verb+rm+。可以重定义为无
% 衬线字体族的默认值 \defmacro{\CJKsfdefault}，即 \verb+sf+；或是打字机字体族
% 的 \defmacro{\CJKttdefault}，即 \verb+tt+。也可以改为其他自定义的字体族。例
% 如，在幻灯片中可以使用如下命令改用无衬线的汉字字体：
% \begin{verbatim}
% \renewcommand\CJKfamilydefault{\CJKsfdefault}
% \end{verbatim}
%
% \defmacro{\setCJKmonofont} 命令后面可以加上星号 |*| 或加号 |+|，分别表示使用
% 放缩的方式或改变间距的方式，让 CJK 字符的宽度等于西文字体中两个空格的宽度。
% 这有利于等宽字体的代码对齐等情形。
%
% \defmacro{\setCJKmonoscale} 和 \defmacro{\setCJKmonoexspace} 命令分别计算并设置
% 当前字号下西文等宽字体与 CJK 字体的放缩比例和字距，以符合上面加 |*| 与加 |+| 号
% 命令的意义。在字号改变时，应该使用两个命令之一；但注意两个命令不能同时使用。
%
% 与 CJK 包类似， 使用命令 \defmacro{\CJKfamily}\arg{family name} 改变当前中文字体。
%
%
% \subsection*{例子}
%
% 以下命令设置缺省英文字体为 TeX Gyre Termes, 缺省中文字体为 AR PLBaosong2GBK Light (文鼎ＰＬ报宋二\kern 0sp GBK)，
% 最后一个命令设置 CJKfamily “song”。
% \begin{verbatim}
% \setmainfont{TeX Gyre Termes}
% \setCJKmainfont{AR PLBaosong2GBK Light}
% \setCJKfamilyfont{song}{AR PLBaosong2GBK Light}
% \end{verbatim}
%
% \noindent
% 下表中， 左边为输入， 右边为排版效果：
%
% \begin{tabular}{ll}
% \verb+这是缺省字体 abCD+ &这是缺省字体 abCD\\
% \verb+\bfseries 这是缺省字体 abCD+ &{\bfseries 这是缺省字体 abCD}\\
% \verb+\itshape 这是缺省字体 abCD+ &{\itshape 这是缺省字体 abCD}\\
% \verb+\bfseries\itshape 这是缺省字体 abCD+ &\bfseries\itshape 这是缺省字体 abCD\\
% \\
% \verb+\CJKfamily{song}这是宋体+ &{\CJKfamily{song}这是宋体}\\
% \end{tabular}
%
%
%
%
%
% \section{高级设置}
%
% \begin{decl}
%  \defmacro{\punctstyle}\arg{punct style}
% \end{decl}
%
% 设置标点格式，有效值分别为
%
% \begin{tabular}{ll}
%   punct style & \\
%   \textcolor{parametercolor}{banjiao}      & 半角式：所有标点占半个汉字宽度。 \\
%   \textcolor{parametercolor}{quanjiao}     & 全角式：所有标点占一个汉字宽度，相邻两个标点占1.5汉字宽度。\\
%   \textcolor{parametercolor}{kaiming}      & 开明式：句末点号用全角，其他半角。\\
%   \textcolor{parametercolor}{hangmobanjiao}& 行末半角式：所有标点占一个汉字宽度，行首行末对齐。\\
%   \textcolor{parametercolor}{CCT}          & CCT格式\\
%   \textcolor{parametercolor}{plain}        & 原样（不调整标点间距）
% \end{tabular}
%
%
%
% \begin{decl}
% \defmacro{\xeCJKallowbreakbetweenpuncts} \\
% \defmacro{\xeCJKnobreakbetweenpuncts}
% \end{decl}
%
% 缺省状态下，\xeCJK\ 禁止在相邻的标点间换行。 使用
%
% \defmacro{\xeCJKallowbreakbetweenpuncts}\newline
% 改变这一设置。
%
% \begin{decl}
% \defmacro{\xeCJKsetslantfactor}\arg{slant factor}\\
% \defmacro{\xeCJKsetemboldenfactor}\arg{embolden factor}
% \end{decl}
% 分别设置斜体和粗体的倾斜和粗细程度。
% 其中 slant factor 的范围为 -0.999 $\sim$ 0.999. 缺省设置为
%
% \begin{verbatim}
%   \xeCJKsetslantfactor{0.17}
%   \xeCJKsetemboldenfactor{4}
% \end{verbatim}
%
% 注意，这两个宏命令仅对随后定义的 CJK 字体有效。
%
%
% \begin{decl}
% \defmacro{\CJKnospace}\\
% \defmacro{\CJKspace}
% \end{decl}
% \verb+\CJKnospace+ 忽略 CJK 文字之间的空格，这是默认行为，与 \verb+nospace+
% 选项相同。\verb+\CJKspace+ 保留 CJK 文字之间的空格，但仍然忽略文字与全角标点
% 间的空格，与宏包 \verb+space+ 选项相同。
%
%
% \begin{decl}
% \defmacro{\CJKsetecglue}
% \end{decl}
%
%
%
% \defmacro{\CJKsetecglue}: 设置中英文间距. 缺省值为\defmacro{\CJKsetecglue\{ \}}.
% 注意: 这个宏命令仅仅影响自动添加的空格.  源文件中直接输入的中英文之间的空格不受影响(直接输出).
% \bgroup\let\CJKecglue\relax
% \begin{verbatim}
% 这是 English 中文 \textit{Chinese} 中文  \LaTeX\
% 中文\textbf{字体} a {\bfseries 数学}  $c$ $d$-th\par
% 这是English中文\textit{Chinese}中文\LaTeX\
% 中文\textbf{字体}a{\bfseries 数学}$c$ $d$-th\par
% \end{verbatim}
% \egroup
%
% \noindent
% 排版效果：
%
% 这是 English 中文 \textit{Chinese} 中文  \LaTeX\
% 中文\textbf{字体} a {\bfseries 数学}  $c$ $d$-th\par
% 这是English中文\textit{Chinese}中文\LaTeX\
% 中文\textbf{字体}a{\bfseries 数学}$c$ $d$-th\par
%
% 说明：
% \begin{enumerate}
%
% \item 中英文之间的空格会保留(不能调整)，
% 但若没有空格，则会根据需要添加(见上面的例子)。
%
% 有时可能无效，
%   解决方案是手动加空格。
%\end{enumerate}
%
%
% \begin{decl}
% \defmacro{\xeCJKenablefallback}\\
% \defmacro{\xeCJKdisablefallback}
% \end{decl}
% 打开或关闭备用字体功能。
%
%
% \begin{decl}
% \defmacro{\xeCJKsetcharclass}\arg{first}\arg{last}\arg{class}
% \end{decl}
%
% 该命令将设定 Unicode 范围 \meta{first}--\meta{last} 的字符类别为
% \meta{class}。
%
% 类别 0 表示一般西文符号，使用西文字体；类型 1 表示一般 CJK 表意符号，使用
% CJK 字体。默认只将 Unicode 区的 CJK 文字和标点使用 CJK 字体，字符类别的详细
% 说明及缺省状态下的设置见源代码第~\ref{sec:charclass}~节。
%
% 例如，以下命令设置 0x0080 --- 0x2FFF 之间的字符为非 CJK 文字，而 0x20000
%  --- 0x30000 之间的为 CJK 文字：
% \begin{verbatim}
%   \xeCJKsetcharclass{"80}{"2FFF}{0}
%   \xeCJKsetcharclass{"20000}{"30000}{1}
% \end{verbatim}
% 注意：最后一个参数只能为 0 或 1，且设定对预定义的标点符号无效。不要轻易改变
% 字符类别。
%
%
% \begin{decl}
% \defmacro{\xeCJKcaption}[\textcolor{optioncolor}{<encoding>}]\arg{caption}
% \end{decl}
%
% 与 \verb+\CJKcaption+ 类似，可选参数用以选择编码， 缺省为 UTF-8。
%
% \begin{decl}
% \defmacro{\xeCJKsetkern}\arg{标点1}\arg{标点2}\arg{kern}
% \end{decl}
%
% 如果对缺省配置不满意，可以使用此命令设置两个标点之间的距离。例如，
%
%  \verb+\xeCJKsetkern{：}{“}{0.3em}+
%
% \begin{decl}
% \defmacro{\normalspacedchars}\arg{char list}
% \end{decl}
%    在<char list>中出现的字符两端不自动添加空格.
%
%
% \begin{decl}
% \defmacro{\makexeCJKactive}\\
% \defmacro{\makexeCJKinactive}
% \end{decl}
%    打开/关闭对中文的特殊处理.
%
% \section{兼容性}
%
% \subsection{CJKfntef}
% 可以在 \xeCJK\  包之后调入 CJKfntef 宏包， 以实现汉字加点等。
%
% \subsection{CJKnumber}
%
% \verb+\CJKnumber{12345}+:  \CJKnumber{12345}
%
% \subsection{CJK}
% 为了与 CJKnumb 和  CJKulem  包兼容，\xeCJK\  重新定义了 CJK 包的部分宏命令，如
% \verb+\CJKfamily+, \verb+\CJKsymbol+, \verb+\CJKpunctsymbol+ 等。
%
% 需要指出，\xeCJK\  包不需要 CJK 包的支持，并且 \xeCJK\  包自动禁止载入 CJK 包。
%
%
% \title{ \hypertarget{English}{The xeCJK Package}
%   \hbox to 0pt{\hskip 40mm\hyperlink{Chinese}{\normalsize 中文版}}\\[1ex]
%   \normalsize Ver. \fileversion}
% \author{Wenchang Sun}
% \date{\filedate}
% \maketitle
%
% \newpage
%
% \section{Main features}
% The package \xeCJK\ allows XeLaTeX users to typeset CJK scripts easily.
%
%
% \begin{enumerate}
% \item different default fonts for CJK and other characters;
% \item spaces automatically ignored between CJK characters;
% \item special effects on full-width CJK punctuation; and
% \item automatic adjustment of the space between CJK and other characters.
% \end{enumerate}
%
% \section{Usage}
%
% To use \xeCJK, one need some version of XeTeX after [2008/03/07].
%
% \begin{decl}
%    \defmacro{\usepackage}[\textcolor{optioncolor}{Options}]
%       \{\textcolor{parametercolor}{xeCJK}\}
% \end{decl}
%
% \def\arraystretch{1.5}
% \begin{tabular}{lp{90mm}}
%    Options & \\
%    BoldFont:  &  Create "synthetic bold" fonts for CJK characters.
%                   Will be overridden by specifying {BoldFont}
%                   in the definition of a CJK family.
% \\
%   SlantFont: &    Create slanted fonts for CJK characters.
%                   Will be overridden by specifying {ItalicFont}
%                   in the definition of a CJK family.
% \\
%  CJKnumber:  & Load the CJKnumb package.
% \\
%  CJKchecksingle: & Prevent last line with only one CJK character\\
%  nospace: &      Ignore spaces between CJK ideographs\\
%  space: &        Do not ignore spaces between CJK ideographs\\
% \end{tabular}
%
%
%
% \begin{decl}
%      \defmacro{\setCJKmainfont} [\textcolor{optioncolor}{<font features>}]\arg{font name}\\
%      \defmacro{\setCJKsansfont} [\textcolor{optioncolor}{<font features>}]\arg{font name}\\
%      \defmacro{\setCJKmonofont} [\textcolor{optioncolor}{<font features>}]\arg{font name}\\
%      \defmacro{\setCJKmonofont*} [\textcolor{optioncolor}{<font features>}]\arg{font name}\\
%      \defmacro{\setCJKmonofont+} [\textcolor{optioncolor}{<font features>}]\arg{font name}\\
%      \defmacro{\setCJKfamilyfont} \arg{family name}[\textcolor{optioncolor}
%                               {<font features>}]\arg{font name}\\
%      \defmacro{\setCJKfallbackfamilyfont} \arg{family name}
%        [\textcolor{optioncolor}{<font features>}]\arg{font name}
% \end{decl}
%
% The first three macros are analogs of
% \begin{quote}
% \defmacro{\setmainfont}, \defmacro{\setsansfont}, and \defmacro{\setmonofont},
% \end{quote}
% respectively.
% The only difference is that they effect only CJK characters.
%
% The last two macros set the primary font and fallback font for a CJK family
% which will be called by
% \begin{quote}
%   \defmacro{\CJKfamily}\arg{family name}.
% \end{quote}
% With these macros, one can set different default fonts for CJK and other characters,
% respectively.
%
% For a full description on the parameters \textcolor{optioncolor}{<font features>}
%  and \arg{font name},
% we refer to the package \verb+fontspec+.
%
% Threr are \defmacro{\CJKfamilydefault}, \defmacro{\CJKrmdefault},
% \defmacro{\CJKsfdefault} and \defmacro{\CJKttdefault}, which correspond to
% \verb+\familydefault+, \verb+\rmdefault+, \verb+\sfdefault+ and
% \verb+\ttdefault+. For example, one can select sans serief CJK font for
% slides:
% \begin{verbatim}
% \renewcommand\CJKfamilydefault{\CJKsfdefault}
% \end{verbatim}
%
% \defmacro{\setCJKmonofont} can be appended with a |*| or |+| symbol. They make sure
% that the width of a CJK glyph equals to 2 space for monospace fonts, by scaling and
% spacing, respectively.
%
% \defmacro{\setCJKmonoscale} and \defmacro{\setCJKmonoexspace} reset the scale and extra
% space introduced by |\setCJKmainfont*| and |\setCJKmonofont+|, respectively. They are
% useful when changing the font size.
%
% \section{Advanced settings}
%
%
%
% \begin{decl}
%  \defmacro{\punctstyle}\arg{punct style}
% \end{decl}
%
% Set the CJK punctuation style.  \xeCJK\ predefines several styles for typesetting full-width punctuation.
%
%
% \begin{tabular}{lp{60mm}}
% style& \\
% \textcolor{parametercolor}{quanjiao} or \textcolor{parametercolor}{fullwidth}& typeset all punctuation in full-width,
%             for two adjoint punctuation, the first is typeset
%             in half-width.
% \\
% \textcolor{parametercolor}{banjiao} or \textcolor{parametercolor}{halfwidth}& typeset all punctuation in half-width.
% \\
% \textcolor{parametercolor}{kaiming} or \textcolor{parametercolor}{mixedwidth}& typeset all punctuation in half-width except
%             the period, question, and exclamation marks.\\
%  \textcolor{parametercolor}{hangmobanjiao} or \textcolor{parametercolor}{marginkerning} &  typeset punctuation at the end of lines in half-width.
% \end{tabular}
%
%
%
%
%
% \begin{decl}
% \defmacro{\xeCJKallowbreakbetweenpuncts} \\
% \defmacro{\xeCJKnobreakbetweenpuncts}
% \end{decl}
%
% By default, \xeCJK\ prohibits line breaks between punctuation. Use
%
% \defmacro{\xeCJKallowbreakbetweenpuncts}\newline
% to make it breakable.
%
%
% \begin{decl}
% \defmacro{\xeCJKsetslantfactor}\arg{slant factor}\\
% \defmacro{\xeCJKsetemboldenfactor}\arg{embolden factor}
% \end{decl}
% Set slant and embolden factors, respectively. The default settings are
% \begin{verbatim}
%   \xeCJKsetslantfactor{0.17}
%   \xeCJKsetemboldenfactor{4}
% \end{verbatim}
%
% Note that both macros effect only CJK families defined after them.
%
%
% \begin{decl}
% \defmacro{\CJKnospace}\\
% \defmacro{\CJKspace}
% \end{decl}
% \verb+\CJKnospace+ ignores spaces between CJK ideographs, see also
% \verb+nospace+ option. \verb+\CJKspace+ reserves the spaces.
%
%
% \begin{decl}
% \defmacro{\xeCJKenablefallback}\\
% \defmacro{\xeCJKdisablefallback}
% \end{decl}
% Enable or disable fallback fonts for CJK families.
%
%
% \section{Compatibility}
%
% \subsection{CJK}
% To be compatible with some CJK-related packages \texttt{CJKnumb}
%  and \texttt{CJKulem}, \xeCJK\ re-defines some macros in the package \texttt{CJK}
% and it is not compatible with the later.
% In fact, \xeCJK\ prevents automatically from loading \texttt{CJK} after \xeCJK.
% \StopEventually{}
%
% \clearpage
% \part{xeCJK.sty}
% \section{宏包选项与内部工具}
%
% \iffalse
%<*xeCJK>
% \fi
% \fontsize{10pt}{10pt}\selectfont
% \xeCJK\ 只能在XeLaTeX中使用
%    \begin{macrocode}
\RequirePackage{ifxetex}
\RequireXeTeX
%    \end{macrocode}
% 禁止在\xeCJK\ 之后调入CJK包。
%    \begin{macrocode}
\expandafter\def\csname ver@CJK.sty\endcsname{2020/01/01}

\newif\ifxeCJK@SlantFont@

\newif\ifxeCJK@BoldFont@

\newif\ifxeCJK@fallback@

\newif\ifxeCJK@num

\newif\ifxeCJK@checksingle

\newif\ifxeCJK@indentfirst
\xeCJK@indentfirsttrue

\newif\ifxeCJK@space@
\xeCJK@space@false

\DeclareOption{boldfont}{\xeCJK@BoldFont@true}
\DeclareOption{BoldFont}{\ExecuteOptions{boldfont}}
\DeclareOption{slantfont}{\xeCJK@SlantFont@true}
\DeclareOption{SlantFont}{\ExecuteOptions{slantfont}}
\DeclareOption{fallback}{\xeCJK@fallback@true}
\DeclareOption{CJKnumber}{\xeCJK@numtrue}
\DeclareOption{normalindentfirst}{\xeCJK@indentfirstfalse}
\DeclareOption{CJKchecksingle}{\AtEndOfPackage{\let\xeCJK@i@i\xeCJK@checksingle}}
\DeclareOption{space}{\xeCJK@space@true}
\DeclareOption{nospace}{\xeCJK@space@false}

\DeclareOption{CJKnormalspaces}{\PackageWarning{xeCJK}{%
  obsolete option 'CJKnormalspaces'. It may be removed in the future.}}
\DeclareOption{CJKaddspaces}{\PackageWarning{xeCJK}{%
  obsolete option 'CJKaddspaces'. It may be removed in the future.}}
\DeclareOption{CJKtextspaces}{\PackageWarning{xeCJK}{%
  obsolete option 'CJKtextspaces'. It may be removed in the future.}}
\DeclareOption{CJKmathspaces}{\PackageWarning{xeCJK}{%
  obsolete option 'CJKmathspaces'. It may be removed in the future.}}
\DeclareOption{CJKsetspaces}{\PackageWarning{xeCJK}{%
  obsolete option 'CJKsetspaces'. It may be removed in the future.}}
\DeclareOption{CJKnospaces}{\PackageWarning{xeCJK}{%
  obsolete option 'CJKnospaces'. It may be removed in the future.}}

\DeclareOption*{\PassOptionsToPackage{\CurrentOption}{fontspec}}
\ProcessOptions\relax

\RequirePackage{xkeyval}
\RequirePackage{expl3}
\RequirePackage{fontspec}

\ifxeCJK@indentfirst
  \let\@afterindentfalse\relax
\fi
%    \end{macrocode}
% 抑制换行符产生的空格
%    \begin{macrocode}
\endlinechar \m@ne
%    \end{macrocode}
%
% 给已有宏内容前后附加补丁
%    \begin{macrocode}
\def\xeCJK@patch#1#2#3{
  \edef#1{
    \unexpanded{#2}
    \unexpanded\expandafter{#1}
    \unexpanded{#3}}}
%    \end{macrocode}
% \section{字符类别设定}
% \label{sec:charclass}
% \xeCJK{} 功能开关
%    \begin{macrocode}
\def\makexeCJKactive{
  \XeTeXinterchartokenstate=1\relax}

\def\makexeCJKinactive{
  \XeTeXinterchartokenstate=0\relax}

\makexeCJKactive
%    \end{macrocode}
% 设定字符类别：
% \begin{center}
% \begin{tabular}{cll}
% \hline
% 编号 & 类别 & 例子 \\
% \hline
% 0 & 西文一般符号 & abc \\
% 1 & CJK 表意符号 & 汉字ぁぃぅ \\
% 2 & 全角左标点 & （《“ \\
% 3 & 全角右标点 & ，。）》” \\
% 4 & 半角左标点 & ( [ \{ \\
% 5 & 半角右标点 & , . ? ) ] \} \\
% 6 & 前后原始间距的符号 & / \\
% \hline
% \end{tabular}
% \end{center}
%    \begin{macrocode}
\def\xeCJKsetcharclass#1#2#3{
  \@tempcnta=#1
  \loop
    \XeTeXcharclass \@tempcnta #3\relax
    \advance\@tempcnta 1\relax
    \unless\ifnum\the\@tempcnta>#2 \repeat
  \xeCJK@setpunctcharclass}

\def\xeCJK@prePunct#1#2{\xeCJK@setPunct{2}{#1}{#2}}
\def\xeCJK@postPunct#1#2{\xeCJK@setPunct{3}{#1}{#2}}

\def\xeCJK@setPunct#1#2#3{
  \def\xeCJK@class{#1}
  \@tempcnta "#2\relax
  \multiply\@tempcnta 256\relax
  \xeCJK@setPunct@#3,,}

\def\xeCJK@setPunct@#1,{
  \edef\xeCJK@temp{#1}%
  \ifx\xeCJK@temp\@empty
  \else
     \@tempcntb "#1\relax
     \advance\@tempcntb\@tempcnta\relax
     \XeTeXcharclass \@tempcntb=\xeCJK@class\relax
     \def\xeCJK@temp{\xeCJK@setPunct@}
  \fi
  \xeCJK@temp}

\def\xeCJK@setpunctcharclass{
  \xeCJK@prePunct{20}{18,1C}
  \xeCJK@postPunct{20}{19,1D,14,26}
  \xeCJK@postPunct{25}{00}
  \xeCJK@prePunct{30}{08,0A,0C,0E,10,12,14,16,18,1A,1D,1F,36}

  \xeCJK@postPunct{30}{01,02,05,06,09,0B,0D,0F,11,15,17,19,1B,1E,
                       41,43,45,47,49,63,83,85,87,8E,
                       9B,9C,9D,9E,A1,A3,A5,A7,A9,C3,E3,E5,E7,EE,F5,F6,FB,FC,FD,FE}
  \xeCJK@prePunct {FE}{59,5B,5D,5F,60,69,6B}
  \xeCJK@postPunct{FE}{50,51,52,54,55,56,57,5A,5C,5E,6A}
  \xeCJK@prePunct {FF}{03,04,08,20,3B,5B,E0,E1,E5,E6}
  \xeCJK@postPunct{FF}{01,05,09,0C,0E,1A,1B,1F,3D,5D,
                       61,63,64,65,67,68,69,6A,6B,6C,6D,6E,6F,70,9E,9F}

  \xeCJK@setPunct{1}{0}{B7}
  \xeCJK@setPunct{4}{0}{28,2D,5B,60,7B}
  \xeCJK@setPunct{5}{0}{21,22,25,27,29,2C,2E,3A,3B,3F,5D,7D}}

%    \end{macrocode}
%
% 以下 Uncode 范围数据取自 fontwrap 宏包：
% \begin{itemize}
% \item Hangul Jamo
%    \begin{macrocode}
\xeCJKsetcharclass{"1100}{"11FF}{1}
%    \end{macrocode}
% \item[] 以下 |"2E80|--|"4DBF| 连续
% \item CJK Radicals Supplement
%    \begin{macrocode}
\xeCJKsetcharclass{"2E80}{"2EFF}{1}
%    \end{macrocode}
% \item Kangxi Radicals
%    \begin{macrocode}
\xeCJKsetcharclass{"2F00}{"2FDF}{1}
%    \end{macrocode}
% \item Ideographic Description Characters
%    \begin{macrocode}
\xeCJKsetcharclass{"2FF0}{"2FFF}{1}
%    \end{macrocode}
% \item CJK Symbolsand Punctuation
%    \begin{macrocode}
\xeCJKsetcharclass{"3000}{"303F}{1}
%    \end{macrocode}
% \item Hiragana
%    \begin{macrocode}
\xeCJKsetcharclass{"3040}{"309F}{1}
%    \end{macrocode}
% \item Katakana
%    \begin{macrocode}
\xeCJKsetcharclass{"30A0}{"30FF}{1}
%    \end{macrocode}
% \item Bopomofo
%    \begin{macrocode}
\xeCJKsetcharclass{"3100}{"312F}{1}
%    \end{macrocode}
% \item Hangul Compatibility Jamo
%    \begin{macrocode}
\xeCJKsetcharclass{"3130}{"318F}{1}
%    \end{macrocode}
% \item Kanbun
%    \begin{macrocode}
\xeCJKsetcharclass{"3190}{"319F}{1}
%    \end{macrocode}
% \item Bopomofo Extended
%    \begin{macrocode}
\xeCJKsetcharclass{"31A0}{"31BF}{1}
%    \end{macrocode}
% \item CJK Strokes
%    \begin{macrocode}
\xeCJKsetcharclass{"31C0}{"31EF}{1}
%    \end{macrocode}
% \item Katakana Phonetic Extensions
%    \begin{macrocode}
\xeCJKsetcharclass{"31F0}{"31FF}{1}
%    \end{macrocode}
% \item Enclosed CJK Letters and Months
%    \begin{macrocode}
\xeCJKsetcharclass{"3200}{"32FF}{1}
%    \end{macrocode}
% \item CJK Compatibility
%    \begin{macrocode}
\xeCJKsetcharclass{"3300}{"33FF}{1}
%    \end{macrocode}
% \item CJKUnified Ideographs Extension A
%    \begin{macrocode}
\xeCJKsetcharclass{"3400}{"4DBF}{1}
%    \end{macrocode}
% \item[] 以下块不连续
% \item CJK Unified Ideographs
%    \begin{macrocode}
\xeCJKsetcharclass{"4E00}{"9FFF}{1}
%    \end{macrocode}
% \item Yi
%    \begin{macrocode}
\xeCJKsetcharclass{"A000}{"A4CF}{1}
%    \end{macrocode}
% \item Hangul Syllables
%    \begin{macrocode}
\xeCJKsetcharclass{"AC00}{"D7AF}{1}
%    \end{macrocode}
% \item CJK Compatibility Ideographs
%    \begin{macrocode}
\xeCJKsetcharclass{"F900}{"FAFF}{1}
%    \end{macrocode}
% \item CJK Compatibility Forms
%    \begin{macrocode}
\xeCJKsetcharclass{"FE30}{"FE4F}{1}
%    \end{macrocode}
% \item Halfwidth and Fullwidth Forms
%    \begin{macrocode}
\xeCJKsetcharclass{"FF00}{"FFEF}{1}
%    \end{macrocode}
% \item CJK Unified Ideographs Extension B
%    \begin{macrocode}
\xeCJKsetcharclass{"20000}{"2A6DF}{1}
%    \end{macrocode}
% \item CJK Unified Ideographs Extension C
%    \begin{macrocode}
\xeCJKsetcharclass{"2A700}{"2B73F}{1}
%    \end{macrocode}
% \item CJK Unified Ideographs Extension D
%    \begin{macrocode}
\xeCJKsetcharclass{"2B740}{"2B81F}{1}
%    \end{macrocode}
% \item CJK Compatibility Ideographs Supplement
%    \begin{macrocode}
\xeCJKsetcharclass{"2F800}{"2FA1F}{1}
%    \end{macrocode}
% \end{itemize}
%    \begin{macrocode}

\def\CJK@stop{\CJK@stop}

\def\normalspacedchars#1{
  \xeCJK@setnormalspacedchar#1\CJK@stop}

\def\xeCJK@setnormalspacedchar#1{
  \ifx#1\CJK@stop
  \else
    \XeTeXcharclass`#1=6
    \expandafter\xeCJK@setnormalspacedchar
  \fi}

\normalspacedchars{/}

%    \end{macrocode}
%
% 单独处理宽度有分歧的两个标点：省略号和间隔号。保证其命令形式输出的是西文字体。
% 并对间隔号（U+00B7）为一些编码的符号宏包做特殊处理：
%    \begin{macrocode}
\AtBeginDocument{%
  \xeCJK@patch\textellipsis       {\begingroup\makexeCJKinactive}{\endgroup}
  \xeCJK@patch\textperiodcentered {\begingroup\makexeCJKinactive}{\endgroup}
  \xeCJK@patch\textcentereddot    {\begingroup\makexeCJKinactive}{\endgroup}
  \xeCJK@patch\tipaencoding      {\makexeCJKinactive}{} % tipa package in T3 encoding
  \let\xeCJK@save@r\r
  \def\r#1{{\makexeCJKinactive\xeCJK@save@r{#1}}} % \r{u} in T1 encoding
  \@ifpackageloaded{pifont}{ % pifont package in U encoding
    \renewcommand\Pifont[1]{\fontfamily{#1}\fontencoding{U}%
      \fontseries{m}\fontshape{n}\selectfont\makexeCJKinactive}}{}
}
%    \end{macrocode}
%
% \section{字符输出规则}
%    \begin{macrocode}
\XeTeXinterchartoks 1 0{\egroup\CJKecglue}
\XeTeXinterchartoks 1 1{\xeCJK@i@i}
\XeTeXinterchartoks 1 2{\xeCJK@i@ii}
\XeTeXinterchartoks 1 3{\xeCJK@i@iii}
\XeTeXinterchartoks 1 4{\egroup\CJKecglue}
\XeTeXinterchartoks 1 5{\egroup}
\XeTeXinterchartoks 1 255{\xeCJK@i@cclv}

\XeTeXinterchartoks 2 0{\xeCJK@ii@}
\XeTeXinterchartoks 2 1{\xeCJK@ii@i}
\XeTeXinterchartoks 2 2{\xeCJK@ii@ii}
\XeTeXinterchartoks 2 3{\xeCJK@ii@iii}
\XeTeXinterchartoks 2 4{\xeCJK@ii@iv}
\XeTeXinterchartoks 2 5{\xeCJK@ii@v}
\XeTeXinterchartoks 2 255{\xeCJK@ii@cclv}

\XeTeXinterchartoks 3 0{\xeCJK@iii@}
\XeTeXinterchartoks 3 1{\xeCJK@iii@i}
\XeTeXinterchartoks 3 2{\xeCJK@iii@ii}
\XeTeXinterchartoks 3 3{\xeCJK@iii@iii}
\XeTeXinterchartoks 3 4{\xeCJK@iii@iv}
\XeTeXinterchartoks 3 5{\xeCJK@iii@v}
\XeTeXinterchartoks 3 255{\xeCJK@iii@cclv}

\XeTeXinterchartoks 0 1{\xeCJK@@i}
\XeTeXinterchartoks 0 2{\xeCJK@@ii}
\XeTeXinterchartoks 0 3{\xeCJK@@iii}
\XeTeXinterchartoks 0 255{\xeCJK@@cclv}

\XeTeXinterchartoks 4 1{\xeCJK@iv@i}
\XeTeXinterchartoks 4 2{\xeCJK@iv@ii}
\XeTeXinterchartoks 4 3{\xeCJK@iv@iii}

\XeTeXinterchartoks 5 1{\xeCJK@v@i}
\XeTeXinterchartoks 5 2{\xeCJK@v@ii}
\XeTeXinterchartoks 5 3{\xeCJK@v@iii}
\XeTeXinterchartoks 5 255{\xeCJK@v@cclv}

\XeTeXinterchartoks 255 0{\xeCJK@cclv@}
\XeTeXinterchartoks 255 1{\xeCJK@cclv@i}
\XeTeXinterchartoks 255 2{\xeCJK@cclv@ii}
\XeTeXinterchartoks 255 3{\xeCJK@cclv@iii}
\XeTeXinterchartoks 255 4{\xeCJK@cclv@iv}

\XeTeXinterchartoks 1 6{\xeCJK@i@vi}
\XeTeXinterchartoks 2 6{\xeCJK@ii@vi}
\XeTeXinterchartoks 3 6{\xeCJK@iii@vi}
\XeTeXinterchartoks 6 1{\xeCJK@vi@i}
\XeTeXinterchartoks 6 2{\xeCJK@vi@ii}
\XeTeXinterchartoks 6 3{\xeCJK@vi@iii}

\def\xeCJK@vi@i{
  \bgroup
  \xeCJK@emptyCJKtoks
  \xeCJK@setfont
  \CJKsymbol}

\def\xeCJK@i@vi{
  \egroup}

\let\xeCJK@ii@vi \xeCJK@i@vi
\let\xeCJK@iii@vi\xeCJK@i@vi

\let\xeCJK@vi@ii \xeCJK@vi@i
\let\xeCJK@vi@iii\xeCJK@vi@i

\def\xeCJK@i@i{
  \CJKglue
  \CJKsymbol}

\def\xeCJK@i@ii#1{
  \xeCJK@punctrule{#1}{l}
  \hskip \csname xeCJK\xeCJK@punctstyle\xeCJK@bboxname @lglue@#1\endcsname
    plus 0.1em minus 0.1 em
  \xeCJK@setprepunct{#1}}

\def\xeCJK@i@iii#1{
  \xeCJK@punctrule{#1}{r}
  \ifcsname xeCJK@specialpunct#1\endcsname
    \CJKglue % breakable
  \else
    \nobreak
  \fi
  \global\edef\xeCJK@lastpunct{#1}
  \CJKpunctsymbol{#1}}

\def\xeCJK@setprepunct#1{
  \edef\xeCJK@lastpunct{#1}
  \vrule width \csname xeCJK\xeCJK@punctstyle\xeCJK@bboxname
    @lrule@#1\endcsname depth \z@ height \z@
  \CJKpunctsymbol{#1}}

\def\xeCJK@i@cclv{
  \egroup
  {\xeCJK@CJKkern}
  \xeCJK@ignorespaces}

\def\xeCJK@ii@i{
  \nobreak
  \CJKsymbol}

\def\xeCJK@ii@ii#1{
  \nobreak
  \xeCJK@punctrule{#1}{l}
  \xeCJK@setkern{\xeCJK@lastpunct}{#1}
  \kern \csname xeCJK\xeCJK@punctstyle\xeCJK@bboxname @kern\xeCJK@lastpunct#1\endcsname
  \xeCJK@setprepunct{#1}}

\def\xeCJK@ii@iii#1{
  \nobreak
  \xeCJK@punctrule{#1}{r}
  \xeCJK@setkern{\xeCJK@lastpunct}{#1}
  \kern \csname xeCJK\xeCJK@punctstyle\xeCJK@bboxname @kern\xeCJK@lastpunct#1\endcsname
  \nobreak
  \edef\xeCJK@lastpunct{#1}
  \CJKpunctsymbol{#1}}

\def\xeCJK@ii@{
  \nobreak
  \egroup}

\let\xeCJK@ii@iv\xeCJK@ii@
\let\xeCJK@ii@v\xeCJK@ii@

\def\xeCJK@ii@cclv{
  \nobreak
  \egroup
  \ignorespaces}

\def\xeCJK@iii@{
  \xeCJK@afterpostpunct
  \egroup}

\def\xeCJK@iii@i{
  \xeCJK@afterpostpunct
  \CJKsymbol}

\def\xeCJK@iii@ii#1{
  \vrule width \csname xeCJK\xeCJK@punctstyle\xeCJK@bboxname
     @rrule@\xeCJK@lastpunct\endcsname depth \z@ height \z@
  \xeCJK@punctrule{#1}{l}
  \xeCJK@setkern{\xeCJK@lastpunct}{#1}
  \kern \csname xeCJK\xeCJK@punctstyle\xeCJK@bboxname @kern\xeCJK@lastpunct#1\endcsname
  \xeCJKpunctnobreak
  \xeCJK@setprepunct{#1}}

\def\xeCJK@iii@iii#1{
  \vrule width \csname xeCJK\xeCJK@punctstyle\xeCJK@bboxname
     @rrule@\xeCJK@lastpunct\endcsname depth \z@ height \z@
  \xeCJK@punctrule{#1}{r}
  \xeCJK@setkern{\xeCJK@lastpunct}{#1}
  \kern \csname xeCJK\xeCJK@punctstyle\xeCJK@bboxname @kern\xeCJK@lastpunct#1\endcsname
  \nobreak
  \edef\xeCJK@lastpunct{#1}
  \CJKpunctsymbol{#1}}

\def\xeCJK@iii@iv{
  \xeCJK@afterpostpunct
  \egroup}

\def\xeCJK@afterpostpunct{
  \vrule width \csname xeCJK\xeCJK@punctstyle\xeCJK@bboxname
     @rrule@\xeCJK@lastpunct\endcsname depth \z@ height \z@
  \hskip \csname xeCJK\xeCJK@punctstyle\xeCJK@bboxname @rglue@\xeCJK@lastpunct\endcsname
    plus 0.1em minus 0.1 em}
\let\xeCJK@iii@v\xeCJK@iii@iv

\def\xeCJK@iii@cclv{
    \xeCJK@afterpostpunct
    \egroup
    \ignorespaces}

\def\xeCJK@@i{
  \CJKecglue
  \bgroup
  \xeCJK@setfont
  \xeCJK@emptyCJKtoks
  \CJKsymbol}

\def\xeCJK@@ii{
  \bgroup
  \xeCJK@setfont
  \XeTeXinterchartoks 0   2{\relax}
  \xeCJK@emptyCJKtoks
  \xeCJK@i@ii}

\def\xeCJK@@iii{
  \bgroup
  \xeCJK@setfont
  \XeTeXinterchartoks 0   3{\relax}
  \xeCJK@emptyCJKtoks
  \xeCJK@i@iii}

\def\xeCJK@iv@i{
  \bgroup
  \xeCJK@setfont
  \XeTeXinterchartoks 4 1{\relax}
  \xeCJK@emptyCJKtoks
  \CJKsymbol}

\def\xeCJK@iv@ii{
  \bgroup
  \xeCJK@setfont
  \XeTeXinterchartoks 4 2{\relax}
  \xeCJK@emptyCJKtoks
  \xeCJK@i@ii}

\def\xeCJK@iv@iii{
  \bgroup
  \xeCJK@setfont
  \XeTeXinterchartoks 4 3{\relax}
  \xeCJK@emptyCJKtoks
  \xeCJK@i@iii}

\def\xeCJK@v@i{
  \CJKecglue
  \bgroup
  \xeCJK@setfont
  \xeCJK@emptyCJKtoks
  \CJKsymbol}

\def\xeCJK@v@ii{
  \bgroup
  \xeCJK@setfont
  \XeTeXinterchartoks 5 2{\relax}
  \xeCJK@emptyCJKtoks
  \xeCJK@i@ii}

\def\xeCJK@v@iii{
  \bgroup
  \xeCJK@setfont
  \XeTeXinterchartoks 5 3{\relax}
  \xeCJK@emptyCJKtoks
  \xeCJK@i@iii}

\def\xeCJK@emptyCJKtoks{
  \XeTeXinterchartoks 255 1{\relax}
  \XeTeXinterchartoks 255 2{\relax}
  \XeTeXinterchartoks 255 3{\relax}}

\def\xeCJK@@cclv{
  \futurelet\xeCJK@nexttoken\xeCJK@zz@cclv}

\def\xeCJK@zz@cclv{
  \ifx\xeCJK@nexttoken\@sptoken
  \else
    {\xeCJK@zerokern}
  \fi}

\let\xeCJK@v@cclv\xeCJK@@cclv

\def\xeCJK@cclv@{
  \ifnum\lastkern=\@ne
    \@sptoken%\CJKecglue
  \fi}
\let\xeCJK@cclv@iv\xeCJK@cclv@

\def\xeCJK@cclv@i{{
  \ifnum\lastkern=\@ne
    \CJKglue
  \else
    \ifnum\lastkern=\xeCJK@four
      \@sptoken%\CJKecglue
    \else
      \ifnum\lastnodetype=\xeCJK@ten
        \CJKecglue
      \fi
    \fi
  \fi}
  \bgroup

  \xeCJK@emptyCJKtoks
  \xeCJK@setfont
  \CJKsymbol}

\def\xeCJK@cclv@ii{
  \bgroup
  \xeCJK@emptyCJKtoks
  \xeCJK@setfont
  \xeCJK@i@ii}

\def\xeCJK@cclv@iii{
  \bgroup
  \xeCJK@emptyCJKtoks
  \xeCJK@setfont
  \xeCJK@i@iii}

\def\CJKglue{\hskip \z@ \@plus .08\baselineskip}
\def\CJK@nobreakglue{\nobreak\CJKglue\nobreak}

\edef\xeCJK@CJKkern{\kern -1sp\kern 1sp}
\edef\xeCJK@prepunctkern{\kern -2sp\kern 2sp}
\edef\xeCJK@zerokern{\kern -4sp\kern 4sp}

\chardef\xeCJK@four=4
\chardef\xeCJK@ten=10

%    \end{macrocode}
%
% 处理省略 CJK 文字间空格的代码。\verb+\CJKspace+ 保留 CJK 文字之间的空格（仍
% 忽略标点相关空格）；\verb+\CJKnospace+ 忽略 CJK 文字之间的空格。默认使用
% \verb+\CJKnospace+。
%    \begin{macrocode}
\def\CJKspace{\let\xeCJK@ignorespaces\@empty}
\def\CJKnospace{\let\xeCJK@ignorespaces\xeCJK@@ignorespaces}
\ifxeCJK@space@
  \AtEndOfPackage{\CJKspace}
\else
  \AtEndOfPackage{\CJKnospace}
\fi

\def\xeCJK@@ignorespaces{
  \futurelet\xeCJK@nexttoken\xeCJK@checknext}

\def\xeCJK@checknext{
  \ifx\xeCJK@nexttoken\@sptoken
    \expandafter\xeCJK@@checknext
  \else
    \ifx $\xeCJK@nexttoken
      \CJKecglue
    \fi
  \fi}

{
  \def\:{\xeCJK@@checknext}
  \global\expandafter\def\: {\futurelet\@let@token\xeCJK@@@checknext}
}

\def\xeCJK@@@checknext{
  \ifx $\@let@token
    \@sptoken%\CJKecglue
  \else
    \if\relax\noexpand\@let@token
      \ifx\@let@token\xeCJK@par
      \else
        \@sptoken
      \fi
    \fi
  \fi
  \let\xeCJK@nexttoken\relax}

\long\def\xeCJK@gobble#1\CJK@stop{}

%    \end{macrocode}
%
% 避免单个汉字占一行。
%    \begin{macrocode}

\def\xeCJK@checksingle#1{
  \def\xeCJK@setcurrentchar@i{
    \CJKglue
    \CJKsymbol{#1}}
  \def\xeCJK@setcurrentnobreakchar@i{
    \CJKsymbol{#1}}
  \futurelet\@let@token\xeCJK@@checksingle}

\def\xeCJK@@checksingle{
  \ifcat 。\noexpand\@let@token
    \expandafter\xeCJK@@@checksingle
  \else
    \expandafter\xeCJK@setcurrentchar@i
  \fi}

\def\xeCJK@@@checksingle#1{
  \def\xeCJK@setcurrentchar@ii{
    \xeCJK@setcurrentchar@i #1}
  \def\xeCJK@setcurrentchar@ii@s{
    \xeCJK@setcurrentchar@i #1 }
  \def\xeCJK@setcurrentnobreakchar@ii{
    \xeCJK@setcurrentnobreakchar@i #1}
  \futurelet\@let@token\xeCJK@@@@checksingle}

\def\xeCJK@@@@checksingle{
  \ifx\@let@token\@sptoken
    \expandafter\xeCJK@checkpar
  \else
    \expandafter\xeCJK@setcurrentchar@ii
  \fi}

\let\xeCJK@par\par
\def\xeCJK@checkpar{
  \@ifnextchar\xeCJK@par{\xeCJK@setcurrentnobreakchar@ii}{\xeCJK@setcurrentchar@ii@s}}
%    \end{macrocode}
%
% 设置中英文间距。
%    \begin{macrocode}

\def\xeCJKsetecglue#1{
    \def\CJK@ecglue{#1}
    \let\CJKecglue\CJK@ecglue}
\let\CJKsetecglue\xeCJKsetecglue
\CJKsetecglue{ }

%    \end{macrocode}
%
% 缺省状态下，不允许在相邻标点中间换行。
%    \begin{macrocode}
\def\xeCJKallowbreakbetweenpuncts{
  \def\xeCJKpunctnobreak{
    \hskip 0pt}}

\def\xeCJKnobreakbetweenpuncts{
  \let\xeCJKpunctnobreak\nobreak}
\xeCJKnobreakbetweenpuncts

%    \end{macrocode}
%
% 重定义\verb+\/+
%    \begin{macrocode}
\let\xeCJK@itcorr\/
\def\/{%
  \relax
  \ifnum\lastkern=4 %
    \unkern\unkern
  \fi
  \xeCJK@itcorr}
\let\@@italiccorr=\/

%    \end{macrocode}
% \section{标点挤压规则}
%    \begin{macrocode}
\newcount\xeCJK@cnta
\newcount\xeCJK@cntb
\newcount\xeCJK@cntc
\newcount\xeCJK@cntd
\newcount\xeCJK@cnte
\newdimen\xeCJK@dima
\newif\ifxeCJK@dokerning

\def\xeCJK@punctrule#1#2{
  \xdef\xeCJK@bboxname{\xeCJK@family/\f@series/\f@shape}
%    \end{macrocode}
%
% 如果 punctstyle$=$plain 不作特殊处理
%
%    \begin{macrocode}
  \ifcsname xeCJK\xeCJK@punctstyle\xeCJK@bboxname @#2rule@#1\endcsname
  \else
    \ifcsname xeCJK@\xeCJK@bboxname @lspace@#1\endcsname
    \else
      {\xeCJK@setfont
       \xeCJK@setpunctbounds{#1}}
    \fi
    \xeCJK@dokerningtrue
    \ifnum\xeCJK@punctstyle=\xeCJK@ps@plain\relax
      \xeCJK@dokerningfalse
    \else
      \ifcsname xeCJK@specialpunct#1\endcsname
        \xeCJK@dokerningfalse
      \fi
    \fi
    \ifxeCJK@dokerning
      \xeCJK@cnta=\csname xeCJK@\xeCJK@bboxname @#2space@#1\endcsname\relax
      \xeCJK@cntc=\xeCJK@cnta
      \ifcase\xeCJK@punctstyle
          % hangmobanjiao
      \or % quanjiao
      \or % banjiao
        \advance\xeCJK@cntc -50\relax
      \or % kaiming
        \ifcsname xeCJK@kaiming#1\endcsname
        \else
          \advance\xeCJK@cntc -50\relax
        \fi
      \or %CCT
        \advance\xeCJK@cntc -20\relax
      \fi
      \xeCJK@cntd=\xeCJK@cntc
      \ifnum\xeCJK@cntc<0\relax
        \xeCJK@cntc=0\relax
      \fi
    \else
      \xeCJK@cnta=0\relax
      \xeCJK@cntc=0\relax
      \xeCJK@cntd=0\relax
    \fi
    \xeCJK@numtodim{\xeCJK@cnta}
    \global\expandafter\edef\csname
      xeCJK\xeCJK@punctstyle\xeCJK@bboxname @#2rule@#1\endcsname{
        -\xeCJK@temp em}
    \xeCJK@numtodim{\xeCJK@cntc}
    \global\expandafter\edef\csname
      xeCJK\xeCJK@punctstyle\xeCJK@bboxname @#2glue@#1\endcsname{
        \xeCJK@temp em}
    \global\expandafter\edef\csname
      xeCJK\xeCJK@punctstyle\xeCJK@bboxname @#2oglue@#1\endcsname{
        \the\xeCJK@cntd}
  \fi}

\def\xeCJK@numtodim#1{
  \xeCJK@cnte=#1\relax
  \ifnum\the\xeCJK@cnte<100\relax
    \def\xeCJK@temp{0}
  \else
    \advance\xeCJK@cnte -100\relax
    \def\xeCJK@temp{1}
  \fi
  \ifnum\the\xeCJK@cnte<10
    \edef\xeCJK@temp{\xeCJK@temp.0\the\xeCJK@cnte}
  \else
    \edef\xeCJK@temp{\xeCJK@temp.\the\xeCJK@cnte}
  \fi}

\expandafter\def\csname xeCJK@kaiming．\endcsname{}
\expandafter\def\csname xeCJK@kaiming。\endcsname{}
\expandafter\def\csname xeCJK@kaiming？\endcsname{}
\expandafter\def\csname xeCJK@kaiming！\endcsname{}
\expandafter\def\csname xeCJK@specialpunct—\endcsname{}% U+2014
\expandafter\def\csname xeCJK@specialpunct─\endcsname{}% U+2500
\expandafter\def\csname xeCJK@specialpunct…\endcsname{}
\def\xeCJK@setkern#1#2{
  \ifcsname xeCJK\xeCJK@punctstyle\xeCJK@bboxname @kern#1#2\endcsname
  \else
    \xeCJK@cnta=0\relax
    \ifcsname xeCJK\xeCJK@punctstyle\xeCJK@bboxname @roglue@#1\endcsname
      \advance\xeCJK@cnta\csname
        xeCJK\xeCJK@punctstyle\xeCJK@bboxname @roglue@#1\endcsname
    \fi
    \ifcsname xeCJK\xeCJK@punctstyle\xeCJK@bboxname @loglue@#2\endcsname
      \advance\xeCJK@cnta\csname xeCJK\xeCJK@punctstyle\xeCJK@bboxname
        @loglue@#2\endcsname
    \fi
    \relax
    \ifcase\xeCJK@punctstyle
        % hangmobanjiao
    \or % quanjiao
      \advance\xeCJK@cnta -50\relax
    \or % banjiao
    \or % kaiming
      \ifcsname xeCJK@kaiming#1\endcsname
        \ifcsname xeCJK\xeCJK@punctstyle\xeCJK@bboxname @roglue@#2\endcsname
          \advance\xeCJK@cnta -50\relax
        \fi
      \fi
    \fi
    \ifnum\xeCJK@cnta<0\relax
      \xeCJK@cnta=0\relax
    \fi
    \xeCJK@numtodim{\xeCJK@cnta}
    \global\expandafter\edef\csname
      xeCJK\xeCJK@punctstyle\xeCJK@bboxname @kern#1#2\endcsname{
        \xeCJK@temp em}
  \fi}

%    \end{macrocode}
%  用户命令：设置两个标点之间的间距
%    \begin{macrocode}
\def\xeCJKsetkern#1#2#3{
  \xdef\xeCJK@bboxname{\xeCJK@family/\f@series/\f@shape}
  \global\expandafter\edef\csname
      xeCJK\xeCJK@punctstyle\xeCJK@bboxname @kern#1#2\endcsname{#3}}

\def\punctstyle#1{
  \ifcsname xeCJK@ps@#1\endcsname
    \edef\xeCJK@punctstyle{\csname xeCJK@ps@#1\endcsname}
    \ifnum\xeCJK@punctstyle=\xeCJK@ps@plain\relax
      \xeCJKallowbreakbetweenpuncts
    \fi
  \else
    \typeout{Warning: Punctstyle #1\space is not defined.}
  \fi}

\def\xeCJK@ps@hangmobanjiao{0}
\def\xeCJK@ps@marginkerning{0}
\def\xeCJK@ps@quanjiao{1}
\def\xeCJK@ps@fullwidth{1}
\def\xeCJK@ps@banjiao{2}
\def\xeCJK@ps@halfwidth{2}
\def\xeCJK@ps@kaiming{3}
\def\xeCJK@ps@mixedwidth{3}
\def\xeCJK@ps@CCT{4}
\def\xeCJK@ps@plain{5}
\punctstyle{quanjiao}

\def\xeCJKplainchr{\punctstyle{plain}}

\def\xeCJK@sidespace{10}

\def\xeCJK@getglyphbounds#1{
  \xeCJK@cnta=\number\XeTeXglyphbounds #1 \xeCJK@gid
  \xeCJK@dima 1em\relax
  \xeCJK@cntb=\number\xeCJK@dima
  \multiply\xeCJK@cnta 100\relax
  \divide\xeCJK@cnta\xeCJK@cntb
  \advance\xeCJK@cnta -15\relax
  \edef\xeCJK@temp{\the\xeCJK@cnta}
  \ifnum\xeCJK@temp<0\relax
    \def\xeCJK@temp{0}
  \fi}


\def\xeCJK@setpunctbounds#1{
  \edef\xeCJK@gid{\the\XeTeXcharglyph`#1}
  \xeCJK@getglyphbounds{1}
  \expandafter\xdef\csname xeCJK@\xeCJK@bboxname @lspace@#1\endcsname{
    \xeCJK@temp}
  \xeCJK@getglyphbounds{3}
  \expandafter\xdef\csname xeCJK@\xeCJK@bboxname @rspace@#1\endcsname{
    \xeCJK@temp}
  \ifcsname xeCJK@specialpunct#1\endcsname
    \ifx#1…
    \else
      \xeCJK@cnta=\number\XeTeXglyphbounds 1 \xeCJK@gid
      \advance\xeCJK@cnta\number\XeTeXglyphbounds 3 \xeCJK@gid
      \xeCJK@dima 1em\relax
      \xeCJK@cntb=\number\xeCJK@dima
      \multiply\xeCJK@cnta 100\relax
      \divide\xeCJK@cnta\xeCJK@cntb
      \advance\xeCJK@cnta 1\relax
      \ifnum\xeCJK@cnta>9
        \edef\xeCJK@temp{-0.\the\xeCJK@cnta em}
      \else
        \ifnum\xeCJK@cnta>1
          \edef\xeCJK@temp{-0.0\the\xeCJK@cnta em}
        \else
          \edef\xeCJK@temp{-0.01 em}
        \fi
      \fi
      \xeCJK@cnta=0
      \loop
        \global\expandafter\edef\csname xeCJK\the\xeCJK@cnta\xeCJK@bboxname
          @kern#1#1\endcsname{\xeCJK@temp}
        \advance \xeCJK@cnta 1\relax
      \ifnum\xeCJK@cnta<6\repeat
    \fi
  \fi}


\ifcsname XeTeXglyphbounds\endcsname
\else
  \PackageError{xeCJK}{\string\XeTeXglyphbounds \space not defined.^^J
    You have to update XeTeX  to the version 0.9995.0 or later}
    \relax
\fi

%    \end{macrocode}
% \section{字体设置}
%    \begin{macrocode}
\def\CJKsymbol#1{#1}
\def\CJKpunctsymbol#1{#1}

%    \end{macrocode}
% 设置备用字体，如果主字体没有相应的符号，将尝试使用备用字体显示。
%    \begin{macrocode}
\def\xeCJK@fallback@testsymbol#1{
  \iffontchar\font`#1
    #1
  \else
    {\csname xeCJK@fallback@\xeCJK@family\endcsname #1}
  \fi}
%    \end{macrocode}
% |\xeCJKenablefallback| 命令打开备用字体功能，|\xeCJKdisablefallback| 命令关
% 闭备用字体功能。此功能默认关闭。
%    \begin{macrocode}
\newcommand\xeCJKenablefallback{\let\xeCJK@fallback@CJKsymbol\CJKsymbol
  \def\CJKsymbol##1{\xeCJK@fallback@CJKsymbol{\xeCJK@fallback@testsymbol{##1}}}}
\newcommand\xeCJKdisablefallback{\let\CJKsymbol\xeCJK@fallback@CJKsymbol}
\ifxeCJK@fallback@
  \xeCJKenablefallback
\fi
%    \end{macrocode}
% |\setCJKfallbackfamilyfont| 为 CJK 字体族设置备用字体。
%    \begin{macrocode}
\newcommand\setCJKfallbackfamilyfont[1]{
  \@ifnextchar[
    {\xeCJK@setfallbackfamilyfont{#1}}
    {\xeCJK@setfallbackfamilyfont{#1}[]}}
\def\xeCJK@setfallbackfamilyfont#1[#2]#3{
  \expandafter\newfontfamily\csname xeCJK@fallback@#1\endcsname[#2]{#3}
}


\DeclareRobustCommand{\xeCJK@ULprepunctchar}[1]{
 {\XeTeXinterchartokenstate=0
  \CJKpunctsymbol{#1}
  \nobreak}
  \ignorespaces}
\DeclareRobustCommand{\xeCJK@ULpostpunctchar}[1]{
 {\XeTeXinterchartokenstate=0
  \CJKpunctsymbol{#1}}
  \xeCJK@ignorespaces}
\def\xeCJK@ULroutines{
  \XeTeXinterchartoks 0   1 {\CJKecglue\CJKsymbol}
  \XeTeXinterchartoks 4   1 {\CJKsymbol}
  \XeTeXinterchartoks 5   1 {\CJKecglue\CJKsymbol}
  \XeTeXinterchartoks 255 1 {\xeCJK@cclv@i}
  \XeTeXinterchartoks 0   2 {\xeCJK@ULprepunctchar}
  \XeTeXinterchartoks 4   2 {\xeCJK@ULprepunctchar}
  \XeTeXinterchartoks 5   2 {\xeCJK@ULprepunctchar}
  \XeTeXinterchartoks 255 2 {\xeCJK@ULprepunctchar}
  \XeTeXinterchartoks 0   3 {\xeCJK@ULpostpunctchar}
  \XeTeXinterchartoks 4   3 {\xeCJK@ULpostpunctchar}
  \XeTeXinterchartoks 5   3 {\xeCJK@ULpostpunctchar}
  \XeTeXinterchartoks 255 3 {\xeCJK@ULpostpunctchar}}

\AtBeginDocument{
  \ifcsname UL@hook\endcsname
    \addto@hook\UL@hook{
      \let\xeCJK@UL@CJKsymbol\CJKsymbol
      \let\xeCJK@UL@CJKpunctsymbol\CJKpunctsymbol
      \def\CJKsymbol#1{{\xeCJK@setfont \xeCJK@UL@CJKsymbol{#1}}
        \kern -1sp\kern 1sp\xeCJK@ignorespaces}
      \def\CJKpunctsymbol#1{{\xeCJK@setfont \xeCJK@UL@CJKpunctsymbol{#1}}}
      \xeCJK@ULroutines}
  \fi
  \ifcsname ver@CJKfntef.sty\endcsname
    \def\XeTeX@CJKfntef@hook{
      \xeCJK@setfont
      \XeTeXinterchartokenstate=0}
  \fi}

%    \end{macrocode}
% |\xeCJK@setfont| 实际切换中文字体。它使用名为
% |xeCJK@\xeCJK@family/\f@series/\f@shape/\f@size| 的宏来缓存特定 NFSS 坐标
% 中文字体的原始 |\font| 命令格式，以加快编译速度。在第一次使用这一 NFSS 坐标
% 时，会调用名为 |xeCJK@font@\xeCJK@family| 的宏（它将展开为 |\fontspec|），
% 利用 |fontspec| 宏包选择中文字体，并缓存原始字体形式。
%    \begin{macrocode}
\def\xeCJK@setfont{
  \ifcsname xeCJK@\xeCJK@family/\f@series/\f@shape/\f@size\endcsname
%    \end{macrocode}
% 使用已缓存的字体。
%    \begin{macrocode}
    \csname xeCJK@\xeCJK@family/\f@series/\f@shape/\f@size\endcsname
  \else
%    \end{macrocode}
% 预存需要的 NFSS 坐标到 |\xeCJK@currentcoor|，以免在缺字体时被替换字体改变。
%    \begin{macrocode}
    \edef\xeCJK@currentcoor{xeCJK@\xeCJK@family/\f@series/\f@shape/\f@size}
%    \end{macrocode}
% 切换未缓存的字体。
%    \begin{macrocode}
    \csname xeCJK@font@\xeCJK@family\endcsname
%    \end{macrocode}
% |\get@external@font| 可能会产生奇怪的副作用\footnote{参见 ctex-kit 项目
% \href{http://code.google.com/p/ctex-kit/issues/detail?id=57}{issue 57}。}。
% 这里使用分组令其局部化，仅保留对 |\external@font| 的赋值。
%    \begin{macrocode}
    \begingroup
      \get@external@font
      \edef\xeCJK@temp{\def\noexpand\external@font{\external@font}}
    \expandafter\endgroup\xeCJK@temp
%    \end{macrocode}
% 缓存字体。
%    \begin{macrocode}
    \expandafter\global\expandafter\font
      \csname\xeCJK@currentcoor\endcsname=\external@font
  \fi}

\def\CJKrmdefault{rm}
\def\setCJKmainfont{
  \xeCJK@newfontfamily{\CJKrmdefault}}

\let\setCJKromanfont\setCJKmainfont

\def\CJKsfdefault{sf}
\def\setCJKsansfont{
  \xeCJK@newfontfamily{\CJKsfdefault}}

\providecommand\CJKttdefault{tt}
%    \end{macrocode}
% |\setCJKmonofont| 在后面单独定义。
%    \begin{macrocode}

\def\setCJKfamilyfont#1{
  \xeCJK@newfontfamily{#1}}
%    \end{macrocode}
% 重定义 |\normalfont|, |\rmfamily|, |\sffamily|，添加 CJK 字体族的设置。
% |\ttfamily| 可能需要单独调整宽度，将在后面定义。
%    \begin{macrocode}
\def\CJKfamilydefault{\CJKrmdefault}
\DeclareRobustCommand\normalfont
        {\CJKfamily{\CJKfamilydefault}
         \usefont\encodingdefault
                 \familydefault
                 \seriesdefault
                 \shapedefault
         \relax}
\let\reset@font\normalfont

\DeclareRobustCommand\rmfamily
        {\not@math@alphabet\rmfamily\mathrm
         \fontfamily\rmdefault\CJKfamily{\CJKrmdefault}\selectfont}

\DeclareRobustCommand\sffamily
        {\not@math@alphabet\sffamily\mathsf
         \fontfamily\sfdefault\CJKfamily{\CJKsfdefault}\selectfont}

%    \end{macrocode}
% \string\xeCJK@newfontfamily is similar to \string\newfontfamily
%   but introduce fake slant/bold fonts for CJK characters.
%    \begin{macrocode}
\newcommand*\xeCJK@newfontfamily[1]{
  \@ifnextchar[
    {\xeCJK@newfontfamily@{#1}}
    {\xeCJK@newfontfamily@{#1}[]}}

\def\xeCJK@setmacro@define@key#1{
  \define@key[xeCJK]{preparse}{#1}{
    \expandafter\xdef\csname xeCJK@#1\endcsname{##1}}}

\xeCJK@setmacro@define@key{ItalicFont}
\xeCJK@setmacro@define@key{BoldFont}
\xeCJK@setmacro@define@key{BoldItalicFont}

\def\xeCJK@newfontfamily@#1[#2]#3{
  %
  % Get user defined options

  \let\xeCJK@BoldFont\@empty
  \let\xeCJK@ItalicFont\@empty
  \let\xeCJK@BoldItalicFont\@empty
  \bgroup
    \setkeys*[xeCJK]{preparse}{#2}
  \egroup
  \edef\xeCJK@Features{}

  \ifxeCJK@BoldFont@
    \ifx\xeCJK@BoldFont\@empty
      \edef\xeCJK@Features{BoldFont={#3},
        BoldFeatures={RawFeature={embolden=\xeCJK@emboldenfactor}}}
    \fi
  \fi

  \ifxeCJK@SlantFont@
    \ifx\xeCJK@ItalicFont\@empty
      \ifx\xeCJK@Features\@empty
        \edef\xeCJK@Features{ItalicFont={#3},
          ItalicFeatures={RawFeature={slant=\xeCJK@slantfactor}}}
      \else
        \edef\xeCJK@Features{\xeCJK@Features,ItalicFont={#3},
          ItalicFeatures={RawFeature={slant=\xeCJK@slantfactor}}}
      \fi
    \fi

    \ifx\xeCJK@BoldItalicFont\@empty
      \ifx\xeCJK@BoldFont\@empty
        \edef\xeCJK@Features{\xeCJK@Features,BoldItalicFont={#3},
          BoldItalicFeatures={RawFeature={embolden=\xeCJK@emboldenfactor,slant=\xeCJK@slantfactor}}}
      \else
        \edef\xeCJK@Features{\xeCJK@Features,BoldItalicFont={\xeCJK@BoldFont},
          BoldItalicFeatures={RawFeature={slant=\xeCJK@slantfactor}}}
      \fi
    \fi
  \fi

  \edef\xeCJK@temp{#2}
  \ifx\xeCJK@temp\@empty
  \else
    \ifx\xeCJK@Features\@empty
      \edef\xeCJK@Features{#2}
    \else
      \edef\xeCJK@Features{\xeCJK@Features,#2}
    \fi
  \fi

  \expandafter\edef\csname xeCJK@font@#1\endcsname{
    \noexpand\fontspec[\xeCJK@Features]{#3}}
  \expandafter\edef\csname xeCJK@fontoptions@#1\endcsname{\xeCJK@Features}
  \expandafter\edef\csname xeCJK@fontname@#1\endcsname{#3}}

%    \end{macrocode}
% Redefine \verb+\addfontfeatures+
%    \begin{macrocode}

\newcount\xeCJK@featureadded
\xeCJK@featureadded=0

\let\xeCJK@addfontfeatures\addfontfeatures
\def\addCJKfontfeatures#1{
  \global\advance\xeCJK@featureadded\@ne
  \ifcsname xeCJK@family\endcsname
    \edef\xeCJK@tempa{\csname xeCJK@fontoptions@\xeCJK@family\endcsname,#1}
    \edef\xeCJK@tempb{\csname xeCJK@fontname@\xeCJK@family\endcsname}
    \edef\xeCJK@tempf{\xeCJK@family @\the\xeCJK@featureadded}
    \expandafter\edef\csname xeCJK@font@\xeCJK@tempf\endcsname{
      \noexpand\fontspec[\xeCJK@tempa]{\xeCJK@tempb}}
    \expandafter\edef\csname xeCJK@fontoptions@\xeCJK@tempf\endcsname{\xeCJK@tempa}
    \expandafter\edef\csname xeCJK@fontname@\xeCJK@tempf\endcsname{\xeCJK@tempb}
    \CJKfamily{\xeCJK@tempf}
  \fi}

\def\addfontfeatures#1{
  \xeCJK@addfontfeatures{#1}
  \addCJKfontfeatures{#1}}

% redefine \verb+\CJKfamily+

\expandafter\def\csname xeCJK@font@\CJKfamilydefault\endcsname{}

\DeclareRobustCommand\CJKfamily[1]{
  \ifcsname xeCJK@font@#1\endcsname
    \edef\xeCJK@family{#1}
  \else
    \ifcsname xeCJK@#1@warned\endcsname
    \else
      \PackageWarning{xeCJK}{
        Unknown CJK family `#1' is ignored.^^J
        Use \string\setCJKfamilyfont \space to define a CJK family.}
      \expandafter\gdef\csname xeCJK@#1@warned\endcsname{}
    \fi
  \fi}
\AtBeginDocument{\CJKfamily{\CJKfamilydefault}}

\def\xeCJKsetslantfactor#1{\edef\xeCJK@slantfactor{#1}}
\def\xeCJKsetemboldenfactor#1{\edef\xeCJK@emboldenfactor{#1}}

\xeCJKsetslantfactor{0.17}
\xeCJKsetemboldenfactor{4}
%    \end{macrocode}
% \section{处理等宽字体和抄录环境}
%    \begin{macrocode}
\ExplSyntaxOn

\fp_new:N \g_xecjk_monoscale_fp
\fp_gset_eq:NN \g_xecjk_monoscale_fp \c_one_fp

\dim_new:N \g_xecjk_exspace_dim
\dim_gset_eq:NN \g_xecjk_exspace_dim \c_zero_dim

\cs_new:Nn \xecjk_setmonoscale:
{
  \dim_gset_eq:NN \g_xecjk_exspace_dim \c_zero_dim
  \group_begin:
    \fontfamily\ttdefault\selectfont
    \fp_gset_from_dim:Nn \g_xecjk_monoscale_fp {\c_two\fontdimen\c_two\font}
    \fp_gdiv:Nn \g_xecjk_monoscale_fp {\f@size}
  \group_end:
}

\newcommand*\setCJKmonoscale{
  \xecjk_setmonoscale:
  \addCJKfontfeatures{Scale=\fp_use:N\g_xecjk_monoscale_fp}
}

\DeclareRobustCommand\setCJKmonoscalefont[2][]{
  \xecjk_setmonoscale:
  \xeCJK@newfontfamily{\CJKttdefault}[#1,Scale=\fp_use:N \g_xecjk_monoscale_fp]{#2}}

\cs_new:Nn \xecjk_set_monoexspace:
{
  \fp_gset_eq:NN \g_xecjk_monoscale_fp \c_one_fp
  \group_begin:
    \fontfamily\ttdefault\selectfont
    \dim_gset:Nn \g_xecjk_exspace_dim {\c_two\fontdimen\c_two\font - \f@size\p@}
  \group_end:
}

\newcommand*\setCJKmonoexspace{
  \xecjk_set_monoexspace:
  \CJKsetecglue{\skip_horizontal:N .5\g_xecjk_exspace_dim}
  \def\CJKglue{\skip_horizontal:N \g_xecjk_exspace_dim}
}


\DeclareRobustCommand\setCJKmonoexspacefont[2][]{
  \setCJKmonoexspace
  \xeCJK@newfontfamily{\CJKttdefault}[#1]{#2}}

\def\xeCJK@ifplus#1{\@ifnextchar +{\@firstoftwo{#1}}}

\DeclareRobustCommand\setCJKmonofont{\@ifstar
  {\setCJKmonoscalefont}
  {\xeCJK@ifplus
    {\setCJKmonoexspacefont}
    {\xeCJK@newfontfamily{\CJKttdefault}}}}

\DeclareRobustCommand\ttfamily
        {\not@math@alphabet\ttfamily\mathtt
         \fontfamily\ttdefault\CJKfamily{\CJKttdefault}\selectfont
         \CJKsetecglue{\skip_horizontal:N .5\g_xecjk_exspace_dim}
         \def\CJKglue{\skip_horizontal:N \g_xecjk_exspace_dim}}

%    \end{macrocode}
% 修补 \verbatim@font
%    \begin{macrocode}
\AtBeginDocument{
  \tl_put_right:Nn \verbatim@font {
    \punctstyle{plain}
    \CJKsetecglue{\skip_horizontal:N \g_xecjk_exspace_dim}
    \def\CJKglue{\skip_horizontal:N \g_xecjk_exspace_dim}}
}

\ExplSyntaxOff

%    \end{macrocode}
% \section{使用CJKnumb宏包}
%    \begin{macrocode}
%


\ifxeCJK@num
  \edef\CJK@UnicodeEnc{UTF8}
  \def\CJKaddEncHook#1#2{\expandafter\def\csname xeCJK@enc@#1\endcsname{#2}}
  \def\Unicode#1#2{\@tempcnta #1\relax
    \multiply\@tempcnta 256\relax
    \advance\@tempcnta #2\relax
    \char\@tempcnta}
  \RequirePackage{CJKnumb}
  \csname xeCJK@enc@UTF8\endcsname
  \def\CJK@tenthousand{万}
\fi
%    \end{macrocode}
%  可以使用CJK包中的cpx或cp文件。
%    \begin{macrocode}

\def\CJK@ifundefined#1{
  \ifx #1\@undefined
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
}

\newcommand{\xeCJKcaption}[2][]{
  \edef\xeCJK@temp{#1}
  \ifx\xeCJK@temp\@empty
  \else
    \XeTeXdefaultencoding "#1"
  \fi
  \makeatletter
  \input{#2.cpx}
  \makeatother
  \XeTeXdefaultencoding "UTF-8"}

\endlinechar `\^^M
\catcode "FEFF=9\relax
%    \end{macrocode}
%
%
%
% \iffalse
%</xeCJK>
%
%
%<*example-addspaces>
% \fi
%
% \clearpage
% \part{example-addspaces.tex}
%    \begin{macrocode}
\documentclass{article}
\usepackage[boldfont,slantfont]{xeCJK}
\usepackage{xcolor}
\setCJKmainfont{AR PLBaosong2GBK Light}
\textwidth 190mm
\oddsidemargin 0pt
\begin{document}
\baselineskip 18pt
\parskip 10pt
\parindent 0em

{\slshape 斜体 Slanted \bfseries  斜体 Slanted}


\long\def\sometexts{\par{\color{\colora}
 这是 English 中文 {\itshape Chinese} 中文    \LaTeX\
  间隔 \textit{Italic} 中文\textbf{字体} a 数学 $b$ 数学 $c$ $d$
\\
 这是English中文{\itshape Chinese}中文\LaTeX\
 间隔\textit{Italic}中文\textbf{字体}a数学$b$数学$c$ $d$\\
This is an example. 这是一个例子
}}

\def\colora{blue}
\CJKsetecglue{\hskip 0.15em plus 0.05em minus 0.05em}
\verb+\CJKsetecglue{\hskip 0.15em plus 0.05em minus 0.05em}+
\sometexts

\def\colora{red}
\CJKsetecglue{ }
\verb+\CJKsetecglue{ }+
\sometexts


{\verb+\CJKspace+

\CJKspace
这 是 一行 文字。}

{\verb+\CJKnospace+

\CJKnospace
这 是 一行 文字。}

\end{document}

%    \end{macrocode}
% \iffalse
%</example-addspaces>
%<*example-CJKchecksingle>
% \fi
%
% \clearpage
% \part{example-CJKchecksingle.tex}
%    \begin{macrocode}
\documentclass{article}
\usepackage[CJKchecksingle]{xeCJK}
\setCJKmainfont{AR PLBaosong2GBK Light}
\textwidth 120mm
\oddsidemargin 0pt
\def\usemacro#1{\csname#1\endcsname $\backslash$#1}
\begin{document}
\baselineskip 18pt
\parskip 10pt
\parindent 0em

\long\def\sometexts{xeCJK   改进了中英文间距的处理，并可以避免单个汉字独占一段的最后一行。

xeCJK  改进了中英文间距的处理，并且可以避免单个汉字独占一段的最后一行。

xeCJK  改进了中英文间距的处理, 并且还可以避免单个汉字独占一段的最后一行.

}

\sometexts
\vskip 20mm

不用CJKchecksingle的效果：

\makeatletter
\def\xeCJK@i@i{\CJKglue\CJKsymbol}
\sometexts
\end{document}

%    \end{macrocode}
% \iffalse
%</example-CJKchecksingle>
%<*example-CJKfntef>
% \fi
%
% \clearpage
% \part{example-CJKfntef.tex}
%    \begin{macrocode}

\documentclass[11pt]{article}
\textheight 220mm
\textwidth 150mm
\oddsidemargin 0pt
\evensidemargin 0pt
\usepackage[boldfont]{xeCJK}
\usepackage{xcolor}
\usepackage{CJKfntef}

\begin{document}
\setCJKmainfont{AR PLBaosong2GBK Light}% 设置缺省中文字体
\setCJKmonofont*{AR PLBaosong2GBK Light}% 设置等宽中文字体，令其与英文对齐

\baselineskip 16pt
\parindent 2em

\section{举例}
\begin{verbatim}
抄录环境中，标点不会被“压缩”。
Alignment with English characters.
\end{verbatim}

\CJKunderline{汉字}\CJKunderline{加下划线加下划线加下划线加下划线
加下划线加下划线加下划线加下划线加下划线加下划线加下划线}

\CJKunderwave{波浪线}

\ifcsname CJKunderanyline\endcsname
  \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 .1em}\kern-.03em}{自定义下划线}

  \CJKunderanysymbol{0.2em}{$\cdot$}{汉字加点}
\fi
\end{document}
%    \end{macrocode}
% \iffalse
%</example-CJKfntef>
%<*example-fallback>
% \fi
% \part{example-fallback.tex}
% \setCJKfallbackfamilyfont{\CJKrmdefault}{SimSun-ExtB}
% \xeCJKenablefallback
%    \begin{macrocode}
\documentclass{article}
\usepackage[fallback]{xeCJK}
\usepackage{CJKfntef}
\setCJKmainfont{SimSun}
\setCJKfallbackfamilyfont{\CJKrmdefault}{SimSun-ExtB}
\begin{document}

漢字源𣴑考

\CJKunderwave{漢字源𣴑考}

\begin{table}[ht]
\caption{生僻字测试}
\centering
\begin{tabular}{|cc|cc|cc|cc|}
𠀀 & 20000 & 𠀁 & 20001 & 𠀂 & 20002 & 𠀃 & 20003 \\
𠀄 & 20004 & 𠀅 & 20005 & 𠀆 & 20006 & 𠀇 & 20007 \\
𠀈 & 20008 & 𠀉 & 20009 & 𠀊 & 2000A & 𠀋 & 2000B \\
𠀌 & 2000C & 𠀍 & 2000D & 𠀎 & 2000E & 𠀏 & 2000F \\
𠀐 & 20010 & 𠀑 & 20011 & 𠀒 & 20012 & 𠀓 & 20013 \\
𠀔 & 20014 & 𠀕 & 20015 & 𠀖 & 20016 & 𠀗 & 20017 \\
𠀘 & 20018 & 𠀙 & 20019 & 𠀚 & 2001A & 𠀛 & 2001B \\
𠀜 & 2001C & 𠀝 & 2001D & 𠀞 & 2001E & 𠀟 & 2001F \\
\end{tabular}
\end{table}
\end{document}
%    \end{macrocode}
% \iffalse
%</example-fallback>
% \fi
% \Finale
%
% \typeout{*************************************************************}
% \typeout{*}
% \typeout{* To finish the installation you have to move the following}
% \typeout{* files into a directory searched by XeTeX:}
% \typeout{*}
% \typeout{* \space\space\space xeCJK.sty}
% \typeout{*}
% \typeout{*************************************************************}
% \Finale
\endinput
