月度归档:2013年06月

Sphinx+reStructuredText+Latex生成中文PDF

Sphinx+reStructuredText生成HTML文档没什么好说,很容易上手。但是要生成PDF,并且完美支持中文,就要折腾一番了。有个rst2pdf软件可以直接转,但是中文支持不好。目前最好的解决方案是通过Latex做中转,整个流程的本质是先将.rst转换成Latex文件(*.tex),再通过xelatex命令将.tex文件转成PDF。

把整个步骤记录一下:

环境:Mac OS Moutain Lion 10.8.2, Texlive 2013, Sphinx v1.2b1。

一、 按Sphinx目录结构编写reST源文件。如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ tree
.
├── Guardfile
├── Makefile
├── README.rst
├── make-livehtml.bat
├── make.bat
└── source
    ├── _templates
    │   └── download.html
    ├── _themes
    │   └── default_mod
    │       ├── static
    │       │   └── default_mod.css_t
    │       └── theme.conf
    ├── conf.py
    └── index.rst

二、 修改conf.py文件,配置一些Latex信息。找到latex_elements节点,修改preamble属性,替换后的配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# -- Options for LaTeX output -------------------------------
 
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',
 
# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',
 
# Additional stuff for the LaTeX preamble.
#'preamble': '',
 
'classoptions': ',english',
'inputenc': '',
'utf8extra': '',
 
'preamble': '''
\usepackage{xeCJK}
\usepackage{indentfirst}
\setCJKmainfont[BoldFont=SimHei, ItalicFont=KaiTi_GB2312]{SimSun}
\setCJKmonofont[Scale=0.9]{Droid Sans Mono}
\setCJKfamilyfont{song}[BoldFont=SimSun]{SimSun}
\setCJKfamilyfont{sf}[BoldFont=SimSun]{SimSun}
''',
}

主要是指定字体,比如\setCJKmainfont[BoldFont=SimHei, ItalicFont=KaiTi_GB2312]{SimSun}表示粗体用SimHei字体(黑体),斜体用KaiTi_GB2312(楷体)。(这段配置网上找来的,具体含义得看Latex手册, -_-!)

三、 make latex,在build/latex目录下生成latex源文件。

1
2
3
4
5
6
7
$ make latex
sphinx-build -b latex -d build/doctrees   source build/latex
Running Sphinx v1.2b1
loading translations [zh_CN]... done
loading pickled environment... done
building [latex]: all documents
...

四、 编译.tex文件,生成PDF。

1
2
3
4
5
6
$ cd build/latex
$ xelatex test.tex
This is XeTeX, Version 3.1415926-2.5-0.9999.3 (TeX Live 2013)
 restricted \write18 enabled.
...
Output written on test_v1.0.pdf (29 pages).

执行xelatex命令后,会在当前目录生成同名的PDF文件。

以上是非常顺利情况下的四个步骤,实际上不会这么顺利的,可能会出现以下问题:

1. xelatex命令找不到。xelatex是Texlive套件中的一个命令,先去Texlive网站上下载最新版。默认安装路径在/usr/local/texlive,大概3.4G。再把xelatex命令所在目录加到$PATH环境变量:

1
2
3
$ vim ~/.bashrc
PATH=$PATH::/usr/local/texlive/2013/bin/x86_64-darwin
$ source ~/.bashrc

2. 字体找不到。步骤二中配置了字体,如果不出意外,步骤四编译.tex文件时一定会出现找不到字体的错误提示。例如:

1
2
3
4
5
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! fontspec error: "font-not-found"
! The font "SimHei" cannot be found.
! See the fontspec documentation for further information.
! For immediate help type H <return>.

意思是SimHei字体找不到。通过fc-list命令可以查看当前系统已安装的字体:

1
2
3
4
$ fc-list :lang-zh
$ fc-list :lang-zh | grep SimHei
$ fc-list :lang-zh | grep KaiTi_GB2312
/Users/fcj/Library/Fonts/楷体_GB2312.ttf: 楷体_GB2312,KaiTi_GB2312:style=Regular

安装步骤二中设置的SimHei和KaiTi_GB2312等字体后,再执行fc-cache,刷新下字体缓存,步骤四一般就没什么问题了。

3. 第一次跑xelatex命令生成出来的PDF貌似没有目录,要再跑一遍才行。原因不明。

Latex生成的PDF格式很专业,很有学术范,今后API文档和用户手册准备都用Sphinx+reStructuredText写,再转成PDF发布。

--EOF--

git hooks

git允许用户在执行一条git命令的前后通过脚本的方式进行一些预处理或善后工作,这些脚本称为hook,也就是钩子。钩子文件统一存放在在.git/hooks目录下,一些常用的钩子介绍在这里可以找到。git hooks配合git config,可以构建一个工作流,非常方便。

比如有个场景,一个仓库下有多个分支,每个分支依赖这不同的配置文件,里面的配置项在不同的开发机上不同(IP,MAC地址等),当有多个开发人员协作开发时,会因为别人的一次提交覆盖自己本地仓库里的配置(加.gitignore也解决不了,git clone时会缺失这个文件)。这时候就可以利用post-checkout这个钩子,每次执行git checkout命令后,post-checkout中的shell脚本会读取本机配置,写入项目配置文件。

一个简单的钩子例子:

1
2
3
#!/bin/sh
 
echo $(git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* .*/\1/')

将上述脚本保存为post-checkout,放在.git/hooks目录下,今后每次执行git-checkout命令都会在控制台显示当前分支名称。

--EOF--

『淘宝技术这十年』

『淘宝技术这十年』读『淘宝技术这十年』有几点感受及收获:

1. 阿里(淘宝、支付宝)的花名是我认为的最能代表其公司文化的载体,一个个著名的武侠人物事迹被重新演绎,大牛工程师们赋予了这些名字不同的意义。这本半技术半休闲的书能看得如此酣畅淋漓,得部分归功于这些拉风的花名。不过,出名的武侠人物基本上都被早期员工占用了,现在入职的基本上很少能注册到著名ID了吧。

2. 淘宝的技术在业内已是翘楚,这是业务推进技术发展最典型的例子。淘宝的基础系统及中间件经过多轮演化,从最早的php架构转到Java系,再到分布式、服务化、模块化的层次结构,撑住一次次“双十一”考验,系统逐渐进化得越来越完善。所谓的形势造就英雄,就是这个道理吧。

3. 关于程序开发中框架的利用,我有自己的一些看法,作为一个初进职场的二年级新生,没有多少技术储备,过多地依赖框架会影响自己对底层实现的理解,要谨慎使用。现在各种框架层出不穷,你想要的任何基础服务,都已有现成的封装。如果选择的框架生命力不强,而自己又没有能力掌握它时,那么这种依赖就是一颗定时炸弹。我的研究生导师在这方面做得很极端,某个项目中需要用到队列数据结构,并且队列元素是一些基本数据类型,我随手就把STL用上了,哪知道他review时看到了,要我自己实现,给出的理由是这里队列使用场景简单没必要用STL这么重量的东西,而且出问题不好调试,得不偿失。

4. 技术上有个收获:现在在做的Web项目中,服务器端不维护Session,所有服务器端的状态信息(其实就是用户名、用户类型等简单信息)都存在Cookie中,浏览器的每次页面请求都携带这个Cookie,服务器端Filter判断当前请求是否有权限访问页面。我一直认为这种方式能保证每次请求响应无状态,加服务器即可线性扩展系统容量,用适量的CPU消耗(解密Cookie)可以换取极好的可扩展性。但是现在看来,它的一个缺点在于网络传输量上,假设一个用户维护状态的Cookie长度为2K(2K其实很正常,需要维护的服务器端信息越多,这个值就越大),那么当1亿PV产生的网络传输量就是200GB。对于需要支撑高并发的网站而言,这确实会是个问题。所以淘宝采用的方案是增加Session缓存服务器,集中式管理Session。

5. 另外还看到个心灵鸡汤:一个人如果把做事、做成事作为主要目标,该他得到的东西,一定会顺理成章的、水到渠成地得到,但是,如果把(职位)上升作为主要目标,做同样的事,结果就会完全不一样,你的心态会最终决定你的成就。这是正祥提到的,这个正祥,如果没推断错的话,就是我当初听闻的手下没人,自己一个人搞研究,每隔半年就能鼓捣出一个很牛逼的东西那个人。很是佩服。

--EOF--

『蝙蝠侠:第一年』

『蝙蝠侠:第一年』那是蝙蝠侠诞生的年代,那是蝙蝠侠开始以暴制暴的第一年。那时戈登还是个初来乍到的普通警员,那时邓特还只是个初出茅庐的检察官。但那时哥谭市的腐败和黑暗却已经是由来已久了的,早在布鲁斯·韦恩还是幼年的时候便是如此,街头暴力随处可见,韦恩父母还因此遭到枪杀,就死在他的面前。这个社会已经没救了,而且情况只会越来越糟。

那个时候的蝙蝠侠和戈登还在各自为战,为了自己心中的理想试图去拯救已被蛀空的哥谭市。戈登的目标是肃清一切法外之徒,也包括蝙蝠侠;蝙蝠侠的目标是铲除一切黑暗和腐败力量,也包括警察局里的官员洛布局长和弗拉斯。他们真正开始成为朋友的时间,应该是从便衣布鲁斯·韦恩救下从桥上坠落的戈登儿子开始的。

于布鲁斯·韦恩来说,蝙蝠侠是他存在的另一种意义,因为他说过,他的生命在父母死去那天便已经没有任何意义,他要用蝙蝠侠这个身份,让今后哥谭市的少年不要再有自己儿时的经历;于这个社会来说,蝙蝠侠是黑暗下的一点曙光,人们找不到可以伸张正义的地方,只能寄托蝙蝠侠。但同时蝙蝠侠又是个见不得光的存在,他用来伸张正义的手段是未经法律允许的,与制度相悖,同样也是犯罪。人们需要他,却又不能大张旗鼓地歌颂他,所以这是个悖论。与超人等完全正面的形象相比,蝙蝠侠只能默默背着黑锅,就像蝙蝠,只能在黑夜里出没。

--EOF--