有啥辦法能讓listings去檢查源代碼是不是和tex文件里一樣,而不是直接把那幾行input進來?
我覺得複製粘貼一遍問題不大。倒是源代碼改了,tex文件不改,結果就錯了,這個比較麻煩。
強烈建議 @劉海洋 的一般方法。
LaTeX 可以藉助 verbatim 宏包來比較每一行,大概是下面這樣子。documentclass{article}
usepackage{verbatim}
makeatletter
% 參數 #1 是外部源文件行號,#2 是文件名稱。
ewenvironment{cmpcode}[2]{%
egingroup@verbatimfrenchspacing@vobeyspaces
IfFileExists{#2}{%
openinverbatim@in@stream@filef@und
elax
skip@beginline{#1}%
letverbatim@processlineverbatim@compareline
}{%
@latex@error{No file #2.}@ehd
}%
verbatim@start
}{%
closeinverbatim@in@stream
endverbatim
}
defskip@beginline#1{%
scr@lineno=#1
elax
count@=scr@lineno
loop
ifnum count@ &> @ne
eadverbatim@in@stream to@tempa
advancecount@m@ne
epeat
}
ewcountscr@lineno
defverbatim@compareline{%
egingroup
edef@tempa{ heverbatim@line}%
endlinecharm@ne
eadverbatim@in@stream to@tempb
ifx@tempa@tempb
else
oks@expandafter{@tempb}%
verbatim@mismatcherror
fi
endgroup
advancescr@lineno@ne
verbatim@printline
}
defverbatim@mismatcherror{%
@latex@error{%
Line mismatch! MessageBreak
* LaTeX line ( heinputlineno): heverbatim@lineMessageBreak
* source line ( hescr@lineno): he oks@
}@ehd
}
defverbatim@printline{ heverbatim@linepar}
makeatother
egin{document}
egin{cmpcode}{1}{jobname.tex}
documentclass{article}
usepackage{verbatim}
makeatletter
end{cmpcode}
end{document}
不是很複雜。
如果還要 listings 包的高亮效果,可能需要處理兩遍。第一遍是比較和把源文件輸出到外部輔助文件,第二遍再把輔助文件 lstinputlisting 進來。
pdfTeX 由於有原語 pdfmdfivesum(LuaTeX 可以藉助 pdftexcmds 宏包的 pdf@filemdfivesum),所以也可以把要比較的代碼輸出到兩個小文件中,再通過文件的 pdfmdfivesum 來比較。顯示文件還是用
lstinputlisting[linerange={5-10}]{foo.c}
這種東西,別用 TeX 搞奇怪的功能。TeX 是排版軟體,不是 diff,不是版本管理軟體,不是回歸測試軟體。
你要檢查 C 文件 foo.c 的第 5 行到第 10 行行號變了沒有。這是個與 TeX 無關的問題。你可以用任何腳本或者 C 代碼來檢查,也可以藉助版本管理工具,具體做法不重要,但都比寫 TeX 代碼舒心。
現在來說一個更有價值的辦法,就是直接從源代碼中抽取需要的部分顯示。簡單的辦法就是,在注釋中做標記。比如說我們規定// &<&<&
表示一個名為 foo 的代碼塊。現在寫一個 python3 腳本
#! /usr/bin/env python3
import sys
import re
if len(sys.argv) != 4:
print("Usage: %s src dst label" % sys.argv[0])
exit(0)
_, src_name, dst_name, label = sys.argv
with open(src_name) as src, open(dst_name, "w") as dst:
match = False
for line in src:
if re.match(r"^//s*&<&<&&>&>", line):
break
if match:
dst.write(line)
就行了。
推薦閱讀:
※TeX Live 2015 有哪些值得關注的新特性?
※如何從零開始,入門 LaTeX?
※有沒有和writelatex(現在叫overleaf)一樣好用的本地tex IDE?如果沒有,為什麼沒有?
※LaTeX 怎麼讓第二頁的頁碼變為 1,封面不標頁碼?
※如何在Latex中畫這種根樹圖形?
TAG:LaTeX |