%D \module %D [ file=m-scite, %D version=2014.04.28, %D title=\CONTEXT\ Extra Modules, %D subtitle=\SCITE\ lexers, %D author=Hans Hagen, %D date=\currentdate, %D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] %C %C This module is part of the \CONTEXT\ macro||package and is %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. % We can simplify the scite lexers, as long as we're able to return the % lexed result table and provide alexer module with the functions that % the lexer expects (so I need to decipher the cxx file). % % lexer._TOKENSTYLES : table % lexer._CHILDREN : flag % lexer._EXTRASTYLES : table % lexer._GRAMMAR : flag % % lexers.load : function % lexers.lex : function % % And some properties that map styles onto scintilla styling. I get the % impression that we end up with something simpler, a hybrid between the % scite lexing and the current context way, so we get an intermediate % step, with some penalty for context, but at least I don't have to % maintain two sets (three sets as we also have a line based series). % TODO: as these files are in tds we can locate them and set the lexer root % to that one. Currently we're on: we're on context/documents. % TODO: tab % This is an experiment: eventually we need to hook it into the verbatim code % and deal with widow lines and so. \startluacode -- todo: merge with collapse -- todo: prehash whitespaces -- todo: hook into the pretty print code -- todo: a simple catcode regime with only \ { } local gsub, sub, find = string.gsub, string.sub, string.find local concat = table.concat local formatters = string.formatters local lpegmatch = lpeg.match local setmetatableindex = table.setmetatableindex local scite = require("util-sci") buffers.scite = scite -- context output: local f_def_color = formatters["\\definecolor[slxc%s][h=%02X%02X%02X]%%"] local f_fore_none = formatters["\\unexpanded\\def\\slx%s#1{{\\slxc%s#1}}%%"] local f_fore_bold = formatters["\\unexpanded\\def\\slx%s#1{{\\slxc%s\\bf#1}}%%"] local f_none_bold = formatters["\\unexpanded\\def\\slx%s#1{{\\bf#1}}%%"] local f_none_none = formatters["\\unexpanded\\def\\slx%s#1{{#1}}%%"] local f_texstyled = formatters["\\slx%s{%s}"] local f_hanging = formatters["\\slxb{%s}%s\\slxe"] local f_mapping = [[ \let\string\slxL\string\letterleftbrace \let\string\slxR\string\letterrightbrace \let\string\slxM\string\letterdollar \let\string\slxV\string\letterbar \let\string\slxU\string\letterhat \let\string\slxD\string\letterunderscore \let\string\slxH\string\letterhash \let\string\slxB\string\letterbackslash \let\string\slxP\string\letterpercent \let\string\slxT\string\lettertilde \let\string\slxS\string\fixedspace %]] local replacer = lpeg.replacer { ["{"] = "\\slxL ", ["}"] = "\\slxR ", ["$"] = "\\slxM ", ["^"] = "\\slxU ", ["_"] = "\\slxD ", ["|"] = "\\slxV ", ["#"] = "\\slxH ", ["\\"] = "\\slxB ", ["%"] = "\\slxP ", ["~"] = "\\slxT ", [" "] = "\\slxS ", -- can be made more efficient: \\slxF{n} } local colors = nil local function exportcolors() if not colors then scite.loadscitelexer() local function black(f) return (f[1] == f[2]) and (f[2] == f[3]) and (f[3] == 0) end local result, r = { f_mapping }, 1 for k, v in table.sortedhash(lexer.context.styles) do local fore = v.fore if fore and not black(fore) then r = r + 1 result[r] = f_def_color(k,fore[1],fore[2] or fore[1],fore[3] or fore[1]) end end r = r + 1 result[r] = "%" for k, v in table.sortedhash(lexer.context.styles) do local bold = v.bold local fore = v.fore r = r + 1 if fore and not black(fore) then if bold then result[r] = f_fore_bold(k,k) else result[r] = f_fore_none(k,k) end else if bold then result[r] = f_none_bold(k) else result[r] = f_none_none(k) end end end colors = concat(result,"\n") end return colors end local function exportwhites() return setmetatableindex(function(t,k) local v = find(k,"white") and true or false t[k] = v return v end) end local function exportstyled(lexer,text) local result = lexer.lex(lexer,text,0) local start = 1 local whites = exportwhites() local buffer = { } for i=1,#result,2 do local style = result[i] local position = result[i+1] local txt = sub(text,start,position-1) txt = lpegmatch(replacer,txt) if whites[style] then buffer[#buffer+1] = txt else buffer[#buffer+1] = f_texstyled(style,txt) end start = position end buffer = concat(buffer) return buffer end function scite.installcommands() context(exportcolors()) end local p1 = lpeg.tsplitat(lpeg.patterns.newline) local p2 = lpeg.P("\\slxS ")^1 local p3 = lpeg.Cs((lpeg.Cp() * lpeg.P(" ") * lpeg.Cp() / function(b,e) return "\\slxF{" .. (e-b-1) .. "}" end + (1-lpeg.P(" "))^1)^0) -- slxb could have a \hskip so then we can replace the slxS's local function indent(str) local l = lpegmatch(p1,str) for i=1,#l do local s = l[i] if #s > 0 then local n = lpegmatch(p2,s) if n then n = (n-1)/6 else n = 0 end s = lpegmatch(p3,s) -- can be combined l[i] = f_hanging(n,s) -- "\\slxb{%s}%s\\slxe " -- print(">",s) -- print("<",l[i]) end end return concat(l,"\n") end local function lexdata(data,lexname) local styled = exportstyled(scite.loadedlexers[lexname],data or "") styled = indent(styled) buffers.assign("lex",styled) end scite.lexdata = lexdata function scite.lexbuffer(name,lexname) lexdata(buffers.getcontent(name) or "",lexname or "tex") end function scite.lexfile(filename,lexname) lexdata(io.loaddata(filename) or "",lexname or file.suffix(filename)) end -- html output \stopluacode % This is a preliminary interface. \unprotect \newdimen\scitespaceskip \unexpanded\def\buff_scite_slxb#1% {%\begingroup \hangindent\numexpr#1+2\relax\scitespaceskip \hangafter 1\relax} \unexpanded\def\buff_scite_slxe {\par }%\endgroup} \unexpanded\def\installscitecommands {\ctxlua{buffers.scite.installcommands()}% \let\installscitecommands\relax \scitespaceskip\fontcharwd\font`0\relax \unexpanded\def\slxS{\hskip\scitespaceskip}% \unexpanded\def\slxF##1{\hskip##1\scitespaceskip\relax}% \let\slxb\buff_scite_slxb \let\slxe\buff_scite_slxe} \unexpanded\def\startscite {\begingroup \dosingleempty\buff_scite_start} \def\buff_scite_start[#1]% {\edef\currentscitelexer{#1}% \dostartbuffer[@scite@][startscite][stopscite]} \unexpanded\def\stopscite {\scitebuffer[\ifx\currentscitelexer\empty tex\else\currentscitelexer\fi][@scite@]% \endgroup} \unexpanded\def\scitefile {\dosingleargument\module_scite_file} \unexpanded\def\module_scite_file[#1]% {\start \ctxlua{buffers.scite.lexfile("#1")}% \installscitecommands \tt \dontcomplain \raggedright \startcontextcode \startlines \getbuffer[lex] \stoplines \stopcontextcode \stop} \unexpanded\def\scitebuffer {\dodoubleargument\module_scite_buffer} \unexpanded\def\module_scite_buffer[#1][#2]% {\start \ifsecondargument \ctxlua{buffers.scite.lexbuffer("#2","#1")}% \else \ctxlua{buffers.scite.lexbuffer("#1","tex")}% \fi \installscitecommands \tt \dontcomplain \raggedright \setcatcodetable\ctxcatcodes % needed in xml \startlines \getbuffer[lex]% \stoplines \stop} \protect \continueifinputfile{m-scite.mkiv} \setupbodyfont[dejavu,8pt] \setuplayout [width=middle, height=middle, header=1cm, footer=1cm, topspace=1cm, bottomspace=1cm, backspace=1cm] \startbuffer[demo] \startsubsubject[title={oeps}] \startMPcode draw fullcircle scaled 2cm withpen pencircle scaled 1mm withcolor .5green; draw textext ( lua ( "local function f(s) return string.upper(s) end mp.quoted(f('foo'))" ) ) withcolor .5red ; \stopMPcode \startluacode context("foo") \stopluacode \stopsubsubject \stopbuffer \starttext % \scitefile[../lexers/scite-context-lexer.lua] \page % \scitefile[t:/manuals/about/about-metafun.tex] \page % \scitefile[t:/sources/strc-sec.mkiv] \page % \scitefile[e:/tmp/mp.w] \page % \scitefile[t:/manuals/hybrid/tugboat.bib] \page \scitefile[e:/tmp/test.bib] \page % \getbuffer[demo] \scitebuffer[demo] \stoptext