So one's LaTeX document might look like this:
\documentclass{article}
\usepackage{python} \title{Test} \begin{document} % This is TeX code Hello, world! \begin{python} # This is python code print r'\begin{verbatim}' import sys print sys.version print r'\end{verbatim}' \end{python} More \TeX here. Here's a list: \begin{itemize} \item What's up? \end{itemize} \begin{Scode} # This is R/S code print('what up') for (i in 1:10) { print(i) } \end{Scode} How was that? \end{document}It's not for everyone, but I find it useful.
What this means though, is that the TeX source file actually contains code in three languages (TeX, Python, R). In my text editor of choice -- Vim -- it took a little bit of thought to enable syntax highlighting for all three simultaneously, without interfering with each other. So I thought I'd share my solution for posterity.
First, I name any documents written in this way with a .Rtex suffix. Add a line like this to ~/.vimrc, causing Vim to set the filetype of files ending in .Rtex to "rtex":
au BufRead *.Rtex setf rtex
Now we can control the syntax highlighting of such files be creating the file ~/.vim/syntax/rtex.vim and putting the appropriate Vim code in it. The following does the trick:
let b:current_syntax = '' unlet b:current_syntax runtime! syntax/tex.vim let b:current_syntax = '' unlet b:current_syntax syntax include @TeX syntax/tex.vim let b:current_syntax = '' unlet b:current_syntax syntax include @Python syntax/python.vim syntax region pythonCode matchgroup=Snip start="\\begin{python}" end="\\end{python}" containedin=@TeX contains=@Python let b:current_syntax = '' unlet b:current_syntax syntax include @R syntax/r.vim syntax region rCode matchgroup=Snip start="\\begin{Scode}" end="\\end{Scode}" containedin=@TeX contains=@R hi link Snip SpecialComment let b:current_syntax = 'rtex'
Now restart vim and open a .Rtex file. Here's a screenshot of the result:
Finally there is the matter of streamlining the compilation process for Rtex documents like this. I generally use the excellent tool latexmk and its "continuous preview" feature, which scans a TeX document, determines all of the ancillary files that it depends on, watches them, and upon detecting a change, invokes latex/pdflatex/bibtex as necessary to fully recompile the document, and finally tells your PDF viewer (or whatever) to refresh its view. Boom, now you're a hacker.
All we have to do is add Sweave, which runs as an R command ("CMD"), to latexmk's compilation process. This is as simple as creating a file named latexmkrc in the directory of the Rtex document, and filling it with something along these lines:
@default_files = ("*.Rtex"); $pdf_mode = 1; $pdflatex = 'R CMD Sweave %B.Rtex && pdflatex -shell-escape %B';
This tells latexmk to compile all .Rtex files in the current directory if no document is explicitly named when we start it, and to generate PDFs by default, using pdflatex, which should be immediately preceded by executing R CMD Sweave on the Rtex file. The -shell-escape option on the call to pdflatex is required by the python.sty package.
Now all we have to do is invoke latexmk -pvc from the command line in the directory of the Rtex document, and latexmk will start up in continuous preview mode, detecting any changes to the Rtex file (and its dependencies), and recompiling our PDF on the fly.
Here's what the example from before looks like once compiled:
Thank you for posting this, it saved me a bit of time.
ReplyDelete@James: My pleasure, thanks for stopping by!
ReplyDeleteI just heard about latexmk today, and didn't really have any idea of how it worked. I have sweave stuff in .Rnw, so I took your 3 lines of code and changed .Rtex to .Rnw, and it works!
ReplyDeleteThank you for the clear explanation.