diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2015-03-24 02:30:13 +0100 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2015-03-24 02:47:48 +0100 |
commit | e4789a60d2a409f74efba9e9a3faf5250a50e0ae (patch) | |
tree | b3d86c086a35d4e0a90511a7d18715cc0d2ef98a /lib | |
parent | f991c5be609226629e906229ed7d32c66e0f5d9b (diff) | |
download | sciteco-e4789a60d2a409f74efba9e9a3faf5250a50e0ae.tar.gz |
added scite2co.lua: a script for generating SciTECO lexer definitions from SciTE properties files
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Makefile.am | 3 | ||||
-rwxr-xr-x | lib/scite2co.lua | 170 |
2 files changed, 173 insertions, 0 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am index c590484..21a8774 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -2,6 +2,9 @@ dist_scitecolib_DATA = color.tes lexer.tes session.tes fnkeys.tes dist_scitecolib_DATA += string.tes +# Helper script for creating lexer definitions +EXTRA_DIST = scite2co.lua + # This list must be extended when adding # a new color scheme: colorschemedir = $(scitecolibdir)/colors diff --git a/lib/scite2co.lua b/lib/scite2co.lua new file mode 100755 index 0000000..21d7c4d --- /dev/null +++ b/lib/scite2co.lua @@ -0,0 +1,170 @@ +#!/usr/bin/lua + +-- string property storage +-- this is what SciTE uses internally +local props = {} + +-- Recursively expand property references like "$(property)" +-- This is done lazily as in SciTE, i.e. not +-- when loading property sets +function expand(str) + return str and str:gsub("$(%b())", function(ref) + -- strips braces and expands nested references + return expand(props[expand(ref:sub(2, -2))]) or "" + end) +end + +-- SciTE property files use properties like +-- keywords.$(file.patterns.lua) +-- When looking for a list of keywords, it inefficiently +-- evaluates all properties beginning with "keywords.", expands +-- the suffix and globs the current file name against the pattern. +-- We have no choice than to emulate that behaviour. +-- However SciTECO does not rematch the current file name against +-- the pattern for every SCI_SETKEYWORDS, so we try to check if +-- the expanded suffix contains the file pattern itself +function get_property_by_pattern(prefix, pattern) + for key, value in pairs(props) do + if key:sub(1, #prefix) == prefix and + expand(key:sub(1+#prefix)):find(pattern, 1, true) then + return value + end + end + -- if property not found, return nil +end + +function load_properties(filename) + local file = io.open(filename, "r") + local line = file:read() + + while line do + -- strip leading white space + line = line:gsub("^%s", "") + + -- strip comments + line = line:gsub("^#.*", "") + + -- read continuations + while line:sub(-1) == "\\" do + line = line:sub(1, -2)..(file:read() or "") + end + + if line:find("^if ") then + -- ignore conditionals + repeat + line = file:read() + until not line or line:sub(1, 1) ~= "\t" + else + -- process assignments + -- property references are not yet expanded, + -- since SciTE relies on lazy evaluation + local key, value = line:match("^([^=]+)=(.*)") + if key then props[key] = value end + + line = file:read() + end + end + + file:close() +end + +if #arg ~= 2 then + io.stderr:write("Usage: ./scite2co.lua <language> <property file>\n\n".. + "Auto-generates a SciTECO lexer configuration from a SciTE\n".. + "properties file and prints it to stdout.\n\n".. + "Example: ./scite2co.lua lua Embedded.properties\n") + os.exit(1) +end + +-- language to extract is first command line argument +local language = arg[1] +table.remove(arg, 1) + +-- load all property files given on the command line in order +for _, filename in ipairs(arg) do + load_properties(filename) +end + +io.write("! AUTO-GENERATED FROM SCITE PROPERTY SET !\n\n") + +-- print [lexer.test...] macro +local shbang = expand(props["shbang."..language]) +local file_patterns = expand(props["file.patterns."..language]) +local teco_patterns = file_patterns:gsub("%*%.", ""):gsub(";", ",") +if teco_patterns:find(",", 1, true) then + teco_patterns = "["..teco_patterns.."]" +end +io.write([=[ +@[lexer.test.]=]..language:lower()..[=[]{ [_ +]=]) +if shbang then io.write([=[ _#!M]=]..shbang..[=[M[lexer.checkheader]"S + -1 + | + ]=]) end +io.write([=[ _.]=]..teco_patterns..[=[M[lexer.checkname] +]=]) +if shbang then io.write([=[ ' +]=]) end +io.write([=[]_ } + +]=]) + +-- print [lexer.set...] macro +local lexer = expand(get_property_by_pattern("lexer.", file_patterns)) +io.write([=[ +@[lexer.set.]=]..language:lower()..[=[]{ + ESSETLEXER,SCLEX_]=]..lexer:upper()..[=[ +]=]) +-- print keyword definitions with word wrapping +for i = 1, 9 do + local keyword_prefix = "keywords"..(i == 1 and "" or i).."." + local value = expand(get_property_by_pattern(keyword_prefix, file_patterns)) + + if value and #value > 0 then + io.write(" "..(i-1).."ESSETKEYWORDS\n ") + local col = 3 + for word in value:gmatch("%g+") do + col = col + 1 + #word + if col > 80 then + io.write("\n ") + col = 3 + end + io.write(" "..word) + end + io.write("\n") + end +end +-- print styles +-- SciTE has a single list of styles per Scintilla lexer which +-- is used by multiple languages - we output these definitions +-- for every language. +-- The SciTE colour settings are mapped to SciTECO color profiles +-- by heuristically analyzing SciTE's style definitions. +local style_mapping = { + ["font.comment"] = "color.comment", + ["colour.code.comment.box"] = "color.comment", + ["colour.code.comment.line"] = "color.comment", + ["colour.code.comment.doc"] = "color.comment", + ["colour.number"] = "color.number", + ["colour.keyword"] = "color.keyword", + ["colour.string"] = "color.string", + ["colour.char"] = "color.string2", + ["colour.preproc"] = "color.preproc", + ["colour.operator"] = "color.operator", + ["colour.error"] = "color.error" +} +for i = 0, 255 do + local value = props["style."..lexer.."."..i] + + if value then + for p in value:gmatch("$(%b())") do + local sciteco_color = style_mapping[p:sub(2, -2)] + + if sciteco_color then + io.write(" :M["..sciteco_color.."],"..i.."M[color.set]\n") + break + end + end + end +end +io.write("}\n") |