Vim Tips Wiki
No edit summary
Line 1: Line 1:
  +
I merged what I thought was the good stuff into [[Open pdf to the current location in a LaTeX file]].
When you are editing a large LaTeX project, it is easy to jump around in Vim using tags, marks, file tree plugins, etc. One problem is after you jump to a tag in Vim the pdf open in other window does not change page. This tip will allow you to add a command to vim to change the page of the pdf to match the current location in Vim.
 
  +
{{TipProposed
 
  +
|id=0
== Finding pdf filename and line for current cursor ==
 
  +
|previous=0
 
  +
|next=0
First, copy one of the OpenPDF functions below specific to your operating system.
 
  +
|created=February 20, 2011
Then drop the following functions in your tex.vim ftplugin file or your vimrc file
 
  +
|complexity=basic
  +
|author=
  +
|version=7.0
  +
|subpage=/201102
  +
|category1=LaTeX
  +
|category2=
  +
}}
  +
When using Adobe Reader on Windows to view pdf files, the current file is locked. That makes it necessary to close the pdf file before recompiling a tex file into pdf. An easy way to do so is to use [http://www.istri.fr/zip/CMCDDE.zip cmcdde].
   
  +
To close the pdf output file of the currently edited tex file one would use:
 
<pre>
 
<pre>
 
!start cmcdde acroviewr10 control [DocOpen("%:p:r.pdf")][DocClose("%:p:r.pdf")]
"Load PDF to the page containing label
 
function! LoadEvinceByLabel(l)
 
for f in split(glob("*.aux"))
 
let label = system('grep "^.newlabel{' . a:l . '" ' . f)
 
let page = matchstr(label, '.\{}{\zs.*\ze}}')
 
if ! empty(page)
 
call OpenPDF(substitute(f, "aux$", "pdf", ""), page)
 
return
 
endif
 
endfor
 
endfunction
 
 
"Load PDF to the page containing the nearest previous label to the cursor
 
function! EvinceNearestLabel()
 
let line = search("\\label{", "bnW")
 
if line > 0
 
let m = matchstr(getline(line), '\\label{\zs[^}]*\ze}')
 
if empty(m)
 
echomsg "No label between here and start of file"
 
else
 
call LoadEvinceByLabel(m)
 
endif
 
endif
 
endfunction
 
 
</pre>
 
</pre>
   
  +
Here <tt>DocOpen</tt> registers the pdf with the dde server. <tt>DocClose</tt> then closes the pdf.
The first function looks through the aux files created by compiling the latex file for the label
 
passed in as a parameter. If it finds the label, it loads the page number and then loads the pdf to the given page.
 
The second function searches for the nearest label from the current position and calls LoadEvinceByLabel.
 
   
  +
The name Adobe uses for the DDE server changed from version 9 to 10. For Adobe Reader versions prior to 10 use <tt>acroview</tt> instead of <tt>acroviewr10</tt>. Adobe announced that future versions will also have the version number in the server name.
To use them, add something like
 
   
  +
==Automatically close pdf before compiling==
  +
To automatically close Adobe before recompiling using the vim-latex suite, put the following in the <tt>tex.vim</tt> file:
 
<pre>
 
<pre>
  +
if has("win32")
map <buffer> <LocalLeader>e :call EvinceNearestLabel()<CR>
 
 
let s:AcroDDE = "cmcdde acroviewr10 control "
  +
let s:ClosePdf = s:AcroDDE.'[DocOpen("%:p:r.pdf")][DocClose("%:p:r.pdf")] '
 
let g:Tex_CompileRule_pdf = s:ClosePdf.' & texify -bp --src $*'
 
let g:Tex_ViewRule_pdf =
 
\ 'C:\Program Files (x86)\Adobe\Reader 10.0\Reader\AcroRd32.exe'
 
endif
 
</pre>
 
</pre>
   
  +
This configuration assumes that the folder containing cmcdde is in your path. Alternatively just specify the full path name to <tt>cmcdde</tt> in <tt>s:AcroDDE</tt>.
Now \e will load the pdf viewer to page containing the nearest label to the current cursor position. Note this works great on multi-file projects since the aux file is searched to find the pdf name. So you can jump around in Vim using all the wonderful tools and plugins (tags, marks, nerdtree, project, etc.) and then tell the pdf viewer to jump to the given page.
 
   
  +
==Comments==
If you have set up tags, you can also add
 
  +
There are also a few other DDE commands available with the Adobe Reader. Most interestingly, <tt>DocGoTo</tt> and <tt>DocGoToNameDest</tt>. The first can be used to jump to a particular page in the pdf while the second jumps to a named destination. I haven't figured out yet how to do so, but maybe one could use the second one to implement some sort of forward search with the Adobe Reader. (The idea is to call <tt>DocGoToNameDest</tt> with a fixed bookmark, say "cursorposition", and use latex to create that bookmark when compiling. Not sure if there exists some latex packet which could be used for that.)
   
  +
Here is a little trick to open Adobe Reader on the last page. Just use <tt>DocGoTo</tt> with a large page number (which doesn't need to exist):
 
<pre>
 
<pre>
 
!start cmcdde acroviewr10 control [DocOpen("%:p:r.pdf")][DocGoTo("%:p:r.pdf,10000")]
com! -nargs=1 -complete=tag Pdf call LoadEvinceByLabel("<args>")
 
 
</pre>
 
</pre>
 
for a command :Pdf that you can use tab completion on labels to jump to a given location.
 
 
== Linux ==
 
 
On linux, use the following OpenPDF function
 
 
<pre>
 
function! OpenPDF(file,page)
 
exec 'silent ! evince --page-label=' . a:page . ' ' . a:file . ' > /dev/null 2>&1 &'
 
endfunction
 
</pre>
 
 
Evince is smart enough so that if the pdf is already open, it just changes the page of the existing
 
window and if the file is not open yet, it creates the new window and jumps to the given page.
 
 
== Windows ==
 
 
==== Acrobat ====
 
 
This is currently untested since I don't have access to a windows machine.
 
If you have access to a windows machine and test it and it works, delete this line.
 
Commands can be sent to acrobat using [http://www.istri.fr/zip/CMCDDE.zip]
 
 
<pre>
 
function! OpenPDF(file, page)
 
exec '!start cmcdde acroviewr10 control [DocOpen("' . a:file . '")][DocGoTo("' . a:file . ',' . a:page . '")]'
 
endfunction
 
</pre>
 
 
If you use the vim-latexsuite plugin, acrobat needs to be closed before compiling which can be done with the following
 
commands.
 
 
<pre>
 
let s:AcroDDE = "cmcdde acroviewr10 control "
 
let s:ClosePdf = s:AcroDDE.'[DocOpen("%:p:r.pdf")][DocClose("%:p:r.pdf")] '
 
let g:Tex_CompileRule_pdf = s:ClosePdf.' & texify -bp --src $*'
 
let g:Tex_ViewRule_pdf =
 
\ 'C:\Program Files (x86)\Adobe\Reader 10.0\Reader\AcroRd32.exe'
 
</pre>
 
 
== Mac ==
 
 
Your help is needed. Some AppleScript in OpenPDF should do the job.
 
[[Category:LaTeX]]
 
[[Category:LaTeX]]
 
[[Category:LaTeX]]
 
[[Category:LaTeX]]
 

Revision as of 03:44, 28 November 2011

I merged what I thought was the good stuff into Open pdf to the current location in a LaTeX file.

Proposed tip Please edit this page to improve it, or add your comments below (do not use the discussion page).

Please use new tips to discuss whether this page should be a permanent tip, or whether it should be merged to an existing tip.
created February 20, 2011 · complexity basic · version 7.0

When using Adobe Reader on Windows to view pdf files, the current file is locked. That makes it necessary to close the pdf file before recompiling a tex file into pdf. An easy way to do so is to use cmcdde.

To close the pdf output file of the currently edited tex file one would use:

!start cmcdde acroviewr10 control [DocOpen("%:p:r.pdf")][DocClose("%:p:r.pdf")]

Here DocOpen registers the pdf with the dde server. DocClose then closes the pdf.

The name Adobe uses for the DDE server changed from version 9 to 10. For Adobe Reader versions prior to 10 use acroview instead of acroviewr10. Adobe announced that future versions will also have the version number in the server name.

Automatically close pdf before compiling

To automatically close Adobe before recompiling using the vim-latex suite, put the following in the tex.vim file:

  if has("win32")
    let s:AcroDDE = "cmcdde acroviewr10 control "
    let s:ClosePdf = s:AcroDDE.'[DocOpen("%:p:r.pdf")][DocClose("%:p:r.pdf")] '
    let g:Tex_CompileRule_pdf = s:ClosePdf.' & texify -bp --src $*'
    let g:Tex_ViewRule_pdf =
            \ 'C:\Program Files (x86)\Adobe\Reader 10.0\Reader\AcroRd32.exe'
  endif

This configuration assumes that the folder containing cmcdde is in your path. Alternatively just specify the full path name to cmcdde in s:AcroDDE.

Comments

There are also a few other DDE commands available with the Adobe Reader. Most interestingly, DocGoTo and DocGoToNameDest. The first can be used to jump to a particular page in the pdf while the second jumps to a named destination. I haven't figured out yet how to do so, but maybe one could use the second one to implement some sort of forward search with the Adobe Reader. (The idea is to call DocGoToNameDest with a fixed bookmark, say "cursorposition", and use latex to create that bookmark when compiling. Not sure if there exists some latex packet which could be used for that.)

Here is a little trick to open Adobe Reader on the last page. Just use DocGoTo with a large page number (which doesn't need to exist):

!start cmcdde acroviewr10 control [DocOpen("%:p:r.pdf")][DocGoTo("%:p:r.pdf,10000")]