framed,overlay,layer 还有 collector
在使用 MS Word “排版”文档时,我们经常要用到“文本框”和“图文框”,在 ConTeXt (MkIV 版本) 中我们可以利用 framed、overlay 和 layer 来实现类似的功能。
vala, vala!
这 1 年多以来,玩 ConTeXt 把我的业余甚至部分主要时间都变成了“暗时间”。昨晚看到 gedit 小版本号更新,有点奇怪这个东西每次都更新了啥,然后就去 http://projects.gnome.org/ 去查看它的更新记录,发现很多次版本升级只是做了一些微小的 bug 修正以及界面本地化,心里对此很不以为然。正在对 gnome 每次都打太极拳感到郁闷时,在那个页面上发现了 vala。
ConTeXt 对参考文献的处理——整容篇
标题党!!!
上一回书说到 ConTeXt 处理参考文献时,给出的是“原生态”的排版效果,这主要是因为 ConTeXt 的参考文献模块默认给出的是适合西文排版的参考文献格式。中文用户,还需要先扮演一下整容师,对参考文献排版样式整顿一下。
ConTeXt 对参考文献的处理
本文讲述 ConTeXt 处理参考文献的基本过程。
ConTeXt MkIV 中文标点间距压缩问题的解决方案
有关在 ConTeXt MkIV 中解决中文标点符号微排版的话题,在背景一文中已做过介绍。为这个问题已经潜水很久,现在才开始准备浮出水面。这篇文章主要总结一下这段时间所做过的一些有关中文标点间距压缩方面的尝试,这样即便我受到一些外因的限制无法完成此事,也可对其他有志于此者有所帮助。
用构造 hlist 的方式实现中文标点符号的“升降”
本来认为无解的事情,结果还比较有灵感,居然想到要去查看“
“所对应的结点类型,结果发现是它是"glyph + kern + hlist + kern + glyph" 的形式,正好与“
“的宏展开式“T\kern-.1667em\lower.5ex\hbox{E}\kern-.125em X”相对应,可见在 LuaTeX 中那个下沉的 "E" 是通过 hlist 封装起来的。
于是自己写函数去造一些中文标点符号的 hlist 结点,然后在遍历文档结点时,用经过 hlist 封装的结点去替换原有结点,这样就可以实现对中文标点符号上下方向的位置调整了。
例如对于文鼎宋体,是台湾公司免费发布的,所以其中的中文标点大都是按照台湾的习惯来设计的,标点符号都是处于中间的,如下图的中文句号:
如果将这个句号字符采用 hlist 的方式封装,例如:
local function full_stop (g)
local n = node.copy (hlist)
n.attr = nil
n.width = fontdata[g.font].size
n.depth = 0
n.shift = 0.3 * n.width
n.glue_order, n.glue_set, n.glue_sign = 0, 0, 0
n.list = nodes.glyph (g.font, g.char)
n.dir = 'TLT'
return n
end
用上述 full_stop 函数所生成的结点替换掉文档中出现的句号字符结点,效果如下图所示:
现在,在 ConTeXt MkIV 对中文标点符号的微排版方面,感觉基本上没有什么太困难的问题了。这段时间,先把以前的各个环节的尝试总结一下,先制作一份文档出来。
freebsd + lighttpd + fastcgi + MoinMoin
最近重新整理了一下实验室的服务器,全新安装了 FreeBSD 7.2。比较郁闷的事情就是在 lighttpd 上重新配置 MoinMoin,以前做过成功的配置,但是升级系统时,忘记保存 lighttpd 的配置文件了。尝试了一段时间,总算又搞定了,这次得做个记录。
首先可以参考这篇文章安装并配置好 lighttpd 环境,然后就可以去 MoinMoin 的官方网站去下载 MoinMoin 的最新版本,目前最新的稳定版本是 1.8.5。
按照 MoinMoin 安装包内的 docs/INSTALL.html 文档的指点,将 MoinMoin 基本安装以及 Wiki 实例创建步骤都做完了,最后的环节就是配置 lighttpd.conf 文件,由于 INSTALL.html 文档在这部分语焉不详,并且我对 Web 服务器的原理以及 lighttpd 的配置语法都不熟悉,让我茫然了好大一会。翻来覆去,看了好几遍 INSTALL.html 给出的这段 lighttpd.conf 的配置代码:
$HTTP["host"] =~ "^(www\.)?example\.org" {
url.rewrite-once = (
"^/robots.txt" => "/robots.txt",
"^/favicon.ico" => "/favicon.ico",
"^/moin_static161/(.*)" => "/moin_static161/$1",
"^/(.*)" => "/wiki-engine/$1"
)
server.document-root = "/srv/org.example/htdocs/"
$HTTP["url"] =~ "^/wiki-engine/" {
fastcgi.server = ( "/wiki-engine" =>
(( "docroot" => "/",
"min-procs" => 10,
"max-procs" => 10,
"max-load-per-proc" => 2,
# allocate successive port numbers for each process, starting with "port"
"bin-path" => "/srv/org.example/bin/moin.fcg",
"host" => "127.0.0.1",
"port" => 3060,
"check-local" => "disable",
))
)
}
}
不禁有点飘飘欲仙之感,因为这串代码对我来说简直如天书一般。连猜带蒙的,最后我是这么来理解的:
- $HTTP["host"] 是用来设置虚拟主机的,就是那种多个域名共享 1 个 IP 的虚拟主机,那个 ^(www\.)?example\.org" 是采用正则表达式来匹配 www.example.org 这个域名。"=~" 就表示后面跟随的字串是正则表达式,对于非正则表达式,可以用 "=="。
- url.rewrite-once 是采用正则表达式匹配的方式用来替换 "www.example.org" 后面所跟随的字串(即 url 字串)的。比如 "www.example.org/robots.txt" 所跟随的字串是 "/robots.txt",当它被 url.rewrite-once 中的 "^/robots.txt" 所匹配时,就会被替换为 "/robots.txt"。嗯,这里对于 "/robots.txt"、"^/favicon.ico" 以及 "^/moin_static161/(.*)" 都是替换为其自身,好像是在咬自己尾巴玩,实际上它们是为了让对应的三个 url 不被那个 "^/(.*)" 替换规则篡改。
- server.documet-root 就是指定 MoinMoin 网页模板所在的目录,而那个 wiki-engine 是 MoinMoin 实例所在的目录。
- $HTTP["url"] 是用来定义 fastcgi 服务器的,它也是采用正则表达式来匹配 "/wiki-engine/" 这个 url 字串,表示只要匹配通过的 url 字串所代表的页面请求都通过一个 fastcgi.server 来处理。
- 在 fastcgi.server 的配置中,除了做一些平常的配置之外,最关键的在于指定 moin.cfg 文件所在的全路径。moin.cfg 是用来实现 MoinMoin 与 fastcgi 服务器相互联接的,它默认位于 server.document-root/../server 目录内,我们可以将它复制到 wiki-engine 所在的目录。
基于上述的理解,我对上述 lighttpd.conf 的配置片段进行了以下修改:
### M2WK MoinMoin
server.modules += ( "mod_alias" )
alias.url = ( "/moin_static185/" => "/usr/local/share/moin/htdocs/" )
$HTTP["host"] =~ "^192\.168\.0\.2" {
url.rewrite-once = (
"^/robots.txt" => "/robots.txt",
"^/favicon.ico" => "/favicon.ico",
"^/moin_static185/(.*)" => "/moin_static185/$1",
"^/(.*)" => "/m2wk/$1"
)
server.document-root = "/usr/local/share/moin/htdocs/"
$HTTP["url"] =~ "^/m2wk/" {
fastcgi.server = ( "/m2wk" =>
(( "docroot" => "/",
"min-procs" => 10,
"max-procs" => 10,
"max-load-per-proc" => 2,
"bin-path" => "/usr/local/var/m2wk/moin.fcg",
"host" => "127.0.0.1",
"port" => 3060,
"check-local" => "disable"
))
)
}
}
值得注意的地方是:我配置的服务器只是在内网中使用的,没有域名,所以 $HTTP["host"] 只能匹配服务器的 IP 地址了;需要启用 lighttpd 的 alias 模块,以便将 MoinMoin 所生成的网页中所使用的 "/moin_static185/" 路径映射到服务器本地目录。
配置完 lighttpd.conf 之后,还得对 moin.fcg 中的一处代码片段进行一些修改:
class Config(FastCgiConfig):
# properties = {'script_name': '/'} # use this instead of the line above if your wiki runs under "/" url
# for backlog, we use a default of 5. if the listen(backlog) call crashes for you, try a smaller value!
# backlog = 1
max_requests = 1000
properties = {'script_name': '/'} # <--- 必须有
现在启动(重新启动) lighttpd 之后,在浏览器中输入服务器的 IP 地址,就应该能够看到 MoinMoin 的页面了,剩下的事情就是有关 Wiki 的配置,不再细说。
但是,这里有个费解的问题。通过上述方式配置好 MoinMoin 之后,当我重启 FreeBSD 时,通过 rc.d 的方式启动 lighttpd 会失败,等 FreeBSD 启动完毕后,通过手工启动 lighttpd,就不出错。
又可以接着做 ConTeXt MkIV 的中文标点处理了
今天在翻看 LuaTeX 文档时,无意中看到已经看了好几遍的一句话:
Callback assignments are always global. You can use the special value nil instead of a function for clearing the callback.
这让我想起四个多月前败了一次就放弃的 ConTeXt MkIV 中文标点处理的事情。当时只是怀疑 Hans 在做字体的 Fallback 时已经利用了那个pre_linebreak_filter 回调函数,以致于只要我使用了自定义的 pre_linebreak_filter 回调函数就会把 Hans 的覆盖掉,所以导致 ConTeXt 的字体机制不正常。所以就简单地放弃了。
刚才进入 /path-to/texmf-context/tex/context/base 目录 grep 了一下,发现 Hans 的确是用了 pre_linebreak_filter:
$ grep pre_linebreak_filter *
node-ini.mkiv:% callbacks.push('pre_linebreak_filter')
node-ini.mkiv:% callbacks.pop('pre_linebreak_filter')
node-pro.lua:function nodes.processors.pre_linebreak_filter(head,groupcode)
node-pro.lua:callback.register('pre_linebreak_filter', nodes.processors.pre_linebreak_filter)
仔细想想,其实是有办法来解决这个回调函数冲撞的问题的,只是我对动态语言太缺乏实战经验,所以一直逃避至今。
大致可以这样解决:
local old_pre_linebreak_filter = callback.find ('pre_linebreak_filter')
function new_pre_line_break (head, groupcode)
old_pre_linebreak_filter (head, groupcode)
-- 下面是我自己的代码
... ...
return true
end
callback.register ('pre_linebreak_filter', new_pre_line_break)
这个问题一旦解决了,那么基于以前所做的那些有关 LuaTeX 的尝试,实现中文标点横排压缩和边界对齐只是个体力活。