Vim+TeX로 페이지 추적

11837 단어 VimTeX

TL;DR



이런 일을 할 수 있게 되었습니다.


이번에 소개하는 플러그인



xuhdev/vim-latex-live-preview
Vim에서 TeX의 실시간 미리보기를 가능하게하는 플러그인입니다.
이번에는 이것에 페이지 추적을 추가합니다.

플러그인 도입



플러그인 관리자로 dein을 사용하는 경우 이것으로 작동한다고 생각합니다.
pdf 뷰어는 evince를 지정합니다. 시도한 한 evince가 가장 잘 움직였습니다.
pLaTeX가 아닌 LuaLaTeX를 지정하는 이유는 중간 파일을 만들지 않고 직접 pdf를 출력하기 때문입니다.jsarticle/jsreport/jsbook 와 높은 호환성이 있는 문서 클래스 ltjsarticle/ltjsreport/ltjsbook 가 있으므로, 표지 템플릿이 pLaTeX판으로 건네받는 등 해도 간단하게 대응할 수 있다고 생각합니다.

~/.vim/rc/dein_lazy.toml
[[plugins]]
repo = 'xuhdev/vim-latex-live-preview'
on_ft = 'tex'
hook_add = '''
  let g:livepreview_previewer = 'evince'
"  let g:livepreview_engine = 'luajittex --fmt=luajitlatex.fmt' "コンパイル速度を上げたい場合はこちら
  let g:livepreview_engine = 'lualatex'
  set swapfile
  set updatetime=1000
'''

추가할 함수



직접 플러그인을 변경하지 않으려면 여기

소스 코드의 행 번호와 생성된 PDF의 페이지 번호의 대응을 덤프하는 함수



~/dein/repos/github.com/xuhdev/vim-latex-live-preview/plugin/latexlivepreview.vim
function! s:Preprocess(file)
execute s:py_exe "<< EEOOFF"
with open(vim.eval("a:file"), "r") as f:
    lines = f.readlines()
for i in range(len(lines) - 1):
    lines[i] = '\write\pagedump{\    \\thepage ,}' + lines[i]
lines[-1] = '\write\pagedump{\    \\thepage ]}' + lines[-1]
lines.insert(0, '\\newwrite\pagedump\n')
lines.insert(1, '\openout\pagedump=pagedump.txt\n')
lines.insert(2, '\write\pagedump{let pagedump = [}')
lines.append('\closeout\pagedump')
with open(vim.eval("a:file"), "w") as f:
    f.writelines(lines)
EEOOFF
endfunction

이 함수의 움직임을 설명합니다. 다음과 같은 TeX 소스 코드가 있었을 때,

before_preprocess.tex
\documentclass{ltjsarticle}
\begin{document}
page1
\newpage
page2
\end{document}

다음과 같이 컴파일하기 전에 전처리를 합니다.

after_preprocess.tex
\newwrite\pagedump
\openout\pagedump=pagedump.txt
\write\pagedump{let pagedump = [}
\write\pagedump{\ \thepage ,}\documentclass{ltjsarticle}
\write\pagedump{\ \thepage ,}\begin{document}
\write\pagedump{\ \thepage ,}page1
\write\pagedump{\ \thepage ,}\newpage
\write\pagedump{\ \thepage ,}page2
\write\pagedump{\ \thepage ]}\end{document}
\closeout\pagedump

컴파일하면 다음과 같은 배열의 정의 파일이 $TEXMFOUTPUT/pagedump.txt에 내보내집니다.
이것을 vim에서 source pagedump.txt 하는 것으로 커서행과 pdf의 페이지 번호의 대응을 취급할 수가 있습니다.

pagedump.txt
let pagedump = [
\ 1,
\ 1,
\ 1,
\ 1,
\ 2,
\ 2]
s:Compile() 의 말미에서 컴파일 직전에 s:Preprocess 를 부르도록(듯이) 재기록합니다.

~/dein/repos/github.com/xuhdev/vim-latex-live-preview/plugin/latexlivepreview.vim
    " Write the current buffer in a temporary file
    silent exec 'write! ' . b:livepreview_buf_data['tmp_src_file']
    call s:Preprocess(b:livepreview_buf_data['tmp_src_file'])
    call s:RunInBackground(b:livepreview_buf_data['run_cmd'])
    lcd -
endfunction

evince에 페이지 번호를 지정하는 키 스트로크를 던지는 함수



내가 사용하고 있는 WSL과 Xming의 조합에서는, WSL내에서 xdotool로 키를 던지면 Xming이 취급하고 있는 윈도우 중, 최근에 선택된 윈도우에 던진다. 라는 거동이 되고 있습니다.
따라서 Vim에서 포커스를 제거하지 않고 뒷면의 evince에 키 스트로크를 던질 수 있습니다.
물론 다른 환경에서는 이 함수를 다시 작성해야 합니다.

~/dein/repos/github.com/xuhdev/vim-latex-live-preview/plugin/latexlivepreview.vim
function! g:EvinceGoTo()
    execute 'source '                   .
    \ b:livepreview_buf_data['tmp_dir'] .
    \      expand('%:p:h')              .
    \      '/pagedump.txt'
    call system("xdotool key 'ctrl+l'")
    call system("xdotool key 'ctrl+a'")
    call system("xdotool key " . g:pagedump[getcurpos()[1]-1])
    call system("xdotool key KP_Enter")
endfunction

조작방법


:LLPStartPreview 로 evince 를 표시한 후 :call EvinceGoTo() 로 커서 행의 페이지가 표시됩니다.

~/dein/repos/github.com/xuhdev/vim-latex-live-preview/plugin/latexlivepreview.vim
nnoremap <Leader>e :<C-u>call EvinceGoTo()<CR>

로 하면 Space e 입니다. (나는 <Leader> 에 공백을 지정하고있다)
다만, 현재 :call EvinceGoTo() 마다 pagedump.txt 를 읽으러 가고 있기 때문에, autocmd cursormoved 로 훅 하려면 좀 더 pagedump.txt 의 독해 타이밍을 궁리할 필요가 있을 것 같습니다.



내일은 크리스마스 이브군요, VimConf2018에서는 Dark Powered한 발표로 화제였던 Λlisue씨의 기사가 됩니다.
전혀 상관없지만 아래는 대학에서 최근 보인 포스터입니다. 도대체 모델은 뭐 뭐야? .

그러고 보니 VimConf2018에서는 Vim의 아버지 Bram씨로부터 사인을 받았습니다.

Vim의 아버지 Bram씨로부터 Surface에 사인 받았다! #vimconf 피 c. 라고 r. 이 m/5L52g5v8에d — ℕ (@mathbbN) 2018년 11월 24일


그러면 Happy Vimming!


좋은 웹페이지 즐겨찾기