if not modules then modules = { } end modules ['util-sci'] = { version = 1.001, comment = "companion to m-scite.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", copyright = "PRAGMA ADE / ConTeXt Development Team", license = "see context related readme files" } 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 = scite or { } utilities.scite = scite local report = logs.reporter("scite") do -- local lexerroot = "c:/data/system/scite/wscite/context/lexers" -- if not lexerroot then lexerroot = file.dirname(resolvers.findfile("scite-context-lexer.lua")) -- end if lfs.isdir(lexerroot) then package.extraluapath(lexerroot) package.extraluapath(lexerroot.."/themes") package.extraluapath(lexerroot.."/data") report("using lexer root %a",lexerroot) else report("no valid lexer root") end end local knownlexers = { tex = "tex", mkiv = "tex", mkvi = "tex", mkxl = "tex", mklx = "tex", mkxi = "tex", mkix = "tex", mkii = "tex", bib = "bibtex", cld = "tex", lua = "lua", lmt = "lua", lfg = "lua", lus = "lua", luv = "lua", mp = "mps", mpiv = "mps", mpxl = "mps", mpii = "mps", w = "web", ww = "web", c = "cpp", h = "cpp", cpp = "cpp", hpp = "cpp", cxx = "cpp", hxx = "cpp", xml = "xml", xsl = "xml", xsd = "xml", dtd = "xml", lmx = "xml", ctx = "xml", rlx = "xml", css = "xml", rme = "txt", txt = "txt", -- todo: pat/hyp ori } lexer = nil -- main lexer, global (for the moment needed for themes) local function loadscitelexer() if not lexer then lexer = require("scite-context-lexer") require("scite-context-theme") -- uses lexer if lexer then lexer.context.disablewordcheck() end end return lexer end local loadedlexers = setmetatableindex(function(t,k) local l = knownlexers[k] or k loadscitelexer() local v = lexer.load(formatters["scite-context-lexer-%s"](l)) t[l] = v t[k] = v return v end) scite.loadedlexers = loadedlexers scite.knownlexers = knownlexers scite.loadscitelexer = loadscitelexer local f_fore_bold = formatters['.%s { display:inline; font-weight:bold; color:#%02X%02X%02X; }'] local f_fore_none = formatters['.%s { display:inline; font-weight:normal; color:#%02X%02X%02X; }'] local f_none_bold = formatters['.%s { display:inline; font-weight:bold; }'] local f_none_none = formatters['.%s { display:inline; font-weight:normal; }'] local f_div_class = formatters['
%s
'] local f_linenumber = formatters['
%s
\n'] local f_lineerror = formatters['
%s
\n'] local f_div_number = formatters['.linenumber { display:inline-block; font-weight:normal; width:%sem; margin-right:2em; padding-right:.25em; text-align:right; color:#000000; }'] -- background-color:#C7C7C7; local s_div_error = '.lineerror { font-weight:bold; color:#FFFFFF; background-color:#000000; }' local replacer_regular = lpeg.replacer { ["<"] = "<", [">"] = ">", ["&"] = "&", } local linenumber = 0 local lineerror = 0 local linenumbers = { } local replacer_numbered = lpeg.replacer { ["<"] = "<", [">"] = ">", ["&"] = "&", [lpeg.patterns.newline] = function() linenumber = linenumber + 1 linenumbers[linenumber] = (linenumber == lineerror and f_lineerror or f_linenumber)(linenumber) return "\n" end, } local css = nil local function exportcsslexing() if not css then loadscitelexer() local function black(f) return (#f == 0 and f[1] == 0) or ((f[1] == f[2]) and (f[2] == f[3]) and (f[3] == 0)) end local result, r = { }, 0 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 local cr, cg, cb = fore[1], fore[2], fore[3] result[r] = (bold and f_fore_bold or f_fore_none)(k,cr,cg or cr,cb or cr) else result[r] = (bold and f_none_bold or f_none_none)(k) end end css = concat(result,"\n") end return css end local function exportwhites() return setmetatableindex(function(t,k) local v = find(k,"white",1,true) and true or false t[k] = v return v end) end local function exportstyled(lexer,text,numbered) local result = lexer.lex(lexer,text,0) local start = 1 local whites = exportwhites() local buffer = { } local b = 0 linenumber = 0 linenumbers = { } lineerror = tonumber(numbered) or 0 local replacer = numbered and replacer_numbered or replacer_regular local n = #result for i=1,n,2 do local ii = i + 1 local style = result[i] local position = result[ii] local txt = sub(text,start,position-1) txt = lpegmatch(replacer,txt) b = b + 1 if whites[style] then buffer[b] = txt else buffer[b] = f_div_class(style,txt) end start = position end return concat(buffer), concat(linenumbers) end local function exportcsslinenumber() return f_div_number(#tostring(linenumber)/2+1) .. "\n" .. s_div_error end local htmlfile = utilities.templates.replacer([[ %title%
%linenumbers%
%lexedcontent%
]]) local htmlblob = utilities.templates.replacer([[
%linenumbers%
%lexedcontent%
]]) function scite.tohtml(data,lexname,numbered,title) local source, lines = exportstyled(loadedlexers[lexname],data or "",numbered) if source then return (title == false and htmlblob or htmlfile) { lexedcontent = source, -- before numberstyles lexingstyles = exportcsslexing(), numberstyles = exportcsslinenumber(), title = title or "context source file", linenumbers = lines, } end end local function maketargetname(name) if name then return file.removesuffix(name) .. "-" .. file.suffix(name) .. ".html" else return "util-sci.html" end end function scite.filetohtml(filename,lexname,targetname,numbered,title) io.savedata(targetname or "util-sci.html",scite.tohtml(io.loaddata(filename),lexname or file.suffix(filename),numbered,title or filename)) end function scite.css() return exportcsslexing() .. "\n" .. exportcsslinenumber() end function scite.html(data,lexname,numbered) return exportstyled(loadedlexers[lexname],data or "",numbered) end local f_tree_entry = formatters['%s'] local htmlfile = utilities.templates.replacer([[ %title%
%dirlist%
        
]]) function scite.converttree(sourceroot,targetroot,numbered) if lfs.isdir(sourceroot) then statistics.starttiming() local skipped = { } local noffiles = 0 dir.makedirs(targetroot) local function scan(sourceroot,targetroot,subpath) local tree = { } for name in lfs.dir(sourceroot) do if name ~= "." and name ~= ".." then local sourcename = file.join(sourceroot,name) local targetname = file.join(targetroot,name) local mode = lfs.attributes(sourcename,'mode') local path = subpath and file.join(subpath,name) or name if mode == 'file' then local filetype = file.suffix(sourcename) local basename = file.basename(name) local targetname = maketargetname(targetname) local fullname = file.join(path,name) if knownlexers[filetype] then report("converting file %a to %a",sourcename,targetname) scite.filetohtml(sourcename,nil,targetname,numbered,fullname) noffiles = noffiles + 1 tree[#tree+1] = f_tree_entry(file.basename(targetname),basename) else skipped[filetype] = true report("no lexer for %a",sourcename) end else dir.makedirs(targetname) scan(sourcename,targetname,path) tree[#tree+1] = f_tree_entry(file.join(name,"files.html"),name) end end end report("saving tree in %a",targetroot) local htmldata = htmlfile { dirlist = concat(tree,"\n"), styles = "", title = path or "context dir listing", } io.savedata(file.join(targetroot,"files.html"),htmldata) end scan(sourceroot,targetroot) if next(skipped) then report("skipped filetypes: %a",table.concat(table.sortedkeys(skipped)," ")) end statistics.stoptiming() report("conversion time for %s files: %s",noffiles,statistics.elapsedtime()) end end -- scite.filetohtml("strc-sec.mkiv",nil,"e:/tmp/util-sci.html",true) -- scite.filetohtml("syst-aux.mkiv",nil,"e:/tmp/util-sci.html",true) -- scite.converttree("t:/texmf/tex/context","e:/tmp/html/context",true) return scite