首页 > 代码库 > 用LATEX 排版编程技术书籍的一些个人经验模板

用LATEX 排版编程技术书籍的一些个人经验模板

format.cls

  1 \usepackage[centering,paperwidth=180mm,paperheight=230mm,%  2 body={390pt,530pt},marginparsep=10pt,marginpar=50pt]{geometry}  3 \usepackage{color}  4 \usepackage{enumitem}  5 \usepackage{fancyvrb}  6 \usepackage[bottom,perpage,symbol*]{footmisc}  7 \usepackage{graphicx}  8 \usepackage[hidelinks]{hyperref}  9 \usepackage{makeidx} 10 \usepackage[toc]{multitoc} 11 \usepackage{pifont} 12 \usepackage{underscore} 13  14 \DefineFNsymbols*{chinese}{{\ding{172}}{\ding{173}}{\ding{174}}{\ding{175}}% 15 {\ding{176}}{\ding{177}}{\ding{178}}{\ding{179}}{\ding{180}}{\ding{181}}} 16 \setfnsymbol{chinese} 17  18 \hypersetup{bookmarksnumbered=true,bookmarksdepth=2} 19  20 \CTEXsetup[number={\thechapter}]{chapter} 21 \CTEXsetup[format+={\raggedleft}]{chapter} 22 \CTEXsetup[beforeskip={10pt}]{chapter} 23 \CTEXsetup[afterskip={30pt}]{chapter} 24 \def\CTEX@chapter@aftername{\par} % \CTEXsetup[aftername={\par}]{chapter} 25 \CTEXsetup[format+={\raggedright}]{section} 26 \CTEXsetup[beforeskip={-3.0ex plus -1ex minus -.2ex}]{section} 27 \CTEXsetup[afterskip={2.3ex plus .2ex minus 0.2ex}]{section} 28  29 \renewcommand \thefigure{\thechapter-\arabic{figure}} 30 \renewcommand \thetable{\thechapter-\arabic{table}} 31  32 \newcommand\figcaption[1]{\def\@captype{figure}\caption{#1}} 33 \newcommand\tabcaption[1]{\def\@captype{table}\caption{#1}} 34  35 \long\def\@caption#1[#2]#3{% 36   \addcontentsline{\csname ext@#1\endcsname}{#1}% 37     {\protect\numberline{\csname fnum@#1\endcsname}{ \ignorespaces #2}}% change "the" to "fnum@" 38     \normalsize 39     \@makecaption{\csname fnum@#1\endcsname}{\ignorespaces #3}} 40  41 \long\def\@makecaption#1#2{% 42   \vskip\abovecaptionskip 43   \sbox\@tempboxa{#1\quad#2}% 44   \ifdim \wd\@tempboxa >\hsize 45     #1\quad#2\par 46   \else 47     \global \@minipagefalse 48     \hb@xt@\hsize{\hfil\box\@tempboxa\hfil}% 49   \fi 50   \vskip\belowcaptionskip} 51  52 \setlength\abovecaptionskip{0pt} 53  54 %\setmainfont{Times New Roman} 55 \setmainfont{Linux Libertine O}%********************************************************************************************************************* 56 %****************************************************************************************************************************************************** 57 %\setmainfont{TeX Gyre Pagella} 58 \newfontfamily\urlfont{PT Sans Narrow} 59 %\setmonofont[AutoFakeBold=1.6,AutoFakeSlant=0.17,Mapping=tex-text-tt]{Inconsolata} 60 \setCJKfamilyfont{zhyou}{YouYuan} 61  62 \newcommand{\fn}[1]{\texttt{#1}} 63 \newcommand{\sfn}[1]{\texttt{\small #1}} 64 \newcommand{\kw}[1]{\textsf{#1}} 65 \newcommand{\myurl}[1]{{\url #1}} 66 \newcommand{\mpar}[1]{\marginpar[\hfill\kaishu #1]{\kaishu #1}} 67 \newcommand{\mn}[1]{\texttt{\bs #1}} 68 \renewcommand{\today}{\the\year-\the\month-\the\day} 69 \newcommand\bs{\textbackslash} 70  71 \newcommand\begindot{\begin{itemize} 72 [itemsep=2pt plus 2pt minus 2pt,% 73 topsep=3pt plus 2pt minus 2pt,% 74 parsep=0pt plus 2pt minus 2pt]} 75 \newcommand\myenddot{\end{itemize}} 76  77 \newcommand\beginnum{\begin{enumerate} 78 [itemsep=2pt plus 2pt minus 2pt,% 79 topsep=3pt plus 2pt minus 2pt,% 80 parsep=0pt plus 2pt minus 2pt]} 81 \newcommand\myendnum{\end{enumerate}} 82  83 \DefineVerbatimEnvironment% 84   {Code}{Verbatim} 85   {fontsize=\small,baselinestretch=0.9,xleftmargin=3mm} 86  87 \raggedbottom 88 %\setlength{\parskip}{1ex plus .5ex minus .5ex} 89  90 \input{verbatim.cls} 91 \DefineVerbatimEnvironment% 92   {Codex}{Verbatim} 93   {fontsize=\small,baselinestretch=0.9,xleftmargin=3mm,% 94   frame=lines,labelposition=all,framesep=5pt} 95  96 \DefineVerbatimEnvironment% 97   {Code}{Verbatim} 98   {fontsize=\small,baselinestretch=0.9,xleftmargin=3mm} 99 100 \makeindex

 

verbatim.cls

  1 \def\FV@SetLineWidth{%  2   \if@FV@ResetMargins\else  3     \advance\leftmargin\@totalleftmargin  4   \fi  5   \advance\leftmargin\FV@XLeftMargin\relax  6   \advance\rightmargin\FV@XRightMargin\relax  7   \linewidth\hsize  8   %\advance\linewidth-\leftmargin  9   %\advance\linewidth-\rightmargin 10   \hfuzz\FancyVerbHFuzz\relax} 11  12  13 \def\FV@SingleFrameLine#1{% 14 %% DG/SR modification end 15   \hbox to\z@{% 16     %\kern\leftmargin 17 %% DG/SR modification begin - Jun. 22, 1998 18     \ifnum#1=\z@ 19       \let\FV@Label\FV@LabelBegin 20     \else 21       \let\FV@Label\FV@LabelEnd 22     \fi 23     \ifx\FV@Label\relax 24 %% DG/SR modification end 25       \FancyVerbRuleColor{\vrule \@width\linewidth \@height\FV@FrameRule}% 26 %% DG/SR modification begin - Jun. 22, 1998 27     \else 28       \ifnum#1=\z@ 29         \setbox\z@\hbox{\strut\enspace\urlfont\FV@LabelBegin\strut}% 30       \else 31         \setbox\z@\hbox{\strut\enspace\urlfont\FV@LabelEnd\strut}% 32       \fi 33       \@tempdimb=\dp\z@ 34       \advance\@tempdimb -.5\ht\z@ 35       \@tempdimc=\linewidth 36       \advance\@tempdimc -\wd\z@ 37       %\divide\@tempdimc\tw@ 38       \ifnum#1=\z@              % Top line 39         \ifx\FV@LabelPositionTopLine\relax 40           \FancyVerbRuleColor{\vrule \@width\linewidth \@height\FV@FrameRule}% 41         \else 42           \FV@FrameLineWithLabel 43         \fi 44       \else                     % Bottom line 45         \ifx\FV@LabelPositionBottomLine\relax 46           \FancyVerbRuleColor{\vrule \@width\linewidth \@height\FV@FrameRule}% 47         \else 48           \FV@FrameLineWithLabel 49         \fi 50       \fi 51     \fi 52 %% DG/SR modification end 53     \hss}} 54  55  56 %% DG/SR modification begin - May. 19, 1998 57 \def\FV@FrameLineWithLabel{% 58   \ht\z@\@tempdimb\dp\z@\@tempdimb% 59   \FancyVerbRuleColor{% 60     \raise 0.5ex\hbox{\vrule \@width\@tempdimc \@height\FV@FrameRule}% 61     \raise\@tempdimb\box\z@}} 62 %% DG/SR modification end 63  64  65 \def\FV@EndListFrame@Lines{% 66   \begingroup 67     %\vskip 0.5ex 68     \baselineskip\z@skip 69     \kern\FV@FrameSep\relax 70 %% DG/SR modification begin - May. 19, 1998 71 %%    \FV@SingleFrameLine 72     \FV@SingleFrameLine{\@ne}% 73 %% DG/SR modification end 74   \endgroup} 75  76 \newskip\mytopsep 77 \setlength{\mytopsep}{4pt plus 2pt minus 3pt} 78  79 \def\FV@ListVSpace{% 80   \@topsepadd\mytopsep 81   \if@noparlist\advance\@topsepadd\partopsep\fi 82   \if@inlabel 83     \vskip\parskip 84   \else 85     \if@nobreak 86       \vskip\parskip 87       \clubpenalty\@M 88     \else 89       \addpenalty\@beginparpenalty 90       \@topsep\@topsepadd 91       \advance\@topsep\parskip 92       \addvspace\@topsep 93     \fi 94   \fi 95   %\showthe \@topsepadd 96   %\showthe \topsep 97   %\showthe \partopsep 98   %\showthe \parskip 99   \global\@nobreakfalse100   \global\@inlabelfalse101   \global\@minipagefalse102   \global\@newlistfalse}103 104 \def\FV@EndList{%105   \FV@ListProcessLastLine106   \FV@EndListFrame107   %\showthe \@topsepadd108   \@endparenv109   \endgroup110   \@endpetrue}111 112 \def\theFancyVerbLine{\sffamily\scriptsize\arabic{FancyVerbLine}}

 

typeset.tex

 1 \documentclass[10pt,adobefonts,fancyhdr,hyperref,UTF8]{ctexbook} 2 %\usepackage{fontspec} 3  4 \makeatletter 5 \input{format.cls} 6 \makeatother 7  8 \graphicspath{{diagrams/}} 9 \begin{document}10 \sloppy11 \newcommand\mybooktitle{《Linux多线程服务端编程:使用muduo C++网络库》}12 \newcommand\BookTitle{用 \LaTeX 排版编程技术书籍的一些个人经验}13 \pagestyle{fancy}14 \fancyhf{}15 \fancyhead[RE]{\normalfont\small\rmfamily\nouppercase{\leftmark}}16 \fancyhead[LO]{\normalfont\small\rmfamily\nouppercase{\rightmark}}17 \fancyhead[LE,RO]{\thepage}18 \fancyfoot[LE,LO]{\small\normalfont\youyuan\BookTitle  by 陈硕}19 \fancyfoot[RE,RO]{\textsf{\small \color{blue} http://www.chenshuo.com/}}20 21 \makeatletter22 \@openrightfalse23 \makeatother24 25 \frontmatter % 开始前言目录,页码用罗马数字26 27 \include{title}28 29 \tableofcontents30 31 \mainmatter % 开始正文,页码用阿拉伯数字32 33 34 35 \include{chapEnvironment}36 \include{chapLayout}37 \include{chapStyle}38 \include{chapExperience}39 \include{chapTools}40 \include{chapDiagram}41 42 \appendix % 开始附录,章用字母编号43 \printindex44 45 \end{document}

 

title.tex

 1 \thispagestyle{plain} 2 \begin{center} 3   {\LARGE\textbf{\BookTitle}} 4   \vspace{1em} 5   {\large 陈硕 (giantchen@gmail.com)} 6  7   \vspace{1ex} 8   最后更新 \today 9 10   \vspace{1em}11   \textbf{\large 版权声明}12 \end{center}13 \noindent 本作品采用“Creative Commons 署名-非商业性使用-相同方式共享 3.0 Unported许可协议14 (cc by-nc-sa)”进行许可。15 \texttt{\small http://creativecommons.org/licenses/by-nc-sa/3.0/}16 17 \vspace{1em}18 \input{abstract}19 %\input{chapEnvironment}

 

abstract.tex

 1 多年之前我写过一篇书评《〈Word排版艺术〉读后感——兼谈与\LaTeX 的比较》 2 \footnote{\myurl{http://blog.csdn.net/solstice/article/details/187233}}, 3 其中写道{\kaishu “如果将来有时间,我把自己用\LaTeX 排书的经验总结一下, 4 让读者在阅读《Word排版艺术》的基础上,更容易地把知识应用到\LaTeX 排版中去。”} 5 我自己排版了 \mybooktitle,现在终于可以把账还上了。 6 本文假定读者已经读过\LaTeX 的入门文档 7 \footnote{\myurl{http://mirrors.ctan.org/info/lshort/chinese/lshort-zh-cn.pdf}} 8 \footnote{\myurl{http://www.tex.ac.uk/tex-archive/info/latex-notes-zh-cn/latex-notes-zh-cn.pdf}} 9 和书籍10 \footnote{《\LaTeX 入门与提高(第2版)》,陈志杰等著,高等教育出版社。},11 具备基本的使用技能,这不是一篇入门教程。12 13 排版是一门大学问,我只是一名技术图书的作者,有一些初步的 \LaTeX  使用经验。14 我不是专家,出版印刷的行话也不怎么会说。15 本文的目的是让有志于用\LaTeX 来排版自己书的人少走一些弯路。16 换句话说,这篇文章是讲“我是怎么做的”,不是讲“哪种做法最好”。17 另外,遇到\LaTeX 使用方面的问题请先阅读FAQ18 \footnote{\myurl{http://www.newsmth.net/bbscon.php?bid=460\&id=282515}},再上CTeX论坛19 \footnote{\myurl{http://bbs.ctex.org/forum.php} } 或水木社区TeX版 \nolinebreak20 \footnote{\myurl{http://www.newsmth.net/bbsdoc.php?board=TeX}} 发帖询问,21 不要给我写信。(我最多能回答我那本书里某个版面是如何排出来的,无法解答你的具体问题。)22 23 最新版下载地址:\myurl{http://code.google.com/p/chenshuo/downloads/detail?name=typeset.pdf}24 25 \LaTeX  源文件:\myurl{http://github.com/chenshuo/typeset}26 27 \subsubsection{更新记录}28 \begindot29 \item[] 2013-02-04 初版30 \myenddot

 

chapEnvironment.tex

  1 \chapter{环境}  2   3 \section{为什么要自己排版?}  4 \label{sec:whyTypesetting}  5   6 如果是纯文学著作,完全可以交给出版社去排版。  7 但是对于编程技术书籍,文字之间还穿插代码和图表,  8 那么出版社的专业排版人员很难排出符合程序员审美观的版面,  9 甚至有可能造成技术错误。 10  11  12 \begindot 13 \item 代码的排版,注意分页和折行。特别是Python这种缩进敏感的语言, 14 一般要避免在一个函数内分页,这会造成阅读困难。可以在函数定义之间分页。 15  16 \item 写作与排版一体化,作者可以适当改写内容,让版面更美观。 17 例如,假如一个函数最后一行那个花括号被挤到了下一页第一行,这就很难看。 18 这时可以考虑临时改变代码的缩进(从BSD风格改为K\&R风格),从而节省一两行空间, 19 让花括号落在本页。另外也可以稍微改变说法,避免段尾孤字成行。 20  21 \item 文责自负,防止误改。例如我为某本书写的序言,其中提到旧的 boost \fn{RegEx} 22 \kw{class} 和新的 \fn{regex} \kw{class} 在线程安全性方面的不同。 23 这本书第二版再用这篇序言的时候被编辑“统一大小写”改为 \fn{RegEx}, 24 整段话也就变得莫名其妙了。 25 类似的还有 $2^{32}-1$ 这种式子很容易被误改为 $232-1$,让人看了一头雾水。 26 \myenddot 27  28  29 \section{为什么要用\LaTeX 排版?} 30 \begindot 31 \item \LaTeX 不会自作聪明地自动更正,例如句首字母大写 32 (关键字 \kw{double} 变为 \kw{Double}), 33 单词头两个字母大写(\fn{IUnknown} 变为 \fn{Iunknown}), 34 括号匹配(“[begin, end)”变为“[begin, end]”)等等。 35 Word 可以关闭自动更正,但是一旦整个流程(作者、编辑、校对、出片)中有一个人的设置不同, 36 稿子就有可能被误改。 37  38 \item \LaTeX 的源文件是文本格式,可以方便地做版本管理(\fn{diff}/\fn{merge}), 39 并且很容易利用和编写各种小工具来处理它。 40 相反Word的 \fn{.doc}/\fn{.docx} 文件处理起来就麻烦多了,如果不是不可能的话。 41 想想一句 \fn{grep | sort | uniq -c | sort -n} 要写多少代码。 42  43 \newpage 44 \item \LaTeX 可以处理英文断字(Hyphenation),避免一行文字太稀疏。 45 例如\fn{Concurrent\-Hash\-Map} 这种在技术书籍中经常出现的长类名, 46 如果不断字就会造成难看的版面。这也是Word排版容易出现的问题。 47 另外\LaTeX 的断行和断页采用动态规划算法,排出来的版面比Word的贪心算法更匀称, 48 见后文的例子。 49  50  51 \item \LaTeX 可以方便地做出交叉引用,引用其他章节图表的页码或编号。 52 \LaTeX 原稿可以分散到多个 \fn{.tex} 文件中,便于编辑。 53 如果 Word 也这么做(每章一个文件),那么交叉引用就麻烦得多。 54 但是如果把整本书做成一个Word文件,那编辑起来就困难多了,牵一发而动全身。 55 而且有一种如履薄冰的感觉,生怕哪天文件突然就损坏了。 56 \myenddot 57  58 以下展示动态规划与贪心算法的区别。这里版心宽度是20个汉字。\label{ex:dynamicProgramming} 59 第一行排满了20字,刚刚好。 60 第二行排了16字,后接一个长单词,其宽度超过5个汉字, 61 因此本行排不下了。Word和\LaTeX 都会把长单词移到第三行, 62 但是区别在于Word不会返回去调整第一行已经排好的那20个字% 63 (贪心算法只管当前行,排满为止,排不下就另起一行), 64 因此第二行比第一行显得稀疏,版面不匀称。 65 而 \LaTeX 则会把整个段落通盘考虑,它会从第一行挪两个字到第二行, 66 让前两行的字距相当,版面更匀称。 67  68 \vspace{1ex} 69 \centerline{\includegraphics[page=2]{linebreak-crop.pdf}} 70  71 \subsection{动手之前} 72 作者有能力并且有意愿完整书籍的排版,向出版社提供印刷质量的PDF文稿。 73 出版社愿意改变通常的工作流程,采用作者提供的PDF文件来校对并印刷。 74 要事先沟通好。 75 \LaTeX 不是一个傻瓜化的工具,它需要投入相当的精力去学习,才能排出满意的效果。 76  77 %\section{硬件设备} 78 %我自己使用两台24吋显示器,并排 79  80 \section{软件工具} 81  82 \subsection{操作系统} 83  84 操作系统应满足三个条件: 85 有好用的中文输入法,有好用的PDF阅读器, 86 能方便地用命令行处理文本文件(\fn{grep}、\fn{sort}、\fn{awk} 等)。 87 目前看来符合这个条件的操作系统是Mac~OS X, 88 但是我不可能为了写一本书去买一台新的笔记本电脑。 89 因此我用的是一种混合办法,笔记本上安装Windows, 90 再在虚拟机中安装Debian Linux, 91 然后在Debian 中安装 TeX Live。 92 最后用Samba共享文件夹,这样就可以在Windows下方便地编辑Linux上的文件。 93 而在Linux上用 Git 管理 \fn{.tex} 源文件和图片,并且编译出PDF。 94  95 \subsection{\TeX 发行版} 96 Linux用TeX Live,Windows用CTeX套装,Mac~OS X 用 Mac TeX。 97 中文处理采用xelatex + xeCJK + ctex 方案 98 \footnote{\myurl{http://blog.jjgod.org/2009/11/21/chinese-in-tex-live-2009/}}, 99 不要采用过时的 CJK 或 CCT 方案。100 101 注意,\TeX 本身是非常稳定的,但是中文处理则在不断改进。102 例如TeX Live 2010和TeX Live 2012在处理中英文混排方面就有区别,103 造成“动版”,严重时会影响既有分页。104 105 \vspace{1ex}106 \centerline{\fbox{\includegraphics[width=360pt]{texlive2010.png}}}107 108 \vspace{1ex}109 \centerline{\fbox{\includegraphics[width=360pt]{texlive2012.png}}}110 111 \vspace{1ex}112 因此我建议不要在排版期间升级 \LaTeX 的大版本,113 这也是我在虚拟机上安装 TeX Live 的原因之一。114 这样可以轻松地备份整个系统,115 将来重印需要修订书中某几页的时候可以使用当年的虚拟机映像,版本一致,不必担心其他页面发生“动版”。116 117 \subsection{PDF阅读器}118 推荐SumatraPDF,它不锁PDF文件,可以随时覆盖,并且自动刷新。119 120 \subsection{离线备份}121 写书是一项耗时的任务,数据备份是必不可少的,122 防止误操作和硬件损坏带来的不可弥补的损失。123 除了 \S \ref{sec:versionControl} 讲的源文件版本管理之外,124 各种图片、表格,以及生成PDF也要及时备份,125 最好是离线(offline)备份。126 可用以下这些网盘:127 128 \begindot129 \item Amazon Cloud Drive130 \item Dropbox131 \item Google Drive132 \item Microsoft Sky Drive133 \myenddot134 135 这几个网盘都有Windows和Mac客户端,136 这也是我使用Windows桌面的原因之一。137 138 \section{版本管理}139 \label{sec:versionControl}140 141 142 我用Git管理 \fn{.tex} 文件和其他输入文件,143 并且同步到 Github 的私人仓库,144 就像这篇文章一样。145 146 \subsection{理想的工作流程}147 作者和编辑都使用版本管理软件,就像开发软件那样工作。148 \LaTeX 就好比是编译器,149 \fn{.tex} 文件是源程序,150 \fn{.pdf} 文件是编译的结果。151 作者和编辑都可以修改源程序,并且通过版本管理软件来merge结果。152 考虑到作者和编辑不在同一个内网,因此一般要用公共的版本库,例如Github。153 GitHub 的私有 repository 可保证数据安全。154 155 \subsection{现实的工作流程}156 编辑往往既不会\LaTeX 也不会Git,那就之好采用原始方案,157 作者提供PDF,编辑加以评注,或者打印出来再用红笔校对。158 159 \section{\fn{.tex} 文件组织}160 \fn{.tex} 文件一律使用 UTF-8编码,一来避免各种编码转换的问题(某些人名用字在GB2312中没有定义),161 二来可以直接使用现有的Linux命令行工具来处理 \fn{.tex} 文件。162 \fn{.tex} 文件一般可以按章或按节划分,每个文件不超过1000行,以利于编辑。163 再用一个 \fn{.tex} 文件把它们 \mn{include} 到一起。164 \fn{.tex} 和图片文件的文件名不要有下划线。

 

chapLayout.tex

  1 \chapter{版式}  2   3 本文使用的长度单位:  4 1英寸 = 25.4mm = 72.27pt \footnote{pt是point的缩写,中文叫“磅”。} = 72bp。  5 注意 \TeX 定义的pt和PostScript(亦即Adobe系列软件)定义的pt的长度不一样,  6 本书以 \TeX 定义的pt为准,Post\-Script的基本长度单位写为bp(big point)。  7   8 \section{纸张大小} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  9  10 书籍的纸张大小通常异于常用的打印纸大小(A4或B5), 11 因此用 \LaTeX 排版书籍的第一步是设置好纸张大小。 12 一般常见的IT图书的开本(成品书尺寸,可以用尺子量出来)是 185mm $\times$ 230mm, 13 即“国际18开”;另外一种常见开本是185mm $\times$ 260mm,即“16开”。 14 本文以“国际18开”为例。 15 我们通常可以用 \fn{geometry} 宏包来设置纸张和版心尺寸, 16 例子见 \S \ref{sec:textbody}。 17 \index{宏包!geometry@\fn{geometry}|(} 18 %\index{开本} 19  20 \section{版心大小} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 21 \label{sec:textbody} 22  23 “版心”即正文区,不包含页眉和页脚 24 \footnote{这是本文的定义,也有将版心定义为包含页眉和页脚的。}。 25 版心的大小可以这样计算: 26 通常正文字号是10pt 27 \footnote{比五号(10.5pt)字略小,比小五号字(9pt)大。}, 28 一行按39个汉字计算, 29 %\footnote{。一般不宜超过40个。} 30 那么行宽是 390pt。 31 行宽是正文字号的整数倍,这样中文间距不会无故拉宽。 32 行宽不宜过大,否则阅读的时候容易读串行; 33 也不宜过小,否则一行排不下80列代码。一般而言, 34 36 \textasciitilde\ 42字比较适宜,本文定为39字,数数上一行:-)。 35 \mybooktitle 一行是37个汉字, 36 因为这本书厚达600页,如果版心太宽容易影响阅读订口的文字。 37  38 对于10pt的正文字体,\LaTeX 默认的行距 39 \footnote{行距指的是英文基线(baseline)之间的距离,即中文汉字底部之间的距离, 40 不是两行之间的空白。} 是12pt,这对于英文是合适的 41 \footnote{因为英文文本多是小写字母,字高远小于10pt。}, 42 但是对于中文则显得太密了。因此 \CTeX 宏包将 \mn{baselinestretch} 定义为 1.3 43 \index{命令!baselinestretch@\mn{baselinestretch}} 44 这样行距是\linebreak 1.3$\times$12pt = 15.6pt,阅读起来就比较顺眼了。 45 如果一页排34行字,那么版心的高度大约是 \nolinebreak 46 \footnote{这里说“大约”,因为第一行上方似乎不必留出多余的空白。} 34$\times$15.6pt=530.4pt, 47 本文取 530pt 48 \footnote{对于技术类图书,通常一个自然段不会太长, 49 一页之内几乎总是会遇到分段(整段代码、图表、章节标题)的情况, 50 因此版心高度不必严格是行距的整数倍。} 。 51  52 综上,对于39字 $\times$ 34行的版心,其尺寸是 390pt $\times$ 530pt,约合 137mm $\times$ 186mm。见下图示意。 53  54 %\vspace{1ex} 55 \centerline{\includegraphics{paper.eps}} 56  57 知道了纸张和版心尺寸,剩下的就交给 \fn{geometry} 宏包。 58 它同时会设置生成的PDF的纸张尺寸。 59 例如 \myurl{examples/paper.tex}。 60 \index{宏包!geometry@\fn{geometry}|)} 61  62 \begin{Codex}[label=examples/paper.tex] 63 \documentclass[10pt,fancyhdr,UTF8]{ctexbook} 64 \usepackage[centering,paperwidth=180mm,paperheight=230mm,% 65             body={390pt,530pt},showframe]{geometry} 66 \end{Codex} 67  68 注意这里把纸张宽度设为 180mm,这是考虑到装订的位置, 69 这样在电脑上预览的时候左右空白更贴近实际印刷的效果。 70 我们也不必关心版心在纸张中的上下左右位置,居中即可, 71 在印刷的时候有专人负责拼版。当然在正式排版的时候要去掉 \fn{showframe} 选项。 72  73 另外,打印纸一般不会刚好和书籍开本一样大, 74 要想在书印出来之前感受版面效果, 75 可以打印在A4纸上,但需要将书页框出来,可用 \fn{crop} 宏包。 76 例如 \myurl{examples/paper-crop.tex}。 77 \index{宏包!crop@\fn{crop}} 78  79 \begin{Code} 80 $ diff -u paper.tex paper-crop.tex 81 --- paper.tex           2012-12-29 14:03:02.000 +0800 82 +++ paper-crop.tex      2012-12-29 14:03:02.000 +0800 83  \documentclass[10pt,fancyhdr,UTF8]{ctexbook} 84  \usepackage[centering,paperwidth=180mm,paperheight=230mm,% 85              body={390pt,530pt},showframe]{geometry} 86 +\usepackage[a4,center,frame,color=blue]{crop} 87 \end{Code} 88  89 \section{页眉与页脚} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 90  91 书籍排版不是以一页(一面)为单位,而是以翻开之后的两面(左右页)为单位。 92 \LaTeX 默认会设法让左右页的内容一样多,即左右页的最后一行位于同一高度。 93 有时候这会造成难看的版面,特别是有可能留下过多段间空白。 94 一般可以用 \mn{raggedbottom} 命令来取消这一设定。 95 \index{命令!raggedbottom@\mn{raggedbottom}} 96  97 页眉的外侧(切口)是页码,内侧(订口)是章节名称,通常是左页(偶数页)放章名, 98 右页(奇数页)放节名 99 \footnote{\mybooktitle p.393 的内侧页眉为空,因为该章第1节出现在 p.394。}。100 页脚通常可以放书名,这样即便复印其中一面也容易知道出自何处%101 (本文把作者姓名和网址也放到页脚,便于网上传播)。102 典型的安排如下图所示。103 104 \vspace{1ex}105 \centerline{\fbox{\includegraphics[page=2,scale=0.9]{header.pdf}}%106 \quad\fbox{\includegraphics[page=3,scale=0.9]{header.pdf}}}107 108 \vspace{1ex}109 我们一般用 \fn{fancyhdr} 宏包来设置页眉和页脚,常用的设置如下。110 其中 \fn{RE} 表示偶数页\linebreak(Even)右侧(Right),111 \fn{LO} 表示奇数页(Odd)左侧(Left),112 \fn{LE}、\fn{RO} 的意思想必读者能举一反三猜出来。113 \index{宏包!fancyhdr@\fn{fancyhdr}}114 115 \begin{Code}116 \pagestyle{fancy}117 \fancyhf{}118 \fancyhead[RE]{\normalfont\small\rmfamily\nouppercase{\leftmark}}119 \fancyhead[LO]{\normalfont\small\rmfamily\nouppercase{\rightmark}}120 \fancyhead[LE,RO]{\thepage}121 \fancyfoot[LE,LO]{\small Book Title}122 \end{Code}123 124 通常每章的第一页没有页眉,页码放到页脚中央,即 \fn{plain} 页面格式,如下图所示。125 126 \vspace{1ex}127 \centerline{\fbox{\includegraphics[page=1,scale=0.9]{header.pdf}}}128 129 \section{中文字体} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%130 131 首先,适合屏幕阅读的字体不一定适合印刷书籍。132 原因可能有两点,一是书籍的印刷分辨率远高于屏幕;133 二是屏幕会主动发光,而书籍是被动反光。134 其次,中文字体用三四种(宋、黑、楷)就足够了,不要太花哨。135 印刷用的正文字体可用方正书宋或华康简宋,136 视出版社的字体授权情况而定。137 屏幕阅读可用Windows中文字体或Adobe中文字体。138 注意某些Adobe中文字体的标点符号位置不正确,139 例如Adobe楷体的全角冒号和分号上下居中,而不是位于左下角(140 \setCJKfamilyfont{adobekai}{Adobe Kaiti Std}141 {\CJKfamily{adobekai}子曰:“食不厌精;脍不厌细。”}),142 使用时需要注意。143 另外,方正书宋和华康简宋缺少某些繁体字(例如“碁”),可以临时改换为Adobe宋体。144 例如145 \begin{Code}146 \setCJKfamilyfont{adobesong}{Adobe Song Std}147 《C++编程规范(繁体版)》由{\CJKfamily{adobesong} 碁峰}出版社出版。148 \end{Code}149 150 \subsection{不要使用中文斜体}151 \label{subsec:noChineseItalic}152 中文斜体是非常难看的,千万不要用。153 为了突出中文术语,可以用\textbf{黑体},例如\textbf{与非门}。154 传统科技书籍也常用{\kaishu 楷体}表示术语和强调,不过黑体目前似乎更流行一些。155 156 157 \section{英文字体} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%158 英文字体可选择的范围就大多了,可参考159 The \LaTeX\ Font Catalogue \footnote{\myurl{http://www.tug.dk/FontCatalogue/}}。160 161 \subsection{罗马字体}162 不要使用 {\fontfamily{lmr}\selectfont Computer Modern Roman},163 它笔画太细而且衬线略显夸张。164 英文罗马字体一般可以选 {\fontspec{Times New Roman} Times Roman}165 \footnote{实际的字体名是 \fn{Nimbus Roman No9 L} 或 \fn{TeX Gyre Termes} 或 \fn{Times New Roman} 等。}166 或 {\fontspec{URW Palladio L} Palatino}167 \footnote{实际的字体名是 \fn{URW Palladio L} 或 \fn{TeX Gyre Pagella} 等。}。168 例如169 \begindot170 \item {\fontspec{TeX Gyre Termes} C++ is a general-purpose programming language. [Times Roman]}171 \item {\fontspec{TeX Gyre Pagella} C++ is a general-purpose programming language. [Palatino]}172 \myenddot173 \subsection{无衬线字体}174 175 一般用于章节标题和编程语言关键字,例如“\kw{this} 指针”、176 “\kw{mutable} 成员变量”。由于它出现的机会少,用什么字体其实无所谓,177 默认的 \kw{Computer Modern Sans Serif} 就行。178 也可以换为 {\fontspec{Nimbus Sans L} Helvetica}179 \footnote{实际的字体名是 \fn{Nimbus Sans L} 或 \fn{TeX Gyre Heros} 或 \fn{Arial} 等。}。180 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%181 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%182 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%183 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%184 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%185 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%186 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%187 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%188 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%189 190 \subsection{等宽字体}191 一般用于代码,包括变量名、类名等等。192 不要使用 {\fontspec{Courier New} Courier New},它太细而且太宽。193 可以用\LaTeX 默认的 {\fontspec{Latin Modern Mono} Computer Modern Typewriter}194 \footnote{实际字体名是 \fn{Latin Modern Mono}。}195 或 {\fontspec{Inconsolata} Inconsolata}。后者要窄一些,但是双引号略弯。例如196 \begindot197 \item[] {\small \fontspec{Latin Modern Mono} printf("Hello \%s\bs n", name);}[cmtt]198 \item[] {\small \fontspec[Mapping=tex-text-tt]{Inconsolata} printf("Hello \%s\bs n", name)};[Inconsolata]199 \myenddot200 201 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%202 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%203 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%204 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%205 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%206 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%207 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%208 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%209 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%210 211 注意如果要使用 Inconsolata 字体来排版代码,需要防止 \LaTeX 替换其中的字符,212 例如 {\fontspec[Mapping=tex-text-tt]{Inconsolata} operator<<()} 变成 {\fontspec{Inconsolata} operator<<()} 等。213 可以通过 \fn{fontspec} 宏包的 \fn{Mapping} 选项来做到这一点,214 并搭配合适的 TECkit 映射文件215 \footnote{见本文源码目录中的 \fn{tex-text-tt.map},需要用 \fn{teckit_compile} 工具编译为 \fn{{}.tec} 文件。}。216 217 如果要排版大量Java代码(一行可长达100列),可以考虑用窄的无衬线等宽字体,218 如 TheSansMono Condensed,但似乎没有免费版本。219 另外,一些英文书籍也用 {\small \fontspec{Lucida Sans Typewriter}Lucida Sans Typewriter} 来排版代码,可以从Sun JDK中找到。220 221 \subsection{特殊字体}222 URL可以用窄字体,以节省空间。223 例如 {\fontspec{Ubuntu Condensed}Ubuntu Condensed} 或者 \myurl{PT Sans Narrow}。224 特殊术语可以用稍微夸张一点的字体凸显,例如“{\fontspec{URW Gothic L} Extract Method} 重构”和225 “{\fontspec{URW Gothic L} Observer} 模式”。226 \section{行距与段距}227 中文区分自然段的方法有三种,传统的方案是段首空两格(indent),228 现代的方案是两段之间增加空白(\mn{parskip}),229 第三种方案是同时使用前两者。本文采用传统方案,230 \mybooktitle 一书采用第三种方案。231 设置\mn{parskip} 的时候要小心,它会影响所有段落之前的空白,232 包括章节标题、图表、图表编号等等。233 \index{命令!parskip@\mn{parskip}}234 235 \section{整段代码}236 \index{宏包!fancyvrb@\fn{fancyvrb}}237 用等宽字体排版代码一般可用 \fn{fancyvrb} 宏包,然后定义自己的\fn{Code} 环境,238 字号9pt,行距0.9,左边留出3mm。239 \begin{Code}240 \DefineVerbatimEnvironment{Code}{Verbatim}%241   {fontsize=\small,baselinestretch=0.9,xleftmargin=3mm}242 \end{Code}243 244 用 {\fontspec{Latin Modern Mono} Computer Modern Typewriter} 字体,版心宽度390pt时,一行可排80列。245 \begin{Verbatim}[fontsize=\small,baselinestretch=0.9,xleftmargin=3mm]246 \begin{Code}247 12345678901234567890123456789012345678901234567890123456789012345678901234567890248          1         2         3         4         5         6         7         8249 \end{Code}250 \end{Verbatim}251 252 用 {\fontspec{Inconsolata} Inconsolata} 字体,版心宽度为390pt时,一行可排84列。253 版心宽度为370pt时可排80列。254 %\setmonofont[AutoFakeBold=1.6,AutoFakeSlant=0.17,Mapping=tex-text-tt]{Inconsolata}255 \makeatletter256 \@namedef{FV@fontfamily@inconsolata}{%257   \def\FV@FontScanPrep{}%258   \def\FV@FontFamily{\fontspec{Inconsolata}}}259 \makeatother260 \begin{Code}[fontfamily=inconsolata]261 123456789012345678901234567890123456789012345678901234567890123456789012345678901234262          1         2         3         4         5         6         7         8263 \end{Code}264 265 另外还可以定义\fn{Codex} 环境,用于排版带标题(文件名)的代码。266 267 \begin{Code}268 \DefineVerbatimEnvironment{Codex}{Verbatim}%269   {fontsize=\small,baselinestretch=0.9,xleftmargin=3mm,%270   frame=lines,labelposition=all,framesep=5pt}271 \end{Code}272 273 我对 \fn{fancyvrb} 宏包有一些改动,见 \fn{verbatim.cls}。274 最终效果如下:275 \begin{Codex}[label=hello.c,numbers=left]276 int main()277 {278   printf("Hello, world.\n");279 }280 \end{Codex}

 

chapStyle.tex

  1 \chapter{样式}  2   3 \section{转义字符}  4 注意“\#\,”是 \TeX 元字符,因此 C\# 要写作 \fn{C\bs\#}。  5 类似的“\textasciitilde”也是元字符,  6 要写作\mn{textasciitilde}。  7 \index{命令!textasciitilde@\mn{textasciitilde}}  8 这两个字符在URL中也经常出现,要特别小心。  9  10 C/C++代码的标识符中经常出现下划线“_”,例如 \fn{boost::shared_ptr}、 11 \fn{random_\linebreak[0]shuffle} 等。 12 为了避免每次都转义,可以使用 \fn{underscore} 宏包, 13 将下划线变为普通字符。 14 \index{宏包!underscore@\fn{underscore}} 15 注意这里 \fn{random_\linebreak[0]shuffle} 在行尾断字, 16 那么下划线之后不应该出现连字号“-”, 17 因此应写为 \verb|random_\linebreak[0]shuffle|。 18  19 \section{斜体} 20 按照排版规范,数学变量名和(非标准)函数名应该用斜体, 21 常量、单位、标准函数名应该用正体。 22 例如:%$\footnote{c是真空中的光速,k是Boltzmann常数。}: 23 $n$-body 问题、%$E = m \mathrm{c}^2 24 %$V_\mathrm{T} = \frac{\mathrm{k} T}{q}$、 25 $\sin x = (\mathrm{e}^{\mathrm{i}x} - \mathrm{e}^{-\mathrm{i}x})/2\mathrm{i}$、 26 5\textmu s。 27 快速排序 $n$ 个元素的数度的平均时间复杂度是 $O(n \log n)$。 28 通过 TCP 发送 $n$ 字节的消息, 29 接收方收到这 $n$ 个字节的事件可能性有 $2^{n-1}$ 种 30 \footnote{在 $n-1$ 个字节间隙中,依次插入 $0, 1, \ldots, n-1$ 个“隔板”, 31 一共有 $C_{n-1}^0 + C_{n-1}^1 + \cdots + C_{n-1}^{n-1} = 2 ^ {n-1} $ 种情况。}。 32  33 \section{列表} 34 \LaTeX 默认的列表环境(\fn{itemize} 和 \fn{enumerate})是为多行文字准备的, 35 因此上下间距较大。我一般使用 \fn{enumitem} 宏包来重新定义列表环境, 36 并且定义几个简单的命令来使用它(\mn{begindot} 和 \mn{myenddot},\mn{beginnum} 和 \mn{myendnum})。 37 \index{宏包!enumitem@\fn{enumitem}} 38 \begin{Code} 39 \newcommand\begindot{\begin{itemize} 40 [itemsep=2pt plus 2pt minus 2pt,% 41 topsep=3pt plus 2pt minus 2pt,% 42 parsep=0pt plus 2pt minus 2pt]} 43 \newcommand\myenddot{\end{itemize}} 44 \end{Code} 45  46 \begin{Code} 47 \newcommand\beginnum{\begin{enumerate} 48 [itemsep=2pt plus 2pt minus 2pt,% 49 topsep=3pt plus 2pt minus 2pt,% 50 parsep=0pt plus 2pt minus 2pt]} 51 \newcommand\myendnum{\end{enumerate}} 52 \end{Code} 53  54 \section{章节标题} 55 章节标题无标点,因此 \S \ref{sec:whyTypesetting} 是错的。 56 \fn{ctex} 宏包默认会把章\mn{chapter} 和节\mn{section} 的标题居中, 57 这种样式显得很古板,章标题可以靠右,节标题和小节标题均靠左。 58 参见本文的\fn{format.cls} 文件。 59  60 \subsection{编号} 61 通常单个小节不编号,因此 \S \ref{subsec:noChineseItalic} 和本小节是错的。 62 应要改用\mn{subsection*} 命令。 63  64 \section{图表编号} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 65  66 我不使用浮动环境,因此自己定义了 \mn{figcaption} 和 \mn{tabcaption} 命令来为图表编号。 67 图的标题位于下方,按章编号(图1-1、图1-2、图2-1 等等)。 68 例如 69  70 \begin{center} 71 \includegraphics{sp0.eps}\ 72 \figcaption{\fn{shared_ptr} 的数据结构}\label{fig:sharedptr} 73 \end{center} 74  75  76 表的标题位于上方,按章编号(表1-1、表1-2、表2-1 等等)。 77 例如 78  79 \begin{center} 80 \tabcaption{水平空格命令的长度} 81  82 \vspace{1ex} 83 \begin{tabular}{ccl} 84 \hline 85 \textbf{命令} & \textbf{长度} & \textbf{用途}\ 86 \hline 87 \mn{quad} & 10pt & 图表编号与图表标题之间的全角空格\ 88 \mn{,} & 1.67pt & 千分空,例如 65\,536\ 89 \hline 90 \end{tabular} 91 \end{center} 92  93 \section{脚注} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 94  95 \subsection{编号} 96 \LaTeX 默认是按章重置脚注编号, 97 这么如果重印的时候需要增加一个脚注, 98 势必会影响后续页码,这是 \mybooktitle 排版的一个教训。 99 因此我意识到脚注应该是按页重置,但是 \verb|\@addtoreset{footnote}{page}|100 无效,必须使用 \fn{footmisc} 宏包的 \fn{perpage} 选项,101 例如 \sfn{\bs usepackage[perpage]\{footmisc\}}。102 \index{宏包!footmisc@\fn{footmisc}}103 104 \LaTeX  默认的脚注编号是数字,这有时会造成误解。105 例如给长度单位pt添加脚注,正文中可能会出现“pt\textsuperscript{2}”,106 让人误以为是面积单位,因此可以改用带圈数字。107 108 \subsection{置底}109 \LaTeX  默认的脚注位置不是固定置底,而有可能随页面内容而浮动。例如 \myurl{footnote-middle.tex}。110 111 \vspace{1ex}112 \centerline{\fbox{\includegraphics[page=1]{footnote-middle.pdf}}%113 \quad\fbox{\includegraphics[page=2]{footnote-middle.pdf}}}114 115 使用 \fn{footmisc} 宏包的 \fn{bottom} 选项之后,116 脚注置底。见 \myurl{footnote-bottom.tex}。 \nopagebreak117 118 \vspace{1ex}119 \centerline{\fbox{\includegraphics[page=1]{footnote-bottom.pdf}}%120 \quad\fbox{\includegraphics[page=2]{footnote-bottom.pdf}}}121 122 \section{参考文献}123 技术书籍不是学术著作,可不必使用 BibTeX 工具,直接按出版社的格式要求排版参考文献即可。

 

chapExperience.tex

 1 \chapter{经验} 2  3 \section{分段与分页} 4 \myurl{http://www.economics.utoronto.ca/osborne/latex/PMAKEUP.HTM} 5  6 \mn{nolinebreak} 7 \index{命令!nolinebreak@\mn{nolinebreak}} 8  9 \mn{nopagebreak}10 \index{命令!nopagebreak@\mn{nopagebreak}}11 12 代码的断页,尽量在函数定义之间的空行处断页,13 并且消去第二页页首的空行。必要时可以拆为两个\mn{begin\{Code\}/\bs end\{Code\}}块。14 15 \section{阿拉伯数字}16 17 飞流直下3000尺,疑似银河落9天。18 19 \section{全角与半角}20 21 注意 Word 和 Live Writer 会替换字符,例如把减号 - 替换为连字号 --,22 如果用 Word 写初稿,或者用 Live Writer 发博客,再整理成书,则有可能遇到字符缺失。23 可以考虑禁用自动替换功能。

 

chapTools.tex

  1 \chapter{工具}  2 《Linux多线程服务端编程——使用muduo C++网络库》这本书是我自己用 \LaTeX 排版的,  3 在排版过程中也积累了一些小工具,本章把它们一一展示出来。  4 不少工具都直接基于开源的 iText PDF 库,可从 \myurl{http://itextpdf.com/} 下载,  5 我用的是 \fn{itextpdf-5.3.0.jar}。另外一些则用到了 Ghostscript,  6 可直接用 \fn{apt-get} 安装。  7   8 \subsubsection{下载}  9  10 Groovy 版本位于 \myurl{https://github.com/chenshuo/typeset/tree/master/tools} 11  12 Java 版本位于 \myurl{https://github.com/chenshuo/recipes/tree/master/java/pdf} 13  14 各个工具的输出示例位于 \myurl{http://vdisk.weibo.com/s/kT4fL} 15  16 \section{统计中文字数} 17 \LaTeX 没有像 Word 那样自带中文字数统计功能,加上 \LaTeX 源文件中有许多控制字符, 18 不能通过文件大小准确获知其中有多少汉字。 19 为此我用C写了一个统计中文字数的小工具,名为 \fn{cwc},即 chinese word counter, 20 这个工具可以处理GBK、Unicode (UCS-2)、UTF-8这三种编码的文件。 21 源码位于 \myurl{https://github.com/chenshuo/recipes/tree/master/utility}。 22 以下是一次运行的输出。 23 \index{工具!cwc@\fn{cwc}} 24 \begin{Code} 25 $ cwc *.tex 26     26    368    1729 abstract.tex (UTF-8) 27    149   1780    7021 chapEnvironment.tex (UTF-8) 28     24    132     737 chapExperience.tex (UTF-8) 29    262   2304   12739 chapLayout.tex (UTF-8) 30     91    671    3977 chapStyle.tex (UTF-8) 31    154   1257    6720 chapTools.tex (UTF-8) 32     12      6     192 title.tex (UTF-8) 33     41     69     963 typeset.tex (UTF-8) 34    759   6587   34078 total 35   行数   字数   字节数 36 \end{Code} 37  38 \section{PDF内容对比(dif\/f\,)} 39 在书籍出版之后,每次印刷都可能修订一些内容, 40 在把新的PDF文件交给出版社的同时,也要通知哪些页码有改动, 41 方便出版社印刷。 42 由于PDF是二进制格式,无法直接对比新旧PDF文件, 43 于是我写了一个 \fn{diffpdf.sh} 小工具用来找出哪些页面的内容有改动。 44 这个工具的思路很土,就是先用 Ghostscript 把PDF按页渲染为多个PNG文件, 45 然后用 \fn{diff(1)} 比较新旧两个PDF渲染出来的这些PNG文件是否相同。 46 然后用 Python 脚本(\fn{diffpng.py})将两个PNG文件的不同之处用红色高亮显示出来。例如: 47 \index{工具!diffpdf@\fn{diffpdf.sh}} 48 \index{工具!diffpng@\fn{diffpng.py}} 49  50 \vspace{1ex} 51 \centerline{\includegraphics{diffpng.png}} 52  53 \section{PDF截取} 54 为了在网上公布样张,我需要从整书中截取一部分页码, 55 另存为PDF文件,这用 \fn{pdftk} 最方便了。 56 例如 57 \index{工具!pdftk@\fn{pdftk}} 58  59 \begin{Code} 60 pdftk book.pdf cat 1-16 output preamble.pdf     # 前言和目录 61 pdftk book.pdf cat 19-46 output chap1.pdf       # 第1章 62 pdftk book.pdf cat 577-end output appendix.pdf  # 附录 63 \end{Code} 64  65  66 \section{PDF页码编号} 67  68 \LaTeX 的 \fn{hyperref} 宏包可以为生成的PDF设置“逻辑页码”, 69 例如前言目录用罗马数字,正文用阿拉伯数字。 70 不过经过 \fn{pdftk} 截取之后就失效了。 71 为此我编写了 \fn{pagenum.groovy} 工具,用来添加逻辑页码。例如 72 \index{工具!pagenum@\fn{pagenum.groovy}} 73  74 \begin{Code} 75 pagenum.groovy ‘1e,3r‘ preamble.pdf  # 第1、2页是封面,没有页码;第3页开始用罗马数字 76 pagenum.groovy ‘1n3‘   chap1.pdf     # 第1章第1页的逻辑页码是3 77 pagenum.groovy ‘1n561‘ appendix.pdf  # 附录第1页的逻辑页码是561 78 \end{Code} 79  80  81 \section{PDF剪裁(crop)} 82 \label{sec:pdfcrop} 83 为了充分利用屏幕空间,也便于在电子阅读器(iPad、Kindle)上阅读校对书稿, 84 我一般会把PDF剪裁为版心大小。 85 例如下面左图是原始PDF,为纸张大小;右图是按固定Crop Box剪裁之后的版心。 86 \mpar{固定剪裁} 87 \index{工具!crop@\fn{crop.groovy}} 88  89 \vspace{1ex} 90 \centerline{\includegraphics[scale=0.4]{crop.png}} 91  92 剪裁工具是 \fn{crop.groovy},设好 \sfn{CLASSPATH} 环境变量后可直接在命令行运行。 93 其核心是根据版心和纸张尺寸算出左下角和右上角左边,然后剪裁每一页。 94 这个工具不管PDF的内容。 95  96 如果需要根据页面内容剪裁PDF,\mpar{按内容剪裁} 97 可以使用Heiko Oberdiek编写的 \fn{pdfcrop} 工具,地址如下: 98 \index{工具!pdfcrop@\fn{pdfcrop}} 99 100 \begindot101 \item \myurl{http://www.ctan.org/tex-archive/support/pdfcrop}102 \item \myurl{http://code.google.com/p/pdfcrop2/}103 \myenddot104 105 %\subsection106 107 108 \section{PDF拼接(two-up)}109 有时候想在宽屏上同时阅读左右两页的书稿,除了可以用PDF阅读器本身的多页显示功能,110 我还常常自己做二合一(two-up)。111 这样得到的PDF也可以打印出来看,既节约纸张,而且与原稿是1:1大小。生成的PDF效果如下图。112 \index{工具!twoup@\fn{twoup.groovy}}113 114 \vspace{1ex}115 \centerline{\includegraphics[scale=0.4]{twoup.png}}116 117 二合一工具是 \fn{twoup.groovy},其核心是算出左右两页在合页中的起始坐标。118 119 \section{PDF小册子(booklet)}120 \index{工具!booklet@\fn{booklet.groovy}}121 有时候我会把一章的内容打印出来,装订成一本小册子,这样读起来有翻书的感觉。122 为了节约纸张,在打印之前要拼版,这样一张纸双面能打印4个页码。123 例如8页内容可以打印到两张A4纸上:124 125 \vspace{1ex}126 \centerline{\includegraphics{booklet-1.eps}\qquad\includegraphics{booklet-2.eps}}127 128 对折、叠好,骑缝订之后就是一本小册子了。129 130 \begin{center}131 第一张纸的正反两面打印:\nopagebreak132 133 \vspace{1ex}134 \includegraphics{booklet-3.eps}\qquad\includegraphics{booklet-4.eps}135 136 \vspace{1em}137 第二张纸的正反两面打印:138 139 \vspace{1ex}140 \includegraphics{booklet-5.eps}\qquad\includegraphics{booklet-6.eps}141 \end{center}142 143 小册子工具是 \fn{booklet.groovy},其核心是算出每面纸应该放哪两个页码的原始内容。144 145 装订这种小册子要用骑缝订,可用旋转订书机146 \footnote{\myurl{http://www.amazon.cn/dp/B0080AF0FM} \quad \myurl{http://product.dangdang.com/product.aspx?product_id=1141537002}}。147 一本小册子一般应该控制在10页纸左右,即40个页码,再厚就订不透了。148 149 \section{PDF字体嵌入}150 \label{sec:embedFont}151 出版社拿到作者提供的终稿PDF之后,如果没有进一步修改,就会准备印刷了。152 第一步是让出片公司用激光照排机打印出胶片,即“出片”。153 这种公司使用的操作系统很可能与作者不同,特别是安装的字体可能不一致。154 为了防止出现文字乱码或字体错乱,出片公司一般都会要求提供嵌入全部字体的PDF文件。155 156 一个办法是修改 Ghostscript 的配置文件,让默认字体全部嵌入157 \footnote{\myurl{http://wand.net.nz/\textasciitilde iam4/latex.html}}。例如:158 \begin{Codex}[label=/usr/share/ghostscript/???/Resource/Init/gs_pdfwr.ps]159 /.standardfonts [160 %  /Courier /Courier-Bold /Courier-Oblique /Courier-BoldOblique161 %  /Helvetica /Helvetica-Bold /Helvetica-Oblique /Helvetica-BoldOblique162 %  /Times-Roman /Times-Bold /Times-Italic /Times-BoldItalic163 %  /Symbol /ZapfDingbats164 ] readonly def165 \end{Codex}166 167 还有一个办法是用 Adobe Acrobat Reader 找出 PDF 中没有嵌入的字体,168 再用 iText 将字体文件嵌入,例子见 \myurl{http://itextpdf.com/examples/iia.php?id=288}。

 

chapDiagram.tex

 1 \chapter{插图} 2  3 尽量用矢量图,少用点阵图(屏幕截图只适合用于step-by-step介绍软件操作)。 4  5 在生成 {} .eps 或 {} .pdf 图片的时候,最好也同时嵌入所用的字体, 6 这样最后生成的书籍 PDF 的字体是全部嵌入的。 7 事后补救的办法见 \S \ref{sec:embedFont}。 8  9 \section{绘图软件}10 11 \mybooktitle 的排版过程中我使用了多种绘图工具,这里简单列举一下。12 这里举的插图例子大多数可以在样章 \footnote{\myurl{http://vdisk.weibo.com/s/mtupb}} 第6章中找到。13 以下这些软件都可以生成矢量图(EPS或PDF文件),印刷效果较好。14 15 \subsection{Graphviz}16 适合绘制依赖关系图,包括 \fn{\#include} 头文件的关系图(书p.132图~6-1)、17 简单的 class 继承关系图等。18 19 优点:自动布局。20 21 缺点:如果对自动布局不满意,不易手工调整。22 \subsection{gpic}23 24 适合绘制线框图,例如数据结构。本文的图~\ref{fig:sharedptr} 就是用 gpic 绘制的。25 gpic 可参考 Brian W. Kernighan 的 《PIC---A Graphics Language for Typesetting, User Manual》26 和 Eric S. Raymond 的《Making Pictures with GNU PIC》。27 28 缺点:无法输入中文。29 30 \subsection{METAPOST}31 适合绘制函数图像,例如书p.349图~9-532 33 \subsection{Visio}34 适合绘制较复杂的 class diagram(书p.132图~6-2),sequence diagram(例如书p.170图~6-12)。35 需要安装     36 Visio Stencil and Template for UML 2.237 \footnote{http://www.softwarestencils.com/uml/index.html}。38 39 可以输入中文,可以可视化编辑,可以导出为 PDF 文件,经过剪裁去掉白边40 \footnote{用 \fn{pdfcrop} 工具 \S \ref{sec:pdfcrop} 按内容剪裁。}41 之后可以方便地嵌入 \LaTeX 文档。42 43 缺点:多幅内容相近的图片不易统一修改,例如《为什么多线程读写 \fn{shared_ptr} 要加锁?》%44 \footnote{\myurl{http://chenshuo.googlecode.com/files/CppEngineering.pdf}}45 中绘制的多幅 \fn{shared_ptr} 内部指针变化图。46 47 \subsection{Word}48 适合复杂的表格,例如书p.161表~6-149 可以输出为PDF文件,剪裁之后以插图的方式嵌入 \LaTeX 文档。50 51 \subsection{Excel}52 适合绘制点数较少的性能数据图($x$-$y$ 坐标系),例如书p.147图~6-353 54 \subsection{Gnuplot}55 适合绘制点数较多的性能数据图,例如书p.150图~6-656 57 %\section{图片工具}58 %\subsection{pdfcrop}59 %\subsection{ps2eps}60 %\subsection{eps2png}61 62 \section{待续……}

 

用LATEX 排版编程技术书籍的一些个人经验模板