preview-latex在GS9.00下报错

在emacs下其实很久不用preview-latex了,一直觉得没有必要——但是忽然用一下的时候发现不能用还是很郁闷的。基本上报错是这样的:

"GSWIN32C.EXE" "-dOutputFile=(_region_.prv/tmp5723kvc/pr1-1.png)" "-q""-dSAFER" "-dNOPAUSE" "-DNOPLATFONTS" "-dPrinted" "-dTextAlphaBits=4""-dGraphicsAlphaBits=4" "-sDEVICE=png16m" "-r70.4906x70.6156"
GS>{DELAYSAFER{.setsafe}if}stopped pop/.preview-BPcurrentpagedevice/BeginPage get dup null eq{pop{pop}bind}ifdef<</BeginPage{currentpagedevice/PageSize get dup 0 get 1 ne exch 1get 1 ne or{.preview-BP }{pop}ifelse}bind/PageSize[1 1]>>setpagedevice/preview-do{[count 3 roll save]3 1 roll dup length 0 eq{pop}{setpagedevice}{ifelse .runandhide}stopped{handleerror quit}if aload pop restore}bind def[(_region_.prv/tmp3712kvc/preview.dsc)(r)file]aload exch dup 0 setfileposition 520()/SubFileDecode filter cvx .runandhide aload pop dup dup 623 setfileposition 50()/SubFileDecode filter cvx<<>>preview-do
Error: /invalidfileaccess in --file--

查了一通后来发现有人遇到这个问题之后把GS降级到8.71以下就好了。说明GS在近来做了一些改动。左看右看看到了-dSAFER这个参数——这个参数本意是要加强权限检查防止gs自动打开系统文件权限——但和权限相关的也只有它了。试着在命令行下重新跑着两个命令(用gswin32会容易些,否则后面这个长命令贴都贴不进去),居然跑通了。又大致查了查,貌似可能是一个BUG,不过我升级到了最新的9.02也没有解决这个问题。

既然如此,到site-lisp/auctex/preview.elc(最好还是用.el重新编译一下) 下面找到
(defcustom preview-gs-options '("-q" "-dSAFER" "-dNOPAUSE" "-DNOPLATFONTS" "-dPrinted" "-dTextAlphaBits=4" "-dGraphicsAlphaBits=4")
-dSAFER一项干掉就是了。虽然这似乎是一个“漏洞”,不过就自己跑跑preview来看,应该没太大风险。

一个更为稳妥的办法是在.emacs里面加上'(preview-gs-options (quote ("-q" "-dNOPAUSE" "-DNOPLATFONTS" "-dPrinted" "-dTextAlphaBits=4" "-dGraphicsAlphaBits=4"))),就好了

用 Ghostscript 替换字体

放这儿以防止自己忘了…

1. 尽量使用 Acrobat 7 打印 pdf,然后另存成 eps。不要用 Acrobat 9! 同样一个文件,7 出来的 eps 260k,9 出来的 10M… 无数的乱七八糟的信息,bs Adobe 一记。
2. 假定原先的字体是 TimesNewRomanPSMT.*之类的,嵌入之后可能变成 ABCDEF+Times****,仅搜索/…..+Times.*? 然后替换成想要的字体,比如/Minion-Regular
3. 如果愿意,可以搜索 %ADOBeginSubsetFont: …..+Times.* 然后匹配%ADOEndSubsetFont,把嵌入的字体去掉
4. 文件末还可能有 /TJMAAA+TimesNewRomanPS-ItalicMT /Font _pdfUndefineResource ^J /N10 /Font _pdfUndefineResource 之类的,也去掉
5. 用 GSView 看一下,保证字体已经替换好了
6. MikTeX/CTeX 2.8 里面自带了一个 gs…(这实在很让人迷惑),叫做 mgs.exe
7. 如果想用这个,可以去 MikTeXghostscriptbase 相应目录里面去找 Fontmap. 这里面定义了具体指向哪个 Fontmap 文件(默认是.aliases..)
8. 如果不想用,直接把它改个名字,然后把自己的 gswin32c 复制一份叫做 mgs.exe
9. mgs -h 查看文件搜索路径
10. 把 Fontmap.atb 复制一份,叫做 Fontmap
11. 把 Minion 添进去,比如
/Minion-Regular (morg____.pfb) ;
/Minion-Bold (mob_____.pfb) ;
/Minion-Italic (moi_____.pfb) ;
/Minion-BoldItalic (mobi____.pfb) ;
12. 试着用 XeTeX 编译一下吧,应该可以看到替换嵌入的字体了,撒花~
13. 注意,GS 的字体搜索路径要在环境变量 FontResourceDir 中定义。
14. 这种办法的缺点在于,可移植性有点差。

补充一些内容:在 MacTeX 环境下,可以新建 /usr/local/share/ghostscript/8.71/lib/Fontmap 来控制字体名称的匹配。用 gs –help 可以看到字体搜索路径。