if not modules then modules = { } end modules ['pret-pas'] = { version = 1.0, comment = "custom pretty printer for Pascal code", author = "Stefan Müller, Chemnitz DE", copyright = "Stefan Müller", license = "see context related readme files" } local utf = unicode.utf8 local utfcharacters, utfvalues = string.utfcharacters, string.utfvalues local utfbyte, utffind = utf.byte, utf.find local byte, sub, find, match = string.byte, string.sub, string.find, string.match local texsprint, texwrite = tex.sprint, tex.write local ctxcatcodes = tex.ctxcatcodes local buffers = buffers local changestate, finishstate = buffers.changestate, buffers.finishstate local visualizer = buffers.newvisualizer("pas") -- reserved words taken from http://www.freepascal.org/docs-html/ref/refse3.html visualizer.reservedwords = { -- Turbo Pascal "absolute", "and", "array", "asm", "begin", "case", "const", "constructor", "destructor", "div", "do", "downto", "else", "end", "file", "for", "function", "goto", "if", "implementation", "in", "inherited", "inline", "interface", "label", "mod", "nil", "not", "object", "of", "on", "operator", "or", "packed", "procedure", "program", "record", "reintroduce", "repeat", "self", "set", "shl", "shr", "string", "then", "to", "type", "unit", "until", "uses", "var", "while", "with", "xor", -- Free Pascal -- these are not bold type (keeping them, just in case) -- "dispose", "exit", "false", "new", "true", -- Object Pascal "as", "class", "dispinterface", "except", "exports", "finalization", "finally", "initialization", "inline", "is", "library", "on", "out", "packed", "property", "raise", "resourcestring", "threadvar", "try", -- Modifiers -- some of these are only bold in specific places (this is deliberately -- ignored) "absolute", "abstract", "alias", "assembler", "cdecl", "cppdecl", "default", "export", "external", "far", "far16", "forward", "index", "local", "name", "near", "nostackframe", "oldfpccall", "override", "pascal", "private", "protected", "public", "published", "read", "register", "reintroduce", "safecall", "softfloat", "stdcall", "virtual", "write" } local known_words = { } for k,v in next, visualizer.reservedwords do known_words[v] = k end local colors = { "prettyone", -- red "prettytwo", -- green "prettythree", -- blue "prettyfour", -- yellow } local states = { ['"']=1, ["'"]=1, ["[["] = 1, ["]]"] = 1, ['+']=1, ['-']=1, ['*']=1, ['/']=1, ['%']=1, ['^']=1, ["("] = 3, [")"] = 3, ["["] = 3, ["]"] = 3, ['--']=4, } local function flush_pas_word(word) if word then local id = known_words[word] if id then tex.sprint(tex.ctxcatcodes,"\{\\bf ") tex.write(word) tex.sprint(tex.ctxcatcodes,"\}") else tex.write(word) end end end local incomment, inlongstring = false, false local incompdirec, inasm = false, false function visualizer.reset() incomment, inlongstring = false, false incompdirec, inasm = false, false end local function written(state,c,i) if c == " " then state = finishstate(state) texsprint(ctxcatcodes,"\\obs") elseif c == "\t" then state = finishstate(state) texsprint(ctxcatcodes,"\\obs") if buffers.visualizers.enabletab then texsprint(ctxcatcodes,rep("\\obs ",i%buffers.visualizers.tablength)) end else texwrite(c) end return state, 0 end function visualizer.flush_line(str, nested) --[[ buffers.currentcolors = colors local identifier = nil for c in string.utfcharacters(str) do if string.string.find(c, "^[%a%_]$") then if identifier then identifier = identifier .. c else identifier = c end elseif string.string.find(c, "^[%d]$") if identifier and #identifier > 1 then identifier = identifier .. c end elseif --flush_pas_word(identifier) identifier = nil end tex.write("p") end --flush_pas_word(identifier) identifier = nil ]] local state, instr, inesc, word = 0, false, false, nil buffers.currentcolors = colors local code, comment = match(str,"^(.-)%-%-%[%[(.*)$") if comment then -- process the code and then flush the comment elseif incomment then comment, code = match(str,"^(.-)%]%](.*)$") if comment then -- flush the comment and then process the code for c in utfcharacters(comment) do if c == " " then texsprint(ctxcatcodes,"\\obs") else texwrite(c) end end state = changestate(states['--'], state) texwrite("]]") state = finishstate(state) incomment = false else for c in utfcharacters(str) do if c == " " then texsprint(ctxcatcodes,"\\obs") else texwrite(c) end end end comment = nil else code = str end if code and code ~= "" then local pre, post = match(code,"^(.-)%-%-(.*)$") if pre then code = pre end local p, s, i = nil, nil, 0 for c in utfcharacters(code) do i = i + 1 if instr then if p then texwrite(p) p = nil end if c == s then if inesc then texwrite(c) inesc = false else state = changestate(states[c],state) instr = false texwrite(c) state = finishstate(state) end s = nil else if c == "\\" then inesc = not inesc else inesc = false end state, i = written(state,c,i) end elseif c == "[" then if word then texwrite(word) word = nil end if p == "[" then inlongstring = true state = changestate(states["[["],state) texwrite(p,c) state = finishstate(state) p = nil else if p then state, i = written(state,p,i) end p = c end elseif c == "]" then if word then texwrite(word) word = nil end if p == "]" then inlongstring = false state = changestate(states["]]"],state) texwrite(p,c) state = finishstate(state) p = nil else if p then state, i = written(state,p,i) end p = c end else if p then state = changestate(states[p],state) texwrite(p) state = finishstate(state) p = nil end if c == " " or c == "\t" then if word then flush_pas_word(word) word = nil end state, i = written(state,c,i) elseif inlongstring then state, i = written(state,c,i) elseif c == '"' or c == "'" then if word then flush_pas_word(word) word = nil end instr = true state = changestate(states[c],state) state, i = written(state,c,i) state = finishstate(state) s = c elseif find(c,"^[%a]$") then state = finishstate(state) if word then word = word .. c else word = c end elseif word and (#word > 1) and find(c,"^[%d%.%_]$") then if word then word = word .. c else word = c end else flush_pas_word(word) word = nil state = changestate(states[c],state) texwrite(c) instr = (c == '"') end end end if p then texwrite(p) -- state, i = written(state,p,i) p = nil end flush_pas_word(word) if post then state = changestate(states['--'], state) texwrite("--") state = finishstate(state) for c in utfcharacters(post) do state, i = written(state,c,i) end end end if comment then incomment = true state = changestate(states['--'], state) texwrite("[[") state = finishstate(state) -- texwrite(comment) -- maybe also split and for c in utfcharacters(comment) do state, i = written(state,c,i) end end state = finishstate(state) end