commit 1a0dd115df557ce02c70c1f389dbc78d79b728de Author: Stefan Müller Date: Wed Sep 29 19:08:31 2010 +0200 - Added: Bold fontface for reserved words works, everything else still from Lua highlighting diff --git a/.hgignore b/.hgignore new file mode 100644 index 0000000..ed6fe29 --- /dev/null +++ b/.hgignore @@ -0,0 +1,4 @@ +.log +.pdf +.synctex.gz +.tuc \ No newline at end of file diff --git a/pret-pas.lua b/pret-pas.lua new file mode 100644 index 0000000..97ac9bd --- /dev/null +++ b/pret-pas.lua @@ -0,0 +1,291 @@ +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 \ No newline at end of file diff --git a/pret-pas_test.tex b/pret-pas_test.tex new file mode 100644 index 0000000..db5a615 --- /dev/null +++ b/pret-pas_test.tex @@ -0,0 +1,24 @@ +\installprettytype[PAS][PAS] +\setupcolors[state=start] +\setuptyping[option=color] +\definetyping[PAS][option=PAS, escape=yes, tab=4, numbering=line] +\setuplinenumbering[location=text] + +\starttext +\startPAS +blub { Comment } blub +blub {$R- compiler directive} blub +procedure TForm1.Button1.Click(Sender: TObject); +var // Delphi Comment + Number, I, X: Integer; +begin + Number := 12345 * (2 + 9); + Caption := 'The number is ' + IntToStr(Number); + asm + MOV AX,1234h + MOV Number,AX + end; + X := 10; +end; +\stopPAS +\stoptext \ No newline at end of file