PGF 制图

很久都没仔细看看 PGF 的文档了,这次为了画些东西决定还是继续研究一下。首先是个流程上的东西,很重要的就是使用 preview 帮助 pdfLatex 进行 crop(见这里)。不知道什么时候 XeLaTeX 才能被 preview 支持。下面是一个简单的代码

\documentclass{article}
\usepackage{tikz}
\usepackage[active, pdftex, tightpage]{preview}
\tikzstyle{vis}=[circle, draw=blue!50, fill=blue!20, thick]
\tikzstyle{lat}=[rectangle, draw=black!50, fill=black!20, thick]
\PreviewEnvironment{tikzpicture}
\begin{document}
\begin{tikzpicture}
  \node[lat] (bt)  at (0, 0)      {$\beta_t$} ;
  \node[lat] (bt1) at (-1.5, 0)   {$\beta_{t-1}$} ;
  \node[lat] (mt)  at (0, 1.5)    {$\mu_t$} ;
  \node[lat] (mt1) at (-1.5, 1.5) {$\mu_{t-1}$} ;
  \node[vis] (yt)  at (0, 3)      {$y_t$} ;
  \node      (ot)  at (-1.5, 3)   {$o_t$} ;
  \begin{scope}[->]
    \draw (mt1) -- (mt) ;
    \draw (bt1) -- (bt) ;
    \draw (bt)  -- (mt) ;
    \draw (mt)  -- (yt) ;
    \draw (ot)  -- (yt) ;
  \end{scope}
\end{tikzpicture}
\end{document}

生成的图片如下:

EMP

下面稍微总结一下现在 PGF 提供的一些很有用的功能:

  • arrow tip lib,可以用 \usetikzlibrary{arrows},提供了各式箭头
  • automata lib,方便绘制自动机,可以用 \usetikzlibrary{automata}
  • background lib,方便为背景添加颜色或者框之类的东西,\usetikzlibrary{backgrounds}
  • calendar,方便绘制日历,\usetikzlibrary{calendar}
  • chains,方便绘制排成一列的东西,\usetikzlibrary{chains}
  • decoration,方便在线条上加一些装饰性的曲线,显得自然一些,\usetikzlibrary{decorations.xxx}
  • entity relationship,方便画一些 entity 之间的关系这类线框图,\usetikzlibrary{er}
  • fading,方便画渐变色,\usetikzlibrary{fadings}
  • fitting,方便放置一个 node,给出 fitting 的条件即可,\usetikzlibrary{fit}
  • matrix,方便画表格或者矩阵类似的结构,\usetikzlibrary{matrix}
  • mindmap,方便画概念的树状结构图,\usetikzlibrary{mindmap}
  • paper folding,方便画折纸,\usetikzlibrary{folding}
  • pattern,填充的 pattern,\usetikzlibrary{pattern}
  • petri net,\usetikzlibrary{petri}
  • plot handlers,没看明白怎么用,\usetikzlibrary{plothandlers}
  • plot mark lib,画某些数据图使用的 marks,\usetikzlibrary{plotmarks}
  • shadow,为某些图形增加 shadow,\usetikzlibrary{shadows}
  • shape,提供了更丰富的 shape,\usetikzlibrary{shape.xxx}
  • topath,简化了曲线等绘制,\usetikzlibrary{topaths}
  • through lib,在绘制形状的时候能够要求通过某点,\usetikzlibrary{through}
  • tree lib,绘制树状结构 \usetikzlibrary{trees}
  • pgfplots 是一个额外的包,提供数据图形的绘制,甚至可以绘制函数,这玩意用好了是不是以后就用 matlab 生成数据就行了… 似乎比 gnuplot 还要好用一点… 加上 pgf 还能 render svg…

啊,好吧,个么我就开始用这个玩意画画吧 🙂

——————
And Abraham drew near, and said, Will you also destroy the righteous with the wicked?

PGF 制图

MathJax

几曾何时在 HTML 里面嵌入数学公式都只能依赖于 offline rendering 图片,然后做一些替换工作将产生的图片放到 dom tree 里面。前几天发现 debian 里面出来个叫 mathjax 的包觉得挺有意思的就装了一个,发现现在 CSS 之类的实在是太牛了。不多说先给个例子

<html>
<head>
<script type="text/javascript" src="mathjax/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
</head>
<body>
<h2>MathJax</h2>
I am always curious about how to typeset mathematical formulaes in web pages. Now we have
MathJax. Please take a look at the inline equation, such as \( E = mc^2\) or between line
equations:
\begin{equation}
  \sum_{i = 1}^\infty \frac{1}{i^2} = \frac{\pi^2}{4}.
\end{equation}
</body>
</html>

大概的效果如下:

mathjax 示例

可能很神奇的是 mathjax 一不要后端 latex 编译 gs 渲染什么的,二还能放大(什么,你说可以 zoom in 没有锯齿?嗯,对,只是某些浏览器上可能会有锯齿)。分析了一下大概是这样做到的,首先 mathjax 会尝试使用 CSS3 的特性直接从服务器上获得显示需要的字体,如果成功就直接使用 open type 的字体渲染公式(因此是矢量的哦);如果浏览器不支持这种特性,则会使用自带的 png。换言之似乎 mathjax 实现了 LaTeX 和 amsmath 的基本功能。只是不知道是不是这个做法将会很难 scale 到如此丰富的 LaTeX packages 上。

在 local machine 上直接访问可能会有点问题,特别是 firefox,但是 chrome 不会存在问题。有兴趣玩玩的话可以去其主页看看,那边的例子也更多。当然 MathJax 还对 MathML 有支持,不过其实个人感觉 MathML 现在用的太少了,还是“野”路子用得多。

——————
And the LORD said, Behold, the people is one, and they have all one language; and this they begin to do: and now nothing will be restrained from them, which they have imagined to do.

MathJax

毕业论文的 xelatex 设计

嗯,不是模板… 给个大致做法介绍。

\documentclass[a4paper, 12pt, twoside, openright]{book}
\input{config}
\setlength\glsdescwidth{.75\linewidth}
\loadglsentries{thesis-acronym}
\setcitestyle{numbers}
\renewcommand\baselinestretch{1.38}

这部分导言将公共的部分放在 config.tex 中,设定了 glossaries 宏包中 acronym 那个 longtable 的宽,读入 acronym,通过 natbib 设定参考文献的引用格式,设定行距。最后有两段

\backmatter
\bibliographystyle{fudannat}
\bibliography{refs}
\printglossary[type=\acronymtype, style=long]
\printindex

\nocitephd{blah blah...}
\bibliographystylephd{fudannat}
\bibliographyphd{refs}
\include{thesis-acknowledge}

通过 multibib 产生的两个参考文献,其中一个是正文引用的,另外一个叫 phd,是指研究生期间发表的论文,其中的格式 fudannat 是修改自 natbib 的 plainnat.bst。

下面介绍 config.tex 里面的东西。这里面包含两部分,一部分是 low.tex,较低层次的命令,主要是对 book.cls 做出的修改。

\renewcommand\@chapapp[1]{第#1章}

重新定义了这个命令,方便产生“第 1 章”这种目录、页眉以及章标题(如果你想的话),因此需要修改 book.cls 里面 \chaptermark、\@chapter、\@makechapterhead 与 \@schapter 这些命令,后面两个因为我想做花一点,就没这样改,而是从 quotchap.sty 里面抄了一段

%% from quotchap.sty
\let\size@chapter\huge
\providecommand*{\chapterheadstartvskip}{\vspace*{1.8\baselineskip}}
\providecommand*{\chapterheadendvskip}{\vspace{1.2\baselineskip}}

\newenvironment{savequote}[1][7cm]{%
  \begin{lrbox}{\@quotebox}
    \begin{minipage}[t]{#1}\footnotesize\slshape
      \ignorespaces}{%
      \unskip\end{minipage}\end{lrbox}
  \global\setbox\@quotebox\copy\@quotebox
  \global\let\@printcites\@iprintcites
  \ignorespacesafterend}
\newcommand{\qauthor}[1]{%
  \par\smallskip
  {\raggedleft\upshape--- #1\qquad\hbox{}\par}\bigskip}
\newsavebox{\@quotebox}
\let\@printcites\relax
\renewcommand\chapter{%
  \if@openright\cleardoublepage\else\clearpage\fi
  \thispagestyle{plain}%
  \global\@topnum\z@
  \@printcites
  \@afterindentfalse
  \secdef\@chapter\@schapter}
\renewcommand{\@makechapterhead}[1]{\chapterheadstartvskip%
  {\size@chapter{\bf\raggedleft
      {% select font
        \chapheadnumfont\color{violet}
        \ifnum \c@secnumdepth >\m@ne%
        \if@mainmatter\thechapter%
        \fi\fi
        \par\nobreak}%
      {\raggedleft\advance\leftmargin10em\interlinepenalty\@M #1\par}}
    \nobreak\chapterheadendvskip}}
\renewcommand{\@makeschapterhead}[1]{%
  {\let\c@secnumdepth\m@ne\@makechapterhead{#1}}}
\newcommand*{\@iprintcites}{%
  \vbox to\z@{\copy\@quotebox\vss}
  \global\let\@printcites\relax}

嗯这样每章前面可以很酷的装 b 了,比如

\begin{savequote}
  Choose beliefs that serve your soul - choose beliefs that serve the grander dream of who you choose to be.
  \qauthor{Joy Page}
\end{savequote}
\chapter{信仰是啥}

然后我喜欢 header 用 small caps 和仿宋,所以需要修改 \ps@headings。让表格统一用 \small,

%% smaller fonts
\renewenvironment{table}
               {\@float{table}\small}
               {\end@float}
\renewenvironment{table*}
               {\@dblfloat{table}\small}
               {\end@dblfloat}

这些都必须在 \makeatletter 和 \makeatother 之间啦。

其余的就是一些比较高层次的调用了,如

\usepackage[a4paper, twoside=true, top=1in, bottom=1in, left=1.25in, right=1.25in]{geometry}

设置页面大小,使用 glossaries 的 acronym 功能

\usepackage{makeidx}
\usepackage[nonumberlist, toc, acronym]{glossaries}
\newcommand\engchs[2]{\emph{#1}(#2)}
\renewcommand{\newacronym}[4][]{%
  \newglossaryentry{#2}{type=\acronymtype,%
  name={#3},description={#4},text={#3},%
  descriptionplural={#4\acrpluralsuffix},%
  first={#3(#4)},plural={#3\acrpluralsuffix},%
  firstplural={\@glo@descplural\space (\@glo@plural)},%
  #1}}

最后一个 \renewcommand 也是 low.tex 里面的,为的是用我希望的格式 format acronym 第一次出现的样式,默认是 full name (acronym) 的写法,我喜欢在 full name 里面加入中文,所以这里颠倒过来,产生的是 acronym (full name) 的样子。这两个宏包不必说

%% links
\usepackage{tocbibind}
\usepackage{hyperref}

然后是数学相关的

\usepackage{amsmath, amssymb, amsthm, bm, mathrsfs}
\usepackage{mathtools}
\usepackage{mathopts}

这里的 mathopts 是自己写的一个常用数学符号定义,比如 \R 之类的,免得每次都要定义,麻烦… 然后是 xelatex 的字体

%% fonts with xelatex
\usepackage{fontspec, xunicode, xltxtra}
\usepackage[CJKtextspaces, CJKmathspaces, CJKnumber]{xeCJK}
%% xelatex configuration
\defaultfontfeatures{Mapping=tex-text}
\XeTeXlinebreaklocale "zh"
\frenchspacing
\setmainfont[Numbers=Lining]{Adobe Jenson Pro Display}
\setCJKmainfont[BoldFont={SimHei}, ItalicFont={STKaiti},%
  SmallCapsFont={STFangsong}]{SimSun}
\newfontfamily\chapheadnumfont[Scale=2.5]{Helvetica LT Std}

嗯,我不是好同学,用了不少商业字体。浮动体

%% float
\usepackage{float, rotating}
\floatplacement{figure}{tpb}
\floatplacement{table}{tbp}

这里用 float 的功能重新定义了 table 和 figure 默认的浮动顺序,个人爱好啦;然后 rotating 的 sidewaystable 可以把很宽的表格横过来放。之后是表格

%% color
\usepackage[table]{xcolor}
\xglobal\definecolor{tabhead}{cmyk}{0,0,0,0.3}
\newcommand\headcolor{\rowcolor{tabhead}}
\newcommand\MCH[3]{\multicolumn{#1}{>{\columncolor[named]{tabhead}}#2}{#3}}
\newcommand\settabularcolor[1][2]{\rowcolors{#1}{black!10}{}}

这里用了 xcolor 的 colortbl 功能,在每个表格前使用 \settabularcolor 产生效果,\headcolor 设置表头,\MCH 是 \multicolumn 的简化版(带颜色)。为了方便设定表格的头一根线和最后根,使用

%% tabular
\usepackage{booktabs}
\belowrulesep=0ex
\aboverulesep=0ex

中的 \toprule 和 \bottomrule。设定图表标题格式

\usepackage[labelfont = bf, font = footnotesize,%
            labelsep = period, format = hang]{caption}

如果喜欢更紧凑的列表,可以用

\usepackage{paralist}

中的 compactitem 等,我比较喜欢 inparaenum 这种东西。参考文献,

\usepackage[square]{natbib}
\usepackage{multibib}
\newcites{phd}{攻读博士期间的研究成果}

然后插图,

\usepackage{subfigure}
\usepackage{graphicx}
\usepackage{tikz}

\graphicspath{{img/}}

最后一个可以把图片放在 img 子目录里面,而 \includegraphics 的时候就不必写路径了。喜欢写算法的,

\usepackage{algorithm, algorithmic}
\floatname{algorithm}{算法}
\floatplacement{algorithm}{thb}

中文文档么,这些名字要改改

\renewcommand\contentsname{目\hspace{2em}录}
\renewcommand\indexname{索\hspace{2em}引}
\renewcommand\tablename{表}
\renewcommand\thetable{\arabic{chapter}.\arabic{table}}
\renewcommand\figurename{图}
\renewcommand\thefigure{\arabic{chapter}.\arabic{figure}}
\renewcommand\appendixname{附录}
\renewcommand\proofname{证明}
\renewcommand\bibname{参考文献}

然后改一下目录里面章的样式,

\usepackage{titletoc}
\titlecontents{chapter}[0em]{\bfseries}{\thecontentslabel\hspace{2em}}{}{\hfill\contentspage}

好了… 就到这里啦,喜欢玩的人继续摸索吧。那个 fudannat.bst 就不写了,TeX 版上贴过。

——————-
The cobweb pretends to catch dewdrops and catches flies.

毕业论文的 xelatex 设计