I am looking at building a Scala web app that will have lots of code snippets in many programming languages that I would like to hightlight. It looks like one of the best, most popular syntax highlighters is Pygments, a Python tool. I downloaded Jython and was able to load first it and then Pygments from within my Scala REPL. However, all the indirection is pretty ugly and it seems rather slow (but maybe faster once everything's compiled?).
My (cleaned-up) REPL session, for illustration:
scala> :cp /usr/local/Cellar/jython/2.5.1/libexec/jython.jar
scala> import org.python.util.PythonInterpreter;
scala> val interp = new PythonInterpreter()
*sys-package-mgr*: processing new jar, '/usr/local/Cellar/scala/2.8.0/libexec/lib/jline.jar'
*sys-package-mgr*: processing new jar, '/usr/local/Cellar/scala/2.8.0/libexec/lib/scala-compiler.jar'
*sys-package-mgr*: processing new jar, '/usr/local/Cellar/scala/2.8.0/libexec/lib/scala-dbc.jar'
*sys-package-mgr*: processing new jar, '/usr/local/Cellar/scala/2.8.0/libexec/lib/scala-library.jar'
*sys-package-mgr*: processing new jar, '/usr/local/Cellar/scala/2.8.0/libexec/lib/scala-swing.jar'
*sys-package-mgr*: processing new jar, '/usr/local/Cellar/scala/2.8.0/libexec/lib/scalap.jar'
interp: org.python.util.PythonInterpreter = org.python.util.PythonInterpreter@111de95a
scala> interp.exec("import sys")
scala> interp.exec("sys.path.append('/Library/Python/2.6/site-packages')")
scala> interp.exec("from pygments import highlight")
scala> interp.exec("from pygments.lexers import PythonLexer")
scala> interp.exec("from pygments.formatters import HtmlFormatter")
scala> interp.exec("html = highlight(code, PythonLexer(), HtmlFormatter())")
scala> val html = interp.get("html").toString
html: java.lang.String =
<div class="highlight"><pre><span class="k">print</span> <span class="s">"Hello World"</span>
</pre></div>
scala>val xhtml = XML.loadString(html)
xhtml: scala.xml.Elem =
<div class="highlight"><pre><span class="k">print</span> <span class="s">"Hello World"</span>
</pre></div>
Assuming that I choose to use Pygments, would you suggest going the Jython route (is a better way to call Python code than interp.exec()
?) or setting up a separate, simple, Python-native web service running Pygments for my Scala code to call? Of course, if there are libraries of comparable quality and breadth of supported languages that are easier to use from Scala, I'm all ears.