# TeX and PDF Synchronization

Skim offers powerful integration with LaTeX.

## Contents

Skim can recognize when the PDF file is updated on disk, for example by a LaTeX process. Skim then offers to reload the file. If you choose Auto from the dialog, Skim will reload this document without asking for future updates.

Use this feature with care, as reloading the file will typically lose any notes. If you have unsaved edits, Skim will always ask you whether to reload, even if you have previously chosen Auto. When you choose No, you can still reload manually by choosing Revert from the File menu.

This feature should be turned on in the LaTeX preferences.

Even though we offer this feature, we discourage you from using it. In general, the only reliable way to automatically reload the document is by triggering the reload yourself from a script as the one below, which therefore is the preferred approach.

Note: Skim's automatic file updating mechanism gets disabled when the PDF file is deleted before it is replaced, because Skim tracks the file object rather than the location of the file. This is by design for good reasons, and it is the way any document based Cocoa application works. Some TeX scripts (e.g. simpdftex) remove the PDF file, and therefore Skim will not automatically reload the file produced by such processes.

Note: The auto-reload functionality will not work properly when you have to run a latex process more than once, for example to support references generated by bibtex, because Skim will be trying to reload the document when the second latex process is busy. You could instead run latex and bibtex together with forcing a Skim reload using the script below.

```#!/bin/bash

# the first argument should be the tex file, either with or without extension
file="\$1"
[ "\${file:0:1}" == "/" ] || file="\${PWD}/\${file}"
pdffile="\${file%.tex}.pdf"

# run pdflatex and bibtex, and open or reload the pdf  in Skim
pdflatex "\${file}" && bibtex "\${file}" && pdflatex "\${file}" && pdflatex "\${file}" && \
/usr/bin/osascript << EOF
set theFile to POSIX file "\${pdffile}" as alias
set thePath to POSIX path of theFile
tell application "Skim"
activate
set theDocs to get documents whose path is thePath
try
if (count of theDocs) > 0 then revert theDocs
end try
open theFile
end tell
EOF
```

Warning: When you use a script like this that uses the revert command, you should not turn on the auto-reload functionality in the preferences, as the different reverting processes can interfere with each other, with unexpected consequences.

## TeX-PDF Synchronization

If you are using the PDFSync package or you use SyncTeX, you can switch back and forth between the PDF document and the text editor. To support PDFSync, at a minimum, your latex documents needs to contain a \usepackage{pdfsync} line. To use SyncTeX you need to use a TeX distribution that includes this new technology (e.g. TeX Live 2008) and supply the command line option -synctex=1 to the tex command. You can also include \synctex=1 in the preamble of your latex file.

There are two actions TeX-PDF synchronization may allow you to perform:

1. Show a line in the LaTeX document corresponding to a point in the PDF in Skim (backward search)
2. Show a point in the PDF in Skim corresponding to a line in the LaTeX document (forward search)

You may need to setup Skim and your LaTeX editor to make either one of these work.

### Activating backward search from Skim

Assuming that you've set up Skim, as detailed below, Shift-Command-click on a point in a PDF document shown in Skim can open the LaTeX source file in a text editor, and have it jump to the corresponding line in the LaTeX file (backward search).

#### Choosing an editor command for backward search

To be able to do backward searches, you'll need to tell Skim how to find your favorite text editor. You do so in the Sync preferences.

This should work through a script or command line tool that opens the editor and let it jump to a given line. Several advanced text editors, such as TextMate, BBEdit, TextWrangler, Emacs, and Aquamacs, come with such tools. Some of them let you install those tools on your system.

You can choose the editor command and its arguments in the Sync preferences of Skim. Some presets are defined for common text editors. You can still customize the command for these presets by first selecting the preset editor from the popup, and then selecting Custom. You can then edit the path to the command. For example, you could give the full path to the tool inside the application bundle. Usually the tool can be found in the Resources folder. For example, for TextMate the full path for the editor command is /Applications/TextMate.app/Contents/Resources/mate. For the preset editors, Skim will always try to locate the tool in the editor's application bundle before it searches in /usr/bin or /usr/local/bin, so the tool does not always need to be installed for those editors.

For custom editor commands, you don't need to provide a full path when the script is located in /usr/bin, /usr/local/bin, ~/Library/Application Support/Skim/bin, or in a location in your PATH.

In the arguments for the editor command, you can use %line as a placeholder for the line number in the LaTeX file, and %file as a placeholder for the full path to the LaTeX file. Make sure you enclose the the latter in double-quotes as "%file", so spaces in the path will be properly escaped.

The line numbers Skim substitutes for %line are 1-based. If your editor expects 0-based line numbers, you may use the construct \$((%line-1)).

#### Editor script for TeXShop

TeXShop does not have a built-in script for Skim to call. But you can write a custom script to do open TeXShop from Skim. An example script is the following.

```#!/bin/bash

file="\$1"
line="\$2"

[ "\${file:0:1}" == "/" ] || file="\${PWD}/\${file}"
[ "\${line}" == "" ] && line=1

osascript << EOF
set texFile to POSIX file "\${file}"
tell application "TeXShop"
activate
open texFile
tell front document
refreshtext
goto line \${line}
end tell
end tell
EOF
```

Save it to e.g. /usr/local/bin/texshop, make it executable, and set the editor command in Skim's preferences to texshop (you may need to use the full path) and the editor arguments to "%file" %line.

You could use such a script also for other scriptable editor aplications.

#### Editor Script for VIM

To call VIM, you can use the following script. Copy this script, and save it somewhere. Make sure you make it executable. Set the editor command in the Skim preferences to the path to the script, and the editor arguments to "%file" %line. (Thanks to Ted Pavlic.)

```#!/bin/bash

file="\$1"
line="\$2"

[ "\${file:0:1}" == "/" ] || file="\${PWD}/\$file"

osascript << EOF
set ESC to ASCII character 27
tell application "Vim" to activate
tell application "System Events"
tell process "Vim"
keystroke ESC & ":set hidden" & return
keystroke ":if bufexists('\$file')" & return
keystroke ":exe \\":buffer \\" . bufnr('\$file')"  & return
keystroke ":else " & return
keystroke ":    edit \${file// /\\\\ }" & return
keystroke ":endif" & return
keystroke ":\$line" & return
keystroke "zO"
end tell
end tell
EOF
```

#### Considerations for Emacs

Some older versions of Emacs may require some extra changes to the .emacs configuration file to work properly for backward search. Also be aware that some versions of Emacs may not support backward search at all. Moreover, Emacs needs to be running for backward search to work.

For Emacs.app and Aquamacs.app, the default tool emacsclient requires Emacs to be running for Skim to be able to call it. You may also use a simple script as the editor command, such as this script to open Emacs and load a file at a particular line.

For Skim to be able to call Emacs, you may need to put the following code in your .emacs file:

```;; Starts the Emacs server
(server-start)
```

In addition, most people would want to make Emacs auto-raise when Skim opens it. If it doesn't do so, you can make it raise by adding the following lines:

```;; Auto-raise Emacs on activation
(defun raise-emacs-on-aqua()
(shell-command "osascript -e 'tell application \"Emacs\" to activate' &"))
```

The ampersand after activate makes the command slightly more robust, but also opens up an *Async Shell Command*. You may experiment with removing it.

### Setting up your editor for forward search

When you use TeX-PDF synchronization, Skim can load the PDF document and jump to the page corresponding to a line in the LaTeX file (forward search). To be able to do this, you'll need to set up your editor to call this script:

```/Applications/Skim.app/Contents/SharedSupport/displayline %line "%pdffile" "%texfile"
```

The argument %line is the line number in the LaTeX file, "%pdffile" is the PDF file, and "%texfile" is the LateX source file. The last argument "%texfile" is optional. If it isn't supplied, it's derived from the "%pdffile" argument. It can be useful for multi-file LaTeX projects. Paths can be relative to the current directory for the script.

Just as for backward search, line numbers passed to the displayline script are expected to be 1-based. If your editor supplies 0-based line numbers you can use a construct like \$((%line+1)).

If you pass an extra -r option to the displayline script, Skim will also revert the PDF file when it was already open.

```/Applications/Skim.app/Contents/SharedSupport/displayline -r %line "%pdffile" "%texfile"
```

Warning: If you use the revert option, you should turn off the auto-reload feature in the Sync preferences.

Refer to the documentation and help of your favorite text editor to find out how to be able to execute scripts and supply the arguments.

If you pass an extra -b option to the displayline script, Skim will indicate the line using thew reading bar rather than a selection.

#### Setting up TextMate

TextMate now has native support for TeX-PDF synchronization in Skim, which is included with the LaTeX bundle. To activate it, choose "Show in PDF Viewer (pdfsync)" from the Latex pop-up menu.

TextMate should also do the reloading for Skim after typesetting, so it is best to turn off automatic checking for file changes on the Skim Sync preference pane.

#### Setting up Vim

To activate forward searching in Vim, open .vimrc and add a mapping:

```map ,r :w<CR>:silent !/Applications/Skim.app/Contents/SharedSupport/displayline <C-r>=line('.')<CR> %<.pdf %<CR>
```

(the <C-r>=line('.')<CR> argument is the only way I could find to retrieve the current line number in the Vim file.

#### Setting up Emacs

Some newer versions of Emacs, in particular Aquamacs Emacs version 1.3 and later, may already have TeX-PDF synchromization support for Skim built in, so you don't need to do anything to make TeX-PDF synchromization work with Skim. Otherwise you may make the following changes to your .emacs file.

```;; The following only works with AUCTeX loaded
(require 'tex-site)
(lambda ()
'("^pdf\$" "."
"/Applications/Skim.app/Contents/SharedSupport/displayline %n %o %b")))
)
```

Additionally, you probably want to set the following default values. The second one is only relevant if you use multi-file LaTeX projects.

```;; Use PDF mode by default
(setq-default TeX-PDF-mode t)
;; Make emacs aware of multi-file projects
(setq-default TeX-master nil)
```

#### Opening Skim from other editors

If you use latex with some other editor, for example VIM from the command line, you could always use a custom script to open a file in Skim. Save the following script to a file, and make sure it is executable.

```#!/bin/bash

file="\$1"
[ "\${file:0:1}" == "/" ] || file=\${PWD}/\${file}

osascript << EOF
tell application "Skim"
activate
open POSIX file "\${file}"
end tell
EOF
```