5

I have defined a new language in Latex (Clojure) but I'm having some issues with delimiting keywords. A keyword in Clojure is any alphanumeric string starting with a colon. E.g., :foo-bar-baz.

So far I have defined the following in my code ( I have trimmed the keywords for brevity):

\lstdefinelanguage{clojure}%
{morekeywords={*,*1,*2,*3,*agent*,*allow-unresolved-vars*,*assert*,*clojure-version*,*command-line-args*
},%
showspaces=false,%
showstringspaces=false,
   sensitive,% ???
   alsodigit=-,%
   morecomment=[l];,%
   morecomment=[s][\color{purple}]{:}{\ },
   morestring=[b]"%
}[keywords,comments,strings]%

The problem is that I want a keyword to not be delimited by a space but by any other char than an alphanumerical character. I.e., A-Z, a-z and 1-9 including -. Or another option would be to delimit using space or ].

What I currently get is the following: current result

The problem is that there has to be space between the square bracket and the keyword in order for the color not to continue. Otherwise I get the output shown below. wrong result

Minimal working example

\documentclass{article}
\usepackage{listings}
\usepackage[usenames,dvipsnames]{color}
\usepackage{todonotes}

\lstdefinelanguage{clojure}%
{morekeywords={*,*1,*2,*3,*agent*,*allow-unresolved-vars*,*assert*,*clojure-version*,*command-line-args*,%
*compile-files*,*compile-path*,*e,*err*,*file*,*flush-on-newline*,*in*,*macro-meta*,%
*math-context*,*ns*,*out*,*print-dup*,*print-length*,*print-level*,*print-meta*,*print-readably*,%
*read-eval*,*source-path*,*use-context-classloader*,*warn-on-reflection*,+,-,->,->>,..,/,:else,%
<,<=,=,==,>,>=,@,accessor,aclone,add-classpath,add-watch,agent,agent-errors,aget,alength,alias,%
all-ns,alter,alter-meta!,alter-var-root,amap,ancestors,and,apply,areduce,array-map,aset,%
aset-boolean,aset-byte,aset-char,aset-double,aset-float,aset-int,aset-long,aset-short,assert,%
assoc,assoc!,assoc-in,associative?,atom,await,await-for,await1,bases,bean,bigdec,bigint,binding,%
bit-and,bit-and-not,bit-clear,bit-flip,bit-not,bit-or,bit-set,bit-shift-left,bit-shift-right,%
bit-test,bit-xor,boolean,boolean-array,booleans,bound-fn,bound-fn*,butlast,byte,byte-array,%
bytes,cast,char,char-array,char-escape-string,char-name-string,char?,chars,chunk,chunk-append,%
chunk-buffer,chunk-cons,chunk-first,chunk-next,chunk-rest,chunked-seq?,class,class?,%
clear-agent-errors,clojure-version,coll?,comment,commute,comp,comparator,compare,compare-and-set!,%
compile,complement,concat,cond,condp,conj,conj!,cons,constantly,construct-proxy,contains?,count,%
counted?,create-ns,create-struct,cycle,dec,decimal?,declare,def,definline,defmacro,defmethod,%
defmulti,defn,defn-,defonce,defprotocol,defstruct,deftype,delay,delay?,deliver,deref,derive,%
descendants,destructure,disj,disj!,dissoc,dissoc!,distinct,distinct?,do,do-template,doall,doc,%
dorun,doseq,dosync,dotimes,doto,double,double-array,doubles,drop,drop-last,drop-while,empty,empty?,%
ensure,enumeration-seq,eval,even?,every?,false,false?,ffirst,file-seq,filter,finally,find,find-doc,%
find-ns,find-var,first,float,float-array,float?,floats,flush,fn,fn?,fnext,for,force,format,future,%
future-call,future-cancel,future-cancelled?,future-done?,future?,gen-class,gen-interface,gensym,%
get,get-in,get-method,get-proxy-class,get-thread-bindings,get-validator,hash,hash-map,hash-set,%
identical?,identity,if,if-let,if-not,ifn?,import,in-ns,inc,init-proxy,instance?,int,int-array,%
integer?,interleave,intern,interpose,into,into-array,ints,io!,isa?,iterate,iterator-seq,juxt,%
key,keys,keyword,keyword?,last,lazy-cat,lazy-seq,let,letfn,line-seq,list,list*,list?,load,load-file,%
load-reader,load-string,loaded-libs,locking,long,long-array,longs,loop,macroexpand,macroexpand-1,%
make-array,make-hierarchy,map,map?,mapcat,max,max-key,memfn,memoize,merge,merge-with,meta,%
method-sig,methods,min,min-key,mod,monitor-enter,monitor-exit,name,namespace,neg?,new,newline,%
next,nfirst,nil,nil?,nnext,not,not-any?,not-empty,not-every?,not=,ns,ns-aliases,ns-imports,%
ns-interns,ns-map,ns-name,ns-publics,ns-refers,ns-resolve,ns-unalias,ns-unmap,nth,nthnext,num,%
number?,odd?,or,parents,partial,partition,pcalls,peek,persistent!,pmap,pop,pop!,pop-thread-bindings,%
pos?,pr,pr-str,prefer-method,prefers,primitives-classnames,print,print-ctor,print-doc,print-dup,%
print-method,print-namespace-doc,print-simple,print-special-doc,print-str,printf,println,println-str,%
prn,prn-str,promise,proxy,proxy-call-with-super,proxy-mappings,proxy-name,proxy-super,%
push-thread-bindings,pvalues,quot,rand,rand-int,range,ratio?,rational?,rationalize,re-find,%
re-groups,re-matcher,re-matches,re-pattern,re-seq,read,read-line,read-string,recur,reduce,ref,%
ref-history-count,ref-max-history,ref-min-history,ref-set,refer,refer-clojure,reify,%
release-pending-sends,rem,remove,remove-method,remove-ns,remove-watch,repeat,repeatedly,%
replace,replicate,require,reset!,reset-meta!,resolve,rest,resultset-seq,reverse,reversible?,%
rseq,rsubseq,second,select-keys,send,send-off,seq,seq?,seque,sequence,sequential?,set,set!,%
set-validator!,set?,short,short-array,shorts,shutdown-agents,slurp,some,sort,sort-by,sorted-map,%
sorted-map-by,sorted-set,sorted-set-by,sorted?,special-form-anchor,special-symbol?,split-at,%
split-with,str,stream?,string?,struct,struct-map,subs,subseq,subvec,supers,swap!,symbol,symbol?,%
sync,syntax-symbol-anchor,take,take-last,take-nth,take-while,test,the-ns,throw,time,to-array,%
to-array-2d,trampoline,transient,tree-seq,true,true?,try,type,unchecked-add,unchecked-dec,%
unchecked-divide,unchecked-inc,unchecked-multiply,unchecked-negate,unchecked-remainder,%
unchecked-subtract,underive,unquote,unquote-splicing,update-in,update-proxy,use,val,vals,%
var,var-get,var-set,var?,vary-meta,vec,vector,vector?,when,when-first,when-let,when-not,%
while,with-bindings,with-bindings*,with-in-str,with-loading-context,with-local-vars,%
with-meta,with-open,with-out-str,with-precision,xml-seq,zero?,zipmap,continue,receive,!,self,create-actor
},%
showspaces=false,%
showstringspaces=false,
   sensitive,% ???
   alsodigit=-,%
   morecomment=[l];,%
   morecomment=[s][\color{purple}]{:}{\ },
   morestring=[b]"%
}[keywords,comments,strings]%

\begin{document}

\section{Foo}

\begin{lstlisting}[basicstyle= \footnotesize\ttfamily,
    belowcaptionskip=0em,
    language=clojure,
    label={lst:ex3}]
(create-actor
  :counter-actor
  (fn [[self [counter] :as args]]
    (receive 
      ([:increment]
        (! :log-actor :log ["incremented counter"])
        (recur [self [(inc counter)]])))))
\end{lstlisting}
\end{document}
1
  • Using morecomment for this kind of things is a bit awkward. You could hack at listings a bit in order to highlight all Clojure keywords automatically, in a way similar to this. Unfortunately, I don't have time to do it myself, at the moment.
    – jub0bs
    May 25, 2015 at 12:33

1 Answer 1

2

So... it is much like TeX except that tokens start with : instead of \?

\documentclass{article}
\usepackage{listings,xcolor}

\makeatletter
    \lst@SaveOutputDef{"3A}\lstum@backslash
\makeatother

\lstdefinelanguage{clojure}{
    moretexcs={counter-actor,as,increment,log-actor,log},
    alsoletter=0123456789-,
    morestring=[b]"
}[keywords,tex,strings]

\begin{document}

\lstset{
    language=clojure,
    basicstyle=\footnotesize\ttfamily,
    texcsstyle=*\color{purple},
    stringstyle=\color{cyan}
}

\begin{lstlisting}[]
(create-actor
  :counter-actor
  (fn [[self [counter] :as args]]
    (receive 
      ([:increment]
        (! :log-actor :log ["incremented counter"])
        (recur [self [(inc counter)]])))))
\end{lstlisting}
\end{document}

If you do not care about coding logic at all, try

\lstdefinelanguage{clojure plus}{
    literate={:}{{\color{purple}:}}1{\ }{{\color{black}\ }}1{]}{{\color{black}]}}1,
    morestring=[b]"
}[strings]

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .