TeXlive: a Powershell workaround for inverse search

Bottom line first: the hack described in this post allows you to use TeXlive on Windows with fully functioning (forward and) inverse search using SumatraPDF. The big win relative to MikTeX is that spaces in file paths are OK. Also, hopefully the hack will soon be rendered unnecessary by a Sublime Text 2 revision.

The details: as I describe in this post, while it is easy to get TeXlive on Windows to work with my Sublime Text 2 LaTeXTools plugin, inverse search is problematic. This is a pity because, unlike MikTeX, TeXlive can generate sync data even if the path to a source file includes spaces. However, “out of the box”, somehow inverse search fails with SumatraPDF and Sublime Text 2.

I set out to investigate this issue; this led to two bug reports and a temporary workaround. For apparently good, but to me unfathomable reasons, the official version of synctex, which TeXlive uses, needs to express source path names in the form


where the “\.\” is of course redundant–“\” would be enough (synctex behaves similarly on OSX and Linux, by the way). MikTeX uses a modified version of synctex that employs “normal” path names, but cannot handle spaces. Unfortunately, up to Version 1.7, and indeed dev version 1.8.4430, upon double-clicking in the PDF file, SumatraPDF initiated an inverse search by passing the augmented path specification to the designated editor. Even more unfortunately, Sublime Text 2 treats the “normal” and the “extended” forms of the path as two different files, so if you already had “test.tex” open in a tab, you will get another tab with exactly the same content, just a different path specification. TeXnicCenter 2 alpha 3 has the same behavior (note: I am told that TeXnicCenter 1 does not, but I haven’t checked).

I reported the issue to the SumatraPDF developers, who promptly issued a fix. Beginning with dev version 1.8.4434, the “\.\” is removed from the path specification (i.e. the path is “normalized”). This, it turns out, makes TeXnicCenter 2 alpha 3 happy enough.

However, all is not good. It turns out that, by normalizing the path, SumatraPDF always uses a lowercase drive letter: “c:”, not “C:”. TeXnicCenter has no problem with this: “C:\file.txt” and “c:\file.txt” are treated as the same file. This is as it should be; case shouldn’t matter as far as drive letters are concerned.

Unfortunately, Sublime Text 2 treats “C:\file.txt” and “c:\file.txt” as two different files. Again, upon invoking inverse search, another tab is opened. Despair!

I reported both the “\.\” issue and the drive letter case issue on the Sublime Text tech support forum (incidentally, if you look at my forum post, you will find that the drive letter issue comes up in very subtle ways). The developer, jps, was prompt and courteous as always. He fixed the “\.\” issue (on all platforms) beginning with dev version 2116. However, as of today (9/15/2011) the drive letter case issue is still open.

So, here’s the hack / workaround. Create a new file called “st2clean.ps1” with the following content (I wish I could simply upload the file, but WordPress won’t let me). Yes,this is a Powershell script!

# Clean up file name and invoke ST2
# Syntax: powershell.exe st2clean.ps1 <path as given by SumatraPDF> <line number>
# In SumatraPDF, use the following line to launch inverse search
# note the SINGLE QUOTES for both the path and the file name:
# http://www.powershell.nu/2009/12/16/running-scripts-with-arguments-in-powershell/
# powershell.exe  &'<path to st2clean.ps1>' '%f' %l
# Finally, don't forget to enable the execution of scripts: e.g. in a Powershell window, do
# Set-ExecutionPolicy RemoteSigned
# cf. http://technet.microsoft.com/en-us/library/ee176949.aspx
# On PS 2.0 (Win7) you can also invoke powershell.exe like so, without setting anything:
# powershell -executionPolicy RemoteSigned <as above>
# You can also give "-WindowStyle Hidden" to have the console only "flash by" quickly

$file = $args[0]
$line = $args[1]

# Just in case, we make sure that the path name does begin with a drive spec
# Use cmatch so we do nothing if the drive letter is already uppercase

if ($file -cmatch "[a-z]:\\") 
	{ $file = $file.Substring(0,1).toUpper() + $file.Substring(1,$file.length-1)}

# Also, just in case, eliminate "\.\", so we can use it with non-dev versions of Sumatra
# (as of 9/15, v. 1.8.4434 does not add the "\.\", but earlier versions do)

$file = $file.Replace("\.\","\")

Write-Output $file

# Modify the following line if necessary
$sublime = "C:\Program Files\Sublime Text 2\sublime_text.exe"
# Note the curly braces: http://winterdom.com/2008/02/watchoutforinpowershell
& $sublime "${file}:$line"

Then, move it somewhere convenient (e.g. the LaTeXTools package directory), and configure the SumatraPDF inverse search command as follows:

powershell.exe -executionPolicy RemoteSigned -WindowStyle Hidden &'<path to st2clean.ps1>' '%f' %l

(of course, replace “<path to st2clean.ps2>” with, well, the path to the script!). The “-executionPolicy” switch ensures that the script will actually run, in case you haven’t enabled local scripts to run globally; the “-WindowStyle” switch makes sure that the command shell will only briefly flash on your screen, and then disappear.

You can take a look at the source, but the basic idea is simply to convert the file name so that the drive letter is always uppercase, and then pass the file name and line number on to Sublime Text 2. If you open a file in Sublime Text 2 (or associate tex files to it, and open a file by double-clicking it in Windows Explorer), the file path (which you can see by hovering on the corresponding tab) uses uppercase drive letters, so voilà, the inverse search problem is solved.

Again, this is only a temporary fix, because I trust that jps will fix the drive letter issue in a future release. But, TeXlive can now be considered fully supported on Windows!

Incidentally, this was my very first experience writing a Powershell script. There are quite a few pitfalls and quirks, all documented in the source file. Have fun!

One response to “TeXlive: a Powershell workaround for inverse search

  1. Pingback: TeXlive is a go (plus, a better README) | Tech, TeX and Theory

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s