* Verbatim: Pascal pretty printer
@ 2010-10-02 21:10 Stefan Müller
0 siblings, 0 replies; only message in thread
From: Stefan Müller @ 2010-10-02 21:10 UTC (permalink / raw)
To: mailing list for ConTeXt users
[-- Attachment #1: Type: text/plain, Size: 1006 bytes --]
Hi list,
I wrote a custom pretty printer (verbatim) for Free Pascal/Turbo
Pascal/Delphi source files. It's attached to this mail together with a
ConTeXt test files that shows the features and some special cases.
The pretty printer can handle:
reserved words (bold)
{...}-, (*...*)- and //...-style comments
{$...} compiler directives
'...' strings
embedded assembler code (asm ... end)
It's based on the Lazarus IDE syntax highlighter (Free Pascal IDE),
which should be pretty Delphi-like. The main difference to Lazarus
highlighting is that comments are not bold, but slanted. That looks much
better when no colors are used.
I'm not experienced in Lua programming, but I hope there are no major
issues. I'd really appreciate any feedback: comments, suggestions and
corrections (if necessary). I hope that eventually the Pascal pretty
printer can make it's way into the ConTeXt distribution.
Best wishes,
Stefan.
PS: Thanks for the Lua pretty printer, which served as a good starting
point.
[-- Attachment #2: pret-pas.lua --]
[-- Type: text/plain, Size: 7788 bytes --]
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"
}
-- The code formatting is adapted from Lazarus, a Free Pascal RAD IDE, which
-- should be quite similar to the Delphi style. Please note that comments are
-- not typeset with bold fontface but slanted, which improves output when not
-- using colors.
-- http://lazarus.freepascal.org/
local visualizer = buffers.newvisualizer("pas")
-- The list of reserved words is 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 (in the following, 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: compiler directive, symbol
"prettytwo", -- green: assembler (dark green)
"prettythree", -- blue: comment, number (dark blue)
"prettyfour", -- yellow
}
local reserved_style = "\{\\bf "
local comment_style = "\{\\sl "
local inlongcomment, inlongcomment_alt, incompdirec, inasm = false, 0, false, false
local function flush_pas_word(word, state)
if word then
local lword = string.lower(word)
local id = known_words[lword]
if id then
if inasm and (lword == "end") then
-- asm mode ends
state = buffers.finishstate(state)
inasm = false
print("leave asm")
end
if not inasm then
tex.sprint(tex.ctxcatcodes, reserved_style)
tex.write(word)
tex.sprint(tex.ctxcatcodes, "\}")
if lword == "asm" then
-- asm mode begins
print("enter asm")
inasm = true
state = buffers.changestate(2, state)
end
else
tex.write(word)
end
else
tex.write(word)
end
end
return state
end
local function flush_whatever(str)
if str then
for c in string.utfcharacters(str) do
if c == " " then
tex.sprint(tex.ctxcatcodes, "\\obs")
elseif c == "\t" then
tex.sprint(tex.ctxcatcodes, "\\obs")
if buffers.visualizers.enabletab then
tex.sprint(tex.ctxcatcodes,rep("\\obs ", buffers.visualizers.tablength))
end
else
tex.write(c);
end
end
end
end
function visualizer.reset()
inlongcomment, inlongcomment_alt, incompdirec, inasm = false, 0, false, false
end
function visualizer.flush_line(str, nested)
local state = 0
local incomment, instring = false, false
--local code, comment = nil, nil
buffers.currentcolors = colors
if inlongcomment or (inlongcomment_alt == 2) or incompdirec then
incomment = true
if incompdirec then
state = buffers.changestate(1, state)
else
state = buffers.changestate(3, state)
end
tex.sprint(tex.ctxcatcodes, comment_style)
elseif inasm then
state = buffers.changestate(2, state)
end
local c, word = nil, nil
for nextc in string.utfcharacters(str .. " ") do
if c then
if instring then
if c == "'" then
-- string ends
tex.write(c)
state = buffers.finishstate(state)
instring = false
else
-- inside the string
flush_whatever(c)
end
elseif incomment then
if ((inlongcomment or incompdirec) and (c == "}"))
or (inlongcomment_alt == 1) then
-- long comment/(alternative)/compiler directive ends
tex.write(c)
tex.sprint(tex.ctxcatcodes, "\}")
if inasm then
-- resume to asm mode
state = buffers.changestate(2, state)
else
state = buffers.finishstate(state)
end
incompdirec = false
inlongcomment = false
inlongcomment_alt = 0
incomment = false
elseif (inlongcomment_alt == 2) and (c == "*") and (nextc == ")") then
-- long comment (alternative) ends after nextc
tex.write(c)
inlongcomment_alt = 1
else
-- inside the comment
flush_whatever(c)
end
elseif string.find(c, "^[%a_]$") then
-- char belongs to identifier
if word then
word = word .. c
else
word = c
end
elseif string.find(c, "^[%d]$") then
if word and (#word > 1) then
-- number, that belongs to identifier
word = word .. c
else
if not inasm then
-- number
state = buffers.changestate(3, state)
end
tex.write(c)
end
else
if not inasm then
state = buffers.finishstate(state)
end
-- identifier complete, check if it's a reserved word and flush
state = flush_pas_word(word, state)
word = nil
if c == " " then
tex.sprint(tex.ctxcatcodes, "\\obs")
elseif c == "\t" then
tex.sprint(tex.ctxcatcodes, "\\obs")
if buffers.visualizers.enabletab then
tex.sprint(tex.ctxcatcodes,rep("\\obs ", buffers.visualizers.tablength))
end
elseif c == "'" then
if not inasm then
-- string begins
instring = true
state = buffers.changestate(3, state)
end
tex.write(c)
elseif (c == "/") and (nextc == "/") then
-- one-line comment begins
incomment = true
state = buffers.changestate(3, state)
tex.sprint(tex.ctxcatcodes, comment_style)
tex.write(c)
elseif c == "{" then
incomment = true
if nextc == "$" then
-- compiler directive begins
incompdirec = true
state = buffers.changestate(1, state)
else
-- long comment begins
inlongcomment = true
state = buffers.changestate(3, state)
end
tex.sprint(tex.ctxcatcodes, comment_style)
tex.write(c)
elseif (c == "(") and (nextc == "*") then
-- long comment (alternative) begins
incomment = true
inlongcomment_alt = 2
state = buffers.changestate(3, state)
tex.sprint(tex.ctxcatcodes, comment_style)
tex.write(c)
else
if not inasm then
-- symbol
state = buffers.changestate(1, state)
end
tex.write(c)
end
end
end
c = nextc
end
if not incomment and not inasm then
state = buffers.finishstate(state)
end
-- maybe something left, check if it's a reserved word and flush
state = flush_pas_word(word, state)
if incomment then
-- end the comment-line
tex.sprint(tex.ctxcatcodes, "\}")
end
state = buffers.finishstate(state)
end
[-- Attachment #3: pret-pas_test.tex --]
[-- Type: application/x-tex, Size: 1276 bytes --]
[-- Attachment #4: Type: text/plain, Size: 486 bytes --]
___________________________________________________________________________________
If your question is of interest to others as well, please add an entry to the Wiki!
maillist : ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context
webpage : http://www.pragma-ade.nl / http://tex.aanhet.net
archive : http://foundry.supelec.fr/projects/contextrev/
wiki : http://contextgarden.net
___________________________________________________________________________________
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2010-10-02 21:10 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-10-02 21:10 Verbatim: Pascal pretty printer Stefan Müller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).