標籤:

TeX 編程有哪些資料與工具?

對一些 .sty, .cls, .bst 文件不滿意時,經常從網上搜來一些零星技巧,做一些小修改。

現在有心寫個自己私人的 package

可是 TeX 程序的文本看上去不太美觀(Vim-Latex 打開 sty 的效果見下圖),

不知有什麼順手的編輯工具(高亮著色縮進等功能)?

網上資料我僅在 Where do I start LaTeX programming? 找到一些,不知是否還有別的。

另外 TeXBook 無疑是一本權威的 TeX 排版教材,對於 TeX 編程有多大幫助呢?

==

真的是忍無可忍了……

我現在問的不是 TeX 排版(typesetting),而是 TeX 程序設計(programming)。

TeX 不僅是排版用的標記語言,也是圖靈完備的程序語言。

希望回答前有個基本了解,比如參考一下 http://pgfplots.sourceforge.net/TeX-programming-notes.pdf


如編程語言的設計上來講,TeX是一門面向排版的宏編語言。TeX語言的特點,就是宏,而並不具有函數的特性。就TeX的內部處理來講,是處理list的,所以有點類似於lisp語言。Paul Graham在他的On Lisp曾經提到過Lisp和TeX的一個設計模式:自底而上。簡單點說,就是先構建想要的一部分功能,然後逐步積累,最終完成一段代碼的設計。這樣的,可以很方便測試那一小塊的功能。而缺點則是,如果沒有完整的文檔,寫出來的代碼比較坑,讓[別]人看了一頭霧水。TeX本身的源代碼也是這種設計,所以有些人看不進去,我是看了十幾遍才看懂的。用TeX編程,就是寫出一系列的宏代碼。在設計的你想要的功能的時候,寫好一段注釋。如果覺得寫的還不錯,對別人可能有用,那麼請按照CTAN上的說明,選擇一個開源許可證,把寫好的宏代碼傳上去。這樣在任何有TeXLive或者MikTeX的地方都有可能找到這段代碼,那樣用起來就方便多了。

先來插一段話,當今的TeX實現,比如XeTeX,LuaTeX等,給TeX本身帶來了一定的擴展性。比如我們可以在LuaTeX下(一下代碼以ye結尾的是plain格式)使用如下方法來定義一些方便的函數:

deffactorial#1{%
directlua{function fac(n) if (n==0) then return 1 else return n * fac(n-1) end end}%
directlua{tex.print(fac(#1))}%
}
obeylines
$4! = factorial{4}$
$7! = factorial{7}$
ye

LuaTeX有一些分析node的庫(node是TeX內部的重要概念),字體分析庫,Unicode庫和PDF處

理庫,不過直接就想上LuaTeX編程的話,恐怕障礙會比較大。不過某些功能在LuaTeX是比較方便的,我建議選一本Herbert Voss的Einführung in LuaTeX und LuaLaTeX。上面的可以用宏來實現:


ewcount

ewcountp
ewcountm
deffactorial#1{{m=#1advancem by 1

=1
p=1
loopifnum
&

無論是想用LaTeX還是plain,找幾本plain TeX的書看看都會對TeX的這些primitive有一定的理解。

比如Einführung in TeX(http://www.ruhr-uni-bochum.de/schwarz/TeX/einfuehrung-in-tex.pdf)和另一本比較舊的Writing with TeX都比較簡短,且結構清晰。至於TeXbook,我建議做書中的習題,做一遍,水平會有很大的提高。

來說說TeX中的一些概念好了,如果對這些概念不了解的話,那麼,有些人對待TeX的態度會很奇怪。

注意0. Glyph。這個我不給定中文名稱。所謂的Glyph是排版後由人眼看到的圖像,比如0是一個圈。Glyph通常由一個編號,稱作Glyph ID,這個ID和輸入編碼有一定關係。

注意1. Metrics。這是字體所定義的一系列參數,在將編碼輸出為glyph的過程中會讀取這些參數進行調整。比如,Te這兩個字母要互相靠近一些,這需要讀取kerning參數。還比如把fi兩個字母,可以縮合成一個字元?(U+FB01),就需要讀取字體的ligature參數進行替換。對於數學字體,在metrics還規定了不同公式元素的間距,比如我們輸入$a=b$,得到的結果會發現=兩邊有一定的間距,這就是讀取了相應的數學信息後做出調整的。TeX下的metrics是以獨立文件的形式存在的,擴展名為.tfm。在OpenType中,glyph和metrics信息是合併在一個文件中的。

注意2. 字體。對普通人而言,字體是Glyph的集合。但字體文件中,有一定的映射關係,比如字元0所對應的glyph可能的ID是10。在TeX中,定義一個字體使用font,比如font est= cmr10 at 15pt。TeX在處理字體的時候,只需要關心metrics,不必關心glyph長什麼樣。在某些情況下,需要做一些METAFONT字體,以配合宏的寫作。

注意3. Glue。Glue就是傳統鉛印術中鉛空,用來調整距離的,不過一個很明顯的特徵就是Glue是可以進行伸縮的,這種設定,有助於斷行的操作。比如,在TeX中,通常情況下,你所敲入的空格都是要轉換成一個glue的,這個glue可以通過定義spaceskip進行修改,這個primitive是控制詞間的glue比例。比如:

defdemo{Happy is the man to whom it is granted to make even one such discovery.}
{spaceskip=.6666emdemo}par
{spaceskip=.3333emdemo}par
ye

注意4. Catcode。Catcode是一個編碼值的屬性,這個值會影響TeX讀取的文本。比如我們會用{}表示一個群組,但是我們可以把&<&>也變成一個群組,比如:

catcode`&<=1 catcode`&>=2
defabc{Hello, ABC.}
defcd&
abc cd
ye

TeX中的Catcode有16種(0-15),如果能夠掌握Catcode,那麼可以寫出比較有技巧的代碼。

0:轉義符,以catcode為0開頭的字元串可能是一個命令,在TeX中默認是,而在TeXinfo中則是@。1:組開頭,默認是{。2:組結束,默認是}。3:切換到數學模式,默認是$。4:對齊符,默認是。5:行尾符,默認是回車。6:宏參數,默認是#。7:上標,默認是^。8:下標,默認是_。9:可被忽略掉的字元,默認為U+0000 & NULL。10:空格,默認就是空格。11:字母,A-Z和a-z。12:其他字元。13:活動字元,作用相當於一個不帶轉義符的命令。14:注釋符號,默認是%。15:被刪除掉的字元,默認是U+007F & DELETE。掌握了catcode,可以寫出如下代碼而不傷身體:

let~catcode~`76~`A13~`F1~`j00~`P2jdefA71F~`7113jdefPALLF
PA""FwPA;;FPAZZFLaLPA//71F71iPAHHFLPAzzFenPASSFthP;A$$FevP
A@@FfPARR717273F737271P;ADDFRgniPAWW71FPATTFvePA**FstRsamP
AGGFRruoPAqq71.72.F717271PAYY7172F727171PA??Fi*LmPA71jfi
Fjfi71PAVVFjbigskipRPWGAUU71727374 75,76Fjpar71727375Djifx
:76jelseU76jfiPLAKK7172F71l7271PAXX71FVLnOSeL71SLRyadR@oL
RrhC?yLRurtKFeLPFovPgaTLtReRomL;PABB71 72,73:Fjif.73.jelse
B73:jfiXF71PU71 72,73:PWs;AMM71F71diPAJJFRdriPAQQFRsreLPAI
I71Fo71dPA!!FRgiePBt"el@ lTLqdrYmu.Q.,Ke;vz vzLqpip.Q.,tz;
;Lql.IrsZ.eap,qn.i. i.eLlMaesLdRcna,;!;h htLqm.MRasZ.ilk,%
s$;z zLqs".ansZ.Ymi,/sx ;LYegseZRyal,@i;@ TLRlogdLrDsW,@;G
LcYlaDLbJsW,SWXJW ree @rzchLhzsW,;WERcesInW qt."oL.Rtrul;e
doTsW,Wk;Rri@stW aHAHHFndZPpqar.tridgeLinZpe.LtYer.W,:jbye

注意5. Penalty。這個需要單獨提出來將,這個penalty是可以影響斷行的。對於中文中,需要進行

避頭尾的標點,都需要添加penalty進行處理。Penalty大於等於10000的時候,插入penalty的地方

不會斷行,小於等於-10000的時候會強制斷行。而介於這兩個值之間,則會影響斷行的整體。

input luaotfload.sty
font est=name:FandolSong-Regular at 10pt
est
parindent=0pt
hsize70pt
錕斤拷錕斤拷,penalty-10000錕斤拷錕斤拷par
錕斤拷錕斤拷,錕斤拷錕斤拷par
ye

注意6. Register。這些所謂的寄存器,可以當成數組來用,他們可以用來保存數值(count),

保存長度(dimen),保存glue(skip),保存token串( oks)。上面的那個計算階乘的,就是

用了數值寄存器的。可以進行運算的寄存器的運算,有三個命令:advance,multiply,divide。

他們都有一個by關鍵字,用法如下示例。TeX生成的文檔中的頁碼就是保存著數值寄存器中的。至於萬能的 he,自己好好看看就好。


ewcountx x=6
$ 6 + 7 = advance x by 7 hex$par
$ 6 * 7 = multiply x by 7 hex$par
$ 6 / 12 = divide x by 12 hex$
ye

注意7:Token。如果沒有讀過編譯原理,那麼就簡單地把token看成輸入的文本好了。TeX中的token分為兩種,一種是ASCII碼,另一類是命令。對於Token,一個比較重要的地方是token的展開。能展開的token是命令。這些命令裡面,有TeX本身定義好了的(叫做primitive),也有後來定義的,如我們的abc。我們定義的命令,一定是看可以展開的,而對於primitive,則大部分不可展開。TeX 中最讓人抓狂的是expandafter命令(必須了解token的展開可能性):

uppercaseexpandafter{
omannumeral1999}
ye


既然題主說了關於文本是否美觀的問題,獻醜了(懶得調圖片大小於是就這樣了,隨意找了一個系統自帶的sty文件用vim打開)

以及黑夜服黑片

題主示例圖片中主要的問題是,紅色用的太多,而且作為暖色的紅色會顯得太密:作為暖色的紅色會往外突出在暗色背景下面。

我現在用的配色方案是solarize,白天用白色方案,晚上用黑色方案,代碼如下

call vundle#rc()
Bundle "vim-colors-solarized"

if ! has("gui_running")
let g:solarized_termcolors=256
endif

function! SetSolarizedBackground()
if strftime("%H") &>= 5 strftime("%H") &< 17 if background != "light" set background=light endif else if background != "dark" set background=dark endif endif endfunction " Set background on launch call SetSolarizedBackground() colorscheme solarized " Every time you save a file, call the function to check the time and change " the background (if necessary). if has("autocmd") autocmd bufwritepost * call SetSolarizedBackground() endif

以及字體用的是droid sans mono

if has("gui_running")
set columns=150 lines=40 "設置gui默認界面大小
set guifont=droidsansmono for powerline 14
set guifontwide=WenQuanYi Micro Hei Mono 15
endif

其實我沒怎麼用過tex的插件( tex 也寫的少),不過這個插件看起來不錯

LaTeX-Box-Team/LaTeX-Box

因為我看到下面幾個功能感覺不錯

  • Highlight matching egin/end and left
    ight pairs.
  • Motion between egin/end and left
    ight pairs with the % key.
  • Environment objects (e.g., select environement with "vie" or "vae").
  • Inline math objects (e.g., select inline math with "vi$" or "va$").
  • 如果題主不僅僅想要了解tex怎麼編程,還想要了解如何高效的編寫tex的話。(emacs如何高效我不太清楚,所以我推薦vim了)推薦:

    1. Practical Vim: Edit Text at the Speed of Thought

    2. http://vimcasts.org

    可能題主沒有時間去糾結這兩個東西,也許需要一些tips之類的東西

    1. Habit breaking, habit making 這裡面討論了如何高效的移動,雖然關於跨行的移動是在comments 之中

    2. text objects 我不記得關於這個我是在哪裡學到了?(似乎是Practical Vim),或許可以看一下 A text-object for ruby blocks 來了解text objects可以幹些什麼

    3. 插件 Lokaltog/vim-easymotion 跨行移動之利器,推薦使用 f系列而不用 w,原因之一是 w在我的電腦上反應較慢

    4. 插件 tpope/vim-commentary 自動敲打注釋的插件

    5. tpope/vim-surround 提供針對 text objects的操作,能夠輕鬆的加上和消除 ""[({之類的東西,以及可以很容易將 [(之類的換成""{之類的

    6. ivyl/vim-bling 賣萌用插件

    7. coderifous/textobj-word-column.vim 理解了text object之後看說明吧

    8. Valloric/YouCompleteMe · GitHub vim下的最強補全


    通常的任務都可以通過載入別人寫好的宏包來實現各種功能,所以讀宏包文檔是一個非常好的做法。但是如果非要寫宏包實現一些尚未實現的功能,TeXBook 則相對來說很重要,一個替代是 TeX by Topic,這兩本書不是那麼好讀。Source2e也非常重要。不過個人感覺一般用戶沒有必要做這些。有問題到 http://tex.stackexchange.com 上去問就行了。

    直接對現有的 sty,cls進行修改並不是一個好的習慣。一般情況下,常用的宏包的功能都是比較完善的,可以自己配置的,這在宏包文檔裡面都有詳細的介紹。

    vim 也可以實現 LaTeX 的高亮,有個插件叫做 vimlatex,如果你喜歡 vim 的話。代碼高亮本身是編輯器的事情,與 TeX 無關,關於編輯器爭論簡直是太多了,提到編輯器vim、emacs總會出現。他們都可以支持 LaTeX 的代碼高亮、縮進什麼的。另一個值得一提的通用編輯器是 Sublime Text 2/3,也有支持 LaTeX 的插件。(La)TeX 只是一種標記語言,算不上什麼程序,個人感覺縮進並不像編程語言那樣重要。

    不過對於 TeX,我喜歡 TeXworks,只因為簡捷,偶爾用 vim。Linux下 Kile 是個不錯的選擇。

    =====關於資料=============

    個人的經驗是:

    0、熟悉LaTeX常用的宏包,讀geometry、titletoc、titlesec、amsmath、listings,xeCJK等的文檔,了解現有的實現。因為熟悉了 LaTeX 各種宏包之後,會發現通常並不需要自己寫什麼底層的東西,而且也不會有那麼多問題,而且這些久經考驗的宏包也沒有很多的衝突,功能上個性化上都非常完善。然後下面晉級:

    1、讀TeXbook/TeX by Topic,這兩本書是關於 TeX 語言的,算作基礎,需要知道宏語言是如何工作的,熟悉 TeX 的盒子。

    2、讀 LaTeX: A Document Preparation System

    3、讀 Source2e,這是 LaTeX 的源代碼。通常的宏包書寫並不是在 plain TeX 的基礎上進行的,而是利用 LaTeX2e 甚至 LaTeX3 的語法、控制序列來完成的。

    4、讀titletoc、titlesec、amsmath等常用宏包的代碼。

    5、練習,調試。

    ======關於高亮===========

    TeX宏包由控制序列構成,各種控制序列都是宏命令,也沒有什麼區別,沒有太多的結構層次什麼的,所以高亮得花花綠綠也不是很現實。


    編輯器用Emacs,使用AUCTeX插件之後有高亮等各種高端效果。

    效果圖如下。截圖來自我的一門課程的結課報告。

    不知道這樣的效果能否滿足要求。


    本回答並未針對題主的補充說明。請摺疊。

    ================================

    tex文本編輯的話,我認為LyX [1]是個不錯的選擇。

    至於資料,我一般在LaTeX編輯部 [2]和LaTeX工作室 [3]找。這兩個地方有很多模版資源和實用技巧。LaTeX編輯部出版的《LaTeX2e 完全學習手冊》我認為也算是最好的LaTeX中文排版教程了(雖然題主可能不大需要中文排版ˊ_&>ˋ)。

    [1] LyX | LyX – The Document Processor

    [2] LaTeX 編輯部

    [3] LaTeX 工作室


    Demonstration Portal

    這個網站編輯公式蠻方便的..可以手寫公式然後 自動生成 LaTex的代碼

    寫論文的時候常用


    推薦閱讀:

    如何評價 upTeX?
    商業出版公司真的有用 LaTeX 的嗎?
    你為什麼用LaTeX?
    如何配置 MacTeX 的中文支持?
    為什麼 CTeX 好久沒有更新?

    TAG:LaTeX | TeX |