目录

用Omega、Aleph排版CJK

documentclass选项

新建一个文件,文件名为docoptions.clo,我们将在这个文件里定义文档类的选项, 诸如纸张大小、字体大小、竖排开关等。文件的初始内容如下:

\ProvidesFile{docoptions.clo}[2015/04/01 cjk file (size option)]
\newcommand\@ptsize{}
\newif\if@restonecol
\newif\if@titlepage
\newif\if@openright
\newif\if@mainmatter
\if@compatibility
\else
\DeclareOption{a0paper}{\setlength\paperheight {1189mm} \setlength\paperwidth {841mm}}
\DeclareOption{a1paper}{\setlength\paperheight {841mm} \setlength\paperwidth {594mm}}
\DeclareOption{a2paper}{\setlength\paperheight {594mm} \setlength\paperwidth {420mm}}
\DeclareOption{a3paper}{\setlength\paperheight {420mm} \setlength\paperwidth {297mm}}
\DeclareOption{a4paper}{\setlength\paperheight {297mm} \setlength\paperwidth {210mm}}
\DeclareOption{landscape}{\setlength\@tempdima {\paperheight} \setlength\paperheight {\paperwidth}\setlength\paperwidth {\@tempdima}}
\fi
%
\if@compatibility
\renewcommand\@ptsize{0}
\else
\DeclareOption{10pt}{\renewcommand\@ptsize{0}\input{size1\@ptsize.clo}}
\fi
\DeclareOption{11pt}{\renewcommand\@ptsize{1}\input{size1\@ptsize.clo}}
\DeclareOption{12pt}{\renewcommand\@ptsize{2}\input{size1\@ptsize.clo}}
%
\if@compatibility\else
\DeclareOption{oneside}{\@twosidefalse \@mparswitchfalse}
\fi
\DeclareOption{twoside}{\@twosidetrue \@mparswitchtrue}
%
\DeclareOption{draft}{\setlength\overfullrule{5pt}}
\if@compatibility\else
\DeclareOption{final}{\setlength\overfullrule{0pt}}
\fi
%
\DeclareOption{titlepage}{\@titlepagetrue}
\if@compatibility\else
\DeclareOption{notitlepage}{\@titlepagefalse}
\fi
%
\if@compatibility\else
\DeclareOption{onecolumn}{\@twocolumnfalse}
\fi
\DeclareOption{twocolumn}{\@twocolumntrue}
%
\DeclareOption{leqno}{\input{leqno.clo}}
\DeclareOption{fleqn}{\input{fleqn.clo}}
\DeclareOption{openbib}{%
\AtEndOfPackage{%
\renewcommand\@openbib@code{%
\advance\leftmargin\bibindent
\itemindent -\bibindent
\listparindent \itemindent
\parsep \z@
}%
\renewcommand\newblock{\par}}%
}
%
\if@compatibility
\@openrighttrue
\else
\DeclareOption{openright}{\@openrighttrue}
\DeclareOption{openany}{\@openrightfalse}
\fi
\endinput

为竖排做好准备

在docoptions.clo文件中加入两个开关项

\newif\if@verticaltypeset
\@verticaltypesetfalse
\newif\if@nopunct
\@nopunctfalse
这是横排和竖排的切换开关。我们在录入文档时输入的标点符号是横排符号,在竖排时应该自动转为 竖排标点,甚至没有标点(古代典籍)。另外,横排和竖排的hsize和vsize是不一样的。

新建一个文件,文件名为punctcjk.sty,我们在这里实现标点符号的替换和消除,文件内容如下:

\ProvidesFile{punctcjk.sty}[2015/04/24 cjk punction]
\def\cjkperiod{\if@nopunct\else\if@verticaltypeset ^^^^fe12\else ^^^^3002\fi\fi}
\def\cjkfullstop{\if@nopunct\else\if@verticaltypeset ^^^^ff65\else ^^^^ff0e\fi\fi}
\def\cjkquestionmark{\if@nopunct\else\if@verticaltypeset ^^^^fe16\else ^^^^ff1f\fi\fi}
\def\cjkexclamationmark{\if@nopunct\else\if@verticaltypeset ^^^^fe15\else ^^^^ff01\fi\fi}
\def\cjkcomma{\if@nopunct\else\if@verticaltypeset ^^^^fe10\else ^^^^ff0c\fi\fi}
\def\cjkthecomma{\if@nopunct\else\if@verticaltypeset ^^^^fe11\else ^^^^3001\fi\fi}
\def\cjksemicolon{\if@nopunct\else\if@verticaltypeset ^^^^fe14\else ^^^^ff1b\fi\fi}
\def\cjkcolon{\if@nopunct\else\if@verticaltypeset ^^^^fe13\else ^^^^ff1a\fi\fi}
\def\cjkleftsinglequotation{\if@nopunct\else\if@verticaltypeset ^^^^fe41\else ^^^^2018\fi\fi}
\def\cjkleftcornerbracket{\if@nopunct\else\if@verticaltypeset ^^^^fe41\else ^^^^300c\fi\fi}
\def\cjkrightsinglequotation{\if@nopunct\else\if@verticaltypeset ^^^^fe42\else ^^^^2019\fi\fi}
\def\cjkrightcornerbracket{\if@nopunct\else\if@verticaltypeset ^^^^fe42\else ^^^^300d\fi\fi}
\def\cjkleftdoublequotation{\if@nopunct\else\if@verticaltypeset ^^^^fe43\else ^^^^201c\fi\fi}
\def\cjkleftwhitecornerbracket{\if@nopunct\else\if@verticaltypeset ^^^^fe43\else ^^^^300e\fi\fi}
\def\cjkrightdoublequotation{\if@nopunct\else\if@verticaltypeset ^^^^fe44\else ^^^^201d\fi\fi}
\def\cjkrightwhitecornerbracket{\if@nopunct\else\if@verticaltypeset ^^^^fe44\else ^^^^300f\fi\fi}
\def\cjkleftparenthesis{\if@nopunct\else\if@verticaltypeset ^^^^fe35\else ^^^^ff08\fi\fi}
\def\cjkrightparenthesis{\if@nopunct\else\if@verticaltypeset ^^^^fe36\else ^^^^ff09\fi\fi}
\def\cjkleftsquarebracket{\if@nopunct\else\if@verticaltypeset ^^^^fe47\else ^^^^fe5d\fi\fi}
\def\cjkrightsquarebracket{\if@nopunct\else\if@verticaltypeset ^^^^fe48\else ^^^^fe5e\fi\fi}
\def\cjklefttortoiseshellbracket{\if@nopunct\else\if@verticaltypeset ^^^^fe39\else ^^^^3014\fi\fi}
\def\cjkrighttortoiseshellbracket{\if@nopunct\else\if@verticaltypeset ^^^^fe3a\else ^^^^3015\fi\fi}
\def\cjkleftcurlybracket{\if@nopunct\else\if@verticaltypeset ^^^^fe37\else ^^^^fe5b\fi\fi}
\def\cjkrightcurlybracket{\if@nopunct\else\if@verticaltypeset ^^^^fe38\else ^^^^fe5c\fi\fi}
\def\cjkleftblacklenticularbracket{\if@nopunct\else\if@verticaltypeset ^^^^fe3b\else ^^^^3010\fi\fi}
\def\cjkrightblacklenticularbracket{\if@nopunct\else\if@verticaltypeset ^^^^fe3c\else ^^^^3011\fi\fi}
\def\cjkquotationdash{\if@nopunct\else\if@verticaltypeset ^^^^fe31\else ^^^^2015\fi\fi}
\def\cjkellipsis{\if@nopunct\else\if@verticaltypeset ^^^^fe19\else ^^^^2026\fi\fi}
\def\cjkleftdoubleanglebracket{\if@nopunct\else\if@verticaltypeset ^^^^fe3d\else ^^^^300a\fi\fi}
\def\cjkrightdoubleanglebracket{\if@nopunct\else\if@verticaltypeset ^^^^fe3e\else ^^^^300b\fi\fi}
\def\cjkleftanglebracket{\if@nopunct\else\if@verticaltypeset ^^^^fe3f\else ^^^^3008\fi\fi}
\def\cjkrightanglebracket{\if@nopunct\else\if@verticaltypeset ^^^^fe40\else ^^^^3009\fi\fi}
\def\cjkwave{\if@nopunct\else\if@verticaltypeset ^^^^fe34\else ^^^^fe4b\fi\fi}
\def\cjkleftwhitelenticularbracket{\if@nopunct\else\if@verticaltypeset ^^^^fe17\else ^^^^3016\fi\fi}
\def\cjkrightwhitelenticularbracket{\if@nopunct\else\if@verticaltypeset ^^^^fe18\else ^^^^3017\fi\fi}
\def\cjkhyphenchar{\if@nopunct\else\if@verticaltypeset ^^^^fe32\else ^^^^2013\fi\fi}
\endinput

再新建一个文件punctcjk.otp,文件内容为:

input: 2;
output: 2;

states: PUNCT, NOPUNCT;

aliases:

PERIOD = (
@"3002 | % 句号
@"ff61 |
@"fe12 % 句号竖排
);

FULLSTOP = (
@"ff0e | % 间隔号
@"ff65 % 间隔号竖排
);

QUESTIONMARK = (
@"ff1f | % 问号
@"fe16 % 问号竖排
);

EXCLAMATIONMARK = (
@"ff01 | % 感叹号
@"fe15 % 感叹号竖排
);

COMMA = (
@"ff0c | % 逗号
@"fe10 % 逗号竖排
);

THECOMMA = (
@"3001 | % 顿号
@"fe11 % 顿号竖排
);

SEMICOLON = (
@"ff1b | % 分号
@"fe14 % 分号竖排
);

COLON = (
@"ff1a | % 冒号
@"fe13 % 冒号竖排
);

QUOTATIONDASH = (
@"2015 | % 破折号
@"fe31 % 破折号竖排
);

ELLIPSIS = (
@"2026 | % 省略号
@"fe19 % 省略号竖排
);

WAVE = (
@"fe4b | @"fe4f | % 波浪书名号
@"fe34 % 波浪书名号竖排
);

HYPHENCHAR = (
@"2013 | % 连接号
@"fe32 % 连接号竖排
);

RIGHTSINGLEQUOTATION = (
@"2019 % 右单引号
);

RIGHTCORNERBRACKET = (
@"300d | % 右单角引号
@"fe42 % 右单角引号竖排
);

RIGHTDOUBLEQUOTATION = (
@"201d % 右双引号
);

RIGHTWHITECORNERBRACKET = (
@"300f | % 右双角引号
@"fe44 % 右双角引号竖排
);

RIGHTPARENTHESIS = (
@"ff09 | % 右括号
@"fe36 % 右括号竖排
);

RIGHTSQUAREBRACKET = (
@"fe5e | % 右方括号
@"ff3d | % 全角右方括号
@"fe48 % 右方括号竖排
);

RIGHTTORTOISESHELLBRACKET = (
@"3015 | % 右龟壳号
@"fe3a % 右龟壳号竖排
);

RIGHTCURLYBRACKET = (
@"fe5c | % 右大括号
@"ff5d | % 全角右大括号
@"fe38 % 右大括号竖排
);

RIGHTBLACKLENTICULARBRACKET = (
@"3011 | % 右黑角括号
@"fe3c % 右黑角括号竖排
);

RIGHTDOUBLEANGLEBRACKET = (
@"300b | % 右双书名号
@"fe3e % 右双书名号竖排
);

RIGHTANGLEBRACKET = (
@"3009 | % 右单书名号
@"fe40 % 右单书名号竖排
);

RIGHTWHITELENTICULARBRACKET = (
@"3017 | % 右白角括号
@"fe18 % 右白角括号竖排
);

LEFTSINGLEQUOTATION = (
@"2018 % 左单引号
);

LEFTCORNERBRACKET = (
@"300c | % 左单角引号
@"fe41 % 左单角引号竖排
);

LEFTDOUBLEQUOTATION = (
@"201c % 左双引号
);

LEFTWHITECORNERBRACKET = (
@"300e | % 左双角引号
@"fe43 % 左双角引号竖排
);

LEFTPARENTHESIS = (
@"ff08 | % 左括号
@"fe35 % 左括号竖排
);

LEFTSQUAREBRACKET = (
@"fe5d | % 左方括号
@"ff3b | % 全角左方括号
@"fe47 % 左方括号竖排
);

LEFTTORTOISESHELLBRACKET = (
@"3014 | % 左龟壳号
@"fe39 % 左龟壳号竖排
);

LEFTCURLYBRACKET = (
@"fe5b | % 左大括号
@"ff5b | % 全角左大括号
@"fe37 % 左大括号竖排
);

LEFTBLACKLENTICULARBRACKET = (
@"3010 | % 左黑角括号
@"fe3b % 左黑角括号竖排
);

LEFTDOUBLEANGLEBRACKET = (
@"300a | % 左双书名号
@"fe3d % 左双书名号竖排
);

LEFTANGLEBRACKET = (
@"3008 | % 左单书名号
@"fe3f % 左单书名号竖排
);

LEFTWHITELENTICULARBRACKET = (
@"3016 | % 左白角括号
@"fe17 % 左白角括号竖排
);

NONPUNCT = (
@"0000-@"2012 |
@"2014 |
@"2016 |
@"2017 |
@"201a |
@"201b |
@"201e-@"2025 |
@"2027-@"3000 |
@"3003-@"3007 |
@"3012 |
@"3013 |
@"3018-@"fe0f |
@"fe1a- @"fe30 |
@"fe33 |
@"fe45 |
@"fe46 |
@"fe49 |
@"fe4a |
@"fe4c-@"fe4e |
@"fe50-@"fe5a |
@"fe5f-@"feff |
@"ff00 |
@"ff02-@"ff07 |
@"ff0a |
@"ff0b |
@"ff0d |
@"ff0f-@"ff19 |
@"ff1c-@"ff1e |
@"ff20-@"ff3a |
@"ff3c |
@"ff3e-@"ff5a |
@"ff5c |
@"ff5e-@"ff60 |
@"ff62-@"ff64 |
@"ff66-@"ffff
);

expressions:

{NONPUNCT} => #(\1);
%
% 替换标点符号
%
{PERIOD} => "\cjkperiod ";
{FULLSTOP} => "\cjkfullstop ";
{QUESTIONMARK} => "\cjkquestionmark ";
{EXCLAMATIONMARK} => "\cjkexclamationmark ";
{COMMA} => "\cjkcomma ";
{THECOMMA} => "\cjkthecomma ";
{SEMICOLON} => "\cjksemicolon ";
{COLON} => "\cjkcolon ";
{QUOTATIONDASH} => "\cjkquotationdash ";
{ELLIPSIS} => "\cjkellipsis ";
{WAVE} => "\cjkwave ";
{HYPHENCHAR} => "\cjkhyphenchar ";
{RIGHTSINGLEQUOTATION} => "\cjkrightsinglequotation ";
{RIGHTCORNERBRACKET} => "\cjkrightcornerbracket ";
{RIGHTDOUBLEQUOTATION} => "\cjkrightdoublequotation ";
{RIGHTWHITECORNERBRACKET} => "\cjkrightwhitecornerbracket ";
{RIGHTPARENTHESIS} => "\cjkrightparenthesis ";
{RIGHTSQUAREBRACKET} => "\cjkrightsquarebracket ";
{RIGHTTORTOISESHELLBRACKET} => "\cjkrighttortoiseshellbracket ";
{RIGHTCURLYBRACKET} => "\cjkrightcurlybracket ";
{RIGHTBLACKLENTICULARBRACKET} => "\cjkrightblacklenticularbracket ";
{RIGHTDOUBLEANGLEBRACKET} => "\cjkrightdoubleanglebracket ";
{RIGHTANGLEBRACKET} => "\cjkrightanglebracket ";
{RIGHTWHITELENTICULARBRACKET} => "\cjkrightwhitelenticularbracket ";

{LEFTSINGLEQUOTATION} => "\cjkleftsinglequotation ";
{LEFTCORNERBRACKET} => "\cjkleftcornerbracket ";
{LEFTDOUBLEQUOTATION} => "\cjkleftdoublequotation ";
{LEFTWHITECORNERBRACKET} => "\cjkleftwhitecornerbracket ";
{LEFTPARENTHESIS} => "\cjkleftparenthesis ";
{LEFTSQUAREBRACKET} => "\cjkleftsquarebracket ";
{LEFTTORTOISESHELLBRACKET} => "\cjklefttortoiseshellbracket ";
{LEFTCURLYBRACKET} => "\cjkleftcurlybracket ";
{LEFTBLACKLENTICULARBRACKET} => "\cjkleftblacklenticularbracket ";
{LEFTDOUBLEANGLEBRACKET} => "\cjkleftdoubleanglebracket ";
{LEFTANGLEBRACKET} => "\cjkleftanglebracket ";
{LEFTWHITELENTICULARBRACKET} => "\cjkleftwhitelenticularbracket ";
这个文件需要用otp2ocp程序编译为相应的ocp文件。

用OTP断行

首先消除用户输入的空格,主要是文本文件中的换行符。新建一个文件spacecjk.otp,文件内容为:

input: 2;
output: 2;

states: SPACE, NOSPACE;

aliases:

SPACE = (
@"0009 | @"000a | @"000c | @"000d | @"0020
);

CJK = (
@"1100-@"11ff | % 韩文字母
@"2e80-@"2eff | % 部首补充
@"2f00-@"2fdf | % 康熙部首
@"2ff0-@"2fff | % 汉字结构描述字符
@"3000-@"303f | % 符号和标点符号
@"3040-@"309f | % 日文平假名
@"30a0-@"30ff | % 日文片假名
@"3100-@"312f | % 注音符号
@"3130-@"318f | % 韩文兼容字母
@"3190-@"319f | % 象形字注释标志
@"31a0-@"31bf | % 注音字母扩展
@"3200-@"32ff | % 封闭式 CJK 文字和月份
@"3300-@"33ff | % CJK 兼容
@"3400-@"4dbf | % CJK 统一表意符号扩展 A
@"4e00-@"9faf | % CJK 统一表意符号
@"a000-@"a48f | % 彝文音节
@"a490-@"a4cf | % 彝文字根
@"ac00-@"d7af | % 朝鲜文音节
@"f900-@"faff | % CJK 兼容象形文字
@"fe30-@"fe4f | % CJK 兼容
@"ff00-@"ffef | % 半型及全型形式
@"00b0 | % 度符号
@"2015 | % 破折号H
@"2018 | % 左单引号
@"2019 | % 右单引号
@"201c | % 左双引号
@"201d | % 右双引号
@"2026 | % 省略号
@"2032 | % PRIME
@"2033 % DOUBLE PRIME
);

expressions:
%
% CJK间不留空格
%
{CJK} {SPACE}<1,> {CJK}=> #(\1) <= #(\$);

接着插入glue,并指定断行规则,比如断在左侧标点符号的左边、右侧标点符号的右边, 新建一个文件breakcjk.otp,文件内容为:

input: 2;
output: 2;

states: INSIDE_CJK;

aliases:

SPACE = (
@"0009 | @"000a | @"000c | @"000d | @"0020
);

ASCII = (
@"0021-@"0080
);

CJK = (
@"1100-@"11ff | % 韩文字母
@"2e80-@"2eff | % 部首补充
@"2f00-@"2fdf | % 康熙部首
@"2ff0-@"2fff | % 汉字结构描述字符
@"3000-@"303f | % 符号和标点符号
@"3040-@"309f | % 日文平假名
@"30a0-@"30ff | % 日文片假名
@"3100-@"312f | % 注音符号
@"3130-@"318f | % 韩文兼容字母
@"3190-@"319f | % 象形字注释标志
@"31a0-@"31bf | % 注音字母扩展
@"3200-@"32ff | % 封闭式 CJK 文字和月份
@"3300-@"33ff | % CJK 兼容
@"3400-@"4dbf | % CJK 统一表意符号扩展 A
@"4e00-@"9faf | % CJK 统一表意符号
@"a000-@"a48f | % 彝文音节
@"a490-@"a4cf | % 彝文字根
@"ac00-@"d7af | % 朝鲜文音节
@"f900-@"faff | % CJK 兼容象形文字
@"fe30-@"fe4f | % CJK 兼容
@"ff00-@"ffef | % 半型及全型形式
@"00b0 | % 度符号
@"2015 | % 破折号H
@"2018 | % 左单引号
@"2019 | % 右单引号
@"201c | % 左双引号
@"201d | % 右双引号
@"2026 | % 省略号
@"2032 | % PRIME
@"2033 | % DOUBLE PRIME
@"fe10 | % 逗号竖排
@"fe11 | % 顿号竖排
@"fe12 | % 句号竖排
@"fe13 | % 冒号竖排
@"fe14 | % 分号竖排
@"fe15 | % 感叹号竖排
@"fe16 | % 问号竖排
@"fe17 | % 左白角括号竖排
@"fe18 | % 右白角括号竖排
@"fe19 | % 省略号竖排
@"fe5b | % 左大括号
@"fe5c | % 右大括号
@"fe5d | % 左方括号
@"fe5e % 右方括号
);

STRICTLYFORBIDDENBEFORE = (
@"0021 |
@"0029 |
@"002c |
@"002e |
@"003a |
@"003b |
@"003f |
@"005d |
@"007d |
@"00b0 |
@"3002 | % 句号
@"ff61 |
@"fe12 | % 句号竖排
@"ff0e | % 间隔号
@"ff65 | % 间隔号竖排
@"ff1f | % 问号
@"fe16 | % 问号竖排
@"ff01 | % 感叹号
@"fe15 | % 感叹号竖排
@"ff0c | % 逗号
@"fe10 | % 逗号竖排
@"3001 | % 顿号
@"fe11 | % 顿号竖排
@"ff1b | % 分号
@"fe14 | % 分号竖排
@"ff1a | % 冒号
@"fe13 | % 冒号竖排
@"2015 | % 破折号
@"fe31 | % 破折号竖排
@"2026 | % 省略号
@"fe19 | % 省略号竖排
@"2013 | % 连接号
@"fe32 | % 连接号竖排
@"2019 | % 右单引号
@"300d | % 右单角引号
@"fe42 | % 右单角引号竖排
@"201d | % 右双引号
@"300f | % 右双角引号
@"fe44 | % 右双角引号竖排
@"ff09 | % 右括号
@"fe36 | % 右括号竖排
@"fe5e | % 右方括号
@"ff3d | % 全角右方括号
@"fe48 | % 右方括号竖排
@"3015 | % 右龟壳号
@"fe3a | % 右龟壳号竖排
@"fe5c | % 右大括号
@"ff5d | % 全角右大括号
@"fe38 | % 右大括号竖排
@"3011 | % 右黑角括号
@"fe3c | % 右黑角括号竖排
@"300b | % 右双书名号
@"fe3e | % 右双书名号竖排
@"3009 | % 右单书名号
@"fe40 | % 右单书名号竖排
@"fe4b | @"FE4F | % 波浪书名号
@"fe34 | % 波浪书名号竖排
@"3017 | % 右白角括号
@"fe18 % 右白角括号竖排
);

FORBIDDENBEFORE = (
@"3005 |
@"3041 |
@"3043 |
@"3045 |
@"3047 |
@"3049 |
@"3063 |
@"3083 |
@"3085 |
@"3087 |
@"308e |
@"30a1 |
@"30a3 |
@"30a5 |
@"30a7 |
@"30a9 |
@"30c3 |
@"30e3 |
@"30e5 |
@"30e7 |
@"30ee |
@"30f5 |
@"30f6 |
@"30fc
);

STRICTLYFORBIDDENAFTER = (
@"0028 |
@"005b |
@"007b |
@"2018 | % 左单引号
@"300c | % 左单角引号
@"fe41 | % 左单角引号竖排
@"201c | % 左双引号
@"300e | % 左双角引号
@"fe43 | % 左双角引号竖排
@"ff08 | % 左括号
@"fe35 | % 左括号竖排
@"fe5d | % 左方括号
@"ff3b | % 全角左方括号
@"fe47 | % 左方括号竖排
@"3014 | % 左龟壳号
@"fe39 | % 左龟壳号竖排
@"fe5b | % 左大括号
@"ff5b | % 全角左大括号
@"fe37 | % 左大括号竖排
@"3010 | % 左黑角括号
@"fe3b | % 左黑角括号竖排
@"300a | % 左双书名号
@"fe3d | % 左双书名号竖排
@"3008 | % 左单书名号
@"fe3f | % 左单书名号竖排
@"3016 | % 左白角括号
@"fe17 % 左白角括号竖排
);

SLIGHTLYFORBIDDENAFTER = (
@"00a5 |
@"0024 |
@"0023 |
@"0040 |
@"00a2 |
@"00a3 |
@"00a7 |
@"ffe5 |
@"ff04 |
@"3012 |
@"266f |
@"ff03 |
@"ffe0 |
@"ffe1 |
@"ff20
);

expressions:

{STRICTLYFORBIDDENAFTER} {CJK} => #(\1) "\strictlyforbiddenbreak\interCJKglue " <= #(\2);
{SLIGHTLYFORBIDDENAFTER} {CJK} => #(\1) "\slightlyforbiddenbreak\interCJKglue " <= #(\2);
{CJK} {STRICTLYFORBIDDENBEFORE} => #(\1) "\strictlyforbiddenbreak\interCJKglue " <= #(\2);
{CJK} {FORBIDDENBEFORE} => #(\1) "\forbiddenbreak\interCJKglue " <= #(\2);

{STRICTLYFORBIDDENAFTER} {ASCII} => #(\1) "\strictlyforbiddenbreak\interCJKglue " <= #(\2);
{SLIGHTLYFORBIDDENAFTER} {ASCII} => #(\1) "\slightlyforbiddenbreak\interCJKglue " <= #(\2);
{ASCII} {STRICTLYFORBIDDENBEFORE} => #(\1) "\strictlyforbiddenbreak\interCJKglue " <= #(\2);
{ASCII} {FORBIDDENBEFORE} => #(\1) "\forbiddenbreak\interCJKglue " <= #(\2);

{CJK} {CJK} => #(\1) "\interCJKglue " <= #(\2);
{CJK} {ASCII} => #(\1) "\boundCJKglue\testbreak " <= #(\2);
{ASCII} {CJK} => #(\1) "\boundCJKglue\testbreak " <= #(\2);

定义字号和行距

首先定义字号。新建一个文件zihao.sty,内容如下:

\ProvidesFile{zihao.sty}[2015/03/31 cjk file ]
\def\bahao@pt{4.5}
\def\xiaoqihao@pt{5}
\def\qihao@pt{5.25}
\def\xiaoliuhao@pt{6.5}
\def\liuhao@pt{7.88}
\def\xiaowuhao@pt{9}
\def\wuhao@pt{10.5}
\def\dawuhao@pt{11}
\def\xiaosihao@pt{12}
\def\banxiaosihao@pt{13}
\def\sihao@pt{13.75}
\def\xiaosanhao@pt{15.06}
\def\sanhao@pt{15.75}
\def\xiaoerhao@pt{18}
\def\erhao@pt{21}
\def\xiaoyihao@pt{24}
\def\yihao@pt{27.5}
\def\xiaochuhao@pt{36}
\def\chuhao@pt{42}
\def\tehao@pt{54}
\def\tedahao@pt{63}
\endinput

然后定义行距,如果行距为字号的1.5倍,新建文件hangju15.sty,内容为:

\ProvidesFile{hangju15.sty}[2015/03/31 cjk file ]
\def\bahao@skip{6.75}
\def\xiaoqihao@skip{7.5}
\def\qihao@skip{7.88}
\def\xiaoliuhao@skip{9.75}
\def\liuhao@skip{11.82}
\def\xiaowuhao@skip{13.5}
\def\wuhao@skip{15.75}
\def\dawuhao@skip{16.5}
\def\xiaosihao@skip{18}
\def\banxiaosihao@skip{19.5}
\def\sihao@skip{20.63}
\def\xiaosanhao@skip{22.59}
\def\sanhao@skip{23.63}
\def\xiaoerhao@skip{27}
\def\erhao@skip{31.5}
\def\xiaoyihao@skip{36}
\def\yihao@skip{41.25}
\def\xiaochuhao@skip{54}
\def\chuhao@skip{63}
\def\tehao@skip{81}
\def\tedahao@skip{94.5}
\endinput

接着定义正文所用的字号,如果是五号字,就新建文件wuhao.clo,内容如下(注意竖排时 文本的宽度用纸张高度计算,文本的高度用纸张的宽度计算):

\ProvidesFile{wuhao.clo}[2015/03/28 cjk file (size option)]
\renewcommand\normalsize{%
\@setfontsize\normalsize\wuhao@pt\wuhao@skip
\abovedisplayskip 10.5\p@ \@plus2\p@ \@minus5\p@
\abovedisplayshortskip \z@ \@plus3\p@
\belowdisplayshortskip 6\p@ \@plus3\p@ \@minus3\p@
\belowdisplayskip \abovedisplayskip
\let\@listi\@listI}
\normalsize
\newcommand\small{%
\@setfontsize\small\xiaowuhao@pt\xiaowuhao@skip%
\abovedisplayskip 9\p@ \@plus3\p@ \@minus4\p@
\abovedisplayshortskip \z@ \@plus2\p@
\belowdisplayshortskip 4\p@ \@plus2\p@ \@minus2\p@
\def\@listi{\leftmargin\leftmargini
\topsep 0\p@
\parsep 0\p@
\itemsep \parsep}%
\belowdisplayskip \abovedisplayskip
}
\newcommand\footnotesize{%
\@setfontsize\footnotesize\liuhao@pt\liuhao@skip%
\abovedisplayskip 7.88\p@ \@plus2\p@ \@minus4\p@
\abovedisplayshortskip \z@ \@plus\p@
\belowdisplayshortskip 3\p@ \@plus\p@ \@minus2\p@
\def\@listi{\leftmargin\leftmargini
\topsep 0\p@
\parsep 0\p@
\itemsep \parsep}%
\belowdisplayskip \abovedisplayskip
}
\newcommand\scriptsize{\@setfontsize\scriptsize\liuhao@pt\liuhao@skip}
\newcommand\tiny{\@setfontsize\tiny\qihao@pt\qihao@skip}
\newcommand\large{\@setfontsize\large\xiaosihao@pt\xiaosihao@skip}
\newcommand\Large{\@setfontsize\Large\sihao@pt\sihao@skip}
\newcommand\LARGE{\@setfontsize\LARGE\sanhao@pt\sanhao@skip}
\newcommand\huge{\@setfontsize\huge\xiaoerhao@pt\xiaoerhao@skip}
\newcommand\Huge{\@setfontsize\Huge\xiaoyihao@pt\xiaoyihao@skip}
\setlength\parindent{2em}
\setlength\smallskipamount{3\p@ \@plus 1\p@ \@minus 1\p@}
\setlength\medskipamount{6\p@ \@plus 2\p@ \@minus 2\p@}
\setlength\bigskipamount{12\p@ \@plus 4\p@ \@minus 4\p@}
\setlength\headheight{12\p@}
\setlength\headsep {25\p@}
\setlength\topskip {10.5\p@}
\setlength\footskip{30\p@}
\if@compatibility
\setlength\maxdepth{4\p@}
\else
\setlength\maxdepth{.5\topskip}
\fi
\if@verticaltypeset
\setlength\@tempdima{\paperheight}
\addtolength\@tempdima{-3.5in}
\addtolength\@tempdima{\topskip}
\@tempcnta=\@tempdima
\setlength\@tempdimb{10.5pt}
\@tempcntb=\@tempdimb
\divide\@tempcnta\@tempcntb
\multiply\@tempdimb\@tempcnta
\setlength\textwidth{\@tempdimb}
\setlength\@tempdima{\paperwidth}
\addtolength\@tempdima{-2in}
\divide\@tempdima\baselineskip
\@tempcnta=\@tempdima
\setlength\textheight{\@tempcnta\baselineskip}
\if@twocolumn
\setlength\marginparsep {10.5\p@}
\else
\setlength\marginparsep{10.5\p@}
\fi
\setlength\marginparpush{5\p@}
\if@compatibility
\if@twoside
\setlength\oddsidemargin {44\p@}
\setlength\evensidemargin {82\p@}
\setlength\marginparwidth {102.44\p@}
\else
\setlength\oddsidemargin {63\p@}
\setlength\evensidemargin {63\p@}
\setlength\marginparwidth {86.68\p@}
\fi
\if@twocolumn
\setlength\oddsidemargin {30\p@}
\setlength\evensidemargin {30\p@}
\setlength\marginparwidth {47.28\p@}
\fi
\else
\if@twoside
\setlength\@tempdima {\paperwidth}
\addtolength\@tempdima {-\textheight}
\setlength\oddsidemargin {.4\@tempdima}
\addtolength\oddsidemargin {-1in}
\setlength\marginparwidth {.6\@tempdima}
\addtolength\marginparwidth {-\marginparsep}
\addtolength\marginparwidth {-0.4in}
\else
\setlength\@tempdima {\paperwidth}
\addtolength\@tempdima {-\textheight}
\setlength\oddsidemargin {.5\@tempdima}
\addtolength\oddsidemargin {-1in}
\setlength\marginparwidth {.5\@tempdima}
\addtolength\marginparwidth {-\marginparsep}
\addtolength\marginparwidth {-0.4in}
\addtolength\marginparwidth {-.4in}
\fi
\ifdim \marginparwidth >2in
\setlength\marginparwidth{2in}
\fi
\@settopoint\oddsidemargin
\@settopoint\marginparwidth
\setlength\evensidemargin {\paperwidth}
\addtolength\evensidemargin{-2in}
\addtolength\evensidemargin{-\textheight}
\addtolength\evensidemargin{-\oddsidemargin}
\@settopoint\evensidemargin
\fi
\if@compatibility
\setlength\topmargin{27pt}
\else
\setlength\topmargin{\paperheight}
\addtolength\topmargin{-2in}
\addtolength\topmargin{-\headheight}
\addtolength\topmargin{-\headsep}
\addtolength\topmargin{-\textwidth}
\addtolength\topmargin{-\footskip} % this might be wrong!
\addtolength\topmargin{-.5\topmargin}
\@settopoint\topmargin
\fi
\else
\if@compatibility
\if@twocolumn
\setlength\textwidth{409.5\p@}
\else
\setlength\textwidth{357\p@}
\fi
\else
\setlength\@tempdimb{\paperwidth}
\addtolength\@tempdimb{-2in}
\@tempcnta=\@tempdimb
\setlength\@tempdima{10.5pt}
\@tempcntb=\@tempdima
\divide\@tempcnta\@tempcntb
\multiply\@tempdima\@tempcnta
\setlength\@tempdimb{357\p@}
\if@twocolumn
\ifdim\@tempdima>2\@tempdimb\relax
\setlength\textwidth{2\@tempdimb}
\else
\setlength\textwidth{\@tempdima}
\fi
\else
\ifdim\@tempdima>\@tempdimb\relax
\setlength\textwidth{\@tempdimb}
\else
\setlength\textwidth{\@tempdima}
\fi
\fi
\fi
\if@compatibility\else
\@settopoint\textwidth
\fi
\if@compatibility
\setlength\textheight{40\baselineskip}
\else
\setlength\@tempdima{\paperheight}
\addtolength\@tempdima{-2in}
\addtolength\@tempdima{-1.5in}
\divide\@tempdima\baselineskip
\@tempcnta=\@tempdima
\setlength\textheight{\@tempcnta\baselineskip}
\fi
\addtolength\textheight{\topskip}
\if@twocolumn
\setlength\marginparsep {10.5\p@}
\else
\setlength\marginparsep{10.5\p@}
\fi
\setlength\marginparpush{5\p@}
\if@compatibility
\if@twoside
\setlength\oddsidemargin {44\p@}
\setlength\evensidemargin {82\p@}
\setlength\marginparwidth {102.44\p@}
\else
\setlength\oddsidemargin {63\p@}
\setlength\evensidemargin {63\p@}
\setlength\marginparwidth {86.68\p@}
\fi
\if@twocolumn
\setlength\oddsidemargin {30\p@}
\setlength\evensidemargin {30\p@}
\setlength\marginparwidth {47.28\p@}
\fi
\else
\if@twoside
\setlength\@tempdima {\paperwidth}
\addtolength\@tempdima {-\textwidth}
\setlength\oddsidemargin {.4\@tempdima}
\addtolength\oddsidemargin {-1in}
\setlength\marginparwidth {.6\@tempdima}
\addtolength\marginparwidth {-\marginparsep}
\addtolength\marginparwidth {-0.4in}
\else
\setlength\@tempdima {\paperwidth}
\addtolength\@tempdima {-\textwidth}
\setlength\oddsidemargin {.5\@tempdima}
\addtolength\oddsidemargin {-1in}
\setlength\marginparwidth {.5\@tempdima}
\addtolength\marginparwidth {-\marginparsep}
\addtolength\marginparwidth {-0.4in}
\addtolength\marginparwidth {-.4in}
\fi
\ifdim \marginparwidth >2in
\setlength\marginparwidth{2in}
\fi
\@settopoint\oddsidemargin
\@settopoint\marginparwidth
\setlength\evensidemargin {\paperwidth}
\addtolength\evensidemargin{-2in}
\addtolength\evensidemargin{-\textwidth}
\addtolength\evensidemargin{-\oddsidemargin}
\@settopoint\evensidemargin
\fi
\if@compatibility
\setlength\topmargin{27pt}
\else
\setlength\topmargin{\paperheight}
\addtolength\topmargin{-2in}
\addtolength\topmargin{-\headheight}
\addtolength\topmargin{-\headsep}
\addtolength\topmargin{-\textheight}
\addtolength\topmargin{-\footskip} % this might be wrong!
\addtolength\topmargin{-.5\topmargin}
\@settopoint\topmargin
\fi
\fi
\setlength\footnotesep{7\p@}
\setlength{\skip\footins}{9.45\p@ \@plus 4\p@ \@minus 2\p@}
\setlength\floatsep {12\p@ \@plus 2\p@ \@minus 2\p@}
\setlength\textfloatsep{20\p@ \@plus 2\p@ \@minus 4\p@}
\setlength\intextsep {12.5\p@ \@plus 2\p@ \@minus 2\p@}
\setlength\dblfloatsep {12.5\p@ \@plus 2\p@ \@minus 2\p@}
\setlength\dbltextfloatsep{20\p@ \@plus 2\p@ \@minus 4\p@}
\setlength\@fptop{0\p@ \@plus 1fil}
\setlength\@fpsep{8.5\p@ \@plus 2fil}
\setlength\@fpbot{0\p@ \@plus 1fil}
\setlength\@dblfptop{0\p@ \@plus 1fil}
\setlength\@dblfpsep{8.5\p@ \@plus 2fil}
\setlength\@dblfpbot{0\p@ \@plus 1fil}
\setlength\partopsep{0\p@}
\def\@listi{\leftmargin\leftmargini
\parsep 0\p@
\topsep 0\p@
\itemsep 0\p@}
\let\@listI\@listi
\@listi
\def\@listii {\leftmargin\leftmarginii
\labelwidth\leftmarginii
\advance\labelwidth-\labelsep
\topsep 0\p@
\parsep 0\p@
\itemsep \parsep}
\def\@listiii{\leftmargin\leftmarginiii
\labelwidth\leftmarginiii
\advance\labelwidth-\labelsep
\topsep 0\p@
\parsep \z@
\partopsep \p@ \@plus\z@ \@minus\p@
\itemsep \topsep}
\def\@listiv {\leftmargin\leftmarginiv
\labelwidth\leftmarginiv
\advance\labelwidth-\labelsep}
\def\@listv {\leftmargin\leftmarginv
\labelwidth\leftmarginv
\advance\labelwidth-\labelsep}
\def\@listvi {\leftmargin\leftmarginvi
\labelwidth\leftmarginvi
\advance\labelwidth-\labelsep}
\endinput

现在可以在docoptions.clo加入五号字选项了,记着同时加入CJK纸张的大小选项:

\DeclareOption{z32kpaper}{\setlength\paperheight {185mm} \setlength\paperwidth {130mm}}
\DeclareOption{d32kpaper}{\setlength\paperheight {203mm} \setlength\paperwidth {140mm}}
%
\DeclareOption{wuhao}{\input{wuhao.clo}}

CJK包

现在我们可以定义自己的CJK包了,新建文件xwcjk.sty,内容如下:

\ProvidesFile{xwcjk.sty} [2015/04/01 cjk file (size option)]
%
\ocp\OCPindefault=inutf8
\ocp\OCPoutdefault=oututf8
\DefaultOutputMode onebyte
\DefaultOutputTranslation onebyte \OCPoutdefault
%
\ocp\OCPpunct=punctcjk
\ocp\OCPspace=spacecjk
\ocp\OCPbreak=breakcjk
\ocplist\OCPinput=
\addafterocplist 1 \OCPbreak
\addafterocplist 1 \OCPspace
\addafterocplist 1 \OCPpunct
\addafterocplist 1 \OCPindefault
\nullocplist
%
\ocplist\OCPverbatim=
\addafterocplist 1 \OCPindefault
\nullocplist
%
\newskip\boundCJKskip % defined later
\def\boundCJKglue{\hspace\boundCJKskip}
\newskip\interCJKskip % defined later
\def\interCJKglue{\hspace\interCJKskip}
\boundCJKskip=0.25em plus 0.125em minus 0.08em
\interCJKskip=0em plus 0.125em
\newdimen\zw \zw=0.92469em
\def\cjkkern{\kern 0.25em}
%
\def\strictlyforbiddenbreak{\nobreak}
\def\forbiddenbreak{\penalty500}
\def\slightlyforbiddenbreak{\penalty100}
\def\testbreak{\penalty-500}
%
\pretolerance=-1
\tolerance=2000
\hyphenpenalty=0
\exhyphenpenalty=0
\linepenalty=10
\adjdemerits=0
\doublehyphendemerits=0
\finalhyphendemerits=0
\lefthyphenmin=2
\righthyphenmin=3
\endinput

为自己的格式配置字体

如果你已经下载了秀文软件,latex格式文件latex.ltx被分成了两部分,放在tex/xiuwen/base目录下,分别是initialize.ltx和dump.ltx, 目的是方便用户定义自己的格式,tex/xiuwen/config目录下的configtemplate.ini是一个模板文件,用户可以仿照它定义自己的格式, 重要内容是定义文档中所需要的字体,tex/xiuwen目录下的readme.txt有完整的说明。

定义自己的文档类

在秀文中,latex的标准类文件被分割成不同的部分,放在tex/xiuwen目录下的子目录中,tex/xiuwen/class目录下的classtemplate.cls文件 是一个模板文件,用户可以仿照它定义自己的类文件。