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}
  • 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 '15 at 12:33
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]

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.