pdflatex를 사용하여 PDF에서 보이지 않는 마커

pdflatex를 사용하여 PDF에서 보이지 않는 마커

나는 latexdiff큰 텍스트(200페이지 이상)에서 변경한 내용을 표시하는 데 사용하고 있습니다. 하지만 대부분의 변경 사항은 몇 페이지에만 영향을 미치므로 독자들이 오타 수정이 적용된 드문 페이지를 찾기 위해 200페이지를 샅샅이 뒤지는 것을 원하지 않습니다. 200페이지 중 약 30pp에만 변경 사항이 포함됩니다.

나는 다음을 원한다:

  1. 변경 사항이 발생한 페이지에 숨겨진 PDF 마커 삽입
  2. pdflatex로 컴파일하기
  3. 숨겨진 PDF 마커가 포함되지 않은 페이지를 필터링하는 스크립트 실행

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

누군가 추천해 주실 수 있나요?

  • PDF 파일에 일종의 "마커"를 삽입하기 위한 tex 패키지
  • PDF를 읽고 해당 마커를 찾기 위한 Python 패키지

답변1

\write내 첫 번째 생각은 I/O 파일 작업(예: 또는 ) 을 사용하는 것이었지만 \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.findLuaTeX에서 사용했습니다 . 이 단계의 터미널에는 다음과 같은 메모가 있습니다 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.

  • 나머지는 비교적 쉬웠습니다. 나는 \includepdf[pages={1,2,4,7,8},fitpaper]{filter.pdf}그것을 문서 본문으로 가져와서 배송하기 위해 LaTeX 명령을 만들었습니다 .

저는 LuaTeX에서 두 개의 매개변수로 명명된 간단한 함수를 만들었습니다 testme. 첫 번째 매개변수는 테스트된 파일( filter)을 요청하고, 코드는 해당 파일 auxpdf파일을 사용하며, 두 번째 매개변수는 우리가 사용하고 있던 접두사를 요청합니다(이론적으로는 더 많은 접두사), malipivo. 실제 조판은 에 의해 수행됩니다 \directlua{testme("filter","malipivo")}.

filtered.tex한 번 실행될 코드( )를 첨부 하고 마지막으로 원본 코드( )에 표시된 lualatex선택된 페이지( )의 미리보기를 첨부합니다 .filtered.pdffilter.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

관련 정보