diff options
Diffstat (limited to 'language/chinese/ctex/ctex.dtx')
-rw-r--r-- | language/chinese/ctex/ctex.dtx | 12172 |
1 files changed, 12172 insertions, 0 deletions
diff --git a/language/chinese/ctex/ctex.dtx b/language/chinese/ctex/ctex.dtx new file mode 100644 index 0000000000..d4a80e4344 --- /dev/null +++ b/language/chinese/ctex/ctex.dtx @@ -0,0 +1,12172 @@ +% \iffalse meta-comment +% !TeX program = XeLaTeX +% !TeX encoding = UTF-8 +% +% Copyright (C) 2003--2019 +% CTEX.ORG and any individual authors listed elsewhere in this file. +% -------------------------------------------------------------------------- +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either +% version 1.3c of this license or (at your option) any later +% version. This version of this license is in +% http://www.latex-project.org/lppl/lppl-1-3c.txt +% and the latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of +% LaTeX version 2005/12/01 or later. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainers of this work are Leo Liu, Qing Lee and Liam Huang. +% +% -------------------------------------------------------------------------- +% +%<*internal> +\iffalse +%</internal> +%<*readme> +ctex +==== + +`ctex` is a collection of macro packages and document classes +for LaTeX Chinese typesetting. + +Authors and Contributors +------------------------ + +* Wu Lingyun <aloft@ctex.org> +* Jiang Jiang <gzjjgod@gmail.com> +* Wang Yue <yuleopen@gmail.com> +* Liu Haiyang <leoliu.pku@gmail.com> +* Li Yanrui <liyanrui.m2@gmail.com> +* Chen Zhichu <zhichu.chen@gmail.com> +* Li Qing <sobenlee@gmail.com> +* Liam Huang <liamhuang0205@gmail.com> + +Contributing +------------ + +This package is a part of the [ctex-kit](https://github.com/CTeX-org/ctex-kit) project. + +Issues and pull requests are welcome. + +Copyright and Licence +--------------------- + + Copyright (C) 2003--2019 + CTEX.ORG and any individual authors listed elsewhere in this file. + ---------------------------------------------------------------------- + + This work may be distributed and/or modified under the + conditions of the LaTeX Project Public License, either + version 1.3c of this license or (at your option) any later + version. This version of this license is in + http://www.latex-project.org/lppl/lppl-1-3c.txt + and the latest version of this license is in + http://www.latex-project.org/lppl.txt + and version 1.3 or later is part of all distributions of + LaTeX version 2005/12/01 or later. + + This work has the LPPL maintenance status `maintained'. + + The Current Maintainers of this work are Leo Liu, Qing Lee and Liam Huang. + + This package consists of the file ctex.dtx, + and the derived files ctex.pdf, + ctex.ins, + ctex.sty, + ctexsize.sty, + ctexheading.sty, + ctexart.cls, + ctexbook.cls, + ctexrep.cls, + ctexbeamer.cls, + ctxdoc.cls, + ctexcap.sty, + ctexhook.sty, + ctexpatch.sty, + ctex-c5size.clo, + ctex-cs4size.clo, + ctex-article.def, + ctex-book.def, + ctex-report.def, + ctex-beamer.def, + ctex-scheme-plain.def, + ctex-scheme-plain-article.def, + ctex-scheme-plain-book.def, + ctex-scheme-plain-report.def, + ctex-scheme-plain-beamer.def, + ctex-scheme-chinese.def, + ctex-scheme-chinese-article.def, + ctex-scheme-chinese-book.def, + ctex-scheme-chinese-report.def, + ctex-scheme-chinese-beamer.def, + ctex-name-gbk.cfg, + ctex-name-utf8.cfg, + ctex.cfg, + ctexopts.cfg, + ctex-engine-pdftex.def, + ctex-engine-xetex.def, + ctex-engine-luatex.def, + ctex-engine-aptex.def, + ctex-engine-uptex.def, + c19rm.fd, + c19sf.fd, + c19tt.fd, + c70rm.fd, + c70sf.fd, + c70tt.fd, + jy2zhrm.fd, + jy2zhsf.fd, + jy2zhtt.fd, + jt2zhrm.fd, + jt2zhsf.fd, + jt2zhtt.fd, + ctex-fontset-windows.def, + ctex-fontset-windowsnew.def, + ctex-fontset-windowsold.def, + ctex-fontset-adobe.def, + ctex-fontset-fandol.def, + ctex-fontset-mac.def, + ctex-fontset-macnew.def, + ctex-fontset-macold.def, + ctex-fontset-founder.def, + ctex-fontset-ubuntu.def, + ctexspa.def, + ctexpunct.spa, + ctexmakespa.tex, + ctexspamacro.tex, + ctxdocstrip.tex, + zhadobefonts.tex, + zhfandolfonts.tex, + zhfounderfonts.tex, + zhubuntufonts.tex, + zhwindowsfonts.tex, + translator-theorem-dictionary-ChineseGBK.dict, + translator-theorem-dictionary-ChineseUTF8.dict, and + README.md (this file). +%</readme> +%<*internal> +\fi +\begingroup + \def\temp{LaTeX2e} +\expandafter\endgroup\ifx\temp\fmtname\else +\csname fi\endcsname +%</internal> +%<*install> + +\input ctxdocstrip % + +\preamble + + Copyright (C) 2003--2019 + CTEX.ORG and any individual authors listed in the documentation. +------------------------------------------------------------------------------ + + This work may be distributed and/or modified under the + conditions of the LaTeX Project Public License, either + version 1.3c of this license or (at your option) any later + version. This version of this license is in + http://www.latex-project.org/lppl/lppl-1-3c.txt + and the latest version of this license is in + http://www.latex-project.org/lppl.txt + and version 1.3 or later is part of all distributions of + LaTeX version 2005/12/01 or later. + + This work has the LPPL maintenance status `maintained'. + + The Current Maintainers of this work are Leo Liu, Qing Lee and Liam Huang. + +------------------------------------------------------------------------------ + +\endpreamble +\postamble + + This package consists of the file ctex.dtx, + and the derived files ctex.pdf, + ctex.ins, + ctex.sty, + ctexsize.sty, + ctexheading.sty, + ctexart.cls, + ctexbook.cls, + ctexrep.cls, + ctexbeamer.cls, + ctxdoc.cls, + ctexcap.sty, + ctexhook.sty, + ctexpatch.sty, + ctex-c5size.clo, + ctex-cs4size.clo, + ctex-article.def, + ctex-book.def, + ctex-report.def, + ctex-beamer.def, + ctex-scheme-plain.def, + ctex-scheme-plain-article.def, + ctex-scheme-plain-book.def, + ctex-scheme-plain-report.def, + ctex-scheme-plain-beamer.def, + ctex-scheme-chinese.def, + ctex-scheme-chinese-article.def, + ctex-scheme-chinese-book.def, + ctex-scheme-chinese-report.def, + ctex-scheme-chinese-beamer.def, + ctex-name-gbk.cfg, + ctex-name-utf8.cfg, + ctex.cfg, + ctexopts.cfg, + ctex-engine-pdftex.def, + ctex-engine-xetex.def, + ctex-engine-luatex.def, + ctex-engine-aptex.def, + ctex-engine-uptex.def, + c19rm.fd, + c19sf.fd, + c19tt.fd, + c70rm.fd, + c70sf.fd, + c70tt.fd, + jy2zhrm.fd, + jy2zhsf.fd, + jy2zhtt.fd, + jt2zhrm.fd, + jt2zhsf.fd, + jt2zhtt.fd, + ctex-fontset-windows.def, + ctex-fontset-windowsnew.def, + ctex-fontset-windowsold.def, + ctex-fontset-adobe.def, + ctex-fontset-fandol.def, + ctex-fontset-mac.def, + ctex-fontset-macnew.def, + ctex-fontset-macold.def, + ctex-fontset-founder.def, + ctex-fontset-ubuntu.def, + ctexspa.def, + ctexpunct.spa, + ctexmakespa.tex, + ctexspamacro.tex, + ctxdocstrip.tex, + zhadobefonts.tex, + zhfandolfonts.tex, + zhfounderfonts.tex, + zhubuntufonts.tex, + zhwindowsfonts.tex, + translator-theorem-dictionary-ChineseGBK.dict, + translator-theorem-dictionary-ChineseUTF8.dict, and + README.md. +\endpostamble + +\generate + { + \usedir{tex/latex/ctex} + \file{ctex.sty} {\from{\jobname.dtx}{style,ctex}} + \file{ctexsize.sty} {\from{\jobname.dtx}{style,ctexsize}} + \file{ctexheading.sty} {\from{\jobname.dtx}{style,ctexheading}} + \file{ctexart.cls} {\from{\jobname.dtx}{class,article}} + \file{ctexbook.cls} {\from{\jobname.dtx}{class,book}} + \file{ctexrep.cls} {\from{\jobname.dtx}{class,report}} + \file{ctexbeamer.cls} {\from{\jobname.dtx}{class,beamer}} + \usepostamble\emptypostamble + \file{ctxdoc.cls} {\from{\jobname.dtx}{ctxdoc}} + \file{ctexcap.sty} {\from{\jobname.dtx}{ctexcap}} + \file{ctexhook.sty} {\from{\jobname.dtx}{ctexhook}} + \file{ctexpatch.sty} {\from{\jobname.dtx}{ctexpatch}} + \file{ctex-c5size.clo} {\from{\jobname.dtx}{c5size}} + \file{ctex-cs4size.clo} {\from{\jobname.dtx}{cs4size}} + \file{ctex-article.def} {\from{\jobname.dtx}{heading,article}} + \file{ctex-book.def} {\from{\jobname.dtx}{heading,book}} + \file{ctex-report.def} {\from{\jobname.dtx}{heading,report}} + \file{ctex-beamer.def} {\from{\jobname.dtx}{heading,beamer}} + \file{ctex-scheme-plain.def} {\from{\jobname.dtx}{scheme,generic,plain}} + \file{ctex-scheme-plain-article.def} {\from{\jobname.dtx}{scheme,article,plain}} + \file{ctex-scheme-plain-book.def} {\from{\jobname.dtx}{scheme,book,plain}} + \file{ctex-scheme-plain-report.def} {\from{\jobname.dtx}{scheme,report,plain}} + \file{ctex-scheme-plain-beamer.def} {\from{\jobname.dtx}{scheme,beamer,plain}} + \file{ctex-scheme-chinese.def} {\from{\jobname.dtx}{scheme,generic,chinese}} + \file{ctex-scheme-chinese-article.def} {\from{\jobname.dtx}{scheme,article,chinese}} + \file{ctex-scheme-chinese-book.def} {\from{\jobname.dtx}{scheme,book,chinese}} + \file{ctex-scheme-chinese-report.def} {\from{\jobname.dtx}{scheme,report,chinese}} + \file{ctex-scheme-chinese-beamer.def} {\from{\jobname.dtx}{scheme,beamer,chinese}} + \file{ctex-name-gbk.cfg} {\from{\jobname.dtx}{name,GBK}} + \file{ctex-name-utf8.cfg} {\from{\jobname.dtx}{name,UTF8}} + \file{ctex.cfg} {\from{\jobname.dtx}{config}} + \file{ctexopts.cfg} {\from{\jobname.dtx}{ctexopts}} + \file{ctex-engine-pdftex.def} {\from{\jobname.dtx}{pdftex}} + \file{ctex-engine-xetex.def} {\from{\jobname.dtx}{xetex}} + \file{ctex-engine-luatex.def} {\from{\jobname.dtx}{luatex}} + \file{ctex-engine-aptex.def} {\from{\jobname.dtx}{aptex}} + \file{ctex-engine-uptex.def} {\from{\jobname.dtx}{uptex}} + \file{c19rm.fd} {\from{\jobname.dtx}{fd,rm,c19}} + \file{c19sf.fd} {\from{\jobname.dtx}{fd,sf,c19}} + \file{c19tt.fd} {\from{\jobname.dtx}{fd,tt,c19}} + \file{c70rm.fd} {\from{\jobname.dtx}{fd,rm,c70}} + \file{c70sf.fd} {\from{\jobname.dtx}{fd,sf,c70}} + \file{c70tt.fd} {\from{\jobname.dtx}{fd,tt,c70}} + \file{jy2zhrm.fd} {\from{\jobname.dtx}{fd,rm,jy2}} + \file{jy2zhsf.fd} {\from{\jobname.dtx}{fd,sf,jy2}} + \file{jy2zhtt.fd} {\from{\jobname.dtx}{fd,tt,jy2}} + \file{jt2zhrm.fd} {\from{\jobname.dtx}{fd,rm,jt2}} + \file{jt2zhsf.fd} {\from{\jobname.dtx}{fd,sf,jt2}} + \file{jt2zhtt.fd} {\from{\jobname.dtx}{fd,tt,jt2}} + \file{ctex-fontset-windows.def} {\from{\jobname.dtx}{fontset,windows}} + \file{ctex-fontset-windowsnew.def} {\from{\jobname.dtx}{fontset,windowsnew}} + \file{ctex-fontset-windowsold.def} {\from{\jobname.dtx}{fontset,windowsold}} + \file{ctex-fontset-adobe.def} {\from{\jobname.dtx}{fontset,adobe}} + \file{ctex-fontset-fandol.def} {\from{\jobname.dtx}{fontset,fandol}} + \file{ctex-fontset-mac.def} {\from{\jobname.dtx}{fontset,mac}} + \file{ctex-fontset-macold.def} {\from{\jobname.dtx}{fontset,macold}} + \file{ctex-fontset-macnew.def} {\from{\jobname.dtx}{fontset,macnew}} + \file{ctex-fontset-founder.def} {\from{\jobname.dtx}{fontset,founder}} + \file{ctex-fontset-ubuntu.def} {\from{\jobname.dtx}{fontset,ubuntu}} + \file{translator-theorem-dictionary-ChineseGBK.dict} + {\from{\jobname.dtx}{dict,theorem,GBK}} + \file{translator-theorem-dictionary-ChineseUTF8.dict} + {\from{\jobname.dtx}{dict,theorem,UTF8}} + \file{ctexspa.def} + { + \from{\jobname.dtx} {ctexspa} + \from{ctexpunct.spa} {} + } + \usedir{tex/generic/ctex} + \file{ctexmakespa.tex} {\from{\jobname.dtx}{spa,make}} + \file{ctexspamacro.tex} {\from{\jobname.dtx}{spa,macro}} + \file{zhadobefonts.tex} {\from{\jobname.dtx}{zhmap,adobe}} + \file{zhfandolfonts.tex} {\from{\jobname.dtx}{zhmap,fandol}} + \file{zhfounderfonts.tex} {\from{\jobname.dtx}{zhmap,founder}} + \file{zhubuntufonts.tex} {\from{\jobname.dtx}{zhmap,ubuntu}} + \file{zhwindowsfonts.tex} {\from{\jobname.dtx}{zhmap,windows}} + \file{ctxdocstrip.tex} {\from{\jobname.dtx}{docstrip}} +%</install> +%<*internal> + \usedir{source/latex/ctex} + \file{\jobname.ins} {\from{\jobname.dtx}{install}} +%</internal> +%<*install> + \nopreamble\nopostamble + \usedir{doc/latex/ctex} + \file{README.md} {\from{\jobname.dtx}{readme}} + } + +\catcode32=12\space + +\Msg{*************************************************************} +\Msg{* *} +\Msg{* To finish the installation you have to move the following *} +\Msg{* file into proper directories searched by TeX: *} +\Msg{* *} +\Msg{* The recommended directory is TDS:tex/latex/ctex *} +\Msg{* *} +\Msg{* ctex.sty *} +\Msg{* ctexsize.sty *} +\Msg{* ctexheading.sty *} +\Msg{* ctexart.cls *} +\Msg{* ctexbook.cls *} +\Msg{* ctexrep.cls *} +\Msg{* ctexbeamer.cls *} +\Msg{* ctxdoc.cls *} +\Msg{* ctexcap.sty *} +\Msg{* ctexhook.sty *} +\Msg{* ctexpatch.sty *} +\Msg{* ctex-c5size.clo *} +\Msg{* ctex-cs4size.clo *} +\Msg{* ctex-article.def *} +\Msg{* ctex-book.def *} +\Msg{* ctex-report.def *} +\Msg{* ctex-beamer.def *} +\Msg{* ctex-scheme-plain.def *} +\Msg{* ctex-scheme-plain-article.def *} +\Msg{* ctex-scheme-plain-book.def *} +\Msg{* ctex-scheme-plain-report.def *} +\Msg{* ctex-scheme-plain-beamer.def *} +\Msg{* ctex-scheme-chinese.def *} +\Msg{* ctex-scheme-chinese-article.def *} +\Msg{* ctex-scheme-chinese-book.def *} +\Msg{* ctex-scheme-chinese-report.def *} +\Msg{* ctex-scheme-chinese-beamer.def *} +\Msg{* ctex-name-gbk.cfg *} +\Msg{* ctex-name-utf8.cfg *} +\Msg{* ctex.cfg *} +\Msg{* ctexopts.cfg *} +\Msg{* ctex-engine-pdftex.def *} +\Msg{* ctex-engine-xetex.def *} +\Msg{* ctex-engine-luatex.def *} +\Msg{* ctex-engine-aptex.def *} +\Msg{* ctex-engine-uptex.def *} +\Msg{* c19rm.fd *} +\Msg{* c19sf.fd *} +\Msg{* c19tt.fd *} +\Msg{* c70rm.fd *} +\Msg{* c70sf.fd *} +\Msg{* c70tt.fd *} +\Msg{* jy2zhrm.fd *} +\Msg{* jy2zhsf.fd *} +\Msg{* jy2zhtt.fd *} +\Msg{* jt2zhrm.fd *} +\Msg{* jt2zhsf.fd *} +\Msg{* jt2zhtt.fd *} +\Msg{* ctex-fontset-windows.def *} +\Msg{* ctex-fontset-windowsnew.def *} +\Msg{* ctex-fontset-windowsold.def *} +\Msg{* ctex-fontset-adobe.def *} +\Msg{* ctex-fontset-fandol.def *} +\Msg{* ctex-fontset-mac.def *} +\Msg{* ctex-fontset-macold.def *} +\Msg{* ctex-fontset-macnew.def *} +\Msg{* ctex-fontset-founder.def *} +\Msg{* ctex-fontset-ubuntu.def *} +\Msg{* ctexspa.def *} +\Msg{* ctexmakespa.tex *} +\Msg{* ctexspamacro.tex *} +\Msg{* ctxdocstrip.tex *} +\Msg{* zhadobefonts.tex *} +\Msg{* zhfandolfonts.tex *} +\Msg{* zhfounderfonts.tex *} +\Msg{* zhubuntufonts.tex *} +\Msg{* zhwindowsfonts.tex *} +\Msg{* translator-theorem-dictionary-ChineseGBK.dict *} +\Msg{* translator-theorem-dictionary-ChineseUTF8.dict *} +\Msg{* *} +\Msg{* To produce the documentation run the file ctex.dtx *} +\Msg{* through XeLaTeX. *} +\Msg{* *} +\Msg{* Happy TeXing! *} +\Msg{* *} +\Msg{*************************************************************} + +\endbatchfile +%</install> +%<*internal> +\fi +%</internal> +%<*!(driver|readme|install|zhmap|spa|docstrip)> +%<*!(fd|ctexspa|dict)> +%<class|style|ctexcap|ctexhook|ctexpatch|ctxdoc>\NeedsTeXFormat{LaTeX2e} +%<class|style|ctexcap|ctexhook|ctexpatch|ctxdoc>\RequirePackage{expl3} +%<+!driver>\GetIdInfo$Id: ctex.dtx 735dfe2 2019-05-29 21:42:29 +0800 Qing Lee <sobenlee@gmail.com> $ +%<ctxdoc> {ctex documentation (CTEX)} +%<ctxdoc>\ProvidesExplClass{ctxdoc} +%<ctex> {Chinese adapter in LaTeX (CTEX)} +%<ctex>\ProvidesExplPackage{\ExplFileName} +%<ctexsize> {Chinese font size definition (CTEX)} +%<ctexsize>\ProvidesExplPackage{ctexsize} +%<ctexheading> {Heading style modification (CTEX)} +%<ctexheading>\ProvidesExplPackage{ctexheading} +%<class&article> {Chinese adapter for class article (CTEX)} +%<class&article>\ProvidesExplClass{ctexart} +%<class&book> {Chinese adapter for class book (CTEX)} +%<class&book>\ProvidesExplClass{ctexbook} +%<class&report> {Chinese adapter for class report (CTEX)} +%<class&report>\ProvidesExplClass{ctexrep} +%<class&beamer> {Chinese adapter for class beamer (CTEX)} +%<class&beamer>\ProvidesExplClass{ctexbeamer} +%<ctexcap> {Chinese adapter in LaTeX (CTEX)} +%<ctexcap>\ProvidesExplPackage{ctexcap} +%<ctexhook> {Document and package hooks (CTEX)} +%<ctexhook>\ProvidesExplPackage{ctexhook} +%<ctexpatch> {Patching commands (CTEX)} +%<ctexpatch>\ProvidesExplPackage{ctexpatch} +%<c5size> {c5size option (CTEX)} +%<c5size>\ProvidesExplFile{ctex-c5size.clo} +%<cs4size> {cs4size option (CTEX)} +%<cs4size>\ProvidesExplFile{ctex-cs4size.clo} +%<heading&article> {Heading modification for article (CTEX)} +%<heading&article>\ProvidesExplFile{ctex-article.def} +%<heading&book> {Heading modification for book (CTEX)} +%<heading&book>\ProvidesExplFile{ctex-book.def} +%<heading&report> {Heading modification for report (CTEX)} +%<heading&report>\ProvidesExplFile{ctex-report.def} +%<heading&beamer> {Heading modification for beamer (CTEX)} +%<heading&beamer>\ProvidesExplFile{ctex-beamer.def} +%<scheme&plain&generic> {Plain scheme for generic (CTEX)} +%<scheme&plain&generic>\ProvidesExplFile{ctex-scheme-plain.def} +%<scheme&plain&article> {Plain scheme for article (CTEX)} +%<scheme&plain&article>\ProvidesExplFile{ctex-scheme-plain-article.def} +%<scheme&plain&book> {Plain scheme for book (CTEX)} +%<scheme&plain&book>\ProvidesExplFile{ctex-scheme-plain-book.def} +%<scheme&plain&report> {Plain scheme for report (CTEX)} +%<scheme&plain&report>\ProvidesExplFile{ctex-scheme-plain-report.def} +%<scheme&plain&beamer> {Plain scheme for beamer (CTEX)} +%<scheme&plain&beamer>\ProvidesExplFile{ctex-scheme-plain-beamer.def} +%<scheme&chinese&generic> {Chinese scheme for generic (CTEX)} +%<scheme&chinese&generic>\ProvidesExplFile{ctex-scheme-chinese.def} +%<scheme&chinese&article> {Chinese scheme for article (CTEX)} +%<scheme&chinese&article>\ProvidesExplFile{ctex-scheme-chinese-article.def} +%<scheme&chinese&book> {Chinese scheme for book (CTEX)} +%<scheme&chinese&book>\ProvidesExplFile{ctex-scheme-chinese-book.def} +%<scheme&chinese&report> {Chinese scheme for report (CTEX)} +%<scheme&chinese&report>\ProvidesExplFile{ctex-scheme-chinese-report.def} +%<scheme&chinese&beamer> {Chinese scheme for beamer (CTEX)} +%<scheme&chinese&beamer>\ProvidesExplFile{ctex-scheme-chinese-beamer.def} +%<name&GBK> {Caption with encoding GBK (CTEX)} +%<name&GBK>\ProvidesExplFile{ctex-name-gbk.cfg} +%<name&UTF8> {Caption with encoding UTF8 (CTEX)} +%<name&UTF8>\ProvidesExplFile{ctex-name-utf8.cfg} +%<config> {Configuration file (CTEX)} +%<config>\ProvidesExplFile{\ExplFileName.cfg} +%<ctexopts> {Option configuration file (CTEX)} +%<ctexopts>\ProvidesExplFile{ctexopts.cfg} +%<pdftex> {(pdf)LaTeX adapter (CTEX)} +%<pdftex>\ProvidesExplFile{ctex-engine-pdftex.def} +%<xetex> {XeLaTeX adapter (CTEX)} +%<xetex>\ProvidesExplFile{ctex-engine-xetex.def} +%<luatex> {LuaLaTeX adapter (CTEX)} +%<luatex>\ProvidesExplFile{ctex-engine-luatex.def} +%<aptex> {Asian pTeX adapter (CTEX)} +%<aptex>\ProvidesExplFile{ctex-engine-aptex.def} +%<uptex> {upTeX adapter (CTEX)} +%<uptex>\ProvidesExplFile{ctex-engine-uptex.def} +%<windows> {Windows fonts definition (CTEX)} +%<windows>\ProvidesExplFile{ctex-fontset-windows.def} +%<windowsnew> {Windows fonts definition for Vista or later version (CTEX)} +%<windowsnew>\ProvidesExplFile{ctex-fontset-windowsnew.def} +%<windowsold> {Windows fonts definition for XP or earlier version (CTEX)} +%<windowsold>\ProvidesExplFile{ctex-fontset-windowsold.def} +%<adobe> {Adobe fonts definition (CTEX)} +%<adobe>\ProvidesExplFile{ctex-fontset-adobe.def} +%<fandol> {Fandol fonts definition (CTEX)} +%<fandol>\ProvidesExplFile{ctex-fontset-fandol.def} +%<mac> {Mac OS X fonts definition (CTEX)} +%<mac>\ProvidesExplFile{ctex-fontset-mac.def} +%<macnew> {Mac OS X fonts definition for El Capitan or later version (CTEX)} +%<macnew>\ProvidesExplFile{ctex-fontset-macnew.def} +%<macold> {Mac OS X fonts definition for Yosemite or earlier version (CTEX)} +%<macold>\ProvidesExplFile{ctex-fontset-macold.def} +%<founder> {Founder fonts definition (CTEX)} +%<founder>\ProvidesExplFile{ctex-fontset-founder.def} +%<ubuntu> {Ubuntu fonts definition (CTEX)} +%<ubuntu>\ProvidesExplFile{ctex-fontset-ubuntu.def} +%<!driver> {\ExplFileDate}{2.4.16}{\ExplFileDescription} +%</!(fd|ctexspa|dict)> +%<c19&rm>\ProvidesFile{c19rm.fd}% +%<c19&sf>\ProvidesFile{c19sf.fd}% +%<c19&tt>\ProvidesFile{c19tt.fd}% +%<c70&rm>\ProvidesFile{c70rm.fd}% +%<c70&sf>\ProvidesFile{c70sf.fd}% +%<c70&tt>\ProvidesFile{c70tt.fd}% +%<jy2&rm>\ProvidesFile{jy2zhrm.fd}% +%<jy2&sf>\ProvidesFile{jy2zhsf.fd}% +%<jy2&tt>\ProvidesFile{jy2zhtt.fd}% +%<jt2&rm>\ProvidesFile{jt2zhrm.fd}% +%<jt2&sf>\ProvidesFile{jt2zhsf.fd}% +%<jt2&tt>\ProvidesFile{jt2zhtt.fd}% +%<ctexspa>\ProvidesFile{ctexspa.def}% +%<dict&theorem&GBK>\ProvidesDictionary{translator-theorem-dictionary}{ChineseGBK}% +%<dict&theorem&UTF8>\ProvidesDictionary{translator-theorem-dictionary}{ChineseUTF8}% +%<fd> [2019/05/29 v2.4.16 Chinese font definition (CTEX)] +%<ctexspa> [2019/05/29 v2.4.16 Space info for CJKpunct (CTEX)] +%<dict&theorem> [2019/05/29 v2.4.16 Chinese translation for theorem name (CTEX)] +%</!(driver|readme|install|zhmap|spa|docstrip)> +%<*driver> +\documentclass{ctxdoc} +\begin{document} + \DocInput{\jobname.dtx} + \IndexLayout + \PrintChanges + \PrintIndex +\end{document} +%</driver> +% +% \fi +% +% \changes{v2.0}{2014/03/06}{应用 \LaTeXiii{} 重新整理代码。} +% \changes{v2.0}{2014/03/12}{删除 \file{c19gbsn.fd} 和 \file{c19gkai.fd}。} +% \changes{v2.1}{2015/05/18}{将章节标题设置功能提取到可以独立使用的宏包 +% \pkg{ctexheading} 中。} +% \changes{v2.2}{2015/06/24}{不再依赖 \pkg{etoolbox} 宏包。} +% \changes{v2.4}{2015/02/19}{加强 \pkg{beamer} 宏包支持。} +% \changes{v2.4.12}{2018/01/13}{同步 \LaTeXiii{} 2017/12/16。} +% \changes{v2.4.15}{2019/03/23}{同步 \LaTeXiii{} 2019/03/05。} +% +% +% \CheckSum{5934} +% +% \CharacterTable +% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z +% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z +% Digits \0\1\2\3\4\5\6\7\8\9 +% Exclamation \! Double quote \" Hash (number) \# +% Dollar \$ Percent \% Ampersand \& +% Acute accent \' Left paren \( Right paren \) +% Asterisk \* Plus \+ Comma \, +% Minus \- Point \. Solidus \/ +% Colon \: Semicolon \; Less than \< +% Equals \= Greater than \> Question mark \? +% Commercial at \@ Left bracket \[ Backslash \\ +% Right bracket \] Circumflex \^ Underscore \_ +% Grave accent \` Left brace \{ Vertical bar \| +% Right brace \} Tilde \~} +% +% \GetFileId{ctex.sty}% +% +% \title{\bfseries \CTeX{} 宏集手册} +% \author{\href{http://www.ctex.org}{CTEX.ORG}} +% \date{\filedate\qquad\fileversion\thanks{\ctexkitrev{\ExplFileVersion}.}} +% \maketitle +% +% \begin{abstract} +% \CTeX{} 宏集是面向中文排版的通用 \LaTeX{} 排版框架,为中文 \LaTeX{} 文档 +% 提供了汉字输出支持、标点压缩、字体字号命令、标题文字汉化、中文版式调整、数字 +% 日期转换等支持功能,可适应论文、报告、书籍、幻灯片等不同类型的中文文档。 +% +% \CTeX{} 宏集支持 \LaTeX、\pdfLaTeX、\XeLaTeX、\LuaLaTeX、\upLaTeX{} 等多种不同 +% 的编译方式,并为它们提供了统一的界面。主要功能由宏包 \pkg{ctex} 和中文文档类 +% \cls{ctexart}、\cls{ctexrep}、\cls{ctexbook} 和 \cls{ctexbeamer} 实现。 +% \end{abstract} +% +% \tableofcontents +% +% \clearpage +% \setlength{\parskip}{0.8ex} +% +% \begin{documentation} +% +% \section{介绍} +% +% \subsection*{历史} +% +% \CTeX{} 宏集的源头有两个:一是王磊编写的 \cls{cjkbook} 文档类,二是吴凌云编写的 +% \file{GB.cap}。 +% 这些工作没有经过认真、系统的设计,也没有用户文档,不利于维护和改进。 +% +% 2003 年,吴凌云使用 \pkg{doc} 和 \pkg{DocStrip} 重构了整个工程,并增加了许多新的功能, +% 称为 \pkg{ctex} 宏包。2007 年,oseen 和王越在 \pkg{ctex} 宏包的基础上, +% 增加了对 UTF-8 编码的支持,开发出了 \pkg{ctexutf8} 宏包。 +% +% 2009 年 5 月,我们在 Google Code 建立了 ctex-kit 项目^^A +% \footnote{\nolinkurl{http://code.google.com/p/ctex-kit/}}, +% 对 \pkg{ctex} 宏包及相关脚本进行了整合,并加入了对 \XeTeX{} 引擎的支持。 +% 在开发新版本时,考虑到合作开发和调试的方便,我们放弃了 \pkg{doc} 和 \pkg{DocStrip}, +% 采取了直接编写宏包代码的方式。 +% +% 2014 年 3 月,为了适应 \LaTeX{} 的最新发展,特别是 \LaTeXiii{} 的逐渐成熟,李清用 +% \LaTeXiii{} 重构了整个宏包的代码,并重新使用 \pkg{doc} 和 \pkg{DocStrip} 工具进行代码 +% 的管理,升级版本号为 2.0,并改称 \CTeX{} 宏集。 +% +% 2015 年 3 月,由于 Google Code 即将停止服务,ctex-kit 项目迁移至 +% \href{https://github.com/CTeX-org/ctex-kit}{GitHub}^^A +% \footnote{\url{https://github.com/CTeX-org/ctex-kit}}。 +% +% 最初,Knuth 在设计开发 \TeX{} 的时候没有考虑到多国语言支持,特别是对多字节的中日韩 +% 语言的支持。这使得 \TeX{} 以至后来的 \LaTeX{} 对中文的支持一直不是很好。即使在 +% \pkg{CJK} 宏包解决了中文字符处理的问题以后,中文用户使用 \LaTeX{} 仍然要面对许 +% 多困难。 +% 这些困难里,以章节标题的中文化为最。由于中文和西文语言习惯的差异,用户很难使用标准 +% 文档类中的代码结构来表达中文标题。于是,用户不得不对标准文档类做较大的修改。 +% 除此之外,日期格式、首行缩进、中文字号和字距等细节问题,也需要精细的调校。 +% 我们设计 \CTeX{} 宏集的目的之一就是解决这些 \LaTeX{} 文档的汉化难题。 +% +% 另一方面,随着 \TeX{} 引擎和 \LaTeX{} 宏包的不断发展,\LaTeX{} 的中文支持方式从早期的 +% 专用系统(如 \pkg{CCT})发展为适用于不同引擎的多种方式^^A +% \footnote{比如:\pdfTeX{} 引擎下的 \pkg{CJK}、\pkg{zhmCJK}宏包, +% \XeTeX{} 引擎下的 \pkg{xeCJK} 宏包和 \LuaTeX{} 引擎下的 \pkg{LuaTeX-ja} 宏 +% 包}。这些方式的适用情况和使用方式有不少细节上的差异,同时操作系统的不同、语言环境的不同等 +% 客观情况又进一步带来了更多的细节差异。我们设计 \CTeX{} 宏集的另一个主要目的就是 +% 尽可能消除这些差异带来的影响,使用户能够以一个统一的接口来使用不同的中文支持方式, +% 使得同一份文档能够在不同环境下交换使用。 +% +% \CTeX{} 宏集的许多实现细节离不开热心朋友们在 \url{bbs.ctex.org} 论坛上的讨论, +% 在此对参与讨论的朋友们表示感谢。 +% +% \subsection*{关于宏集名字的说明} +% +% \CTeX{} 之名是英文单词 China(中国)或 Chinese(中文)的首字母“C”与 “\TeX{}” +% 结合而成的。在纯文本环境下,该名字应写作“CTeX”。 +% +% \CTeX{} 宏集是由 \href{http://bbs.ctex.org}{\CTeX{} 社区} 发起并维护的 +% \LaTeX{} \emph{宏包和文档类的集合}。 +% 社区另有发布名为 \href{http://www.ctex.org/CTeX}{\CTeX{} 套装} +% 的 \TeX{} 发行版,与本文档所述的 \CTeX{} 宏集并非是同一事物。 +% +% \pkg{ctex} 则是本宏集中的 \pkg{ctex.sty} 的名字。这一完全小写的名称,在过去 +% 也被用来指代整个 \CTeX{} 宏集,不过现在则特指 \pkg{ctex.sty} 这一宏包。 +% 在不引起歧义的情况下,它也可以沿用过去的习惯,代指整个宏集。 +% +% \section{简明教程} +% +% \subsection{\CTeX{} 宏集的组成} +% +% 为了适应用户不同的需求,我们将 \CTeX{} 宏集的主要功能分散在四个中文文档类和 +% 三个宏包当中,具体的组成见表~\ref{tab:ctex}。 +% +% \begin{table}[htbp] +% \centering +% \caption{\CTeX{} 宏集的组成}\label{tab:ctex} +% \begin{tabularx}{\linewidth}{llX} +% \toprule +% 类别 & 文件 & 说明 \\ +% \midrule +% 文档类 & \file{ctexart.cls} & 标准文档类 \cls{article} 的汉化版本,一般适用于 +% 短篇幅的文章 \\ +% & \file{ctexrep.cls} & 标准文档类 \cls{report} 的汉化版本,一般适用于 +% 中篇幅的报告 \\ +% & \file{ctexbook.cls} & 标准文档类 \cls{book} 的汉化版本,一般适用于 +% 长篇幅的书籍 \\ +% & \file{ctexbeamer.cls} & 文档类 \cls{beamer} 的汉化版本,适用于 +% 幻灯片演示 \\ +% \midrule +% 宏包 & \file{ctex.sty} & 提供全部功能,但\emph{默认不开启章节标题设置功能}, +% 需要使用 \opt{heading} 选项来开启 \\ +% & \file{ctexsize.sty} & 定义和调整中文字号,在 \pkg{ctex} 宏包 +% 或 \CTeX{} 中文文档类之外单独调用 \\ +% & \file{ctexheading.sty} & 提供章节标题设置功能(见 \ref{sec:secstyle} +% 节),在 \pkg{ctex} 宏包或 \CTeX{} 中文 +% 文档类之外单独调用 \\ +% \bottomrule +% \end{tabularx} +% \end{table} +% +% \subsection{\CTeX{} 宏集的安装和更新} +% \label{subsec:easy-ins} +% +% \CTeX{} 宏集依赖的宏包和宏集已被最常见的 \TeX{} 发行版 \TeXLive{} 和 \MiKTeX{} +% 所收录。如果本地安装 \TeXLive{} 或 \MiKTeX{} 不是完全版本,就可能需要通过这 +% 两个发行版提供的\emph{宏包管理器}来安装宏包。 +% +% \TeXLive{} 的宏包管理器是 tlmgr。用户可以在系统命令行中^^A +% \footnote{Windows 系统的命令行是 CMD 命令提示符,你可以使用 Win + R 组合键^^A +% 打开“运行”对话框,然后输入 cmd 确认打开命令提示符窗口。}^^A +% 执行 +% \begin{frameverb} +% tlmgr gui +% \end{frameverb} +% 启动管理器的图形界面(Windows 用户也可以通过开始菜单的 +% TeX Live 2015 \ding{212} TeX Live Manager 打开)。 +% 连接上远程仓库之后,搜索 ctex 安装即可。 +% tlmgr 的图形界面使用 Perl 编写,容易造成系统假死。遇到这种问题的用户, +% 也可以直接在系统命令行执行 +% \begin{frameverb} +% tlmgr install ctex +% \end{frameverb} +% 来安装 \CTeX{} 宏集\footnote{*nix 用户可能需要超级用户权限才能正确安装宏集。}。 +% +% \MiKTeX{} 的宏包管理器是 mpm (\MiKTeX{} Package Manager)。用户可以在开始菜单 +% 找到 MiKTeX \ding{212} Maintenance (Admin) \ding{212} Package Manager (Admin), +% 打开管理器,连接上远程仓库之后,搜索 ctex 安装即可。 +% +% 若希望了解 \CTeX{} 宏集具体的依赖情况和手工安装宏集的方法, +% 请参阅第 \ref{sec:dep-ins}~节。 +% +% 当宏包发布新版本,并被发行版在远程仓库安装之后,在本地就可以通过宏包管理器来 +% 取得新版本。 +% +% 对于 \TeXLive{},可以在 tlmgr 的图形界面点击“更新全部已安装的”按钮或者在 +% 命令行执行 +% \begin{frameverb} +% tlmgr update --all +% \end{frameverb} +% 来完整更新已安装的宏包。 +% +% 对于 \MiKTeX{},在开始菜单找到 +% MiKTeX \ding{212} Maintenance (Admin) \ding{212} Update (Admin), +% 按照界面说明更新即可。 +% +% \subsection{使用 \CTeX{} 文档类} +% +% \emph{如果用户需要在标准文档类的基础上添加中文支持和中文版式支持,我们建议用户使用 \CTeX{} +% 宏集提供的四个中文文档类。} +% +% \CTeX{} 宏集提供了四个中文文档类:\cls{ctexart}、\cls{ctexrep}、\cls{ctexbook} 和 +% \cls{ctexbeamer},分别对应 \LaTeX{} 的标准文档类 \cls{article}、\cls{report}、 +% \cls{book} 和 \cls{beamer}。使用它们的时候,需要将涉及到的所有源文件使用 UTF-8 +% 编码保存\footnote{使用 (pdf)\LaTeX{} 时也能够使用 GBK 编码,但不推荐。(见 +% \ref{subs:encoding}~节)}。 +% +% \begin{ctexexam} +% \documentclass[UTF8]{ctexart} +% \begin{document} +% 中文文档类测试。你需要将所有源文件保存为 UTF-8 编码。 +% +% 你可以使用 XeLaTeX、LuaLaTeX 或 upLaTeX 编译,也可以使用 (pdf)LaTeX 编译。 +% 推荐使用 XeLaTeX 或 LuaLaTeX 编译。 +% \end{document} +% \end{ctexexam} +% +% 以下是使用 \cls{ctexbeamer} 文档类编写中文演示文稿的一个示例。 +% \begin{ctexexam} +% \documentclass[UTF8]{ctexbeamer} +% \begin{document} +% \begin{frame}{中文演示文档} +% \begin{itemize} +% \item 你需要将所有源文件保存为 UTF-8 编码 +% \item 你可以使用 XeLaTeX、LuaLaTeX 或 upLaTeX 编译 +% \item 也可以使用 (pdf)LaTeX 编译 +% \item 推荐使用 XeLaTeX 或 LuaLaTeX 编译 +% \end{itemize} +% \end{frame} +% \end{document} +% \end{ctexexam} +% +% \subsection{使用 \pkg{ctex} 宏包} +% +% \emph{用户在使用非标准文档类时,如果需要添加中文支持或中文版式支持,则可以使用 \pkg{ctex} +% 宏包。} +% +% 有些文档类是建立在 \LaTeX{} 标准文档类之上开发的。这时,给 \pkg{ctex} 宏包 +% 加上 \opt{heading} 选项,可以将章节标题设置为中文风格。 +% \begin{ctexexam} +% \documentclass{ltxdoc} +% \usepackage[UTF8, heading = true]{ctex} +% \begin{document} +% \section{简介} +% 章节标题中文化的 \LaTeX{} 手册。 +% \end{document} +% \end{ctexexam} +% +% \section{宏包选项与 \tn{ctexset} 命令} +% \label{sec:options} +% +% \CTeX{} 宏集已经尽可能就中文的行文和版式习惯做了调整和配置,通常而言,这些配置 +% 已经够用。因此,除非必要,我们不建议普通用户修改这些默认配置。如果你认为 \CTeX{} 宏集 +% 的默认配置还可以完善,可以在项目主页上% +% \href{https://github.com/CTeX-org/ctex-kit/issues}{提交 issue}, +% 向我们反映,我们会酌情在后续版本中予以改进。 +% +% 不过,\CTeX{} 宏集也提供了一系列选项。用户可以使用这些选项来控制 \CTeX{} 宏集的行为。 +% 具体来说,这些选项里,有的以传统的方式提供, +% 也有的以 \meta{key}|=|\meta{value} 的形式提供。对于以键值对形式提供的选项, +% 在下面的说明中使用\textbf{粗体}来表示 \CTeX{} 的默认设置。 +% +% 另一方面,这些选项可以分为以下三类: +% \begin{itemize} +% \item 名字后带有 \rexptarget\rexpstar{} 号的选项,只能作为宏包/文档类选项,需要 +% 在引入宏包/文档类的时候指定; +% \item 名字后带有 \exptarget\expstar{} 号的选项,只能通过 \CTeX{} 宏集提供的 +% 用户接口 \tn{ctexset} 来设定; +% \item 名字后不带有特殊符号的选项,既可以作为宏包/文档类选项,也可以通过 +% \tn{ctexset} 来设定。 +% \end{itemize} +% 后续文档将在使用说明中对某些特殊的选项加以说明。 +% +% \begin{function}[added=2014-03-18]{\ctexset} +% \begin{syntax} +% \tn{ctexset} \Arg{键值列表} +% \end{syntax} +% 是 \CTeX{} 宏集的通用控制命令,用来在宏包载入后控制宏包的各项功能。 +% \tn{ctexset} 的参数是一个键值列表,以通用的接口完成各项设置。 +% \end{function} +% +% \tn{ctexset} 的参数是一组由逗号分隔的选项列表,列表中的选项通常是一个 +% \meta{key}|=|\meta{value} 格式的定义。例如设置摘要与参考文献标题名称 +% (\ref{subs:capname}~节)就可以使用: +% \begin{ctexexam}[labelref=exam:capname] +% \ctexset{ +% abstractname = {本文概要}, +% bibname = {文\quad 献} +% } +% \end{ctexexam} +% +% \tn{ctexset} 采用 \LaTeXiii{} 风格的键值设置,支持不同类型的选项与层次化的选 +% 项设置,相关示例见 \ref{sec:secstyle}~节。 +% +% \section{编译方式、编码与中文字库} +% \label{sec:chinese} +% +% \subsection{编译方式} +% \label{subs:compile} +% +% \CTeX{} 宏集会根据用户使用的编译方式\footnote{\LaTeX、\pdfLaTeX、\XeLaTeX、 +% \LuaLaTeX{} 及 \upLaTeX。},在底层选择不同的中文支持方式(见 +% 表~\ref{tab:chinese-support})。 +% +% \begin{table}[htbp] +% \centering +% \begin{threeparttable} +% \caption{\CTeX{} 宏集的中文支持方式} +% \label{tab:chinese-support} +% \begin{tabular}{*6c} +% \toprule +% 编译方式 & (pdf)\LaTeX & \XeLaTeX & \LuaLaTeX & \upLaTeX\tnote{*} \\ +% \midrule +% 支持宏包 & \pkg{CJK} & \pkg{xeCJK} & \pkg{LuaTeX-ja} & 原生 \\ +% \bottomrule +% \end{tabular} +% \begin{tablenotes} +% \item[*] p\LaTeX-ng(或称 \ApLaTeX)与 \upLaTeX{} 兼容。使用 p\LaTeX-ng 编译 +% 时,\pkg{ctex} 采用与 \upLaTeX{} 相同的设置。 +% \end{tablenotes} +% \end{threeparttable} +% \end{table} +% +% 不同的编译方式和中文支持方式会在一定程度上影响 \CTeX{} 宏集的行为,比如宏包对 +% 编码的处理。 +% 在用户使用 \XeLaTeX、\LuaLaTeX{} 及 \upLaTeX{} 编译时,\CTeX{} 宏集使用(且仅 +% 能使用)UTF-8 编码;而因为历史原因,在用户使用 \LaTeX{} 及 \pdfLaTeX{} 编译 +% 时,宏包默认使用 GBK 编码。用户需要\emph{保证编译方式、 +% 源文件编码、宏包编码选项三者一致}。 +% 关于宏包编码选项,可以参考 \ref{subs:encoding}~节。 +% +% 除去文档编码之外,选择不同的编译方式还可能影响 \CTeX{} 宏集对字体选择、空格处理、 +% 标点处理的处理。具体的影响将在本文档后续内容中进行阐述。 +% +% \subsection{中文编码} +% \label{subs:encoding} +% +% \begin{function}[rEXP]{GBK, UTF8} +% 指明编写文档时使用的编码格式。\CTeX{} 宏集无法检测用户编写文档时使用的编码格式,因此 +% 需要用户自行指定编码。\emph{我们建议用户总是使用 UTF-8 编码,并显式指定 \opt{UTF8} +% 选项,并使用 \XeLaTeX、\LuaLaTeX{} 或 \upLaTeX{} 编译。} +% +% 使用 \XeLaTeX、\LuaLaTeX{} 或 \upLaTeX{} 编译时,\CTeX{} 宏集强制使用 UTF-8 +% 编码,此时 \opt{GBK} 选项无效。 +% 使用 (pdf)\LaTeX{} 编译时,\CTeX{} 宏集默认启用 \opt{GBK} 选项;不过,用户也可以 +% 显式声明 \opt{UTF8} 选项,使 \CTeX{} 宏集工作在 UTF-8 编码下。 +% \end{function} +% +% \subsection{中文字库} +% \label{subs:options-CJK-font} +% +% 以往,为 \LaTeX{} 文档配置中文支持是一件相当繁琐的事情。默认情况下, +% \CTeX{} 宏集能自动检测用户使用的编译方式(参见 \ref{subs:compile}~节)和 +% 操作系统\footnote{\CTeX{} 宏集现在能够识别 Mac~OS~X 系统以及 Windows 系统。}, +% 选择合适的底层支持和字库,从而简化配置过程。自动配置的情况参见 +% 表~\ref{tab:default-font-select}。 +% +% \begin{table}[htbp] +% \centering +% \begin{threeparttable} +% \caption{\CTeX{} 宏集自动配置字体策略} +% \label{tab:default-font-select} +% \begin{tabular}{*{5}{c}} +% \toprule +% & Mac OS X & Windows New\tnote{1} & Windows Old\tnote{2} & +% 其他 \\ +% \midrule +% \XeLaTeX{} & \makecell{\pkg{xeCJK}\\华文字库} & +% \makecell{\pkg{xeCJK}\\中易字库 + 微软雅黑} & \makecell{\pkg{xeCJK}\\中易字库} & +% \makecell{\pkg{xeCJK}\\Fandol 字库\tnote{3}} \\ +% \cmidrule(lr){1-5} +% \LuaLaTeX{}\tnote{4} & \makecell{\pkg{LuaTeX-ja}\\华文字库} & +% \makecell{\pkg{LuaTeX-ja}\\中易字库 + 微软雅黑} & +% \makecell{\pkg{LuaTeX-ja}\\中易字库} & +% \makecell{\pkg{LuaTeX-ja}\\Fandol 字库} \\ +% \cmidrule(lr){1-5} +% \pdfLaTeX{} & 不可用\tnote{5} & +% \makecell{\pkg{CJK} + \pkg{zhmetrics}\\中易字库 + 微软雅黑} & +% \makecell{\pkg{CJK} + \pkg{zhmetrics}\\中易字库} & 不可用\tnote{5} \\ +% \cmidrule(lr){1-5} +% \makecell{\LaTeX{} + \\\dvipdfmx{}} & 不可用\tnote{6} & +% \makecell{\pkg{CJK} + \pkg{zhmetrics}\\中易字库 + 微软雅黑} & +% \makecell{\pkg{CJK} + \pkg{zhmetrics}\\中易字库} & +% \makecell{\pkg{CJK} + \pkg{zhmetrics}\\Fandol 字库} \\ +% \cmidrule(lr){1-5} +% \makecell{\upLaTeX{} + \\\dvipdfmx{}} & 不可用\tnote{6} & +% \makecell{\pkg{zhmetrics-uptex}\\中易字库 + 微软雅黑} & +% \makecell{\pkg{zhmetrics-uptex}\\中易字库} & +% \makecell{\pkg{zhmetrics-uptex}\\Fandol 字库} \\ +% \bottomrule +% \end{tabular} +% \begin{tablenotes} +% \item [1] Windows Vista 及以后的 Windows 操作系统。 +% \item [2] Windows XP 及以前的 Windows 操作系统。 +% \item [3] 由马起园、苏杰、黄晨成等人开发的开源中文字体, +% 参见:\url{https://github.com/clerkma/fandol-fonts}。 +% \item [4] \LuaLaTeX{} 编译时使用 \pkg{LuaTeX-ja} 宏包。对此, +% 第 \ref{sec:lualatex-chinese}~节有特别说明。 +% \item [5] 受 \pdfTeX{} 的限制,无法嵌入 OpenType 字体。 +% \item [6] 目前受 \dvipdfmx{} 的限制,Mac OS X 系统上的黑体和仿宋无法读取。 +% \end{tablenotes} +% \end{threeparttable} +% \end{table} +% +% 通常,由 \CTeX{} 宏集进行的自动配置已经足够使用,无需用户手工干预;但 +% 是 \CTeX{} 仍然提供了一系列选项,供在 \CTeX{} 的自动选择机制因为 +% 意外情况失效,或者在用户有特殊需求的情况下使用。\emph{除非必要,用户不 +% 应使用这些选项。} +% +% \begin{function}[rEXP,updated=2014-03-08]{zhmap} +% \begin{syntax} +% zhmap = <\TTF|zhmCJK> +% \end{syntax} +% 指定字体映射机制。本选项只在使用 \pdfLaTeX/\LaTeX{} 编译时有意义。 +% \end{function} +% \begin{optdesc} +% \item[true] 使用 \pkg{zhmetrics} 宏包,将 CJK 字库通过 \tn{special} +% 命令映射到 \file{.ttf} 文件。 +% +% \item[false] 使用传统的 CJK 字库(Type 1)^^A +% \footnote{如果需要使用自定义的字体映射文件,或者希望使用 Type1 字库,请禁用本选项。}。 +% +% \item[zhmCJK] 载入 \pkg{zhmCJK} 宏包^^A +% \footnote{\pkg{zhmCJK} 宏包基于 \pkg{zhmetrics} 和 \pkg{CJK} 宏包,提供与 +% \pkg{xeCJK} 宏包类似的用户接口。}^^A +% ,由 \pkg{zhmCJK} 宏包提供从 CJK 字库到 \file{.ttf} 的映射。 +% \end{optdesc} +% +% \begin{function}[added=2014-03-08]{fontset} +% \begin{syntax} +% fontset =^^A +% <none|adobe|fandol|founder|mac|macnew|macold|ubuntu|windows|windowsnew|windowsold|...> +% \end{syntax} +% 指定 \CTeX{} 宏集加载的字库。 +% +% 如果没有指定 \opt{fontset} 的值,\CTeX{} 宏集将自动检测用户使用的操作系统,配置 +% 相应的字体(参见表~\ref{tab:default-font-select})。 +% \end{function} +% +% \CTeX{} 预定义了以下六种中文字库。 +% +% \begin{optdesc} +% \item[adobe] 使用 Adobe 公司的四款中文字体,\emph{不支持 \pdfLaTeX}。 +% \item[fandol] 使用 Fandol 中文字体,\emph{不支持 \pdfLaTeX}。 +% \item[founder] 使用方正公司的中文字体。 +% \item[mac] 使用 Mac OS X 系统下的字体,\emph{不支持 (pdf)\LaTeX}。 +% \item[macnew] 使用 El Capitan 或之后的多字重宋体、苹方黑体。 +% \item[macold] 使用 Yosemite 或之前的华文字库。 +% \item[ubuntu] 使用 Ubuntu 系统下的文泉驿和文鼎字体。 +% \item[windows] 使用简体中文 Windows 系统下的中文字体,自动判断 Windows 系 +% 统版本,采用 |windowsnew| 或 |windowsold| 的设置。 +% \item[windowsnew] 使用简体中文 Windows Vista 或之后系统下的中易字体和微软 +% 雅黑字体。 +% \item[windowsold] 使用简体中文 Windows XP 或之前系统下的中易字体。 +% \end{optdesc} +% +% 注意:使用 (pdf)\LaTeX{} 编译的时候,若设置 \opt{zhmap = false}(比如需要 +% 使用 \LaTeX{} + Dvips 编译),则需要按照传统方式^^A +% \footnote{可以使用 \pkg{zhmetrics} 宏包提供的脚本 +% \href{https://github.com/CTeX-org/ctex-kit/blob/master/zhmetrics/CTeXFonts.lua} +% {\file{CTeXFonts.lua}}。}^^A +% 在本地安装好 CJK 字体。 +% +% 如果不想使用 \CTeX{} 预定义的中文字库,可以设置 \opt{fontset} 为下述值之一。 +% +% \begin{optdesc} +% \item[none] 不配置中文字体,需要用户自己配置。 +% \item[\meta{name}] 这里 \meta{name} 为自定义的名字。 +% \CTeX{} 宏集将载入名为 |ctex-fontset-|\meta{name}|.def| 的文件作为字体配置 +% 文件。因此,请先保证文件的存在。可以在当前工作目录或者本地 \texttt{TDS} 目录 +% 树下合适位置建立一个名为 |ctex-fontset-|\meta{name}|.def| 的文件,在这个文件 +% 里面自定义中文字体。然后通过使用 |fontset=|\meta{name} 选项来调用它。字体配置 +% 文件的具体写法可以参考 \CTeX{} 宏集 \texttt{fontset} 目录下的字体配置文件。 +% \end{optdesc} +% +% 注意:\emph{如果希望使用 \tn{ctexset} 在导言区指定字库,则需要先在宏包/文档类选项中指定 +% \opt{fontset = none}}。例如: +% \begin{ctexexam} +% \documentclass[fontset = none]{ctexart} +% \ctexset{fontset = founder} +% \begin{document} +% 在文档类选项中声明 \verb|fontset = none|,随后在导言区用 \verb|\ctexset| +% 指定字体。 +% \end{document} +% \end{ctexexam} +% +% \CTeX{} 宏集预定义的中文字库还定义了一些字体命令。除了在 \opt{ubuntu} 字库中没有 +% \tn{fangsong} 的定义外,所有字库都有以下四个字体命令。 +% +% \begin{optdesc} +% \item[\tn{songti}] 宋体,CJK 等价命令 |\CJKfamily{zhsong}|。 +% \item[\tn{heiti}] 黑体,CJK 等价命令 |\CJKfamily{zhhei}|。 +% \item[\tn{fangsong}] 仿宋,CJK 等价命令 |\CJKfamily{zhfs}|。 +% \item[\tn{kaishu}] 楷书,CJK 等价命令 |\CJKfamily{zhkai}|。 +% \end{optdesc} +% +% 在 \opt{windows} 和 \opt{founder} 字库中,额外定义了 \tn{lishu} 和 \tn{youyuan}。 +% \begin{optdesc} +% \item[\tn{lishu}] 隶书,CJK 等价命令 |\CJKfamily{zhli}|。 +% \item[\tn{youyuan}] 圆体,CJK 等价命令 |\CJKfamily{zhyou}|。 +% \end{optdesc} +% 在 \opt{windowsnew} 和 \opt{macnew} 字库中,还有 \tn{yahei}。 +% 其中在 \opt{macnew} 字库中,\tn{yahei} 实际调用苹方黑体。此举乃是为了更好的兼容性而设。 +% \begin{optdesc} +% \item[\tn{yahei}] 微软雅黑,CJK 等价命令 |\CJKfamily{zhyahei}|。 +% \end{optdesc} +% +% 在 \opt{macnew} 字库中,还定义了 \tn{pingfang}。 +% \begin{optdesc} +% \item[\tn{pingfang}] 苹方黑体,CJK 等价命令 |\CJKfamily{zhpf}|。 +% \end{optdesc} +% +% \section{排版格式设定} +% \label{sec:format-settings} +% \subsection{文档默认字号} +% \label{subs:options-class} +% +% \begin{function}[rEXP,added=2015-05-06]{zihao} +% \begin{syntax} +% zihao = <-4|5|false> +% \end{syntax} +% 将文章默认字号(\tn{normalsize})设置为小四号字或五号字, +% 具体情况见表 \ref{tab:fontsize}。\opt{false} 禁用本功能。 +% 本选项可以用于四个 \CTeX{} 文档类和 \pkg{ctex} 宏包, +% 也可以用于 \pkg{ctexsize} 宏包。 +% +% \opt{scheme = chinese} 时,对标准文档类默认值为 |5|,即设置 +% \tn{normalsize} 为五号字;对 \cls{beamer} 则为 |false|,使用文档类原有的设 +% 置。 +% \end{function} +% +% \begin{table}[htbp] +% \centering +% \setlength\tabcolsep{1em} +% \caption{标准字体命令与字号的对应}\label{tab:fontsize} +% \begin{tabular}{l*2{c>{\ttfamily}r}*3{>{\ttfamily}c}} +% \toprule +% & \multicolumn2c{|zihao = 5|} & \multicolumn2c{|zihao = -4|} & +% \multicolumn1c{|10pt|} & \multicolumn1c{|11pt|} & \multicolumn1c{|12pt|} \\ +% \cmidrule(lr){2-3} \cmidrule(lr){4-5} +% \cmidrule(lr){6-6} \cmidrule(lr){7-7} \cmidrule(lr){8-8} +% 字体命令 & 字号 & \si{bp} & 字号 & \si{bp} +% & \si{pt} & \si{pt} & \si{pt} \\ +% \midrule +% |\tiny| & 七号 & 5.5 & 小六 & 6.5 & ~5 & ~6 & ~6 \\ +% |\scriptsize| & 小六 & 6.5 & 六号 & 7.5 & ~7 & ~8 & ~8 \\ +% |\footnotesize| & 六号 & 7.5 & 小五 & 9~~ & ~8 & ~9 & 10 \\ +% |\small| & 小五 & 9~~ & 五号 & 10.5 & ~9 & 10 & 11 \\ +% |\normalsize| & 五号 & 10.5 & 小四 & 12~~ & 10 & 11 & 12 \\ +% |\large| & 小四 & 12~~ & 小三 & 15~~ & 12 & 12 & 14 \\ +% |\Large| & 小三 & 15~~ & 小二 & 18~~ & 14 & 14 & 17 \\ +% |\LARGE| & 小二 & 18~~ & 二号 & 22~~ & 17 & 17 & 20 \\ +% |\huge| & 二号 & 22~~ & 小一 & 24~~ & 20 & 20 & 25 \\ +% |\Huge| & 一号 & 26~~ & 一号 & 26~~ & 25 & 25 & 25 \\ +% \bottomrule +% \end{tabular} +%\end{table} +% +% \begin{function}[rEXP]{10pt, 11pt, 12pt} +% \CTeX{} 文档类是在 \LaTeX{} 标准文档类之上开发的。因此,除了可以使用 \CTeX{} +% 宏包定义的字号选项之外,还可以使用标准文档类的同类选项(\opt{10pt}、\opt{11pt} +% 和 \opt{12pt})。在使用这些来自标准文档类的选项的时候,\CTeX{} 文档类的字号 +% 选项会被抑制。亦即,在 \opt{zihao} 选项之后设置 \opt{10pt} 选项, +% \opt{zihao} 选项将不再起作用。 +% \end{function} +% +% 标准文档类的其他选项在 \CTeX{} 文档类中依旧有效。例如,设置纸张大小和方向的 +% \opt{a4paper} 和 \opt{landscape},设置单双面的 \opt{oneside} 和 +% \opt{twoside} 等。\CTeX{} 会将这些选项传给标准文档类^^A +% \footnote{事实上,\LaTeX{} 在文档类中的选项是全局设定的,除了对使用的文档类有 +% 影响外,也可能会影响到随后使用的宏包。如果这些宏包中有某些选项出现在文档类的 +% 选项列表中,那么该选项将会被自动激活。}。 +% +% \subsection{章节标题风格} +% \label{subs:options-heading} +% +% \begin{function}[rEXP,added=2014-03-08]{heading} +% \begin{syntax} +% heading = <\TFF> +% \end{syntax} +% 本选项只能在调用 \pkg{ctex.sty} 时作为宏包选项使用。 +% +% \CTeX{} 宏集提供了一套用于修改文档章节标题格式的接口。该选项用于选择是否 +% 启用该功能。详细的设置方法请参见 +% \ref{sec:secstyle}~节和 \ref{subs:pagestyle}~节。 +% \end{function} +% +% \CTeX{} 宏集提供的四个文档类总是启用该功能。如果在 \pkg{ctex.sty} 下启用该选项, +% 将会检查当前是否使用 \LaTeX{} 标准文档类。 +% 若然,则该选项将会使得 \pkg{ctex.sty} 宏包的行为和 \CTeX{} 宏集提供的 +% 四个中文文档类\emph{完全}一致;若不然,则会根据 \tn{chapter} +% 是否有定义来使用 \cls{ctexbook} 或者 \cls{ctexart} 的标题设置。 +% +% \begin{function}[rEXP]{sub3section, sub4section} +% 修改 \tn{paragraph} 和 \tn{subparagraph} 的格式。 +% +% 默认情况下,\tn{paragraph} 和 \tn{subparagraph} 会将标题与随后的正文 +% 排版在同一个段落。启用 \opt{sub3section} 会将 \tn{paragraph} 的格式修改为 +% 类似 \tn{section} 的格式,并将 \tn{subparagraph} 的格式修改为原本 \tn{paragraph} +% 的格式。启用 \opt{sub4section} 会将 \tn{paragraph} 和 \tn{subparagraph} 的格式 +% 都修改为类似 \tn{section} 的格式。 +% +% 启用该选项通常需要将计数器 |secnumdepth| 的值为设置为 4 或 5。 +% +% 具体格式可参考 \ref{sec:secstyle}~节中的 \opt{runin} 和 \opt{afterskip} 选项。 +% +% 注意,上述两个选项只有在非 \cls{beamer} 文档类下 \opt{heading} 选项启用的时候 +% 才有意义。亦即,只有在使用除了 \cls{ctexbeamer} 的三个 \CTeX{} 文档类或启用了 +% \opt{heading} 的 \pkg{ctex.sty} 的时候才有意义。 +% \end{function} +% +% \subsection{排版方案选项} +% \label{subs:options-type-style} +% +% \begin{function}[rEXP,added=2015-04-15]{scheme} +% \begin{syntax} +% scheme = <(chinese)|plain> +% \end{syntax} +% 选择文章的排版方案,预设有 \opt{chinese} 和 \opt{plain} 两种方案。% +% \end{function} +% \begin{optdesc}[itemsep=\medskipamount] +% \item[chinese] 对 \cls{beamer} 以外的文档类,调整默认字号为五号字,并调 +% 整行距为 |1.3|;汉化文档中的标题名字(如“图”、“表”、“目录”和“参 +% 考文献”等,见 \ref{subs:capname}~节); +% 在 \opt{heading = true} 的情况下^^A +% \footnote{使用 \CTeX{} 文档类,或者使用 \pkg{ctex} 宏包且开启该选项时。}^^A +% (\ref{subs:options-heading}~节),还会将章节标题的风格修改为 +% 中文样式(见 \ref{sec:secstyle}~节)。 +% +% 当关闭 \opt{heading} 选项的 \pkg{ctex} 宏包与标准文档类或其衍生文档类 +% 联用时,会载入 \pkg{indentfirst} 宏包,以实现章节标题后的段首缩进。 +% \item[plain] 不调整默认字号和行距,不会汉化文档中的标题名字,也不会将章节 +% 标题风格修改为中文样式,同时不会调整 \tn{pagestyle},并禁用 \opt{autoindent} +% 选项。事实上,此时的 \CTeX{} 宏集只提供了中文支持功能,而不对文章版式进行任何修改。 +% \end{optdesc} +% +% \begin{function}[updated=2014-04-11]{punct} +% \begin{syntax} +% punct = <(quanjiao)|banjiao|kaiming|CCT|plain> +% \end{syntax} +% 设置标点处理格式。预定义好的格式有: +% \end{function} +% \begin{optdesc} +% \item[quanjiao] 全角式:所有标点占一个汉字宽度,相邻两个标点占 1.5 汉字宽度; +% \item[banjiao] 半角式:所有标点占半个汉字宽度; +% \item[kaiming] 开明式:句末点号^^A +% \footnote{标点符号分为标号与点号。点号分为两类,一共七种:句末点号有^^A +% 句号、问号和叹号;句内点号有逗号、顿号、冒号和分号。}用占一个汉字宽度,标^^A +% 号和句内点号占半个汉字宽度; +% \item[CCT] CCT 式:所有标点符号的宽度略小于一个汉字宽度; +% \item[plain] 原样(不调整标点间距)。 +% \end{optdesc} +% +% \begin{function}[updated=2014-03-08]{space} +% \begin{syntax} +% space = <\TF|(auto)> +% \end{syntax} +% 是否在生成的 PDF 中保留汉字后面的空格。 +% \end{function} +% +% \begin{optdesc} +% \item[true] 总是保留汉字后的空格。此时,用户需要自行在行尾加上~|%|~处理换行产生 +% 的空格\footnote{\LaTeX{} 将单个换行视作一个空格。}。 +% \item[false] 总是忽略掉汉字后面的空格,不论汉字后是什么(使用 (pdf)\LaTeX{} +% 编译时);等同于 \opt{auto} 的效果(使用 \XeLaTeX{} 编译时)。不建议使用该选项。 +% \item[auto] 根据空格后面的情况决定是否保留:如果空格后面是汉字,则忽略该 +% 空格,否则保留。 +% \end{optdesc} +% +% 例如,使用 +% \begin{ctexexam} +% \ctexset{space=true} +% 汉字 分词 +% 技术 English +% \end{ctexexam} +% 将得到“{\ctexset{space=true}汉字 分词 技术 English}”;使用 +% \begin{ctexexam} +% \ctexset{space=auto} +% 汉字 分词 +% 技术 English +% \end{ctexexam} +% 则会得到“{\ctexset{space=auto}汉字 分词 技术 English}”。 +% +% \emph{使用 \textup{\LuaLaTeX{} 及 \upLaTeX} 编译的时候,该选项无效:汉字间的 +% 空格以及汉字与西文字符之间的空格总是有效,不会被忽略,但可以自动忽略掉由换行 +% 产生的空格。} +% +% \begin{function}[rEXP,added=2014-04-23]{linespread} +% \begin{syntax} +% linespread = <数值> +% \end{syntax} +% 接受一个浮点数值,设置行距倍数。本选项的初始值与 \opt{scheme} 有关。 +% \end{function} +% \begin{optdesc} +% \item[scheme = chinese] 对标准文档类初始值为 $1.3$,即 $1.3$ 倍行距。此 +% 时,相邻两行的基线(\tn{baselineskip})距离为 $1.3\times 1.2=1.56$ 倍字体 +% 高度。对 \cls{beamer} 不改变行距,即使用默认的单倍行距。 +% +% \item[scheme = plain] \CTeX{} 宏集默认不调整行距倍数,文档中的行距由所选文档类和 +% 其他宏包或用户设置决定。 +% \end{optdesc} +% +% \begin{function}[added=2014-03-13]{autoindent} +% \begin{syntax} +% autoindent = <\TTF|数值|带单位的数值> +% \end{syntax} +% 在字体大小发生变化时,是否自动调整段首缩进(\tn{parindent})的大小。 +% \end{function} +% \begin{optdesc} +% \item[\meta{数值或带单位的数值}] 用于设置段首缩进的长度。如果不带单位,则默认 +% 单位是单个汉字字宽 \tn{ccwd};如果带单位,则使用该单位。 +% +% \item[true] 等价于设置 \opt{autoindent = 2}。 +% +% \item[false] 禁用自动调整功能,可以设置固定长度的段首缩进。如设置每段缩进 40 点: +% \begin{ctexexam} +% \ctexset{autoindent=false} +% \setlength\parindent{40pt} +% \end{ctexexam} +% \end{optdesc} +% +% \begin{function}[EXP,added=2014-03-26]{linestretch} +% \begin{syntax} +% linestretch = <数值或长度> +% \end{syntax} +% \opt{linestretch} 是一个比较特殊的选项,它用来设置汉字之间弹性间距的弹性程 +% 度。如果有单位,则可以在选项中直接写;如果是数字,单位则是汉字宽度 +% \tn{ccwd} 的倍数。 +% \end{function} +% +% 如果行宽不是汉字宽度的整数倍,为了让段落左右两端对齐,自然就要求伸展汉字之 +% 间的间距,而 \opt{linestretch} 选项就是设置每行总的允许伸行量。初始值是允 +% 许每行伸行一个汉字的宽度 \tn{ccwd},并且此宽度能根据字号变化动态调整。 +% +% 过小的 \opt{linestretch} 可能导致段落文字右侧可能参差不齐;较大的 +% \opt{linestretch} 选项则可以帮助拥有较长不可断行内容的复杂段落方便地断行, +% 而不会产生大量编译警告;但很大的 \opt{linestretch} 则会掩盖段落不良断行产 +% 生的坏盒子警告。 +% +% 如果将 \opt{linestretch} 选项的值设置为 \tn{maxdimen},则可以禁止按字号自 +% 动修改每行的允许伸长量。此时汉字间的弹性间距则固定为 \tn{baselineskip} 的 +% $0.08$ 倍。 +% +% \section{文档汉化} +% \label{sec:chinese-localization} +% \subsection{日期汉化} +% +% \CTeX 宏包对显示当前日期的 \tn{today} 命令进行了汉化,使之以中文的方式显示今 +% 天的日期。如编译本文档的日期就是“\today”。 +% +% \begin{function}[EXP]{today} +% \begin{syntax} +% today = <(small)|big|old> +% \end{syntax} +% 该选项用来控制 \tn{today} 命令的输出格式: +% \begin{optdesc} +% \item[small] \ctexset{today=small} +% 效果为“\today”。使用阿拉伯数字和汉字的日期格式。 +% \item[big] \ctexset{today=big} +% 效果为“\today”。使用全汉字的日期格式。 +% \item[old] \ctexset{today=old} +% 效果为“\today”。使用文档原来的(英文)日期格式。 +% \end{optdesc} +% \end{function} +% +% 设置日期格式使用 \tn{ctexset} 命令完成,例如设置全汉字的日期格式: +% \begin{ctexexam} +% \ctexset{today=big} +% \end{ctexexam} +% +% \CTeX 宏包的中文日期功能实际上是调用 \pkg{zhnumber} 宏包完成的。如果需要更 +% 多有关日期、时间的命令和更复杂的设置,可以查阅 \pkg{zhnumber} 宏包的文档。 +% +% \subsection{文档标题汉化} +% \label{subs:capname} +% +% 这里主要介绍由宏包 \opt{scheme} 选项(\ref{subs:options-type-style}~节)控制 +% 的文档标题汉化功能。 +% +% 设置文档标题名的示例可见例~\ref{exam:capname}。下面的选项(如 +% \opt{contentsname})主要用来重新定义与选项同名的宏(如 \tn{contentsname})的 +% 定义。 +% +% \begin{defaultcapconfig} +% +% \begin{function}[EXP]{contentsname} +% \begin{syntax} +% contentsname = <名字> +% \end{syntax} +% 设置目录标题名 \tn{contentsname}。中文默认为“\contentsname”。 +% \end{function} +% +% \begin{function}[EXP]{listfigurename} +% \begin{syntax} +% listfigurename = <名字> +% \end{syntax} +% 设置插图目录标题名 \tn{listfigurename}。中文默认为“\listfigurename”。 +% \end{function} +% +% \begin{function}[EXP]{listtablename} +% \begin{syntax} +% listtablename = <名字> +% \end{syntax} +% 设置表格目录标题名 \tn{listtablename}。中文默认为“\listtablename”。 +% \end{function} +% +% \begin{function}[EXP]{figurename} +% \begin{syntax} +% figurename = <名字> +% \end{syntax} +% 设置图片环境标题名 \tn{figurename}。中文默认为“\figurename”。 +% \end{function} +% +% \begin{function}[EXP]{tablename} +% \begin{syntax} +% tablename = <名字> +% \end{syntax} +% 设置表格环境标题名 \tn{tablename}。中文默认为“\tablename”。 +% \end{function} +% +% \begin{function}[EXP]{abstractname} +% \begin{syntax} +% abstractname = <名字> +% \end{syntax} +% 设置摘要 \env{abstract} 环境标题名 \tn{abstractname}。中文默认 +% 为“\abstractname”。注意 \cls{book} 类没有摘要,该选项无效。 +% \end{function} +% +% \begin{function}[EXP]{indexname} +% \begin{syntax} +% indexname = <名字> +% \end{syntax} +% 设置索引标题名 \tn{indexname}。中文默认为“\indexname”。 +% \end{function} +% +% \begin{function}[EXP]{appendixname} +% \begin{syntax} +% appendixname = <名字> +% \end{syntax} +% 设置附录标题名 \tn{appendixname}。中文默认为“\appendixname”。 +% \end{function} +% +% \begin{function}[EXP]{bibname} +% \begin{syntax} +% bibname = <名字> +% \end{syntax} +% 设置参考文献标题名 \tn{refname}(对 \cls{article})或 \tn{bibname}(对 +% \cls{report}、\cls{book} 和 \cls{beamer})。中文默认为“\refname”。 +% \end{function} +% +% \begin{function}[EXP]{proofname} +% \begin{syntax} +% proofname = <名字> +% \end{syntax} +% 设置证明环境的名称 \tn{proofname}。中文默认为“\proofname”。 +% \end{function} +% +% 如果使用 \cls{ctexbeamer} 文档类或者在 \cls{beamer} 文档类下使用 \pkg{ctex} 包, +% 还会汉化常用定理类环境的诸如“定义”、“定理”和“引理”等名称。此时,还有下列 +% 三个选项。 +% +% \begin{function}[EXP]{refname} +% \begin{syntax} +% refname = <名字> +% \end{syntax} +% 设置参考文献标题名 \tn{refname}。中文默认为“\refname”。 +% \end{function} +% +% \begin{function}[EXP]{algorithmname} +% \begin{syntax} +% algorithmname = <名字> +% \end{syntax} +% 设置算法环境标题名 \tn{algorithmname}。中文默认为“算法”。 +% \end{function} +% +% \begin{function}[EXP]{continuation} +% \begin{syntax} +% continuation = <名字> +% \end{syntax} +% 设置 \cls{beamer} 可断页的帧在续页标题中的延续标识 \tn{insertcontinuationtext}。 +% 中文默认为“(续)”。 +% \end{function} +% +% \end{defaultcapconfig} +% +% \subsection{页面格式设置与汉化} +% \label{subs:pagestyle} +% +% 当使用了 \CTeX 的文档类或是用 \pkg{ctex} 宏包加载了 \opt{heading} 选项时,会 +% 设置整个文档的页面格式(page style)为 |headings|,即相当于设置了 +% \begin{frameverb} +% \pagestyle{headings} +% \end{frameverb} +% 在页眉中显示当前章节的编号与标题。 +% +% 同时,\CTeX 宏包也会对默认的 |headings| 页面格式进行修改,使之调用 +% \tn{CTEXthechapter}、\tn{CTEXthesection} 等宏来正确显示中文的章节编号。 +% +% \CTeX 宏包的默认页面格式设置是经过汉化的 |headings|,其基本效果如本文档所 +% 示,只在页眉一侧显示章节编号和标题,另一侧显示页码。 +% +% 更复杂的页面格式可以通过调用 \pkg{fancyhdr}、\pkg{titleps} 等宏包来设 +% 置。\CTeX 宏包同时也为这些自定义页面格式 +% 的包提供了以下宏供使用: +% \begin{itemize} +% \item \tn{CTEXthechapter}、\tn{CTEXthesection} 等章节编号(见 +% \ref{sec:secstyle} 节)。它们用来代替英文文档类中的 +% \tn{thechapter}、\tn{thesection} 等宏。 +% +% \item \tn{leftmark}、\tn{rightmark},它们是在使用章节标题命令后,自动设置的 +% 宏。它们实际是在与章节标题命令对应的标记命令 +% \tn{chaptermark}、\tn{sectionmark} 中调用 \tn{markright} 或 \tn{markboth} 生 +% 成的。 +% \end{itemize} +% 有关 \LaTeX 页面标记的涵义与使用细节,已经超出了本文档讨论的范围。可以参考 +% \cite[Chapter~23]{knuthtex1986}、\cite[\S4.3, \S4.4]{mittelbach2004} 等书籍。 +% +% 这里举一个例子,说明通过重定义 \tn{sectionmark},在 \cls{ctexart} 文档类中的 +% 标准 |headings| 页面格式下控制页眉的方式: +% \begin{ctexexam} +% \documentclass{ctexart} +% \pagestyle{headings} +% \ctexset{section={ +% name={第,节}, +% number=\arabic{section}, +% } +% } +% \renewcommand\sectionmark[1]{% +% \markright{\CTEXifname{\CTEXthesection——}{}#1}} +% +% \begin{document} +% +% \section{天地玄黄} +% \newpage +% +% \section{宇宙洪荒} +% +% \end{document} +% \end{ctexexam} +% 在上例中,我们设置了页眉的形式是用破折号分开的节编号与节标题,即“第 1 节 +% ——天地玄黄”、“第 2 节——宇宙洪荒”。 +% +% \CTeX 宏包已经对 \pkg{fancyhdr} 宏包进行了补丁,载入 \pkg{fancyhdr} 后,其 +% |fancy| 页面格式将使用 \tn{CTEXthechapter} 等宏显示中文章节编号。 +% +% 关于 \pkg{fancyhdr} 的具体用法可以参见其宏包手册。通常也只要像在标准的英文文 +% 档类中使用 \pkg{fancyhdr} 一样定义页眉页脚格式即可,并不需要额外的定义。 +% +% 下面我则给出一个与前例类似而稍复杂的例子,展示如何在文档中设置页眉内容与页眉 +% 的格式。 +% \begin{ctexexam} +% \documentclass{ctexart} +% \ctexset{section={ +% name={第,节}, +% number=\arabic{section}, +% } +% } +% \usepackage{fancyhdr} +% \fancyhf{} +% \lhead{\textnormal{\kaishu\rightmark}} +% \rhead{--\ \thepage\ --} +% \pagestyle{fancy} +% % \sectionmark 的重定义需要在 \pagestyle 之后生效 +% \renewcommand\sectionmark[1]{% +% \markright{\CTEXifname{\CTEXthesection——}{}#1}} +% +% \begin{document} +% +% \section{天地玄黄} +% \newpage +% +% \section{宇宙洪荒} +% +% \end{document} +% \end{ctexexam} +% 本例的页眉效果大致如下(有页眉线): +% \begin{trivlist}\item +% \textnormal{\kaishu 第 1 节——天地玄黄}\hfill -- 1 --\par +% \smallskip\hrule +% \end{trivlist} +% +% \section{章节标题格式设置} +% \label{sec:secstyle} +% +% \CTeX 宏包对 \LaTeX 的标准文档类(\cls{article}、\cls{report} 和 +% \cls{book})和 \cls{beamer} 进行了扩充。当以 \opt{heading} 选项调用 \CTeX +% 宏包时(\ref{subs:options-heading}~节),则会启用章 +% 节标题的格式设置功能。本节就来介绍有关章节标题的格式选项,所有选项使用 +% \tn{ctexset} 命令设置。 +% +% 第 \ref{subs:pagestyle} 节和本节介绍的功能已经被提取到 \pkg{ctexheading} +% 宏包之中,可以在 \pkg{ctex} 宏包和 \cls{ctexart} 等文档类之外独立使用。 +% 各选项的默认值与 \opt{scheme = plain} 时的情形相同。 +% +% \changes{v2.0}{2015/03/21}{\tn{CTEXsetup}, \tn{CTEXoptions} 是过时命令。} +% 章节标题的格式选项是分层设置的。顶层的选项是章节标题名称,次一级的选项是章节 +% 标题的格式。章节标题名包括 |part|, |chapter|, |section|, |subsection|, +% |subsubsection|, |paragraph|, |subparagraph|;而可用的格式包括 \opt{numbering}, +% \opt{name}, \opt{number}, \opt{format}, \opt{nameformat}, \opt{numberformat}, +% \opt{aftername}, \opt{titleformat}, \opt{aftertitle}, \opt{runin}, +% \opt{afterindent}, \opt{beforeskip}, \opt{afterskip}, \opt{fixskip}, +% \opt{lotskip}, \opt{lofskip}, \opt{indent}, \opt{hang}, +% \opt{pagestyle}, \opt{break}, \opt{tocline} 等。 +% +% 注意,对 \cls{article} 及其衍生的 \cls{ctexart} 等文档类,没有 |chapter| +% 级别的标题。而对于 \cls{beamer} 文档类,这些选项控制的是由 \tn{partpage}, +% \tn{sectionpage} 和 \tn{subsectionpage} 产生的标题格式,此时只有 |part|, +% |section| 和 |subsection| 这三层级别,并且 \opt{runin}, \opt{afterindent}, +% \opt{fixskip}, \opt{hang}, \opt{break} 和 \opt{tocline} 这六个格式无效。 +% +% 多级选项之间用斜线分开,例如,\opt{part/name} 选项设置 \tn{part} 标题的在数 +% 字前后的名称,而 \opt{section/number} 选项设置 \tn{section} 标题的数字类型。 +% 注意,斜线 |/| 前后不能有空格或者换行。 +% +% 使用 \tn{ctexset} 设置多级选项时,可以在同一个上级选项下设置多个下级选项。 +% +% 例如,同时设置 |part| 一级标题的 \opt{pagestyle} 选项,|chapter| 一级标题的 +% \opt{format} 与 \opt{pagestyle} 选项和 |section| 一级标题的 \opt{name} 与 +% \opt{number} 选项: +% \begin{ctexexam} +% \ctexset { +% part/pagestyle = empty, +% chapter = { +% format = \raggedright, +% pagestyle = empty, +% }, +% section = { +% name = {第,节}, +% number = \chinese{section}, +% } +% } +% \end{ctexexam} +% +% \begin{function}[EXP,added=2015-06-21]{part/numbering, chapter/numbering, +% section/numbering, subsection/numbering, subsubsection/numbering, +% paragraph/numbering, subparagraph/numbering} +% \begin{syntax} +% numbering = \TTF +% \end{syntax} +% 控制是否对章节标题编号。对各级标题的默认值均为 \opt{true}。 +% +% 我们知道,\LaTeX{} 带星号的章节标题命令(如 \tn{section*})不会对标题编号, +% 但也不会将该没编号的标题编入目录中。本选项控制的是不带星号的标题命令是否编号。 +% 设置本选项为 \opt{false},除了不对标题编号以外,功能与正常标题一致, +% 比如可以编目录,正确的 \pkg{hyperref} 目录超链接位置和页眉标记。 +% +% 注意,章节标题的编号深度受 \LaTeX{} 计数器 |secnumdepth| 的控制。 +% \opt{numbering} 选项在 |secnumdepth| 的控制下起作用。 +% \end{function} +% +% 如果没有特别说明,以下将用 “|...|” 代表各级章节标题名。 +% +% \begin{function}[EXP,updated=2014-03-08]{.../name} +% \begin{syntax} +% name = \{<前名字>,<后名字>\} +% name = \Arg{前名字} +% \end{syntax} +% 设置章节的名字。名字可以分为前后两部分,即章节编号前后的词语,两个词之间用 +% 一个半角逗号分开;也可以只有一部分,表示只有章节编号之前的名字。例如: +% \begin{ctexexam} +% \ctexset{ +% chapter/name = {第,章}, +% section/name = {\S}, +% } +% \end{ctexexam} +% 会使得 \tn{chapter} 标题使用形如“第一章”的名字,而 \tn{section} 标题则使 +% 用形如“\S1”的名字。 +% \end{function} +% +% \begin{table}[htbp] +% \small\centering +% \caption{\opt{name} 选项的默认设置} +% \begin{tabular}{llll} +% \toprule +% 标题名 & \opt{scheme = chinese} & \opt{scheme = plain} & 注 \\ +% \midrule +% part & |{第,部分}| & |{\partname\space}| & 原 \tn{partname} 为 Part \\ +% chapter & |{第,章}| & |{\chaptername\space}| +% & 原 \tn{chaptername} 为 Chapter \\ +% section (beamer) & |{}| & |{\sectionname\space}| +% & \BSTACK 原 \tn{sectionname} 为\\ |\translate{Section}| \ESTACK \\ +% section & 同右 & |{}| & \\ +% subsection (beamer) & |{}| & |{\subsectionname\space}| +% & \BSTACK 原 \tn{subsectionname} 为\\ |\translate{Subsection}| \ESTACK \\ +% subsection & 同右 & |{}| & \\ +% subsubsection & 同右 & |{}| & \\ +% paragraph & 同右 & |{}| & \\ +% subparagraph & 同右 & |{}| & \\ +% \bottomrule +% \end{tabular} +% \end{table} +% +% \begin{function}[EXP]{.../number} +% \begin{syntax} +% number = \Arg{数字输出命令} +% \end{syntax} +% 设置章节编号的数字输出格式。\meta{数字输出命令} 通常是对应章节编号计数器的 +% 输出命令,如 \tn{thesection} 或 |\chinese{chapter}| 之类。 +% \begin{ctexexam} +% \ctexset{ +% section/number = \Roman{section} +% } +% \end{ctexexam} +% \end{function} +% +% \opt{number} 选项的定义同时将控制对章节计数器的交叉引用。在引用计数器时, +% 记录在 \LaTeX{} 辅助文件中的是 \opt{number} 选项的定义。 +% +% 但是,\opt{number} 选项不会影响计数器本身的输出。即设置 |section/number| +% 不会影响 \tn{thesection} 的定义。(但该选项会影响 \tn{CTEXthesection} 的定 +% 义,见后。) +% +% \begin{table}[htbp] +% \small\centering +% \caption{\opt{number} 选项的默认设置} +% \setlength\leftskip{0pt plus 1 fil minus \marginparwidth} +% \begin{tabular}{llll} +% \toprule +% 标题名 & \opt{scheme = chinese} & \opt{scheme = plain} +% & 原 |\the|\meta{标题} 等价定义 \\ +% \midrule +% part (beamer) & |\chinese{part}| & |\insertromanpartnumber| & 意义为 |\Roman{part}| \\ +% part & |\chinese{part}| & |\thepart| & |\Roman{part}| \\ +% chapter & |\chinese{chapter}| & |\thechapter| & |\arabic{chapter}| \\ +% section (beamer) & 同右 & |\insertsectionnumber| & 意义为 |\arabic{section}| \\ +% section & 同右 & |\thesection| & |\arabic{section}| \\ +% subsection (beamer) +% & \BSTACK |\arabic{section}.|\\ |\arabic{subsection}| \ESTACK +% & |\insertsubsectionnumber| & 意义为 |\arabic{subsection}| \\ +% subsection & 同右 & |\thesubsection| & |\thesection.\arabic{subsection}| \\ +% subsubsection & 同右 & |\thesubsubsection| +% & |\thesubsection.\arabic{subsubsection}| \\ +% paragraph & 同右 & |\theparagraph| +% & |\thesubsubsection.\arabic{paragraph}| \\ +% subparagraph & 同右 & |\thesubparagraph| +% & |\theparagraph.\arabic{subparagraph}| \\ +% \bottomrule +% \end{tabular} +% \end{table} +% +% \begin{function}{\CTEXthepart, \CTEXthechapter, \CTEXthesection, +% \CTEXthesubsection, \CTEXthesubsubsection, \CTEXtheparagraph, +% \CTEXthesubparagraph} +% 以 |\CTEXthe| 开头的这组宏给出结合了 \opt{name} 与 \opt{number} 选项的章节 +% 编号输出格式。例如在 \opt{scheme = chinese} 时,默认章编号输出格式就是 +% \tn{CTEXthechapter},形如“第一章”。 +% +% 这组宏在 \CTeX 文档类中将代替 \tn{thechapter} 等宏的作用,在章节中引用本章 +% 节的完整编号。例如用于帮助定义自定义的目录格式、页眉格式等。 +% \end{function} +% +% \begin{function}[added=2016-09-18]{\CTEXifname} +% \begin{syntax} +% \tn{CTEXifname} \Arg{有名字时的格式命令} \Arg{无名字时的格式命令} +% \end{syntax} +% \tn{CTEXifname} 用于根据当前章节的名字的有无设置不同的格式。 +% +% 它可用于 \opt{format}, \opt{titleformat}, \opt{aftertitle}, \opt{afterskip}, +% \opt{indent} 这五个选项和 \tn{chapter} 标题 \opt{beforeskip} 选项的格式设置之中。 +% 也可用于帮助定义自定义的目录格式、页眉格式等。 +% +% 例如,设置章的标题有名字时左对齐,无名字时居中对齐,并且在标题后画一条横线。 +% \begin{ctexexam} +% \ctexset{ +% chapter/format = \CTEXifname{\raggedright}{\centering}, +% chapter/aftertitle = \par\CTEXifname{}{\hrule}, +% } +% \end{ctexexam} +% \end{function} +% +% \begin{function}[EXP,updated=2015-06-30]{.../format, .../format+} +% \begin{syntax} +% format = \Arg{格式命令} +% format+= \Arg{格式命令} +% \end{syntax} +% \opt{format} 选项用于控制章节标题的全局格式,作用域为章节名字和随后的标题 +% 内容。可以用于控制章节标题的对齐方式、整体字体字号等格式。 +% +% 带加号的 \opt{format+} 选项则用于在已有格式之后追加新的格式命令。 +% +% 例如,设置章格式为无衬线字体左对齐,为节格式增加无衬线字体设置: +% \begin{ctexexam} +% \ctexset{ +% chapter/format = \sffamily\raggedright, +% section/format += \sffamily +% } +% \end{ctexexam} +% \end{function} +% +% \begin{table}[htbp] +% \small\centering +% \caption{\opt{format} 选项的默认设置} +% \begin{tabular}{lll} +% \toprule +% 标题名 & \opt{scheme = chinese} & \opt{scheme = plain} \\ +% \midrule +% part (article) & |\Large\bfseries\centering| & |\raggedright| \\ +% part (beamer) & 同右 & |\centering| \\ +% part & |\huge\bfseries\centering| & |\centering| \\ +% chapter & |\huge\bfseries\centering| & |\raggedright| \\ +% section (beamer) & 同右 & |\centering| \\ +% section & |\Large\bfseries\centering| & |\Large\bfseries| \\ +% subsection (beamer) & 同右 & |\centering| \\ +% subsection & 同右 & |\large\bfseries| \\ +% subsubsection & 同右 & |\normalsize\bfseries| \\ +% paragraph & 同右 & |\normalsize\bfseries| \\ +% subparagraph & 同右 & |\normalsize\bfseries| \\ +% \bottomrule +% \end{tabular} +% \end{table} +% +% \begin{function}[EXP,updated=2015-06-30]{.../nameformat, .../nameformat+} +% \begin{syntax} +% nameformat = \Arg{格式命令} +% nameformat+= \Arg{格式命令} +% \end{syntax} +% \opt{nameformat} 用于控制章节名字的格式,作用域为章节名字,包括编号。它一 +% 般用于章节名(包括编号)与章节标题的字体、字号等设置不一致的情形。参见 +% \opt{titleformat} 选项。 +% +% \opt{nameformat+} 用于在已有的章节名字格式后附加内容。 +% +% \opt{nameformat} 选项的最后一个格式命令可以是一个有一个参数的命令。 +% 这个命令的参数用于接受章节名字和编号,实现特殊效果(见例~\ref{exam:miscopt})。 +% +% \opt{nameformat} 选项的默认值,在 \opt{scheme} 选项的不同取值下相同。 +% \end{function} +% +% \begin{table}[htbp] +% \small\centering +% \caption{\opt{nameformat} 选项的默认设置} +% \begin{tabular}{lll} +% \toprule +% 标题名 & \opt{scheme = chinese} & \opt{scheme = plain} \\ +% \midrule +% part (article) & |{}| & |\Large\bfseries| \\ +% part (beamer) & 同右 +% & \BSTACK |\usebeamerfont{part name}| \\ +% |\usebeamercolor[fg]{part name}| \ESTACK \\ +% part & |{}| & |\huge\bfseries| \\ +% chapter & |{}| & |\huge\bfseries| \\ +% section (beamer) & 同右 +% & \BSTACK |\usebeamerfont{section name}| \\ +% |\usebeamercolor[fg]{section name}| \ESTACK \\ +% section & 同右 & |{}| \\ +% subsection (beamer) & 同右 +% & \BSTACK |\usebeamerfont{subsection name}| \\ +% |\usebeamercolor[fg]{subsection name}| \ESTACK \\ +% subsection & 同右 & |{}| \\ +% subsubsection & 同右 & |{}| \\ +% paragraph & 同右 & |{}| \\ +% subparagraph & 同右 & |{}| \\ +% \bottomrule +% \end{tabular} +% \end{table} +% +% \begin{function}[EXP,updated=2015-06-19]{.../numberformat, .../numberformat+} +% \begin{syntax} +% numberformat = \Arg{格式命令} +% numberformat+= \Arg{格式命令} +% \end{syntax} +% \opt{numberformat} 选项用于控制章节编号的格式,作用域仅为编号数字本身。对 +% 各级标题默认均为空,当你需要编号的格式和前后的章节名字不一样时可以使用。 +% +% \opt{numberformat+} 选项用于在原有编号格式后面附加格式命令。 +% +% \opt{numberformat} 选项的最后一个格式命令可以是一个有一个参数的命令。 +% 这个命令的参数用于接受编号数字。 +% \end{function} +% +% 例如,我们可以使用 \opt{numberformat} 特别强调章标题中的数字: +% \begin{ctexexam} +% \ctexset{ +% chapter/number = \arabic{chapter}, +% chapter/numberformat = \color{blue}\zihao{0}\itshape, +% } +% \end{ctexexam} +% 上面的代码在 \opt{scheme = chinese} 时可以做出类似这样的章标题效果: +% \begin{center} +% \huge\bfseries 第 \textit{\color{blue}\zihao{0}4} 章 +% \end{center} +% +% \begin{function}[EXP,updated=2014-03-08]{.../aftername, .../aftername+} +% \begin{syntax} +% aftername = \Arg{代码} +% aftername+= \Arg{代码} +% \end{syntax} +% \opt{aftername} 选项的参数 \meta{代码} 将被插入到章节编号与其后的标题内容之 +% 间,用于控制格式变换。常用于控制章节编号与标题内容之间的距离,或者控制标题 +% 是否另起一行。 +% +% \opt{aftername+} 选项用于在原有代码后面附加代码。 +% \end{function} +% +% \begin{table}[htbp] +% \small\centering +% \caption{\opt{aftername} 选项的默认设置} +% \begin{tabular}{lll} +% \toprule +% 标题名 & \opt{scheme = chinese} & \opt{scheme = plain} \\ +% \midrule +% part (article) & |\quad| & |\par\nobreak| \\ +% part (beamer) & 同右 & |\vskip 1em \par| \\ +% part & 同右 & |\par\vskip 20pt| \\ +% chapter & |\quad| & |\par\nobreak\vskip 20pt| \\ +% section (beamer) & 同右 & |\vskip 1em \par| \\ +% section & 同右 & |\quad| \\ +% subsection (beamer) & 同右 & |\vskip 1em \par| \\ +% subsection & 同右 & |\quad| \\ +% subsubsection & 同右 & |\quad| \\ +% paragraph & 同右 & |\quad| \\ +% subparagraph & 同右 & |\quad| \\ +% \bottomrule +% \end{tabular} +% \end{table} +% +% \begin{function}[EXP,updated=2015-06-30]{.../titleformat, .../titleformat+} +% \begin{syntax} +% titleformat = \Arg{格式命令} +% titleformat+= \Arg{格式命令} +% \end{syntax} +% \opt{titleformat} 选项用于控制标题内容的格式,作用域为章节标题内容。 +% +% \opt{titleformat+} 选项用于在原有标题格式后面附加格式命令。 +% +% 需要注意的是,\opt{titleformat} 选项的最后一个格式命令可以是一个有一个 +% 参数的命令。这个命令的参数接受标题内容,用于实现特殊效果。 +% 例如,实现多行标题的居中悬挂对齐: +% \end{function} +% \begin{ctexexam} +% \usepackage{varwidth} %% 提供 varwidth 环境 +% \ctexset{ +% chapter/name = {第,回}, +% chapter/titleformat = \chaptertitleformat +% } +% \newcommand\chaptertitleformat[1]{%% 以标题内容为参数 +% \begin{varwidth}[t]{.7\linewidth}#1\end{varwidth}} +% ...... +% \chapter{情中情因情感妹妹\\错里错以错劝哥哥} +% \end{ctexexam} +% 上面的代码可以做出类似这样的章标题效果: +% \begin{center}\Large\bfseries +% 第三十四回\quad +% \begin{tabular}[t]{l} +% 情中情因情感妹妹\\ +% 错里错以错劝哥哥 +% \end{tabular} +% \end{center} +% +% \begin{table}[htbp] +% \small\centering +% \caption{\opt{titleformat} 选项的默认设置} +% \begin{tabular}{lll} +% \toprule +% 标题名 & \opt{scheme = chinese} & \opt{scheme = plain} \\ +% \midrule +% part (article) & |{}| & |\huge\bfseries| \\ +% part (beamer) & 同右 & |\usebeamerfont{part title}| \\ +% part & |{}| & |\Huge\bfseries| \\ +% chapter & |{}| & |\Huge\bfseries| \\ +% section (beamer) & 同右 & |\usebeamerfont{section title}| \\ +% section & 同右 & |{}| \\ +% subsection (beamer) & 同右 & |\usebeamerfont{subsection title}| \\ +% subsection & 同右 & |{}| \\ +% subsubsection & 同右 & |{}| \\ +% paragraph & 同右 & |{}| \\ +% subparagraph & 同右 & |{}| \\ +% \bottomrule +% \end{tabular} +% \end{table} +% +% \begin{function}[EXP,added=2015-06-19]{.../aftertitle, .../aftertitle+} +% \begin{syntax} +% aftertitle = \Arg{代码} +% aftertitle+= \Arg{代码} +% \end{syntax} +% \opt{aftertitle} 选项的参数 \meta{代码} 将被插入到章节标题内容之后。 +% +% \opt{aftertitle+} 选项用于在原有代码后面附加代码。 +% +% \opt{aftertitle} 选项的默认值,在 \opt{scheme} 选项的不同取值下相同。 +% +% \opt{sub3section} 或 \opt{sub4section} 宏包选项(见 +% \ref{subs:options-heading}~节)会影响 \opt{aftertitle} 选项的默认值。 +% \end{function} +% +% \begin{table}[htbp] +% \begin{minipage}[t]{.5\linewidth} +% \small\centering +% \caption{\opt{aftertitle} 选项的默认设置} +% \begin{tabular}{ll} +% \toprule +% 标题名 & 默认值 \\ +% \midrule +% part & |\par| \\ +% chapter & |\par| \\ +% section & |\@@par| \\ +% subsection & |\@@par| \\ +% subsubsection & |\@@par| \\ +% paragraph & |{}| \\ +% \qquad(sub3section) & |\@@par| \\ +% \qquad(sub4section) & 同上 \\ +% subparagraph & |{}| \\ +% \qquad(sub4section) & |\@@par| \\ +% \bottomrule +% \end{tabular} +% \end{minipage}% +% \begin{minipage}[t]{.5\linewidth} +% \small\centering +% \caption{\opt{runin} 选项的默认设置} +% \begin{tabular}{ll} +% \toprule +% 标题名 & 默认值 \\ +% \midrule +% part & 无效 \\ +% chapter & 无效 \\ +% section & |false| \\ +% subsection & |false| \\ +% subsubsection & |false| \\ +% paragraph & |true| \\ +% \qquad(sub3section) & |false| \\ +% \qquad(sub4section) & 同上 \\ +% subparagraph & |true| \\ +% \qquad(sub4section) & |false| \\ +% \bottomrule +% \end{tabular} +% \end{minipage} +% \end{table} +% +% \begin{function}[EXP,added=2015-06-27]{section/runin, subsection/runin, +% subsubsection/runin, paragraph/runin, subparagraph/runin} +% \begin{syntax} +% runin = \TF +% \end{syntax} +% \opt{runin} 选项只对 \tn{section} 级以下标题有意义。 +% 用于确定标题与随后的正文是否排在同一段之上。 +% +% \opt{runin} 选项的默认值,在 \opt{scheme} 选项的不同取值下相同。 +% +% 默认情况下,\tn{paragraph}、\tn{subparagraph} 两级标题是与后面正文排在同一 +% 段的,\opt{runin} 选项为 \opt{true};但使用 \opt{sub3section} 或 +% \opt{sub4section} 宏包选项(见 \ref{subs:options-heading}~节)后, +% 将对这两级标题设 \opt{runin} 选项为 \opt{false},这两级标题会改为排在不同段。 +% \end{function} +% +% \begin{function}[EXP,added=2015-06-27]{.../afterindent} +% \begin{syntax} +% afterindent = \TF +% \end{syntax} +% \opt{afterindent} 选项用于设置章节标题后首段的缩进。 +% +% \cls{book} 和 \cls{report} 类的 \tn{part} 标题被单独排在一页之上, +% \opt{afterindent} 选项没有意义。 +% +% 对于 \tn{section} 级以下标题,若设置了 \opt{runin} 选项为 \opt{true}, +% 即标题与随后正文排在同一段,\opt{afterindent} 选项也就没有了意义。 +% \end{function} +% +% \begin{table}[htbp] +% \small\centering +% \caption{\opt{afterindent} 选项的默认设置} +% \begin{tabular}{lll} +% \toprule +% 标题名 & \opt{scheme = chinese} & \opt{scheme = plain} \\ +% \midrule +% part (article) & |true| & |false| \\ +% part & 无效 & 无效 \\ +% chapter & |true| & |false| \\ +% section & |true| & |false| \\ +% subsection & |true| & |false| \\ +% subsubsection & |true| & |false| \\ +% paragraph & |true| & |false| \\ +% subparagraph & |true| & |false| \\ +% \bottomrule +% \end{tabular} +% \end{table} +% +% \begin{function}[EXP,updated=2016-05-10]{.../beforeskip} +% \begin{syntax} +% beforeskip = \Arg{弹性间距} +% \end{syntax} +% \opt{beforeskip} 选项用于设置章节标题前的垂直间距。 +% +% \opt{beforeskip} 选项的默认值,在 \opt{scheme} 选项的不同取值下相同。 +% \end{function} +% +% \begin{table}[htbp] +% \setlength\leftskip{0pt plus 1 fil minus \marginparwidth} +% \begin{minipage}[t]{.6\linewidth} +% \small\centering +% \caption{\opt{beforeskip} 选项的默认设置} +% \begin{tabular}{ll} +% \toprule +% 标题名 & 默认值 \\ +% \midrule +% part (article) & |4ex| \\ +% part (beamer) & |0pt| \\ +% part & |0pt plus 1fil| \\ +% chapter & |50pt| \\ +% section (beamer) & |0pt| \\ +% section & |3.5ex plus 1ex minus .2ex| \\ +% subsection (beamer) & |0pt| \\ +% subsection & |3.25ex plus 1ex minus .2ex| \\ +% subsubsection & |3.25ex plus 1ex minus .2ex| \\ +% paragraph & |3.25ex plus 1ex minus .2ex| \\ +% subparagraph & |3.25ex plus 1ex minus .2ex| \\ +% \bottomrule +% \end{tabular} +% \end{minipage}% +% \begin{minipage}[t]{.5\linewidth} +% \small\centering +% \caption{\opt{afterskip} 选项的默认设置} +% \begin{tabular}{ll} +% \toprule +% 标题名 & 默认值 \\ +% \midrule +% part (article) & |3ex| \\ +% part (beamer) & |0pt| \\ +% part & |0pt plus 1fil| \\ +% chapter & |40pt| \\ +% section (beamer) & |0pt| \\ +% section & |2.3ex plus .2ex| \\ +% subsection (beamer) & |0pt| \\ +% subsection & |1.5ex plus .2ex| \\ +% subsubsection & |1.5ex plus .2ex| \\ +% paragraph & |1em| \\ +% \qquad(sub3section) & |1ex plus .2ex| \\ +% \qquad(sub4section) & 同上 \\ +% subparagraph & |1em| \\ +% \qquad(sub4section) & |1ex plus .2ex| \\ +% \bottomrule +% \end{tabular} +% \end{minipage} +% \end{table} +% +% \begin{function}[EXP,updated=2015-06-27]{.../afterskip} +% \begin{syntax} +% afterskip = \Arg{弹性间距} +% \end{syntax} +% \opt{afterskip} 选项控制章节标题与后面下方之间的距离。 +% +% 对于 \tn{section} 级以下标题,\opt{runin} 选项会影响 \opt{afterskip} 选项的意义: +% 若 \opt{runin} 为 \opt{true},标题与随后正文排在同一段,\meta{弹性间距} 给出水平间距。 +% 否则,正文另起一段,\meta{弹性间距} 给出的是垂直间距。 +% +% \opt{afterskip} 选项的默认值,在 \opt{scheme} 选项的不同取值下相同。 +% +% \opt{sub3section} 或 \opt{sub4section} 宏包选项(见 +% \ref{subs:options-heading}~节)会影响 \opt{aftertitle} 选项的默认值。 +% \end{function} +% +% \begin{function}[EXP,added=2016-06-03]{.../fixskip} +% \begin{syntax} +% fixskip = \TFF +% \end{syntax} +% 默认情况下,\cls{article}、\cls{book} 和 \cls{report} 类的标题与正文的距离除了由 +% \opt{beforeskip} 和 \opt{afterskip} 选项设置的垂直间距外,还会有一些多余的间距。 +% \opt{fixskip} 选项用于抑制这些多余间距。 +% \end{function} +% +% \begin{function}[EXP,added=2016-10-01]{chapter/lofskip, chapter/lotskip} +% \begin{syntax} +% lofskip = \Arg{弹性间距} +% lotskip = \Arg{弹性间距} +% \end{syntax} +% \opt{lofskip} 选项控制插图目录(\file{.lof})中,章之间的插图标题的距离。 +% +% 同样,\opt{lotskip} 选项控制表格目录(\file{.lot})中,章之间的表格标题的距离。 +% +% 目前,这两个选项只在 \opt{chapter} 标题下有定义。 +% 他们的默认值,在 \opt{scheme} 选项的不同取值下都为 \SI{10}{pt}。 +% \end{function} +% +% \begin{function}[EXP,updated=2015-06-27]{.../indent} +% \begin{syntax} +% indent = \Arg{缩进间距} +% \end{syntax} +% \opt{indent} 选项用于设置章节标题本身的首行缩进。 +% +% \opt{indent} 选项的默认值,在 \opt{scheme} 选项的不同取值下相同。 +% +% 如果 \opt{indent} 的值是以 \texttt{em}、\texttt{ex} 或 \cs{ccwd} 为单位, +% 那么缩进间距的大小是相对于 \opt{format} 中指定的字号大小。 +% +% 例如,设置 \tn{part} 标题缩进三个字、\tn{section} 标题缩进 \SI{20}{pt}: +% \end{function} +% \begin{ctexexam} +% \ctexset{ +% part={ +% format+=\raggedright, +% indent=3\ccwd, +% }, +% section={ +% format=\Large\bfseries, +% indent=20pt, +% } +% } +% \part{首行缩进的标题} +% \noindent 无缩进的正文。 +% \section{首行缩进的标题} +% \noindent 无缩进的正文。 +% \end{ctexexam} +% +% \begin{table}[htbp] +% \begin{minipage}[t]{.5\linewidth} +% \small\centering +% \caption{\opt{indent} 选项的默认设置} +% \begin{tabular}{ll} +% \toprule +% 标题名 & 默认值 \\ +% \midrule +% part & |0pt| \\ +% chapter & |0pt| \\ +% section & |0pt| \\ +% subsection & |0pt| \\ +% subsubsection & |0pt| \\ +% paragraph & |0pt| \\ +% subparagraph & |\parindent| \\ +% \qquad(sub3section) & |0pt| \\ +% \qquad(sub4section) & 同上 \\ +% \bottomrule +% \end{tabular} +% \end{minipage}% +% \begin{minipage}[t]{.5\linewidth} +% \small\centering +% \caption{\opt{hang} 选项的默认设置} +% \begin{tabular}{ll} +% \toprule +% 标题名 & 默认值 \\ +% \midrule +% part & |false| \\ +% chapter & |false| \\ +% section & |true| \\ +% subsection & |true| \\ +% subsubsection & |true| \\ +% paragraph & 无意义 \\ +% \qquad(sub3section) & |true| \\ +% \qquad(sub4section) & |true| \\ +% subparagraph & 无意义 \\ +% \qquad(sub4section) & |true| \\ +% \bottomrule +% \end{tabular} +% \end{minipage}% +% \end{table} +% +% \begin{function}[EXP,updated=2019-03-31]{part/hang, chapter/hang, section/hang, +% subsection/hang, subsubsection/hang, paragraph/hang, subparagraph/hang} +% \begin{syntax} +% hang = \TF +% \end{syntax} +% \opt{hang} 选项用于设置是否对章节标题实施悬挂缩进(缩进的宽度为名字宽度和 \opt{indent} 选项 +% 设置的宽度之和)。 +% +% 本选项对 \cls{beamer}/\cls{ctexbeamer} 文档类无效。 +% 对于 \tn{section} 级以下标题,若设置了 \opt{runin} 选项为 \opt{true}, +% 即标题与随后正文排在同一段,\opt{hang} 选项没有意义。 +% \end{function} +% +% \begin{function}[EXP,added=2014-03-21]{part/pagestyle, chapter/pagestyle} +% \begin{syntax} +% pagestyle = \Arg{页面格式} +% \end{syntax} +% 设置 \cls{book}/\cls{ctexbook} 或 \cls{report}/\cls{ctexrep} 文档类 +% 中,\tn{part} 与 \tn{chapter} 标题所在页的页面格式(page style)。 +% \end{function} +% +% \begin{table}[htbp] +% \small\centering +% \caption{\opt{pagestyle} 选项的默认设置} +% \begin{tabular}{ll} +% \toprule +% 标题名 & 默认值 \\ +% \midrule +% part (article) & 无效 \\ +% part & |plain| \\ +% chapter & |plain| \\ +% \bottomrule +% \end{tabular} +% \end{table} +% +% \begin{function}[EXP,added=2016-09-19]{.../break, .../break+} +% \begin{syntax} +% break = \Arg{格式命令} +% break+= \Arg{格式命令} +% \end{syntax} +% \opt{break} 选项用于控制章节标题与之前正文的分隔关系。一般用于设置是否在标题之前分页或者设置行间罚点。 +% +% 带加号的 \opt{break+} 选项则用于在已有格式之后追加新的格式命令。 +% +% \opt{break} 选项的默认值,在 \opt{scheme} 选项的不同取值下相同。 +% +% 例如,若当前页剩余高度小于正文高度的一半时,则另起一页输出 \tn{section} 标题: +% \begin{ctexexam} +% \usepackage{needspace} +% \ctexset{section/break = \Needspace{.5\textheight}} +% \end{ctexexam} +% \end{function} +% +% \begin{table}[htbp] +% \small\centering +% \caption{\opt{break} 选项的默认设置} +% \begin{tabular}{ll} +% \toprule +% 标题名 & 默认值 \\ +% \midrule +% part (article) & |{}| \\ +% part & |\if@openright\cleardoublepage\else\clearpage\fi| \\ +% chapter & 同上 \\ +% section & |\addpenalty{\@secpenalty}| \\ +% subsection & 同上 \\ +% subsubsection & 同上 \\ +% paragraph & 同上 \\ +% subparagraph & 同上 \\ +% \bottomrule +% \end{tabular} +% \end{table} +% +% \begin{function}[EXP,added=2016-10-25]{.../tocline} +% \begin{syntax} +% tocline = \Arg{格式定义} +% \end{syntax} +% \opt{tocline} 选项用于定义章节标题在目录文件(\file{.toc})中的格式。\meta{格式定义}有两个参数: +% 参数 |#1| 是 |part|、|chapter| 等名字,参数 |#2| 是标题内容。 +% \end{function} +% +% \begin{table}[htbp] +% \small\centering +% \caption{\opt{tocline} 选项的默认设置} +% \begin{tabular}{ll} +% \toprule +% 标题名 & 默认值 \\ +% \midrule +% part & |\CTEXifname{\CTEXthepart\hspace{1em}}{}#2| \\ +% chapter (\opt{chinese}) +% & |\CTEXifname{\protect\numberline{\CTEXthechapter\hspace{.3em}}}{}#2| \\ +% chapter (\opt{plain}) +% & |\CTEXnumberline{#1}#2| \\ +% section & |\CTEXnumberline{#1}#2| \\ +% subsection & 同上 \\ +% subsubsection & 同上 \\ +% paragraph & 同上 \\ +% subparagraph & 同上 \\ +% \bottomrule +% \end{tabular} +% +% \medskip +% 其中 \tn{CTEXnumberline} 的意义是若标题 |#1| 没有名字,则不输出 |\numberline{\CTEXthe#1}| +% 等编号: +% \begin{verbatim} +% \CTEXifname{\protect\numberline{\csname CTEXthe#1\endcsname}}{} +% \end{verbatim} +% \end{table} +% +% \begin{function}[EXP,added=2015-06-21]{appendix/numbering} +% \begin{syntax} +% numbering = \TTF +% \end{syntax} +% 控制是否对附录章(对 \cls{book} 与 \cls{report})或附录节(对 \cls{article}) +% 进行编号。 +% +% 用法与普通章节 \opt{numbering} 选项类似。 +% \end{function} +% +% \begin{function}[EXP,updated=2014-03-08]{appendix/name} +% \begin{syntax} +% name = \{<前名字>,<后名字>\} +% name = \Arg{前名字} +% \end{syntax} +% 设置附录章(对 \cls{book} 与 \cls{report})或附录节(对 \cls{article})的 +% 名字。 +% +% 用法与普通章节 \opt{name} 选项类似。 +% +% 注意该选项与 \opt{appendixname} 选项(\ref{subs:capname}~节)在意义上有 +% 些重叠,但意义不同。\opt{appendixname} 选项只用来重定义 +% \tn{appendixname},而不管 \tn{appendixname} 如何使用;该选项则决定在章节标 +% 题中输出的名字,可以调用 \tn{appendixname} 设置。 +% \end{function} +% +% \begin{table}[htbp] +% \small\centering +% \caption{\opt{appendix/name} 选项的默认设置} +% \begin{tabular}{llllll} +% \toprule +% 文档类 & 影响命令 & \opt{scheme = chinese} & 实际定义 +% & \opt{scheme = plain} & 实际定义 \\ +% \midrule +% article & \tn{section} & |{}| & & |{}| & \\ +% book, report & \tn{chapter} & |\appendixname\space| & \verb*|附录 | +% & |\appendixname\space| & \verb*|Appendix | \\ +% \bottomrule +% \end{tabular} +% \end{table} +% +% \begin{function}[EXP]{appendix/number} +% \begin{syntax} +% number = \Arg{数字输出命令} +% \end{syntax} +% 设置附录章(对 \cls{book} 与 \cls{report})或附录节(对 \cls{article})编 +% 号的数字输出格式。 +% +% 用法与普通章节的 \opt{number} 选项类似。 +% +% 该选项也同时控制附录章节计数器的交叉引用。 +% +% 与普通章节的 \opt{number} 选项类似,同样需要注意,该选项不会影响计数器本身 +% 的输出,即不影响 \tn{thesection} 或 \tn{thechapter} 的定义。 +% \end{function} +% +% \begin{table}[htbp] +% \small\centering +% \caption{\opt{appendix/number} 选项的默认设置} +% \begin{tabular}{llllll} +% \toprule +% 文档类 & 影响命令 & 默认值 \\ +% \midrule +% article & \tn{section} & |\Alph{section}| \\ +% book, report & \tn{chapter} & |\Alph{chapter}| \\ +% \bottomrule +% \end{tabular} +% \end{table} +% +% 我们最后举一个稍微复杂的例子,来看看上述选项的综合应用。 +% +% \begin{ctexexam}[labelref=exam:miscopt] +% \ctexset { +% chapter = { +% beforeskip = 0pt, +% fixskip = true, +% format = \Huge\bfseries, +% nameformat = \rule{\linewidth}{1bp}\par\bigskip\hfill\chapternamebox, +% number = \arabic{chapter}, +% aftername = \par\medskip, +% aftertitle = \par\bigskip\nointerlineskip\rule{\linewidth}{2bp}\par +% } +% } +% \newcommand\chapternamebox[1]{% +% \parbox{\ccwd}{\linespread{1}\selectfont\centering #1}} +% ...... +% \chapter{熟悉 \LaTeX} +% \end{ctexexam} +% 本例的设置效果大致如下: +% \begin{center} +% \begin{minipage}{.75\linewidth}\Large\bfseries +% \hrule height .5bp \relax +% \medskip +% \hfill\parbox{\ccwd}{\linespread{1}\selectfont\centering 第 1 章} +% \par\smallskip +% \noindent 熟悉 \LaTeX +% \medskip\hrule height 1bp \relax +% \end{minipage} +% \end{center} +% +% \section{实用命令} +% \label{sec:useful-commands} +% \subsection{字号与间距} +% +% \begin{function}[updated = 2014-03-08, label = ]{\zihao} +% \begin{syntax} +% \tn{zihao} \Arg{字号} +% \end{syntax} +% 用于调整字号大小。其中 \meta{字号} 的有效值共有 16 个,如表 \ref{tab:zihao} +% 所示。使用 \tn{zihao} 命令调整字体大小时,西文字号大小会始终和中文字号保持一致。 +% \end{function} +% +% \begin{table}[!htbp] +% \centering +% \def\ZH#1{\zihaopt{#1} & \zihao{#1}} +% \tabcolsep=1em +% \caption{中文字号}\label{tab:zihao} +% \begin{tabular}{>{\ttfamily}S[mode=text,detect-family,table-format=-1] +% S[table-format=2.1]S[table-format=2.5]l} +% \toprule +% {\meta{字号}} & {大小(bp)} & {大小(pt)} & 意义 \\ +% \midrule +% 0 & 42 & \ZH{0} 初号 \\ +% {−0} & 36 & \ZH{-0} 小初号 \\ +% 1 & 26 & \ZH{1} 一号 \\ +% -1 & 24 & \ZH{-1} 小一号 \\ +% 2 & 22 & \ZH{2} 二号 \\ +% -2 & 18 & \ZH{-2} 小二号 \\ +% 3 & 16 & \ZH{3} 三号 \\ +% -3 & 15 & \ZH{-3} 小三号 \\ +% 4 & 14 & \ZH{4} 四号 \\ +% -4 & 12 & \ZH{-4} 小四号 \\ +% 5 & 10.5 & \ZH{5} 五号 \\ +% -5 & 9 & \ZH{-5} 小五号 \\ +% 6 & 7.5 & \ZH{6} 六号 \\ +% -6 & 6.5 & \ZH{-6} 小六号 \\ +% 7 & 5.5 & \ZH{7} 七号 \\ +% 8 & 5 & \ZH{8} 八号 \\ +% \bottomrule +% \end{tabular} +% \end{table} +% +% \begin{function}[updated=2014-03-28]{\ziju} +% \begin{syntax} +% \tn{ziju} \Arg{中文字符宽度的倍数} +% \end{syntax} +% 用于调整相邻汉字之间的间距,即(在正常中文行文中)前一个汉字的右边缘与后一个汉字 +% 的左边缘之间的距离。其中参数可以是任意浮点数值;而中文字符宽度指的是实际汉字的 +% 宽度,不包含当前字距。 +% +% 这个命令会影响 \tn{ccwd} 的值,但不会影响英文字距。 +% \end{function} +% +% \begin{function}[updated=2014-03-27]{\ccwd} +% 当前汉字的字宽保存在长度寄存器 \tn{ccwd} 之中。汉字字宽是相邻两个汉字中心 +% 之间的距离,包含字距在内。因此修改字距会间接修改字宽。 +% \end{function} +% +% \subsection{中文数字转换} +% +% \CTeX{} 宏集的中文数字转换功能实际上是调用 \pkg{zhnumber} 宏包来完成。下面只 +% 介绍一些基本的用法,更高级的用法可以查阅 \pkg{zhnumber} 宏包的文档。 +% +% \begin{function}[updated=2016-05-01]{\chinese} +% \begin{syntax} +% \tn{chinese} \Arg{counter} +% \tn{pagenumbering} \{chinese\} +% \end{syntax} +% \tn{chinese} 命令与 \tn{roman} 等命令的用法类似,作用在一个 \LaTeX{} +% 计数器上,将计数器的值以中文数字的形式输出。 +% \end{function} +% +% \begin{function}[added=2014-03-08]{\zhnumber} +% \begin{syntax} +% \tn{zhnumber} \Arg{number} +% \end{syntax} +% 以中文格式输出数字。这里的数字可以是整数、小数和分数。 +% \end{function} +% +% \begin{function}[added=2014-03-08]{\zhdigits} +% \begin{syntax} +% \tn{zhdigits} \Arg{number} +% \end{syntax} +% 将阿拉伯数字转换为中文数字串。 +% \end{function} +% +% \begin{function}{\CTEXnumber} +% \begin{syntax} +% \tn{CTEXnumber} "\"<macro> \Arg{number} +% \end{syntax} +% |\|<macro> 必须是一个 \TeX{} 宏,不需预先定义。\tn{CTEXnumber} 通过 +% \tn{zhnumber} 将 \meta{number} 转为中文数字,最后将结果存储在 |\|<macro> +% 里。对 |\|<macro> 的定义是局部的,将它展开一次就可以得到转换结果。 +% \end{function} +% +% 一般来说,并不需要使用 \tn{CTEXnumber},直接使用 \tn{zhnumber} 即可。但是,如果 +% 在文档中需要多次使用同一个数字 \meta{number} 的中文形式,就可以先用 +% \tn{CTEXnumber} 将结果保存起来备用,而不是每次使用时都用 \tn{zhnumber} 现场 +% 转换一次。 +% +% \begin{function}{\CTEXdigits} +% \begin{syntax} +% \tn{CTEXdigits} "\"<macro> \Arg{number} +% \end{syntax} +% \tn{CTEXdigits} 与 \tn{CTEXnumber} 类似,但其转换的结果是中文数字串,而不是 +% 中文数字。 +% \end{function} +% +% \subsection{杂项} +% +% \begin{function}{\CTeX} +% 用于显示 \CTeX 标志。 +% \end{function} +% +% \section{\LuaLaTeX{} 下的中文支持方式} +% \label{sec:lualatex-chinese} +% +% 在 \LuaLaTeX{} 下,\CTeX{} 宏集依赖 \pkg{LuaTeX-ja} 宏包来完成中文支持。 +% 该宏包是日本 \TeX{} 社区的北川弘典、前田一贵、八登崇之等人开发的,设计目的主要 +% 是在 \LuaTeX{} 引擎下实现日本 p\TeX{} 引擎的(大部分)功能。它为了兼容 p\LaTeX +% 的使用习惯,对 \LaTeXe 的 \pkg{NFSS} 作了不少修改和扩充。这对于简体中文用户来说 +% 不是必要的,因而 \CTeX{} 禁用了它在 \LaTeX{} 格式下的大部分设置,只保留了必要的 +% 部分。同时修改了它的字体设置方式,使得相关命令与 \pkg{xeCJK} 宏包大致相同。 +% +% 20150420 版以后的 \pkg{LuaTeX-ja} 宏包开始支持竖排,但 \CTeX{} 暂不支持竖排。 +% +% \subsection{\LuaLaTeX{} 下替代字体的设置} +% +% \begin{function}[added=2014-04-14]{AlternateFont} +% \begin{syntax} +% \tn{setCJKfamilyfont} \Arg{family} +% \ [ +% \ AlternateFont = +% \ \{ +% \ \Arg{character range_1} \oarg{alternate font features_1} \Arg{alternate font name_1} || +% \ \Arg{character range_2} \oarg{alternate font features_2} \Arg{alternate font name_2} || +% \ ...... +% \ \} , +% \ <base font features> +% \ ] \Arg{base font name} +% \end{syntax} +% 在设置字体族 \meta{family} 的时候,同时设置该字体族在字符范围 +% \meta{character range_n} 内,对应字形的替代字体。 +% \end{function} +% +% \begin{function}[added=2014-04-14]{CharRange} +% \begin{syntax} +% \tn{setCJKfamilyfont} \Arg{family} +% \ [ +% \ CharRange = \Arg{character range} , +% \ <alternate font features> +% \ ] \Arg{alternate font name} +% \end{syntax} +% 只设置字体族 \meta{family} 在字符范围 \meta{character range} 内,对应字形的 +% 替代字体。 +% \end{function} +% +% 一个 \tn{setCJKfamilyfont} 里只能使用一次 \opt{CharRange} 或者 +% \opt{AlternateFont},但可以将它们分开重叠使用。例如下面的方式是有效的。 +% +% \begin{ctexexam} +% \setCJKmainfont[AlternateFont={...}{...}, ...]{...} +% \setCJKmainfont[CharRange={"4E00->"67FF,-2}, ...]{...} +% \setCJKmainfont[CharRange={"6800->"9FFF}, ...]{...} +% \end{ctexexam} +% +% \begin{function}[EXP,added=2014-04-14]{declarecharrange} +% \begin{syntax} +% \tn{ctexset} +% \ \{ +% \ declarecharrange = +% \ \{ +% \ \Arg{name_1} \Arg{character range_1} , +% \ \Arg{name_2} \Arg{character range_2} , +% \ ... +% \ \} +% \ \} +% \end{syntax} +% 预先声明字符范围。声明字符范围 \meta{name} 之后,它的名字 \meta{name} 可以 +% 用在 \opt{AlternateFont} 和 \opt{CharRange} 选项的 \meta{character range} +% 之中,表示对应的字符范围。 +% \end{function} +% +% 在声明字符范围 \meta{name} 的同时,还为 \tn{setCJKmainfont} 等字体设置命令定义 +% 了选项 \meta{name},用于设置对应字符的替代字体: +% \begin{quote}\linespread{1}\small\ttfamily +% \meta{name} = \oarg{alternate font features} \Arg{alternate font name} +% \end{quote} +% \meta{name} 选项可以与 \opt{AlternateFont} 共同使用,但不能与 \opt{CharRange} +% 一起使用。如果没有给 \meta{name} 设置值,则等价于设置 \opt{CharRange=\meta{name}}, +% 即只设置 \meta{name} 对应的字符范围的替代字体。 +% +% \begin{function}[EXP,added=2014-04-15]{clearalternatefont,resetalternatefont} +% \begin{syntax} +% \tn{ctexset} +% \ \{ +% \ clearalternatefont = \Arg{family_1, family_2, ...} , +% \ resetalternatefont = \Arg{family_1, family_2, ...} , +% \ clearalternatefont , +% \ resetalternatefont +% \ \} +% \end{syntax} +% 清除与重置 CJK 字体族 \meta{family} 的替换字体设置。如果没有给定值,则作用于 +% 当前 CJK 字体族。清除与重置操作总是全局的。 +% \end{function} +% +% \section{\CTeX{} 宏集的配置文件} +% +% \CTeX{} 宏集提供了不同的配置文件,可以通过修改配置文件来改变 \CTeX{} 宏集的 +% 默认行为。 +% +% 在多数情况下,并不需要修改配置文件,\CTeX{} 宏集的默认设置已经能满足大多数用 +% 户的需要。不恰当地修改 \CTeX{} 宏集的默认行为也可能导致同一文件在别处无法正 +% 常编译或排版效果完全不同,因此修改应该慎重。 +% +% 但在一些情况下,直接修改配置文件仍是必要的,例如: +% \begin{itemize} +% \item 系统没有安装默认设置的字体文件,无法编译。 +% \item 需要经常编译来自其他系统的中文 \TeX{} 文件,但对方的操作系统或默认设置 +% 与本机不同。 +% \end{itemize} +% +% 与 \CTeX{} 宏集的源代码一样,配置文件采用 \LaTeXiii{} 的语法编写。 +% +% \CTeX{} 宏集的配置文件随宏包其他文件一起安装在 \TeX{} 系统 TDS 目录树中,文 +% 件后缀是 \file{.cfg}。为了避免本地配置文件内容因 \CTeX{} 宏集的更新而丢失, +% 不要直接修改系统 TDS 目录树中的配置文件,而应该将系统自带的配置文件复制到本 +% 地的或用户私有的 TDS 目录树中修改,并运行 \bashcmd{texhash} 命令刷新文件名数据库。 +% +% 例如对于 \TeX{} Live,系统自带的配置文件就在 \TeX{} Live 安装目录下的 +% \path{texmf-dist/tex/latex/ctex/config/} 子目录下,可以修改它的副本,保存在 +% 本地 TDS 树的 \path{texmf-local/tex/latex/ctex/} 目录下,或者用户 TDS 树的 +% \path{~/.texlive2015/texmf-var/tex/latex/ctex/} 目录下,作为本地/用户专有的 +% 配置文件。复制配置文件后需要运行 |texhash| 命令使本地配置文件生效。 +% +% \MiKTeX{} 的配置文件也保存在类似的目录结构中,\MiKTeX{} 管理的 +% 几个 TDS 根目录可以在 \MiKTeX{} Options 设置项中查看到,这里不再赘述。 +% +% 除了修改本地 \TeX{} 系统中的配置文件,对于特定文档,也可以将修改过的配置文件 +% 保存在文档的工作目录下。此时配置文件就只对工作目录下的所有文档生效。 +% +% \subsection{修改宏包默认选项} +% +% 配置文件 \file{ctexopts.cfg} 可以用来修改宏包的默认选项。随系统安装的配置文 +% 件除了文件信息声明外没有实际的内容,但在注释中给出了一个简单的示例,只要取消 +% 注释就可以生效。 +% +% \begin{ctexexam} +% % 系统自带 ctexopts.cfg 注释中的示例语句,固定默认字体集为 windowsnew。 +% % 该设置可以用在安装了 Windows 字体的非 Windows 系统中。 +% \keys_set:nn { ctex / option } { fontset = windowsnew } +% \end{ctexexam} +% 如上例所示,宏包选项通常使用 \LaTeXiii{} 的 \cs{keys_set:nn} 命令完成键值设置, +% 第一个参数是固定的子模块 |ctex/option|,第二个参数中是用户定义的新的默认宏包 +% 选项。 +% +% \file{ctexopts.cfg} 中的设置将在 \CTeX{} 宏集的开始处,定义过宏包选项之后, +% \tn{ProcessKeysOptions} 命令之前生效。最好只使用此配置文件修改宏包默认选项。 +% +% \subsection{宏包载入后的配置} +% +% 配置文件 \file{ctex.cfg} 将在宏包的末尾被载入生效。可以用它完成任意的设置, +% 或是覆盖已有的定义。随系统安装的配置文件除版本信息外没有实际内容,注意配置文 +% 件中也使用 \LaTeXiii{} 语法。 +% +% \begin{ctexexam} +% % 简单的 ctex.cfg 内容示例。 +% % 修改默认的页面格式设置。 +% \pagestyle{plain} +% \end{ctexexam} +% +% \begin{ctexexam} +% % 略复杂的 ctex.cfg 内容示例:禁止段末孤字成行。 +% % 在使用 XeTeX 编译时,打开 xeCJK 的 CheckSingle 选项。 +% \sys_if_engine_xetex:T +% { +% \xeCJKsetup { CheckSingle } +% } +% % 在使用 LuaTeX 编译时,设置 LuaTeX-ja 的 jcharwidowpenalty 参数。 +% \sys_if_engine_luatex:T +% { +% \ltjsetparameter { jcharwidowpenalty = 10000 } +% } +% \end{ctexexam} +% +% \subsection{配置标题中文翻译} +% +% 由于 \CTeX{} 宏集需要同时支持 GBK 和 UTF-8 两种编码,因此对标题的中文翻译写 +% 在两个配置文件当中:\file{ctex-name-gbk.cfg} 和 \file{ctex-name-utf8.cfg}。 +% 两个文件的设置相同,只是编码不同。 +% +% 为了同一文档在不同电脑上编译效果的一致性,通常不建议修改默认的中文翻译。 +% +% \subsection{自定义字体集} +% +% \ref{subs:options-CJK-font}~节介绍的用于 |fontset| 选项的自定义字库文件, +% 类似于 \CTeX{} 宏集的配置文件,也应该与其他本地配置文件一起保存在本地 +% \texttt{TDS} 目录树下,并可以配合 \file{ctexopts.cfg} 等配置文件使用。 +% +% \section{对旧版本的兼容性} +% +% \subsection{\CTeX\ 0.8a 及以前的版本} +% +% 在 ctex-kit 项目成立之前,\CTeX 宏包的最后一个版本是 \CTeX\ +% 0.8a(2007/05/06)。 +% +% 第 2 版未考虑对这些很早版本的兼容性。 +% +% \subsection{\CTeX\ 0.9--\CTeX\ 1.0d} +% +% 在 2009 年在 ctex-kit 项目成立后,新增了 \XeTeX{} 引擎的支持,并增加了不少控 +% 制字体的命令和选项。 +% +% 这里主要介绍新版本 \CTeX 宏包相对 1.02d 版本(2014/06/09)的兼容性。 +% +% 第 2 版的 \CTeX 宏包已尽力保证对 1.0x 版本的兼容性,原有为 1.0x 编写的代码, +% 在第 2 版的 \CTeX 宏包下保证仍能编译,并且在大多数情况下保持编译效果不变。 +% +% \CTeX 宏包在 0.8a 以前的版本支持以 \pkg{CCT} 作为底层中文支持方式,从 0.9 版 +% 之后即不再推荐使用,只保留向后兼容。在 \CTeX 宏包第 2 版中则完全不再支持 +% \pkg{CCT}。 +% +% 下面这些是在旧版本 \CTeX 宏包中存在,而在新版本中已不建议使用的选项和命令, +% 在未来版本中可能会删去它们的支持。 +% +% 在多数情况下它们的功能仍将保留,但也有部分选项命令功能已失效。 +% +% \begin{function}{cs4size, c5size} +% 分别相当于 |zihao=-4| 和 |zihao=5|,过时选项。 +% \end{function} +% +% \begin{function}{CCT, CCTfont} +% 相关选项已删除。 +% \end{function} +% +% \begin{function}{indent, noindent} +% \opt{indent} 和 \opt{noindent} 什么也不做,过时选项。 +% +% 在中文版式下,\pkg{ctex} 宏包的相关功能在与标准文档类及其衍生文档类联用时 +% 默认打开。\CTeX{} 文档类的相关功能由章节标题的 \opt{afterindent} 选项的值 +% 来确定。 +% \end{function} +% +% \begin{function}[label = ]{zhmap, nozhmap} +% \opt{zhmap} 宏包选项增加了参数,扩充了功能,除了支持真假值参数外,还支持选择 +% \pkg{zhmCJK} 作为底层中文处理宏包。(\ref{subs:options-CJK-font}~节) +% +% \opt{nozhmap} 选项相当于 |zhmap=false|。过时选项。 +% \end{function} +% +% \begin{function}{winfonts, adobefonts, nofonts} +% 宏包选项 \opt{winfonts} 相当于 |fontset=windows|,\opt{adobefonts} 相当于 +% |fontset=adobe|,\opt{nofonts} 相当于 |fontset=none|。这几个选项是过时选项, +% 对于新文档,应使用 \opt{fontset} 选项设置不同字体集。 +% +% 另外,第 2 版 \CTeX 宏包的默认字体不再是 Windows 系统字体,而是根据检测到的 +% 操作系统选择使用 Windows、Mac 的系统字体还是 Fandol 字体 +% (\ref{subs:options-CJK-font}~节)。 +% \end{function} +% +% \begin{function}[label = ]{punct, nopunct} +% 旧版本中宏包 \opt{punct} 选项没有参数,现在可以用参数设定标点风格 +% (\ref{subs:options-type-style}~节)。原有无参形式的 \opt{punct} 选项相当 +% 于 |punct=quanjiao|。 +% +% 旧版宏包中 \opt{nopunct} 选项的效果大致相当于 |punct=plain|。过时选项,不推荐使用。 +% \end{function} +% +% \begin{function}{cap, nocap} +% 原有的 \opt{cap} 和 \opt{nocap} 选项由新的 \opt{scheme} 选项代替。 +% (\ref{subs:options-type-style}~节) +% +% \opt{cap} 选项相当于 |scheme = chinese|,\opt{nocap} 选项相当 +% 于 |scheme = plain|。它们均已过时,仅因兼容性而保留。 +% \end{function} +% +% \begin{function}[label = ]{space, nospace} +% 新版本宏包 \opt{space} 选项增加真假值参数。 +% (\ref{subs:options-type-style}~节) +% +% \opt{nospace} 选项相当于 |space=false|,成为过时选项。 +% \end{function} +% +% \begin{function}{fancyhdr} +% 新版本宏包中总是自动处理对 \pkg{fancyhdr} 宏包的兼容性,而由用户自己使用 +% \tn{usepackage} 载入 \pkg{fancyhdr} 宏包。 +% +% \opt{fancyhdr} 选项过时,因兼容性保留,功能是载入 \pkg{fancyhdr} 宏包。 +% \end{function} +% +% \begin{function}{hyperref} +% 新版本宏包中总是自动处理对 \pkg{hyperref} 宏包的兼容性,而由用户自己使用 +% \tn{usepackage} 载入 \pkg{hyperref} 宏包。 +% +% \opt{hyperref} 选项过时,因兼容性保留,功能是在导言区末尾载入 \pkg{hyperref} +% 宏包。 +% \end{function} +% +% \begin{function}{fntef} +% 旧版本的 \opt{fntef} 选项用于统一 \pkg{CCTfntef} 与 \pkg{CJKfntef} 的界面, +% 新版本 \CTeX{} 宏集不再支持 \pkg{CCT},而是直接载入 \pkg{CJKfntef} 或 +% \pkg{xeCJKfntef} 宏包并禁用其彩色设置。该选项是过时选项。 +% \end{function} +% +% \begin{function}{\CTEXunderdot, \CTEXunderline, \CTEXunderdblline, +% \CTEXunderwave, \CTEXsout, \CTEXxout, \CTEXfilltwosides} +% 在调用 \opt{fntef} 宏包选项的同时,旧版本 \CTeX{} 宏包由于需要支持 \pkg{CCT} +% 系统,会将以 |\CJK| 开头的 \tn{CJKunderline} 等宏换名为以 |\CTEX| 开头的 +% \tn{CTEXunderline} 等宏。此功能在新版本的 \CTeX{} 宏集中已失去意义。 +% +% 此外,在 \pdfTeX{} 引擎下,用于设置格式的 \tn{CJKunderdotbasesep} 等宏也被换 +% 名为 \tn{CTEXunderdotbasesep} 等宏。 +% +% 在新版本中,上述由 \opt{fntef} 衍生的相关宏都成为过时命令。 +% \end{function} +% +% \begin{function}{\CTEXsetfont} +% 更新当前的中文字体信息,包括当前字距(\tn{ccwd})和段首缩进(\tn{parindent})。 +% 一般来说,用户无需使用这个命令。 +% \end{function} +% +% \begin{function}{\CTEXindent} +% 更新 \tn{ccwd} 宽度后设置 |\parindent=2\ccwd|。过时命令。 +% \end{function} +% +% \begin{function}{\CTEXnoindent} +% 设置 |\parindent=0pt|。过时命令。 +% \end{function} +% +% \begin{function}{\CTEXsetup} +% \begin{syntax} +% \tn{CTEXsetup}\oarg{选项}\Arg{标题} +% \end{syntax} +% 相当于设置了 +% \texttt{\tn{ctexset}\{ \meta{标题} = \Arg{选项} \}}。 +% 过时命令。 +% \end{function} +% +% \begin{function}{\CTEXoptions} +% \begin{syntax} +% \tn{CTEXoptions}\oarg{选项} +% \end{syntax} +% 相当于设置了 +% \texttt{\tn{ctexset}\Arg{选项}}。 +% 过时命令。 +% \end{function} +% +% \begin{function}{\Chinese} +% \begin{syntax} +% \tn{Chinese}\Arg{counter} +% \end{syntax} +% 新版宏集中 \tn{chinese} 统一了旧版本中 \tn{chinese} 和 \tn{Chinese} 的功能。因此, +% 该命令已过时。 +% \end{function} +% +% \begin{function}{captiondelimiter} +% 原为 \tn{CTEXoptions} 命令的选项,用于控制 \tn{caption} 编号后面的标点。此选 +% 项已过时,并在新版本的 \CTeX 宏包中失效。 +% +% 可以使用 \pkg{caption} 宏包的 \opt{labelsep} 选项来完成同样的功能。 +% \begin{ctexexam} +% % 代替 \CTEXoptions[captiondelimiter={:}] +% \usepackage{caption} +% \captionsetup{labelsep=colon} +% \end{ctexexam} +% \end{function} +% +% \subsection{\CTeX\ 1.02c 以后的 SVN 开发版} +% +% \CTeX 宏包在 1.02c 版本(2011/03/11)之后在 Google code 上的 SVN 开发版本, +% 内部版本号一直升到 1.11 版,但从未正式发布。SVN 开发版在 1.02c 版本的基础上 +% 新增的功能在第 2 版中大多继承了过来,但新增的命令与选项都不再保持兼容。 +% +% \CTeX 宏包第 2 版不保证对未发布的 SVN 开发版兼容。 +% +% \subsection{\CTeX\ 2.2 之前的版本} +% +% \begin{function}{part/beforeskip, chapter/beforeskip, section/beforeskip, +% subsection/beforeskip, subsubsection/beforeskip, paragraph/beforeskip, +% subparagraph/beforeskip} +% 在 \CTeX\ 2.2 之前的版本中,\opt{beforeskip} 选项的符号还用于确定章节标题后 +% 首段的缩进。当 \opt{beforeskip} 是负值时,章节标题后的第一段按英文文档的排版 +% 习惯,没有首行缩进,否则保留首行缩进。 +% +% 这一特性在 2.2 版和后续版本中不再保留,相应的功能通过新的 \opt{afterindent} +% 选项来设置。如果原先设置 \opt{beforeskip} 为负值,在新版本中需要改为正值, +% 并设置相应的 \opt{afterindent} 选项为 \opt{false}。 +% \end{function} +% +% \begin{function}{section/afterskip, subsection/afterskip, +% subsubsection/afterskip, paragraph/afterskip, subparagraph/afterskip} +% 在 \CTeX\ 2.2 之前的版本中,对于 \tn{section} 级以下标题,\opt{afterskip} +% 选项的符号用于确定标题与随后正文是否排在同一段。 +% 如果是正值,则正文另起一段,否则标题与随后正文排在同一段, +% \opt{afterskip} 的绝对值给出水平间距。 +% +% 这一特性在 2.2 版和后续版本中不再保留,相应的功能通过新的 \opt{runin} +% 选项来设置。如果原先设置 \opt{afterskip} 为负值,在新版本中需要改为正值, +% 并设置相应的 \opt{runin} 选项为 \opt{true}。 +% \end{function} +% +% \subsection{\CTeX\ 2.4.1 和 2.4.2} +% +% \begin{function}{part/fixbeforeskip, chapter/fixbeforeskip} +% 这两个选项已经被删除,相应功能由新的选项 \opt{fixskip} 提供。 +% \end{function} +% +% \section{宏集依赖情况与手工安装方法} +% \label{sec:dep-ins} +% +% 本节介绍 \CTeX{} 宏集的依赖情况,并介绍手工编译安装的具体方法。 +% 通常用户只需参照第 \ref{subsec:easy-ins}~节介绍的方法,使用发行版自带的宏包管理器安装 +% 本宏集。 +% +% \CTeX{} 宏集有两个源文件:\file{ctex.dtx}、\file{ctexpunct.spa}。 +% 使用不同的编译方式时,\CTeX{} 依赖的宏包略有不同。在手工安装 \CTeX{} 宏集之前,请确保 +% 你的 \TeX{} 发行版中已经正确安装了这些宏包。\CTeX{} 依赖宏包的详情叙述如下: +% +% \begin{itemize} +% \item \pkg{expl3}、\pkg{xparse} 和 \pkg{l3keys2e} 宏包。它们属于 \pkg{l3kernel} +% 和 \pkg{l3packages} 宏集。 +% \item \pkg{indentfirst} 宏包,属于 \pkg{tools} 宏集。 +% \item \pkg{everysel} 宏包,属于 \pkg{ms} 宏集。 +% \item \pkg{ulem} 宏包。 +% \item \pkg{zhnumber} 宏包。 +% \item[\ding{229}] 以上是各种编译方式都必需的依赖项。 +% \item \pkg{CJK} 宏集。 +% \item \pkg{CJKpunct} 宏包。 +% \item \pkg{xCJK2uni} 宏包。 +% \item \pkg{zhmetrics} 宏包。 +% \item \pkg{zhmCJK} 宏包,它还依赖 \pkg{oberdiek} 宏集。 +% \item[\ding{229}] 以上是使用 \pdfLaTeX{} 或 \LaTeX{} + \dvipdfmx{} 的编译方式所需要 +% 的依赖项,其中 \pkg{zhmCJK} 是可选的。 +% \item \pkg{xeCJK} 宏集,它还依赖 +% \begin{itemize} +% \item \pkg{xtemplate} 宏包,它属于 \pkg{l3packages} 宏集。 +% \item \pkg{fontspec} 宏包。 +% \end{itemize} +% \item \pkg{environ} 宏包,它还依赖 \pkg{trimspaces} 宏包。 +% \item[\ding{229}] 以上是使用 \XeLaTeX{} 编译时的依赖项。 +% \item \pkg{luatexja} 宏包,它还依赖 +% \begin{itemize} +% \item \pkg{adobemapping} 宏包。 +% \item \pkg{lualibs} 宏包。 +% \item \pkg{luaotfload} 宏包。 +% \item \pkg{luatexbase} 宏包,它还依赖 \pkg{ctablestack} 宏包。 +% \item \pkg{oberdiek} 宏集。 +% \item \pkg{xkeyval} 宏包。 +% \item \pkg{etoolbox} 宏包。 +% \end{itemize} +% \item \pkg{fontspec} 宏包。 +% \item \pkg{xunicode-addon} 宏包,属于 \pkg{xeCJK} 宏集,它还依赖 +% \begin{itemize} +% \item \pkg{xunicode} 宏包,它还依赖 +% \begin{itemize} +% \item \pkg{graphics} 宏集。 +% \item \pkg{graphics-cfg} 宏包。 +% \item \pkg{graphics-def} 宏包。 +% \end{itemize} +% \end{itemize} +% \item[\ding{229}] 以上是使用 \LuaLaTeX{} 编译时的依赖项。 +% \item \pkg{pxeverysel} 宏包,属于 \pkg{platex-tools} 宏集。 +% \item \pkg{zhmetrics-uptex} 宏包。 +% \item[\ding{229}] 以上是使用 \upLaTeX{} 编译时的依赖项。 +% \end{itemize} +% +% 出于一些原因,\pkg{zhmCJK} 尚未被收入 \TeXLive{} 和 \MiKTeX。因此,若 +% 你希望使用 \pkg{zhmCJK} 作为 \CTeX{} 宏集的底层中文支持方式,那么你需要自行安装该宏包。 +% \pkg{zhmCJK} 的安装较为复杂。我们建议你 +% \begin{enumerate} +% \item 从 CTAN 下载 \pkg{zhmCJK} 宏包的 +% \href{http://mirrors.ctan.org/install/language/chinese/zhmcjk.tds.zip} +% {TDS 安装包}, +% \item 按目录结构将文件复制到 \TeX{} 发行版的本地 TDS 根目录, +% \item 最后执行 \bashcmd{texhash} 刷新 \TeX{} 发行版的 ls-R 数据库以完成安装。 +% \end{enumerate} +% 其他细节,可参照其 +% \href{http://mirrors.ctan.org/language/chinese/zhmcjk/zhmCJK.pdf}{宏包手册} +% 中第 3 节的指导。 +% +% \emph{\CTeX{} 宏集已被 \TeXLive{} 和 \MiKTeX{} 收录,若无特别理由, +% 我们强烈建议用户使用宏包管理器安装本宏集。} +% +% 若要手工安装,请遵循如下步骤: +% \begin{enumerate} +% \item 从 CTAN 下载 \CTeX{} 宏集的 +% \href{http://mirrors.ctan.org/install/language/chinese/ctex.tds.zip} +% {TDS 安装包}, +% \item 按目录结构将文件复制到 \TeX{} 发行版的本地 TDS 根目录, +% \item 最后执行 \bashcmd{texhash} 刷新 \TeX{} 发行版的 ls-R 数据库以完成安装。 +% \end{enumerate} +% +% \section{开发人员} +% +% \begin{itemize} +% \item 吴凌云 (\email{aloft@ctex.org}) +% \item 江疆 (\email{gzjjgod@gmail.com}) +% \item 王越 (\email{yuleopen@gmail.com}) +% \item 刘海洋 (\email{LeoLiu.PKU@gmail.com}) +% \item 李延瑞 (\email{LiYanrui.m2@gmail.com}) +% \item 陈之初 (\email{zhichu.chen@gmail.com}) +% \item 李清 (\email{sobenlee@gmail.com}) +% \item 黄晨成 (\email{liamhuang0205@gmail.com}) +% \end{itemize} +% +% 目前比较活跃的开发维护人员是刘海洋、李清和黄晨成。 +% +% +% \begin{thebibliography}{9} +% \bibitem{knuthtex1986} +% \textsc{Donald~Ervin Knuth}. +% \newblock \textit{The {{\TeX{}book}}}, \textit{Computers \& Typesetting}, +% volume~A. +% \newblock Addison-Wesley, 1986 +% +% \bibitem{mittelbach2004} +% \textsc{Frank Mittelbach} and \textsc{Michel Goossens}. +% \newblock \textit{The {{\LaTeX}} Companion}. +% \newblock Tools and Techniques for Computer Typesetting. Boston: +% Addison-Wesley, second edition, 2004 +% +% \end{thebibliography} +% +% \end{documentation} +% +% +% \StopEventually{} +% +% +%\begin{implementation} +% \clearpage +% \section{代码实现} +% +% \begin{macrocode} +%<@@=ctex> +% \end{macrocode} +% +% 宏包载入检查。 +% \begin{macrocode} +%<*class|ctex> +\tl_const:Nx \c_@@_version_tl + { \cs_if_exist_use:cF { ver@ \@currname . \@currext } { 9999/99/99 } } +%<*class> +\cs_new_eq:cN { ver@ctex. \@pkgextension } \c_@@_version_tl +\cs_new_eq:cN { ver@ctexcap. \@pkgextension } \c_@@_version_tl +\cs_new_eq:cN { ver@ctexsize. \@pkgextension } \c_@@_version_tl +\cs_new_eq:cN { ver@ctexheading. \@pkgextension } \c_@@_version_tl +%</class> +%<*ctex> +\msg_new:nnnn { ctex } { subpackage-loaded } + { Package~`#1'~can~not~be~loaded~with~`ctex'. } + { + `#1'~is~actually~a~part~of~`ctex'.\\ + It~is~not~necessary~to~load~it~separately. + } +\@ifpackageloaded { ctexsize } + { \msg_error:nnn { ctex } { subpackage-loaded } { ctexsize } } + { \cs_new_eq:cN { ver@ctexsize. \@pkgextension } \c_@@_version_tl } +\@ifpackageloaded { ctexheading } + { \msg_error:nnn { ctex } { subpackage-loaded } { ctexheading } } + { \cs_new_eq:cN { ver@ctexheading. \@pkgextension } \c_@@_version_tl } +%</ctex> +%</class|ctex> +% \end{macrocode} +% +% \begin{macrocode} +%<*class|style> +\RequirePackage { xparse , l3keys2e } +%</class|style> +% \end{macrocode} +% +% \begin{macrocode} +%<*class|ctex> +% \end{macrocode} +% +% \changes{v2.3}{2015/12/20}{与 \LaTeXiii{} (2015/12/20) 同步。} +% \changes{v2.4.10}{2017/07/19}{常数 \cs{c_minus_one} 已过时。} +% \changes{v2.4.10}{2017/07/22}{使用 \texttt{lazy} 函数对 Boolean 表达式 +% 进行最小化运算(\LaTeXiii{} 2017/07/19)。} +% +% 检查 \pkg{expl3} 和 \pkg{l3keys2e} 的版本。 +% \begin{macrocode} +\msg_new:nnnn { ctex } { l3-too-old } + { Support~package~`#1'~too~old. } + { + Please~update~an~up~to~date~version~of~the~bundles\\\\ + `l3kernel'~and~`l3packages'\\\\ + using~your~TeX~package~manager~or~from~CTAN. + } +\@ifpackagelater { expl3 } { 2019/03/05 } { } + { \msg_error:nnn { ctex } { l3-too-old } { expl3 } } +%<*class> +\@ifpackagelater { l3keys2e } { 2015/12/20 } { } + { \msg_error:nnn { ctex } { l3-too-old } { l3keys2e } } +%</class> +% \end{macrocode} +% +% \begin{variable}{\c_@@_engine_str,\c_@@_engine_file_str} +% 引擎检查。目前 \LaTeXiii{} 将 \ApTeX{} 识别为 \upTeX。 +% \begin{macrocode} +\str_const:Nx \c_@@_engine_str + { \cs_if_exist:NTF \ngostype { aptex } { \c_sys_engine_str } } +\msg_new:nnnn { ctex } { engine-not-supported } + { Engine~`#1'~is~not~yet~supported,~ctex~will~abort! } + { You~can~switch~to~xelatex,~lualatex,~pdflatex,~uplatex,~or~aplatex. } +\file_if_exist:nTF { ctex-engine- \c_@@_engine_str .def } + { + \str_const:Nx \c_@@_engine_file_str + { ctex-engine- \c_@@_engine_str .def } + } + { \msg_critical:nnx { ctex } { engine-not-supported } { \c_@@_engine_str } } +% \end{macrocode} +% \end{variable} +% +% \begin{macrocode} +%</class|ctex> +% \end{macrocode} +% +% \begin{macrocode} +%<*class|ctex|ctexheading> +% \end{macrocode} +% +% \begin{macrocode} +\RequirePackage { ctexhook , ctexpatch } +%<!ctexheading>\RequirePackage { fix-cm , everysel } +% \end{macrocode} +% +% \subsection{内部函数与变量} +% +% \begin{variable}{\l_@@_tmp_tl,\l_@@_tmp_int,\l_@@_tmp_box,\l_@@_tmp_dim} +% 临时变量。 +% \begin{macrocode} +\tl_clear_new:N \l_@@_tmp_tl +\int_new:N \l_@@_tmp_int +\box_new:N \l_@@_tmp_box +%<!ctexheading>\dim_new:N \l_@@_tmp_dim +% \end{macrocode} +% \end{variable} +% +% \begin{macro}[int]{\ctex_file_wrapper:nnn} +% 设置文件操作的 \tn{catcode} 环境,参数 |#1| 是设置,|#2| 是文件操作,|#3| 是恢复。 +% 默认关闭 \LaTeXiii{} 语法环境,并设置 |@| 的 \tn{catcode} 为 $11$。 +% \begin{macrocode} +\cs_new_protected:Npn \ctex_file_wrapper:nnn #1#2#3 + { + \use:x + { + \ExplSyntaxOff + \char_set_catcode_letter:n { 64 } + #1 + \exp_not:n {#2} + \bool_if:NTF \l__kernel_expl_bool + { \ExplSyntaxOn } + { \ExplSyntaxOff } + \char_set_catcode:nn { 64 } { \char_value_catcode:n { 64 } } + #3 + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_file_input:n} +% 输入文件。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_file_input:n #1 + { \ctex_file_wrapper:nnn { } { \file_input:n {#1} } { } } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_scheme_input:n} +% 输入 \opt{scheme} 文件。先查找当前文档类下的 \meta{scheme},找不到再查找一般的文件。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_scheme_input:n #1 + { + \ctex_file_wrapper:nnn + { } + { + \tl_if_exist:NTF \c_@@_class_tl + { + \file_if_exist_input:nF { ctex-scheme- #1 - \c_@@_class_tl .def } + { \file_input:n { ctex-scheme- #1 .def } } + } + { \file_input:n { ctex-scheme- #1 .def } } + } + { } + } +\cs_generate_variant:Nn \ctex_scheme_input:n { o } +% \end{macrocode} +% \end{macro} +% +% \begin{variable}{\g_@@_section_depth_int} +% 若大于 |3|,则 \tn{paragraph} 和 \tn{subparagraph} 标题单独占一行;若为 |3|,则 +% \tn{paragraph} 单独占一行。 +% \begin{macrocode} +%<*!beamer> +\int_new:N \g_@@_section_depth_int +\int_gset:Nn \g_@@_section_depth_int { 2 } +%</!beamer> +% \end{macrocode} +% \end{variable} +% +% \begin{macrocode} +%</class|ctex|ctexheading> +%<*class|ctex> +% \end{macrocode} +% +% 对旧版本的宏包给出错误信息。 +% \begin{macrocode} +\msg_new:nnnn { ctex } { package-too-old } + { Support~package~`#1'~too~old. } + { + Please~update~an~up~to~date~version~of~the~package~`#1'\\ + using~your~TeX~package~manager~or~from~CTAN. + } +% \end{macrocode} +% +% \changes{v2.1}{2015/05/25}{不依赖 \pkg{ifpdf} 宏包。} +% +% \begin{macro}[int]{\ifctexpdf} +% 在 \pkg{zhmetrics} 映射文件中使用。 +% \begin{macrocode} +\sys_if_output_pdf:TF + { \cs_new_eq:NN \ifctexpdf \if_true: } + { \cs_new_eq:NN \ifctexpdf \if_false: } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_if_preamble:TF} +% 测试是否在 \LaTeXe{} 的导言区。在宏包内部初始为真,文档最开始位置再设置为假。 +% 注意,钩子 \cs{ctex_after_end_preamble:n} 在 \tn{AtBeginDocument} 之后执行, +% 可以与 \tn{@onlypreamble} 的行为一致。 +% \begin{macrocode} +\cs_new_eq:NN \ctex_if_preamble:TF \use_i:nn +\ctex_after_end_preamble:n { \cs_set_eq:NN \ctex_if_preamble:TF \use_ii:nn } +% \end{macrocode} +% \end{macro} +% +% \changes{v2.3}{2015/09/17}{代码实现避免使用 \tn{lowercase} 技巧(Joseph Wright)。} +% +% \changes{v2.4.16}{2019/05/11}{允许设置 \texttt{autoindent} 为 $0$。} +% +% \begin{macro}[int]{\ctex_set_default_ccwd:Nn} +% 若参数 |#2| 带长度单位,则设置它为 |tl| 变量 |#1| 的值,否则以 \tn{ccwd} 为单位。 +% \begin{macrocode} +\cs_new_protected:Npn \ctex_set_default_ccwd:Nn #1#2 + { \tl_set:Nx #1 { \@@_default_ccwd_aux:n {#2} } } +\cs_new:Npn \@@_default_ccwd_aux:n #1 + { + \exp_not:n {#1} + \exp_after:wN \@@_default_ccwd_aux:w + \dim_use:N \tex_dimexpr:D #1 pt \scan_stop: \q_stop + } +\exp_last_unbraced:NNNNo + \cs_new:Npn \@@_default_ccwd_aux:w #1 { \tl_to_str:n { pt } } #2 \q_stop + { \tl_if_empty:nT {#2} { \ccwd } } +% \end{macrocode} +% \end{macro} +% +% \begin{variable}{\l_@@_encoding_tl} +% (pdf)\LaTeX{} 初始化编码为 GBK,其它则是 UTF8。 +% \begin{macrocode} +\tl_new:N \l_@@_encoding_tl +\tl_set:Nx \l_@@_encoding_tl + { \sys_if_engine_pdftex:TF { GBK } { UTF8 } } +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\g_@@_zhmCJK_bool} +% 是否使用 \pkg{zhmCJK} 宏包。 +% \begin{macrocode} +\bool_new:N \g_@@_zhmCJK_bool +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_autoindent_tl} +% 保存 \opt{autoindent} 选项的值,空值表示不自动调整首行缩进。 +% \begin{macrocode} +\tl_new:N \l_@@_autoindent_tl +% \end{macrocode} +% \end{variable} +% +% \begin{macro}[int]{\ctex_if_autoindent_touched:F} +% 检查 \opt{autoindent} 选项是否被用户设置。 +% \begin{macrocode} +\cs_new_eq:NN \ctex_if_autoindent_touched:F \use:n +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_zhmap_case:nnn} +% 参数 |#1| 是 \pkg{zhmCJK} 的内容,|#2| 是 \pkg{zhmetrics}。 +% \begin{macrocode} +\cs_new_eq:NN \ctex_zhmap_case:nnn \use_ii:nnn +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_at_end:n} +% 区分 \tn{AtEndOfClass} 和 \tn{AtEndOfPackage},虽然它们的意思都是一样的。 +% \begin{macrocode} +%<class>\cs_new_protected_nopar:Npn \ctex_at_end:n { \AtEndOfClass } +%<ctex>\cs_new_protected_nopar:Npn \ctex_at_end:n { \AtEndOfPackage } +% \end{macrocode} +% \end{macro} +% +% \begin{variable}{\g_@@_std_options_clist} +% 保存传递给标准文档类的选项。 +% \begin{macrocode} +%<*class> +\clist_new:N \g_@@_std_options_clist +%</class> +% \end{macrocode} +% \end{variable} +% +% 对无效选项给出警告。 +% \begin{macrocode} +\msg_new:nnn { ctex } { invalid-option } + { Option~`\l_keys_key_tl'~is~invalid~in~current~mode. } +\msg_new:nnn { ctex } { invalid-value } + { Value~`#1'~is~invalid~for~the~key~`\l_keys_key_tl'. } +% \end{macrocode} +% +% 对过时选项或命令给出警告。 +% \begin{macrocode} +\msg_new:nnn { ctex } { deprecated-option } + { Option~ `\l_keys_key_tl'~ is~ deprecated.\\ #1 } +\msg_new:nnn { ctex } { deprecated-command } + { Command~ #1 is~ deprecated.\\ #2 } +\msg_new:nnn { ctex } { deprecated-environment } + { Environment~ `#1'~ is~ deprecated.\\ #2 } +% \end{macrocode} +% +% \begin{macrocode} +%</class|ctex> +% \end{macrocode} +% +% \begin{variable}{\g_@@_font_size_int} +% |0| 表示修改默认字体大小为五号,|1| 为小四号,大于 1 则不作修改。初始值 |-1| +% 表示 \opt{zihao} 选项未初始化,会在将来根据文档类决定初值。 +% \begin{macrocode} +%<*class|ctex|ctexsize> +\int_new:N \g_@@_font_size_int +\int_set:Nn \g_@@_font_size_int { -1 } +%</class|ctex|ctexsize> +% \end{macrocode} +% \end{variable} +% +% \subsection{宏包选项} +% +% \changes{v2.3}{2015/09/25} +% {\texttt{.value_required:} 和 \texttt{.value_forbidden:} 已过时。} +% +% \begin{macrocode} +%<*class|style> +\keys_define:nn { ctex / option } + { +%</class|style> +% \end{macrocode} +% +% \changes{v2.0}{2015/05/06}{新增 \opt{zihao} 选项。} +% \changes{v2.0}{2015/05/06}{\opt{c5size}, \opt{cs4size} 是过时选项。} +% +% \begin{macro}{zihao} +% \changes{v2.4.1}{2016/05/13}{不允许无参 \opt{zihao} 选项。} +% \begin{macrocode} +%<*class|ctex|ctexsize> + zihao .choice: , + zihao .value_required:n = true , + zihao / 5 .code:n = { \int_gset:Nn \g_@@_font_size_int { 0 } } , + zihao / -4 .code:n = { \int_gset:Nn \g_@@_font_size_int { 1 } } , + zihao / false .code:n = { \int_gset:Nn \g_@@_font_size_int { 2 } } , +%<ctexsize> } +%</class|ctex|ctexsize> +%<*class|ctex> + c5size .code:n = + { + \msg_warning:nnn { ctex } { deprecated-option } + { Option~ `zihao=5'~ is~ set. } + \keys_set:nn { ctex / option } { zihao = 5 } + } , + cs4size .code:n = + { + \msg_warning:nnn { ctex } { deprecated-option } + { Option~ `zihao=-4'~ is~ set. } + \keys_set:nn { ctex / option } { zihao = -4 } + } , + c5size .value_forbidden:n = true , + cs4size .value_forbidden:n = true , +% \end{macrocode} +% \end{macro} +% +% \changes{v2.0}{2014/04/23}{新增 \opt{linespread} 选项。} +% +% \begin{macro}{linespread} +% 行距初始值为标志 \texttt{nan},用于检查用户是否设置了 \opt{linespread} 选项。 +% \begin{macrocode} + linespread .fp_set:N = \l_@@_line_spread_fp , + linespread .initial:n = { \c_nan_fp } , + linespread .value_required:n = true , +% \end{macrocode} +% \end{macro} +% +% \changes{v2.0}{2014/03/13}{新增 \opt{autoindent} 选项。} +% +% \begin{macro}{autoindent} +% 自动调整段落的首行缩进功能。 +% \begin{macrocode} + autoindent .choice: , + autoindent .default:n = { true } , + autoindent / true .code:n = + { + \tl_set:Nn \l_@@_autoindent_tl { 2 \ccwd } + \cs_set_eq:NN \ctex_if_autoindent_touched:F \use_none:n + } , + autoindent / false .code:n = + { + \tl_clear:N \l_@@_autoindent_tl + \cs_set_eq:NN \ctex_if_autoindent_touched:F \use_none:n + } , + autoindent / unknown .code:n = + { + \ctex_set_default_ccwd:Nn \l_@@_autoindent_tl {#1} + \cs_set_eq:NN \ctex_if_autoindent_touched:F \use_none:n + } , +% \end{macrocode} +% \end{macro} +% +% \changes{v2.0}{2015/03/21}{\opt{indent}, \opt{noindent} 是过时选项。} +% \begin{macro}{indent} +% 仅为兼容性保留,已过时。 +% \begin{macrocode} + indent .code:n = + { + \msg_warning:nnn { ctex } { deprecated-option } + { + The~ functionality~ has~ been~ removed.\\ + It's~ better~ to~ set~ the~ heading~ styles~ via~ `afterindent'~ + options.~ + } + } , + indent .value_forbidden:n = true , + noindent .code:n = + { + \msg_warning:nnn { ctex } { deprecated-option } + { + The~ functionality~ has~ been~ removed.\\ + It's~ better~ to~ set~ the~ heading~ styles~ via~ `afterindent'~ + options. + } + } , + noindent .value_forbidden:n = true , +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{GBK,UTF8} +% \begin{macrocode} + GBK .code:n = { \tl_set:Nn \l_@@_encoding_tl { GBK } } , + UTF8 .code:n = { \tl_set:Nn \l_@@_encoding_tl { UTF8 } } , + GBK .value_forbidden:n = true , + UTF8 .value_forbidden:n = true , +% \end{macrocode} +% \end{macro} +% +% \changes{v2.0}{2014/03/08}{新增 \opt{fontset} 选项。} +% \changes{v2.0}{2015/03/21}{\opt{nofonts}, \opt{adobefonts}, \opt{winfonts} +% 是过时选项。} +% +% \begin{macro}{fontset} +% 初始值为空。若用户未指定,则根据操作系统载入对应字体配置,可以区分 Windows、 +% Mac~OS~X 和其它。 +% \begin{macrocode} + fontset .tl_gset:N = \g_@@_fontset_tl , + nofonts .code:n = + { + \msg_warning:nnn { ctex } { deprecated-option } + { + Option~ `fontset=none'~ is~ set.~ It~ is~ better~ to~ use~ + fontset~ option. + } + \keys_set:nn { ctex / option } { fontset = none } + } , + adobefonts .code:n = + { + \msg_warning:nnn { ctex } { deprecated-option } + { + Option~ `fontset=adobe'~ is~ set.~ It~ is~ better~ to~ use~ + fontset~ option. + } + \keys_set:nn { ctex / option } { fontset = adobe } + } , + winfonts .code:n = + { + \msg_warning:nnn { ctex } { deprecated-option } + { + Option~ `fontset=windows'~ is~ set.~ It~ is~ better~ to~ use~ + fontset~ option. + } + \keys_set:nn { ctex / option } { fontset = windows } + } , + nofonts .value_forbidden:n = true , + winfonts .value_forbidden:n = true , + adobefonts .value_forbidden:n = true , +% \end{macrocode} +% \end{macro} +% +% \changes{v2.0}{2014/03/08}{新增 \opt{zhmCJK} 支持选项。} +% \changes{v2.0}{2015/03/22}{\opt{nozhmap} 是过时选项。} +% +% \begin{macro}{zhmap} +% \begin{macrocode} + zhmap .choice: , + zhmap .default:n = { true } , + zhmap / zhmCJK .code:n = + { + \bool_gset_true:N \g_@@_zhmCJK_bool + \cs_gset_eq:NN \ctex_zhmap_case:nnn \use_i:nnn + } , + zhmap / true .code:n = + { + \bool_gset_false:N \g_@@_zhmCJK_bool + \cs_gset_eq:NN \ctex_zhmap_case:nnn \use_ii:nnn + } , + zhmap / false .code:n = + { + \bool_gset_false:N \g_@@_zhmCJK_bool + \cs_gset_eq:NN \ctex_zhmap_case:nnn \use_iii:nnn + } , + nozhmap .code:n = + { + \msg_warning:nnn { ctex } { deprecated-option } + { Option~ `zhmap=false'~ is~ set. } + \keys_set:nn { ctex / option } { zhmap = false } + } , + nozhmap .value_forbidden:n = true , +% \end{macrocode} +% \end{macro} +% +% \changes{v2.0}{2014/04/11}{\opt{punct} 选项可以设置标点格式。} +% \changes{v2.0}{2015/03/21}{\opt{nopunct} 是过时选项。} +% +% \begin{macro}{punct} +% 设置标点符号输出格式。 +% \begin{macrocode} + punct .tl_set:N = \l_@@_punct_tl , + punct .default:n = { quanjiao } , + punct .initial:n = { quanjiao } , + nopunct .code:n = + { + \msg_warning:nnn { ctex } { deprecated-option } + { Option~ `punct=plain'~ is~ set. } + \keys_set:nn { ctex / option } { punct = plain } + } , + nopunct .value_forbidden:n = true , +% \end{macrocode} +% \end{macro} +% +% \changes{v2.0}{2015/03/22}{\opt{nospace} 是过时选项。} +% \begin{macro}{space} +% \begin{macrocode} + space .choices:nn = + { true , auto , false } + { + \exp_args:Nx \ctex_at_end:n + { \keys_set:nn { ctex } { space = \l_keys_choice_tl } } + } , + space .default:n = { true } , + nospace .code:n = + { + \msg_warning:nnn { ctex } { deprecated-option } + { Option~ `space=false'~ is~ set. } + \keys_set:nn { ctex / option } { space = false } + } , + nospace .value_forbidden:n = true , +% \end{macrocode} +% \end{macro} +% +% \changes{v2.0}{2014/03/08}{\pkg{ctex} 宏包新增 \opt{heading} 选项。} +% +% \begin{macro}{heading} +% \begin{macrocode} + heading .bool_set:N = \l_@@_heading_bool , +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%</class|ctex> +%<*class|ctex|ctexheading> +% \end{macrocode} +% +% \begin{macro}{sub3section,sub4section} +% \begin{macrocode} +%<*!beamer> + sub3section .code:n = + { \int_gset:Nn \g_@@_section_depth_int { 3 } } , + sub4section .code:n = + { \int_gset:Nn \g_@@_section_depth_int { 4 } } , + sub3section .value_forbidden:n = true , + sub4section .value_forbidden:n = true , +%</!beamer> +% \end{macrocode} +% \end{macro} +% +% \changes{v2.0}{2015/04/15}{新增 \opt{scheme} 选项,并将 \opt{cap} 和 \opt{nocap} +% 列为过时选项。} +% \begin{macro}{scheme} +% \begin{macrocode} + scheme .tl_set:N = \l_@@_scheme_tl , +%<*ctexheading> + scheme .default:n = { plain } , + scheme .initial:n = { plain } + } +%</ctexheading> +%<*!ctexheading> + scheme .default:n = { chinese } , + scheme .initial:n = { chinese } , +%</!ctexheading> +% \end{macrocode} +% +% \begin{macrocode} +%</class|ctex|ctexheading> +%<*class|ctex> +% \end{macrocode} +% +% \begin{macrocode} + cap .code:n = + { + \msg_warning:nnn { ctex } { deprecated-option } + { Option~ `scheme = chinese' ~ is~ set. } + \keys_set:nn { ctex / option } { scheme = chinese } + } , + nocap .code:n = + { + \msg_warning:nnn { ctex } { deprecated-option } + { Option~ `scheme = plain' ~ is~ set. } + \keys_set:nn { ctex / option } { scheme = plain } + } , + cap .value_forbidden:n = true , + nocap .value_forbidden:n = true , +% \end{macrocode} +% \end{macro} +% +% \changes{v2.0}{2015/04/20}{\opt{hyperref} 成为过时选项,原选项功能总是打开。} +% \changes{v2.0}{2015/04/20}{\opt{fancyhdr} 成为过时选项,原选项功能总是打开。} +% \changes{v2.0}{2015/04/20}{\opt{fntef} 成为过时选项,原选项功能总是打开。} +% \begin{macro}{fntef,fancyhdr,hyperref} +% \changes{v2.1}{2015/06/03}{补充定义 \tn{hypersetup}。} +% 这些都是过时的宏包兼容选项,原选项功能总是打开的。 +% \begin{macrocode} + fntef .code:n = + { + \msg_warning:nnn { ctex } { deprecated-option } + { `(xe)CJKfntef'~ package~ is~ always~ loaded. } + } , + fancyhdr .code:n = + { + \msg_warning:nnn { ctex } { deprecated-option } + { `fancyhdr'~ package~ is~ loaded. } + \RequirePackage { fancyhdr } + } , + hyperref .code:n = + { + \msg_warning:nnn { ctex } { deprecated-option } + { `hyperref'~ package~ will~ be~ loaded. } + \ctex_at_end:n + { + \cs_if_exist:NF \hypersetup + { \cs_new_eq:NN \hypersetup \ctex_hypersetup:n } + } + \ctex_at_end_preamble:n { \RequirePackage { hyperref } } + } , + } +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%</class|ctex> +%<*class|ctex|ctexsize> +% \end{macrocode} +% +% \changes{v2.0}{2015/05/06}{兼容 \pkg{extsizes} 宏包、\cls{beamer}、\pkg{memoir} +% 等提供的更多字号选项。} +% \changes{v2.0.1}{2015/05/15}{修复 \opt{10pt}、\opt{11pt} 等选项无效的问题。} +% \begin{macro}{10pt,11pt,12pt} +% 使 \pkg{ctex} 和 \pkg{ctexsize} 可以接受文档类的全局选项,不修改默认字体大小。 +% 在文档类下还将参数传给标准文档类。 +% \begin{macrocode} +\tl_clear_new:N \l_@@_tmp_tl +\clist_map_inline:nn + { + 10pt , 11pt , 12pt , + 8pt , 9pt , 14pt , 17pt , 20pt , 25pt , 30pt , 36pt , 48pt , 60pt + } + { + \tl_put_right:Nn \l_@@_tmp_tl + { + #1 .code:n = +%<*!class> + { \int_gset:Nn \g_@@_font_size_int { 2 } } , +%</!class> +%<*class> + { + \int_gset:Nn \g_@@_font_size_int { 2 } + \clist_gput_right:Nn \g_@@_std_options_clist {#1} + } , +%</class> + #1 .value_forbidden:n = true , + } + } +\use:x { \keys_define:nn { ctex / option } { \exp_not:o { \l_@@_tmp_tl } } } +\tl_clear:N \l_@@_tmp_tl +% \end{macrocode} +% \end{macro} +% +% 将未知选项传给标准文档类。 +% \begin{macrocode} +%<*class> +\keys_define:nn { ctex / option } + { + unknown .code:n = + { \clist_gput_right:No \g_@@_std_options_clist { \CurrentOption } } + } +%</class> +% \end{macrocode} +% +% \begin{macrocode} +%<!ctexsize>\ctex_file_input:n { ctexopts.cfg } +%</class|ctex|ctexsize> +% \end{macrocode} +% +% \begin{macrocode} +%<*class|style> +\ProcessKeysOptions { ctex / option } +%</class|style> +% \end{macrocode} +% +% \begin{macrocode} +%<*class> +% \end{macrocode} +% +% 五号字使用标准文档类的 |10pt| 字体大小设置,小四号字则使用 |12pt|。 +% \begin{macrocode} +\if_case:w \g_@@_font_size_int + \clist_gput_right:Nn \g_@@_std_options_clist { 10pt } +\or: + \clist_gput_right:Nn \g_@@_std_options_clist { 12pt } +\fi: +% \end{macrocode} +% +% 使用 \tn{PassOptionsToClass} 是为了预防可能存在的选项冲突。 +% \begin{macrocode} +%<*article> +\tl_const:Nn \c_@@_class_tl { article } +\PassOptionsToClass { \g_@@_std_options_clist } { article } +\LoadClass { article } +%</article> +%<*book> +\tl_const:Nn \c_@@_class_tl { book } +\PassOptionsToClass { \g_@@_std_options_clist } { book } +\LoadClass { book } +%</book> +%<*report> +\tl_const:Nn \c_@@_class_tl { report } +\PassOptionsToClass { \g_@@_std_options_clist } { report } +\LoadClass { report } +%</report> +%<*beamer> +\tl_const:Nn \c_@@_class_tl { beamer } +\PassOptionsToClass { \g_@@_std_options_clist } { beamer } +\LoadClass { beamer } +%</beamer> +% \end{macrocode} +% +% \begin{macrocode} +%</class> +% \end{macrocode} +% +% \subsection{特定引擎支持与设置} +% +% \subsubsection{\pkg{ctex-engine-pdftex.def}} +% +% \begin{macro}[int]{\ctex_set_zhmap:n} +% 设置 \upTeX{} 字体映射,同时作用于 \tn{AtBeginDvi} 与 +% \tn{AtBeginShipoutFirst}。该宏对 \pdfTeX{} 和 \upTeX{} 均有用。 +% \begin{macrocode} +%<*pdftex|uptex|aptex> +\cs_new_protected_nopar:Npn \ctex_set_zhmap:n #1 + { + \AtBeginDvi {#1} + \ctex_at_end_package:nn { atbegshi } + { \AtBeginShipoutFirst {#1} } + } +\@onlypreamble \ctex_set_zhmap:n +%</pdftex|uptex|aptex> +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%<*pdftex> +% \end{macrocode} +% +% \changes{v2.1}{2015/05/18}{给 \pdfLaTeX{} 下的非 UTF8 编码 CJK 字体族加上 CMap。} +% +% \begin{variable}{\c_@@_cmap_encoding_seq} +% 需要加上 CMap 的 CJK 字体编码。 +% \begin{macrocode} +\seq_const_from_clist:Nn \c_@@_cmap_encoding_seq + { C19 , C10 , C00 , C09 , C40 , C60 } +% \end{macrocode} +% \end{variable} +% +% \begin{macro}[int]{\ctex_family_cmap:nn} +% 在 \tn{DeclareFontFamily} 的 \meta{loading-settings} 中给 CJK 字体族加上 CMap。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_family_cmap:nn #1#2 + { + \cs_if_free:cF { #1 + #2 } + { + \seq_if_in:NnT \c_@@_cmap_encoding_seq {#1} + { \tl_gput_right:cn { #1 + #2 } { \ctex_add_cmap:n {#1} } } + } + } +\cs_generate_variant:Nn \ctex_family_cmap:nn { x } +\cs_new_eq:NN \CTEX@Family@CMap \ctex_family_cmap:xn +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_add_cmap:n} +% 给 |#1| 编码的 CJK 字体加上 CMap。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_add_cmap:n #1 + { + \cs_if_free:NF \CJK@plane + { \ctex_add_cmap:cn { @@_add_cmap_ #1 \CJK@plane : } {#1} } + } +\cs_new_protected_nopar:Npn \ctex_add_cmap:Nn #1#2 + { + \cs_if_exist:NF #1 { \@@_save_cmap:Nn #1 {#2} } + #1 + } +\cs_generate_variant:Nn \ctex_add_cmap:Nn { c } +\cs_new_protected_nopar:Npn \@@_save_cmap:Nn #1#2 + { + \tl_set:Nx \l_@@_tmp_tl { \str_lower_case:n {#2} \CJK@plane } + \tex_immediate:D \tex_pdfobj:D stream ~ file { \l_@@_tmp_tl .cmap } + \cs_new_protected_nopar:Npx #1 + { + \exp_not:N \tex_pdffontattr:D \exp_not:N \tex_font:D + { /ToUnicode ~ \int_use:N \tex_pdflastobj:D \c_space_tl 0 ~ R } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\DeclareFontFamily} +% 只在 \pdfLaTeX{} 下加 CMap。如 \pkg{cmap} 宏包被引入,则不重复设置。 +% \begin{macrocode} +\group_begin: +\char_set_catcode_other:N \# +\sys_if_output_pdf:TF + { + \group_end: + \ctex_appto_cmd:NnnTF \DeclareFontFamily { \ExplSyntaxOff } + { \CTEX@Family@CMap {#1} {#2} } + { + \ctex_at_end_package:nn { cmap } + { \cs_gset_eq:NN \CTEX@Family@CMap \use_none:nn } + } + { \ctex_patch_failure:N \DeclareFontFamily } + } + { \group_end: } +% \end{macrocode} +% \end{macro} +% +% 首先检查选项,决定是否载入 \pkg{zhmCJK} 宏包。 +% \begin{macrocode} +\if_bool:N \g_@@_zhmCJK_bool + \PassOptionsToPackage { encoding = \l_@@_encoding_tl } { zhmCJK } + \RequirePackage { zhmCJK } +% \end{macrocode} +% 不载入 \pkg{zhmCJK} 宏包时直接调用 \pkg{CJK} 及相关宏包。 +% \begin{macrocode} +\else: + \str_if_eq:onTF { \l_@@_encoding_tl } { GBK } + { \RequirePackage { CJK } } + { \RequirePackage { CJKutf8 } } + \RequirePackage { CJKpunct , CJKspace } +% \end{macrocode} +% +% \begin{macro}[int]{\ctex_load_zhmap:nnnn} +% 载入 \pkg{zhmetrics} 的字体映射文件,同时设置 \tn{CJKrmdefault} 等。 +% \begin{macrocode} + \cs_new_protected_nopar:Npn \ctex_load_zhmap:nnnn #1#2#3#4 + { + \tl_set:Nn \CJKrmdefault {#1} + \tl_set:Nn \CJKsfdefault {#2} + \tl_set:Nn \CJKttdefault {#3} + \ctex_set_zhmap:n { \ctex_zhmap_input:n {#4} } + } + \@onlypreamble \ctex_load_zhmap:nnnn +% \end{macrocode} +% \end{macro} +% +% \changes{v2.4.4}{2016/09/09}{解决 \opt{zhmap} 文件的 \tn{catcode} 问题。} +% \begin{macro}[int]{\ctex_zhmap_input:n} +% 载入字体映射文件时,确认 |%| 和 |\| 的 \tn{catcode}。 +% \begin{macrocode} + \cs_new_protected_nopar:Npn \ctex_zhmap_input:n #1 + { + \ctex_file_wrapper:nnn + { + \char_set_catcode_comment:n { 37 } % % + \char_set_catcode_escape:n { 92 } % \ + } + { \file_input:n {#1} } + { + \char_set_catcode:nn { 37 } { \char_value_catcode:n { 37 } } + \char_set_catcode:nn { 92 } { \char_value_catcode:n { 92 } } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} + \tl_if_exist:NF \CJKfamilydefault + { \tl_const:Nn \CJKfamilydefault { \CJKrmdefault } } + \tl_if_exist:NF \CJKrmdefault { \tl_new:N \CJKrmdefault } + \tl_if_exist:NF \CJKsfdefault { \tl_new:N \CJKsfdefault } + \tl_if_exist:NF \CJKttdefault { \tl_new:N \CJKttdefault } + \ctex_preto_cmd:NnnTF \rmfamily { \ExplSyntaxOff } + { \CJKfamily { \CJKrmdefault } } + { } + { \ctex_patch_failure:N \rmfamily } + \ctex_preto_cmd:NnnTF \sffamily { \ExplSyntaxOff } + { \CJKfamily { \CJKsfdefault } } + { } + { \ctex_patch_failure:N \sffamily } + \ctex_preto_cmd:NnnTF \ttfamily { \ExplSyntaxOff } + { \CJKfamily { \CJKttdefault } } + { } + { \ctex_patch_failure:N \ttfamily } + \ctex_preto_cmd:NnnTF \normalfont { \ExplSyntaxOff } + { \CJKfamily { \CJKfamilydefault } } + { \cs_set_eq:NN \reset@font \normalfont } + { \ctex_patch_failure:N \normalfont } +% \end{macrocode} +% +% \pkg{zhmCJK} 判断结束。 +% \begin{macrocode} +\fi: +% \end{macrocode} +% +% \begin{macro}[int]{\ctex_CJK_input:n,\CJK@input} +% \pkg{breqn} 包可能会在正文中将 |^| 的 \tn{catcode} 改为 $12$ 或 $13$,这将 +% 破坏 \pkg{CJK} 对汉字的首字节的定义(\tn{CJK@loadBinding} 和 +% \tn{CJK@loadEncoding})。因此需要确保载入 \file{.enc} 和 \file{.bdg} 文件时, +% |^| 的 \tn{catcode} 为 $7$。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_CJK_input:n #1 + { + \ctex_file_wrapper:nnn + { + \char_set_catcode_other:n { 60 } % < + \char_set_catcode_math_superscript:n { 94 } % ^ + \int_set:Nn \tex_endlinechar:D { -1 } + } + { \file_input:n {#1} } + { + \char_set_catcode:nn { 60 } { \char_value_catcode:n { 60 } } + \char_set_catcode:nn { 94 } { \char_value_catcode:n { 94 } } + \int_set:Nn \tex_endlinechar:D { \int_use:N \tex_endlinechar:D } + } + } +\cs_set_eq:NN \CJK@input \ctex_CJK_input:n +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_plane_to_utfxvibe:Nn,\CJK@surr} +% \changes{v2.0}{2014/04/08}{解决与 \tn{nouppercase} 的冲突。} +% \pkg{fancyhdr} 宏包的 \tn{nouppercase} 会将 \tn{uppercase} 定义为 \tn{relax},而 +% \tn{CJK@surr} 需要用它将 \tn{CJK@plane} 转化成大写字母,这就造成了冲突^^A +% \footnote{\url{https://github.com/CTeX-org/ctex-kit/issues/146}}。 +% 我们在这里给出 \tn{CJK@surr} 的一个不依赖 \tn{uppercase} 的实现。 +% \begin{macrocode} +\if_cs_exist:N \CJK@surr + \cs_new_protected_nopar:Npn \ctex_plane_to_utfxvibe:Nn #1#2 + { + \tl_set:Nx \l_@@_tmp_tl {#2} + \int_set:Nn \l_@@_tmp_int + { \exp_args:No \int_from_hex:n { \l_@@_tmp_tl } } + \int_compare:nNnTF \l_@@_tmp_int < { 256 } + { \tl_gset:Nx #1 { \int_to_Hex:n { \l_@@_tmp_int } } } + { + \int_sub:Nn \l_@@_tmp_int { 256 } + \tl_gset:Nx #1 + { + \int_to_Hex:n + { \int_div_truncate:nn { \l_@@_tmp_int } { 4 } + "D800 } + \int_to_Hex:n + { \int_mod:nn { \l_@@_tmp_int } { 4 } + "DC } + } + } + } + \cs_set_eq:NN \CJK@surr \ctex_plane_to_utfxvibe:Nn +\fi: +% \end{macrocode} +% \end{macro} +% +% \pkg{CJKpunct} 宏包会在 \tn{AtBeginDocument} 的里设置标点格式为 \opt{quanjiao}。 +% \begin{macrocode} +\AtBeginDocument + { + \str_if_eq:eeF { \l_@@_punct_tl } { quanjiao } + { \punctstyle { \l_@@_punct_tl } } + } +% \end{macrocode} +% +% 在导言区末尾更新 \tn{CJKfamilydefault},注意要在 \tn{CJK@envStart} 之前使用。 +% \begin{macrocode} +\ctex_at_end_preamble:n { \ctex_update_default_family: } +% \end{macrocode} +% +% 启用中文字符功能。\texttt{GBK} 编码时,将汉字的首字节设置为活动字符,并对这些 +% 字符初始化;\texttt{UTF8} 编码时,上游宏包已经处理好。 +% \tn{CJK@makeActive} 应该先于 \file{ctex-name-gbk.cfg} 等文件的载入。 +% 注意 \tn{CJK@loadBinding} 需要调用补丁后的 \tn{CJK@input}。使用 +% \pkg{zhmCJK} 时,此功能已经被启用。 +% \begin{macrocode} +\reverse_if:N \if_bool:N \g_@@_zhmCJK_bool + \str_if_eq:onF { \l_@@_encoding_tl } { UTF8 } + { + \CJK@makeActive + \CJK@loadBinding { standard } + } +% \end{macrocode} +% +% 在导言区结束时调用 \tn{CJK@envStart} 启用完整的中文功能。 +% +% \tn{CJK@envStart} 的定义是 +% \begin{verbatim} +% \def\CJK@envStart#1#2#3{ +% \CJK@upperReset +% \ifCJK@lowercase@ +% \CJK@lowerReset +% \fi% +% \CJK@makeActive% +% \CJK@global\let\CJK@selectFamily \CJK@selFam +% \CJK@global\let\CJK@selectEnc \CJK@selEnc% +% \def\CJK@@@enc{#2} +% \ifx\CJK@@@enc \@empty +% \PackageInfo{CJK}{ +% no encoding parameter given,\MessageBreak +% waiting for \protect\CJKenc\space commands} +% \else +% \CJKenc{#2} +% \fi +% \CJKfontenc{#2}{#1} +% \CJKfamily{#3} +% \def\CJK@series{\f@series} +% \def\CJK@shape{\f@shape}% +% \csname CJKhook\endcsname} +% \end{verbatim} +% \tn{CJK@upperReset} 可能会有一定风险,因此我们直到导言区末尾才使用 +% \tn{CJK@envStart}。这样可以避免将 \env{CJK} 环境内置入 \env{document} 环境的 +% 最里层,最后也就不需要 \tn{clearpage}。\pkg{zhmCJK} 已经提供类似功能。 +% 注意先使用 \cs{ctex_update_default_family:} 更新 \tn{CJKfamilydefault}。 +% \begin{macrocode} + \exp_args:Nx \ctex_at_end_preamble:n + { + \exp_not:N \CJK@envStart + { } { \l_@@_encoding_tl } { \exp_not:N \CJKfamilydefault } + \exp_not:N \CJKtilde + } +% \end{macrocode} +% +% \pkg{zhmCJK} 判断结束。 +% \begin{macrocode} +\fi: +% \end{macrocode} +% +% \begin{macro}[int]{\ctex_auto_ignorespaces:} +% 关闭名字空间,保存 \tn{CJK@@ignorespaces} 的定义,方便使用。 +% \begin{macrocode} +%<@@=> +\cs_new_eq:NN \ctex_auto_ignorespaces: \CJK@@ignorespaces +% \end{macrocode} +% 恢复名字空间,要把它放在一个 \env{macrocode} 环境中,\cls{l3doc} 才能正确工作。 +% \begin{macrocode} +%<@@=ctex> +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_ignorespaces_case:N,\ctex_set_ignorespaces:} +% 设置忽略空格的的方式。根据 \opt{space} 选项的值重定义 \tn{CJK@ignorespaces}, +% 并保存起来供 \tn{CJKhook} 备用。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_ignorespaces_case:N #1 + { + \cs_set_protected_nopar:Npn \ctex_set_ignorespaces: + { \cs_set_eq:NN \CJK@ignorespaces #1 } + \ctex_set_ignorespaces: + } +\cs_new_protected_nopar:Npn \ctex_set_ignorespaces: + { \cs_set_eq:NN \CJK@ignorespaces \ctex_auto_ignorespaces: } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\CJKhook} +% \env{CJK} 和 \env{CJK*} 环境都会重新定义 \tn{CJK@ignorespaces}。我们在 \pkg{CJK} +% 宏包提供的 \tn{CJKhook} 里重新设置它,让这两个环境忽略空格的方式都受 \opt{space} +% 选项的控制。这对 \pkg{zhmCJK} 是必要的。 +% \begin{macrocode} +\ctex_gadd_hook:Nn \CJKhook { \ctex_set_ignorespaces: } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_punct_set:n} +% 设置 CJK 族对应到实际的字体。|#1| 是 \opt{fontset} 的名字。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_punct_set:n #1 + { + \clist_map_inline:Nn \c_@@_punct_family_clist + { + \cs_if_free:cF { c_@@_ #1 ##1 _punct_spaces_tl } + { + \cs_set_eq:cc + { CJKpunct@ ##1 @spaces } + { c_@@_ #1 ##1 _punct_spaces_tl } + } + } + } +\clist_const:Nn \c_@@_punct_family_clist + { + zhsong , zhhei , zhfs , zhkai , zhli , zhyou , + zhsongb , zhheil , zhheib , zhyoub , zhyahei , zhyaheib + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_punct_map_family:nn} +% CJK 族 |#1| 使用族 |#2| 的边界信息。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_punct_map_family:nn #1#2 + { + \cs_if_free:cF { CJKpunct@ #2 @spaces } + { \cs_set_eq:cc { CJKpunct@ #1 @spaces } { CJKpunct@ #2 @spaces } } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_punct_map_bfseries:nn} +% CJK 族 |#1| 的 \tn{bfseries} 使用族 |#2| 的边界信息。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_punct_map_bfseries:nn #1#2 + { + \clist_map_inline:nn {#1} + { + \ctex_punct_map_series:nnn { ##1 } { b } {#2} + \ctex_punct_map_series:nnn { ##1 } { bx } {#2} + } + } +\cs_new_protected_nopar:Npn \ctex_punct_map_series:nnn #1#2#3 + { + \CJKpunctmapfamily { C19 } {#1} {#2} { m } {#3} + \CJKpunctmapfamily { C19 } {#1} {#2} { it } {#3} + \CJKpunctmapfamily { C19 } {#1} {#2} { sl } {#3} + \CJKpunctmapfamily { C70 } {#1} {#2} { m } {#3} + \CJKpunctmapfamily { C70 } {#1} {#2} { it } {#3} + \CJKpunctmapfamily { C70 } {#1} {#2} { sl } {#3} + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_punct_map_itshape:nn} +% CJK 族 |#1| 的 \tn{itshape} 使用族 |#2| 的边界信息。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_punct_map_itshape:nn #1#2 + { + \CJKpunctmapfamily { C19 } {#1} { m } { it } {#2} + \CJKpunctmapfamily { C19 } {#1} { b } { it } {#2} + \CJKpunctmapfamily { C19 } {#1} { bx } { it } {#2} + \CJKpunctmapfamily { C70 } {#1} { m } { it } {#2} + \CJKpunctmapfamily { C70 } {#1} { b } { it } {#2} + \CJKpunctmapfamily { C70 } {#1} { bx } { it } {#2} + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_punct_space:nn,\ctexspadef} +% 定义标点的边界信息。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_punct_space:nn #1#2 + { \tl_const:cn { c_@@_ #1 _punct_spaces_tl } {#2} } +\cs_new_eq:NN \ctexspadef \ctex_punct_space:nn +% \end{macrocode} +% \end{macro} +% +% 载入边界信息文件。 +% \begin{macrocode} +\ctex_file_input:n { ctexspa.def } +% \end{macrocode} +% +% \begin{macrocode} +%</pdftex> +% \end{macrocode} +% +% \subsubsection{\pkg{ctex-engine-xetex.def}} +% +% \begin{macrocode} +%<*xetex> +% \end{macrocode} +% +% \changes{v2.4.4}{2016/09/12}{不再默认设置 \pkg{xeCJK} 的伪粗体。} +% \begin{macrocode} +\RequirePackage { xeCJK } +\exp_args:Nx \xeCJKsetup + { + LoadFandol = false , + PunctStyle = \l_@@_punct_tl + } +% \end{macrocode} +% +% 最新版本的 \pkg{fontspec} 默认对 \tn{rmfamily} 和 \tn{sffamily} 设置 +% |Ligatures=TeX|,对 \tn{ttfamily} 设置 |WordSpace={1,0,0}| 和 +% |PunctuationSpace=WordSpace|。 +% \begin{macrocode} +\@ifpackagelater { fontspec } { 2014/05/25 } { } + { \msg_error:nnn { ctex } { package-too-old } { fontspec } } +% \end{macrocode} +% +% \begin{macrocode} +%</xetex> +% \end{macrocode} +% +% \subsubsection{\pkg{ctex-engine-luatex.def}} +% +% \begin{macrocode} +%<*luatex> +% \end{macrocode} +% +% \changes{v2.0}{2014/03/08}{通过 \pkg{LuaTeX-ja} 宏包支持 \LuaLaTeX。} +% \changes{v2.3}{2015/09/25}{更新 \pkg{LuaTeX-ja} 支持(20150922.0)。} +% +% \pkg{LuaTeX-ja} 为了兼容 p\LaTeX 的使用习惯,对 \LaTeXe 的 \pkg{NFSS} 作了不少 +% 修改和扩充,这对于简体中文用户来说不是必要的。我们在这里禁用它。 +% \begin{macrocode} +\msg_new:nnn { ctex } { luatexja-loaded } + { + Package~`luatexja'~can~not~be~loaded~before~`ctex'.\\ + Loading~file~`#1'~will~abort! + } +\@ifpackageloaded { luatexja } + { \msg_critical:nnx { ctex } { luatexja-loaded } { \g_file_curr_name_str } } + { \tl_const:cn { ver@ltj-latex.\@pkgextension } { 9999/99/99 } } +% \end{macrocode} +% +% \begin{macrocode} +\RequirePackage { luatexja } +\@ifpackagelater { luatexja } { 2015/09/21 } { } + { \msg_error:nnn { ctex } { package-too-old } { luatexja } } +% \end{macrocode} +% +% \begin{macrocode} +\RequirePackage { fontspec } +\@ifpackagelater { fontspec } { 2014/05/25 } { } + { \msg_error:nnn { ctex } { package-too-old } { fontspec } } +% \end{macrocode} +% +% \paragraph{\pkg{LuaTeX-ja} 的默认设置} +% +% \begin{macrocode} +\ExplSyntaxOff +% \end{macrocode} +% +% 以下设置抄录自 \file{lltjdefs.sty},略有改动。 +% +% \changes{v2.4.11}{2017/08/17}{不把 Enclosed Alphanumerics 设置为 JAchar。} +% U+2460--U+24FF (Enclosed Alphanumerics) 原属于字符范围 6,是 JAchar, +% 我们把它们归入字符范围 3,改成 ALchar。 +% \begin{macrocode} +\ltjdefcharrange{1}{"80-"36F, "1E00-"1EFF} +\ltjdefcharrange{2}{"370-"4FF, "1F00-"1FFF} +\ltjdefcharrange{3}{% + "2000-"206F, "2070-"243F, "2460-"24FF, "2500-"27BF, "2900-"29FF, + "2B00-"2BFF} +\ltjdefcharrange{4}{% + "500-"10FF, "1200-"1DFF, "2440-"245F, "27C0-"28FF, "2A00-"2AFF, + "2C00-"2E7F, "4DC0-"4DFF, "A4D0-"A82F, "A840-"ABFF, "FB00-"FE0F, + "FE20-"FE2F, "FE70-"FEFF, "10000-"1FFFF, "E000-"F8FF} % non-Japanese +\ltjdefcharrange{5}{"D800-"DFFF, "E0000-"E00FF, "E01F0-"10FFFF} +\ltjdefcharrange{6}{% + "2E80-"2EFF, "3000-"30FF, "3190-"319F, "31F0-"4DBF, + "4E00-"9FFF, "F900-"FAFF, "FE10-"FE6F, "20000-"2FFFF, "E0100-"E01EF} +\ltjdefcharrange{7}{% + "1100-"11FF, "2F00-"2FFF, "3100-"31EF, "A000-"A4CF, + "A830-"A83F, "AC00-"D7FF} +\ltjdefcharrange{8}{"A7, "A8, "B0, "B1, "B4, "B6, "D7, "F7} +% \end{macrocode} +% 将引号、破折号等中西文公用的标点符号归入字符范围 9,将他们设置为 JAchar。 +% \begin{macrocode} +\ltjdefcharrange{9}{% + "2018, "2019, "201C, "201D, "2013, "2014, "2025, "2026, "2027, "2E3A} +% \end{macrocode} +% \changes{v2.4.11}{2017/08/17}{不把希腊和西里尔字母设置为 JAchar。} +% \pkg{LuaTeX-ja} 默认把字符范围 2 和 3 设置为 JAchar,我们这里把它们都改成 ALchar。 +% \begin{macrocode} +\ltjsetparameter{jacharrange={-1, -2, -3, -4, -5, +6, +7, -8, +9}} +\directlua{for x=128,255 do luatexja.math.is_math_letters[x] = true end} +% \end{macrocode} +% +% 以下设置抄录自 \file{ltj-latex.sty}。 +% \begin{macrocode} +\directlua{ + local s = kpse.find_file('ltj-kinsoku.lua', 'tex') + luatexja.stack.charprop_stack_table[0] = s and dofile(s) or {} +} +\ltjsetparameter{kanjiskip=\z@ plus .4pt minus .5pt, + xkanjiskip=.25\zw plus 1pt minus 1pt, + autospacing, autoxspacing, jacharrange={-1}, + yalbaselineshift=\z@, yjabaselineshift=\z@, + jcharwidowpenalty=500, differentjfm=paverage +} +% \end{macrocode} +% +% \begin{macrocode} +\ExplSyntaxOn +% \end{macrocode} +% +% \paragraph{\pkg{LuaTeX-ja} 的补丁} +% +% \begin{macrocode} +%<@@=ctex_ltj> +% \end{macrocode} +% +% \changes{v2.3}{2015/09/26}{更新 \pkg{unicode-math} 宏包补丁。} +% +% 在 \LaTeX{} 下,\pkg{LuaTeX-ja} 对 \pkg{fontspec}、\pkg{xunicode}、\pkg{unicode-math} +% 和 \pkg{listings} 打了补丁。其中前三个是把 \tn{char} 换成 \tn{ltjalchar},确保 +% 字符是 ALchar 类。我们这里用 \pkg{xunicode-addon} 来处理 \pkg{xunicode}。 +% \begin{macrocode} +\RequirePackage { xunicode-addon } +\AtBeginUTFCommand + { + \group_begin: + \lua_now:e { tex.globaldefs = 0 } + \ltj@allalchar + } +\AtEndUTFCommand { \group_end: } +% \end{macrocode} +% +% \changes{v2.4.2}{2016/05/15}{恢复 \pkg{luatexja} 对 \tn{emshape} 和 +% \tn{eminnershape} 的重定义。} +% \changes{v2.4.3}{2016/08/26}{简化 \pkg{fontspec} 补丁。} +% \begin{macro}[int]{\fontspec_visible_space:} +% 我们不使用 \pkg{luatexja} 对 \pkg{fontspec} 的补丁,直接处理。 +% \begin{macrocode} +\cs_set_protected:Npn \fontspec_visible_space: + { + \tex_iffontchar:D \tex_font:D "2423 \exp_stop_f: + \ltjalchar "2423 \exp_stop_f: + \else: + \fontspec_visible_space_fallback: + \fi: + } +% \end{macrocode} +% \end{macro} +% +% 对 \pkg{listings} 的补丁是让代码环境支持 JAchar 类。\pkg{LuaTeX-ja} 的补丁会将 +% 代码目录标题改为日文,我们不需要。 +% \begin{macrocode} +\ctex_at_end_package:nn { listings } + { + \use:x + { + \exp_not:N \RequirePackage { lltjp-listings } + \tl_set:Nn \exp_not:N \lstlistingname + { \exp_not:o { \lstlistingname } } + \tl_set:Nn \exp_not:N \lstlistlistingname + { \exp_not:o { \lstlistlistingname } } + } + } +% \end{macrocode} +% +% \paragraph{字体切换方式} +% +% \begin{macro}[int]{\ctex_ltj_select_font:,\CJK@family} +% \tn{CJK@family} 保存的是当前 CJK 实际的字体族名,如果为空表示没有设置过字体。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_ltj_select_font: + { + \cs_if_exist_use:cF { \l_@@_current_font_tl } + { \tl_if_empty:NF \CJK@family { \@@_select_font_aux: } } + } +\tl_new:N \CJK@family +\tl_new:N \l_@@_current_font_tl +\tl_set:Nn \l_@@_current_font_tl + { \CJK@encoding / \CJK@family / \f@series / \f@shape / \f@size } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_select_font_aux:} +% 使用 \tn{pickup@font} 取得字体名称前,总需要先设置 \tn{font@name}。在这里将 +% \tn{f@family} 换成 CJK 字体族,并确保编码正确。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_select_font_aux: + { + \group_begin: + \tl_set_eq:NN \f@encoding \CJK@encoding + \tl_set_eq:NN \f@family \CJK@family + \@@_push_fontname:n { \use:c { \curr@fontshape / \f@size } } + \ctex_ltj_pickup_font: + \group_end: + \font@name + \@@_pop_fontname: +% \end{macrocode} +% 当字形未定义的时候,\textsf{NFSS} 就会启动替换机制(\tn{wrong@fontshape})。 +% 第一次启动后,\cs{l_@@_current_font_tl} 还是没有定义。为此,我们再次选择字体, +% 确保它有定义和指向正确的 \texttt{font.id}。这对 \opt{AlternateFont} 的设置 +% 特别重要。 +% \begin{macrocode} + \cs_if_exist:cF { \l_@@_current_font_tl } + { \@@_select_font_aux: } + } +\cs_new_protected_nopar:Npn \@@_push_fontname:n #1 + { + \cs_gset_eq:NN \@@_save_fontname:w \font@name + \cs_gset_nopar:Npx \font@name {#1} + } +\cs_new_protected_nopar:Npn \@@_pop_fontname: + { \cs_gset_eq:NN \font@name \@@_save_fontname:w } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_ltj_pickup_font:} +% 替换 \tn{define@newfont} 内部调用的 \tn{extract@font} 和 \tn{do@subst@correction}。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_ltj_pickup_font: + { + \exp_after:wN \cs_if_exist:NF \font@name + { + \group_begin: + \cs_set_eq:NN \extract@font \ctex_ltj_extract_font: + \cs_set_eq:NN \do@subst@correction \ctex_ltj_subst_font: + \define@newfont + \group_end: + } + } +\cs_new_eq:NN \pickup@jfont \ctex_ltj_pickup_font: +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_ltj_extract_font:} +% \pkg{LuaTeX-ja} 的 \tn{globaljfont} 在 \pkg{luatexja-core} 中定义: +% \begin{verbatim} +% %%%%%%%% \jfont\CS={...:...;jfm=metric;...}, \globaljfont +% \protected\def\jfont#1{% +% \afterassignment\ltj@@jfont +% \directlua{luatexja.jfont.jfontdefX(false, 'yoko','\luatexluaescapestring{\noexpand#1}')}} +% \protected\def\globaljfont#1{% +% \afterassignment\ltj@@jfont +% \directlua{luatexja.jfont.jfontdefX(true, 'yoko','\luatexluaescapestring{\noexpand#1}')}} +% \def\ltj@@jfont{\directlua{luatexja.jfont.jfontdefY()}} +% \end{verbatim} +% \texttt{jfontdefX} 函数的作用是把 \tn{CS} 定义为其后的字体,\texttt{jfontdefY} +% 的作用是更新 \texttt{JFM} 和记录相关字体信息。最后的工作是: +% \begin{verbatim} +% tex.sprint(cat_lp, global_flag, '\\protected\\expandafter\\def\\csname ', +% (cstemp==' ') and '\\space' or cstemp, '\\endcsname{\\ltj@cur'.. +% (jfm_dir == 'yoko' and 'j' or 't') .. 'fnt', fn, '\\relax}') +% \end{verbatim} +% \tn{CS} 的作用就是把 \tn{ltj@curjfnt} 设置为刚才定义的字体的 \texttt{font.id}。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_ltj_extract_font: + { + \get@external@font + \ctex_ltj_if_alternate_shape_exist:nT { \curr@fontshape } + { + \tl_set:Nx \external@font + { \exp_after:wN \@@_patch_external_font:w \external@font } + } + \exp_after:wN \globaljfont \font@name \external@font \scan_stop: +% \end{macrocode} +% 这里 \tn{font@name} 不会直接改变当前字体,而 \tn{DeclareFontFamily} 和 +% \tn{DeclareFontShape} 的最后一个参数通常要使用 \tn{font} 来引用当前字体。 +% 为此,我们在分组内启用之前定义的字体,以便能得到正确的 \tn{font}。对字体参数的 +% 赋值总是全局的,不会受到分组的影响。 +% \begin{macrocode} + \font@name + \lua_now:e { font.current(tex.getattribute('ltj@curjfnt')) } + \use:c { \f@encoding + \f@family } + \use:c { \curr@fontshape } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_ltj_subst_font:} +% \tn{do@subst@correction} 在设置通过 \texttt{sub} 或者 \texttt{ssub} 函数定义的 +% 字体时会用到。如果没有设置 \opt{SlantedFont},\pkg{fontspec} 会设置 +% \tn{itdefault} 作为 \tn{sldefault} 的替代字形,因而会用到这个函数。它的本来定义是: +% \begin{verbatim} +% \def\do@subst@correction{% +% \xdef\subst@correction{% +% \font@name +% \global\expandafter\font +% \csname \curr@fontshape/\f@size\endcsname +% \noexpand\fontname\font +% \relax}% +% \aftergroup\subst@correction +% } +% \end{verbatim} +% 我们在这里不需要定义新字体,而是设置对应字体的命令。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_ltj_subst_font: + { + \ctex_ltj_if_alternate_shape_exist:nF { \curr@fontshape } + { + \group_begin: + \tl_set_eq:NN \CJK@family \f@family + \cs_if_exist:cF { \l_@@_current_font_tl } + { + \cs_gset_protected_nopar:Npx \subst@correction + { + \cs_new_eq:NN + \exp_not:c { \l_@@_current_font_tl } + \font@name + } + \group_insert_after:N \group_insert_after:N + \group_insert_after:N \subst@correction + } + \group_end: + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int,TF]{\ctex_ltj_if_alternate_shape_exist:n} +% 即 \pkg{LuaTeX-ja} 中的 \tn{ltj@@does@alt@set},判断是否存在替代字体。 +% \begin{macrocode} +\prg_new_conditional:Npnn \ctex_ltj_if_alternate_shape_exist:n #1 { T , F , TF } + { + \lua_now:e { luatexja.jfont.does_alt_set ('\lua_escape:e {#1}') } + \prg_return_true: \else: \prg_return_false: \fi: + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_patch_external_font:w} +% 若对字体的定义完全相同,则它们有相同的 \texttt{font.id}。因此如果字形是由 +% \textsf{NFSS} 的替换机制定义的,它们就有相同的 \texttt{font.id}。 +% |print_aftl_address| 函数的定义是 +% \begin{verbatim} +% function print_aftl_address() +% tex.sprint(cat_lp, ';ltjaltfont' .. tostring(aftl_base):sub(8)) +% end +% \end{verbatim} +% 主要目的是,如果当前字形有替代字体,则往字形的定义中加入一些标志,确保 +% \texttt{font.id} 唯一。 +% \begin{macrocode} +\cs_new_nopar:Npn \@@_patch_external_font:w #1 ~ at + { #1 \lua_now:e { luatexja.jfont.print_aftl_address() } ~ at } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_ltj_select_alternate_font:} +% 在 \tn{selectfont} 中更新替代字体。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_ltj_select_alternate_font: + { + \ctex_ltj_if_alternate_shape_exist:nT { \l_@@_current_shape_tl } + { + \lua_now:e + { + luatexja.jfont.output_alt_font_cmd + ('y', '\lua_escape:e { \l_@@_current_shape_tl }') + } + \lua_now:e { luatexja.jfont.pickup_alt_font_a ('\f@size') } + } + } +\tl_new:N \l_@@_current_shape_tl +\tl_set:Nn \l_@@_current_shape_tl + { \CJK@encoding / \CJK@family / \f@series / \f@shape } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ltj@pickup@altfont@auxy} +% 被用在函数 |output_alt_font_cmd| 中,作用是定义替代字体。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ltj@pickup@altfont@auxy #1 + { + \cs_if_exist:cF { #1/\f@size } + { + \group_begin: + \use:x { \exp_not:N \split@name #1 / \f@size } \@nil + \@@_push_fontname:n { \use:c { \curr@fontshape / \f@size } } + \ctex_ltj_pickup_font: + \group_end: + \@@_pop_fontname: + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%<@@=> +% \end{macrocode} +% +% \begin{macro}[int]{\ltj@pickup@altfont@copy} +% 被用在函数 |pickup_alt_font_a| 中。\tn{ltj@@getjfontnumber} 的作用是将字体命令 +% |#1| 对应的 \texttt{font.id} 保存到 \tn{ltj@tempcntc} 中。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ltj@pickup@altfont@copy #1#2 + { + \ltj@@getjfontnumber #1 + \lua_now:e + { + luatexja.jfont.pickup_alt_font_b + ( \int_use:N \ltj@tempcntc, '\lua_escape:e {#2}' ) + } + } +% \end{macrocode} +% \end{macro} +% +% \paragraph{数学字体族} +% +% \begin{macrocode} +%<@@=ctex_ltj> +% \end{macrocode} +% +% 以下内容来自 \file{lltjfont.sty},目的是让汉字可以在数学环境中直接使用。 +% +% \begin{macro}[int]{\ctex_ltj_if_jfont:nTF} +% 参数 |#1| 是一个 \LaTeXe{} 编码名称或者字体命令。\LaTeXe{} 字体命令的一般形式是: +% \begin{quote}\ttfamily\small +% \textbackslash\meta{encoding}/\meta{family}/\meta{series}/\meta{shape} +% \end{quote} +% 通过截取名字中的 \meta{encoding} 来判断是否是 jfont。 +% 最后会设置 \tn{ifin@} 为对应的 \tn{iftrue} 或者 \tn{iffalse}。 +% \begin{macrocode} +\cs_new:Npn \ctex_ltj_if_jfont:nTF #1 + { + \lua_now:e + { luatexja.jfont.is_kenc( string.match('\lua_escape:e {#1}', '[^/]+') ) } + \ifin@ \exp_after:wN \use_i:nn \else: \exp_after:wN \use_ii:nn \fi: + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_ltj_if_jfont_math:NTF} +% |#1| 是一个形式为 |\M@|\meta{encoding} 的命令,它由 \tn{DeclareFontEncoding} 的 +% 第三个参数来定义。 +% \begin{macrocode} +\cs_new:Npn \ctex_ltj_if_jfont_math:NTF #1 + { \exp_after:wN \@@_if_jfont_math:w \token_to_str:N #1 \q_stop } +\group_begin: + \char_set_catcode_other:N M + \cs_new:Npn \@@_if_jfont_math:w #1 M #2#3 \q_stop + { \ctex_ltj_if_jfont:nTF {#3} } +\group_end: +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%<@@=> +% \end{macrocode} +% +% \begin{macro}[int]{\getanddefine@fonts,\ctex_ltj_get_and_define_fonts:nN} +% 在使用的场合,\tn{escapechar} 已经被设置成 $-1$,使用 \cs{token_to_str:N} 就 +% 可以得到名字,不必使用 \cs{cs_to_str:N}。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_ltj_get_and_define_fonts:nN #1#2 + { + \ctex_ltj_if_jfont:nTF { \token_to_str:N #2 } + { \ctex_ltj_get_and_define_fonts_ja:nN } + { \ctex_ltj_get_and_define_fonts_al:nN } + {#1} #2 + } +\cs_new_eq:NN \ctex_ltj_get_and_define_fonts_al:nN \getanddefine@fonts +\cs_set_eq:NN \getanddefine@fonts \ctex_ltj_get_and_define_fonts:nN +\cs_new_protected_nopar:Npn \ctex_ltj_get_and_define_fonts_ja:nN #1#2 + { + \tl_gset:Nx \font@name { \use:c { \token_to_str:N #2 / \tf@size } } + \ctex_ltj_pickup_font: \tl_set_eq:NN \textfont@name \font@name + \tl_gset:Nx \font@name { \use:c { \token_to_str:N #2 / \sf@size } } + \ctex_ltj_pickup_font: \tl_set_eq:NN \scriptfont@name \font@name + \tl_gset:Nx \font@name { \use:c { \token_to_str:N #2 / \ssf@size } } + \ctex_ltj_pickup_font: + \tl_put_right:Nx \math@fonts + { + \ltj@setpar@global + \ltj@@set@stackfont #1 , \textfont@name \c_colon_str { MJT } + \ltj@@set@stackfont #1 , \scriptfont@name \c_colon_str { MJS } + \ltj@@set@stackfont #1 , \font@name \c_colon_str { MJSS } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%<@@=ctex_ltj> +% \end{macrocode} +% +% \begin{macro}[int]{\use@mathgroup,\ctex_ltj_use_math_group:Nn} +% 在使用 \pkg{unicode-math} 宏包时,\cs{ctex_ltj_math_group_hook:} 将被重定义。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_ltj_use_math_group:Nn #1#2 + { + \mode_if_math:T + { + \math@bgroup + \cs_if_eq:cNF { M@ \f@encoding } #1 {#1} + \ctex_ltj_math_group_hook: + \ctex_ltj_if_jfont_math:NTF #1 + { \jfam } { \mathgroup } #2 \scan_stop: + \math@egroup + } + } +\cs_new_eq:NN \ctex_ltj_math_group_hook: \prg_do_nothing: +\cs_set_eq:NN \use@mathgroup \ctex_ltj_use_math_group:Nn +% \end{macrocode} +% \end{macro} +% +% \changes{v2.4.3}{2016/08/25}{更新 \pkg{unicode-math} 补丁。} +% \changes{v2.4.9}{2017/02/27}{调整 \pkg{unicode-math} 补丁的代码顺序。} +% 对 \pkg{unicode-math} 的补丁主要是将 \file{unicode-math-table.tex} 中的数学符号设置为 +% \pkg{luatexja} 中的数学字母。 +% 本段代码应放在 \cs{ctex_ltj_math_group_hook:} 的定义之后,避免因宏包载入顺序而造成的编译错误。 +% \begin{macrocode} +\cs_new_protected:Npn \ctex_ltj_set_math_letter:NN #1#2 + { + \group_begin: + \cs_set_protected:Npn #1 ##1##2##3 + { \ltjsetmathletter { ##1 } } + #2 + \group_end: + } +\ctex_at_end_package:nn { unicode-math } + { + \cs_if_exist:NTF \um_input_math_symbol_table: + { + \ctex_ltj_set_math_letter:NN + \um_sym:nnn + \um_input_math_symbol_table: + } + { + \cs_set_eq:NN \use@mathgroup \ctex_ltj_use_math_group:Nn + \cs_set_protected_nopar:Npn \ctex_ltj_math_group_hook: + { \__um_switchto_literal: } + \ctex_ltj_set_math_letter:NN + \__um_sym:nnn + \__um_input_math_symbol_table: + } + } +% \end{macrocode} +% +% \paragraph{字体族的定义与使用} +% +% \begin{macro}[int]{\ctex_mono_jfm:n} +% \begin{variable}{\l_@@_jfm_tl} +% \pkg{LuaTeX-ja} 中与标点格式 \opt{plain} 对应的 \texttt{JFM} 是 \opt{mono}。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_mono_jfm:n #1 + { + \str_if_eq:nnTF {#1} { plain } + { \tl_set:Nn \l_@@_jfm_tl { mono } } + { \tl_set:Nn \l_@@_jfm_tl {#1} } + } +\tl_new:N \l_@@_jfm_tl +\cs_generate_variant:Nn \ctex_mono_jfm:n { o } +\ctex_mono_jfm:o { \l__ctex_punct_tl } +% \end{macrocode} +% \end{variable} +% \end{macro} +% +% \begin{macro}[int]{\CJK@encoding} +% \begin{macro}{\@@_change_encoding:} +% 在 \LaTeX 下,\pkg{LuaTeX-ja} 依赖字体编码来实现特殊设置。例如上述的 +% \cs{ctex_ltj_if_jfont:nTF} 就是通过判断编码来实现的,它在设置数学字体时会用到。所以 +% 不应该与西文共用 \texttt{EU2}。定义字体族 song 为 \tn{CJK@encoding} 的默认替换 +% 字体。下划线 |_| 不在 \tn{nfss@catcodes} 里,可以放心使用。 +% \begin{macrocode} +\tl_const:Nn \CJK@encoding { LTJY3 } +\DeclareFontEncoding { \CJK@encoding } { } { } +\use:x + { + \exp_not:N \DeclareFontSubstitution + { \CJK@encoding } { song } { \mddefault } { \updefault } + } +\lua_now:e { luatexja.jfont.add_kyenc_list('\CJK@encoding') } +\cs_new_protected_nopar:Npn \@@_change_encoding: + { \tl_set_eq:NN \g_fontspec_encoding_tl \CJK@encoding } +\DeclareFontFamily { \CJK@encoding } { song } { } +\DeclareFontShape { \CJK@encoding } { song } { \mddefault } { \updefault } + { <-> psft:SimSun:cid=Adobe-GB1-5;jfm=\l_@@_jfm_tl } { } +\DeclareFontShape { \CJK@encoding } { song } { \bfdefault } { \updefault } + { <-> psft:SimHei:cid=Adobe-GB1-5;jfm=\l_@@_jfm_tl } { } +\tl_const:Nn \c_@@_math_tl { CJKmath } +\DeclareSymbolFont { \c_@@_math_tl } + { \CJK@encoding } { song } { \mddefault } { \updefault } +\SetSymbolFont { \c_@@_math_tl } { bold } + { \CJK@encoding } { song } { \bfdefault } { \updefault } +\int_const:Nn \c_@@_math_fam_int { \use:c { sym \c_@@_math_tl } } +\jfam \c_@@_math_fam_int +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% 这是 \pkg{luatexja-fontspec} 中新增的一些字体选项。 +% \begin{macrocode} +\newfontfeature { CID } { cid = #1 } +\newfontfeature { JFM } { jfm = #1 } +\newfontfeature { JFM-var } { jfmvar = #1 } +% \end{macrocode} +% +% 在新版本的 \pkg{fontspec} 中,\cs{__fontspec_fontname_wrap:n} 变成了私有函数。 +% \begin{macrocode} +\keys_define:nn { fontspec-preparse-external } + { + NoEmbed .code:n = + { \cs_set_eq:NN \__fontspec_fontname_wrap:n \@@_noembed_wrap:n } + } +\cs_new:Npn \@@_noembed_wrap:n #1 { psft: #1 } +% \end{macrocode} +% +% \begin{macro}[int]{\ctex_ltj_set_family:nnn} +% 将自定义的字体族名与 \pkg{fontspec} 实际设置的名字对应起来。 +% \begin{macrocode} +\cs_new_protected:Npn \ctex_ltj_set_family:nnn #1#2#3 + { + \group_begin: + \clist_clear:N \l_@@_char_range_clist + \seq_clear:N \l_@@_alternate_seq + \tl_set:Nn \l_@@_base_CJKfamily_tl {#1} + \keys_set_known:nnN { ctex_ltj / fontspec } {#2} \l_@@_tmp_tl + \clist_set:No \l_@@_font_options_clist { \l_@@_tmp_tl } + \ctex_ltj_set_alternate_family:nnF {#1} {#3} + { + \prop_gput:Nnn \g_@@_family_font_name_prop {#1} {#3} + \prop_gput:Nno \g_@@_family_font_options_prop + {#1} { \l_@@_font_options_clist } + \@@_update_family_uid:N \l_@@_font_options_clist + \@@_use_global_options:N \l_@@_font_options_clist + \@@_gset_family_cs:nn {#1} {#3} + } + \group_end: + } +\tl_new:N \l_@@_base_CJKfamily_tl +\clist_new:N \l_@@_font_options_clist +\cs_new_protected_nopar:Npn \@@_use_global_options:N #1 + { + \clist_concat:NNN #1 \g_@@_default_features_clist #1 + \clist_put_left:Nx #1 { JFM = \l_@@_jfm_tl } + } +% \end{macrocode} +% \end{macro} +% +% \begin{variable} +% {\g_@@_family_name_prop,\g_@@_family_font_name_prop,\g_@@_family_font_options_prop} +% 分别保存 \pkg{fontspec} 设置的字体族名、字体名称和字体选项。 +% \begin{macrocode} +\prop_new:N \g_@@_family_name_prop +\prop_new:N \g_@@_family_font_name_prop +\prop_new:N \g_@@_family_font_options_prop +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\@@_check_family:n} +% 删除重复的定义,清除替代字体的先前设置。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_check_family:n #1 + { + \prop_gpop:NnNT \g_@@_family_font_name_prop {#1} \l_@@_tmp_tl + { + \cs_undefine:c { \@@_family_csname:n {#1} } + \cs_undefine:c { \@@_alternate_cs:n {#1} } + \prop_gpop:NnNT \g_@@_family_name_prop {#1} \l_@@_base_family_tl + { + \use:c { \@@_alternate_cs:n { clear / #1 } } + \cs_undefine:c { \@@_alternate_cs:n { clear / #1 } } + \cs_undefine:c { \@@_alternate_cs:n { reset / #1 } } + \prop_gremove:Nn \g_@@_reset_alternate_prop {#1} + } + \msg_warning:nnxx { ctex } { redefine-family } {#1} { \l_@@_tmp_tl } + } + } +\tl_new:N \l_@@_tmp_tl +\msg_new:nnn { ctex } { redefine-family } + { Redefining~CJKfamily~`\@@_msg_family_map:n {#1}'~(#2). } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_gset_family_cs:nn} +% 在设置字体时,实际上并不是马上就定义。而是只保存相关参数,在通过 \tn{CJKfamily} +% 第一次使用时才定义。需要注意将编码改为 \tn{CJK@encoding}。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_gset_family_cs:nn #1#2 + { + \cs_gset_protected_nopar:cpx { \@@_family_csname:n {#1} } + { + \group_begin: + \@@_change_encoding: + \exp_not:n { \cs_set_eq:NN \CJKfamily \use_none:n } + \exp_not:n { \cs_set_eq:NN \CTEX@fontfamily \use_none:n } + \exp_not:n { \fontspec_set_family:Nnn \g_@@_fontspec_family_tl } + { \exp_not:o { \l_@@_font_options_clist } } {#2} + \prop_gput:Nno \exp_not:N \g_@@_family_name_prop {#1} + { \exp_not:N \g_@@_fontspec_family_tl } + \tl_gset_eq:NN \exp_not:N \g_@@_fontspec_family_tl + \exp_not:N \g_@@_fontspec_family_tl + \@@_set_alternate_family:n {#1} + \group_end: + } + } +\tl_new:N \l_@@_base_family_tl +\tl_new:N \g_@@_fontspec_family_tl +\cs_new_nopar:Npn \@@_family_csname:n #1 { ctex_ltj/family/#1 } +\cs_new_protected_nopar:Npn \@@_set_alternate_family:n #1 + { + \tl_set:Nn \l_@@_base_CJKfamily_tl {#1} + \tl_set_eq:NN \l_@@_base_family_tl \g_@@_fontspec_family_tl + \cs_if_exist_use:c { \@@_alternate_cs:n { reset / #1 } } + \cs_if_exist_use:c { \@@_alternate_cs:n {#1} } + } +\cs_new:Npn \@@_alternate_cs:n #1 { ctex_ltj/alternate_family/#1 } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\CJKfamily} +% 切换字体。 +% \begin{macrocode} +\NewDocumentCommand \CJKfamily { m } + { \ctex_ltj_switch_family:x {#1} \tex_ignorespaces:D } +\cs_new_protected_nopar:Npn \ctex_ltj_switch_family:n #1 + { + \ctex_ltj_family_if_exist:nNTF {#1} \CJK@family + { + \tl_set:Nn \l_ctex_ltj_family_tl {#1} + \selectfont + } + { \@@_family_unknown_warning:n {#1} } + } +\tl_new:N \l_ctex_ltj_family_tl +\cs_generate_variant:Nn \ctex_ltj_switch_family:n { x } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int,TF]{\ctex_ltj_family_if_exist:nN} +% 判断 CJK 字体族 |#1| 是否存在,若存在则把实际族名保存到 |#2| 中。 +% \begin{macrocode} +\prg_new_protected_conditional:Npnn \ctex_ltj_family_if_exist:nN #1#2 { T , F , TF } + { + \prop_get:NnNTF \g_@@_family_name_prop {#1} #2 + { \prg_return_true: } + { + \cs_if_exist_use:cTF { \@@_family_csname:n {#1} } + { + \tl_set_eq:NN #2 \g_@@_fontspec_family_tl + \prg_return_true: + } + { \prg_return_false: } + } + } +\prg_generate_conditional_variant:Nnn \ctex_ltj_family_if_exist:nN { x } { T , F , TF } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_family_unknown_warning:n} +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_family_unknown_warning:n #1 + { + \prop_if_empty:NF \g_@@_family_font_name_prop + { + \seq_if_in:NnF \g_@@_unknown_family_seq {#1} + { + \seq_gput_right:Nn \g_@@_unknown_family_seq {#1} + \msg_warning:nnn { ctex } { family-unknown } {#1} + } + } + } +\seq_new:N \g_@@_unknown_family_seq +\msg_new:nnn { ctex } { family-unknown } + { + Unknown~CJK~family~`\@@_msg_family_map:n {#1}'~is~being~ignored.\\ + Try~to~use~`\@@_msg_def_family_map:n {#1}'~to~define~it. + } +\cs_new_nopar:Npn \@@_msg_def_family_map:n #1 + { + \str_case_e:nnF {#1} + { + \CJKrmdefault { \token_to_str:N \setCJKmainfont } + \CJKsfdefault { \token_to_str:N \setCJKsansfont } + \CJKttdefault { \token_to_str:N \setCJKmonofont } + } + { \token_to_str:N \setCJKfamilyfont \{ #1 \} } + [...]\{...\} + } +\cs_new_nopar:Npn \@@_msg_family_map:n #1 + { + \str_case_e:nnF {#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}[int]{\ctex_ltj_fontspec:nn} +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_ltj_fontspec:nn #1#2 + { + \prop_get:NnNTF \g_@@_fontspec_prop + { CJKfontspec/#1/#2/id } \l_ctex_ltj_family_tl + { \ctex_ltj_switch_family:x { \l_ctex_ltj_family_tl } } + { + \int_gincr:N \g_@@_family_int + \@@_fontspec:xnn + { CJKfontspec ( \int_use:N \g_@@_family_int ) } + {#1} {#2} + } + } +\cs_new_protected_nopar:Npn \ctex_ltj_fontspec:xx #1#2 + { \use:x { \ctex_ltj_fontspec:nn {#1} {#2} } } +\cs_new_protected_nopar:Npn \@@_fontspec:nnn #1#2#3 + { + \bool_if:NT \l_@@_add_alternate_bool + { + \cs_if_free:cF + { \@@_alternate_cs:n { reset / \l_ctex_ltj_family_tl } } + { + \cs_gset_eq:cc + { \@@_alternate_cs:n { reset / #1 } } + { \@@_alternate_cs:n { reset / \l_ctex_ltj_family_tl } } + \cs_gset_eq:cc + { \@@_alternate_cs:n { clear / #1 } } + { \@@_alternate_cs:n { clear / \l_ctex_ltj_family_tl } } + } + \bool_set_false:N \l_@@_add_alternate_bool + } + \prop_gput:Nnn \g_@@_fontspec_prop { CJKfontspec/#2/#3/id } {#1} + \ctex_ltj_set_family:nnn {#1} {#2} {#3} + \ctex_ltj_switch_family:n {#1} + } +\cs_generate_variant:Nn \@@_fontspec:nnn { x } +\prop_new:N \g_@@_fontspec_prop +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int] +% {\ctex_ltj_add_font_features:n,\ctex_ltj_add_font_features:nn} +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_ltj_add_font_features:n #1 + { \ctex_ltj_add_font_features:xn { \l_ctex_ltj_family_tl } {#1} } +\cs_new_protected_nopar:Npn \ctex_ltj_add_font_features:nn #1#2 + { + \prop_get:NnNTF \g_@@_family_font_name_prop + {#1} \l_@@_tmp_tl + { + \prop_get:NnN \g_@@_family_font_options_prop + {#1} \l_@@_font_options_clist + \clist_put_right:Nn \l_@@_font_options_clist {#2} + \bool_set_true:N \l_@@_add_alternate_bool + \ctex_ltj_fontspec:xx + { \exp_not:o { \l_@@_font_options_clist } } + { \exp_not:o { \l_@@_tmp_tl } } + } + { \msg_warning:nn { ctex } { addCJKfontfeature-ignored } } + } +\bool_new:N \l_@@_add_alternate_bool +\cs_generate_variant:Nn \ctex_ltj_add_font_features:n { x } +\cs_generate_variant:Nn \ctex_ltj_add_font_features:nn { x } +\msg_new:nnn { ctex } { addCJKfontfeature-ignored } + { + \token_to_str:N \addCJKfontfeature (s)~ignored.\\ + It~cannot~be~used~with~a~font~that~wasn't~selected~by~ctex. + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_pass_args:nnnn} +% 为了支持字体属性可选项在前在后两种语法,给出两个辅助工具,自带展开功能。 +% \begin{macrocode} +\cs_new_protected:Npn \@@_pass_args:nnnn #1#2#3#4 + { + \IfNoValueTF {#2} + { \@@_post_arg:w {#1} {#3} {#4} } + { + \use:x { #1 {#2} {#3} } + #4 + } + } +\NewDocumentCommand \@@_post_arg:w { m m m O { } } + { + \use:x { #1 {#4} {#2} } + #3 + } +% \end{macrocode} +% \end{macro} +% +% \changes{v2.4.6}{2016/11/20}{支持字体属性可选项在后的新语法。} +% +% \begin{macro}[int] +% {\setCJKfamilyfont,\newCJKfontfamily,\CJKfontspec,\addCJKfontfeatures} +% \begin{macrocode} +\NewDocumentCommand \setCJKfamilyfont { m o m } + { + \@@_pass_args:nnnn + { \ctex_ltj_set_family:nnn {#1} } {#2} {#3} + { } + } +\NewDocumentCommand \newCJKfontfamily { o m o m } + { + \tl_set:Nx \l_@@_tmp_tl + { \IfNoValueTF {#1} { \cs_to_str:N #2 } {#1} } + \cs_new_protected_nopar:Npx #2 + { \ctex_ltj_switch_family:n { \l_@@_tmp_tl } } + \@@_pass_args:nnnn + { \ctex_ltj_set_family:nnn { \l_@@_tmp_tl } } {#3} {#4} + { } + } +\NewDocumentCommand \CJKfontspec { o m } + { + \@@_pass_args:nnnn + { \ctex_ltj_fontspec:nn } {#1} {#2} + { \tex_ignorespaces:D } + } +\NewDocumentCommand \addCJKfontfeatures { m } + { + \ctex_ltj_add_font_features:x {#1} + \tex_ignorespaces:D + } +\cs_new_eq:NN \addCJKfontfeature \addCJKfontfeatures +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int] +% {\setCJKmainfont,\setCJKsansfont,\setCJKmonofont, +% \setCJKmathfont,\defaultCJKfontfeatures} +% \begin{macrocode} +\NewDocumentCommand \setCJKmainfont { o m } + { + \@@_pass_args:nnnn + { \ctex_ltj_set_family:nnn { \CJKrmdefault } } {#1} {#2} + { \normalfont } + } +\cs_new_eq:NN \setCJKromanfont \setCJKmainfont +\NewDocumentCommand \setCJKsansfont { o m } + { + \@@_pass_args:nnnn + { \ctex_ltj_set_family:nnn { \CJKsfdefault } } {#1} {#2} + { \normalfont } + } +\NewDocumentCommand \setCJKmonofont { o m } + { + \@@_pass_args:nnnn + { \ctex_ltj_set_family:nnn { \CJKttdefault } } {#1} {#2} + { \normalfont } + } +\NewDocumentCommand \setCJKmathfont { o m } + { + \@@_pass_args:nnnn + { \ctex_ltj_set_family:nnn { \c_@@_math_tl } } {#1} {#2} + { } + } +\NewDocumentCommand \defaultCJKfontfeatures { m } + { \clist_gset:Nn \g_@@_default_features_clist {#1} } +\clist_new:N \g_@@_default_features_clist +\@onlypreamble \setCJKmainfont +\@onlypreamble \setCJKsansfont +\@onlypreamble \setCJKmonofont +\@onlypreamble \setCJKmathfont +\@onlypreamble \setCJKromanfont +\@onlypreamble \defaultCJKfontfeatures +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +\tl_if_exist:NF \CJKfamilydefault + { \tl_const:Nn \CJKfamilydefault { \CJKrmdefault } } +\tl_if_exist:NF \CJKrmdefault { \tl_const:Nn \CJKrmdefault { rm } } +\tl_if_exist:NF \CJKsfdefault { \tl_const:Nn \CJKsfdefault { sf } } +\tl_if_exist:NF \CJKttdefault { \tl_const:Nn \CJKttdefault { tt } } +% \end{macrocode} +% +% \begin{macro}[int]{\fontfamily} +% \begin{macro}[int]{\CTEX@fontfamily} +% \changes{v2.4.8}{2017/02/23} +% {解决与 \pkg{fontspec} 2017/01/24 v2.5d 的字体族匹配兼容问题。} +% 修改 \tn{fontfamily},使主要 |CJK| 字体族能随西文主要字体更新。 +% \begin{macrocode} +\RenewDocumentCommand \fontfamily { m } + { + \tl_set:Nx \f@family {#1} + \CTEX@fontfamily {#1} + } +\cs_new_protected_nopar:Npn \CTEX@fontfamily #1 + { + \str_if_eq:nnTF {#1} { \familydefault } + { \CJKfamily { \CJKfamilydefault } } + { \@@_update_family_aux: } + } +\cs_new_protected_nopar:Npn \@@_update_family_aux: + { + \str_case_e:nn { \f@family } + { + { \rmdefault } { \CJKfamily { \CJKrmdefault } } + { \sfdefault } { \CJKfamily { \CJKsfdefault } } + { \ttdefault } { \CJKfamily { \CJKttdefault } } + { \familydefault } { \CJKfamily { \CJKfamilydefault } } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% 在导言区末尾更新 \tn{CJKfamilydefault}。 +% \begin{macrocode} +\ctex_at_end_preamble:n { \ctex_update_default_family: } +% \end{macrocode} +% +% \begin{macro}[int]{\ctex_ltj_ensure_default_family:} +% 在导言区结束确认 \tn{CJKfamilydefault} 确实存在。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_ltj_ensure_default_family: + { + \prop_if_empty:NF \g_@@_family_font_name_prop + { + \ctex_ltj_family_if_exist:xNF { \CJKfamilydefault } \l_@@_tmp_tl + { + \str_if_eq:eeTF { \CJKfamilydefault } { \CJKrmdefault } + { \use:n } + { + \ctex_ltj_family_if_exist:xNTF { \CJKrmdefault } \l_@@_tmp_tl + { \tl_gset:Nn \CJKfamilydefault { \CJKrmdefault } \use_none:n } + { \use:n } + } + { + \prop_map_inline:Nn \g_@@_family_font_name_prop + { + \prop_map_break:n + { \tl_gset_rescan:Nnn \CJKfamilydefault { } { ##1 } } + } + } + } + \normalfont + \ctex_ltj_update_mathfont: + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_ltj_update_mathfont:} +% 更新数学字体为实际的字体。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_ltj_update_mathfont: + { + \ctex_ltj_family_if_exist:xNTF { \c_@@_math_tl } \l_@@_tmp_tl + { \ctex_ltj_update_mathfont:n { \l_@@_tmp_tl } } + { + \ctex_ltj_family_if_exist:xNT { \CJKfamilydefault } \l_@@_tmp_tl + { \ctex_ltj_update_mathfont:n { \l_@@_tmp_tl } } + } + } +\cs_new_protected_nopar:Npn \ctex_ltj_update_mathfont:n #1 + { + \tl_const:Nx \c_@@_math_family_tl {#1} + \DeclareSymbolFont { \c_@@_math_tl } { \CJK@encoding } + { \c_@@_math_family_tl } { \mddefault } { \updefault } + \cs_if_free:cTF + { \CJK@encoding/\c_@@_math_family_tl/\bfdefault/\updefault } + { + \SetSymbolFont { \c_@@_math_tl } { bold } { \CJK@encoding } + { \c_@@_math_family_tl } { \mddefault } { \updefault } + } + { + \SetSymbolFont { \c_@@_math_tl } { bold } { \CJK@encoding } + { \c_@@_math_family_tl } { \bfdefault } { \updefault } + } + } +% \end{macrocode} +% \end{macro} +% +% \paragraph{替代字体的设置} +% +% \begin{macro}{AlternateFont,CharRange} +% 设置替代字体的选项。 +% \begin{macrocode} +\keys_define:nn { ctex_ltj / fontspec } + { + AlternateFont .code:n = \ctex_ltj_set_alternate_seq:n {#1} , + AlternateFont .value_required:n = true , + CharRange .clist_set:N = \l_@@_char_range_clist , + CharRange .value_required:n = true + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_ltj_set_alternate_seq:n} +% 我们使用 \verb=||= 作为替代字体序列的分隔标志。它可能被设置为活动字符,为此 +% 需要先“消毒”,同时过滤掉空元素。 +% \begin{macrocode} +\group_begin: + \char_set_catcode_other:N \| + \cs_set:Npn \@@_tmp:w #1 + { + \cs_new_protected:Npn \ctex_ltj_set_alternate_seq:n ##1 + { + \clist_if_empty:NT \l_@@_char_range_clist + { + \tl_set:Nn \l_@@_tmp_tl { ##1 } + \tl_replace_all:Nnn \l_@@_tmp_tl {#1} { || } + \seq_set_split:NnV \l_@@_tmp_seq { || } \l_@@_tmp_tl + \seq_set_filter:NNn \l_@@_tmp_seq \l_@@_tmp_seq + { ! \tl_if_blank_p:n { ####1 } } + \seq_concat:NNN \l_@@_alternate_seq + \l_@@_alternate_seq \l_@@_tmp_seq + } + } + } + \char_set_catcode_active:N \| + \@@_tmp:w { || } +\group_end: +\seq_new:N \l_@@_tmp_seq +\seq_new:N \l_@@_alternate_seq +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_ltj_set_alternate_family:nnF} +% 如果在字体的选项中设置了 \opt{CharRange},则只设置替代字体。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_ltj_set_alternate_family:nnF #1#2#3 + { + \clist_if_empty:NTF \l_@@_char_range_clist + { + \@@_check_family:n {#1} + \seq_if_empty:NF \l_@@_alternate_seq + { \ctex_ltj_save_alternate_seq:cn { \@@_alternate_cs:n {#1} } {#2} } + #3 + } + { \ctex_ltj_set_alternate_family:nn {#1} {#2} } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int] +% {\ctex_ltj_save_alternate_seq:Nn,\ctex_ltj_save_alternate_seq:Nnnwn} +% 保存由 \opt{AlternateFont} 设置的替代字体序列。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_ltj_save_alternate_seq:Nn #1#2 + { + \seq_map_inline:Nn \l_@@_alternate_seq + { \ctex_ltj_save_alternate_seq:Nnnwnw #1 {#2} ##1 { } \q_stop } + } +\cs_generate_variant:Nn \ctex_ltj_save_alternate_seq:Nn { c } +\NewDocumentCommand \ctex_ltj_save_alternate_seq:Nnnwnw + { m m m +O{ } m u{ \q_stop } } + { + \clist_set:Nn \l_@@_char_range_clist {#3} + \clist_set:Nn \l_@@_alternate_options_clist {#4} + \@@_use_global_options:N \l_@@_alternate_options_clist + \tl_if_blank:nTF {#5} + { \tl_set:Nn \l_@@_tmp_tl {#2} } + { + \tl_set:Nn \l_@@_tmp_tl {#5} + \tl_replace_all:Nnn \l_@@_tmp_tl { * } {#2} + } + \use:x + { + \ctex_ltj_save_alternate_family:Nnnn \exp_not:N #1 + { \exp_not:o { \l_@@_char_range_clist } } + { \exp_not:o { \l_@@_alternate_options_clist } } + { \exp_not:o { \l_@@_tmp_tl } } + } + } +\clist_new:N \l_@@_alternate_options_clist +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_ltj_set_alternate_family:nn} +% 设置选项 \opt{CharRange} 范围内的替代字体。如果已经定义了主字体,我们也马上 +% 定义替代字体,否则只保存起来备用。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_ltj_set_alternate_family:nn #1#2 + { + \@@_update_family_uid:N \l_@@_font_options_clist + \@@_use_global_options:N \l_@@_font_options_clist + \ctex_ltj_set_alternate_family:coonn + { \@@_alternate_cs:n {#1} } + { \l_@@_char_range_clist } + { \l_@@_font_options_clist } {#2} {#1} + } +\cs_new_protected_nopar:Npn \ctex_ltj_set_alternate_family:Nnnnn #1#2#3#4#5 + { + \prop_get:NnNT \g_@@_family_name_prop {#5} \l_@@_base_family_tl + { \ctex_ltj_set_alternate_family:nnn {#2} {#3} {#4} } + \ctex_ltj_save_alternate_family:Nnnn #1 {#2} {#3} {#4} + } +\cs_generate_variant:Nn \ctex_ltj_set_alternate_family:Nnnnn { coo } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_ltj_save_alternate_family:Nnnn} +% 保存替代字体序列的定义,以备定义主字体时使用。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_ltj_save_alternate_family:Nnnn #1#2#3#4 + { + \cs_if_exist:NF #1 { \cs_set_eq:NN #1 \prg_do_nothing: } + \cs_gset_protected_nopar:Npx #1 + { \exp_not:o { #1 \ctex_ltj_set_alternate_family:nnn {#2} {#3} {#4} } } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_ltj_set_alternate_family:nnn} +% 实际定义替代字体族。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_ltj_set_alternate_family:nnn #1#2#3 + { + \group_begin: + \@@_change_encoding: + \cs_set_eq:NN \CJKfamily \use_none:n + \ctex_ltj_swap_cs:NN + \DeclareFontShape@ \ctex_ltj_declare_alternate_shape:nnnnnn + \tl_set:Nn \l_@@_char_range_clist {#1} + \fontspec_set_family:Nnn \l_@@_alternate_family_tl {#2} {#3} + \group_end: + } +\tl_new:N \l_@@_alternate_family_tl +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_ltj_swap_cs:NN} +% 交换两个控制序列的意义。 +% \begin{macrocode} +\cs_new_protected:Npn \ctex_ltj_swap_cs:NN #1#2 + { + \cs_set_eq:NN \@@_tmp:w #1 + \cs_set_eq:NN #1 #2 + \cs_set_eq:NN #2 \@@_tmp:w + \cs_undefine:N \@@_tmp:w + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{LTJFONTUID} +% \begin{macro}{\@@_update_family_uid:N} +% \pkg{fontspec} 在一个字体族的选项和字体名称相同的时候,就不定义新字体。为了 +% 避免混淆替代字体的设置,我们新定义一个虚拟的选项 \opt{LTJFONTUID},确保 +% \pkg{fontspec} 对 CJK 字体族总是定义新字体。 +% \begin{macrocode} +\keys_define:nn { fontspec } { LTJFONTUID .code:n = } +\cs_new_protected_nopar:Npn \@@_update_family_uid:N #1 + { + \int_gincr:N \g_@@_family_int + \clist_put_right:Nx #1 { LTJFONTUID = \int_use:N \g_@@_family_int } + } +\int_new:N \g_@@_family_int +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[int]{\ctex_ltj_declare_alternate_shape:nnnnnn} +% 在定义替代字体的字形时,通过字符范围与主字体的对应字形关联起来。 +% \tn{DeclareFontShape@} 一个有六个参数,我们只需要使用它的第三个参数 \meta{series} +% 和第四个参数 \meta{shape}。 +% \begin{macrocode} +\cs_new_protected:Npn \ctex_ltj_declare_alternate_shape:nnnnnn #1#2#3#4#5#6 + { + \ctex_ltj_declare_alternate_shape:nnnnnn {#1} {#2} {#3} {#4} {#5} {#6} + \ctex_ltj_set_alternate_shape:Nnnnnnn \l_@@_char_range_clist + { \l_@@_base_family_tl } {#3} {#4} + { \l_fontspec_family_tl } {#3} {#4} + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_ltj_set_alternate_shape:Nnnnnnn} +% 与 \pkg{LuaTeX-ja} 的 \tn{DeclareAlternateKanjiFont} 的功能类似,区别是固定编码 +% 为 \tn{CJK@encoding}。这个设置总是全局的。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_ltj_set_alternate_shape:Nnnnnnn #1#2#3#4#5#6#7 + { + \clist_map_inline:Nn #1 + { + \prop_get:NnNTF \g_@@_char_range_prop { ##1 } \l_@@_char_range_tl + { + \ctex_ltj_set_alternate_shape:nnN { #2/#3/#4 } { #5/#6/#7 } + \l_@@_char_range_tl + } + { \ctex_ltj_set_alternate_shape:nnn { #2/#3/#4 } { #5/#6/#7 } { ##1 } } + } + \@@_save_alternate_shape:cnn + { \@@_alternate_cs:n { clear / \l_@@_base_CJKfamily_tl } } + { luatexja.jfont.clear_alt_font_latex } + { '\lua_escape:e { \CJK@encoding/#2/#3/#4 }' } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_ltj_set_alternate_shape:nnn} +% 我们使用 \texttt{->} 而不是像 \pkg{LuaTeX-ja} 一样使用 \texttt{-} 作为区间的 +% 分隔符。\pkg{LuaTeX-ja} 支持使用负数来引用由 \texttt{JFM} 设置的字符类。如果 +% 使用 \texttt{-} 作为分隔符,那么负数单独使用时,就需要把它放在两层花括号之内 +% (例如 |{{-1}}|),或者使用类似 |{-1}-{-1}| 的形式才不会解释错误。 +% \begin{macrocode} +\NewDocumentCommand \ctex_ltj_set_alternate_shape:nnn + { m m > { \SplitArgument { 1 } { -> } } m } + { \ctex_ltj_set_alternate_shape:nnnn {#1} {#2} #3 } +\cs_new_protected_nopar:Npn \ctex_ltj_set_alternate_shape:nnnn #1#2#3#4 + { + \ctex_ltj_set_alternate_shape:n + { + \IfNoValueTF {#4} + { \int_eval:n {#3} , \int_eval:n {#3} , } + { + \int_eval:n { \tl_if_blank:nTF {#3} { "80 } {#3} } , + \int_eval:n { \tl_if_blank:nTF {#4} { "10FFFF } {#4} } , + } + '\lua_escape:e { \CJK@encoding/#2 }' , + '\lua_escape:e { \CJK@encoding/#1 }' + } + } +\cs_new_protected_nopar:Npn \ctex_ltj_set_alternate_shape:n #1 + { + \lua_now:e { luatexja.jfont.set_alt_font_latex ( #1 ) } + \@@_save_alternate_shape:cnn + { \@@_alternate_cs:n { reset / \l_@@_base_CJKfamily_tl } } + { luatexja.jfont.set_alt_font_latex } {#1} + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_ltj_set_alternate_shape:nnN} +% 若字符范围预先由 \texttt{declarecharrange} 声明,则可以直接使用。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_ltj_set_alternate_shape:nnN #1#2#3 + { + \tl_map_inline:Nn #3 + { + \ctex_ltj_set_alternate_shape:n + { + ##1 , + '\lua_escape:e { \CJK@encoding/#2 }' , + '\lua_escape:e { \CJK@encoding/#1 }' + } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_save_alternate_shape:Nnn} +% 将实际设置的替换字形保存起来用于清除或恢复。 +% 暂时令 \cs{l_@@_base_family_tl} 为 \cs{scan_stop:} 是让它不被展开,使得替换 +% 字体的设置可以在 \tn{addCJKfontfeature} 中直接使用。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_save_alternate_shape:Nnn #1#2#3 + { + \group_begin: + \cs_if_exist:NF #1 { \cs_set_eq:NN #1 \prg_do_nothing: } + \cs_set_eq:NN \l_@@_base_family_tl \scan_stop: + \cs_set_eq:NN \lua_escape:e \scan_stop: + \cs_gset_protected_nopar:Npx #1 + { \exp_not:o {#1} \exp_not:N \lua_now:e { #2 ( #3 ) } } + \group_end: + } +\cs_generate_variant:Nn \@@_save_alternate_shape:Nnn { c } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{clearalternatefont,resetalternatefont} +% 清除和重置操作总是全局的。 +% \begin{macrocode} +\keys_define:nn { ctex } + { + clearalternatefont .code:n = + { \clist_map_function:xN {#1} \ctex_ltj_clear_alternate_font:n } , + resetalternatefont .code:n = + { \clist_map_function:xN {#1} \ctex_ltj_reset_alternate_font:n } , + clearalternatefont .default:n = \l_ctex_ltj_family_tl , + resetalternatefont .default:n = \l_ctex_ltj_family_tl + } +\cs_new_protected_nopar:Npn \ctex_ltj_clear_alternate_font:n #1 + { + \group_begin: + \ctex_ltj_family_if_exist:xNTF {#1} \l_@@_base_family_tl + { + \cs_if_exist_use:cT { \@@_alternate_cs:n { clear / #1 } } + { + \prop_gput:Nno \g_@@_reset_alternate_prop + {#1} { \l_@@_base_family_tl } + \tl_set_eq:NN \CJK@family \l_@@_base_family_tl + \selectfont + } + } + { \@@_family_unknown_warning:n {#1} } + \group_end: + } +\cs_new_protected_nopar:Npn \ctex_ltj_reset_alternate_font:n #1 + { + \group_begin: + \prop_gpop:NnNT \g_@@_reset_alternate_prop {#1} \CJK@family + { + \tl_set_eq:NN \l_@@_base_family_tl \CJK@family + \use:c { \@@_alternate_cs:n { reset / #1 } } + \selectfont + } + \group_end: + } +\prop_new:N \g_@@_reset_alternate_prop +\cs_generate_variant:Nn \clist_map_function:nN { x } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{declarecharrange} +% 预先声明字符范围。 +% \begin{macrocode} +\keys_define:nn { ctex } + { + declarecharrange .code:n = \ctex_ltj_declare_char_range:x {#1} , + declarecharrange .value_required:n = true + } +\cs_new_protected_nopar:Npn \ctex_ltj_declare_char_range:n #1 + { \clist_map_inline:nn {#1} { \@@_declare_char_range:nn ##1 } } +\cs_generate_variant:Nn \ctex_ltj_declare_char_range:n { x } +\cs_new_protected_nopar:Npn \@@_declare_char_range:nn #1#2 + { \use:x { \ctex_ltj_declare_char_range:nn { \tl_trim_spaces:n {#1} } } {#2} } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_ltj_declare_char_range:nn} +% \begin{variable}{\g_@@_char_range_prop} +% |#1| 是名字,|#2| 是范围。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_ltj_declare_char_range:nn #1#2 + { + \tl_clear:N \l_@@_char_range_tl + \clist_map_function:nN {#2} \ctex_ltj_save_char_range:n + \prop_gput:Nno \g_@@_char_range_prop {#1} { \l_@@_char_range_tl } + \ctex_ltj_def_char_range_key:n {#1} + \tl_clear:N \l_@@_char_range_tl + } +\tl_new:N \l_@@_char_range_tl +\prop_new:N \g_@@_char_range_prop +% \end{macrocode} +% \end{variable} +% \end{macro} +% +% \begin{macro}[int]{\ctex_ltj_save_char_range:n} +% 预先解释字符区间的意义。 +% \begin{macrocode} +\NewDocumentCommand \ctex_ltj_save_char_range:n + { > { \SplitArgument { 1 } { -> } } m } + { \ctex_ltj_save_char_range:nn #1 } +\cs_new_protected_nopar:Npn \ctex_ltj_save_char_range:nn #1#2 + { + \tl_put_right:Nx \l_@@_char_range_tl + { { + \IfNoValueTF {#2} + { \int_eval:n {#1} , \int_eval:n {#1} } + { + \int_eval:n { \tl_if_blank:nTF {#1} { "80 } {#1} } , + \int_eval:n { \tl_if_blank:nTF {#2} { "10FFFF } {#2} } + } + } } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_ltj_def_char_range_key:n} +% 在字体设置选项中定义字符范围键。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_ltj_def_char_range_key:n #1 + { + \keys_if_exist:nnF { ctex_ltj / fontspec } {#1} + { + \keys_define:nn { ctex_ltj / fontspec } + { #1 .code:n = \ctex_ltj_char_range_key:nn {#1} { ##1 } } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_ltj_char_range_key:nn} +% 如果字符范围键没有值,则只设置的这个字符范围内的替代字体。 +% \begin{macrocode} +\cs_new_protected:Npn \ctex_ltj_char_range_key:nn #1#2 + { + \tl_if_blank:nTF {#2} + { \tl_set:Nn \l_@@_char_range_clist {#1} } + { + \clist_if_empty:NT \l_@@_char_range_clist + { + \tl_set:Nn \l_@@_tmp_tl { {#1} } + \@@_char_range_parse_feature:w #2 \q_stop + } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_char_range_parse_feature:w} +% 可以使用加方括号的方式,通过文件名来调用字体。这容易与字体选项混淆。例如,需要 +% 将 |[simsun.ttc]| 设置为 \opt{range} 的主字体,就需要使用 +% |range={{[simsun.ttc]}}| 或者 |[]{[simsun.ttc]}|。下面的目的是,支持直接使用 +% |[simsun.ttc]| 和 |[...][simsun.ttc]|。 +% \begin{macrocode} +\NewDocumentCommand \@@_char_range_parse_feature:w + { +o o u { \q_stop } } + { + \exp_args:NNf \tl_put_right:Nn \l_@@_tmp_tl + { + \IfNoValueTF {#1} { {#3} } + { + \IfNoValueTF {#2} + { \tl_if_blank:nTF {#3} { { [#1] } } { [ {#1} ] {#3} } } + { [ {#1} ] { [#2] } } + } + } + \seq_put_right:No \l_@@_alternate_seq { \l_@@_tmp_tl } + } +% \end{macrocode} +% \end{macro} +% +% \paragraph{其它设置} +% +% 在抄录环境中禁用 \opt{autospacing} 和 \opt{autoxspacing}。然而,\pkg{LuaTeX-ja} +% 还是会使 JAchar 自动折行。没有看到有简单的禁用折行的办法,可能需要设置所有的 +% JAchar 的 \opt{prebreakpenalty} 或 \opt{postbreakpenalty} 为 \texttt{10000}: +% \begin{verbatim} +% \directlua +% { +% luatexja.isglobal = tex.globaldefs > 0 and "global" or "" +% for i = 0x80, 0x10FFFF do +% if luatexja.charrange.jcr_table_main[i] > 0 and +% luatexja.charrange.jcr_table_main[i] < 218 and +% luatexja.charrange.is_japanese_char_curlist(i) then +% luatexja.stack.set_stack_table(luatexja.stack_table_index.PRE + i, 10000) +% end +% end +% } +% \end{verbatim} +% \begin{macrocode} +\AtBeginDocument + { + \ctex_appto_cmd:NnnTF \verbatim@font + { \char_set_catcode_letter:n { 64 } } + { \CTEX@verbatim@font@hook } + { } + { \ctex_patch_failure:N \verbatim@font } + } +\cs_new_protected_nopar:Npn \CTEX@verbatim@font@hook + { \ltjsetparameter { autospacing = false , autoxspacing = false } } +% \end{macrocode} +% +% \begin{macro}{\@@italiccorr} +% \LaTeX{} 的倾斜校正也要重新定义。 +% \begin{macrocode} +%<@@=> +\cs_set_eq:NN \@@italiccorr \/ +%<@@=ctex> +% \end{macrocode} +% \end{macro} +% +% \changes{v2.4.12}{2018/01/27}{正确使用 \tn{ltjsetkanjiskip} 和 \tn{ltjsetxkanjiskip}。} +% +% \begin{macro}[int]{\ctex_ltj_set_kanjiskip:N,\ctex_ltj_set_xkanjiskip:N} +% \tn{ltjsetkanjiskip} 和 \tn{ltjsetxkanjiskip} 是相应的 \tn{ltjsetparameter} +% 的快捷方式,在使用他们时,要注意先使用 \tn{ltj@setpar@global}。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_ltj_set_kanjiskip:N + { \ltj@setpar@global \ltjsetkanjiskip } +\cs_new_protected_nopar:Npn \ctex_ltj_set_xkanjiskip:N + { \ltj@setpar@global \ltjsetxkanjiskip } +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%</luatex> +% \end{macrocode} +% +% \subsubsection{\pkg{ctex-engine-uptex.def}} +% +% \begin{macrocode} +%<*uptex|aptex> +% \end{macrocode} +% +% \changes{v2.4}{2016/02/28}{初步支持 \upLaTeX。} +% \changes{v2.4.15}{2019/04/05}{显式补丁 \upLaTeX 的 \tn{rmfamily} 等字体命令。} +% +% 按 \pkg{CJK} 的命名习惯模拟部分命令,并设置默认字体。 +% \begin{macrocode} +\tl_set:Nn \CJKrmdefault { zhrm } +\tl_set:Nn \CJKsfdefault { zhsf } +\tl_set:Nn \CJKttdefault { zhtt } +\tl_set:Nn \CJKfamilydefault { \CJKrmdefault } +\tl_set:Nn \kanjifamilydefault { \CJKfamilydefault } +\RenewDocumentCommand \rmfamily { } + { + \not@math@alphabet \rmfamily \mathrm + \romanfamily \rmdefault + \kanjifamily \CJKrmdefault + \selectfont + } +\RenewDocumentCommand \sffamily { } + { + \not@math@alphabet \sffamily \mathsf + \romanfamily \sfdefault + \kanjifamily \CJKsfdefault + \selectfont + } +\RenewDocumentCommand \ttfamily { } + { + \not@math@alphabet \ttfamily \mathtt + \romanfamily \ttdefault + \kanjifamily \CJKttdefault + \selectfont + } +\NewDocumentCommand \CJKfamily { m } + { + \kanjifamily {#1} + \selectfont + } +% \end{macrocode} +% +% \changes{v2.4.15}{2019/04/05}{将 \upLaTeX 的默认字体由 \texttt{mc} 改为 +% \texttt{zhrm},并启用 \tn{jfam}。} +% +% 将 \upLaTeX 的默认字体由 |mc| 改为 |zhrm|,并启用 \tn{jfam}。 +% \begin{macrocode} +\DeclareErrorKanjiFont{JY2}{zhrm}{m}{n}{10} +\DeclareKanjiSubstitution{JY2}{zhrm}{m}{n} +\DeclareKanjiSubstitution{JT2}{zhrm}{m}{n} +\DeclareSymbolFont{mincho}{JY2}{zhrm}{m}{n} +\SetSymbolFont{mincho}{bold}{JY2}{zhrm}{bx}{n} +\jfam \symmincho +% \end{macrocode} +% +% 在导言区末尾更新 \tn{CJKfamilydefault}。 +% \begin{macrocode} +\ctex_at_end_preamble:n { \ctex_update_default_family: } +% \end{macrocode} +% +% 使修改立刻生效,保证导言区字体族正确。 +% \begin{macrocode} +\normalfont +% \end{macrocode} +% +% \begin{macro}[int]{\em} +% \changes{v2.4.2}{2016/05/15}{兼容 \upLaTeX{} 2016/05/07u00 的定义。} +% 取消 \upLaTeX{} 对 \tn{em} 使用 |\mcfamily|、|\gtfamily| 命令的重定义,恢复 +% \LaTeXe{} 对 \tn{em} 的原始定义。如果用户已经重定义了 \tn{em},则新定义保持 +% 不变。\upLaTeX{} 2016/05/07u00 的定义有所变化,这一行为可以由用户通过 \pkg{platexrelease} +% 包改变,需要分支处理。 +% \begin{macrocode} +\ctex_patch_cmd_once:NnnnTF \em + { \ExplSyntaxOff } + { \eminnershape \else \gtfamily \itshape } + { \eminnershape \else \itshape } + { } + { + \ctex_patch_cmd:Nnn \em + { \mcfamily \upshape \else \gtfamily \itshape } + { \eminnershape \else \itshape } + } +\cs_set_nopar:Npn \eminnershape { \upshape } +% \end{macrocode} +% \end{macro} +% +% \changes{v2.4}{2016/04/24}{正确设置 \upTeX{} 下字体命令。} +% \begin{macro}[int]{\ctex_set_upfamily:nnn} +% 将 NFSS 字体族 |#1| 设置为 JFM 字体名 |#2|,粗体形式字体名 |#3|。其中字体名 +% 形如 |upzhserif|,不包括表示方向的后缀 |-h| 与 |-v|。粗体字体名为空时不设置该 +% 字形。本命令不设置字体映射,需要复用已有的字体映射或另行设置。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_set_upfamily:nnn #1 #2 #3 + { + \DeclareKanjiFamily{JY2}{#1}{} + \DeclareKanjiFamily{JT2}{#1}{} + \DeclareFontShape{JY2}{#1}{m}{n}{<->~ #2-h}{} + \DeclareFontShape{JT2}{#1}{m}{n}{<->~ #2-v}{} + \tl_if_empty:nF { #3 } + { + \DeclareFontShape{JY2}{#1}{bx}{n}{<->~ #3-h}{} + \DeclareFontShape{JT2}{#1}{bx}{n}{<->~ #3-v}{} + } + } +\@onlypreamble \ctex_set_upfamily:nnn +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_set_upmap:nnn} +% 设置 \upTeX{} 字体映射。|#1| 是形如 |upserif| 的 PS TFM 字体名,不带表示粗体 +% 的后缀 |b| 与表示排版方向的后缀 |-h| 与 |-v|。|#2| 与 |#3| 是普通与粗体的实际 +% 字体名。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_set_upmap:nnn #1 #2 #3 + { + \ctex_set_zhmap:n + { + \special{ pdf:mapline~ #1-h~ UniGB-UTF16-H~ #2 } + \special{ pdf:mapline~ #1-v~ UniGB-UTF16-V~ #2 } + \tl_if_empty:nF { #3 } + { + \special{ pdf:mapline~ #1b-h~ UniGB-UTF16-H~ #3 } + \special{ pdf:mapline~ #1b-v~ UniGB-UTF16-V~ #3 } + } + } + } +\@onlypreamble \ctex_set_upmap:nnn +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_set_upfonts:nnnnnn} +% 设置 \upTeX{} 基本字体映射,按 \pkg{zhmetrics-uptex} 的定义,依次设置衬线体 +% 正、粗、意大利,无衬线体正、粗,等宽体正——共 6 种字体,并分横排及直排。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_set_upfonts:nnnnnn #1 #2 #3 #4 #5 #6 + { + \ctex_set_upmap:nnn { upserif } { #1 } { #2 } + \ctex_set_upmap:nnn { upserifit } { #3 } {} + \ctex_set_upmap:nnn { upsans } { #4 } { #5 } + \ctex_set_upmap:nnn { upmono } { #6 } {} + } +\@onlypreamble \ctex_set_upfonts:nnnnnn +% \end{macrocode} +% \end{macro} +% +% \changes{v2.4.7}{2016/12/27}{依赖 \pkg{pxeverysel} 宏包。} +% +% \pkg{everysel} 宏包(2011/10/28)未考虑 \upLaTeX{} 对 \tn{selectfont} 的修 +% 改,需要引入 \pkg{pxeverysel} 宏包。 +% \begin{macrocode} +\RequirePackage { pxeverysel } +% \end{macrocode} +% +% \begin{macrocode} +%</uptex|aptex> +% \end{macrocode} +% +% \subsubsection{调整 \tn{CJKfamilydefault}} +% +% \changes{v2.4}{2016/02/15}{正确更新 \pkg{CJK} 包的 \tn{CJKfamilydefault}。} +% \changes{v2.4.1}{2016/04/26}{正确更新 \upLaTeX{} 的 \tn{CJKfamilydefault}。} +% +% \begin{macro}[int]{\ctex_update_default_family:} +% 在导言区结束,如果 \tn{CJKfamilydefault} 没有被更改,则在此时根据西文字体的情况 +% 更新 \tn{CJKfamilydefault}。\pkg{xeCJK} 已经有这个功能,不需要再调整。 +% \begin{macrocode} +%<*pdftex|luatex|uptex|aptex> +\cs_new_protected_nopar:Npn \ctex_update_default_family: + { + \tl_if_eq:NNT \CJKfamilydefault \l_@@_family_default_init_tl + { + \group_begin: + \cs_set_eq:NN \@@_family_default_wrap:n \exp_not:n + \tl_gset:Nx \CJKfamilydefault + { + \str_case:onF { \familydefault } + { + { \rmdefault } { \exp_not:N \CJKrmdefault } + { \sfdefault } { \exp_not:N \CJKsfdefault } + { \ttdefault } { \exp_not:N \CJKttdefault } + } + { \CJKfamilydefault } + } + \group_end: + } +% \end{macrocode} +% 使用 \LuaLaTeX{} 时,自动调整得到的 \tn{CJKfamilydefault} 可能没有定义,需要 +% 确认它的存在性。使用 \pkg{CJK} 宏包或 \upLaTeX{} +% 时,\texttt{C19rm}、\texttt{JY2rm} 等总是有定义的,不需要确认。 +% \begin{macrocode} +%<*luatex> + \ctex_ltj_ensure_default_family: +%</luatex> + } +% \end{macrocode} +% \end{macro} +% +% \begin{variable}{\l_@@_family_default_init_tl} +% 往 \tn{CJKfamilydefault} 中加入标志,用于判断它是否被更改。 +% \begin{macrocode} +\tl_new:N \l_@@_family_default_init_tl +\cs_new_eq:NN \@@_family_default_wrap:n \use:n +\tl_set:Nx \l_@@_family_default_init_tl + { + \exp_not:N \@@_family_default_wrap:n + { \exp_not:o { \CJKfamilydefault } } + } +\tl_gset_eq:NN \CJKfamilydefault \l_@@_family_default_init_tl +%</pdftex|luatex|uptex|aptex> +% \end{macrocode} +% \end{variable} +% +% \subsubsection{操作系统的判断} +% +% \changes{v2.0}{2014/04/16}{自动检测操作系统,载入对应的字体配置。} +% +% \begin{macro}[int]{\ctex_detected_platform:} +% 在 \LuaTeX{} 下直接用调用 |os.name| 来判断。 +% \begin{macrocode} +%<*luatex> +\cs_new_protected_nopar:Npn \ctex_detected_platform: + { + \tl_gset:Nx \g_@@_fontset_tl + { + \lua_now:e + { + if ~ os.name == 'windows' then ~ + tex.sprint ( 'windows' ) + elseif ~ os.name == 'macosx' then ~ + tex.sprint ( 'mac' ) + else ~ + tex.sprint ( 'fandol' ) + end + } + } + } +%</luatex> +% \end{macrocode} +% +% \ApTeX{} 可以使用 \tn{ngostype} 来判断。 +% \begin{macrocode} +%<*aptex> +\cs_new_protected_nopar:Npn \ctex_detected_platform: + { + \tl_gset:Nx \g_@@_fontset_tl + { + \str_case:onF { \ngostype } + { + { Win32 } { windows } + { Win64 } { windows } + { Darwin } { mac } + } + { fandol } + } + } +%</aptex> +% \end{macrocode} +% +% \pdfTeX{} 和 \XeTeX{} 下则依据 \file{/dev/null} 和 \file{nul:} 的存在性以及 +% 文件系统的大小写敏感性来判断。Mac~OS~X 的大小写敏感性在安装时是可选的。为了 +% 保险起见,这里的判断很繁琐,最多要进行 4 次文件操作! +% \begin{macrocode} +%<*xetex|pdftex|uptex> +\cs_new_protected_nopar:Npn \ctex_detected_platform: + { + \file_if_exist:nTF { /dev/null } + { + \file_if_exist:nTF { nul: } + { + \file_if_exist:nTF { \c_@@_upper_case_file_str } + { \ctex_if_macosx:TF { mac } { windows } } + { \ctex_if_macosx:TF { mac } { fandol } } + } + { \ctex_if_macosx:TF { mac } { fandol } } + } + { \tl_gset:Nn \g_@@_fontset_tl { windows } } + } +\str_const:Nx \c_@@_upper_case_file_str + { \exp_args:No \str_upper_case:n { \g_file_curr_name_str } } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_if_macosx:TF} +% \changes{v2.1}{2015/06/17}{改用 \file{/Library/Fonts/Songti.ttc} 为特征文件。} +% 以 \file{/Library/Fonts/Songti.ttc} 为特征文件判断 Mac~OS~X。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_if_macosx:TF #1#2 + { + \file_if_exist:nTF { \c_@@_macosx_file_str } + { \tl_gset:Nn \g_@@_fontset_tl {#1} } + { \tl_gset:Nn \g_@@_fontset_tl {#2} } + } +\str_const:Nn \c_@@_macosx_file_str { /Library/Fonts/Songti.ttc } +%</xetex|pdftex|uptex> +% \end{macrocode} +% \end{macro} +% +% \subsubsection{\pkg{hyperref} 兼容性处理} +% +% \changes{v2.1}{2015/06/16}{不再设置 \pkg{hyperref} 宏包的 \opt{colorlinks} 选项。} +% +% 现在处理各个引擎下的 PDF 中文书签问题。根据编译引擎与文件编码的不 +% 同,\pkg{ctex} 向 \pkg{hyperref} 传递适当的参数,完成中文书签的正确设置。用 +% 户仍需要自己载入 \pkg{hyperref} 宏包。 +% +% \begin{macro}[int]{\ctex_hypersetup:n} +% 如果已经载入 \pkg{hyperref} 宏包,则直接使用其定义设置选项;否则 +% \cs{ctex_hypersetup:n} 的效果与 \tn{PassOptionsToPackage} 一致,只传递宏包参 +% 数。如果用户不载入 \pkg{hyperref} 宏包,相关参数即被丢弃。 +% \begin{macrocode} +%<*class|ctex> +\@ifpackageloaded { hyperref } + { + \cs_new_protected_nopar:Npn \ctex_hypersetup:n #1 + { \hypersetup {#1} } + } + { + \cs_new_protected_nopar:Npn \ctex_hypersetup:n #1 + { \PassOptionsToPackage {#1} { hyperref } } + } +%</class|ctex> +% \end{macrocode} +% \end{macro} +% +% 在 \pdfTeX{} 下使用 \texttt{GBK} 编码,\dvipdfmx{} 驱动可以直接用它的 +% \tn{special} 命令,其它模式用 \pkg{xCJK2uni} 宏包处理。使用 \texttt{UTF-8} 编 +% 码时,\pkg{CJKutf8} 已经处理了书签问题,但仍需要设置 \opt{pdfencoding} 为 +% \opt{unicode},目的是在书签的开头写入 BOM (|\376\377|),提示这是 +% \texttt{UTF-16BE} 字节流。 +% \begin{macrocode} +%<*pdftex> +\ctex_hypersetup:n { driverfallback = dvipdfmx } +\str_if_eq:onTF { \l_@@_encoding_tl } { GBK } + { + \ctex_hypersetup:n { CJKbookmarks = true } + \sys_if_output_pdf:TF + { \ctex_at_end_package:nn { hyperref } { \RequirePackage { xCJK2uni } } } + { + \ctex_at_end_package:nn { hyperref } + { + \str_if_eq:onTF { \Hy@driver } { hdvipdfm } + { + \AtBeginShipoutFirst + { \special { pdf:tounicode~GBK-EUC-UCS2 } } + } + { \RequirePackage { xCJK2uni } } + } + } + } + { \ctex_hypersetup:n { pdfencoding = unicode } } +%</pdftex> +% \end{macrocode} +% 在 \XeTeX{} 下,\pkg{hyperref} 在处理带有非 ASCII 字符和 |\%| 的书签时有问题^^A +% \footnote{\url{https://github.com/CTeX-org/ctex-kit/issues/39}}。 +% 事实上,\pkg{hyperref} 在驱动文件 \file{hxetex.def} 中设置了 +% \tn{Hy@unicodetrue},从而书签总是会被 \tn{HyPsd@ConvertToUnicode} 转化成 +% \texttt{UTF-16BE} 编码的形式(抄录自 \tn{pdfstringdef}的定义): +% \begin{verbatim} +% \ifHy@unicode +% \HyPsd@ConvertToUnicode#1% +% \ifx\HyPsd@pdfencoding\HyPsd@pdfencoding@auto +% \ltx@IfUndefined{StringEncodingConvertTest}{% +% }{% +% \EdefUnescapeString\HyPsd@temp#1% +% \ifxetex +% \let\HyPsd@UnescapedString\HyPsd@temp +% \StringEncodingConvertTest\HyPsd@temp\HyPsd@temp +% {utf16be}{ascii-print}{% +% \EdefEscapeString\HyPsd@temp\HyPsd@temp +% \global\let#1\HyPsd@temp +% \HyPsd@EscapeTeX#1% +% \Hy@unicodefalse +% }{% +% \HyPsd@ToBigChars#1% +% }% +% \end{verbatim} +% 通过宏包选项 \opt{pdfencoding=unicode} 设置 \tn{HyPsd@pdfencoding} 为 +% \opt{unicode},可以避免随后再将书签从 \texttt{UTF-16BE} 字节流转化回正常 +% 字符(其中使用的 \tn{HyPsd@ToBigChars} 没有考虑书签中含有 |\%| 的情况)。 +% Heiko Oberdiek 在 \file{README} 中说明了将书签转化回正常字符的意图:避免 +% XDVIPDFMX 的警告^^A +% \footnote{\url{http://project.ktug.org/dvipdfmx/mailman/dvipdfmx/2009-December/000153.html}}: +% \begin{verbatim} +% ** WARNING ** Failed to convert input string to UTF16... +% \end{verbatim} +% \XeTeX{} 的维护者 Khaled Hosny 已经注意到了这个问题^^A +% \footnote{\url{http://tug.org/pipermail/tex-live/2013-December/034613.html}}。 +% 需要注意的是,\file{hxetex.def} 重载了宏包选项 \opt{unicode},目的是不能设置 +% 它为 \opt{false},但也导致它不会改变 \tn{HyPsd@pdfencoding}。如果 +% \pkg{hyperref} 先于 \CTeX{} 被载入,那么 \opt{unicode} 选项是没有意义的。 +% 因此要通过意义相同但在 \XeTeX{} 下更保险的 \opt{pdfencoding} 选项来设置。 +% 为了与 \XeTeX 下的行为一致(使用 \tn{HyPsd@LoadUnicode} 载入 \file{puenc.def}), +% 在 \LuaTeX{} 下也启用这个选项。 +% \begin{macrocode} +%<*xetex|luatex> +\ctex_hypersetup:n { pdfencoding = unicode } +%</xetex|luatex> +% \end{macrocode} +% +% 我们假定 \upTeX{} 使用 \dvipdfmx{} 驱动输出,于是使用与 \pdfTeX{} 类似的设 +% 置。注意 \upTeX{} 需要使用 UTF8-UTF16 的编码转换。 +% \begin{macrocode} +%<*uptex|aptex> +\ctex_hypersetup:n { driverfallback = dvipdfmx } +\ctex_at_end_package:nn { hyperref } + { \AtBeginShipoutFirst { \special { pdf:tounicode~ UTF8-UTF16 } } } +%</uptex|aptex> +% \end{macrocode} +% +% \begin{macrocode} +%<*pdftex|xetex|luatex|uptex|aptex> +% \end{macrocode} +% +% \subsubsection{\pkg{CJKfntef}、\pkg{xeCJKfntef} 相关设置} +% +% \CTeX{} 宏集对 \pdfTeX{} 与 \XeTeX{} 引擎,分别载入 \pkg{CJKfntef} 或 +% \pkg{xeCJKfntef} 宏包,并关闭宏包默认的彩色等多余格式。 +% +% \changes{v2.0}{2015/03/25}{默认关闭 \pkg{CJKfntef} 或 \pkg{xeCJKfntef} 的彩 +% 色设置。} +% \changes{v2.0}{2015/03/25}{\tn{CTEXunderdot}, \tn{CTEXunderline}, +% \tn{CTEXunderdblline}, \tn{CTEXunderwave}, \tn{CTEXsout}, \tn{CTEXxout} 是过 +% 时命令;\env{CTEXfilltwosides} 是过时环境。} +% +% 载入 \pkg{CJKfntef} 或 \pkg{xeCJKfntef} 并做适当格式设置。有关 |\CTEX| 开头 +% 的宏定义是过时命令,仅做兼容性保留。 +% +% \begin{macrocode} +%<*pdftex> +\RequirePackage { CJKfntef } +\normalem +\cs_new_protected_nopar:Npn \@@_clear_fntef_color:n #1 + { \tl_clear:c { CJK#1color } } +%</pdftex> +%<*xetex> +\RequirePackage { xeCJKfntef } +\@ifpackagelater { xeCJKfntef } { 2014/11/04 } + { + \cs_new_protected_nopar:Npn \@@_clear_fntef_color:n #1 + { \xeCJKsetup { #1 / format = { } } } + } + { + \cs_new_protected_nopar:Npn \@@_clear_fntef_color:n #1 + { \tl_clear:c { CJK#1color } } + } +%</xetex> +%<*luatex|uptex|aptex> +\msg_new:nnn { ctex } { fntef-not-available } +%<luatex> { Functions~ of~ `CJKfntef'~ is~ not~ available~ in~ LuaLaTeX. } +%<uptex> { Functions~ of~ `CJKfntef'~ is~ not~ available~ in~ upLaTeX. } +%<aptex> { Functions~ of~ `CJKfntef'~ is~ not~ available~ in~ ApLaTeX. } +\msg_warning:nn { ctex } { fntef-not-available } +%</luatex|uptex|aptex> +\clist_map_inline:nn + { underdot , underline , underdblline , underwave , sout , xout } +%<*pdftex|xetex> + { + \@@_clear_fntef_color:n {#1} + \cs_new_protected_nopar:cpx { CTEX#1 } + { + \msg_warning:nnnn { ctex } { deprecated-command } { \exp_not:c { CTEX#1 } } + { You~ can~ use~ the~ command~ with~ prefix~ \exp_not:N \CJK~ instead. } + \exp_not:c { CJK#1 } + } + } +\cs_new_protected_nopar:Npn { \CTEXfilltwosides } + { + \msg_warning:nnnn { ctex } { deprecated-environment } { CTEXfilltwosides } + { You~ can~ use~ `CJKfilltwosides'~ environment~ instead. } + \CJKfilltwosides + } +\cs_new_protected_nopar:Npn { \endCTEXfilltwosides } { \endCJKfilltwosides } +%</pdftex|xetex> +%<*luatex|uptex|aptex> + { \cs_new_eq:cN { CTEX#1 } \use:n } +\cs_new_eq:NN \CTEXfilltwosides \use_none:n +\cs_new_eq:NN \endCTEXfilltwosides \prg_do_nothing: +%</luatex|uptex|aptex> +%<*pdftex> +\clist_map_inline:nn + { + underdotbasesep , underdotsep , underlinebasesep , + underlinesep , underdbllinesep , underdbllinebasesep , + underwavebasesep , underwavesep , southeight , + underdotcolor , underwavecolor , underlinecolor , + underdbllinecolor , soutcolor , xoutcolor + } + { + \cs_new_eq:cc { CTEX#1 } { CJK#1 } + \cs_set_nopar:cpx { CJK#1 } { \exp_not:c { CTEX#1 } } + } +%</pdftex> +% \end{macrocode} +% +% \subsubsection{\tn{ccwd} 的更新} +% +% \begin{macro}[int]{\ctex_update_ccwd:,\ccwd} +% \changes{v2.4.1}{2016/04/29}{正确设置 \upTeX{} 下的 \tn{ccwd}。} +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_update_ccwd: +%<*pdftex|xetex> + { + \hbox_set:Nn \l_@@_tmp_box { \CJKglue } + \dim_set:Nn \ccwd { \box_wd:N \l_@@_tmp_box + \f@size \p@ } + } +%</pdftex|xetex> +%<*luatex> + { \skip_set:Nn \ccwd { \ltjgetparameter { kanjiskip } + \zw } } +%</luatex> +%<*uptex|aptex> + { \skip_set:Nn \ccwd { 1zw + \tex_kanjiskip:D } } +%</uptex|aptex> +\dim_new:N \ccwd +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_update_ccglue:} +% 更新字间距。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_update_ccglue: +%<*pdftex|xetex> + { + \cs_set_protected_nopar:Npn \CJKglue + { \skip_horizontal:N \l_@@_ccglue_skip } + } +%</pdftex|xetex> +%<*luatex> + { \ctex_ltj_set_kanjiskip:N \l_@@_ccglue_skip } +%</luatex> +%<*uptex|aptex> + { \skip_set_eq:NN \tex_kanjiskip:D \l_@@_ccglue_skip } +%</uptex|aptex> +\skip_new:N \l_@@_ccglue_skip +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int,pTF]{\ctex_if_ccglue_touched:} +% 检查用户是否修改过汉字间距。 +% \begin{macrocode} +\prg_new_conditional:Npnn \ctex_if_ccglue_touched: { TF } + { +%<*pdftex|xetex> + \if_meaning:w \CJKglue \@@_ccglue: + \prg_return_false: \else: \prg_return_true: \fi: +%</pdftex|xetex> +%<*luatex> + \skip_if_eq:nnTF { \l_@@_ccglue_skip } { \ltjgetparameter { kanjiskip } } + { \prg_return_false: } { \prg_return_true: } +%</luatex> +%<*uptex|aptex> + \skip_if_eq:nnTF { \l_@@_ccglue_skip } { \tex_kanjiskip:D } + { \prg_return_false: } { \prg_return_true: } +%</uptex|aptex> + } +% \end{macrocode} +% 注意下面的标记不能用 \verb"%<pdftex|xetex>",它会导致旧版本的 \pkg{l3docstrip} +% 不能替换 \texttt{@@}。 +% \begin{macrocode} +%<*pdftex|xetex> +\ctex_at_end:n { \cs_new_eq:NN \@@_ccglue: \CJKglue } +%</pdftex|xetex> +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_update_em_unit:} +% 将当前汉字的宽度保存到 \tn{ccwd} 中备用。不采用 \texttt{1em},因为这时的 +% \texttt{1em} 实际上来自西文字体的信息,未必等于汉字的宽度,这似乎在传统的 +% \file{.tfm} 字体上表现更明显。在 \pdfTeX{} 和 \XeTeX{} 下,直接使用 |\f@size\p@| +% 作为汉字的宽度,这应该对大多数汉字字体都成立,但不适用于诸如“方正兰亭黑长”之类 +% 的特殊字体。在 \XeTeX{} 可以用 \tn{fontcharwd} 来改进。而在 \pdfTeX{} 下,若使用 +% \pkg{zhmetrics} 技术,所有的汉字共享同一个 \file{.tfm},\tn{fontcharwd} 也就没有 +% 意义。在 \LuaTeX{} 下,\pkg{LuaTeX-ja} 总是按照 JFM 中的设置输出汉字的宽度,可以 +% 直接用 \tn{zw} 作为汉字宽度。\upTeX{} 可以直接使用原生的长度单位 |zw|。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_update_em_unit: +%<pdftex|xetex> { \dim_set:Nn \ccwd { \f@size \p@ } } +%<luatex> { \dim_set:Nn \ccwd { \zw } } +%<uptex|aptex> { \dim_set:Nn \ccwd { 1zw } } +% \end{macrocode} +% \end{macro} +% +% \subsubsection{其它} +% +% \changes{v2.4.13}{2018/03/23}{修正导言区 \tn{selectfont} 钩子位置。} +% +% \begin{macro}[int]{\ctex_add_to_selectfont:n,\CTEX@selectfont@hook} +% \tn{EverySelectfont} 直到文档开始时才有效。为了 \tn{ccwd} 和 \pkg{LuaTeX-ja} 的 +% 字体设置在导言区也可用,我们还需要在这里手工修改 \tn{selectfont}。\pkg{everysel} +% 宏包会用 \tn{CheckCommand} 来检查 \tn{selectfont} 是否为标准定义。我们修改了 +% \tn{selectfont},所以会给出一个警告。为了消除这个警告,在它检查之前,还原本来 +% 定义。\pkg{pxeverysel} 宏包取消了检查,但也需要恢复定义,避免重复使用钩子。 +% \begin{macrocode} +\cs_new_protected:Npn \ctex_add_to_selectfont:n #1 + { + \cs_set_protected_nopar:Npx \CTEX@selectfont@hook + { \exp_not:o { \CTEX@selectfont@hook #1 } } + } +\cs_new_eq:NN \CTEX@selectfont@hook \prg_do_nothing: +\if_cs_exist:N \@EverySelectfont@Init + \group_begin: + \cs_set:Npn \@@_tmp:N #1 + { + \tl_set:Nn \l_@@_tmp_tl {#1} + \cs_new_eq:NN \CTEX@selectfont@save #1 + \cs_new_protected_nopar:Npn \@@_restore_selectfont: + { + \tl_put_left:Nn \@EverySelectfont@Init + { \let #1 \CTEX@selectfont@save } + \cs_undefine:N \@@_restore_selectfont: + } + } + \ctex_parse_name:NN \@@_tmp:N \selectfont + \exp_last_unbraced:NNo \group_end: + \ctex_patch_cmd_once:NnnnTF { \l_@@_tmp_tl } + { \ExplSyntaxOff } + { \size@update } + { \CTEX@selectfont@hook \size@update } + { \@@_restore_selectfont: } + { \ctex_patch_failure:N \selectfont } +\fi: +% \end{macrocode} +% \end{macro} +% +% \tn{CJK@plane} 有定义,说明处于 \pkg{CJK} 宏包的 \tn{CJKsymbol} 之内,不必使用钩子。 +% \begin{macrocode} +%<*pdftex> +\EverySelectfont { \cs_if_exist:NF \CJK@plane { \CTEX@selectfont@hook } } +%</pdftex> +%<*xetex|luatex|uptex|aptex> +\EverySelectfont { \CTEX@selectfont@hook } +%</xetex|luatex|uptex|aptex> +% \end{macrocode} +% +% Attribute 寄存器 \tn{ltj@curjfnt} 的初始值是 $-1$,必须把它设置为一个有效的 +% \texttt{font.id},否则编译时会直接退出。 +% \begin{macrocode} +%<*luatex> +\ctex_add_to_selectfont:n + { + \ctex_ltj_select_font: + \ctex_ltj_select_alternate_font: + } +\tl_set:Nn \CJK@family { song } \selectfont +\tl_clear:N \CJK@family +%</luatex> +% \end{macrocode} +% +% \changes{v2.4.1}{2016/05/01}{随字体更新 \upTeX{} 的 \tn{xkanjiskip}。} +% +% \begin{macro}[int]{\ctex_update_xkanjiskip:} +% \begin{variable}{\l_@@_xkanjiskip_skip} +% \upTeX{} 和 \pkg{LuaTeX-ja} 对 \tn{xkanjiskip} 都是即时赋值。单位 \opt{zw} 与字体相关,因此 +% 需要每次 \tn{selectfont} 的时候更新一次 \tn{xkanjiskip}。如果用户设置过 +% \tn{xkanjiskip},就不更新。注意,同 \TeX{} 的 \tn{baselineskip} 一样,如果在 +% 一个段落内多次设置了 \tn{kanjiskip} 或 \tn{xkanjiskip},只有最后的设置会影响 +% 全段。 +% \begin{macrocode} +%<*luatex|uptex|aptex> +\cs_new_protected_nopar:Npn \ctex_update_xkanjiskip: + { + \skip_if_eq:nnT +%<luatex> { \ltjgetparameter { xkanjiskip } } { \l_@@_xkanjiskip_skip } +%<uptex|aptex> { \tex_xkanjiskip:D } { \l_@@_xkanjiskip_skip } + { + \skip_set:Nn \l_@@_xkanjiskip_skip { \l_@@_xkanjiskip_tl } +%<luatex> \ctex_ltj_set_xkanjiskip:N \l_@@_xkanjiskip_skip +%<uptex|aptex> \skip_set_eq:NN \tex_xkanjiskip:D \l_@@_xkanjiskip_skip + } + } +\tl_new:N \l_@@_xkanjiskip_tl +\tl_set:Nn \l_@@_xkanjiskip_tl +%<luatex> { .25\zw plus 1pt minus 1pt } +%<uptex|aptex> { .25zw plus 1pt minus 1pt } +\skip_new:N \l_@@_xkanjiskip_skip +\skip_set:Nn \l_@@_xkanjiskip_skip +%<luatex> { \ltjgetparameter { xkanjiskip } } +%<uptex|aptex> { \tex_xkanjiskip:D } +% \end{macrocode} +% \end{variable} +% \end{macro} +% +% \begin{macrocode} +\ctex_add_to_selectfont:n { \ctex_update_xkanjiskip: } +%</luatex|uptex|aptex> +% \end{macrocode} +% +% \changes{v2.4.10}{2017/07/23}{定义 \tn{cht},\tn{cdp} 和 \tn{cwd}。} +% +% \begin{macro}[int]{\cht,\cdp,\cwd} +% 分别从 \file{.jfm} 中读取字符高度、深度和宽度,目前仅考虑横排的情况。 +% \begin{macrocode} +%<*luatex> +\dim_new:N \cht +\dim_new:N \cdp +\dim_new:N \cwd +\newluafunction \g_@@_kanjisize_func +\group_begin: +\char_set_catcode_space:n { 32 } +\lua_now:e + { + local nulltable = { } + local t = lua.get_functions_table() + local fmt = luatexja.jfont.font_metric_table + local getattribute = tex.getattribute + local setdimen = tex.setdimen + t[\int_use:N \g_@@_kanjisize_func] = function () + local ft = fmt[getattribute('ltj@curjfnt')] or nulltable + local ft = ft and ft.char_type or nulltable + local fk = ft and ft[0] or nulltable + setdimen('cht', fk.height or 0) + setdimen('cdp', fk.depth or 0) + setdimen('cwd', fk.width or ft.zw or 0) + end + } +\group_end: +\cs_new_protected_nopar:Npn \ctex_update_kanjisize: + { \tex_luafunction:D \g_@@_kanjisize_func } +\ctex_add_to_selectfont:n { \ctex_update_kanjisize: } +%</luatex> +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{space} +% 在导言区或正文中设置忽略空格方式。 +% \pdfTeX{} 和 \XeTeX{} 下初始设置为 \opt{auto},\LuaTeX{}、\upTeX{} 下是无效 +% 选项。 +% \begin{macrocode} +\keys_define:nn { ctex } + { +%<*pdftex|xetex> + space .choice: , + space / true .code:n = +%<pdftex> { \ctex_ignorespaces_case:N \prg_do_nothing: } , +%<xetex> { \xeCJKsetup { CJKspace = true } } , + space / auto .code:n = +%<pdftex> { \ctex_ignorespaces_case:N \ctex_auto_ignorespaces: } , +%<xetex> { \xeCJKsetup { CJKspace = false } } , + space / false .code:n = +%<pdftex> { \ctex_ignorespaces_case:N \tex_ignorespaces:D } , +%<xetex> { \xeCJKsetup { CJKspace = false } } , + space .default:n = { true } , + space .initial:n = { auto } +%</pdftex|xetex> +%<*luatex|uptex|aptex> + space .code:n = + { \msg_warning:nn { ctex } { invalid-option } } +%</luatex|uptex|aptex> + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{punct} +% 在导言区或正文中设置标点符号输出格式。\pkg{LuaTeX-ja} 设置的是字体的默认 \texttt{JFM}, +% 只会影响到之后设置的字体。\upTeX{} 暂时无效。 +% \begin{macrocode} +\keys_define:nn { ctex } + { + punct .code:n = + { + \tl_set:Nx \l_@@_punct_tl { #1 } +%<pdftex> \punctstyle { \l_@@_punct_tl } +%<xetex> \xeCJKsetup { PunctStyle = \l_@@_punct_tl } +%<luatex> \ctex_mono_jfm:o { \l_@@_punct_tl } +%<uptex|aptex> \msg_warning:nn { ctex } { invalid-option } + } , + punct .default:n = { quanjiao } , + } +% \end{macrocode} +% \end{macro} +% +% \XeLaTeX{}、\LuaLaTeX{} 和 \upLaTeX{} 总是使用 \texttt{UTF8} 编码。 +% \begin{macrocode} +%<*xetex|luatex|uptex|aptex> +\tl_set:Nn \l_@@_encoding_tl { UTF8 } +%</xetex|luatex|uptex|aptex> +% \end{macrocode} +% +% \begin{macrocode} +%</pdftex|xetex|luatex|uptex|aptex> +% \end{macrocode} +% +% \subsubsection{载入引擎定义文件} +% +% 最后载入各个编译引擎的定义文件。 +% \begin{macrocode} +%<class|ctex>\ctex_file_input:n { \c_@@_engine_file_str } +% \end{macrocode} +% +% \subsection{用户设置接口} +% +% \changes{v2.0}{2014/03/18}{新增统一设置接口 \tn{ctexset}。} +% \changes{v2.4.12}{2018/01/14} +% {修正 \tn{ctexset} 在 \pkg{ctexheading} 包中无定义的错误(曾祥东)。 } +% +% \begin{macro}{\ctexset} +% \begin{macrocode} +%<*class|ctex|ctexheading> +\NewDocumentCommand \ctexset { } { \keys_set:nn { ctex } } +%</class|ctex|ctexheading> +% \end{macrocode} +% \end{macro} +% +% \changes{v2.0}{2015/03/21}{\tn{CTEXsetup}, \tn{CTEXoptions} 是过时命令。} +% \begin{macro}{\CTEXsetup,\CTEXoptions} +% 过时命令。出于历史原因,\tn{CTEXoptions} 需要在 \pkg{pxeverysel} 宏包之后定义。 +% \begin{macrocode} +%<*class|ctex> +\NewDocumentCommand \CTEXsetup { +o > { \TrimSpaces } m } + { + \msg_warning:nnnn { ctex } { deprecated-command } { \CTEXsetup } + { \ctexset~ {~ #2~ =~ {~ #1~ }~ }~ is~ set. } + \IfNoValueF {#1} { \keys_set:nn { ctex / #2 } {#1} } + } +\NewDocumentCommand \CTEXoptions { +o } + { + \msg_warning:nnnn { ctex } { deprecated-command } { \CTEXoptions } + { \ctexset~ {~ #1~ }~ is~ set. } + \IfNoValueF {#1} { \keys_set:nn { ctex } {#1} } + } +% \end{macrocode} +% \end{macro} +% +% \subsection{字距与缩进} +% +% \begin{macro}{autoindent} +% \opt{autoindent} 也是可以用在正文中的选项,意义与宏包选项 |option/autoindent| 相同。 +% \begin{macrocode} +\keys_define:nn { ctex } + { + autoindent .choice: , + autoindent .default:n = { true } , + autoindent / true .code:n = + { + \tl_set:Nn \l_@@_autoindent_tl { 2 \ccwd } + \ctex_select_size: + } , + autoindent / false .code:n = + { \tl_clear:N \l_@@_autoindent_tl } , + autoindent / unknown .code:n = + { + \ctex_set_default_ccwd:Nn \l_@@_autoindent_tl {#1} + \ctex_select_size: + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\CTEXsetfont} +% 无论字体大小是否变化都更新相关信息。 +% \begin{macrocode} +\NewDocumentCommand \CTEXsetfont { } { \ctex_select_size: } +\cs_new_protected_nopar:Npn \ctex_select_size: + { \cs_if_free:NTF \size@update { \ctex_update_size: } { \selectfont } } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_update_size:} +% 在字号变化时更新 \tn{ccwd}、\tn{parindent} 和汉字间距。字距为零则恢复正常设置。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_update_size: + { + \tl_if_eq:NNTF \l_@@_ziju_tl \c_@@_zero_tl + { + \ctex_update_stretch: + \ctex_update_parindent: + } + { \ctex_update_ziju: } + } +\tl_const:Nx \c_@@_zero_tl { \fp_use:N \c_zero_fp } +\tl_new:N \l_@@_ziju_tl +\tl_set_eq:NN \l_@@_ziju_tl \c_@@_zero_tl +% \end{macrocode} +% 在 \tn{selectfont} 中,若 \tn{size@update} 为 \tn{relax},说明字体大小没有变化, +% 我们也就不用更新相关参数。 +% \begin{macrocode} +\ctex_add_to_selectfont:n + { \cs_if_free:NF \size@update { \ctex_update_size: } } +% \end{macrocode} +% \end{macro} +% +% \changes{v2.0}{2014/03/26}{新增 \opt{linestretch} 选项。} +% +% \begin{macro}{linestretch} +% 若行宽不是汉字宽度的整数倍,自然要求伸展它们之间的差。这里设置的是在此基础上的 +% 额外伸展量。初始化为一个汉字的宽度。若设置为 \tn{maxdimen},则禁用此功能。 +% 参数的默认单位是汉字的宽度 \tn{ccwd}。 +% \begin{macrocode} +\keys_define:nn { ctex } + { + linestretch .code:n = + { + \ctex_set_default_ccwd:Nn \l_@@_line_stretch_tl {#1} + \ctex_select_size: + } , + linestretch .value_required:n = true + } +\tl_new:N \l_@@_line_stretch_tl +\tl_set:Nn \l_@@_line_stretch_tl { \ccwd } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_update_stretch:} +% 首先计算一行上汉字的字数,\tn{CJKglue} 相当于将 \tn{linewidth} 与汉字总宽度之差 +% 均匀地填充到汉字之间。\hologo{eTeX} 的除法是四舍五入,而我们这里应该用截断。由于 +% 没有可展性的要求,直接用原语 \cs{tex_divide:D} 要比 \cs{int_div_truncate:nn} +% 快一些。下面的算法还兼顾到了 \tn{linewidth} 不为汉字字宽的整数倍的情况。 +% 若用户禁用 \opt{linestretch} 并且修改过 \tn{CJKglue},则只更新 +% \tn{ccwd},否则设置伸展量为 $0.08$ 倍 \tn{baselineskip}。注意 \pkg{everysel} 的 +% 钩子位于 \tn{size@update} 之前,\tn{baselineskip} 还未更新,不能直接使用它。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_update_stretch: + { + \ctex_update_em_unit: + \dim_set:Nn \l_@@_tmp_dim { \l_@@_line_stretch_tl } + \dim_compare:nNnTF \l_@@_tmp_dim = \c_max_dim + { + \ctex_if_ccglue_touched:TF + { \ctex_update_ccwd: } + { + \dim_set:Nn \l_@@_tmp_dim + { \baselinestretch \tex_glueexpr:D \f@baselineskip \scan_stop: } + \skip_set:Nn \l_@@_ccglue_skip + { \c_zero_dim plus .08 \l_@@_tmp_dim } + \ctex_update_ccglue: + } + } + { + \int_set:Nn \l_@@_tmp_int + { \tex_dimexpr:D \linewidth - \ccwd - \l_@@_tmp_dim \scan_stop: } + \tex_divide:D \l_@@_tmp_int \ccwd + \int_compare:nNnTF \l_@@_tmp_int > \c_zero_int + { + \skip_set:Nn \l_@@_ccglue_skip + { + \c_zero_dim plus \dim_eval:n + { + ( \linewidth - \ccwd - \l_@@_tmp_int \ccwd ) / + \l_@@_tmp_int + } + } + } + { \skip_zero:N \l_@@_ccglue_skip } + \ctex_update_ccglue: + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_update_parindent:} +% 更新段落首行缩进。此函数在字号变化时调用。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_update_parindent: + { + \tl_if_empty:NF \l_@@_autoindent_tl + { + \dim_compare:nNnF \parindent = \c_zero_dim + { \dim_set:Nn \parindent { \l_@@_autoindent_tl } } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\ziju} +% 若参数为 $0$,则恢复正常间距。 +% \begin{macrocode} +\NewDocumentCommand \ziju { m } + { \exp_args:Nx \ctex_ziju:n {#1} \tex_ignorespaces:D } +\cs_new_protected_nopar:Npn \ctex_ziju:n #1 + { + \tl_set:Nx \l_@@_ziju_tl { \fp_eval:n {#1} } + \ctex_select_size: + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_update_ziju:} +% 更新字距。若字距不大于 $-1$,即 \tn{ccwd} 为非正值,则不计算伸缩值。 +% 否则,首先假定汉字的宽度为正常宽度加上字距,看一行上能正常放下多少个汉字。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_update_ziju: + { + \ctex_update_em_unit: + \dim_set:Nn \l_@@_ziju_dim { \l_@@_ziju_tl \ccwd } + \dim_add:Nn \ccwd { \l_@@_ziju_dim } + \dim_compare:nNnTF \ccwd > \c_zero_dim +% \end{macrocode} +% 伸展量保证行内的剩余空白能够被均匀地填充到汉字之间,收缩的最大限度是让当前行 +% 还能够再挤下一个汉字并且不会出现负间距。由 \TeX{} 决定伸展还是收缩。 +% \begin{macrocode} + { + \dim_set:Nn \l_@@_tmp_dim + { \linewidth - \ccwd + \l_@@_ziju_dim } + \int_set:Nn \l_@@_tmp_int { \l_@@_tmp_dim } + \tex_divide:D \l_@@_tmp_int \ccwd + \dim_sub:Nn \l_@@_tmp_dim { \l_@@_tmp_int \ccwd } +% \end{macrocode} +% 由于 \tn{parindent} 是一个固定值,并不参与伸缩,容易导致第一行出现坏盒子。 +% 我们在这里将字数减去 $2$,以此放大伸缩值。 +% \begin{macrocode} + \dim_compare:nNnF \parindent = \c_zero_dim + { + \int_compare:nNnF \l_@@_tmp_int < 3 + { \int_sub:Nn \l_@@_tmp_int { 2 } } + } + \skip_set:Nn \l_@@_ccglue_skip + { + \l_@@_ziju_dim + plus \dim_eval:n { \l_@@_tmp_dim / \l_@@_tmp_int } + minus \dim_min:nn { \dim_abs:n { \l_@@_ziju_dim } } + { ( \ccwd - \l_@@_tmp_dim ) / ( \l_@@_tmp_int + 1 ) } + } + } + { \skip_set:Nn \l_@@_ccglue_skip { \l_@@_ziju_dim } } + \ctex_update_ccglue: +% \end{macrocode} +% 字距设置得比较大时,为了尽量保证段首缩进能够与下一行对齐,应该需要相应地加上 +% 或者减去伸缩值。但是这里并不清楚 \TeX{} 是伸展还是收缩,之前以“当前行是否还 +% 放得下一个汉字”为标准加上或减去伸缩值的做法也未必与实际结果一致,所以只好还 +% 是设置为 |2\ccwd|。 +% \begin{macrocode} + \ctex_update_parindent: + } +\dim_new:N \l_@@_ziju_dim +% \end{macrocode} +% \end{macro} +% +% \changes{v2.0}{2015/03/21}{\tn{CTEXindent}, \tn{CTEXnoindent} 是过时命令。} +% \begin{macro}{\CTEXindent,\CTEXnoindent} +% 过时命令。 +% \begin{macrocode} +\NewDocumentCommand \CTEXindent { } + { + \msg_warning:nnnn { ctex } { deprecated-command } { \CTEXindent } + { \parindent is~ set~ to~ 2\ccwd. } + \ctex_update_ccwd: \dim_set:Nn \parindent { 2 \ccwd } + } +\NewDocumentCommand \CTEXnoindent { } + { + \msg_warning:nnnn { ctex } { deprecated-command } { \CTEXnoindent } + { \parindent is~ set~ to~ 0pt. } + \dim_zero:N \parindent + } +% \end{macrocode} +% \end{macro} +% +% \subsection{中文数字与日期} +% +% \begin{macrocode} +\PassOptionsToPackage { encoding = \l_@@_encoding_tl } { zhnumber } +\RequirePackage { zhnumber } +% \end{macrocode} +% +% \begin{macro}{\chinese} +% \changes{v2.4.1}{2016/05/01}{支持 \tn{pagenumbering}。} +% \begin{macrocode} +\cs_new_nopar:Npn \chinese { \zhnum_counter:n } +\cs_new_eq:NN \@chinese \@zhnum +\cs_new_eq:NN \Chinese \chinese +\cs_new_eq:NN \CTEXcounter \use_none:n +% \end{macrocode} +% \end{macro} +% +% \changes{v2.2}{2015/06/29}{给 \pkg{enumitem} 宏包注册 \tn{chinese} 和 +% \tn{zhnum}。} +% +% 给 \pkg{enumitem} 宏包注册 \tn{chinese}、\tn{zhnum} 和 \tn{zhdig}。 +% \begin{macrocode} +\ctex_at_end_package:nn { enumitem } + { + \cs_if_free:NF \AddEnumerateCounter + { + \AddEnumerateCounter * { \zhnum } { \@zhnum } { 1 } + \AddEnumerateCounter * { \zhdig } { \@zhdig } { 1 } + \AddEnumerateCounter * { \chinese } { \@chinese } { 1 } + } + } +% \end{macrocode} +% +% \begin{macro}{\CTEXnumber,\CTEXdigits} +% \begin{macrocode} +\NewDocumentCommand \CTEXnumber { m m } + { \protected@edef #1 { \zhnumber {#2} } } +\NewDocumentCommand \CTEXdigits { m m } + { \protected@edef #1 { \zhdigits {#2} } } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{today} +% \begin{macrocode} +\cs_set_eq:NN \CTEX@todayold \today +\keys_define:nn { ctex } + { + today .choice: , + today / old .code:n = + { \cs_set_eq:NN \today \CTEX@todayold } , + today / small .code:n = + { + \cs_set_eq:NN \today \zhtoday + \zhnumsetup { time = Arabic } + } , + today / big .code:n = + { + \cs_set_eq:NN \today \zhtoday + \zhnumsetup { time = Chinese } + } , + today / unknown .code:n = + { \msg_error:nnx { ctex } { today-undef } {#1} } + } +\msg_new:nnnn { ctex } { today-undef } + { Today~format~`#1'~is~undefined. } + { Available~today~formats~are~`old',~`small',~and~`big'. } +% \end{macrocode} +% \end{macro} +% +% \subsection{其它中文标题定义} +% +% \changes{v2.0}{2014/03/08}{将标题汉化功能加入 \pkg{ctex.sty}。} +% \changes{v2.4.3}{2016/08/18}{确保 \tn{proofname} 非空。} +% +% \begin{macro}[int]{\proofname} +% \tn{proofname} 未在标准文档类中定义,需要确保它非空。 +% \begin{macrocode} +\tl_if_exist:NF \proofname + { + \tl_new:N \proofname + \tl_set:Nn \proofname { Proof } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +\keys_define:nn { ctex } + { + contentsname .tl_set:N = \contentsname , + listfigurename .tl_set:N = \listfigurename , + listtablename .tl_set:N = \listtablename , + figurename .tl_set:N = \figurename , + tablename .tl_set:N = \tablename , + abstractname .tl_set:N = \abstractname , + indexname .tl_set:N = \indexname , + appendixname .tl_set:N = \appendixname , + proofname .tl_set:N = \proofname , +%<article> bibname .tl_set:N = \refname +%<book|report> bibname .tl_set:N = \bibname +%<*beamer> + algorithmname .tl_set:N = \algorithmname , + bibname .tl_set:N = \bibname , + refname .tl_set:N = \refname , + continuation .tl_set:N = \insertcontinuationtext +%</beamer> + } +% \end{macrocode} +% +% \begin{macrocode} +%<*ctex> +\msg_new:nnn { ctex } { ctexbibname } + { + Neither~`\token_to_str:N \bibname'~nor~`\token_to_str:N \refname'~can~be~found.\\ + The~key~`bibname'~will~set~`\token_to_str:N \ctexbibname'~to~the~given~value. + } +\tl_if_exist:NTF \insertcontinuationtext + { + \keys_define:nn { ctex } + { + algorithmname .tl_set:N = \algorithmname , + bibname .tl_set:N = \bibname , + refname .tl_set:N = \refname , + continuation .tl_set:N = \insertcontinuationtext + } + } + { + \tl_if_exist:NTF \bibname + { \keys_define:nn { ctex } { bibname .tl_set:N = \bibname } } + { + \tl_if_exist:NTF \refname + { \keys_define:nn { ctex } { bibname .tl_set:N = \refname } } + { + \msg_warning:nn { ctex } { ctexbibname } + \keys_define:nn { ctex } { bibname .tl_set:N = \ctexbibname } + } + } + } +%</ctex> +% \end{macrocode} +% +% \begin{macrocode} +%</class|ctex> +% \end{macrocode} +% +% \subsection{中文化的标题结构} +% +% 本节内容在 \CTeX{} 文档类或打开 \opt{heading} 选项下生效。 +% \begin{macrocode} +%<*class|heading> +% \end{macrocode} +% +% \subsubsection{定义标题格式选项} +% +% \begin{variable}{\c_@@_section_headings_seq} +% 保存 \tn{section} 级以下标题名字。 +% \begin{macrocode} +%<*article|book|report> +\seq_const_from_clist:Nn \c_@@_section_headings_seq + { section , subsection , subsubsection , paragraph , subparagraph } +%</article|book|report> +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\c_@@_headings_seq} +% \begin{macrocode} +%<*article|book|report> +\seq_new:N \c_@@_headings_seq +\seq_gset_eq:NN \c_@@_headings_seq \c_@@_section_headings_seq +%<book|report>\seq_gput_left:Nn \c_@@_headings_seq { chapter } +\seq_gput_left:Nn \c_@@_headings_seq { part } +%</article|book|report> +%<*beamer> +\seq_const_from_clist:Nn \c_@@_headings_seq + { part , section , subsection } +%</beamer> +% \end{macrocode} +% \end{variable} +% +% \changes{v2.1}{2015/06/19}{\opt{nameformat} 可以接受章节名字为参数。} +% \changes{v2.3}{2016/01/05}{修复 \opt{nameformat} 作用域问题。} +% +% \begin{macro}{\@@_initial_heading:n} +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_initial_heading:n #1 + { + \tl_new:c { CTEX@pre#1 } + \tl_new:c { CTEX@post#1 } + \tl_const:cx { CTEXthe#1 } + { + \exp_not:c { CTEX@pre#1 } + \exp_not:c { CTEX@the#1 } + \exp_not:c { CTEX@post#1 } + } + \tl_const:cx { CTEX@#1name } + { + \group_begin: + \exp_not:c { CTEX@#1@nameformat } + { + \exp_not:c { CTEX@pre#1 } + \exp_not:N \tl_if_empty:NTF + \exp_not:c { CTEX@#1@numberformat } + { \exp_not:c { CTEX@the#1 } } + { + \group_begin: + \exp_not:c { CTEX@#1@numberformat } + \exp_not:c { CTEX@the#1 } + \group_end: + } + \exp_not:c { CTEX@post#1 } + } + \group_end: + } + } +% \end{macrocode} +% \end{macro} +% +% \changes{v2.1}{2015/05/22}{\opt{format+}, \opt{nameformat+} 等带加号的选项, +% 加号与前面的文字之间可以有可选的空格。} +% \changes{v2.1}{2015/06/19}{新的标题格式选项 \opt{aftertitle}。} +% \changes{v2.2}{2015/06/21}{新的标题格式选项 \opt{numbering}。} +% \changes{v2.2}{2015/06/27}{\opt{beforeskip} 和 \opt{afterskip} 选项的符号 +% 不再有特殊意义。} +% \changes{v2.2}{2015/06/27}{新的标题格式选项 \opt{afterindent}。} +% \changes{v2.2}{2015/06/27}{新的标题格式选项 \opt{runin}。} +% \changes{v2.4.3}{2016/06/03}{新的标题格式选项 \opt{fixskip}。} +% \changes{v2.4.4}{2016/09/19}{新的标题格式选项 \opt{break}。} +% \changes{v2.4.5}{2016/10/22}{新的标题格式选项 \opt{hang}。} +% \changes{v2.4.5}{2016/10/25}{新的标题格式选项 \opt{tocline}。} +% \changes{v2.4.11}{2017/11/21}{因上游 \pkg{l3keys} 变化,重新定义 +% \opt{format\textvisiblespace+} 等带空格加号的选项。} +% +% \begin{macro}{\@@_def_heading_keys:n} +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_def_heading_keys:n #1 + { + \tl_put_right:Nx \l_@@_tmp_tl + { + #1 .meta:nn = { ctex / #1 } { ####1 } , + #1 / name .code:n = + { \ctex_assign_heading_name:nn {#1} { ####1 } } , + #1 / number .tl_set:N = \exp_not:c { CTEX@the#1 } , + #1 / beforeskip .tl_set:N = \exp_not:c { CTEX@#1@beforeskip } , + #1 / afterskip .tl_set:N = \exp_not:c { CTEX@#1@afterskip} , + #1 / indent .tl_set:N = \exp_not:c { CTEX@#1@indent } , + #1 / numbering .bool_set:N = \exp_not:c { CTEX@#1@numbering } , + #1 / numbering .initial:n = true , + #1 / beforeskip .initial:n = \c_zero_skip , + #1 / afterskip .initial:n = \c_zero_skip , + #1 / indent .initial:n = \c_zero_dim , + #1 / beforeskip .value_required:n = true , + #1 / afterskip .value_required:n = true , + #1 / indent .value_required:n = true , +%<*article|book|report> + #1 / afterindent .bool_set:N = \exp_not:c { CTEX@#1@afterindent } , + #1 / fixskip .bool_set:N = \exp_not:c { CTEX@#1@fixskip } , + #1 / hang .bool_set:N = \exp_not:c { CTEX@#1@hang } , + #1 / hang .initial:n = true , + #1 / runin .bool_set:N = \exp_not:c { CTEX@#1@runin } , + #1 / tocline .code:n = + { + \cs_set:Npn \exp_not:c { CTEX@#1@tocline} + \exp_not:n { ####1####2 } { ####1 } + } , + \@@_plus_key_aux:nn {#1} { break } , +%</article|book|report> + \@@_plus_key_aux:nn {#1} { format } , + \@@_plus_key_aux:nn {#1} { nameformat } , + \@@_plus_key_aux:nn {#1} { numberformat } , + \@@_plus_key_aux:nn {#1} { titleformat } , + \@@_plus_key_aux:nn {#1} { aftername } , + \@@_plus_key_aux:nn {#1} { aftertitle } , + } + } +\cs_new_nopar:Npn \@@_plus_key_aux:nn #1#2 + { + #1 / #2 .tl_set:N = \exp_not:c { CTEX@#1@#2 } , + #1 / #2 + .code:n = + { \tl_put_right:Nn \exp_not:c { CTEX@#1@#2 } { ####1 } } , + #1 / #2 ~ + .code:n = + { \tl_put_right:Nn \exp_not:c { CTEX@#1@#2 } { ####1 } } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_assign_heading_name:nn} +% \begin{macro}{\@@_assign_heading_name:nnn} +% \opt{name} 的值是一个至多两个元素的逗号分隔列表。由于 \LaTeXiii{} 的 +% \texttt{clist} 总是会自动忽略空元素,所以设置 |name={,章}| 后,第一个元素将会 +% 是“章”,必须用空的分组保护空元素:|name={{},章}|,这在使用中有些许不便。我们 +% 可以改用 \texttt{seq} 或者手写函数解析参数来加以改进。为实现的简单起见,这里用 +% 了 \pkg{xparse} 的 \tn{SplitArgument},它带有参数的长度检查。 +% \begin{macrocode} +\NewDocumentCommand \ctex_assign_heading_name:nn + { m > { \SplitArgument { 1 } { , } } +m } + { \@@_assign_heading_name:nnn {#1} #2 } +\cs_new_protected:Npn \@@_assign_heading_name:nnn #1#2#3 + { + \tl_set:cn { CTEX@pre#1 } {#2} + \IfNoValueTF {#3} + { \tl_clear:c { CTEX@post#1 } } + { \tl_set:cn { CTEX@post#1 } {#3} } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \changes{v2.0}{2014/03/21}{标题设置新增 \opt{pagestyle} 选项。} +% \changes{v2.4.1}{2016/05/10}{新的标题格式选项 \opt{part/fixbeforeskip} 和 +% \opt{chapter/fixbeforeskip}。} +% \changes{v2.4.3}{2016/06/03}{删除选项 \opt{part/fixbeforeskip} 和 +% \opt{chapter/fixbeforeskip}。} +% \changes{v2.4.5}{2016/10/01}{新的标题格式选项 \opt{chapter/lofskip} 和 +% \opt{chapter/lotskip}。} +% +% \begin{macro}{part/pagestyle,chapter/pagestyle,chapter/lofskip,chapter/lotskip} +% 只在 \cls{ctexbook} 和 \cls{ctexrep} 下有定义。 +% \begin{macrocode} +\group_begin: +%<*book|report> +\tl_set:Nn \l_@@_tmp_tl + { + part / pagestyle .tl_set:N = \CTEX@part@pagestyle , + chapter / pagestyle .tl_set:N = \CTEX@chapter@pagestyle , + chapter / lofskip .tl_set:N = \CTEX@chapter@lofskip , + chapter / lotskip .tl_set:N = \CTEX@chapter@lotskip , + chapter / lofskip .initial:n = \c_zero_skip , + chapter / lotskip .initial:n = \c_zero_skip , + chapter / lofskip .value_required:n = true , + chapter / lotskip .value_required:n = true , + } +%</book|report> +%<*article|beamer> +\tl_clear:N \l_@@_tmp_tl +%</article|beamer> +% \end{macrocode} +% \end{macro} +% +% 定义标题键值选项。 +% \begin{macrocode} +\seq_map_inline:Nn \c_@@_headings_seq + { + \@@_initial_heading:n {#1} + \@@_def_heading_keys:n {#1} + } +\use:x + { + \group_end: + \keys_define:nn { ctex } { \exp_not:o { \l_@@_tmp_tl } } + } +% \end{macrocode} +% +% \begin{macrocode} +%<*article|book|report> +% \end{macrocode} +% +% \subsubsection{标准标题命令的修改} +% +% \begin{macro}[int]{\CTEX@fixtopskip} +% 修正 \cls{book} 和 \cls{report} 类的 \tn{part} 和 \tn{chapter} 标题之前的多余空行。 +% \begin{macrocode} +%<*book|report> +\cs_new_protected_nopar:Npn \CTEX@fixtopskip + { + \CTEX@fixheadingskip + \dim_compare:nNnF \tex_pagegoal:D < \c_max_dim + { \skip_sub:Nn \l_@@_heading_skip { \tex_topskip:D } } + } +%</book|report> +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\CTEX@fixheadingskip} +% 抑制行间粘连,修正标题前后的多余间距。事实上,减掉 \tn{parskip},有一定的风险。 +% 如果接下来的内容不会进入水平模式(例如在 \opt{format} 选项中使用 \tn{hrule} 或者 \tn{hbox}), +% \TeX{} 就不会加上 \tn{parskip}。这时候就需要用户把 \tn{parskip} 加到 \opt{beforeskip} +% 或者 \opt{afterskip} 作为修正。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \CTEX@fixheadingskip + { + \par + \dim_set:Nn \tex_prevdepth:D { -1000pt } + \skip_sub:Nn \l_@@_heading_skip { \tex_parskip:D } + } +\skip_new:N \l_@@_heading_skip +\cs_new_protected_nopar:Npn \CTEX@setheadingskip + { \skip_set:Nn \l_@@_heading_skip } +\cs_new_eq:NN \CTEX@headingskip \l_@@_heading_skip +% \end{macrocode} +% \end{macro} +% +% \changes{v2.4.4}{2016/09/18}{提供 \tn{partmark}。} +% \begin{macro}[int]{\partmark} +% 提供 \tn{partmark}。 +% \begin{macrocode} +\ProvideDocumentCommand \partmark { m } + { \markboth { } { } } +% \end{macrocode} +% \end{macro} +% +% \changes{v2.4.4}{2016/09/19}{提供 \tn{CTEXifname}。} +% \changes{v2.4.6}{2016/10/31}{\tn{CTEXifname} 初始为假。} +% \begin{macro}{\CTEXifname} +% \begin{macro}[int]{\CTEX@ifnametrue,\CTEX@ifnamefalse} +% 用于判断当前标题是否有编号。 +% \begin{macrocode} +\cs_new_eq:NN \CTEXifname \use_ii:nn +\cs_new_protected_nopar:Npn \CTEX@ifnametrue + { \cs_set_eq:NN \CTEXifname \use_i:nn } +\cs_new_protected_nopar:Npn \CTEX@ifnamefalse + { \cs_set_eq:NN \CTEXifname \use_ii:nn } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[int]{\CTEX@addloflotskip} +% 往插图和表格目录中加入额外间距。如果间距为零,则不加入。 +% \begin{macrocode} +%<*book|report> +\cs_new_protected_nopar:Npn \CTEX@addloflotskip #1 + { + \skip_set:Nn \l_@@_heading_skip { \use:c { CTEX@#1@lofskip } } + \skip_if_eq:nnF { \l_@@_heading_skip } { \c_zero_skip } + { + \addtocontents { lof } + { \protect \addvspace { \skip_use:N \l_@@_heading_skip } } + } + \skip_set:Nn \l_@@_heading_skip { \use:c { CTEX@#1@lotskip } } + \skip_if_eq:nnF { \l_@@_heading_skip } { \c_zero_skip } + { + \addtocontents { lot } + { \protect \addvspace { \skip_use:N \l_@@_heading_skip } } + } + } +%</book|report> +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\CTEX@addtocline} +% \begin{macrocode} +\cs_new_protected:Npn \CTEX@addtocline #1#2 + { \addcontentsline { toc } {#1} { \use:c { CTEX@#1@tocline } {#1} {#2} } } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\CTEX@disableautoindent} +% 禁用自动调整首行缩进。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \CTEX@disableautoindent + { \tl_clear:N \l_@@_autoindent_tl } +% \end{macrocode} +% \end{macro} +% +% \changes{v2.2}{2015/06/27}{\opt{beforeskip}、\opt{afterskip} 和 \opt{indent} +% 选项支持表达式。} +% \changes{v2.4.15}{2019/03/31}{修正 \opt{part/indent} 和 \opt{chapter/indent} 的实现方法。} +% \changes{v2.4.15}{2019/03/31}{定义 \opt{part/hang} 和 \opt{chapter/hang}。} +% \changes{v2.4.16}{2019/05/11}{修正 \opt{part/indent} 和 \opt{chapter/indent} +% 的实现方法,在其标题内部禁用 \opt{autoindent}。} +% +% \paragraph{part 的标题} +% +% \begin{macrocode} +%<@@=> +% \end{macrocode} +% +% \changes{v2.2}{2015/06/27}{非 \cls{ctexart} 类的 \opt{part/beforeskip} 和 +% \opt{part/afterskip} 选项有意义。} +% +% \begin{macro}[int]{\part} +% \begin{macrocode} +%<*article> +\renewcommand\part{% + \if@noskipsec \leavevmode \fi + \par + \CTEX@part@break +% \addvspace{4ex}% + \CTEX@setheadingskip \CTEX@part@beforeskip + \ifodd \CTEX@part@fixskip \CTEX@fixheadingskip \fi + \addvspace \CTEX@headingskip + \ifodd \CTEX@part@afterindent + \@afterindenttrue + \else + \@afterindentfalse + \fi + \secdef\@part\@spart} +%</article> +%<*book|report> +\renewcommand\part{% +% \if@openright +% \cleardoublepage +% \else +% \clearpage +% \fi + \CTEX@part@break +% \thispagestyle{plain}% + \thispagestyle{\CTEX@part@pagestyle}% + \if@twocolumn + \onecolumn + \@tempswatrue + \else + \@tempswafalse + \fi +% \null\vfil + \CTEX@setheadingskip \CTEX@part@beforeskip + \ifodd \CTEX@part@fixskip \CTEX@fixtopskip \fi + \vspace*{\CTEX@headingskip}% + \secdef\@part\@spart} +%</book|report> +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\@part} +% \begin{macrocode} +%<*article> +\def\@part[#1]#2{% + \ifnum \c@secnumdepth >\m@ne + \ifodd \CTEX@part@numbering + \CTEX@ifnametrue + \refstepcounter{part}% +% \addcontentsline{toc}{part}{\thepart\hspace{1em}#1}% + \else + \CTEX@ifnamefalse + \CTEX@makeanchor{part*}% +% \addcontentsline{toc}{part}{#1}% + \fi + \else + \CTEX@ifnamefalse + \CTEX@makeanchor{part*}% +% \addcontentsline{toc}{part}{#1}% + \fi + \CTEX@gettitle{#1}% + \CTEX@addtocline{part}{#1}% + {\interlinepenalty \@M +% \normalfont \parindent \z@ \raggedright + \CTEX@disableautoindent + \normalfont \CTEX@part@format +% \ifnum \c@secnumdepth >\m@ne +% \Large\bfseries\partname\nobreakspace\thepart\par\nobreak +% \fi + \CTEX@hangindent{part}% + {\CTEXifname{\CTEX@partname\CTEX@part@aftername}{}}% +% \huge\bfseries #2% + \CTEX@part@titleformat{#2}% +% \markboth{}{}% + \partmark{#1}% + \CTEX@part@aftertitle}% + \nobreak +% \vskip 3ex + \CTEX@setheadingskip \CTEX@part@afterskip + \ifodd \CTEX@part@fixskip \CTEX@fixheadingskip \fi + \vskip \CTEX@headingskip + \@afterheading} +%</article> +%<*book|report> +\def\@part[#1]#2{% + \ifnum \c@secnumdepth >-2\relax + \ifodd \CTEX@part@numbering + \CTEX@ifnametrue + \refstepcounter{part}% +% \addcontentsline{toc}{part}{\thepart\hspace{1em}#1}% + \else + \CTEX@ifnamefalse + \CTEX@makeanchor{part*}% +% \addcontentsline{toc}{part}{#1}% + \fi + \else + \CTEX@ifnamefalse + \CTEX@makeanchor{part*}% +% \addcontentsline{toc}{part}{#1}% + \fi + \CTEX@gettitle{#1}% + \CTEX@addtocline{part}{#1}% +% \markboth{}{}% + \partmark{#1}% + {\interlinepenalty \@M +% \normalfont \centering + \CTEX@disableautoindent + \normalfont \CTEX@part@format +% \ifnum \c@secnumdepth >-2\relax +% \huge\bfseries\partname\nobreakspace\thepart\par\vskip 20\p@ +% \fi + \CTEX@hangindent{part}% + {\CTEXifname{\CTEX@partname\CTEX@part@aftername}{}}% +% \Huge\bfseries #2\par}% + \CTEX@part@titleformat{#2}% + \CTEX@part@aftertitle}% + \@endpart} +%</book|report> +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\@spart} +% \begin{macrocode} +%<*article> +\def\@spart#1{% + \CTEX@ifnamefalse + \CTEX@makeanchor@spart{part*}% + \CTEX@gettitle{#1}% + {\interlinepenalty \@M +% \normalfont \parindent \z@ \raggedright + \CTEX@disableautoindent + \normalfont \CTEX@part@format + \CTEX@hangindent{part}{}% +% \huge \bfseries #1\par}% + \CTEX@part@titleformat{#1}% + \CTEX@part@aftertitle}% + \nobreak +% \vskip 3ex + \CTEX@setheadingskip \CTEX@part@afterskip + \ifodd \CTEX@part@fixskip \CTEX@fixheadingskip \fi + \vskip \CTEX@headingskip + \@afterheading} +%</article> +%<*book|report> +\def\@spart#1{% + \CTEX@ifnamefalse + \CTEX@makeanchor@spart{part*}% + \CTEX@gettitle{#1}% + {\interlinepenalty \@M +% \normalfont \centering + \CTEX@disableautoindent + \normalfont \CTEX@part@format + \CTEX@hangindent{part}{}% +% \Huge \bfseries #1\par}% + \CTEX@part@titleformat{#1}% + \CTEX@part@aftertitle}% + \@endpart} +%</book|report> +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\@endpart} +% \begin{macrocode} +%<*book|report> +\def\@endpart{% +% \vfil + \CTEX@setheadingskip \CTEX@part@afterskip + \ifodd \CTEX@part@fixskip \CTEX@fixheadingskip \fi + \vskip \CTEX@headingskip + \newpage + \if@twoside + \if@openright + \null + \thispagestyle{empty}% + \newpage + \fi + \fi + \if@tempswa + \twocolumn + \fi} +%</book|report> +% \end{macrocode} +% \end{macro} +% +% \paragraph{chapter 的标题} +% +% \begin{macrocode} +%<*book|report> +% \end{macrocode} +% +% \begin{macro}[int]{\chapter} +% \begin{macrocode} +\renewcommand\chapter{% +% \if@openright\cleardoublepage\else\clearpage\fi +% \thispagestyle{plain}% + \CTEX@chapter@break + \thispagestyle{\CTEX@chapter@pagestyle}% + \global\@topnum\z@ +% \@afterindentfalse + \ifodd \CTEX@chapter@afterindent + \@afterindenttrue + \else + \@afterindentfalse + \fi + \secdef\@chapter\@schapter} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\@chapter} +% \begin{macrocode} +\def\@chapter[#1]#2{% + \ifnum \c@secnumdepth >\m@ne +%<*book> + \if@mainmatter +%</book> + \ifodd \CTEX@chapter@numbering + \CTEX@ifnametrue + \refstepcounter{chapter}% +% \typeout{\@chapapp\space\thechapter.}% + \typeout{\CTEXthechapter}% +% \addcontentsline{toc}{chapter} +% {\protect\numberline{\thechapter}#1}% + \else + \CTEX@ifnamefalse + \CTEX@makeanchor{\Hy@chapapp*}% +% \addcontentsline{toc}{chapter}{#1}% + \fi +%<*book> + \else + \CTEX@ifnamefalse + \CTEX@makeanchor@chapter{\Hy@chapapp*}% +% \addcontentsline{toc}{chapter}{#1}% + \fi +%</book> + \else + \CTEX@ifnamefalse + \CTEX@makeanchor@chapter{\Hy@chapapp*}% +% \addcontentsline{toc}{chapter}{#1}% + \fi + \CTEX@gettitle{#1}% + \CTEX@addtocline{chapter}{#1}% + \chaptermark{#1}% +% \addtocontents{lof}{\protect\addvspace{10\p@}}% +% \addtocontents{lot}{\protect\addvspace{10\p@}}% + \CTEX@addloflotskip{chapter}% + \if@twocolumn + \@topnewpage[\@makechapterhead{#2}]% + \else + \@makechapterhead{#2}% + \@afterheading + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\@schapter} +% \begin{macrocode} +\def\@schapter#1{% + \CTEX@ifnamefalse + \CTEX@makeanchor@schapter{\Hy@chapapp*}% + \CTEX@gettitle{#1}% + \if@twocolumn + \@topnewpage[\@makeschapterhead{#1}]% + \else + \@makeschapterhead{#1}% + \@afterheading + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\@makechapterhead} +% \begin{macrocode} +\def\@makechapterhead#1{% +% \vspace*{50\p@}% + \CTEX@setheadingskip \CTEX@chapter@beforeskip + \ifodd \CTEX@chapter@fixskip \CTEX@fixtopskip \fi + \vspace*{\CTEX@headingskip}% +% {\normalfont \parindent \z@ \raggedright + {\CTEX@disableautoindent + \normalfont \CTEX@chapter@format + \interlinepenalty\@M +% \ifnum \c@secnumdepth >\m@ne +% \if@mainmatter +% \huge\bfseries\@chapapp\space\thechapter\par\nobreak\vskip 20\p@ +% \fi +% \fi + \CTEX@hangindent{chapter}% + {\CTEXifname{\CTEX@chaptername\CTEX@chapter@aftername}{}}% +% \Huge \bfseries #1\par\nobreak + \CTEX@chapter@titleformat{#1}% + \CTEX@chapter@aftertitle + \nobreak +% \vskip 40\p@ + \CTEX@setheadingskip \CTEX@chapter@afterskip + \ifodd \CTEX@chapter@fixskip \CTEX@fixheadingskip \fi + \vskip \CTEX@headingskip + }} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\@makeschapterhead} +% \begin{macrocode} +\def\@makeschapterhead#1{% +% \vspace*{50\p@}% + \CTEX@setheadingskip \CTEX@chapter@beforeskip + \ifodd \CTEX@chapter@fixskip \CTEX@fixtopskip \fi + \vspace*{\CTEX@headingskip}% +% {\normalfont \parindent \z@ \raggedright + {\CTEX@disableautoindent + \normalfont \CTEX@chapter@format + \interlinepenalty\@M + \CTEX@hangindent{chapter}{}% +% \Huge \bfseries #1\par\nobreak + \CTEX@chapter@titleformat{#1}% + \CTEX@chapter@aftertitle + \nobreak +% \vskip 40\p@ + \CTEX@setheadingskip \CTEX@chapter@afterskip + \ifodd \CTEX@chapter@fixskip \CTEX@fixheadingskip \fi + \vskip \CTEX@headingskip + }} +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%</book|report> +% \end{macrocode} +% +% \paragraph{section 类的标题} +% +% \begin{macro}[int]{\@startsection} +% \begin{macrocode} +\def\@startsection#1#2#3#4#5#6{% + \if@noskipsec \leavevmode \fi + \par +% \@tempskipa #4\relax +% \@afterindenttrue +% \ifdim \@tempskipa <\z@ +% \@tempskipa -\@tempskipa \@afterindentfalse +% \fi + \CTEX@update@sectionformat@n{#1}% + \ifodd \CTEX@afterindent + \@afterindenttrue + \else + \@afterindentfalse + \fi + \if@nobreak + \everypar{}% + \else +% \addpenalty\@secpenalty\addvspace\@tempskipa + \csname CTEX@#1@break\endcsname + \CTEX@setheadingskip{#4}% + \ifodd \CTEX@fixskip \CTEX@fixheadingskip \fi + \addvspace \CTEX@headingskip + \fi + \@ifstar + {\CTEX@makeanchor@ssect{#1*}\@ssect{#3}{#4}{#5}{#6}}% + {\@dblarg{\@sect{#1}{#2}{#3}{#4}{#5}{#6}}}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\@seccntformat} +% \begin{macrocode} +\def\@seccntformat#1{% +% \csname the#1\endcsname\quad}% + \csname CTEX@#1name\endcsname + \csname CTEX@#1@aftername\endcsname} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\@sect} +% \begin{macrocode} +\def\@sect#1#2#3#4#5#6[#7]#8{% + \ifnum #2>\c@secnumdepth + \CTEX@ifnamefalse + \CTEX@makeanchor@sect{#1*}% + \let\@svsec\@empty + \else + \ifodd \csname CTEX@#1@numbering\endcsname + \CTEX@ifnametrue + \refstepcounter{#1}% + \protected@edef\@svsec{\@seccntformat{#1}\relax}% + \else + \CTEX@ifnamefalse + \CTEX@makeanchor{#1*}% + \let\@svsec\@empty + \fi + \fi + \CTEX@gettitle{#7}% +% \@tempskipa #5\relax +% \ifdim \@tempskipa>\z@ + \unless \ifodd \CTEX@runin + \begingroup + #6{% + \CTEX@hangfrom{\hskip\glueexpr #3\relax\@svsec}% +% \interlinepenalty \@M #8\@@par}% + \interlinepenalty \@M + \csname CTEX@#1@titleformat\endcsname{#8}% + \csname CTEX@#1@aftertitle\endcsname}% + \endgroup + \csname #1mark\endcsname{#7}% +% \addcontentsline{toc}{#1}{% +% \ifnum #2>\c@secnumdepth \else +% \protect\numberline{\csname the#1\endcsname}% +% \fi +% #7}% + \CTEX@addtocline{#1}{#7}% + \else + \def\@svsechd{% + #6{\hskip\glueexpr #3\relax +% \@svsec #8}% + \@svsec + \csname CTEX@#1@titleformat\endcsname{#8}% + \csname CTEX@#1@aftertitle\endcsname}% + \csname #1mark\endcsname{#7}% +% \addcontentsline{toc}{#1}{% +% \ifnum #2>\c@secnumdepth \else +% \protect\numberline{\csname the#1\endcsname}% +% \fi +% #7}% + \CTEX@addtocline{#1}{#7}}% + \fi + \@xsect{#5}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\@ssect} +% \begin{macrocode} +\def\@ssect#1#2#3#4#5{% + \CTEX@ifnamefalse + \CTEX@gettitle{#5}% +% \@tempskipa #3\relax +% \ifdim \@tempskipa>\z@ + \unless \ifodd \CTEX@runin + \begingroup + #4{% + \CTEX@hangfrom{\hskip\glueexpr #1\relax}% +% \interlinepenalty \@M #5\@@par}% + \interlinepenalty \@M + \CTEX@titleformat@n{#5}% + \CTEX@aftertitle}% + \endgroup + \else +% \def\@svsechd{#4{\hskip\glueexpr #1\relax #5}}% + \def\@svsechd{#4{\hskip\glueexpr #1\relax + \CTEX@titleformat@n{#5}\CTEX@aftertitle}}% + \fi + \@xsect{#3}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\@xsect} +% \begin{macrocode} +\def\@xsect#1{% +% \@tempskipa #1\relax +% \ifdim \@tempskipa>\z@ + \unless \ifodd \CTEX@runin + \par \nobreak +% \vskip \@tempskipa + \CTEX@setheadingskip{#1}% + \ifodd \CTEX@fixskip \CTEX@fixheadingskip \fi + \vskip \CTEX@headingskip + \@afterheading + \else + \@nobreakfalse + \global\@noskipsectrue + \everypar{% + \if@noskipsec + \global\@noskipsecfalse + {\setbox\z@\lastbox}% + \clubpenalty\@M + \begingroup \@svsechd \endgroup + \unskip +% \@tempskipa #1\relax +% \hskip -\@tempskipa + \hskip\glueexpr #1\relax + \else + \clubpenalty \@clubpenalty + \everypar{}% + \fi}% + \fi + \ignorespaces} +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%<@@=ctex> +% \end{macrocode} +% +% \begin{macro}[int]{\CTEX@hangindent} +% 用于实现 \tn{part} 和 \tn{chapter} 标题的 \opt{indent} 和 \opt{hang} 选项。 +% \begin{macrocode} +\cs_new_protected:Npn \CTEX@hangindent #1#2 + { + \dim_set:Nn \parindent { \use:c { CTEX@#1@indent } } + \bool_if:cTF { CTEX@#1@hang } + { \@hangfrom { \@@_indent_aux: #2 } } + {#2} + } +\cs_new_protected_nopar:Npn \@@_indent_aux: + { + \dim_compare:nNnF \parindent = \c_zero_dim + { \skip_horizontal:n { \parindent } } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\CTEX@hangfrom} +% \opt{hang} 选项控制是否采用悬挂缩进。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \CTEX@hangfrom + { + \bool_if:NTF \CTEX@hang + { \@hangfrom } + { \noindent \use:n } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\CTEX@update@sectionformat@n} +% 在 \tn{@startsection} 中设置 \tn{CTEX@titleformat@n} 等为相应函数。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \CTEX@update@sectionformat@n #1 + { + \cs_set_eq:Nc \CTEX@titleformat@n { CTEX@#1@titleformat } + \cs_set_eq:Nc \CTEX@aftertitle { CTEX@#1@aftertitle } + \cs_set_eq:Nc \CTEX@afterindent { CTEX@#1@afterindent } + \cs_set_eq:Nc \CTEX@fixskip { CTEX@#1@fixskip } + \cs_set_eq:Nc \CTEX@hang { CTEX@#1@hang } + \cs_set_eq:Nc \CTEX@runin { CTEX@#1@runin } + } +\cs_new_eq:NN \CTEX@titleformat@n \use:n +\cs_new_eq:NN \CTEX@aftertitle \prg_do_nothing: +\cs_new_eq:NN \CTEX@afterindent \c_true_bool +\cs_new_eq:NN \CTEX@fixskip \c_false_bool +\cs_new_eq:NN \CTEX@hang \c_true_bool +\cs_new_eq:NN \CTEX@runin \c_false_bool +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\CTEX@part@tocline, \CTEX@chapter@tocline} +% \begin{macrocode} +\cs_new:Npn \CTEX@part@tocline #1#2 + { + \CTEXifname + { \CTEXthepart \hspace { 1em } } + { } + #2 + } +%<*book|report> +\cs_new:Npn \CTEX@chapter@tocline #1#2 + { + \CTEXifname + { \protect \numberline { \CTEXthechapter \hspace { .3em } } } + { } + #2 + } +%</book|report> +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\CTEXnumberline} +% \begin{macrocode} +\cs_new_nopar:Npn \CTEXnumberline #1 + { + \CTEXifname + { \protect \numberline { \use:c { CTEXthe #1 } } } + { } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +\int_zero:N \l_@@_tmp_int +\seq_map_inline:Nn \c_@@_section_headings_seq + { + \int_incr:N \l_@@_tmp_int + \cs_gset_protected_nopar:cpx {#1} + { + \exp_not:N \@startsection {#1} + { \int_use:N \l_@@_tmp_int } + { \exp_not:c { CTEX@#1@indent } } + { \exp_not:c { CTEX@#1@beforeskip } } + { \exp_not:c { CTEX@#1@afterskip } } + { \exp_not:N \normalfont \exp_not:c { CTEX@#1@format } } + } + \cs_new:cpn { CTEX@#1@tocline } ##1##2 + { \CTEXnumberline { ##1 } ##2 } + } +% \end{macrocode} +% +% \paragraph{附录标题} +% +% \begin{macro}[int]{appendix/name,appendix/number,appendix/numbering} +% \begin{macrocode} +\keys_define:nn { ctex } + { + appendix .meta:nn = { ctex / appendix } {#1} , + appendix / name .code:n = + { \ctex_assign_heading_name:nn { appendix } {#1} } , + appendix / number .tl_set:N = \CTEX@appendix@number , + appendix / numbering .bool_set:N = \CTEX@appendix@numbering , + appendix / numbering .initial:n = true + } +\tl_new:N \CTEX@preappendix +\tl_new:N \CTEX@postappendix +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\appendix} +% \begin{macrocode} +\cs_new_eq:NN \CTEX@save@appendix \appendix +\cs_gset_protected_nopar:Npn \appendix + { + \CTEX@save@appendix +%<*article> + \gdef \CTEX@presection { \CTEX@preappendix } + \gdef \CTEX@thesection { \CTEX@appendix@number } + \gdef \CTEX@postsection { \CTEX@postappendix } + \gdef \CTEX@section@numbering { \CTEX@appendix@numbering } +%</article> +%<*book|report> + \gdef \CTEX@prechapter { \CTEX@preappendix } + \gdef \CTEX@thechapter { \CTEX@appendix@number } + \gdef \CTEX@postchapter { \CTEX@postappendix } + \gdef \CTEX@chapter@numbering { \CTEX@appendix@numbering } +%</book|report> + } +% \end{macrocode} +% \end{macro} +% +% \paragraph{设置 \pkg{hyperref} 宏包的标题锚点} +% +% \changes{v2.4.4}{2016/09/12}{改进 \pkg{hyperref} 宏包的标题锚点设置。} +% +% \begin{macro}[int]{\CTEX@makeanchor} +% 设置超链接跳转锚点,在 \pkg{hyperref} 载入后才有意义。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \CTEX@makeanchor #1 + { } +% \end{macrocode} +% \end{macro} +% +% \begin{variable}{\c_@@_headings_cs_seq} +% 保存内部标题命令的 \CTeX{} 定义,用于随后比较。 +% \begin{macrocode} +\seq_const_from_clist:Nn \c_@@_headings_cs_seq +%<article> { part , spart , sect , ssect } +%<book|report> { part , spart , chapter , schapter , sect , ssect } +\seq_map_inline:Nn \c_@@_headings_cs_seq + { + \cs_new_eq:cc { CTEX@ #1 } { @ #1 } + \cs_new_eq:cN { CTEX@makeanchor@ #1 } \CTEX@makeanchor + } +% \end{macrocode} +% \end{variable} +% +% \begin{macro}[int]{\CTEX@hyperheadinghook} +% \pkg{hyperref} 会重定义内部标题命令,目的在于为没有编号的标题设置锚点(这一功能受他的 +% \opt{implicit} 选项的控制)。我们在上面对标题命令的修改已经包含这一功能,如果这些标题命令在 +% \pkg{hyperref} 载入之前没有被修改过,则恢复 \CTeX{} 的定义。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \CTEX@hyperheadinghook + { + \group_begin: + \ifHy@implicit + \cs_set_eq:NN \H@old@chapter \Hy@org@chapter + \seq_map_inline:Nn \c_@@_headings_cs_seq + { + \cs_if_eq:ccT { H@old@ ##1 } { CTEX@ ##1 } + { + \cs_gset_eq:cc { @ ##1 } { CTEX@ ##1 } + \cs_gset_eq:cN { CTEX@makeanchor@ ##1 } \CTEX@makeanchor + } + } + \else: + \seq_map_inline:Nn \c_@@_headings_cs_seq + { \cs_gset_eq:cN { CTEX@makeanchor@ ##1 } \CTEX@makeanchor } + \fi: + \group_end: + } +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +\ctex_at_end_package:nn { hyperref } + { + \cs_gset_protected_nopar:Npn \CTEX@makeanchor #1 + { + \Hy@MakeCurrentHrefAuto {#1} + \Hy@raisedlink + { + \hyper@anchorstart { \@currentHref } + \hyper@anchorend + } + } + \CTEX@hyperheadinghook + } +% \end{macrocode} +% +% \paragraph{兼容 \pkg{nameref} 宏包} +% +% \changes{v2.4.16}{2019/05/29}{更好地兼容 \pkg{nameref} 宏包。} +% +% \begin{macro}[int]{\CTEX@gettitle} +% 在 \pkg{nameref} 载入后才有意义,与上述 \pkg{hyperref} 的处理类似。 +% \begin{macrocode} +\cs_new_protected:Npn \CTEX@gettitle #1 + { } +\ctex_at_end_package:nn { nameref } + { + \cs_gset_protected_nopar:Npn \CTEX@gettitle { \NR@gettitle } + \seq_map_inline:Nn \c_@@_headings_cs_seq + { + \cs_if_eq:ccT { NR@ #1 } { CTEX@ #1 } + { \cs_gset_eq:cc { @ #1 } { CTEX@ #1 } } + } + } +% \end{macrocode} +% \end{macro} +% +% \paragraph{兼容 \pkg{titlesec} 宏包} +% +% 我们修改了 \tn{@startsection} 的定义,它的第四个(\meta{beforeskip})和 +% 第五个(\meta{afterskip})参数的符号不再有特殊意义,改由相应的选项 +% \opt{afterindent} 和 \opt{runin} 来控制。 +% +% 引入 \pkg{titlesec} 宏包,并且未设置它的 \opt{loadonly} 选项时,\pkg{titlesec} +% 会展开 section 类标题获取它们的参数,进行初始设置。我们需要进行一些调整。 +% +% \begin{macro}[int]{\ctex_titlesec_hook:} +% \tn{titleformat} 的设置保存在名为 |\ttlf@|\meta{section} 的宏中备用,它的内容是 +% \begin{quote}\small +% |\ttlh@|\meta{shape}\Arg{format}\Arg{label}\Arg{sep}\Arg{before}\Arg{after} +% \end{quote} +% 我们这里的 \meta{shape} 为 |hang| 或者 |runin|。\tn{titlespacing} 的设置保存在 +% |\ttls@|\meta{section} 之中,它的内容是 +% \begin{quote}\small +% \Arg{left}\Arg{right}\Arg{before}\Arg{after}\Arg{afterindent} +% \end{quote} +% 其中 \meta{afterindent} 为 |1| 或 |0|,分别对应是否保留段首缩进。 +% 我们需要根据 \CTeX{} 的 \opt{runin} 和 \opt{afterindent} 选项调整 +% |\ttlh@|\meta{shape} 和 \meta{afterindent}。注意,由 \tn{ttl@extract} 得的 +% \meta{before} 和 \meta{after} 的值总是非负的,而 \CTeX{} 的 \opt{beforeskip} +% 和 \opt{afterskip} 是可以取负值的,但我们不打算调整它们了。 +% 如果使用了 \pkg{titlesec} 的 \opt{indentafter} 等选项,也不需要调整 +% |\ttls@|\meta{section}。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_titlesec_hook: + { + \@ifpackagewith { titlesec } { explicit } + { + \cs_set_eq:NN \@@_titlesec_format:Nn + \@@_titlesec_format_explicit:Nn + } + { } + \clist_map_inline:nn + { indentafter , noindentafter , indentfirst , nonindentfirst } + { + \@ifpackagewith { titlesec } { ##1 } + { + \clist_map_break:n + { \cs_set_eq:NN \@@_titlesec_hook:n \@@_titlesec_format:n } + } + { } + } + \seq_map_function:NN \c_@@_section_headings_seq \@@_titlesec_hook:n + } +\cs_new_protected_nopar:Npn \@@_titlesec_hook:n #1 + { + \@@_titlesec_format:n {#1} + \exp_args:Nc \@@_titlesec_spacing:Nn { ttls@#1 } {#1} + } +\cs_new_protected_nopar:Npn \@@_titlesec_format:n #1 + { + \cs_if_free:cF { ttlf@#1 } + { \exp_args:Nc \@@_titlesec_format:Nn { ttlf@#1 } {#1} } + } +\cs_new_protected_nopar:Npn \@@_titlesec_format:Nn #1#2 + { + \tl_set:Nx #1 + { + \bool_if:cTF { CTEX@#2@runin } + { \exp_not:N \ttlh@runin } + { \exp_not:N \ttlh@hang } + \tl_tail:N #1 + } + } +\cs_new_protected_nopar:Npn \@@_titlesec_format_explicit:Nn #1#2 + { + \cs_set_nopar:Npx #1 ##1 + { + \bool_if:cTF { CTEX@#2@runin } + { \exp_not:N \ttlh@runin } + { \exp_not:N \ttlh@hang } + \exp_args:No \tl_tail:n { #1 { } } + } + } +\cs_new_protected_nopar:Npn \@@_titlesec_spacing:Nn #1#2 + { \tl_set:Nx #1 { \exp_after:wN \@@_titlesec_spacing:nnnnnn #1 {#2} } } +\cs_new:Npn \@@_titlesec_spacing:nnnnnn #1#2#3#4#5#6 + { + \exp_not:n { {#1} {#2} {#3} {#4} } + { \bool_if:cTF { CTEX@#6@afterindent } { \@ne } { \z@ } } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +\@ifpackageloaded { titlesec } + { } + { + \ctex_at_end_package:nn { titlesec } + { + \@ifpackagewith { titlesec } { loadonly } + { } + { \ctex_titlesec_hook: } + } + } +% \end{macrocode} +% +% \changes{v2.4.4}{2016/09/13}{使用 \pkg{titlesec} 时,章节目录也使用 \CTeX{} 的编号。} +% 让编译时终端显示 \tn{CTEXthechapter},目录使用 |\CTEXtheXXX| 编号。 +% \begin{macrocode} +\ctex_at_end_package:nn { titlesec } + { +%<*book|report> + \tl_set:Nn \ttl@chapterout { \typeout { \CTEXthechapter } } +%</book|report> + \cs_if_free:NF \ttl@tocpart + { + \cs_set_protected_nopar:Npn \ttl@tocpart + { \tl_set:Nn \ttl@a { \CTEXthepart \hspace { 1em } } } + } + \seq_map_inline:Nn \c_@@_headings_seq + { + \cs_if_exist:cF { ttl@toc #1 } + { + \cs_new_protected_nopar:cpx { ttl@toc #1 } + { + \tl_set:Nn \exp_not:N \ttl@a + { + \exp_not:N \protect + \exp_not:N \numberline { \exp_not:c { CTEXthe #1 } } + } + } + } + } + } +% \end{macrocode} +% +% \paragraph{兼容 \pkg{titleps} 宏包} +% +% \changes{v2.3}{2015/12/25}{兼容 \pkg{titleps} 宏包。} +% +% 按照 \pkg{titleps} 宏包的实现机制,|\CTEXtheXXX| 等宏直到页眉排版时才会被展开, +% 这可能会造成问题\footnote{\url{https://github.com/CTeX-org/ctex-kit/issues/217}}。 +% +% \begin{macro}[int]{\ctex_titleps_hook:} +% 我们修改 \pkg{titleps} 包的内部命令 \tn{ttl@settopmark} 和 \tn{ttl@setsubmark}, +% 将 |\CTEXtheXXX| 等加入更新队列中。 +% \begin{macrocode} +\group_begin: +\char_set_catcode_other:N \# +\cs_new_protected_nopar:Npn \ctex_titleps_hook: + { + \ctex_patch_cmd:Nnn \ttl@settopmark + { \protect \@namedef { the#1 } { \@nameuse { the#1 } } } + { + \protect \@namedef { the#1 } { \@nameuse { the#1 } } + \CTEX@titlepslabel@set {#1} + } + \ctex_patch_cmd:Nnn \ttl@setsubmark + { \protect \@namedef { the#1 } { } } + { + \protect \@namedef { the#1 } { } + \CTEX@titlepslabel@clear {#1} + } + \ctex_patch_cmd:Nnn \ttl@setsubmark + { \protect \@namedef { the#2 } { \@nameuse { the#2 } } } + { + \protect \@namedef { the#2 } { \@nameuse { the#2 } } + \CTEX@titlepslabel@set {#2} + } + } +\group_end: +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\CTEX@titlepslabel@set,\CTEX@titlepslabel@clear} +% 这两个函数要在随后被 \tn{xdef} 展开来获得 |\CTEXtheXXX| 的内容,不应该用 +% \tn{protected} 来定义。 +% \begin{macrocode} +\cs_new_nopar:Npn \CTEX@titlepslabel@set #1 + { + \cs_if_free:cF { CTEXthe#1 } + { \protect \@namedef { CTEXthe#1 } { \@nameuse { CTEXthe#1 } } } + } +\cs_new_nopar:Npn \CTEX@titlepslabel@clear #1 + { + \cs_if_free:cF { CTEXthe#1 } + { \protect \@namedef { CTEXthe#1 } { } } + } +% \end{macrocode} +% \end{macro} +% +% \pkg{titleps} 宏包的功能可以由 \pkg{titlesec} 的选项 \opt{pagestyles} 引入。 +% \begin{macrocode} +\ctex_at_end_package:nn { titlesec } + { \cs_if_free:NF \ttl@settopmark { \ctex_titleps_hook: } } +\ctex_at_end_package:nn { titleps } { \ctex_titleps_hook: } +% \end{macrocode} +% +% 除此之外,也可以使用 \pkg{titleps} 提供的命令 \tn{newtitlemark} 来完成: +% \begin{verbatim} +% \newtitlemark { \CTEXthechapter } +% \newtitlemark { \CTEXthesection } +% \end{verbatim} +% 但 \tn{newtitlemark} 不包含章节间的层次信息,功能上不及修改内部命令完整。 +% +% \changes{v2.4.6}{2016/10/31}{重新初始化 \tn{ifthechapter} 等。} +% \begin{macro}[int]{\ttl@setifthe} +% 使 |\iftheXXX| 等命令在页眉设置中可用。 +% \begin{macrocode} +\ctex_at_end_package:nn { titleps } + { + \cs_set_protected_nopar:Npn \ttl@setifthe #1 + { + \exp_args:Nco \cs_set_nopar:Npn { ifthe #1 } + { + \CTEXifname + { \protect \@firstoftwo } + { \protect \@secondoftwo } + } + } + \seq_map_function:NN \c_@@_headings_seq \ttl@setifthe + } +% \end{macrocode} +% \end{macro} +% +% +% \subsubsection{目录标签的宽度} +% +% \begin{macro}[int]{\numberline} +% \begin{macrocode} +\cs_new_protected:Npn \CTEX@toc@width@n #1 + { + \hbox_set:Nn \l_@@_tmp_box {#1} + \dim_set:Nn \@tempdima + { + \dim_max:nn { \@tempdima } + { \box_wd:N \l_@@_tmp_box + \f@size \p@ / 2 } + } + } +\group_begin: +\char_set_catcode_other:N \# +\use:n + { + \group_end: + \ctex_preto_cmd:NnnTF \numberline { \ExplSyntaxOff } + { \CTEX@toc@width@n {#1} } + { } + { \ctex_patch_failure:N \numberline } + \@ifpackageloaded { tocloft } + { } + { + \ctex_at_end_package:nn { tocloft } + { + \ctex_preto_cmd:NnnTF \numberline + { \char_set_catcode_letter:n { 64 } } + { \CTEX@toc@width@n {#1} } + { } + { \ctex_patch_failure:N \numberline } + } + } + } +% \end{macrocode} +% \end{macro} +% +% \subsubsection{页眉信息的修改} +% +% \begin{macro}[int]{\ps@headings} +% \changes{v2.4.5}{2016/10/01}{修复补丁失败。} +% \changes{v2.4.7}{2016/12/23}{修复 \cls{ctexrep} 类的 \tn{chaptermark} 汉化错误。} +% \changes{v2.4.11}{2017/09/13}{补充页眉空格。} +% \begin{macrocode} +%<*article> +\if@twoside + \ctex_patch_cmd:Nnn \ps@headings + { \ifnum \c@secnumdepth > \z@ \thesection \quad \fi } + { \CTEXifname { \CTEXthesection \quad } { } } + \ctex_patch_cmd:Nnn \ps@headings + { \ifnum \c@secnumdepth > \@ne \thesubsection \quad \fi } + { \CTEXifname { \CTEXthesubsection \quad } { } } +\else: +% \end{macrocode} +% 不知为何,标准文档类此处对 \texttt{secnumdepth} 的判断为 $0$,与 \tn{section} 的层次 $1$ 不符。 +% \begin{macrocode} + \ctex_patch_cmd:Nnn \ps@headings + { \ifnum \c@secnumdepth > \m@ne \thesection \quad \fi } + { \CTEXifname { \CTEXthesection \quad } { } } +\fi: +%</article> +%<*book|report> +\ctex_patch_cmd:Nnn \ps@headings + { +%<book> \ifnum \c@secnumdepth > \m@ne \if@mainmatter +%<report> \ifnum \c@secnumdepth > \m@ne + \@chapapp \ \thechapter . ~ \ % +%<report> \fi +%<book> \fi \fi + } + { \CTEXifname { \CTEXthechapter \quad } { } } +\if@twoside + \ctex_patch_cmd:Nnn \ps@headings + { \ifnum \c@secnumdepth > \z@ \thesection . ~ \ \fi } + { \CTEXifname { \CTEXthesection \quad } { } } +\fi: +%</book|report> +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}[int]{\ps@fancy} +% 这里对 \pkg{fancyhdr} 宏包打补丁。原来 \pkg{fancyhdr} 宏包中使用 +% \tn{thesection} 等宏表示页眉中的章节编号,这里改用 \pkg{ctex} 包所用的 +% \tn{CTEXthesection} 系列宏。 +% \begin{macrocode} +\ctex_at_end_package:nn { fancyhdr } + { +%<*article> + \ctex_patch_cmd:Nnn \ps@fancy + { \ifnum \c@secnumdepth > \z@ \thesection \hskip 1em \relax \fi } + { \CTEXifname { \CTEXthesection \quad } { } } + \ctex_patch_cmd:Nnn \ps@fancy + { \ifnum \c@secnumdepth > \@ne \thesubsection \hskip 1em \relax \fi } + { \CTEXifname { \CTEXthesubsection \quad } { } } +%</article> +%<*book|report> + \ctex_patch_cmd:Nnn \ps@fancy + { \ifnum \c@secnumdepth > \m@ne \@chapapp \ \thechapter . ~ \ \fi } + { \CTEXifname { \CTEXthechapter \quad } { } } + \ctex_patch_cmd:Nnn \ps@fancy + { \ifnum \c@secnumdepth > \z@ \thesection . ~ \ \fi } + { \CTEXifname { \CTEXthesection \quad } { } } +%</book|report> + } +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%</article|book|report> +% \end{macrocode} +% +% \subsubsection{\cls{beamer} 标题页模板的修改} +% +% \begin{macrocode} +%<*beamer> +% \end{macrocode} +% +% \begin{macrocode} +\ExplSyntaxOff +% \end{macrocode} +% +% \changes{v2.4.15}{2019/01/29}{局部指定 \opt{autoindent} 为 \opt{false},并交换 +% \tn{CTEX@XXX@indent} 与 \tn{CTEX@XXX@format} 的顺序。} +% +% 对应 \tn{partpage}。 +% \begin{macrocode} +\defbeamertemplate*{part page}{CTEX}[1][]{% + \begingroup + \CTEX@disableautoindent +% \centering +% {\usebeamerfont{part name}% +% \usebeamercolor[fg]{part name}\partname~\insertromanpartnumber} +% \vskip1em\par + \par \addvspace{\glueexpr\CTEX@part@beforeskip\relax}% + \CTEX@part@format + \parindent \dimexpr \CTEX@part@indent \relax + \ifodd \CTEX@part@numbering + \CTEX@partname \CTEX@part@aftername + \fi + \begin{beamercolorbox}[sep=16pt,center,#1]{part title} +% \usebeamerfont{part title}\insertpart\par + \CTEX@part@titleformat \insertpart \CTEX@part@aftertitle + \end{beamercolorbox}% + \par \addvspace{\glueexpr\CTEX@part@afterskip\relax}% + \endgroup +} +% \end{macrocode} +% +% 对应 \tn{sectionpage}。 +% \begin{macrocode} +\defbeamertemplate*{section page}{CTEX}[1][]{% + \begingroup + \CTEX@disableautoindent +% \centering +% {\usebeamerfont{section name}% +% \usebeamercolor[fg]{section name}\sectionname~\insertsectionnumber} +% \vskip1em\par + \par \addvspace{\glueexpr\CTEX@section@beforeskip\relax}% + \CTEX@section@format + \parindent \dimexpr \CTEX@section@indent \relax + \ifodd \CTEX@section@numbering + \CTEX@sectionname \CTEX@section@aftername + \fi + \begin{beamercolorbox}[sep=12pt,center,#1]{part title} +% \usebeamerfont{section title}\insertsection\par + \CTEX@section@titleformat \insertsection \CTEX@section@aftertitle + \end{beamercolorbox}% + \par \addvspace{\glueexpr\CTEX@section@afterskip\relax}% + \endgroup +} +% \end{macrocode} +% +% 对应 \tn{subsectionpage}。 +% \begin{macrocode} +\defbeamertemplate*{subsection page}{CTEX}[1][]{% + \begingroup + \CTEX@disableautoindent +% \centering +% {\usebeamerfont{subsection name}% +% \usebeamercolor[fg]{subsection name}\subsectionname~\insertsubsectionnumber} +% \vskip1em\par + \par \addvspace{\glueexpr\CTEX@subsection@beforeskip\relax}% + \CTEX@subsection@format + \parindent \dimexpr \CTEX@subsection@indent \relax + \ifodd \CTEX@subsection@numbering + \CTEX@subsectionname \CTEX@subsection@aftername + \fi + \begin{beamercolorbox}[sep=8pt,center,#1]{part title} +% \usebeamerfont{subsection title}\insertsubsection\par + \CTEX@subsection@titleformat \insertsubsection \CTEX@subsection@aftertitle + \end{beamercolorbox}% + \par \addvspace{\glueexpr\CTEX@subsection@afterskip\relax}% + \endgroup +} +% \end{macrocode} +% +% 将 \cls{beamer} 的默认模板重定向为 \texttt{CTEX} 模板。 +% \begin{macrocode} +\defbeamertemplatealias{part page}{default}{CTEX} +\defbeamertemplatealias{section page}{default}{CTEX} +\defbeamertemplatealias{subsection page}{default}{CTEX} +% \end{macrocode} +% +% \begin{macrocode} +\ExplSyntaxOn +% \end{macrocode} +% +% \begin{macrocode} +%</beamer> +% \end{macrocode} +% +% \subsubsection{标签引用数字的汉化} +% +% \begin{macro}[int]{\refstepcounter} +% 对标题进行引用时,设置标签为通过 \opt{number} 选项设置的形式。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \CTEX@setcurrentlabel@n #1 + { + \protected@edef \@currentlabel + { + \cs_if_exist:cTF { CTEX@the#1 } + { \exp_args:cc { p@#1 } { CTEX@the#1 } } + { \exp_not:o { \@currentlabel } } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_varioref_hook:} +% 关于标签引用的宏包可能会修改 \tn{refstepcounter}。其中 \pkg{cleveref} 和 +% \pkg{hyperref} 宏包都会保存之前的定义,并且它们都要求尽可能晚的被载入,所以 +% 对我们上述的修改影响不大。需要注意的是 \pkg{varioref} 宏包,如果它在 +% \CTeX{} 之后被载入,我们之前的修改将会被覆盖。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_varioref_hook: + { + \seq_map_inline:Nn \c_@@_headings_seq + { \ctex_fix_varioref_label:n { ##1 } } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_fix_varioref_label:n} +% \pkg{varioref} 宏包的 \tn{labelformat} 实际上是定义一个以 |\the<#1>| 为参数的宏 +% |\p@<#1>|。\LaTeX{} 在定义计数器 |<#1>| 时,都会将 |\p@<#1>| 初始化为 \tn{@empty}。 +% 如果这个宏非空,说明用户自定义了标签格式,我们就不再修改。这里不能使用 +% \cs{exp_args:Nnc},因为 \texttt{c} 这种展开格式不会将参数放在花括号内。而 +% \tn{labelformat} 的定义是 +% \begin{verbatim} +% \def\labelformat#1{\expandafter\def\csname p@#1\endcsname##1} +% \end{verbatim} +% 它的第二个参数必须放在花括号内,否则将会被作为宏的定界符号。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_fix_varioref_label:n #1 + { + \tl_if_empty:cT { p@#1 } + { \exp_args:Nno \labelformat {#1} { \cs:w CTEX@the#1 \cs_end: } } + } +% \end{macrocode} +% \end{macro} +% +% 如果 \pkg{varioref} 已经被载入,则使用它来设置。 +% \begin{macrocode} +\@ifpackageloaded { varioref } + { \ctex_varioref_hook: } + { + \cs_new_eq:NN \CTEX@save@refstepcounter \refstepcounter + \RenewDocumentCommand \refstepcounter { m } + { + \CTEX@save@refstepcounter {#1} + \CTEX@setcurrentlabel@n {#1} + } + \ctex_at_end_package:nn { varioref } { \ctex_varioref_hook: } + } +% \end{macrocode} +% +% \subsubsection{载入 \meta{scheme} 文件} +% +% \begin{macrocode} +\ctex_scheme_input:o { \l_@@_scheme_tl } +% \end{macrocode} +% +% \begin{macrocode} +%</class|heading> +% \end{macrocode} +% +% \subsubsection{标题格式的 \opt{scheme} 定义} +% +% 下面使用 \CTeX 文档类的设置方式,\opt{plain} 模拟标准文档类直接定义或以 +% \tn{@startsection} 设定的章节标题格式,\opt{chinese} 汉化的标题格式。 +% +% \begin{macrocode} +%<*scheme&(article|book|report|beamer)> +% \end{macrocode} +% +% \changes{v2.1}{2015/05/30}{修复 \cls{ctexbook} 和 \cls{ctexrep} 类的中文 +% \opt{part/number} 选项初值为空的错误。} +% \changes{v2.2}{2015/06/30}{将中文版式下的 \texttt{part} 和 \texttt{chapter} +% 标题的 \opt{nameformat} 和 \opt{titleformat} 选项的初值合并到 \opt{format} 中。} +% +% \begin{macrocode} +\keys_set:nn { ctex / part } + { + aftertitle = \par , +%<*article|book|report> + hang = false , +%</article|book|report> +%<*plain> + name = \partname \space , +%<*article|book|report> + number = \thepart , +%</article|book|report> +%<*beamer> + number = \insertromanpartnumber , +%</beamer> +%</plain> +%<*chinese> + number = \chinese { part } , +%</chinese> +%<*article> + beforeskip = 4ex , + afterskip = 3ex , +%<*plain> + format = \raggedright , + nameformat = \Large \bfseries , + aftername = \par \nobreak , + titleformat = \huge \bfseries , + afterindent = false +%</plain> +%<*chinese> + format = \Large \bfseries \centering , + aftername = \quad , + afterindent = true +%</chinese> +%</article> +%<*book|report> + aftername = \par \vskip 20 \p@ , + beforeskip = 0pt \@plus 1fil , + afterskip = 0pt \@plus 1fil , + pagestyle = plain , + break = \if@openright \cleardoublepage \else \clearpage \fi , +%<*plain> + format = \centering , + nameformat = \huge \bfseries , + titleformat = \Huge \bfseries +%</plain> +%<*chinese> + format = \huge \bfseries \centering +%</chinese> +%</book|report> +%<*beamer> + format = \centering , + nameformat = \usebeamerfont { part ~ name } + \usebeamercolor [fg] { part ~ name } , + aftername = \vskip 1em \par , + titleformat = \usebeamerfont { part ~ title } +%</beamer> + } +% \end{macrocode} +% +% \begin{macrocode} +%<*book|report> +\keys_set:nn { ctex / chapter } + { + pagestyle = plain , + aftertitle = \par , + hang = false , + beforeskip = 50 \p@ , + afterskip = 40 \p@ , + lofskip = 10 \p@ , + lotskip = 10 \p@ , + break = \if@openright \cleardoublepage \else \clearpage \fi , +%<*plain> + name = \chaptername \space , + number = \thechapter , + format = \raggedright , + nameformat = \huge \bfseries , + aftername = \par \nobreak \vskip 20 \p@ , + titleformat = \Huge \bfseries , + afterindent = false , + tocline = \CTEXnumberline {#1} #2 +%</plain> +%<*chinese> + number = \chinese { chapter } , + format = \huge \bfseries \centering , + aftername = \quad , + afterindent = true +%</chinese> + } +%</book|report> +% \end{macrocode} +% +% \begin{macrocode} +%<@@=> +% \end{macrocode} +% +% \begin{macrocode} +\keys_set:nn { ctex / section } + { +%<*article|book|report> + number = \thesection , + aftername = \quad , + aftertitle = \@@par , + beforeskip = 3.5ex \@plus 1ex \@minus .2ex , + afterskip = 2.3ex \@plus .2ex , + runin = false , + break = \addpenalty \@secpenalty , +%<*plain> + format = \Large \bfseries , + afterindent = false +%</plain> +%<*chinese> + format = \Large \bfseries \centering , + afterindent = true +%</chinese> +%</article|book|report> +%<*beamer> +%<*plain> + name = \sectionname \space , +%</plain> + format = \centering , + number = \insertsectionnumber , + nameformat = \usebeamerfont { section ~ name } + \usebeamercolor [fg] { section ~ name } , + aftername = \vskip 1em \par , + titleformat = \usebeamerfont { section ~ title } , + aftertitle = \par +%</beamer> + } +% \end{macrocode} +% +% \begin{macrocode} +\keys_set:nn { ctex / subsection } + { +%<*article|book|report> + number = \thesubsection , + format = \large \bfseries , + aftername = \quad , + aftertitle = \@@par , + beforeskip = 3.25ex \@plus 1ex \@minus .2ex , + afterskip = 1.5ex \@plus .2ex , + runin = false , + break = \addpenalty \@secpenalty , +%<*plain> + afterindent = false +%</plain> +%<*chinese> + afterindent = true +%</chinese> +%</article|book|report> +%<*beamer> +%<*plain> + name = \subsectionname \space , + number = \insertsubsectionnumber , +%</plain> +%<*chinese> + number = \arabic { section } . \arabic { subsection } , +%</chinese> + format = \centering , + nameformat = \usebeamerfont { subsection ~ name } + \usebeamercolor [fg] { subsection ~ name } , + aftername = \vskip 1em \par , + titleformat = \usebeamerfont { subsection ~ title } , + aftertitle = \par +%</beamer> + } +% \end{macrocode} +% +% \begin{macrocode} +%<*article|book|report> +% \end{macrocode} +% +% \begin{macrocode} +\keys_set:nn { ctex / subsubsection } + { + number = \thesubsubsection , + format = \normalsize \bfseries , + aftername = \quad , + aftertitle = \@@par , + beforeskip = 3.25ex \@plus 1ex \@minus .2ex , + afterskip = 1.5ex \@plus .2ex , + runin = false , + break = \addpenalty \@secpenalty , +%<*plain> + afterindent = false +%</plain> +%<*chinese> + afterindent = true +%</chinese> + } +% \end{macrocode} +% +% \begin{macrocode} +\keys_set:nn { ctex / paragraph } + { + number = \theparagraph , + format = \normalsize \bfseries , + aftername = \quad , + beforeskip = 3.25ex \@plus 1ex \@minus .2ex , + break = \addpenalty \@secpenalty , +%<*plain> + afterindent = false +%</plain> +%<*chinese> + afterindent = true +%</chinese> + } +% \end{macrocode} +% +% \begin{macrocode} +\keys_set:nn { ctex / subparagraph } + { + number = \thesubparagraph , + format = \normalsize \bfseries , + aftername = \quad , + beforeskip = 3.25ex \@plus 1ex \@minus .2ex , + break = \addpenalty \@secpenalty , +%<*plain> + afterindent = false +%</plain> +%<*chinese> + afterindent = true +%</chinese> + } +% \end{macrocode} +% +% 处理 \opt{sub3section} 与 \opt{sub4section} 的格式。 +% \begin{macrocode} +\int_compare:nNnTF \g__ctex_section_depth_int > 2 + { + \keys_set:nn { ctex / paragraph } + { + aftertitle = \@@par , + afterskip = 1ex \@plus .2ex , + runin = false + } + } + { + \keys_set:nn { ctex / paragraph } + { + afterskip = 1em , + runin = true + } + } +\int_compare:nNnTF \g__ctex_section_depth_int > 3 + { + \keys_set:nn { ctex / subparagraph } + { + aftertitle = \@@par , + afterskip = 1ex \@plus .2ex , + runin = false + } + } + { + \keys_set:nn { ctex / subparagraph } + { + afterskip = 1em , + runin = true + } + } +\int_compare:nNnTF \g__ctex_section_depth_int > 2 + { \keys_set:nn { ctex / subparagraph } { indent = \c_zero_dim } } + { \keys_set:nn { ctex / subparagraph } { indent = \parindent } } +% \end{macrocode} +% +% \begin{macrocode} +%<@@=ctex> +% \end{macrocode} +% +% 处理附录的格式。 +% \begin{macrocode} +\keys_set:nn { ctex / appendix } +%<*article> + { number = \@Alph \c@section } +%</article> +%<*book|report> + { + name = \appendixname \space , + number = \@Alph \c@chapter + } +%</book|report> +% \end{macrocode} +% +% \begin{macrocode} +%</article|book|report> +% \end{macrocode} +% +% \begin{macrocode} +%</scheme&(article|book|report|beamer)> +% \end{macrocode} +% +% \subsubsection{\pkg{ctex.sty} 的 \opt{heading} 选项} +% +% \begin{macrocode} +%<*ctex|ctexheading> +% \end{macrocode} +% +% \begin{variable}{\c_@@_std_class_tl} +% 用于记录被引入的标准文档类。 +% \begin{macrocode} +\clist_map_inline:nn { article , book , report , beamer } + { + \@ifclassloaded {#1} + { \clist_map_break:n { \tl_const:Nn \c_@@_std_class_tl {#1} } } + { } + } +% \end{macrocode} +% \end{variable} +% +% 若标准文档类被引入,则载入对应的标题定义文件。否则视 \tn{chapter} 是否有定义来 +% 引入 \cls{book} 或者 \cls{article}。 +% \begin{macrocode} +\msg_new:nnn { ctex } { not-standard-class } + { + None~of~the~standard~document~classes~was~loaded.\\ + Heading~`#1'~is~selected.\\ + ctex~may~not~work~as~expected. + } +%<ctex>\bool_if:NTF \l_@@_heading_bool +%<ctexheading>\use:n + { + \tl_if_exist:NTF \c_@@_std_class_tl + { \cs_new_eq:NN \c_@@_class_tl \c_@@_std_class_tl } + { + \cs_if_exist:NTF \chapter + { + \cs_if_exist:NF \if@mainmatter + { \cs_new_eq:NN \if@mainmatter \tex_iftrue:D } + \tl_const:Nn \c_@@_class_tl { book } + } + { \tl_const:Nn \c_@@_class_tl { article } } + \msg_warning:nnx { ctex } { not-standard-class } { \c_@@_class_tl } + } + \ctex_file_input:n { ctex- \c_@@_class_tl .def } + } +%<ctex> { \ctex_scheme_input:o { \l_@@_scheme_tl } } +% \end{macrocode} +% +% \begin{macrocode} +%</ctex|ctexheading> +% \end{macrocode} +% +% \subsubsection{标题配置文件} +% +% \begin{macrocode} +%<*name> +% \end{macrocode} +% +% \begin{macrocode} +\keys_set_known:nn { ctex } + { + contentsname = 目录 , + listfigurename = 插图 , + listtablename = 表格 , + figurename = 图 , + tablename = 表 , + abstractname = 摘要 , + indexname = 索引 , + bibname = 参考文献 , + appendixname = 附录 , + proofname = 证明 , + algorithmname = 算法 , + refname = 参考文献 , + continuation = (续) , + part / name = { 第 , 部分 } , + chapter / name = { 第 , 章 } + } +% \end{macrocode} +% +% \begin{macrocode} +%</name> +% \end{macrocode} +% +% \subsection{\opt{chinese} 方案的其他设置} +% +% \begin{macrocode} +%<*scheme&chinese> +% \end{macrocode} +% +% \opt{chinese} 在标准文档类下的页面格式总采用 \texttt{headings}。 +% \begin{macrocode} +%<article|book|report>\pagestyle { headings } +% \end{macrocode} +% +% 日期格式。 +% \begin{macrocode} +\keys_set:nn { ctex } { today = small } +% \end{macrocode} +% +% 若用户未设置宏包选项 \opt{autoindent},则自动调整首行缩进。 +% \begin{macrocode} +\ctex_if_autoindent_touched:F + { \keys_set:nn { ctex } { autoindent = true } } +% \end{macrocode} +% +% 使用标题定义时的设置。首先是命题名字汉化。\cls{beamer} 需要汉化定理名称。 +% \begin{macrocode} +%<*!generic> +\str_if_eq:onTF { \l_@@_encoding_tl } { GBK } +%<*beamer> + { + \uselanguage { ChineseGBK } + \languagealias { chinese } { ChineseGBK } + \ctex_file_input:n { ctex-name-gbk.cfg } + } + { + \uselanguage { ChineseUTF8 } + \languagealias { chinese } { ChineseUTF8 } + \ctex_file_input:n { ctex-name-utf8.cfg } + } +% \end{macrocode} +% 让 \pkg{translator} 包优先查找中文翻译。 +% \begin{macrocode} +\clist_put_left:Nn \trans@languagepath { chinese } +%</beamer> +%<*!beamer> + { \ctex_file_input:n { ctex-name-gbk.cfg } } + { \ctex_file_input:n { ctex-name-utf8.cfg } } +% \end{macrocode} +% +% \changes{v2.4.1}{2016/05/09}{\cls{beamer} 不调整默认字体大小。} +% 对 \cls{beamer} 以外的文档类,若用户未设置宏包选项 \opt{zihao},则设置 \tn{normalsize} +% 为五号字。\cls{beamer} 不调整默认字体大小。 +% \begin{macrocode} +\int_compare:nNnF \g_@@_font_size_int > { -1 } + { \int_gset:Nn \g_@@_font_size_int { 0 } } +% \end{macrocode} +% +% \changes{v2.4.1}{2016/05/09}{\cls{beamer} 不调整默认行距。} +% 对 \cls{beamer} 以外的文档类,若用户未设置宏包选项 \opt{linespread},则设置行 +% 距初始值为 $1.3\times 1.2=1.56$ 倍字体大小。\cls{beamer} 不调整行距。 +% \begin{macrocode} +\fp_compare:nNnT { \l_@@_line_spread_fp } ? { \c_zero_fp } + { \fp_set:Nn \l_@@_line_spread_fp { 1.3 } } +%</!beamer> +%</!generic> +% \end{macrocode} +% +% 不使用标题定义时的通用设置。 +% \begin{macrocode} +%<*generic> +\tl_set:Nn \l_@@_tmp_tl { beamer } +\tl_if_eq:NNTF \c_@@_std_class_tl \l_@@_tmp_tl + { + \str_if_eq:onTF { \l_@@_encoding_tl } { GBK } + { + \uselanguage { ChineseGBK } + \languagealias { chinese } { ChineseGBK } + \ctex_file_input:n { ctex-name-gbk.cfg } + } + { + \uselanguage { ChineseUTF8 } + \languagealias { chinese } { ChineseUTF8 } + \ctex_file_input:n { ctex-name-utf8.cfg } + } + \clist_put_left:Nn \trans@languagepath { chinese } + } + { + \str_if_eq:onTF { \l_@@_encoding_tl } { GBK } + { \ctex_file_input:n { ctex-name-gbk.cfg } } + { \ctex_file_input:n { ctex-name-utf8.cfg } } + \int_compare:nNnF \g_@@_font_size_int > { -1 } + { \int_gset:Nn \g_@@_font_size_int { 0 } } + \fp_compare:nNnT { \l_@@_line_spread_fp } ? { \c_zero_fp } + { \fp_set:Nn \l_@@_line_spread_fp { 1.3 } } +% \end{macrocode} +% \changes{v2.0.2}{2015/05/16}{修复加载 \pkg{ctex} 宏包后章节标题后第一段 +% 无段首缩进的问题。} +% 若 \pkg{ctex} 宏包与标准文档类及其衍生文档类联用,则将载入 \pkg{indentfirst} 宏包, +% 实现章节标题后首个段落的段首缩进。 +% \begin{macrocode} + \tl_if_exist:NT \c_@@_std_class_tl + { \RequirePackage { indentfirst } } + } +%</generic> +% \end{macrocode} +% +% \begin{macrocode} +%</scheme&chinese> +% \end{macrocode} +% +% \subsection{中文字号} +% +% \begin{macrocode} +%<*class|ctex|ctexsize> +% \end{macrocode} +% +% \changes{v2.0}{2014/03/08}{将中文字号功能提取到可以独立使用的 \pkg{ctexsize}。} +% +% \begin{macro}{\zihao} +% \begin{macrocode} +\NewDocumentCommand \zihao { m } + { \exp_args:Nx \ctex_zihao:n {#1} \tex_ignorespaces:D } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_zihao:n} +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_zihao:n #1 + { + \prop_get:NnNTF \c_@@_font_size_prop {#1} \l_@@_font_size_tl + { \exp_after:wN \fontsize \l_@@_font_size_tl \selectfont } + { \msg_error:nnn { ctex } { fontsize } {#1} } + } +\msg_new:nnnn { ctex } { fontsize } + { Undefined~Chinese~font~size~`#1'~in~command~\token_to_str:N \zihao.} + { + The~old~font~size~is~used~if~you~continue.\\ + The~available~font~sizes~are~listed~as~follow.\\ + \seq_use:Nnnn \c_@@_font_size_seq { ~and~ } { ,~ } { ,~and~ }. + } +% \end{macrocode} +% \end{macro} +% +% \subsubsection{定义中文字号} +% +% \changes{v2.0}{2014/03/08}{中文字号不再采用近似值。} +% +% \begin{variable}{\c_@@_font_size_prop} +% \begin{macro}{\@@_save_font_size:nn} +% 基础行距是字号的 $1.2$ 倍,采用 \hologo{eTeX} 的 scaling 运算得到的结果 +% 要比简单的 |1.2\dimexpr| 精确^^A +% \footnote{\url{http://thread.gmane.org/gmane.comp.tex.latex.latex3/3190}}。 +% \begin{macrocode} +\prop_new:N \c_@@_font_size_prop +\seq_new:N \c_@@_font_size_seq +\cs_new_protected_nopar:Npn \@@_save_font_size:nn #1#2 + { + \use:x + { + \prop_gput:Nnn \exp_not:N \c_@@_font_size_prop {#1} + { + { \dim_to_decimal:n {#2} } + { \dim_to_decimal:n { (#2) * 6 / 5 } } + } + } + \seq_gput_right:Nn \c_@@_font_size_seq {#1} + } +\clist_map_inline:nn + { + { 8 } { 5 bp } , + { 7 } { 5.5 bp } , + { -6 } { 6.5 bp } , + { 6 } { 7.5 bp } , + { -5 } { 9 bp } , + { 5 } { 10.5 bp } , + { -4 } { 12 bp } , + { 4 } { 14 bp } , + { -3 } { 15 bp } , + { 3 } { 16 bp } , + { -2 } { 18 bp } , + { 2 } { 22 bp } , + { -1 } { 24 bp } , + { 1 } { 26 bp } , + { -0 } { 36 bp } , + { 0 } { 42 bp } + } + { \@@_save_font_size:nn #1 } +% \end{macrocode} +% \end{macro} +% \end{variable} +% +% \begin{macro}[int]{\ctex_declare_math_sizes:nnnn} +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_declare_math_sizes:nnnn #1#2#3#4 + { + \@@_get_font_sizes:Nn \l_@@_font_size_tl { {#1} {#2} {#3} {#4} } + \exp_after:wN \DeclareMathSizes \l_@@_font_size_tl + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_get_font_sizes:Nn} +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_get_font_sizes:Nn #1#2 + { + \tl_clear:N #1 + \tl_map_inline:nn {#2} + { + \prop_get:NnNTF \c_@@_font_size_prop {##1} \l_@@_tmp_tl + { \tl_put_right:Nx #1 { { \tl_head:N \l_@@_tmp_tl } } } + { \tl_put_right:Nx #1 { { \dim_to_decimal:n { ##1 } } } } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +\clist_map_inline:nn + { + { 8 }{ 8 }{ 5pt }{ 5pt } , + { 7 }{ 7 }{ 5pt }{ 5pt } , + { -6 }{ -6 }{ 5pt }{ 5pt } , + { 6 }{ 6 }{ 5pt }{ 5pt } , + { -5 }{ -5 }{ 6pt }{ 5pt } , + { 5 }{ 5 }{ 7pt }{ 5pt } , + { -4 }{ -4 }{ 8pt }{ 6pt } , + { 4 }{ 4 }{ 5 }{ 6 } , + { -3 }{ -3 }{ -4 }{ -5 } , + { 3 }{ 3 }{ 4 }{ 5 } , + { -2 }{ -2 }{ -3 }{ -4 } , + { 2 }{ 2 }{ 3 }{ 4 } , + { -1 }{ -1 }{ -2 }{ -3 } , + { 1 }{ 1 }{ 2 }{ 3 } , + { -0 }{ -0 }{ -1 }{ -2 } , + { 0 }{ 0 }{ 1 }{ 2 } + } + { \ctex_declare_math_sizes:nnnn #1 } +% \end{macrocode} +% +% \subsubsection{修改默认字号大小} +% +% \begin{macro}[int]{\ctex_set_font_size:Nnn} +% \begin{macrocode} +\cs_new_protected:Npn \ctex_set_font_size:Nnn #1#2#3 + { + \prop_get:NnNTF \c_@@_font_size_prop {#2} \l_@@_font_size_tl + { \exp_after:wN \@@_set_font_size:nnNn \l_@@_font_size_tl #1 {#3} } + { \msg_error:nnn { ctex } { fontsize } {#2} } + } +\cs_new_protected:Npn \@@_set_font_size:nnNn #1#2#3#4 + { \cs_set_protected_nopar:Npn #3 { \@setfontsize #3 {#1} {#2} #4 } } +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +\if_case:w \g_@@_font_size_int + \ctex_file_input:n { ctex-c5size.clo } +\or: + \ctex_file_input:n { ctex-cs4size.clo } +\fi: +% \end{macrocode} +% +% \begin{macrocode} +%</class|ctex|ctexsize> +% \end{macrocode} +% +% \begin{macrocode} +%<*c5size> +\ctex_set_font_size:Nnn \normalsize { 5 } + { + \abovedisplayskip 10\p@ \@plus2\p@ \@minus5\p@ + \abovedisplayshortskip \z@ \@plus3\p@ + \belowdisplayshortskip 6\p@ \@plus3\p@ \@minus3\p@ + \belowdisplayskip \abovedisplayskip + \let\@listi\@listI + } +\ctex_set_font_size:Nnn \small { -5 } + { + \abovedisplayskip 8.5\p@ \@plus3\p@ \@minus4\p@ + \abovedisplayshortskip \z@ \@plus2\p@ + \belowdisplayshortskip 4\p@ \@plus2\p@ \@minus2\p@ + \def\@listi{\leftmargin\leftmargini + \topsep 4\p@ \@plus2\p@ \@minus2\p@ + \parsep 2\p@ \@plus\p@ \@minus\p@ + \itemsep \parsep} + \belowdisplayskip \abovedisplayskip + } +\ctex_set_font_size:Nnn \footnotesize { 6 } + { + \abovedisplayskip 6\p@ \@plus2\p@ \@minus4\p@ + \abovedisplayshortskip \z@ \@plus\p@ + \belowdisplayshortskip 3\p@ \@plus\p@ \@minus2\p@ + \def\@listi{\leftmargin\leftmargini + \topsep 3\p@ \@plus\p@ \@minus\p@ + \parsep 2\p@ \@plus\p@ \@minus\p@ + \itemsep \parsep} + \belowdisplayskip \abovedisplayskip + } +\ctex_set_font_size:Nnn \scriptsize { -6 } { } +\ctex_set_font_size:Nnn \tiny { 7 } { } +\ctex_set_font_size:Nnn \large { -4 } { } +\ctex_set_font_size:Nnn \Large { -3 } { } +\ctex_set_font_size:Nnn \LARGE { -2 } { } +\ctex_set_font_size:Nnn \huge { 2 } { } +\ctex_set_font_size:Nnn \Huge { 1 } { } +%</c5size> +%<*cs4size> +\ctex_set_font_size:Nnn \normalsize { -4 } + { + \abovedisplayskip 12\p@ \@plus3\p@ \@minus7\p@ + \abovedisplayshortskip \z@ \@plus3\p@ + \belowdisplayshortskip 6.5\p@ \@plus3.5\p@ \@minus3\p@ + \belowdisplayskip \abovedisplayskip + \let\@listi\@listI + } +\ctex_set_font_size:Nnn \small { 5 } + { + \abovedisplayskip 11\p@ \@plus3\p@ \@minus6\p@ + \abovedisplayshortskip \z@ \@plus3\p@ + \belowdisplayshortskip 6.5\p@ \@plus3.5\p@ \@minus3\p@ + \def\@listi{\leftmargin\leftmargini + \topsep 9\p@ \@plus3\p@ \@minus5\p@ + \parsep 4.5\p@ \@plus2\p@ \@minus\p@ + \itemsep \parsep} + \belowdisplayskip \abovedisplayskip + } +\ctex_set_font_size:Nnn \footnotesize { -5 } + { + \abovedisplayskip 10\p@ \@plus2\p@ \@minus5\p@ + \abovedisplayshortskip \z@ \@plus3\p@ + \belowdisplayshortskip 6\p@ \@plus3\p@ \@minus3\p@ + \def\@listi{\leftmargin\leftmargini + \topsep 6\p@ \@plus2\p@ \@minus2\p@ + \parsep 3\p@ \@plus2\p@ \@minus\p@ + \itemsep \parsep} + \belowdisplayskip \abovedisplayskip + } +\ctex_set_font_size:Nnn \scriptsize { 6 } { } +\ctex_set_font_size:Nnn \tiny { -6 } { } +\ctex_set_font_size:Nnn \large { -3 } { } +\ctex_set_font_size:Nnn \Large { -2 } { } +\ctex_set_font_size:Nnn \LARGE { 2 } { } +\ctex_set_font_size:Nnn \huge { -1 } { } +\ctex_set_font_size:Nnn \Huge { 1 } { } +%</cs4size> +% \end{macrocode} +% +% \begin{macrocode} +%<ctexsize>\normalsize +% \end{macrocode} +% +% \begin{macrocode} +%<*class|ctex> +% \end{macrocode} +% +% \subsection{更新行距} +% +% \cs{l_@@_line_spread_fp} 被设置了才有必要更新行距和 \tn{footnotesep}。 +% \begin{macrocode} +\fp_compare:nNnF { \l_@@_line_spread_fp } ? { \c_zero_fp } + { + \exp_args:Nx \linespread { \fp_use:N \l_@@_line_spread_fp } +% \end{macrocode} +% +% \changes{v2.0}{2014/04/23}{调整 \tn{footnotesep} 的大小,以适合行距的变化。} +% +% \begin{variable}[int]{\footnotesep} +% 我们调整了行距,可能导致脚注的间距与行距不协调,需要调整 \tn{footnotesep}。标准 +% 文档类对 \tn{footnotesep} 的设置是,字体大小为 \tn{footnotesize} 时 \tn{strutbox} +% 的高度(默认值是 |.7\baselineskip|)。我们沿用这个设置方法,只需要更新具体的大小。 +% \begin{macrocode} + \group_begin: \footnotesize \exp_args:NNNo \group_end: + \dim_set:Nn \footnotesep { \dim_use:N \box_ht:N \strutbox } + } +% \end{macrocode} +% \end{variable} +% +% 激活默认字体大小,更新行距、\tn{parindent} 和 \tn{CJKglue}。 +% \begin{macrocode} +\normalsize +% \end{macrocode} +% +% \subsection{其它功能} +% +% \begin{macro}{\CTeX} +% \changes{v2.4.12}{2017/12/05}{不依赖 \tn{ifincsname}。} +% \file{ctex-faq.sty} 中的定义是 +% \begin{verbatim} +% \DeclareRobustCommand\CTeX{$\mathbb{C}$\kern-.05em\TeX} +% \end{verbatim} +% 然而 \tn{mathbb} 未必有定义,这里就不采用它了,只定义最简单的形式。 +% \CTeX{} 可以直接用在 PDF 书签中。 +% \begin{macrocode} +\NewDocumentCommand \CTeX { } + { C \TeX } +\ctex_at_end_package:nn { hyperref } + { \pdfstringdefDisableCommands { \tl_set:Nn \CTeX { CTeX } } } +% \end{macrocode} +% \end{macro} +% +% \changes{v2.0}{2014/03/28}{\opt{captiondelimiter} 是过时选项。} +% \begin{macro}{captiondelimiter} +% 过时选项。 +% \begin{macrocode} +\keys_define:nn { ctex } + { + captiondelimiter .code:n = + { + \msg_warning:nnn { ctex } { deprecated-option } + { You~can~load~the~package~`caption'~to~get~its~functionality. } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%</class|ctex> +% \end{macrocode} +% +% \subsubsection{列表环境的缩进} +% +% \begin{macro}[int]{\verse,\quotation} +% 只在使用文档类的时候修改诗歌和引用环境的缩进。 +% \begin{macrocode} +%<*scheme&chinese&(article|book|report)> +\ctex_patch_cmd:Nnn \verse { -1.5em } { -2 \ccwd } +\ctex_patch_cmd:Nnn \verse { 1.5em } { 2 \ccwd } +\ctex_patch_cmd:Nnn \quotation { 1.5em } { 2 \ccwd } +%</scheme&chinese&(article|book|report)> +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%<*class|ctex> +% \end{macrocode} +% +% \changes{v2.0}{2014/03/09} +% {解决 \pkg{etoolbox} 与 \pkg{breqn} 关于 \tn{end} 的冲突。} +% \changes{v2.2}{2015/06/23}{删去 \pkg{etoolbox} 与 \pkg{breqn} 的兼容补丁。} +% +% \subsection{载入中文字体} +% +% \begin{macro}[int]{\ctex_fontset_error:n} +% 字库不可用时给出紧急错误信息,停止读取定义文件。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_fontset_error:n #1 + { \msg_critical:nnn { ctex } { fontset-unavailable } {#1} } +\msg_new:nnn { ctex } { fontset-unavailable } + { CTeX~fontset~`#1'~is~unavailable~in~current~mode. } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_load_fontset:} +% 如果用户没有指定字体,则探测操作系统,载入相应的字体配置。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_load_fontset: + { + \tl_if_empty:NTF \g_@@_fontset_tl + { + \ctex_detected_platform: + \ctex_file_input:n { ctex-fontset- \g_@@_fontset_tl .def } + } + { + \file_if_exist:nTF { ctex-fontset- \g_@@_fontset_tl .def } + { \ctex_file_input:n { ctex-fontset- \g_@@_fontset_tl .def } } + { + \use:x + { + \ctex_detected_platform: + \msg_error:nnxx { ctex } { fontset-not-found } + { \g_@@_fontset_tl } { \exp_not:N \g_@@_fontset_tl } + } + \ctex_file_input:n { ctex-fontset- \g_@@_fontset_tl .def } + } + } + } +\@onlypreamble \ctex_load_fontset: +\msg_new:nnnn { ctex } { fontset-not-found } + { + CTeX~fontset~`#1'~could~not~be~found.\\ + Fontset~`#2'~will~be~used~instead. + } + { You~may~run~`mktexlsr'~firstly. } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{fontset} +% 在导言区通过 \tn{ctexset} 载入中文字库的选项。 +% \begin{macrocode} +\keys_define:nn { ctex } + { + fontset .code:n = + { + \ctex_if_preamble:TF + { + \str_if_eq:eeTF {#1} { none } + { \msg_warning:nnn { ctex } { invalid-value } {#1} } + { + \str_if_eq:onTF { \g_@@_fontset_tl } { none } + { + \tl_gset:Nx \g_@@_fontset_tl {#1} + \ctex_load_fontset: + } + { + \msg_error:nnxx { ctex } { fontset-loaded } + { \g_@@_fontset_tl } {#1} + } + } + } + { \msg_error:nn { ctex } { fontset-only-preamble } } + } + } +\msg_new:nnnn { ctex } { fontset-loaded } + { + CTeX~fontset~`#1'~has~been~loaded. + \str_if_eq:nnF {#1} {#2} { \\ Fontset~`#2'~will~be~ignored. } + } + { Only~one~fontset~can~be~loaded~in~the~preamble. } +\msg_new:nnn { ctex } { fontset-only-preamble } + { + The~ `fontset'~ option~ can~ be~ used~ only~ in~ preamble. + } +% \end{macrocode} +% \end{macro} +% +% 载入中文字库。 +% \begin{macrocode} +\str_if_eq:onF { \g_@@_fontset_tl } { none } + { \ctex_load_fontset: } +% \end{macrocode} +% +% \subsection{宏包配置文件} +% +% \subsubsection{\pkg{ctex.cfg}} +% +% \begin{macrocode} +\ctex_at_end:n { \ctex_file_input:n { ctex.cfg } } +% \end{macrocode} +% +% \begin{macrocode} +%</class|ctex> +% \end{macrocode} +% +% \begin{macrocode} +%<*config> +%% +%</config> +% \end{macrocode} +% +% \subsubsection{\pkg{ctexopts.cfg}} +% +% 这里仅为配置文件示例:使用 Windows Vista 或以后版本的字体设置。 +% \begin{macrocode} +%<*ctexopts> +%% +%% \keys_set:nn { ctex / option } { fontset = windowsnew } +%</ctexopts> +% \end{macrocode} +% +% \subsection{字体定义文件} +% +% \subsubsection{传统定义方式} +% +% \changes{v2.4.15}{2019/04/05}{将 \texttt{JY2} 和 \texttt{JT2} 编码的字体定义提取到单独的文件中。} +% +% \begin{macrocode} +%<*c19|c70> +%% +%% Chinese characters +%% +%<c19>%% character set: GBK (extension of GB 2312) +%<c70>%% character set: Unicode +%% font encoding: Unicode +%% +%</c19|c70> +% \end{macrocode} +% +% \pkg{CJK} 宏包使用的字体族。 +% \begin{macrocode} +%<rm&c19>\DeclareFontFamily{C19}{rm}{\hyphenchar\font\m@ne} +%<rm&c70>\DeclareFontFamily{C70}{rm}{\hyphenchar\font\m@ne} +%<sf&c19>\DeclareFontFamily{C19}{sf}{\hyphenchar\font\m@ne} +%<sf&c70>\DeclareFontFamily{C70}{sf}{\hyphenchar\font\m@ne} +%<tt&c19>\DeclareFontFamily{C19}{tt}{\hyphenchar\font\m@ne} +%<tt&c70>\DeclareFontFamily{C70}{tt}{\hyphenchar\font\m@ne} +% \end{macrocode} +% +% \changes{v2.4}{2016/04/25}{提供 \upLaTeX{} 的 NFSS 字体定义。} +% \upLaTeX{} 使用的字体族。\upLaTeX 在 NFSS 下使用字体编码 |JY2| 和 |JT2| 来分别 +% 表示横排与直排的日文。 +% \begin{macrocode} +%<rm&jy2>\DeclareKanjiFamily{JY2}{zhrm}{} +%<rm&jt2>\DeclareKanjiFamily{JT2}{zhrm}{} +%<sf&jy2>\DeclareKanjiFamily{JY2}{zhsf}{} +%<sf&jt2>\DeclareKanjiFamily{JT2}{zhsf}{} +%<tt&jy2>\DeclareKanjiFamily{JY2}{zhtt}{} +%<tt&jt2>\DeclareKanjiFamily{JT2}{zhtt}{} +% \end{macrocode} +% +% +% \begin{macrocode} +%<*rm> +%<*c19> +\DeclareFontShape{C19}{rm}{m}{n}{<-> CJK * gbksong}{\CJKnormal} +\DeclareFontShape{C19}{rm}{b}{n}{<-> CJK * gbkhei}{\CJKnormal} +\DeclareFontShape{C19}{rm}{bx}{n}{<-> CJK * gbkhei}{\CJKnormal} +\DeclareFontShape{C19}{rm}{m}{sl}{<-> CJK * gbksongsl}{\CJKnormal} +\DeclareFontShape{C19}{rm}{b}{sl}{<-> CJK * gbkheisl}{\CJKnormal} +\DeclareFontShape{C19}{rm}{bx}{sl}{<-> CJK * gbkheisl}{\CJKnormal} +\DeclareFontShape{C19}{rm}{m}{it}{<-> CJK * gbkkai}{\CJKnormal} +\DeclareFontShape{C19}{rm}{b}{it}{<-> CJKb * gbkkai}{\CJKbold} +\DeclareFontShape{C19}{rm}{bx}{it}{<-> CJKb * gbkkai}{\CJKbold} +%</c19> +%<*c70> +\DeclareFontShape{C70}{rm}{m}{n}{<-> CJK * unisong}{\CJKnormal} +\DeclareFontShape{C70}{rm}{b}{n}{<-> CJK * unihei}{\CJKnormal} +\DeclareFontShape{C70}{rm}{bx}{n}{<-> CJK * unihei}{\CJKnormal} +\DeclareFontShape{C70}{rm}{m}{sl}{<-> CJK * unisongsl}{\CJKnormal} +\DeclareFontShape{C70}{rm}{b}{sl}{<-> CJK * uniheisl}{\CJKnormal} +\DeclareFontShape{C70}{rm}{bx}{sl}{<-> CJK * uniheisl}{\CJKnormal} +\DeclareFontShape{C70}{rm}{m}{it}{<-> CJK * unikai}{\CJKnormal} +\DeclareFontShape{C70}{rm}{b}{it}{<-> CJKb * unikai}{\CJKbold} +\DeclareFontShape{C70}{rm}{bx}{it}{<-> CJKb * unikai}{\CJKbold} +%</c70> +%<*jy2> +\DeclareFontShape{JY2}{zhrm}{m}{n}{<-> upzhserif-h}{} +\DeclareFontShape{JY2}{zhrm}{m}{it}{<-> upzhserifit-h}{} +\DeclareFontShape{JY2}{zhrm}{bx}{n}{<-> upzhserifb-h}{} +%</jy2> +%<*jt2> +\DeclareFontShape{JT2}{zhrm}{m}{n}{<-> upzhserif-v}{} +\DeclareFontShape{JT2}{zhrm}{m}{it}{<-> upzhserifit-v}{} +\DeclareFontShape{JT2}{zhrm}{bx}{n}{<-> upzhserifb-v}{} +%</jt2> +%</rm> +% \end{macrocode} +% +% \begin{macrocode} +%<*sf> +%<*c19> +\DeclareFontShape{C19}{sf}{m}{n}{<-> CJK * gbkyou}{\CJKnormal} +\DeclareFontShape{C19}{sf}{b}{n}{<-> CJKb * gbkyou}{\CJKbold} +\DeclareFontShape{C19}{sf}{bx}{n}{<-> CJKb * gbkyou}{\CJKbold} +\DeclareFontShape{C19}{sf}{m}{sl}{<-> CJK * gbkyousl}{\CJKnormal} +\DeclareFontShape{C19}{sf}{b}{sl}{<-> CJKb * gbkyousl}{\CJKbold} +\DeclareFontShape{C19}{sf}{bx}{sl}{<-> CJKb * gbkyousl}{\CJKbold} +\DeclareFontShape{C19}{sf}{m}{it}{<-> CJK * gbkyou}{\CJKnormal} +\DeclareFontShape{C19}{sf}{b}{it}{<-> CJKb * gbkyou}{\CJKbold} +\DeclareFontShape{C19}{sf}{bx}{it}{<-> CJKb * gbkyou}{\CJKbold} +%</c19> +%<*c70> +\DeclareFontShape{C70}{sf}{m}{n}{<-> CJK * uniyou}{\CJKnormal} +\DeclareFontShape{C70}{sf}{b}{n}{<-> CJKb * uniyou}{\CJKbold} +\DeclareFontShape{C70}{sf}{bx}{n}{<-> CJKb * uniyou}{\CJKbold} +\DeclareFontShape{C70}{sf}{m}{sl}{<-> CJK * uniyousl}{\CJKnormal} +\DeclareFontShape{C70}{sf}{b}{sl}{<-> CJKb * uniyousl}{\CJKbold} +\DeclareFontShape{C70}{sf}{bx}{sl}{<-> CJKb * uniyousl}{\CJKbold} +\DeclareFontShape{C70}{sf}{m}{it}{<-> CJK * uniyou}{\CJKnormal} +\DeclareFontShape{C70}{sf}{b}{it}{<-> CJKb * uniyou}{\CJKbold} +\DeclareFontShape{C70}{sf}{bx}{it}{<-> CJKb * uniyou}{\CJKbold} +%</c70> +%<*jy2> +\DeclareFontShape{JY2}{zhsf}{m}{n}{<-> upzhsans-h}{} +\DeclareFontShape{JY2}{zhsf}{bx}{n}{<-> upzhsansb-h}{} +%</jy2> +%<*jt2> +\DeclareFontShape{JT2}{zhsf}{m}{n}{<-> upzhsans-v}{} +\DeclareFontShape{JT2}{zhsf}{bx}{n}{<-> upzhsansb-v}{} +%</jt2> +%</sf> +% \end{macrocode} +% +% \begin{macrocode} +%<*tt> +%<*c19> +\DeclareFontShape{C19}{tt}{m}{n}{<-> CJK * gbkfs}{\CJKnormal} +\DeclareFontShape{C19}{tt}{b}{n}{<-> CJKb * gbkfs}{\CJKbold} +\DeclareFontShape{C19}{tt}{bx}{n}{<-> CJKb * gbkfs}{\CJKbold} +\DeclareFontShape{C19}{tt}{m}{sl}{<-> CJK * gbkfssl}{\CJKnormal} +\DeclareFontShape{C19}{tt}{b}{sl}{<-> CJKb * gbkfssl}{\CJKbold} +\DeclareFontShape{C19}{tt}{bx}{sl}{<-> CJKb * gbkfssl}{\CJKbold} +\DeclareFontShape{C19}{tt}{m}{it}{<-> CJK * gbkfs}{\CJKnormal} +\DeclareFontShape{C19}{tt}{b}{it}{<-> CJKb * gbkfs}{\CJKbold} +\DeclareFontShape{C19}{tt}{bx}{it}{<-> CJKb * gbkfs}{\CJKbold} +%</c19> +%<*c70> +\DeclareFontShape{C70}{tt}{m}{n}{<-> CJK * unifs}{\CJKnormal} +\DeclareFontShape{C70}{tt}{b}{n}{<-> CJKb * unifs}{\CJKbold} +\DeclareFontShape{C70}{tt}{bx}{n}{<-> CJKb * unifs}{\CJKbold} +\DeclareFontShape{C70}{tt}{m}{sl}{<-> CJK * unifssl}{\CJKnormal} +\DeclareFontShape{C70}{tt}{b}{sl}{<-> CJKb * unifssl}{\CJKbold} +\DeclareFontShape{C70}{tt}{bx}{sl}{<-> CJKb * unifssl}{\CJKbold} +\DeclareFontShape{C70}{tt}{m}{it}{<-> CJK * unifs}{\CJKnormal} +\DeclareFontShape{C70}{tt}{b}{it}{<-> CJKb * unifs}{\CJKbold} +\DeclareFontShape{C70}{tt}{bx}{it}{<-> CJKb * unifs}{\CJKbold} +%</c70> +%<*jy2> +\DeclareFontShape{JY2}{zhtt}{m}{n}{<-> upzhmono-h}{} +%</jy2> +%<*jt2> +\DeclareFontShape{JT2}{zhtt}{m}{n}{<-> upzhmono-v}{} +%</jt2> +%</tt> +% \end{macrocode} +% +% \begin{macrocode} +%<*fontset> +% \end{macrocode} +% +% \subsubsection{\pkg{ctex-fontset-windows.def} 等} +% +% \changes{v2.4.1}{2016/05/14}{使用 \file{bootfont.bin} 判断 Windows XP 以避免 +% 权限问题。} +% \pkg{ctex} 包利用 |C:\bootfont.bin| 文件的存在性来判断是否使用 Windows XP 版 +% 本,分别载入新旧字体设置。(注:\pkg{ctex} 包不支持 Windows 2000 以前使用 +% \file{simsun.ttf} 的旧宋体文件名。) +% \begin{macrocode} +%<*windows> +\file_if_exist:nTF { C:/bootfont.bin } + { \ctex_file_input:n { ctex-fontset-windowsold.def } } + { \ctex_file_input:n { ctex-fontset-windowsnew.def } } +%</windows> +% \end{macrocode} +% +% 旧的 Windows 字体设置使用黑体作为无衬线体,楷体和仿宋是 GB2312 编码;新的 +% Windows 字体设置使用微软雅黑作为无衬线体,楷体和仿宋是大字库。 +% Windows 8 以后,微软雅黑由原来的 \file{.ttf} 后缀改为 \file{.ttc} 后缀,需要 +% 加以区分。 +% \begin{macrocode} +%<*windowsnew> +\tl_new:N \l_@@_msyh_suffix_tl +\tl_set:Nn \l_@@_msyh_suffix_tl { .ttc } +\file_if_exist:nF { C:/Windows/Fonts/msyh.ttc } + { + \file_if_exist:nF { msyh.ttc } + { \tl_set:Nn \l_@@_msyh_suffix_tl { .ttf } } + } +%</windowsnew> +%<*windowsnew|windowsold> +\sys_if_engine_pdftex:TF + { + \ctex_zhmap_case:nnn + { + \ctex_punct_set:n { windows } + \setCJKmainfont + [ BoldFont = simhei.ttf , ItalicFont = simkai.ttf ] { simsun.ttc } +%<*windowsold> + \setCJKsansfont { simhei.ttf } + \ctex_punct_map_family:nn { \CJKsfdefault } { zhhei } +%</windowsold> +%<*windowsnew> + \setCJKsansfont + [ BoldFont = msyhbd\l_@@_msyh_suffix_tl ] { msyh\l_@@_msyh_suffix_tl } + \setCJKfamilyfont { zhyahei } + [ BoldFont = msyhbd\l_@@_msyh_suffix_tl ] { msyh\l_@@_msyh_suffix_tl } + \ctex_punct_map_family:nn { \CJKsfdefault } { zhyahei } + \ctex_punct_map_bfseries:nn { \CJKsfdefault , zhyahei } { zhyaheib } +%</windowsnew> + \setCJKmonofont { simfang.ttf } + \setCJKfamilyfont { zhkai } { simkai.ttf } + \setCJKfamilyfont { zhfs } { simfang.ttf } + \setCJKfamilyfont { zhsong } { simsun.ttc } + \setCJKfamilyfont { zhhei } { simhei.ttf } + \setCJKfamilyfont { zhli } { simli.ttf } + \setCJKfamilyfont { zhyou } { simyou.ttf } + \ctex_punct_map_family:nn { \CJKrmdefault } { zhsong } + \ctex_punct_map_family:nn { \CJKttdefault } { zhfs } + \ctex_punct_map_itshape:nn { \CJKrmdefault } { zhkai } + \ctex_punct_map_bfseries:nn { \CJKrmdefault } { zhhei } + } + { + \ctex_load_zhmap:nnnn { rm } { zhhei } { zhfs } { zhwindowsfonts } + \ctex_punct_set:n { windows } + \ctex_punct_map_family:nn { \CJKrmdefault } { zhsong } + \ctex_punct_map_bfseries:nn { \CJKrmdefault } { zhhei } + \ctex_punct_map_itshape:nn { \CJKrmdefault } { zhkai } + } + { + \tl_set:Nn \CJKrmdefault { rm } + \tl_set:Nn \CJKsfdefault { sf } + \tl_set:Nn \CJKttdefault { tt } + } + } + { + \sys_if_engine_uptex:TF + { + \ctex_set_upfonts:nnnnnn + {simsun.ttc} {simhei.ttf} {simkai.ttf} +%<windowsnew> {msyh\l_@@_msyh_suffix_tl} {msyhbd\l_@@_msyh_suffix_tl} +%<windowsold> {simhei.ttf} {simhei.ttf} + {simfang.ttf} + \ctex_set_upfamily:nnn { zhsong } { upzhserif } {} + \ctex_set_upfamily:nnn { zhhei } { upzhserifb } {} + \ctex_set_upfamily:nnn { zhfs } { upzhmono} {} + \ctex_set_upfamily:nnn { zhkai } { upzhserifit } {} +%<windowsnew> \ctex_set_upfamily:nnn { zhyahei } { upzhsans } { upzhsansb } + \ctex_set_upfamily:nnn { zhli } { upschrm } {} + \ctex_set_upmap:nnn { upstsl } { simli.ttf } {} + \ctex_set_upfamily:nnn { zhyou } { upschgt } {} + \ctex_set_upmap:nnn { upstht } { simyou.ttf } {} + } + { +%<*windowsold> + \setCJKmainfont + [ BoldFont = SimHei , ItalicFont = KaiTi_GB2312 ] { SimSun } + \setCJKsansfont { SimHei } + \setCJKmonofont { FangSong_GB2312 } + \setCJKfamilyfont { zhkai } { KaiTi_GB2312 } + \setCJKfamilyfont { zhfs } { FangSong_GB2312 } +%</windowsold> +%<*windowsnew> + \setCJKmainfont + [ BoldFont = SimHei , ItalicFont = KaiTi ] { SimSun } + \setCJKsansfont + [ BoldFont = { *~Bold } ] { Microsoft~YaHei } + \setCJKmonofont { FangSong } + \setCJKfamilyfont { zhkai } { KaiTi } + \setCJKfamilyfont { zhfs } { FangSong } +%</windowsnew> + \setCJKfamilyfont { zhsong } { SimSun } + \setCJKfamilyfont { zhhei } { SimHei } + \setCJKfamilyfont { zhli } { LiSu } + \setCJKfamilyfont { zhyou } { YouYuan } +%<*windowsnew> + \setCJKfamilyfont { zhyahei } + [ BoldFont = { *~Bold } ] { Microsoft~YaHei } +%</windowsnew> + } + } +%</windowsnew|windowsold> +% \end{macrocode} +% +% \subsubsection{\pkg{ctex-fontset-adobe.def}} +% +% \begin{macrocode} +%<*adobe> +% \end{macrocode} +% +% \tn{pdfmapline} 不支持 OpenType 字体,因而 \opt{adobe} 字体集在 pdf 模式下 +% 就没有定义。\opt{fandol} 的情况类似。 +% \begin{macrocode} +\sys_if_engine_pdftex:TF + { + \sys_if_output_pdf:TF + { \ctex_fontset_error:n { adobe } } + { + \ctex_zhmap_case:nnn + { + \setCJKmainfont + [ + cmap = UniGB-UTF16-H , + BoldFont = AdobeHeitiStd-Regular.otf , + ItalicFont = AdobeKaitiStd-Regular.otf + ] { AdobeSongStd-Light.otf } + \setCJKsansfont [ cmap = UniGB-UTF16-H ] { AdobeHeitiStd-Regular.otf } + \setCJKmonofont [ cmap = UniGB-UTF16-H ] { AdobeFangsongStd-Regular.otf } + \setCJKfamilyfont { zhsong } + [ cmap = UniGB-UTF16-H ] { AdobeSongStd-Light.otf } + \setCJKfamilyfont { zhhei } + [ cmap = UniGB-UTF16-H ] { AdobeHeitiStd-Regular.otf } + \setCJKfamilyfont { zhkai } + [ cmap = UniGB-UTF16-H ] { AdobeKaitiStd-Regular.otf } + \setCJKfamilyfont { zhfs } + [ cmap = UniGB-UTF16-H ] { AdobeFangsongStd-Regular.otf } + \ctex_punct_set:n { adobe } + \ctex_punct_map_family:nn { \CJKrmdefault } { zhsong } + \ctex_punct_map_family:nn { \CJKsfdefault } { zhhei } + \ctex_punct_map_family:nn { \CJKttdefault } { zhfs } + \ctex_punct_map_itshape:nn { \CJKrmdefault } { zhkai } + \ctex_punct_map_bfseries:nn { \CJKrmdefault } { zhhei } + } + { + \ctex_load_zhmap:nnnn { rm } { zhhei } { zhfs } { zhadobefonts } + \ctex_punct_set:n { adobe } + \ctex_punct_map_family:nn { \CJKrmdefault } { zhsong } + \ctex_punct_map_bfseries:nn { \CJKrmdefault } { zhhei } + \ctex_punct_map_itshape:nn { \CJKrmdefault } { zhkai } + } + { \ctex_fontset_error:n { adobe } } + } + } + { + \sys_if_engine_uptex:TF + { + \ctex_set_upfonts:nnnnnn + {AdobeSongStd-Light.otf} {AdobeHeitiStd-Regular.otf} {AdobeKaitiStd-Regular.otf} + {AdobeHeitiStd-Regular.otf} {AdobeHeitiStd-Regular.otf} + {AdobeFangsongStd-Regular.otf} + \ctex_set_upfamily:nnn { zhsong } { upzhserif } {} + \ctex_set_upfamily:nnn { zhhei } { upzhsans } {} + \ctex_set_upfamily:nnn { zhfs } { upzhmono} {} + \ctex_set_upfamily:nnn { zhkai } { upzhserifit } {} + } + { + \setCJKmainfont + [ + BoldFont = AdobeHeitiStd-Regular , + ItalicFont = AdobeKaitiStd-Regular + ] { AdobeSongStd-Light } + \setCJKsansfont { AdobeHeitiStd-Regular} + \setCJKmonofont { AdobeFangsongStd-Regular} + \setCJKfamilyfont { zhsong } { AdobeSongStd-Light } + \setCJKfamilyfont { zhhei } { AdobeHeitiStd-Regular } + \setCJKfamilyfont { zhfs } { AdobeFangsongStd-Regular } + \setCJKfamilyfont { zhkai } { AdobeKaitiStd-Regular } + } + } +% \end{macrocode} +% +% \begin{macrocode} +%</adobe> +%<*fandol> +% \end{macrocode} +% +% \subsubsection{\pkg{ctex-fontset-fandol.def}} +% +% \begin{macrocode} +\sys_if_engine_pdftex:TF + { + \sys_if_output_pdf:TF + { \ctex_fontset_error:n { fandol } } + { + \ctex_zhmap_case:nnn + { + \setCJKmainfont + [ + cmap = UniGB-UTF16-H , + BoldFont = FandolSong-Bold.otf , + ItalicFont = FandolKai-Regular.otf + ] { FandolSong-Regular.otf } + \setCJKsansfont + [ + cmap = UniGB-UTF16-H , + BoldFont = FandolHei-Bold.otf + ] { FandolHei-Regular.otf } + \setCJKmonofont [ cmap = UniGB-UTF16-H ] { FandolFang-Regular.otf } + \setCJKfamilyfont { zhsong } + [ + cmap = UniGB-UTF16-H , + BoldFont = FandolSong-Bold.otf + ] { FandolSong-Regular.otf } + \setCJKfamilyfont { zhhei } + [ + cmap = UniGB-UTF16-H , + BoldFont = FandolHei-Bold.otf + ] { FandolHei-Regular.otf } + \setCJKfamilyfont { zhfs } + [ cmap = UniGB-UTF16-H ] { FandolFang-Regular.otf } + \setCJKfamilyfont { zhkai } + [ cmap = UniGB-UTF16-H ] { FandolKai-Regular.otf } + \ctex_punct_set:n { fandol } + \ctex_punct_map_family:nn { \CJKrmdefault } { zhsong } + \ctex_punct_map_family:nn { \CJKsfdefault } { zhhei } + \ctex_punct_map_family:nn { \CJKttdefault } { zhfs } + \ctex_punct_map_itshape:nn { \CJKrmdefault } { zhkai } + \ctex_punct_map_bfseries:nn { \CJKrmdefault , zhsong } { zhsongb } + \ctex_punct_map_bfseries:nn { \CJKsfdefault , zhhei } { zhheib } + } + { + \ctex_load_zhmap:nnnn { rm } { zhhei } { zhfs } { zhfandolfonts } + \ctex_punct_set:n { fandol } + \ctex_punct_map_family:nn { \CJKrmdefault } { zhsong } + \ctex_punct_map_bfseries:nn { \CJKrmdefault } { zhhei } + \ctex_punct_map_itshape:nn { \CJKrmdefault } { zhkai } + } + { \ctex_fontset_error:n { fandol } } + } + } + { + \sys_if_engine_uptex:TF + { + \ctex_set_upfonts:nnnnnn + {FandolSong-Regular.otf} {FandolSong-Bold.otf} {FandolKai-Regular.otf} + {FandolHei-Regular.otf} {FandolHei-Bold.otf} + {FandolFang-Regular.otf} + \ctex_set_upfamily:nnn { zhsong } { upzhserif } { upzhserifb } + \ctex_set_upfamily:nnn { zhhei } { upzhsans } { upzhsansb } + \ctex_set_upfamily:nnn { zhfs } { upzhmono} {} + \ctex_set_upfamily:nnn { zhkai } { upzhserifit } {} + } + { + \setCJKmainfont + [ + Extension = .otf , + BoldFont = FandolSong-Bold , ItalicFont = FandolKai-Regular + ] + { FandolSong-Regular } + \setCJKsansfont + [ Extension = .otf , BoldFont = FandolHei-Bold ] { FandolHei-Regular } + \setCJKmonofont [ Extension = .otf ] { FandolFang-Regular } + \setCJKfamilyfont { zhsong } + [ Extension = .otf , BoldFont = FandolSong-Bold ] { FandolSong-Regular } + \setCJKfamilyfont { zhhei } + [ Extension = .otf , BoldFont = FandolHei-Bold ] { FandolHei-Regular } + \setCJKfamilyfont { zhfs } [ Extension = .otf ] { FandolFang-Regular } + \setCJKfamilyfont { zhkai } [ Extension = .otf ] { FandolKai-Regular } + } + } +% \end{macrocode} +% +% \begin{macrocode} +%</fandol> +% \end{macrocode} +% +% \subsubsection{\pkg{ctex-fontset-mac.def} 等} +% \changes{v2.4.14}{2018/05/01}{区分 \texttt{macold} 及 \texttt{macnew}。} +% +% 按 \href{https://github.com/CTeX-org/ctex-kit/issues/351}{Issue 351} +% 的讨论,以 El Capitan 为分界,分别设置 |macold|(El Capitan 之前) +% 和 |macnew|(El Capitan 及之后)。检测方式则以 El Capitan 及之后 +% 的苹方字体为准。 +% +% \begin{macrocode} +%<*mac> +\file_if_exist:nTF { /System/Library/Fonts/PingFang.ttc } + { \ctex_file_input:n { ctex-fontset-macnew.def } } + { \ctex_file_input:n { ctex-fontset-macold.def } } +%</mac> +% \end{macrocode} +% +% |macold| 的设置参考了 ^^A +% \href{https://github.com/CTeX-org/ctex-kit/wiki/OS-X-Mavericks-(10.9)-\%E9\%A2\%84\%E8\%A3\%85\%E7\%9A\%84\%E4\%B8\%BB\%E8\%A6\%81\%E7\%AE\%80\%E4\%BD\%93\%E4\%B8\%AD\%E6\%96\%87\%E5\%AD\%97\%E4\%BD\%93}^^A +% {OS X Mavericks (10.9) 预装的主要简体中文字体列表}。 +% +% 在 \dvipdfmx{} 下,可以通过下述方式使用华文宋体和华文楷体: +% \begin{verbatim} +% \special{pdf:mapline unisong@Unicode@ unicode :4:Songti.ttc} +% \special{pdf:mapline unikai@Unicode@ unicode :4:Kaiti.ttc} +% \end{verbatim} +% 而 \tn{pdfmapline} 似乎不支持带索引的 \texttt{ttc} 字体,\file{Songti.ttc} 默认 +% 使用的是 Songti SC Black,\file{Kaiti.ttc} 默认使用的是 Kaiti SC Black。 +% 华文黑体不能通过这种方式使用: +% \begin{verbatim} +% \special{pdf:mapline unihei@Unicode@ unicode \detokenize{华文黑体}.ttf} +% \end{verbatim} +% \dvipdfmx{} 不能生成 PDF,报下述错误: +% \begin{verbatim} +% ** WARNING ** UCS-4 TrueType cmap table... +% ** ERROR ** Unable to read OpenType/TrueType Unicode cmap table. +% \end{verbatim} +% 如果将 CMap 改为 UniGB-UTF16-H,错误信息是 +% \begin{verbatim} +% ** WARNING ** No usable TrueType cmap table found for font "华文黑体.ttf". +% ** WARNING ** CID character collection for this font is set to "Adobe-GB1" +% ** ERROR ** Cannot continue without this... +% \end{verbatim} +% 在 \pdfTeX{} 下生成的 PDF 只有方框^^A +% \footnote{\url{http://www.newsmth.net/bbscon.php?bid=460&id=312640}}。 +% 华文细黑和华文仿宋的情况类似。 +% 这确认为 \dvipdfmx{} 的 bug^^A +% \begingroup\makeatletter\@makeother\#\@firstofone{\endgroup +% \footnote{\url{https://github.com/clerkma/ptex-ng/blob/master/texk/libdpx/cidtype2.c#L597}}}。 +% +% \changes{v2.4.14}{2018/05/01}{配置 \texttt{macnew} 的默认字体设置。} +% +% |macnew| 在默认字体设置方面,引入了多字重的宋体作为罗马字族, +% 以及引入了苹方黑体作为无衬线字族。 +% +% 由于 Songti SC Light 的字重与 STSong 及 Windows 上的 SimSun 更接近,故默认字重 +% 使用 Songti SC Light,而不带后缀的正常字重事实上没有使用。下方关于 |zhsong| 的字族 +% 设置也有同样的情况。 +% +% \begin{macrocode} +%<*macold|macnew> +\sys_if_engine_pdftex:TF + { \ctex_fontset_error:n { mac } } + { + \sys_if_engine_uptex:TF + { \ctex_fontset_error:n { mac } } + { +%<*macold> + \setCJKmainfont [ BoldFont = STHeiti , ItalicFont = STKaiti ] { STSong } + \setCJKsansfont [ BoldFont = STHeiti ] { STXihei } +%</macold> +%<*macnew> + \setCJKmainfont + [ + UprightFont = *~Light , + BoldFont = *~Bold , + ItalicFont = Kaiti~SC , + BoldItalicFont = Kaiti~SC~Bold + ] { Songti~SC } + \setCJKsansfont { PingFang~SC } +%</macnew> + \setCJKmonofont { STFangsong } +%<*macold> + \setCJKfamilyfont { zhsong } { STSong } + \setCJKfamilyfont { zhhei } { STHeiti } +%</macold> +%<*macnew> + \setCJKfamilyfont { zhsong } + [ + UprightFont = *~Light , + BoldFont = *~Bold , + ] { Songti~SC } + \setCJKfamilyfont { zhhei } { Heiti~SC } + \setCJKfamilyfont { zhpf } { PingFang~SC } +%</macnew> + \setCJKfamilyfont { zhfs } { STFangsong } +%<macold>\setCJKfamilyfont { zhkai } { STKaiti } +%<macnew>\setCJKfamilyfont { zhkai } { Kaiti~SC } + } + } +%</macold|macnew> +% \end{macrocode} +% +% \subsubsection{\pkg{ctex-fontset-founder.def}} +% +% \begin{macrocode} +%<*founder> +% \end{macrocode} +% +% \changes{v2.4.15}{2019/03/28}{统一“方正细黑一\_GBK”的名称为 \texttt{FZXiHeiI-Z08}。} +% +% \begin{macrocode} +\sys_if_engine_pdftex:TF + { + \ctex_zhmap_case:nnn + { + \setCJKmainfont + [ BoldFont = FZXBSK.TTF , ItalicFont = FZKTK.TTF ] { FZSSK.TTF } + \setCJKsansfont [ BoldFont = FZHTK.TTF ] { FZXH1K.TTF } + \setCJKmonofont { FZFSK.TTF } + \setCJKfamilyfont { zhsong } [ BoldFont = FZXBSK.TTF ] { FZSSK.TTF } + \setCJKfamilyfont { zhhei } { FZHTK.TTF } + \setCJKfamilyfont { zhkai } { FZKTK.TTF } + \setCJKfamilyfont { zhfs } { FZFSK.TTF } + \setCJKfamilyfont { zhli } { FZLSK.TTF } + \setCJKfamilyfont { zhyou } [ BoldFont = FZY3K.TTF ] { FZY1K.TTF } + \ctex_punct_set:n { founder } + \ctex_punct_map_family:nn { \CJKrmdefault } { zhsong } + \ctex_punct_map_family:nn { \CJKsfdefault } { zhheil } + \ctex_punct_map_family:nn { \CJKttdefault } { zhfs } + \ctex_punct_map_itshape:nn { \CJKrmdefault } { zhkai } + \ctex_punct_map_bfseries:nn { \CJKrmdefault , zhsong } { zhsongb } + \ctex_punct_map_bfseries:nn { \CJKsfdefault } { zhhei } + \ctex_punct_map_bfseries:nn { zhyou } { zhyoub } + } + { + \ctex_load_zhmap:nnnn { rm } { zhhei } { zhfs } { zhfounderfonts } + \ctex_punct_set:n { founder } + \ctex_punct_map_family:nn { \CJKrmdefault } { zhsong } + \ctex_punct_map_bfseries:nn { \CJKrmdefault } { zhhei } + \ctex_punct_map_itshape:nn { \CJKrmdefault } { zhkai } + } + { \ctex_fontset_error:n { founder } } + } + { + \sys_if_engine_uptex:TF + { + \ctex_set_upfonts:nnnnnn + { FZSSK.TTF } { FZXBSK.TTF } { FZKTK.TTF } + { FZXH1K.TTF } { FZHTK.TTF } + { FZFSK.TTF } + \ctex_set_upfamily:nnn { zhsong } { upzhserif } { upzhserifb } + \ctex_set_upfamily:nnn { zhhei } { upzhsans } { upzhsansb } + \ctex_set_upfamily:nnn { zhfs } { upzhmono} {} + \ctex_set_upfamily:nnn { zhkai } { upzhserifit } {} + \ctex_set_upfamily:nnn { zhli } { upschrm } {} + \ctex_set_upmap:nnn { upstsl } { FZLSK.TTF } {} + \ctex_set_upfamily:nnn { zhyou } { upschgt } {} + \ctex_set_upmap:nnn { upstht } { FZY1K.TTF } {} + } + { + \setCJKmainfont + [ BoldFont = FZXiaoBiaoSong-B05 , ItalicFont = FZKai-Z03 ] { FZShuSong-Z01 } + \setCJKsansfont [ BoldFont = FZHei-B01 ] { FZXiHeiI-Z08 } + \setCJKmonofont { FZFangSong-Z02 } + \setCJKfamilyfont { zhsong } [ BoldFont = FZXiaoBiaoSong-B05 ] { FZShuSong-Z01 } + \setCJKfamilyfont { zhhei } { FZHei-B01 } + \setCJKfamilyfont { zhkai } { FZKai-Z03 } + \setCJKfamilyfont { zhfs } { FZFangSong-Z02 } + \setCJKfamilyfont { zhli } { FZLiShu-S01 } + \setCJKfamilyfont { zhyou } [ BoldFont = FZZhunYuan-M02 ] { FZXiYuan-M01 } + } + } +% \end{macrocode} +% +% \begin{macrocode} +%</founder> +%<*ubuntu> +% \end{macrocode} +% +% \subsubsection{\pkg{ctex-fontset-ubuntu.def}} +% +% 以下根据 Ubuntu 12.04 的中文字体情况设置。CMap 不清楚应该是什么,指定为 +% UniGB-UTF16-H 还是有警告: +% \begin{verbatim} +% ** WARNING ** UCS-4 TrueType cmap table... +% \end{verbatim} +% 需要注意的是 \file{uming.ttc} 和 \file{ukai.ttc} 看起来像有四种字形的样子,但 +% 其实只有“令”和“骨”这区区两个字有新字形,其余都取旧字形^^A +% \footnote{\url{http://www.freedesktop.org/wiki/Software/CJKUnifonts/Download/}}。 +% \begin{macrocode} +\sys_if_engine_pdftex:TF + { + \ctex_zhmap_case:nnn + { + \setCJKmainfont + [ BoldFont = wqy-zenhei.ttc , ItalicFont = ukai.ttc ] { uming.ttc } + \setCJKsansfont { wqy-zenhei.ttc } + \setCJKmonofont { uming.ttc } + \setCJKfamilyfont { zhsong } { uming.ttc } + \setCJKfamilyfont { zhhei } { wqy-zenhei.ttc } + \setCJKfamilyfont { zhkai } { ukai.ttc } + \ctex_punct_set:n { ubuntu } + \ctex_punct_map_family:nn { \CJKrmdefault } { zhsong } + \ctex_punct_map_family:nn { \CJKsfdefault } { zhhei } + \ctex_punct_map_family:nn { \CJKttdefault } { zhsong } + \ctex_punct_map_itshape:nn { \CJKrmdefault } { zhkai } + \ctex_punct_map_bfseries:nn { \CJKrmdefault } { zhhei } + } + { + \ctex_load_zhmap:nnnn { rm } { zhhei } { zhsong } { zhubuntufonts } + \ctex_punct_set:n { ubuntu } + \ctex_punct_map_family:nn { \CJKrmdefault } { zhsong } + \ctex_punct_map_bfseries:nn { \CJKrmdefault } { zhhei } + \ctex_punct_map_itshape:nn { \CJKrmdefault } { zhkai } + } + { \ctex_fontset_error:n { ubuntu } } + } + { + \sys_if_engine_uptex:TF + { + \ctex_set_upfonts:nnnnnn + { uming.ttc } { wqy-zenhei.ttc } { ukai.ttc } + { wqy-zenhei.ttc } { wqy-zenhei.ttc } + { uming.ttc } + \ctex_set_upfamily:nnn { zhsong } { upzhserif } {} + \ctex_set_upfamily:nnn { zhhei } { upzhsans } {} + \ctex_set_upfamily:nnn { zhkai } { upzhserifit } {} + } + { + \setCJKmainfont + [ BoldFont = WenQuanYi~Zen~Hei , ItalicFont = AR~PL~UKai~CN ] { AR~PL~UMing~CN } + \setCJKsansfont { WenQuanYi~Zen~Hei } + \setCJKmonofont { AR~PL~UMing~CN } + \setCJKfamilyfont { zhsong } { AR~PL~UMing~CN } + \setCJKfamilyfont { zhhei } { WenQuanYi~Zen~Hei } + \setCJKfamilyfont { zhkai } { AR~PL~UKai~CN } + } + } +% \end{macrocode} +% +% \begin{macrocode} +%</ubuntu> +% \end{macrocode} +% +% \subsubsection{中文字体命令} +% \changes{v2.4.14}{2018/05/01}{为 \texttt{macnew} 配置字体命令。} +% +% \begin{macrocode} +%<*!windows&!mac> +% \end{macrocode} +% +% \begin{macrocode} +\NewDocumentCommand \songti { } { \CJKfamily { zhsong } } +\NewDocumentCommand \heiti { } { \CJKfamily { zhhei } } +%<!ubuntu>\NewDocumentCommand \fangsong { } { \CJKfamily { zhfs } } +\NewDocumentCommand \kaishu { } { \CJKfamily { zhkai } } +%<*windowsnew|windowsold|founder> +\NewDocumentCommand \lishu { } { \CJKfamily { zhli } } +\NewDocumentCommand \youyuan { } { \CJKfamily { zhyou } } +%</windowsnew|windowsold|founder> +%<windowsnew>\NewDocumentCommand \yahei { } { \CJKfamily { zhyahei } } +%<*macnew> +\NewDocumentCommand \yahei { } { \CJKfamily { zhpf } } +\NewDocumentCommand \pingfang { } { \CJKfamily { zhpf } } +%</macnew> +% \end{macrocode} +% +% \begin{macrocode} +%</!windows&!mac> +%</fontset> +%<*zhmap> +% \end{macrocode} +% +% \subsubsection{\pkg{zhmetrics} 的字体映射} +% +% 确认 \tn{catcode},没有重复载入检查。 +% \begin{macrocode} +\begingroup\catcode61\catcode48\catcode32=10\relax% + \catcode 35=6 % # + \catcode123=1 % { + \catcode125=2 % } + \toks0{\endlinechar=\the\endlinechar\relax}% + \toks2{\endlinechar=13 }% + \def\x#1 #2 {% + \toks0\expandafter{\the\toks0 \catcode#1=\the\catcode#1\relax}% + \toks2\expandafter{\the\toks2 \catcode#1=#2 }}% + \x 13 5 % carriage return + \x 32 10 % space + \x 35 6 % # + \x 40 12 % ( + \x 41 12 % ) + \x 45 12 % - + \x 46 12 % . + \x 47 12 % / + \x 58 12 % : + \x 60 12 % < + \x 61 12 % = + \x 64 11 % @ + \x 91 12 % [ + \x 93 12 % ] + \x 123 1 % { + \x 125 2 % } + \edef\x#1{\endgroup% + \edef\noexpand#1{% + \the\toks0 % + \let\noexpand\noexpand\noexpand#1% + \noexpand\noexpand\noexpand\undefined% + \noexpand\noexpand\noexpand\endinput}% + \the\toks2}% +\expandafter\x\csname ctex@zhmap@endinput\endcsname +% \end{macrocode} +% +% \begin{macrocode} +\begingroup\expandafter\endgroup +\expandafter\let\csname ifzhmappdf\expandafter\endcsname\csname + \expandafter\ifx\csname ifctexpdf\endcsname\relax + \expandafter\ifx\csname pdfoutput\endcsname\relax + iffalse\else\ifnum\pdfoutput < 1 iffalse\else iftrue\fi\fi + \else ifctexpdf\fi +\endcsname +% \end{macrocode} +% +% 提供非 \LaTeX{} 格式下的 \tn{ProvidesFile}。 +% \begin{macrocode} +\begingroup +\expandafter\ifx\csname ProvidesFile\endcsname\relax + \long\def\x#1\ProvidesFile#2[#3]{% + #1% + \immediate\write-1{File: #2 #3}% + \expandafter\xdef\csname ver@#2\endcsname{#3}} + \expandafter\x% +\fi +\endgroup +% \end{macrocode} +% +% \paragraph{\pkg{zhwindowsfonts.tex}} +% +% \begin{macrocode} +%<*windows> +\ProvidesFile{zhwindowsfonts.tex}% + [2019/05/29 v2.4.16 Windows font map loader for pdfTeX and DVIPDFMx (CTEX)] + +\ifzhmappdf + \pdfmapline{=gbk@UGBK@ <simsun.ttc} + \pdfmapline{=gbksong@UGBK@ <simsun.ttc} + \pdfmapline{=gbkkai@UGBK@ <simkai.ttf} + \pdfmapline{=gbkhei@UGBK@ <simhei.ttf} + \pdfmapline{=gbkfs@UGBK@ <simfang.ttf} + \pdfmapline{=gbkli@UGBK@ <simli.ttf} + \pdfmapline{=gbkyou@UGBK@ <simyou.ttf} + + \pdfmapline{=cyberb@Unicode@ <simsun.ttc} + \pdfmapline{=unisong@Unicode@ <simsun.ttc} + \pdfmapline{=unikai@Unicode@ <simkai.ttf} + \pdfmapline{=unihei@Unicode@ <simhei.ttf} + \pdfmapline{=unifs@Unicode@ <simfang.ttf} + \pdfmapline{=unili@Unicode@ <simli.ttf} + \pdfmapline{=uniyou@Unicode@ <simyou.ttf} + + \pdfmapline{=gbksongsl@UGBK@ <simsun.ttc} + \pdfmapline{=gbkkaisl@UGBK@ <simkai.ttf} + \pdfmapline{=gbkheisl@UGBK@ <simhei.ttf} + \pdfmapline{=gbkfssl@UGBK@ <simfang.ttf} + \pdfmapline{=gbklisl@UGBK@ <simli.ttf} + \pdfmapline{=gbkyousl@UGBK@ <simyou.ttf} + + \pdfmapline{=unisongsl@Unicode@ <simsun.ttc} + \pdfmapline{=unikaisl@Unicode@ <simkai.ttf} + \pdfmapline{=uniheisl@Unicode@ <simhei.ttf} + \pdfmapline{=unifssl@Unicode@ <simfang.ttf} + \pdfmapline{=unilisl@Unicode@ <simli.ttf} + \pdfmapline{=uniyousl@Unicode@ <simyou.ttf} + +\else + \special{pdf:mapline gbk@UGBK@ unicode :0:simsun.ttc -v 50} + \special{pdf:mapline gbksong@UGBK@ unicode :0:simsun.ttc -v 50} + \special{pdf:mapline gbkkai@UGBK@ unicode simkai.ttf -v 70} + \special{pdf:mapline gbkhei@UGBK@ unicode simhei.ttf -v 150} + \special{pdf:mapline gbkfs@UGBK@ unicode simfang.ttf -v 50} + \special{pdf:mapline gbkli@UGBK@ unicode simli.ttf -v 150} + \special{pdf:mapline gbkyou@UGBK@ unicode simyou.ttf -v 60} + + \special{pdf:mapline cyberb@Unicode@ unicode :0:simsun.ttc -v 50} + \special{pdf:mapline unisong@Unicode@ unicode :0:simsun.ttc -v 50} + \special{pdf:mapline unikai@Unicode@ unicode simkai.ttf -v 70} + \special{pdf:mapline unihei@Unicode@ unicode simhei.ttf -v 150} + \special{pdf:mapline unifs@Unicode@ unicode simfang.ttf -v 50} + \special{pdf:mapline unili@Unicode@ unicode simli.ttf -v 150} + \special{pdf:mapline uniyou@Unicode@ unicode simyou.ttf -v 60} + + \special{pdf:mapline gbksongsl@UGBK@ unicode :0:simsun.ttc -s .167 -v 50} + \special{pdf:mapline gbkkaisl@UGBK@ unicode simkai.ttf -s .167 -v 70} + \special{pdf:mapline gbkheisl@UGBK@ unicode simhei.ttf -s .167 -v 150} + \special{pdf:mapline gbkfssl@UGBK@ unicode simfang.ttf -s .167 -v 50} + \special{pdf:mapline gbklisl@UGBK@ unicode simli.ttf -s .167 -v 150} + \special{pdf:mapline gbkyousl@UGBK@ unicode simyou.ttf -s .167 -v 60} + + \special{pdf:mapline unisongsl@Unicode@ unicode :0:simsun.ttc -s .167 -v 50} + \special{pdf:mapline unikaisl@Unicode@ unicode simkai.ttf -s .167 -v 70} + \special{pdf:mapline uniheisl@Unicode@ unicode simhei.ttf -s .167 -v 150} + \special{pdf:mapline unifssl@Unicode@ unicode simfang.ttf -s .167 -v 50} + \special{pdf:mapline unilisl@Unicode@ unicode simli.ttf -s .167 -v 150} + \special{pdf:mapline uniyousl@Unicode@ unicode simyou.ttf -s .167 -v 60} + +%</windows> +% \end{macrocode} +% +% \paragraph{\pkg{zhadobefonts.tex}} +% +% \begin{macrocode} +%<*adobe> +\ProvidesFile{zhadobefonts.tex}% + [2019/05/29 v2.4.16 Adobe font map loader for DVIPDFMx (CTEX)] + +\ifzhmappdf +%% pdfTeX does not support OTF fonts + +\else + \special{pdf:mapline gbk@UGBK@ UniGB-UTF16-H AdobeSongStd-Light.otf} + \special{pdf:mapline gbksong@UGBK@ UniGB-UTF16-H AdobeSongStd-Light.otf} + \special{pdf:mapline gbkkai@UGBK@ UniGB-UTF16-H AdobeKaitiStd-Regular.otf} + \special{pdf:mapline gbkhei@UGBK@ UniGB-UTF16-H AdobeHeitiStd-Regular.otf} + \special{pdf:mapline gbkfs@UGBK@ UniGB-UTF16-H AdobeFangsongStd-Regular.otf} + + \special{pdf:mapline cyberb@Unicode@ UniGB-UTF16-H AdobeSongStd-Light.otf} + \special{pdf:mapline unisong@Unicode@ UniGB-UTF16-H AdobeSongStd-Light.otf} + \special{pdf:mapline unikai@Unicode@ UniGB-UTF16-H AdobeKaitiStd-Regular.otf} + \special{pdf:mapline unihei@Unicode@ UniGB-UTF16-H AdobeHeitiStd-Regular.otf} + \special{pdf:mapline unifs@Unicode@ UniGB-UTF16-H AdobeFangsongStd-Regular.otf} + + \special{pdf:mapline gbksongsl@UGBK@ UniGB-UTF16-H AdobeSongStd-Light.otf -s .167} + \special{pdf:mapline gbkkaisl@UGBK@ UniGB-UTF16-H AdobeKaitiStd-Regular.otf -s .167} + \special{pdf:mapline gbkheisl@UGBK@ UniGB-UTF16-H AdobeHeitiStd-Regular.otf -s .167} + \special{pdf:mapline gbkfssl@UGBK@ UniGB-UTF16-H AdobeFangsongStd-Regular.otf -s .167} + + \special{pdf:mapline unisongsl@Unicode@ UniGB-UTF16-H AdobeSongStd-Light.otf -s .167} + \special{pdf:mapline unikaisl@Unicode@ UniGB-UTF16-H AdobeKaitiStd-Regular.otf -s .167} + \special{pdf:mapline uniheisl@Unicode@ UniGB-UTF16-H AdobeHeitiStd-Regular.otf -s .167} + \special{pdf:mapline unifssl@Unicode@ UniGB-UTF16-H AdobeFangsongStd-Regular.otf -s .167} + +%</adobe> +% \end{macrocode} +% +% \paragraph{\pkg{zhfandolfonts.tex}} +% +% \begin{macrocode} +%<*fandol> +\ProvidesFile{zhfandolfonts.tex}% + [2019/05/29 v2.4.16 Fandol font map loader for DVIPDFMx (CTEX)] + +\ifzhmappdf +%% pdfTeX does not support OTF fonts + +\else + \special{pdf:mapline gbk@UGBK@ UniGB-UTF16-H FandolSong-Regular.otf} + \special{pdf:mapline gbksong@UGBK@ UniGB-UTF16-H FandolSong-Regular.otf} + \special{pdf:mapline gbkkai@UGBK@ UniGB-UTF16-H FandolKai-Regular.otf} + \special{pdf:mapline gbkhei@UGBK@ UniGB-UTF16-H FandolHei-Regular.otf} + \special{pdf:mapline gbkfs@UGBK@ UniGB-UTF16-H FandolFang-Regular.otf} + + \special{pdf:mapline cyberb@Unicode@ UniGB-UTF16-H FandolSong-Regular.otf} + \special{pdf:mapline unisong@Unicode@ UniGB-UTF16-H FandolSong-Regular.otf} + \special{pdf:mapline unikai@Unicode@ UniGB-UTF16-H FandolKai-Regular.otf} + \special{pdf:mapline unihei@Unicode@ UniGB-UTF16-H FandolHei-Regular.otf} + \special{pdf:mapline unifs@Unicode@ UniGB-UTF16-H FandolFang-Regular.otf} + + \special{pdf:mapline gbksongsl@UGBK@ UniGB-UTF16-H FandolSong-Regular.otf -s .167} + \special{pdf:mapline gbkkaisl@UGBK@ UniGB-UTF16-H FandolKai-Regular.otf -s .167} + \special{pdf:mapline gbkheisl@UGBK@ UniGB-UTF16-H FandolHei-Regular.otf -s .167} + \special{pdf:mapline gbkfssl@UGBK@ UniGB-UTF16-H FandolFang-Regular.otf -s .167} + + \special{pdf:mapline unisongsl@Unicode@ UniGB-UTF16-H FandolSong-Regular.otf -s .167} + \special{pdf:mapline unikaisl@Unicode@ UniGB-UTF16-H FandolKai-Regular.otf -s .167} + \special{pdf:mapline uniheisl@Unicode@ UniGB-UTF16-H FandolHei-Regular.otf -s .167} + \special{pdf:mapline unifssl@Unicode@ UniGB-UTF16-H FandolFang-Regular.otf -s .167} + +%</fandol> +% \end{macrocode} +% +% \paragraph{\pkg{zhfounderfonts.tex}} +% +% \begin{macrocode} +%<*founder> +\ProvidesFile{zhfounderfonts.tex}% + [2019/05/29 v2.4.16 Founder font map loader for pdfTeX and DVIPDFMx (CTEX)] + +\ifzhmappdf + \pdfmapline{=gbk@UGBK@ <FZSSK.TTF} + \pdfmapline{=gbksong@UGBK@ <FZSSK.TTF} + \pdfmapline{=gbkkai@UGBK@ <FZKTK.TTF} + \pdfmapline{=gbkhei@UGBK@ <FZHTK.TTF} + \pdfmapline{=gbkfs@UGBK@ <FZFSK.TTF} + \pdfmapline{=gbkli@UGBK@ <FZLSK.TTF} + \pdfmapline{=gbkyou@UGBK@ <FZY1K.TTF} + + \pdfmapline{=cyberb@Unicode@ <FZSSK.TTF} + \pdfmapline{=unisong@Unicode@ <FZSSK.TTF} + \pdfmapline{=unikai@Unicode@ <FZKTK.TTF} + \pdfmapline{=unihei@Unicode@ <FZHTK.TTF} + \pdfmapline{=unifs@Unicode@ <FZFSK.TTF} + \pdfmapline{=unili@Unicode@ <FZLSK.TTF} + \pdfmapline{=uniyou@Unicode@ <FZY1K.TTF} + + \pdfmapline{=gbksongsl@UGBK@ <FZSSK.TTF} + \pdfmapline{=gbkkaisl@UGBK@ <FZKTK.TTF} + \pdfmapline{=gbkheisl@UGBK@ <FZHTK.TTF} + \pdfmapline{=gbkfssl@UGBK@ <FZFSK.TTF} + \pdfmapline{=gbklisl@UGBK@ <FZLSK.TTF} + \pdfmapline{=gbkyousl@UGBK@ <FZY1K.TTF} + + \pdfmapline{=unisongsl@Unicode@ <FZSSK.TTF} + \pdfmapline{=unikaisl@Unicode@ <FZKTK.TTF} + \pdfmapline{=uniheisl@Unicode@ <FZHTK.TTF} + \pdfmapline{=unifssl@Unicode@ <FZFSK.TTF} + \pdfmapline{=unilisl@Unicode@ <FZLSK.TTF} + \pdfmapline{=uniyousl@Unicode@ <FZY1K.TTF} + +\else + \special{pdf:mapline gbk@UGBK@ unicode FZSSK.TTF} + \special{pdf:mapline gbksong@UGBK@ unicode FZSSK.TTF} + \special{pdf:mapline gbkkai@UGBK@ unicode FZKTK.TTF} + \special{pdf:mapline gbkhei@UGBK@ unicode FZHTK.TTF} + \special{pdf:mapline gbkfs@UGBK@ unicode FZFSK.TTF} + \special{pdf:mapline gbkli@UGBK@ unicode FZLSK.TTF} + \special{pdf:mapline gbkyou@UGBK@ unicode FZY1K.TTF} + + \special{pdf:mapline cyberb@Unicode@ unicode FZSSK.TTF} + \special{pdf:mapline unisong@Unicode@ unicode FZSSK.TTF} + \special{pdf:mapline unikai@Unicode@ unicode FZKTK.TTF} + \special{pdf:mapline unihei@Unicode@ unicode FZHTK.TTF} + \special{pdf:mapline unifs@Unicode@ unicode FZFSK.TTF} + \special{pdf:mapline unili@Unicode@ unicode FZLSK.TTF} + \special{pdf:mapline uniyou@Unicode@ unicode FZY1K.TTF} + + \special{pdf:mapline gbksongsl@UGBK@ unicode FZSSK.TTF -s .167} + \special{pdf:mapline gbkkaisl@UGBK@ unicode FZKTK.TTF -s .167} + \special{pdf:mapline gbkheisl@UGBK@ unicode FZHTK.TTF -s .167} + \special{pdf:mapline gbkfssl@UGBK@ unicode FZFSK.TTF -s .167} + \special{pdf:mapline gbklisl@UGBK@ unicode FZLSK.TTF -s .167} + \special{pdf:mapline gbkyousl@UGBK@ unicode FZY1K.TTF -s .167} + + \special{pdf:mapline unisongsl@Unicode@ unicode FZSSK.TTF -s .167} + \special{pdf:mapline unikaisl@Unicode@ unicode FZKTK.TTF -s .167} + \special{pdf:mapline uniheisl@Unicode@ unicode FZHTK.TTF -s .167} + \special{pdf:mapline unifssl@Unicode@ unicode FZFSK.TTF -s .167} + \special{pdf:mapline unilisl@Unicode@ unicode FZLSK.TTF -s .167} + \special{pdf:mapline uniyousl@Unicode@ unicode FZY1K.TTF -s .167} + +%</founder> +% \end{macrocode} +% +% \paragraph{\pkg{zhubuntufonts.tex}} +% +% \begin{macrocode} +%<*ubuntu> +\ProvidesFile{zhubuntufonts.tex}% + [2019/05/29 v2.4.16 Ubuntu font map loader for pdfTeX and DVIPDFMx (CTEX)] + +\ifzhmappdf + \pdfmapline{=gbk@UGBK@ <uming.ttc} + \pdfmapline{=gbksong@UGBK@ <uming.ttc} + \pdfmapline{=gbkkai@UGBK@ <ukai.ttc} + \pdfmapline{=gbkhei@UGBK@ <wqy-zenhei.ttc} + \pdfmapline{=gbkfs@UGBK@ <uming.ttc} + \pdfmapline{=gbkyou@UGBK@ <wqy-zenhei.ttc} + + \pdfmapline{=cyberb@Unicode@ <uming.ttc} + \pdfmapline{=unisong@Unicode@ <uming.ttc} + \pdfmapline{=unikai@Unicode@ <ukai.ttc} + \pdfmapline{=unihei@Unicode@ <wqy-zenhei.ttc} + \pdfmapline{=unifs@Unicode@ <uming.ttc} + \pdfmapline{=uniyou@Unicode@ <wqy-zenhei.ttc} + + \pdfmapline{=gbksongsl@UGBK@ <uming.ttc} + \pdfmapline{=gbkkaisl@UGBK@ <ukai.ttc} + \pdfmapline{=gbkheisl@UGBK@ <wqy-zenhei.ttc} + \pdfmapline{=gbkfssl@UGBK@ <uming.ttc} + \pdfmapline{=gbkyousl@UGBK@ <wqy-zenhei.ttc} + + \pdfmapline{=unisongsl@Unicode@ <uming.ttc} + \pdfmapline{=unikaisl@Unicode@ <ukai.ttc} + \pdfmapline{=uniheisl@Unicode@ <wqy-zenhei.ttc} + \pdfmapline{=unifssl@Unicode@ <uming.ttc} + \pdfmapline{=uniyousl@Unicode@ <wqy-zenhei.ttc} + +\else + \special{pdf:mapline gbk@UGBK@ unicode :0:uming.ttc} + \special{pdf:mapline gbksong@UGBK@ unicode :0:uming.ttc} + \special{pdf:mapline gbkkai@UGBK@ unicode :0:ukai.ttc} + \special{pdf:mapline gbkhei@UGBK@ unicode :0:wqy-zenhei.ttc} + \special{pdf:mapline gbkfs@UGBK@ unicode :0:uming.ttc} + + \special{pdf:mapline cyberb@Unicode@ unicode :0:uming.ttc} + \special{pdf:mapline unisong@Unicode@ unicode :0:uming.ttc} + \special{pdf:mapline unikai@Unicode@ unicode :0:ukai.ttc} + \special{pdf:mapline unihei@Unicode@ unicode :0:wqy-zenhei.ttc} + \special{pdf:mapline unifs@Unicode@ unicode :0:uming.ttc} + + \special{pdf:mapline gbksongsl@UGBK@ unicode :0:uming.ttc -s .167} + \special{pdf:mapline gbkkaisl@UGBK@ unicode :0:ukai.ttc -s .167} + \special{pdf:mapline gbkheisl@UGBK@ unicode :0:wqy-zenhei.ttc -s .167} + \special{pdf:mapline gbkfssl@UGBK@ unicode :0:uming.ttc -s .167} + + \special{pdf:mapline unisongsl@Unicode@ unicode :0:uming.ttc -s .167} + \special{pdf:mapline unikaisl@Unicode@ unicode :0:ukai.ttc -s .167} + \special{pdf:mapline uniheisl@Unicode@ unicode :0:wqy-zenhei.ttc -s .167} + \special{pdf:mapline unifssl@Unicode@ unicode :0:uming.ttc -s .167} + +%</ubuntu> +% \end{macrocode} +% +% \begin{macrocode} +\fi + +\ctex@zhmap@endinput +%</zhmap> +% \end{macrocode} +% +% \subsubsection{制作 \texttt{spa} 文件} +% +% 我们通过 \XeTeX{} 的 \tn{XeTeXglyphbounds} 取得字体中标点符号的边界信息,为 +% \pkg{CJKpunct} 宏包制作 \file{spa}。 +% +% \begin{macrocode} +%<*spa> +%<*macro> +\input expl3-generic % +\ExplSyntaxOn +\sys_if_engine_xetex:F + { + \msg_new:nn { ctex } { xetex } + { XeTeX~is~required~to~compile~this~document! } + \msg_fatal:nn { ctex } { xetex } + } +% \end{macrocode} +% +% \pkg{CJKpunct} 定义的标点符号是: +% \begin{verbatim} +% ‘“「『〔([{〈《〖【 +% —…、。,.:;!?%〕)]}〉》〗】’”」』 +% \end{verbatim} +% 注意顺序不能改变。 +% \begin{macrocode} +\seq_const_from_clist:Nn \c_@@_punct_seq + { + "2018 , "201C , "300C , "300E , "3014 , "FF08 , "FF3B , "FF5B , + "3008 , "300A , "3016 , "3010 , + "2014 , "2026 , "3001 , "3002 , "FF0C , "FF0E , "FF1A , "FF1B , + "FF01 , "FF1F , "FF05 , "3015 , "FF09 , "FF3D , "FF5D , "3009 , + "300B , "3017 , "3011 , "2019 , "201D , "300D , "300F + } +% \end{macrocode} +% +% \begin{macro}[int]{\ctex_make_spa:nn} +% |#1| 是 \file{spa} 文件名,|#2| 是由 CJK 族名与字体构成的逗号列表。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_make_spa:nn #1#2 + { + \iow_open:Nn \g_@@_spa_iow {#1} + \clist_map_inline:nn {#2} + { \@@_write_family:nn ##1 } + \iow_close:N \g_@@_spa_iow + } +\iow_new:N \g_@@_spa_iow +\cs_new_eq:NN \MAKESPA \ctex_make_spa:nn +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_write_family:nn #1#2 + { + \group_begin: + \tex_font:D \l_@@_punct_font = "#2" ~ at ~ 100 pt \scan_stop: + \l_@@_punct_font + \clist_clear:N \l_@@_punct_bounds_clist + \seq_map_inline:Nn \c_@@_punct_seq + { \exp_args:No \@@_save_bounds:n { \int_use:N \tex_XeTeXcharglyph:D ##1 } } + \iow_now:Nx \g_@@_spa_iow + { + \token_to_str:N \ctexspadef {#1} +% \end{macrocode} +% 最后这三个逗号对 \pkg{CJKpunct} 来说是必要的。 +% \begin{macrocode} + { \l_@@_punct_bounds_clist , , , } + } + \group_end: + } +\cs_new_protected_nopar:Npn \@@_save_bounds:n #1 + { + \clist_put_right:Nx \l_@@_punct_bounds_clist + { + \@@_calc_bounds:nn { 1 } {#1} , + \@@_calc_bounds:nn { 3 } {#1} + } + } +\clist_new:N \l_@@_punct_bounds_clist +% \end{macrocode} +% +% \pkg{CJKpunct} 要求的格式是边界空白宽度与 1\,em 的比值的一百倍。 +% \begin{macrocode} +\cs_new_nopar:Npn \@@_calc_bounds:nn #1#2 + { + \fp_eval:n + { + round + ( + \dim_to_decimal_in_unit:nn + { 100 \tex_XeTeXglyphbounds:D #1 ~ #2 } + { 1 em } + ) + } + } +\ExplSyntaxOff +%</macro> +% \end{macrocode} +% +% 下面是 \CTeX{} 定义的一些字体。 +% \begin{macrocode} +%<*make> +\input ctexspamacro % + +\MAKESPA {ctexpunct.spa} + { + {adobezhsong} {AdobeSongStd-Light} , + {adobezhhei} {AdobeHeitiStd-Regular} , + {adobezhkai} {AdobeKaitiStd-Regular} , + {adobezhfs} {AdobeFangsongStd-Regular} , + {fandolzhsong} {FandolSong} , + {fandolzhsongb} {FandolSong-Bold} , + {fandolzhhei} {FandolHei} , + {fandolzhheib} {FandolHei-Bold} , + {fandolzhkai} {FandolKai} , + {fandolzhfs} {FandolFang} , + {founderzhsong} {FZShuSong-Z01} , + {founderzhsongb} {FZXiaoBiaoSong-B05} , + {founderzhhei} {FZHei-B01} , + {founderzhheil} {FZXiHeiI-Z08} , + {founderzhkai} {FZKai-Z03} , + {founderzhfs} {FZFangSong-Z02} , + {founderzhli} {FZLiShu-S01} , + {founderzhyou} {FZXiYuan-M01} , + {founderzhyoub} {FZZhunYuan-M02} , + {ubuntuzhsong} {AR PL UMing CN} , + {ubuntuzhhei} {WenQuanYi Zen Hei} , + {ubuntuzhkai} {AR PL UKai CN} , + {windowszhsong} {SimSun} , + {windowszhhei} {SimHei} , + {windowszhkai} {KaiTi} , + {windowszhfs} {FangSong} , + {windowszhli} {LiSu} , + {windowszhyou} {YouYuan} , + {windowszhyahei} {Microsoft YaHei} , + {windowszhyaheib} {Microsoft YaHei Bold} + } + +\primitive\end +%</make> +%</spa> +% \end{macrocode} +% +% \subsection{\pkg{translator} 宏包的中文字典} +% +% \begin{macrocode} +%<*dict> +% \end{macrocode} +% +% \changes{v2.4}{2016/02/19}{提供 \pkg{translator} 宏包的中文定理名称翻译。} +% +% 包括 \pkg{ChineseGBK} 和 \pkg{ChineseUTF8} 两种形式,目前只翻译 \pkg{beamer} +% 宏包需要的定理环境名称。 +% +% \begin{macrocode} +%<*theorem> +\providetranslation{Comments}{评论} +\providetranslation{comments}{评论} +\providetranslation{Comment}{评论} +\providetranslation{comment}{评论} +\providetranslation{Corollaries}{推论} +\providetranslation{corollaries}{推论} +\providetranslation{Corollary}{推论} +\providetranslation{corollary}{推论} +\providetranslation{Definitions}{定义} +\providetranslation{definitions}{定义} +\providetranslation{Definition}{定义} +\providetranslation{definition}{定义} +\providetranslation{Examples}{例} +\providetranslation{examples}{例} +\providetranslation{Example}{例} +\providetranslation{example}{例} +\providetranslation{Exercises}{练习} +\providetranslation{exercises}{练习} +\providetranslation{Exercise}{练习} +\providetranslation{exercise}{练习} +\providetranslation{Facts}{事实} +\providetranslation{facts}{事实} +\providetranslation{Fact}{事实} +\providetranslation{fact}{事实} +\providetranslation{Key Lemmas}{关键引理} +\providetranslation{key lemmas}{关键引理} +\providetranslation{Key Lemma}{关键引理} +\providetranslation{key lemma}{关键引理} +\providetranslation{Key Observations}{关键观察} +\providetranslation{key observations}{关键观察} +\providetranslation{Key Observation}{关键观察} +\providetranslation{key observation}{关键观察} +\providetranslation{Lemmas}{引理} +\providetranslation{lemmas}{引理} +\providetranslation{Lemma}{引理} +\providetranslation{lemma}{引理} +\providetranslation{Main Theorems}{主要定理} +\providetranslation{main theorems}{主要定理} +\providetranslation{Main Theorem}{主要定理} +\providetranslation{main theorem}{主要定理} +\providetranslation{Observations}{观察} +\providetranslation{observations}{观察} +\providetranslation{Observation}{观察} +\providetranslation{observation}{观察} +\providetranslation{Problems}{问题} +\providetranslation{problems}{问题} +\providetranslation{Problem}{问题} +\providetranslation{problem}{问题} +\providetranslation{Proofs}{证明} +\providetranslation{proofs}{证明} +\providetranslation{Proof}{证明} +\providetranslation{proof}{证明} +\providetranslation{Proof Sketch}{证明提要} +\providetranslation{Proof sketch}{证明提要} +\providetranslation{proof sketch}{证明提要} +\providetranslation{Proof Sketches}{证明提要} +\providetranslation{Proof sketches}{证明提要} +\providetranslation{proof sketches}{证明提要} +\providetranslation{Sketch of Proof}{证明提要} +\providetranslation{Sketch of Proofs}{证明提要} +\providetranslation{Sketch of proof}{证明提要} +\providetranslation{Sketch of proofs}{证明提要} +\providetranslation{sketch of proof}{证明提要} +\providetranslation{sketch of proofs}{证明提要} +\providetranslation{Propositions}{命题} +\providetranslation{propositions}{命题} +\providetranslation{Proposition}{命题} +\providetranslation{proposition}{命题} +\providetranslation{Remarks}{注} +\providetranslation{remarks}{注} +\providetranslation{Remark}{注} +\providetranslation{remark}{注} +\providetranslation{Solutions}{解} +\providetranslation{solutions}{解} +\providetranslation{Solution}{解} +\providetranslation{solution}{解} +\providetranslation{Theorems}{定理} +\providetranslation{theorems}{定理} +\providetranslation{Theorem}{定理} +\providetranslation{theorem}{定理} +%</theorem> +% \end{macrocode} +% +% \begin{macrocode} +%</dict> +% \end{macrocode} +% +% \subsection{\pkg{ctexcap} 宏包} +% +% \begin{macrocode} +%<*ctexcap> +% \end{macrocode} +% +% \pkg{ctexcap} 是过时宏包。 +% \begin{macrocode} +\clist_new:N \l_@@_ctexcap_options_clist +\clist_set:Nx \l_@@_ctexcap_options_clist + { \exp_not:v { opt@ \@currname . \@currext } , heading } +\msg_new:nnn { ctexcap } { deprecated } + { + Package~`ctexcap'~is~deprecated.\\ + Please~use~package~`ctex'~with~option~`#1'~instead: \\\\ + \iow_indent:n { \token_to_str:N \usepackage [#1] \{ ctex \} } \\ + } +\msg_warning:nnx { ctexcap } { deprecated } + { \clist_use:Nn \l_@@_ctexcap_options_clist { , ~ } } +% \end{macrocode} +% +% \pkg{ctexcap} 是默认打开 \opt{heading} 选项的 \pkg{ctex}。 +% \begin{macrocode} +\PassOptionsToPackage { heading = true } { ctexcap } +\RequirePackageWithOptions { ctex } +% \end{macrocode} +% +% \begin{macrocode} +%</ctexcap> +% \end{macrocode} +% +% +% \subsection{\pkg{ctexhook} 宏包} +% +% \changes{v2.2}{2015/06/26}{将文档开头和宏包末尾钩子提取到 \pkg{ctexhook} 宏包中。} +% +% \begin{macrocode} +%<*ctexhook> +% \end{macrocode} +% +% \begin{macro}[int]{\ctex_at_end_preamble:n,\ctex_after_end_preamble:n} +% 实现 \pkg{etoolbox} 宏包的 \tn{AtEndPreamble} 和 \tn{AfterEndPreamble}。 +% \begin{macrocode} +\cs_new_protected:Npn \ctex_at_end_preamble:n #1 + { \tl_gput_right:Nn \g_@@_end_preamble_hook_tl {#1} } +\cs_new_protected:Npn \ctex_after_end_preamble:n #1 + { \tl_gput_right:Nn \g_@@_after_end_preamble_hook_tl {#1} } +\cs_new_protected_nopar:Npn \CTEX@document@left@hook + { \group_end: \g_@@_end_preamble_hook_tl \group_begin: } +\cs_new_protected_nopar:Npn \CTEX@document@right@hook + { \scan_stop: \g_@@_after_end_preamble_hook_tl \tex_ignorespaces:D } +\cs_set_nopar:Npx \document + { + \CTEX@document@left@hook + \exp_not:o { \document } + \CTEX@document@right@hook + } +\tl_new:N \g_@@_end_preamble_hook_tl +\tl_new:N \g_@@_after_end_preamble_hook_tl +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_at_end_package:nn} +% 与 \pkg{filehook} 的 \tn{AtEndOfPackageFile*} 类似,如果原来没有在载入宏包则 +% 在宏包末尾执行语句,否则立即执行。 +% \begin{macrocode} +\cs_new_protected:Npn \ctex_at_end_package:nn #1#2 + { + \@ifpackageloaded {#1} + {#2} + { \ctex_gadd_hook:cn { g_@@_at_end_ #1 _hook_tl } {#2} } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_gadd_hook:Nn, \ctex_gadd_hook:cn} +% 给钩子附加内容。 +% \begin{macrocode} +\cs_new_protected:Npn \ctex_gadd_hook:Nn #1#2 + { + \tl_if_exist:NF #1 { \tl_new:N #1 } + \tl_gput_right:Nn #1 {#2} + } +\cs_generate_variant:Nn \ctex_gadd_hook:Nn { c } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_package_end_hook:n, \ctex_package_end_hook:o} +% 宏包末尾钩子,只执行一次,用后清除。 +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ctex_package_end_hook:n #1 + { + \cs_if_exist_use:cT { g_@@_at_end_ #1 _hook_tl } + { \cs_undefine:c { g_@@_at_end_ #1 _hook_tl } } + } +\cs_generate_variant:Nn \ctex_package_end_hook:n { o } +% \end{macrocode} +% \end{macro} +% +% 对 \tn{@popfilename} 做补丁来实现 \cs{ctex_at_end_package:nn} 的功能。 +% \begin{macrocode} +\tl_put_left:Nn \@popfilename + { + \cs_if_eq:NNT \@currext \@pkgextension + { \ctex_package_end_hook:o { \@currname } } + } +% \end{macrocode} +% +% \begin{macrocode} +%</ctexhook> +% \end{macrocode} +% +% +% \subsection{\pkg{ctexpatch} 宏包} +% +% \changes{v2.2}{2015/06/23}{新增子宏包 \pkg{ctexpatch} 实现给宏打补丁功能。} +% +% \begin{macrocode} +%<*ctexpatch> +% \end{macrocode} +% +% \begin{macrocode} +\cs_if_exist:NF \str_new:N { \RequirePackage { l3str } } +% \end{macrocode} +% +% \begin{macro}[int]{\ctex_patch_cmd_once:NnnnTF} +% 只进行第一次匹配进行替换。参数 |#2| 是宏重建时的 \tn{catcode} 设置。 +% \begin{macrocode} +\cs_new_protected:Npn \ctex_patch_cmd_once:NnnnTF #1#2 + { + \ctex_patch_boot:NNnnTF \@@_patch_cmd:Nnnnnw #1 + { once } {#2} { \use_i:nn } { \use_ii:nn } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_patch_cmd_all:NnnnTF} +% 替换所有匹配到的文本。 +% \begin{macrocode} +\cs_new_protected:Npn \ctex_patch_cmd_all:NnnnTF #1#2 + { + \ctex_patch_boot:NNnnTF \@@_patch_cmd:Nnnnnw #1 + { all } {#2} { \use_i:nn } { \use_ii:nn } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_patch_cmd:Nnn} +% 快捷方式,在补丁的时候关闭 \LaTeXiii{} 语法和设置 |@| 为字母类,补丁失败时给出警告。 +% \begin{macrocode} +\cs_new_protected:Npn \ctex_patch_cmd:Nnn #1 + { + \ctex_patch_boot:NNnnTF \@@_patch_cmd:Nnnnnw #1 + { once } + { + \ExplSyntaxOff + \char_set_catcode_letter:n { 64 } + } + { } + { \ctex_patch_failure:N #1 } + } +\cs_new_protected:Npn \ctex_patch_failure:N #1 + { \msg_warning:nnx { ctex } { patch-failure } { \token_to_str:N #1 } } +\msg_new:nnn { ctex } { patch-failure } + { Oops!~Command~`#1'~is~NOT~patchable.\\ } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_preto_cmd:NnnTF} +% 在宏的原本定义前面增加钩子。 +% \begin{macrocode} +\cs_new_protected:Npn \ctex_preto_cmd:NnnTF #1#2 + { + \ctex_patch_boot:NNnnTF \@@_hookto_cmd:Nnnnw #1 + { left } {#2} { \use_i:nn } { \use_ii:nn } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_appto_cmd:NnnTF} +% 在宏的原本定义后面追加钩子。 +% \begin{macrocode} +\cs_new_protected:Npn \ctex_appto_cmd:NnnTF #1#2 + { + \ctex_patch_boot:NNnnTF \@@_hookto_cmd:Nnnnw #1 + { right } {#2} { \use_i:nn } { \use_ii:nn } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_patch_boot:NNnnTF} +% 参数记号 |#| 作为宏的参数被读入时,总是会双写,会影响随后的字符串替换。需要先 +% 将它转换为普通符号。 +% \begin{macrocode} +\cs_new_protected:Npn \ctex_patch_boot:NNnnTF #1#2#3#4#5#6 + { + \tl_set:Nn \@@_patch_true:w {#5} + \tl_set:Nn \@@_patch_false:w {#6} + \group_begin: + \char_set_catcode_other:n { 35 } + \ctex_parse_name:NN #1 #2 {#3} {#4} + } +\tl_new:N \@@_patch_true:w +\tl_new:N \@@_patch_false:w +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\ctex_parse_name:NN} +% \changes{v2.4}{2016/04/11}{修复宏名解析错误。} +% 用 \tn{DeclareRobustCommand} 定义的宏或者由 \tn{newcommand} 或 \tn{newrobustcmd} +% 定义的带一个可选参数的宏第一次展开的结果都不是其实际定义,实际定义被保存在另外的 +% 宏中。由这些命令定义的宏的第一次展开结果可以有下面的形式(细节可查阅 \pkg{xpatch} +% 的文档): +% \begin{verbatim}[numbers=left,gobble=4] +% \protect␣\xaa␣␣ % \DeclareRobustCommand\xaa[1]{...} +% \protect␣\xab␣␣ % \DeclareRobustCommand\xab[1][]{...} +% \@protected@testopt␣\xac␣\\xac␣{} % \newcommand\xac[1][]{...} +% \@testopt␣\\xad␣{} % \newrobustcmd\xad[1][]{...} +% \x@protect␣\1\protect␣\1␣␣ % \DeclareRobustCommand\1[1]{...} +% \x@protect␣\2\protect␣\2␣␣ % \DeclareRobustCommand\2[1][]{...} +% \@protected@testopt␣\3\\3␣{} % \newcommand\3[1][]{...} +% \@testopt␣\\4␣{} % \newrobustcmd\4[1][]{...} +% \end{verbatim} +% \pkg{ctexpatch} 的主要原理是先对宏的 \tn{meaning} 作字符串替换,然后再用 +% \tn{scantokens} 来重建它。我们希望对宏的实际定义打补丁,为此需要先得到 +% 对应的名字。\pkg{letltxmacro}、\pkg{show2e} 和 \pkg{xpatch} 宏包中都有 +% 类似的工作。 +% \begin{macrocode} +\cs_new_protected:Npn \ctex_parse_name:NN #1#2 + { \ctex_parse_name:NNx #1#2 { \cs_to_str:N #2 } } +\group_begin: +\cs_set_protected:Npn \@@_tmp:w #1#2#3 + { + \cs_new_protected:Npn \ctex_parse_name:NNn ##1##2##3 + { + \bool_lazy_or:nnTF + { \cs_if_exist_p:c { ##3 ~ } } + { \cs_if_exist_p:c { #1##3 } } + { + \group_begin: + \use:x + { + \group_end: + \@@_parse_name:nNNNnN + { \cs_replacement_spec:N ##2 } + \exp_not:N ##2 + \exp_not:c { ##3 ~ } + \exp_not:c { #1##3 } + } {##3} ##1 + } + { ##1##2 } + } + \cs_new_protected:Npn \@@_parse_name:nNNNnN ##1##2##3##4##5##6 + { + \exp_args:Nc ##6 + { + \str_case:nnTF {##1} + { + { \protect ##3 } { } + { \x@protect ##2 \protect ##3 } { } + } + { + \str_if_eq:eeTF + { \exp_not:n { #1@protected@ ##3 #1##3 } } + { + \exp_last_unbraced:Nf \@@_parse_name:w + \cs_replacement_spec:N ##3 #3 ~ #2 \q_stop + } + { #1##5 ~ } { ##5 ~ } + } + { + \str_case:onTF { \@@_parse_name:w ##1 #3 ~ #2 \q_stop } + { + { #1@protected@ ##2 ##4 } { } + { #1@ ##4 } { } + } + { #1##5 } {##5} + } + } + } + \cs_new:Npn \@@_parse_name:w ##1 #3 ~ ##2 #2 ##3 \q_stop { ##1##2 } + } +\use:x + { + \@@_tmp:w + { \c_backslash_str } + { \c_left_brace_str } + { \tl_to_str:n { testopt } } + } +\group_end: +\cs_generate_variant:Nn \ctex_parse_name:NNn { NNx } +% \end{macrocode} +% \end{macro} +% +% \begin{variable}{\l_@@_prefix_str,\l_@@_parameter_str,\l_@@_replacement_str} +% 分别保存宏的 \tn{meaning} 中的前缀、参数文本和替换文本。 +% \begin{macrocode} +\str_new:N \l_@@_prefix_str +\str_new:N \l_@@_parameter_str +\str_new:N \l_@@_replacement_str +% \end{macrocode} +% \end{variable} +% +% \begin{macro}[int]{\ctex_get_macro_meaning:NTF} +% \begin{macro}{\@@_get_macro_meaning:w} +% 解构待补丁宏的 \tn{meaning}。若命令不是宏,则走向 |false| 分支。 +% \begin{macrocode} +\group_begin: + \cs_set_protected:Npn \@@_tmp:w #1 + { + \prg_new_protected_conditional:Npnn + \ctex_get_macro_meaning:N ##1 { TF } + { + \exp_after:wN \@@_get_macro_meaning:w + \token_to_meaning:N ##1 \q_mark #1 -> \q_mark \q_stop + } + \cs_new_protected:Npn \@@_get_macro_meaning:w + ##1 #1 ##2 -> ##3 \q_mark ##4 \q_stop + { + \tl_if_empty:nTF { ##4 } + { \prg_return_false: } + { + \str_set:Nn \l_@@_prefix_str { ##1 } + \str_set:Nn \l_@@_parameter_str { ##2 } + \str_set:Nn \l_@@_replacement_str { ##3 } + \prg_return_true: + } + } + } + \exp_args:No \@@_tmp:w { \tl_to_str:n { macro: } } +\group_end: +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[int]{\ctex_if_rescanable:NnTF} +% 检查宏是否可以重建。 +% \begin{macrocode} +\cs_new_protected:Npn \ctex_if_rescanable:NnTF #1#2#3#4 + { + \ctex_get_macro_meaning:NTF #1 + { + \@@_patch_rebuild:Nn \@@_rebuild_cmd:w {#2} + \cs_if_eq:NNTF #1 \@@_rebuild_cmd:w {#3} {#4} + } + {#4} + } +\cs_new_eq:NN \@@_rebuild_cmd:w \prg_do_nothing: +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_patch_rebuild:Nn} +% 使用 \cs{tl_rescan:nn} 来重新记号化 \tn{meaning} 字符串。 +% \begin{macrocode} +\cs_new_protected:Npn \@@_patch_rebuild:Nn #1#2 + { + \@@_patch_rescan:NNn \l_@@_prefix_tl \l_@@_prefix_str {#2} + \@@_patch_rescan:NNn \l_@@_parameter_tl \l_@@_parameter_str {#2} + \@@_patch_rescan:NNn \l_@@_replacement_tl \l_@@_replacement_str {#2} + \use:x + { + \exp_not:o { \l_@@_prefix_tl } \tex_def:D \exp_not:N #1 + \exp_not:o { \l_@@_parameter_tl } + { \exp_not:o { \l_@@_replacement_tl } } + } + } +\cs_new_protected:Npn \@@_patch_rescan:NNn #1#2#3 + { + \str_if_empty:NTF #2 + { \tl_clear:N #1 } + { \tl_set_rescan:Nno #1 {#3} {#2} } + } +\tl_new:N \l_@@_prefix_tl +\tl_new:N \l_@@_parameter_tl +\tl_new:N \l_@@_replacement_tl +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_patch_cmd:Nnnnnw} +% 对宏的替换文本进行字符串替换,然后重建。 +% \begin{macrocode} +\cs_new_protected:Npn \@@_patch_cmd:Nnnnnw #1#2#3#4#5 + { + \group_end: + \ctex_if_rescanable:NnTF #1 {#3} + { + \use:x + { + \@@_patch_replace:nnnTF {#2} + { \tl_to_str:n {#4} } + { \tl_to_str:n {#5} } + } + { + \@@_patch_rebuild:Nn #1 {#3} + \@@_patch_true:w + } + { \@@_patch_false:w } + } + { \@@_patch_false:w } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_patch_replace:nnnTF} +% 替换前先检查原文本是否存在。 +% \begin{macrocode} +\cs_new_protected:Npn \@@_patch_replace:nnnTF #1#2#3#4 + { + \tl_if_in:NnTF \l_@@_replacement_str {#2} + { \use:c { tl_replace_ #1 :Nnn } \l_@@_replacement_str {#2} {#3} #4 } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_hookto_cmd:Nnnnw} +% 在宏的前/后附加钩子。 +% \begin{macrocode} +\cs_new_protected:Npn \@@_hookto_cmd:Nnnnw #1#2#3#4 + { + \group_end: + \ctex_get_macro_meaning:NTF #1 + { + \str_if_empty:NTF \l_@@_parameter_str + { \@@_hookto_cmd_parameterless:Nnnnw } + { \@@_hookto_cmd_parameter:Nnnnw } + #1 {#2} {#3} {#4} + } + { \@@_patch_false:w } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_hookto_cmd_parameterless:Nnnnw} +% 如果宏没有参数,可以直接进行附加操作。注意保持宏的前缀。 +% \begin{macrocode} +\cs_new_protected:Npn \@@_hookto_cmd_parameterless:Nnnnw #1#2#3#4 + { + \str_if_empty:NF \l_@@_prefix_str + { \tl_rescan:no {#3} { \l_@@_prefix_str } } + \tex_edef:D #1 + { + \use:c { @@_ #2 _hook_aux:nn } + { \exp_not:o {#1} } + { \exp_not:n {#4} } + } + \@@_patch_true:w + } +\cs_generate_variant:Nn \tl_rescan:nn { no } +\cs_new:Npn \@@_left_hook_aux:nn #1#2 { #2#1 } +\cs_new_eq:NN \@@_right_hook_aux:nn \use:nn +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_hookto_cmd_parameter:Nnnnw} +% 如果宏有参数,需要在字符串中进行附加,然后再重建。 +% \begin{macrocode} +\cs_new_protected:Npn \@@_hookto_cmd_parameter:Nnnnw #1#2#3#4 + { + \@@_patch_rebuild:Nn \@@_rebuild_cmd:w {#3} + \cs_if_eq:NNTF #1 \@@_rebuild_cmd:w + { + \use:c { str_put_ #2 :Nn } \l_@@_replacement_str {#4} + \@@_patch_rebuild:Nn #1 {#3} + \@@_patch_true:w + } + { \@@_patch_false:w } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%</ctexpatch> +% \end{macrocode} +% +% \end{implementation} +% +% \Finale +% +% \endinput +% +% \DisableImplementation +% +% \begin{implementation} +% +% \subsection{\cls{ctxdoc}} +% +% \begin{macrocode} +%<*ctxdoc> +% \end{macrocode} +% +% \begin{macrocode} +%<@@=ctxdoc> +% \end{macrocode} +% +% \begin{macrocode} +\ExplSyntaxOff +\let\pdfmdfivesum\mdfivesum +\DeclareOption*{\PassOptionsToClass{\CurrentOption}{l3doc}} +\PassOptionsToClass{a4paper,full}{l3doc} +\ProcessOptions +\@namedef{ver@thumbpdf.sty}{9999/99/99} +\LoadClass{l3doc} +\RequirePackage[UTF8, punct = kaiming, heading, fontset = none, + linespread = 1.2, sub3section]{ctex} +\ifxetex + \xeCJKsetup{AutoFakeBold=false} +\fi +\ctexset{ + fontset, + abstractname = 简介, + indexname = 代码索引, + section = { + format = \Large\bfseries\raggedright, + name = {第,节}, + }, +} +\RequirePackage[toc]{multitoc} +\RequirePackage{geometry} +\RequirePackage{tabularx} +\RequirePackage{makecell} +\RequirePackage{threeparttable} +\RequirePackage{siunitx} +\RequirePackage{unicode-math} +\RequirePackage{xcolor} +\RequirePackage{caption} +\RequirePackage{fancyvrb-ex} +\RequirePackage{zref-base} +\geometry{includemp,hmargin={0mm,15mm},vmargin={25mm,15mm},footskip=7mm} +\hypersetup{pdfstartview=FitH,bookmarksdepth=subparagraph} +\setcounter{secnumdepth}{4} +\setcounter{tocdepth}{2} +\newcommand*\email{\nolinkurl} +\setmainfont{TeX Gyre Pagella} +\setsansfont{TeX Gyre Heros} +\setmonofont[ + HyphenChar = None , + UprightFont=* Light, BoldFont=* Bold, + SlantedFont=* Light Oblique]{CMU Typewriter Text} +\setmathfont{texgyrepagella-math.otf} +\captionsetup{strut=off, labelsep=quad, labelfont+=bf} +%% <--- http://tex.stackexchange.com/a/40896 +\patchcmd{\@addtocurcol}% + {\vskip \intextsep}% + {\edef\save@first@penalty{\the\lastpenalty}\unpenalty + \ifnum \lastpenalty = \@M % hopefully the OR penalty + \unpenalty + \else + \penalty \save@first@penalty \relax % put it back + \fi + \ifnum\outputpenalty <-\@Mii + \addvspace\intextsep + \vskip\parskip + \else + \addvspace\intextsep + \fi}% + {\typeout{*** SUCCESS ***}}{\typeout{*** FAIL ***}} +\patchcmd{\@addtocurcol}% + {\vskip\intextsep \ifnum\outputpenalty <-\@Mii \vskip -\parskip\fi}% + {\ifnum\outputpenalty <-\@Mii + \aftergroup\vskip\aftergroup\intextsep + \aftergroup\nointerlineskip + \else + \vskip\intextsep + \fi}% + {\typeout{*** SUCCESS ***}}{\typeout{*** FAIL ***}} +\patchcmd{\@getpen}{\@M}{\@Mi} + {\typeout{*** SUCCESS ***}}{\typeout{*** FAIL ***}} +%% ---> +%% 不对代码实现的 \section 以下标题编目录。 +\AtBeginEnvironment{implementation}{% + \ifnum\value{tocdepth}>\@ne + \addtocontents{toc}{\protect\value{tocdepth}=1\relax}% + \fi} +\ifxetex + \let\ctexdocverbaddon\xeCJKVerbAddon + \def\ctexdisableecglue{\xeCJKsetup{CJKecglue}} + \def\ctexplainps{\xeCJKsetup{PunctStyle=plain}} + \appto\meta@font@select{\ifinner\ctexdisableecglue\fi} +\else + \let\ctexdocverbaddon\relax + \let\ctexplainps\relax + \def\ctexdisableecglue{\ltjsetparameter{autoxspacing=false}} + \appto\meta@font@select{\ctexdisableecglue} +\fi +\setlist{noitemsep,topsep=\smallskipamount} +\setlist[1]{labelindent=\parindent} +\setlist[enumerate]{leftmargin=*} +\setlist[itemize]{leftmargin=*} +\newlist{optdesc}{description}{3} +%% 设置间距为 \marginparsep,与 l3doc 一致 +\setlist[optdesc]{% + font=\mdseries\small\ttfamily,align=right,listparindent=\parindent, + labelsep=\marginparsep,labelindent=-\marginparsep,leftmargin=*} +%% 重新定义 threeparttable 包的 tablenotes 环境 +\renewlist{tablenotes}{description}{1} +\setlist[tablenotes]{% + format=\normalfont\tnote@item,align=right,listparindent=\parindent, + labelindent=\tabcolsep,leftmargin=*,rightmargin=\tabcolsep, + after=\@noparlisttrue} +\AtBeginEnvironment{tablenotes}{% + \setlength\parindent{2\ccwd}% + \normalfont\footnotesize} +\AtBeginEnvironment{threeparttable}{% + \stepcounter{tpt@id}% + \edef\curr@tpt@id{tpt@\arabic{tpt@id}}} +\newcounter{tpt@id} +\def\tnote@item#1{% + \Hy@raisedlink{\hyper@anchor{\curr@tpt@id-#1}}#1} +\def\TPTtagStyle#1{\hyperlink{\curr@tpt@id-#1}{#1}} +\fvset{ + fontsize=\small,baselinestretch=1,numbersep=5pt, + formatcom=\ctexdocverbaddon, + listparameters=\setlength\topsep{\MacrocodeTopsep}} +\DefineVerbatimEnvironment{frameverb}{Verbatim}{% + gobble=4, + frame=single,framesep=8pt, + listparameters= + \setlength\topsep{\medskipamount}% + \appto\FV@EndList{\nointerlineskip}} +\DefineVerbatimEnvironment{ctexexam}{Verbatim}{% + gobble=4, + frame=single,framesep=10pt, + label=\rule{0pt}{12pt}\textnormal{\bfseries 例 \arabic{ctexexam}}, + listparameters= + \setlength\topsep{\bigskipamount}% + \refstepcounter{ctexexam}\ctexexamlabelref + \appto\FV@EndList{\nointerlineskip}} +\define@key{FV}{labelref}{\def\ctexexamlabelref{\label{#1}}} +\let\ctexexamlabelref\empty +\newcounter{ctexexam} +\BeforeBeginEnvironment{function}{\par\nointerlineskip} +\AtEndEnvironment{function}{% + \par\xdef\ctexfixprevdepth{\prevdepth=\the\prevdepth\space}} +\AfterEndEnvironment{function}{\ctexfixprevdepth} +\AtBeginEnvironment{syntax}{\linespread{1}\ctexplainps\ctexdisableecglue} +\BeforeBeginEnvironment{SideBySideExample}{\par\addvspace{\medskipamount}} +\newcommand*\exptarget{\Hy@raisedlink{\hypertarget{expstar}{}}} +\newcommand*\rexptarget{\Hy@raisedlink{\hypertarget{rexpstar}{}}} +\newcommand*\expstar{\hyperlink{expstar}{$\star$}} +\newcommand*\rexpstar{\hyperlink{rexpstar}{\ding{73}}} +\ExplSyntaxOn +%% l3doc 会设置列表环境中 \listparindent=\z@,我们在这里恢复它。 +\cs_set_eq:NN \list \__codedoc_oldlist:nn +\cs_new_nopar:Npn \zihaopt #1 + { + \exp_last_unbraced:Nf \tl_head:w + { \prop_item:Nn \c__ctex_font_size_prop {#1} } { } \q_stop + } +%% 抑制首段的 \parskip +\ctex_patch_cmd_once:NnnnTF \__codedoc_function_descr_start:w + { } + { \noindent } + { \skip_vertical:n { -\parskip } \noindent } + { \iow_term:n { *** ~ SUCCESS ~ *** } } + { \iow_term:n { *** ~ FAIL ~ *** } } +%% l3doc 会在 function 环境的 syntax 和 descr 盒子中间加上 \medskipamount 的距离。 +%% 但是若 syntax 盒子为空(未使用 syntax 环境),就会显得不好看。 +%% 此时我们通过将 \medskipamount 设置为零来修正。若盒子非空,则将 \parskip 还回去。 +\ctex_preto_cmd:NnnTF \__codedoc_function_assemble: + { } + { \ctex_doc_fix_yoffset: } + { \iow_term:n { *** ~ SUCCESS ~ *** } } + { \iow_term:n { *** ~ FAIL ~ *** } } +\cs_new_protected_nopar:Npn \ctex_doc_fix_yoffset: + { + \box_if_empty:NTF \g__codedoc_syntax_box + { \skip_zero:N \medskipamount } + { \skip_add:Nn \medskipamount { \parskip } } + } +%% 左侧边注的函数列表采用单倍行距 +\ctex_preto_cmd:NnnTF \__codedoc_typeset_functions: + { } + { \MacroFont } + { \iow_term:n { *** ~ SUCCESS ~ *** } } + { \iow_term:n { *** ~ FAIL ~ *** } } +\ctex_patch_cmd_once:NnnnTF \__codedoc_macro_init: + { } + { \hbox:n } + { \MacroFont \hbox:n } + { \iow_term:n { *** ~ SUCCESS ~ *** } } + { \iow_term:n { *** ~ FAIL ~ *** } } +\ctex_patch_cmd_once:NnnnTF \__codedoc_macro_dump: + { } + { \hbox_unpack_drop:N } + { \MacroFont \hbox_unpack_drop:N } + { \iow_term:n { *** ~ SUCCESS ~ *** } } + { \iow_term:n { *** ~ FAIL ~ *** } } +\cs_set_eq:NN \__codedoc_macro_end_style:n \use_none:n +\cs_set_protected:Npn \__codedoc_macro_typeset_one:nN #1#2 + { + \vbox_set:Nn \l__codedoc_macro_box + { + \MacroFont + \vbox_unpack_drop:N \l__codedoc_macro_box + \hbox_set:Nn \l_tmpa_box + { \__codedoc_print_macroname:nN {#1} #2 } + \dim_set:Nn \l_tmpa_dim { \marginparwidth - \labelsep } + \dim_compare:nNnT { \box_wd:N \l_tmpa_box } > \l_tmpa_dim + { + \box_resize_to_wd_and_ht:Nnn \l_tmpa_box + { \l_tmpa_dim } + { \box_ht:N \l_tmpa_box } + } + \hbox_overlap_left:n + { + \box_use:N \l_tmpa_box + \skip_horizontal:n { \marginparsep - \labelsep } + } + } + \int_incr:N \l__codedoc_macro_int + } +\cs_set_protected:Npn \__codedoc_print_macroname:nN #1#2 + { + \strut + \__codedoc_get_hyper_target:xN + { + \exp_not:n {#1} + \bool_if:NT #2 { \tl_to_str:n {TF} } + } + \l__codedoc_tmpa_tl + \cs_if_exist:cTF { r@ \l__codedoc_tmpa_tl } + { \exp_args:NNo \label@hyperref [ \l__codedoc_tmpa_tl ] } + { \use:n } + { + \tl_set:Nn \l__codedoc_tmpa_tl {#1} + \tl_replace_all:Non \l__codedoc_tmpa_tl + { \c_catcode_other_space_tl } + { \fontspec_visible_space: } + \__codedoc_macroname_prefix:o \l__codedoc_tmpa_tl + \__codedoc_macroname_suffix:N #2 + } + } +\AtBeginEnvironment { syntax } + { + \char_set_catcode_active:N \| + \char_set_active_eq:NN \| \orbar + \char_set_catcode_active:N \( + \char_set_active_eq:NN \( \defaultvalaux + } +%% 不对目录中出现的 \cs 和 \tn 等编索引 +\DeclareDocumentCommand \StopSpecialIndexModule { } + { \cs_set_eq:NN \__codedoc_special_index_module:nnnnN \use_none:nnnnn } +\tl_map_inline:nn { \actualchar \encapchar \levelchar } + { \exp_args:Nx \DoNotIndex { \bslash \tl_to_str:N #1 } } +\DeclareDocumentCommand \package { o m } + { + \exp_args:Nx \href + { + http \c_colon_str //www.ctan.org/pkg/ + \IfNoValueTF {#1} { \str_fold_case:n {#2} } {#1} + } + { \pkg {#2} } + } +\DeclareDocumentCommand \GetFileId { m } + { + \GetFileInfo {#1} + \file_get:nnNTF { \c_sys_jobname_str .id } + { \int_set:Nn \tex_endlinechar:D { -1 } } \l_@@_tmp_tl + { \exp_after:wN \GetIdInfo \l_@@_tmp_tl } + { \GetIdInfo $Id$ } + { \fileinfo } + } +\cs_new_eq:NN \@@_ltx_changes:nnn \changes@ +\cs_set_protected:Npn \changes@ #1#2 + { + \@@_save_version_date:nn {#1} {#2} + \tl_if_empty:nTF {#1} + { \@@_ltx_changes:nnn } + { \@@_version_zfill:wnnn #1 \q_stop } + {#1} {#2} + } +\cs_new_protected:Npn \@@_version_zfill:wnnn #1#2 \q_stop + { + \str_if_eq:nnTF {#1} { v } + { \@@_version_zfill:nnnn {#2} } + { \@@_ltx_changes:nnn } + } +\cs_new_protected:Npn \@@_version_zfill:nnnn #1#2 + { + \tl_clear:N \l_@@_tmp_tl + \int_zero:N \l_tmpa_int + \seq_set_split:Nnn \l_tmpa_seq { . } {#1} + \seq_map_function:NN \l_tmpa_seq \@@_version_zfill:n + \int_compare:nNnF \l_tmpa_int > 2 + { + \tl_put_right:Nx \l_@@_tmp_tl + { \prg_replicate:nn { 3 - \l_tmpa_int } { 00000 } } + } + \@@_ltx_changes:nnn { \l_@@_tmp_tl \actualchar #2 } + } +\tl_new:N \l_@@_tmp_tl +\cs_new_protected:Npn \@@_version_zfill:n #1 + { + \int_incr:N \l_tmpa_int + \tl_put_right:Nx \l_@@_tmp_tl + { + \prg_replicate:nn + { \int_max:nn { 0 } { 5 - \tl_count:n {#1} } } { 0 } + \exp_not:n {#1} + } + } +\cs_new_protected:Npn \@@_save_version_date:nn #1#2 + { + \prop_get:NnNTF \g_@@_version_date_prop {#1} \l_@@_tmp_tl + { \exp_after:wN \@@_save_version_date:nnnn \l_@@_tmp_tl {#2} {#1} } + { \@@_save_version_date:nnn {#1} {#2} {#2} } + } +\cs_new_protected:Npn \@@_save_version_date:nnnn #1#2#3#4 + { + \@@_if_date_later:nnTF {#1} {#3} + { \@@_save_version_date:nnn {#4} {#3} {#2} } + { + \@@_if_date_later:nnT {#3} {#2} + { \@@_save_version_date:nnn {#4} {#1} {#3} } + } + } +\prg_new_conditional:Npnn \@@_if_date_later:nn #1#2 { TF , T } + { + \if_int_compare:w \@@_parse_date:w #1 / / / 0 \q_stop > + \@@_parse_date:w #2 / / / 0 \q_stop \exp_stop_f: + \prg_return_true: \else: \prg_return_false: \fi: + } +\cs_new:Npn \@@_parse_date:w #1/#2/#3/ #4 \q_stop + { #1#2#3 } +\cs_new_protected:Npn \@@_save_version_date:nnn #1#2#3 + { \prop_gput:Nnn \g_@@_version_date_prop {#1} { {#2} {#3} } } +\cs_new_protected:Npn \CTEX@versionitem #1 \efill + { + \@idxitem + \prop_get:NnNTF \g_@@_version_date_prop {#1} \l_@@_tmp_tl + { \exp_after:wN \@@_version_item:nnn \l_@@_tmp_tl {#1} } + { \BOOM } + } +\cs_new_protected:Npn \@@_version_item:nnn #1#2#3 + { + \noindent + \Hy@raisedlink { \belowpdfbookmark {#3} { HD.#3 } } + \textbf {#3} \hfill + \hbox:n + { + \footnotesize + \str_if_eq:nnTF {#1} {#2} + { ( #1 ) } + { ( #1 ~ -- ~ #2 ) } + } + \par \nopagebreak + } +\prop_new:N \g_@@_version_date_prop +\ctex_patch_cmd:Nnn \HDorg@theglossary + { \let \item \@idxitem } + { \let \item \CTEX@versionitem } +\ctex_patch_cmd:Nnn \l@section { 2.5em } { 1.5em } +\ctex_patch_cmd:Nnn \l@subsection { 2.5em } { 1.5em } +\ctex_patch_cmd:Nnn \@wrglossary + { hdpindex } + { + \ifnum \c@HD@hypercount = \z@ + hdpindex + \else + hdclindex { \the \c@HD@hypercount } + \fi + } +%% 重定义 macrocode 环境的实现,逐行处理 +\cs_set_protected_nopar:Npn \xmacro@code + { \@@_marco_code:w } +\cs_set_protected_nopar:Npn \sxmacro@code + { + \fontspec_print_visible_spaces: + \xmacro@code + } +\cs_new_protected_nopar:Npn \@@_marco_code:w + { + \ifcodeline@index + \@@_marco_every_par:n { \@@_code_line_no: } + \else: + \@@_marco_every_par:n { } + \fi: + \exp_args:Nx \@@_make_finish_tag:n { \@currenvir } + \@@_verbatim_start:w + } +\cs_new_protected:Npn \@@_marco_every_par:n #1 + { + \everypar + { + \everypar {#1} + \if@inlabel + \global \@inlabelfalse + \@noparlistfalse + \llap { \box \@labels \hskip \leftskip } + \fi + #1 + } + } +\ctex_patch_cmd:Nnn \macro@code + { \if@inlabel \leavevmode \fi } + { \partopsep \z@skip } +\group_begin: + \int_set:Nn \tex_endlinechar:D { -1 } + \use:n + { + \char_set_catcode_active:n { 32 } + \tl_const:Nn \c_@@_active_space_tl + } + { } +\group_end: +\group_begin: + \char_set_catcode_active:n { 13 } + \cs_new_protected:Npx \@@_make_finish_tag:n #1 + { + \tl_set:Nn \exp_not:N \l_@@_verbatim_finish_tl + { + \c_percent_str + \prg_replicate:nn { 4 } + { \exp_not:o { \c_@@_active_space_tl } } + \exp_not:o { \active@escape@char } end + \c_left_brace_str #1 \c_right_brace_str + \exp_not:N ^^M + } + } + \cs_new_protected:Npn \@@_verbatim_start:w #1 + { + \str_if_eq:nnTF {#1} { ^^M } + { \@@_verbatim_read_line:w } + { \@@_verbatim_read_line:w #1 } + } + \cs_new_protected:Npn \@@_verbatim_read_line:w #1 ^^M + { + \tl_set:Nn \l_@@_verbatim_line_tl { #1 ^^M } + \tl_if_eq:NNTF \l_@@_verbatim_line_tl \l_@@_verbatim_finish_tl + { \exp_args:Nx \end { \@currenvir } } + { + \@@_verbatim_process_line: + \@@_verbatim_read_line:w + } + } + \cs_new_protected:Npn \@@_swap_cr: + { \exp_after:wN \@@_swap_cr:w \l_@@_verbatim_line_tl } + \cs_new_protected:Npn \@@_swap_cr:w #1 ^^M + { + \group_insert_after:N ^^M + \tl_set:Nn \l_@@_verbatim_line_tl {#1} + } + \tl_const:Nn \c_@@_active_cr_tl { ^^M } +\group_end: +\tl_new:N \l_@@_verbatim_line_tl +\tl_new:N \l_@@_verbatim_finish_tl +\tl_new:N \g_@@_verbatim_verb_stop_tl +\cs_new_protected_nopar:Npn \@@_process_normal_line: + { + \str_if_eq:eeTF + { \str_head:N \l_@@_verbatim_line_tl } { \c_percent_str } + { \@@_check_angle:x { \tl_tail:N \l_@@_verbatim_line_tl } } + { \@@_output_line: } + } +\cs_new_protected_nopar:Npn \@@_process_verb_line: + { + \tl_if_eq:NNTF \l_@@_verbatim_line_tl \g_@@_verbatim_verb_stop_tl + { + \tl_gclear:N \g_@@_verbatim_verb_stop_tl + \cs_gset_eq:NN \@@_verbatim_process_line: \@@_process_normal_line: + \@@_output_module:nn + { \color { verb@guard } } + { + \@@_swap_cr: + \@@_module_pop:n { \l_@@_verbatim_line_tl } + } + } + { \tl_use:N \l_@@_verbatim_line_tl } + } +\cs_new_eq:NN \@@_verbatim_process_line: \@@_process_normal_line: +\DeclareDocumentCommand \CheckModules { } + { \cs_set_eq:NN \@@_verbatim_process_line: \@@_process_normal_line: } +\DeclareDocumentCommand \DontCheckModules { } + { \cs_set_eq:NN \@@_verbatim_process_line: \@@_output_line: } +\cs_new_protected:Npn \@@_check_angle:n #1 + { + \str_if_eq:eeTF { \str_head:n {#1} } { < } + { \@@_check_module:x { \tl_tail:n {#1} } } + { \@@_output_percent_line: } + } +\cs_generate_variant:Nn \@@_check_angle:n { x } +\cs_new_protected:Npn \@@_check_module:n #1 + { + \exp_args:Nx \str_case:nnF { \str_head:n {#1} } + { + { * } { \@@_module_star:w } + { / } { \@@_module_slash:w } + { @ } { \@@_module_at:w } + { < } { \@@_module_verb:w } + } + { \@@_module_pm:w } + #1 \q_stop + } +\cs_generate_variant:Nn \@@_check_module:n { x } +\group_begin: + \char_set_catcode_active:N \> + \cs_new_protected:Npn \@@_module_star:w #1 > #2 \q_stop + { + \@@_output_module:nn + { \@@_star_color: } + { \@@_module_push:n { \@@_module_angle:n {#1} } } + \@@_output_line:n {#2} + \@@_star_format: + } + \cs_new_protected:Npn \@@_module_slash:w #1 > #2 \q_stop + { + \@@_output_module:nn + { \@@_slash_color: } + { \@@_module_pop:n { \@@_module_angle:n {#1} } } + \@@_output_line:n {#2} + \@@_slash_format: + } + \cs_new_protected:Npn \@@_module_at:w @ @ = #1 > #2 \q_stop + { + \@@_output_module:nn + { \color { at@guard } } + { \@@_module_angle:n { @ @ = #1 } } + \tl_gset:Nn \g__codedoc_module_name_tl {#1} + \@@_output_line:n {#2} + } + \cs_new_protected:Npn \@@_module_pm:w #1 > #2 \q_stop + { + \tex_noindent:D + \hbox_overlap_left:n + { + \@@_output_module:nn + { \@@_pm_color: } + { \@@_module_angle:n {#1} } + \skip_horizontal:n { \leftskip + \smallskipamount } + } + \group_begin: + \@@_pm_format: + \@@_output_line:n {#2} + \group_end: + } + \cs_new_protected:Npn \@@_module_verb:w #1 \q_stop + { + \cs_gset_eq:NN \@@_verbatim_process_line: \@@_process_verb_line: + \tl_gset:Nx \g_@@_verbatim_verb_stop_tl + { \c_percent_str \tl_tail:n {#1} } + \@@_output_module:nn + { \color { verb@guard } } + { + \@@_swap_cr: + \@@_module_push:n { \l_@@_verbatim_line_tl } + } + } +\group_end: +\cs_new_protected_nopar:Npn \@@_output_line: + { + \tex_noindent:D + \@@_replace_at_at:N \l_@@_verbatim_line_tl + \tl_use:N \l_@@_verbatim_line_tl + } +\cs_new_protected:Npn \@@_replace_at_at:N #1 + { + \tl_if_empty:NF \g__codedoc_module_name_tl + { + \exp_args:NNo \@@_replace_at_at_aux:Nn + #1 \g__codedoc_module_name_tl + } + } +\cs_new_protected:Npn \@@_replace_at_at_aux:Nn #1#2 + { + \tl_replace_all:Nnn #1 { _ @ @ } { _ _ #2 } + \tl_replace_all:Nnn #1 { @ @ } { _ _ #2 } + } +\cs_new_protected:Npn \@@_output_line:n #1 + { + \tl_set:Nn \l_@@_verbatim_line_tl {#1} + \tl_if_eq:NNTF \l_@@_verbatim_line_tl \c_@@_active_cr_tl + { \tl_use:N \l_@@_verbatim_line_tl } + { + \str_if_eq:eeTF + { \str_head:N \l_@@_verbatim_line_tl } + { \c_percent_str } + { \@@_output_percent_line: } + { \@@_output_line: } + } + } +\cs_new_protected:Npn \@@_output_percent_line: + { + \tex_noindent:D + \group_begin: + \color { code@gray } + \@@_swap_cr: + \str_if_eq:eeTF { \f@shape } { \updefault } + { \slshape } + { \upshape } + \@@_output_line: + \group_end: + } +\cs_new_protected_nopar:Npn \@@_module_push:n + { \exp_args:No \@@_module_push_aux:nn { \int_use:N \c@HD@hypercount } } +\cs_new_protected:Npn \@@_module_push_aux:nn #1 + { + \seq_gpush:Nn \g_@@_module_dest_seq {#1} + \hypersetup { hidelinks } + \exp_args:Nx \hdclindex + { \zref@extractdefault { HD.#1 } { guard@end } { 1 } } { } + } +\cs_new_protected_nopar:Npn \@@_module_pop:n + { + \seq_gpop:NNTF \g_@@_module_dest_seq \l_@@_tmp_tl + { \exp_args:No \@@_module_pop_aux:nn { \l_@@_tmp_tl } } + { \BOOM \use:n } + } +\cs_new_protected:Npn \@@_module_pop_aux:nn #1 + { + \zref@labelbylist { HD.#1 } { ctxdoc } + \hypersetup { hidelinks } + \hdclindex {#1} { } + } +\seq_new:N \g_@@_module_dest_seq +\zref@newlist { ctxdoc } +\zref@newprop { guard@end } [ 1 ] + { \int_eval:n { \c@HD@hypercount - 1 } } +\zref@addprop { ctxdoc } { guard@end } +\cs_new_protected_nopar:Npn \@@_star_format: + { + \seq_gpush:No \g_@@_slash_format_seq { \macro@font } + \seq_gpop:NNF \g_@@_star_format_seq \l_@@_format_tl + { \@@_pop_format: } + \@@_select_format: + } +\cs_new_protected_nopar:Npn \@@_slash_format: + { + \seq_gpop:NNTF \g_@@_slash_format_seq \l_@@_format_tl + { + \seq_gpush:No \g_@@_star_format_seq { \macro@font } + \@@_select_format: + } + { \BOOM } + } +\cs_new_protected_nopar:Npn \@@_pm_format: + { + \seq_get:NNF \g_@@_star_format_seq \l_@@_format_tl + { + \@@_pop_format: + \seq_gpush:No \g_@@_star_format_seq { \l_@@_format_tl } + } + \cs_if_eq:NNF \macro@font \l_@@_format_tl + { \l_@@_format_tl } + } +\cs_new_protected_nopar:Npn \@@_pop_format: + { + \seq_gpop_left:NN \g_@@_format_seq \l_@@_format_tl + \seq_gput_right:No \g_@@_format_seq { \l_@@_format_tl } + } +\cs_new_protected_nopar:Npn \@@_select_format: + { + \cs_if_eq:NNF \macro@font \l_@@_format_tl + { + \cs_gset_eq:NN \macro@font \l_@@_format_tl + \macro@font + } + } +\tl_new:N \l_@@_format_tl +\seq_new:N \g_@@_format_seq +\seq_new:N \g_@@_star_format_seq +\seq_new:N \g_@@_slash_format_seq +\seq_gput_right:Nn \g_@@_format_seq { \MacroFont } +\seq_gput_right:Nn \g_@@_format_seq { \AltMacroFont } +\cs_set_protected:Npn \MacroFont + { + \linespread { 1 } + \small + \fontseries { \mddefault } + \fontshape { \updefault } + \ttfamily + \ctexdocverbaddon + } +\cs_set_protected:Npn \AltMacroFont + { + \linespread { 1 } + \small + \fontseries { \mddefault } + \fontshape { \sldefault } + \ttfamily + \ctexdocverbaddon + } +\AtBeginDocument + { + \tl_gset:Nx \macro@font + { \seq_item:Nn \g_@@_format_seq { 1 } } + } +\cs_new_protected:Npn \@@_output_module:nn #1#2 + { + \tex_noindent:D + \group_begin: + #1 + \footnotesize \normalfont \sffamily #2 + \group_end: + } +\cs_new_protected_nopar:Npn \@@_star_color: + { + \seq_gpop:NNTF \g_@@_star_color_seq \current@color + { \set@color } + { \@@_select_color: } + \seq_gpush:No \g_@@_slash_color_seq { \current@color } + } +\cs_new_protected_nopar:Npn \@@_slash_color: + { + \seq_gpop:NNTF \g_@@_slash_color_seq \current@color + { + \set@color + \seq_gpush:No \g_@@_star_color_seq { \current@color } + } + { \BOOM } + } +\cs_new_protected_nopar:Npn \@@_pm_color: + { + \seq_get:NNTF \g_@@_star_color_seq \current@color + { \set@color } + { + \@@_select_color: + \seq_gpush:No \g_@@_star_color_seq { \current@color } + } + } +\seq_new:N \g_@@_star_color_seq +\seq_new:N \g_@@_slash_color_seq +\cs_new_protected_nopar:Npn \@@_select_color: + { \color { guard@series!!+ } } +\definecolorseries { guard@series } + { cmyk } { last } { blue } { purple } +\resetcolorseries [ 3 ] { guard@series } +\definecolor { verb@guard } { rgb } { 0.5 , 0.5 , 0 } +\definecolor { at@guard } { rgb } { 0.5 , 0 , 0.5 } +\definecolor { code@gray } { gray } { 0.5 } +\cs_new_protected:Npn \@@_module_angle:n #1 + { \textlangle #1 \textrangle } +\cs_new_protected_nopar:Npn \@@_code_line_no: + { + \int_gincr:N \c@CodelineNo + \hbox_overlap_left:n + { + \hbox_to_wd:nn + { \MacroIndent } + { + \HD@target + \tex_hss:D + \@@_code_line_no_style: + \theCodelineNo \enspace + } + \tex_kern:D \@totalleftmargin + } + } +\tl_set:Nn \theCodelineNo + { \arabic { CodelineNo } } +\cs_new_protected_nopar:Npn \@@_code_line_no_style: + { \color { code@gray } \normalfont \sffamily \tiny } +\cs_set_protected:Npn \HD@SetMacroIndent #1 + { + \group_begin: + \settowidth \MacroIndent + { + \@@_code_line_no_style: + \prg_replicate:nn { \tl_count:n {#1} } { 0 } + \enspace + } + \dim_gset_eq:NN \MacroIndent \MacroIndent + \group_end: + } +\ExplSyntaxOff +\AtBeginDocument{\addtocontents{toc}{\StopSpecialIndexModule}} +\pdfstringdefDisableCommands{% + \let\path\meta + \let\opt\@firstofone} +\preto\@thehead{\cslet{MakeUppercase\space}{\@iden}} +\def\orbar{\textup{\textbar}} +\def\defaultval#1{\textbf{\textup{#1}}} +\def\defaultvalaux#1){\defaultval{#1}} +\def\TF{true\orbar false} +\def\TTF{\defaultval{true}\orbar false} +\def\TFF{true\orbar\defaultval{false}} +\protected\def\opt{\texttt} +\def\pdfTeX{\hologo{pdfTeX}} +\def\XeTeX{\hologo{XeTeX}} +\def\XeLaTeX{\hologo{XeLaTeX}} +\def\LuaLaTeX{\hologo{LuaLaTeX}} +\def\pdfLaTeX{\hologo{pdfLaTeX}} +\def\LaTeX{\hologo{LaTeX}} +\def\LaTeXe{\hologo{LaTeX2e}} +\def\LaTeXiii{\hologo{LaTeX3}} +\def\dvipdfmx{DVIPDFM\textit{x}} +\def\TeX{\hologo{TeX}} +\def\ApTeX{Ap\TeX} +\def\ApLaTeX{Ap\LaTeX} +\def\upTeX{up\TeX} +\def\upLaTeX{up\LaTeX} +\def\bashcmd{\texttt} +\def\TeXLive{\TeX\ Live} +\def\MiKTeX{\hologo{MiKTeX}} +\def\BSTACK{\begin{tabular}[t]{@{}l@{}}} +\def\ESTACK{\end{tabular}} +\newenvironment{defaultcapconfig}{% + \MakePercentComment + \input{ctex-name-utf8.cfg}% + \ExplSyntaxOff + \MakePercentIgnore}{} +\def\ctexkit{\href{https://github.com/CTeX-org/ctex-kit/}{\texttt{ctex-kit}}} +\def\ctexkitrev#1{% + \href{https://github.com/CTeX-org/ctex-kit/commit/#1}{\texttt{ctex-kit} rev. #1}} +\appto\GlossaryParms{% + \raggedcolumns + \let\Hy@writebookmark\HDorg@writebookmark + \def\@idxitem{\par\hangindent 2em }% + \def\subitem{\@idxitem\hspace*{1em}}% + \def\subsubitem{\@idxitem\hspace*{2em}}} +\def\glossaryname{版本历史} +\GlossaryPrologue{\section{\glossaryname}} +\IndexPrologue{% + \section{\indexname} + \textit{意大利体的数字表示描述对应索引项的页码; + 带下划线的数字表示定义对应索引项的代码行号; + 罗马字体的数字表示使用对应索引项的代码行号。}} +\def\IndexLayout{% + \newgeometry{hmargin=15mm,vmargin={25mm,15mm},footskip=7mm}% + \setlength\IndexMin{.5\textheight}% + \ctexset{section/numbering=false}% + \StopSpecialIndexModule} +\EnableCrossrefs +\CodelineIndex +\RecordChanges +% \end{macrocode} +% +% \begin{macrocode} +%</ctxdoc> +% \end{macrocode} +% +% \subsection{\pkg{ctxdocstrip}} +% +% \begin{macrocode} +%<*docstrip> +\csname ctxdocstriploaded\endcsname +\let\ctxdocstriploaded\endinput +\input l3docstrip % +\edef\ctxresetcatcode{% + \catcode\number`\$=\the\catcode`\$\relax} +\makeOther\$ +\def\plusOption+#1>#2$#3$\endLine{% + \maybeMsg{<+#1 . >}% + \Evaluate{#1}% + \def\ctxCMD{#2}% + \def\ctxID{$#3$}% + \def\do##1##2##3{% + \if1\Expr{##2}% + \readIDFile + \StreamPut##1{\inLine}% + \fi + }% + \activefiles +} +\def\readIDFile{% + \openin\inputcheck=\jobname.id\relax + \ifeof\inputcheck\else + \read \inputcheck to \inLine + \closein\inputcheck + \ifx\inLine\empty\else + \let\ctxID\inLine + \fi + \fi + \maybeMsg{^^J\ctxID^^J}% + \def\inLine{\ctxCMD\ctxID}% +} +\keepsilent +\askforoverwritefalse +\declarepreamble\emptypreamble +\endpreamble +\declarepostamble\emptypostamble +\endpostamble +\ctxresetcatcode +%</docstrip> +% \end{macrocode} +% +% \end{implementation} +% +\endinput |