使用 pdflatex 在 PDF 中隱藏標記

使用 pdflatex 在 PDF 中隱藏標記

我用來latexdiff顯示我在大文本(200 多頁)中所做的更改。不過,我的大部分更改只影響幾頁,因此我不希望讀者在 200 頁中篩選,尋找進行了孤立的拼寫錯誤更正的罕見頁面:200 頁中只有大約 30 頁包含更改。

我想:

  1. 在發生變更的頁面上插入隱藏的 PDF 標記
  2. 使用pdflatex編譯
  3. 執行一個腳本來過濾掉不包含隱藏 PDF 標記的頁面

    book.tex -latexdiff-> book_diff.tex -pdftex-> 200pp.pdf -script-> 30pp.pdf

有人可以推薦:

  • 用於在 PDF 檔案中插入某種「標記」的 tex 包
  • 一個用於閱讀 PDF 的 python 套件(並尋找所述標記)

答案1

我的第一個想法是使用 I/O 檔案操作,例如\writeor \immediate\write,但它面臨著浮動物件及其行為的已知問題。當沒有\global前綴時,我也遇到了關於帶有自己的計數器的浮動物件的問題。

我寧願直接使用交叉引用來確保受保護的寫入。我可以在 LuaTeX 的幫助下為您提供這個解決方案。處理的步驟為:

  • 我們排版常規文件並標記位置。就本文而言,它是一個可見的標記,並且是一個頁碼。該定義使用\label帶有特定前綴的常規命令,例如malipivo。我將文件filter.tex和命令命名為\writeme.該命令使用自己的計數器,確保\label命令中標記的唯一性。
  • 根據實際排版資料,文件filter.tex被處理多次,在本例中為兩次。第一次運行後,我們得到一個帶有兩個紅色問號的文檔(預覽中的第 1 行),第二次運行後,我們得到正確排版的交叉引用(預覽中的第 2 行)。

這是代碼:

%! *latex filter.tex
%! Run me twice or even more times to get references right.
\def\myprefixis{malipivo}

\documentclass[a4paper]{article}
\usepackage{tikz}
\usepackage[numbers]{kantlipsum}
\newcount\mycounter 
\mycounter=0
% Our own marker...
% Save the reference and mark it...
\def\writeme{%
\global\advance\mycounter by 1%
\label{\myprefixis\the\mycounter}%
\begin{tikzpicture}%
\begin{pgfinterruptboundingbox}%
\node[red,font=\bfseries\Huge,scale=4]{\pageref{\myprefixis\the\mycounter}};%
\end{pgfinterruptboundingbox}%
\end{tikzpicture}%
  }% End of \writeme...

\begin{document}
\section{My experiment}
\kant[1-2]\writeme
\kant[14]\writeme
\kant[15-16]\writeme
\kant[25]\writeme\ There is a typo and\writeme\ one more\writeme
\kant[26-32]\writeme
\kant[46]\writeme
\begin{figure}[p]
\kant[51] I am floating.\writeme
\end{figure}
\kant[52-61]\writeme
\end{document}

第一次運行後的filter.pdf 第二次運行後的filter.pdf

該文件的內容filter.aux如下所示:

\relax 
\@writefile{toc}{\contentsline {section}{\numberline {1}My experiment}{1}}
\newlabel{malipivo1}{{1}{1}}
\newlabel{malipivo2}{{1}{1}}
\newlabel{malipivo3}{{1}{2}}
\newlabel{malipivo4}{{1}{2}}
\newlabel{malipivo5}{{1}{2}}
\newlabel{malipivo6}{{1}{2}}
\newlabel{malipivo7}{{1}{4}}
\newlabel{malipivo8}{{1}{4}}
\newlabel{malipivo10}{{1}{7}}
\newlabel{malipivo9}{{1}{8}}

malipivo10您實際上可以看到,當數字交換為其頁碼對應項( <-> malipivo9; 7<-> 8)時,存在一些浮動物件。我們需要以某種方式處理這個輔助文件並從 中提取頁面filter.pdf。我使用 LuaTeX 和pdfpages包。

  • 起初我以為我需要對行進行排序,但似乎沒有必要,它已經按頁碼排序,而不是按標記排序。

  • 但是,我需要提取malipivo包含前綴的行並跳過其他行。我用的string.find是LuaTeX。此步驟中的終端機中有一條註釋,表示Testing note on page 1...

  • 然後我需要提取頁碼來獲取1 1 2 2 2 2 4 4 7 8,我使用了該string.gsub函數。

  • 我必須確保每個頁面僅包含一次,因此我們應該1 2 4 7 8在刪除重複項後獲得這個數字序列。

  • 我的下一步是添加逗號,我在連接臨時字串時這樣做了。我們快要到了1,2,4,7,8

  • 剩下的就相對容易了。我用它創建了一個 LaTeX 命令來獲取\includepdf[pages={1,2,4,7,8},fitpaper]{filter.pdf}並將其發送到文檔正文。

我在 LuaTeX 中創建了一個簡單的函數,命名testme為兩個參數,第一個參數要求測試文件 ( filter),程式碼使用它的auxpdf文件,第二個參數要求我們使用的前綴(理論上,可能有更多前綴),我使用了malipivo.實際的排版是由 完成的\directlua{testme("filter","malipivo")}

filtered.tex我附上要運行一次的程式碼 ( ) lualatex,最後預覽filtered.pdf在原始程式碼 ( filter.tex) 中標記的選定頁面 ( )。

%! lualatex filtered.tex
%! run me only once
\documentclass{article}
\usepackage{pdfpages}
\usepackage{luacode}

\begin{document}

\begin{luacode*}
function testme (filtering, thekey)
-- Initializing variables...
local myinput=filtering..".aux" -- Where are the reference?
local myinputpdf=filtering..".pdf" -- Where are the real PDF pages?
local mylines="" -- List of pages to get is?
local mycount=0 -- How many tested reference do we have?
local lastcount="" -- What is the previous reference?
-- The core of the function...
for mylinetemp in io.lines(myinput) do -- Read input file line by line
  test=string.find(mylinetemp,thekey) -- Is a unique key involved? 
  if test~=nil then -- Yes, the key is present there...
    myline=string.gsub(mylinetemp,"\\newlabel{"..thekey..".-}{{.-}{(.-)}}", "%1", 1) -- Find a group with page reference.
    print("Testing note on page "..myline.."...") -- Print information to the terminal
    mycount=mycount+1 -- Increase a number of tested references
    if mycount==1 then -- Save the first value as the starting value
      mylines=myline -- Start the resulting string
      lastcount=myline -- Remember the last occurance
    else -- Add value to the list if not already stored in the list
      if lastcount~=myline then -- But only if last two values differ (aka uniq)
        mylines=mylines..","..myline -- Add comma and value to the string (aka join)
        lastcount=myline -- Remember this occurance as the last one for next testing
      end -- of if not lastcount
    end -- of if mycount
  end -- of if thekey is involved
end -- of myline
-- Print the results and generate PDF via regular typesetting...
local keyresult="\\includepdf[pages={"..mylines.."},fitpaper]{"..myinputpdf.."}"
print(keyresult)
tex.print(keyresult)
end -- of function testme
\end{luacode*}

% The tested file, e.g. filter.{aux,pdf}, and its reference label prefix.
\directlua{testme("filter","malipivo")}

\end{document}

過濾.pdf

答案2

好的,我寫了工作管道的初稿。

  • 根據@ChristianH的建議,我使用了pdf註釋
  • 對於腳本,我使用了:

代碼在這裡: https://gist.github.com/ivanistheone/219dad11a30efef82b7e

相關內容