From 39e924d6f565d3b9eff9d1a335e65c4a3460285c Mon Sep 17 00:00:00 2001 From: Baptiste Fontaine Date: Wed, 12 Feb 2014 17:01:51 +0100 Subject: [PATCH] experimental 'highlight function --- .gitignore | 2 ++ README.md | 6 ++++-- doc/intro.md | 3 --- project.clj | 8 +++++--- src/clygments/core.clj | 46 +++++++++++++++++++++++++++++++++++++----- 5 files changed, 52 insertions(+), 13 deletions(-) delete mode 100644 doc/intro.md diff --git a/.gitignore b/.gitignore index e04714b..74506f3 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,5 @@ pom.xml.asc *.class /.lein-* /.nrepl-port +*.sw* +*~ diff --git a/README.md b/README.md index 3ab7b45..d661a46 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # clygments -A Clojure library designed to ... well, that part is up to you. +**clygments** is a Clojure bridge for [Pygments][]. + +[Pygments]: http://pygments.org/ ## Usage @@ -8,7 +10,7 @@ FIXME ## License -Copyright © 2014 FIXME +Copyright © 2014 Baptiste Fontaine Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version. diff --git a/doc/intro.md b/doc/intro.md deleted file mode 100644 index 9668dda..0000000 --- a/doc/intro.md +++ /dev/null @@ -1,3 +0,0 @@ -# Introduction to clygments - -TODO: write [great documentation](http://jacobian.org/writing/great-documentation/what-to-write/) diff --git a/project.clj b/project.clj index a156aa4..3cd3019 100644 --- a/project.clj +++ b/project.clj @@ -1,6 +1,8 @@ (defproject clygments "0.1.0-SNAPSHOT" - :description "FIXME: write description" - :url "http://example.com/FIXME" + :description "Use Pygments from Clojure" + :url "http://github.com/bfontaine/clygments" :license {:name "Eclipse Public License" :url "http://www.eclipse.org/legal/epl-v10.html"} - :dependencies [[org.clojure/clojure "1.5.1"]]) + :dependencies [[org.clojure/clojure "1.5.1"] + [org.python/jython-standalone "2.5.3"] + [org.pygments/pygments "1.5"]]) diff --git a/src/clygments/core.clj b/src/clygments/core.clj index 087565c..bbf1dd2 100644 --- a/src/clygments/core.clj +++ b/src/clygments/core.clj @@ -1,6 +1,42 @@ -(ns clygments.core) +(ns clygments.core + (:import [org.python.util PythonInterpreter])) -(defn foo - "I don't do a whole lot." - [x] - (println x "Hello, World!")) +(def ^{:private true} python + (doto (PythonInterpreter.) + (.exec (str "from pygments import highlight\n" + "from pygments.lexers import *\n" + "from pygments.formatters import *\n")))) + +(defn- exec-code-in + "put the result of the execution of a line of code in a variable, with + an optional default value if it encounters an exception" + ([var-name code] + (.exec python (str var-name "=" code))) + ([var-name code default] + (.exec python (str "try:\n\t" var-name "=" code "\n" + "except:\n\t" var-name "=" default "\n")))) + +(def ^{:private true} py-true (.eval python "True")) +(defn- py-true? + "test if an expression evals to True in Python" + [expr] + (= (.eval python expr) py-true)) + +(defn highlight + "highlight a piece of code." + ([code] (highlight code :python :html)) + ([code lang output] + (try + (exec-code-in "_r" (str "get_lexer_by_name(\"" (name lang) "\")") "None") + (exec-code-in + "_f" (str "get_formatter_by_name(\"" (name output) "\")") "None") + (if (and (py-true? "_r!=None") (py-true? "_f!=None")) + (do + ;; XXX it won't work if 'code contains a sequence of three or more + ;; double quotes, e.g.: """ + (.exec python (str "_res=highlight(\"\"\"" code "\"\"\",_r,_f)\n")) + ;; XXX it won't work with non-text formatters, such as gif + (.get python "_res" String))) + (catch Exception e + (.printStackTrace e) + (println (.getMessage e))))))