summaryrefslogtreecommitdiff
path: root/src/luaotfload-parsers.lua
diff options
context:
space:
mode:
authorPhilipp Gesang <phg42.2a@gmail.com>2014-04-21 16:48:02 +0200
committerPhilipp Gesang <phg42.2a@gmail.com>2014-04-21 16:48:02 +0200
commitf8d43e62f3927545d06e39d01499442b0f64fe79 (patch)
treeb0f4b6eb2985124117aa9b709d732fc589947fec /src/luaotfload-parsers.lua
parent1189a46556c80c9d98b21e3f2dd71bf6a540b78e (diff)
downloadluaotfload-f8d43e62f3927545d06e39d01499442b0f64fe79.tar.gz
[parsers] add INI file parser
Diffstat (limited to 'src/luaotfload-parsers.lua')
-rw-r--r--src/luaotfload-parsers.lua121
1 files changed, 120 insertions, 1 deletions
diff --git a/src/luaotfload-parsers.lua b/src/luaotfload-parsers.lua
index c3c3843..a45fcb8 100644
--- a/src/luaotfload-parsers.lua
+++ b/src/luaotfload-parsers.lua
@@ -21,6 +21,8 @@ luaotfload = luaotfload or { }
luaotfload.parsers = luaotfload.parsers or { }
local parsers = luaotfload.parsers
+local rawset = rawset
+
local lpeg = require "lpeg"
local P, R, S = lpeg.P, lpeg.R, lpeg.S
local lpegmatch = lpeg.match
@@ -62,14 +64,22 @@ local semicolon = P";"
local comma = P","
local noncomma = 1 - comma
local slash = P"/"
+local backslash = P"\\"
local equals = P"="
+local dash = P"-"
+local gartenzaun = P"#"
local lbrk, rbrk = P"[", P"]"
+local squote = P"'"
+local dquote = P"\""
+local newline = P"\n"
+local returnchar = P"\r"
local spacing = S" \t\v"
local linebreak = S"\n\r"
local whitespace = spacing + linebreak
local ws = spacing^0
local xmlws = whitespace^1
+local eol = P"\n\r" + P"\r\n" + linebreak
local digit = R"09"
local alpha = R("az", "AZ")
@@ -339,7 +349,7 @@ parsers.splitcomma = splitcomma
-------------------------------------------------------------------------------
---- FONT REQUEST
+--- FONT REQUEST
-------------------------------------------------------------------------------
@@ -576,3 +586,112 @@ local font_request = Ct(path_lookup * (colon^-1 * features)^-1
luaotfload.parsers.font_request = font_request
+-------------------------------------------------------------------------------
+--- INI FILES
+-------------------------------------------------------------------------------
+
+--[[doc--
+
+ Luaotfload uses the pervasive flavor of the INI files that allows '#' in
+ addition to ';' to indicate comment lines (see git-config(1) for a
+ description of the syntax we’re targeting).
+
+--doc]]--
+
+local truth_ids = {
+ ["true"] = true,
+ ["1"] = true,
+ yes = true,
+ on = true,
+ ["false"] = false,
+ ["2"] = false,
+ no = false,
+ off = false,
+}
+
+local maybe_cast = function (var)
+ local bool = truth_ids[var]
+ if bool ~= nil then
+ return bool
+ end
+ return tonumber (var) or var
+end
+local escape = function (chr, repl)
+ return (backslash * P(chr) / (repl or chr))
+end
+local valid_escapes = escape "\""
+ + escape "\\"
+ + escape ("n", "\n")
+ + escape ("t", "\t")
+ + escape ("b", "\b")
+local comment_char = semicolon + gartenzaun
+local comment_line = ws * comment_char * (1 - eol)^0 * eol
+local blank_line = ws * eol
+local skip_line = comment_line + blank_line
+local ini_id_char = alpha + dash
+local ini_id = (alpha * ini_id_char^0) / stringlower
+local ini_value_char = (valid_escapes + (1 - newline - backslash - comment_char))
+local ini_value = (Cs (ini_value_char^0) / string.strip)
+ * (comment_char * (1 - eol)^0)^-1
+local ini_string_char = (valid_escapes + (1 - newline - dquote - backslash))
+local ini_string = dquote
+ * Cs (ini_string_char^0)
+ * dquote
+
+local ini_heading_title = Ct (Cg (ini_id, "title")
+ * (ws * Cg (ini_string / stringlower, "subtitle"))^-1)
+local ini_heading = lbrk * ws
+ * Cg (ini_heading_title, "section")
+ * ws * rbrk * ws * eol
+
+local ini_variable_full = Cg (ws
+ * ini_id
+ * ws
+ * equals
+ * ws
+ * (ini_string + (ini_value / maybe_cast))
+ * ws
+ * eol)
+local ini_variable_true = Cg (ws * ini_id * ws * eol * Cc (true))
+local ini_variable = ini_variable_full
+ + ini_variable_true
+ + skip_line
+local ini_variables = Cg (Cf (Ct "" * ini_variable^0, rawset), "variables")
+
+local ini_section = Ct (ini_heading * ini_variables)
+local ini_sections = skip_line^0 * ini_section^0
+local config = Ct (ini_sections)
+
+--[[doc--
+
+ The INI parser converts an input of the form
+
+ [==[
+ [foo]
+ bar = baz
+ xyzzy = no
+ buzz
+
+ [lavernica "brutalitops"]
+ # It’s a locomotive that runs on us.
+ laan-ev = zip zop zooey ; jib-jab
+ Crouton = "Fibrosis \"\\ # "
+
+ ]==]
+
+ to a Lua table of the form
+
+ { { section = { title = "foo" },
+ variables = { bar = "baz",
+ xyzzy = false,
+ buzz = true } },
+ { section = { title = "boing",
+ subtitle = "brutalitops" },
+ variables = { ["laan-ev"] = "zip zop zooey",
+ crouton = "Fibrosis \"\\ # " } } }
+
+--doc]]--
+
+luaotfload.parsers.config = config
+
+-- vim:ft=lua:tw=71:et:sts=4:ts=8