summaryrefslogtreecommitdiff
path: root/tex/context/base/chem-ini.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/chem-ini.lua')
-rw-r--r--tex/context/base/chem-ini.lua75
1 files changed, 75 insertions, 0 deletions
diff --git a/tex/context/base/chem-ini.lua b/tex/context/base/chem-ini.lua
new file mode 100644
index 000000000..908749092
--- /dev/null
+++ b/tex/context/base/chem-ini.lua
@@ -0,0 +1,75 @@
+if not modules then modules = { } end modules ['chem-ini'] = {
+ version = 1.001,
+ comment = "companion to chem-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local format, texsprint = string.format, tex.sprint
+local lpegmatch = lpeg.match
+
+local trace_molecules = false trackers.register("chemistry.molecules", function(v) trace_molecules = v end)
+
+local ctxcatcodes = tex.ctxcatcodes
+
+chemicals = chemicals or { }
+
+--[[
+<p>The next code is an adaptation of code from Wolfgang Schuster
+as posted on the mailing list. This version supports nested
+braces and unbraced integers as scripts. We could consider
+spaces as terminals for them but first let collect a bunch
+of input then.</p>
+]]--
+
+-- some lpeg, maybe i'll make an syst-lpg module
+
+local lowercase = lpeg.R("az")
+local uppercase = lpeg.R("AZ")
+local backslash = lpeg.P("\\")
+local csname = backslash * lpeg.P(1) * (1-backslash)^0
+local plus = lpeg.P("+") / "\\textplus "
+local minus = lpeg.P("-") / "\\textminus "
+local digit = lpeg.R("09")
+local sign = plus + minus
+local cardinal = digit^1
+local integer = sign^0 * cardinal
+
+local leftbrace = lpeg.P("{")
+local rightbrace = lpeg.P("}")
+local nobrace = 1 - (leftbrace + rightbrace)
+local nested = lpeg.P { leftbrace * (csname + sign + nobrace + lpeg.V(1))^0 * rightbrace }
+local any = lpeg.P(1)
+
+local subscript = lpeg.P("_")
+local superscript = lpeg.P("^")
+local somescript = subscript + superscript
+
+--~ local content = lpeg.Cs(nested + integer + sign + any)
+local content = lpeg.Cs(csname + nested + sign + any)
+
+-- could be made more efficient
+
+local lowhigh = lpeg.Cc("\\lohi{%s}{%s}") * subscript * content * superscript * content / format
+local highlow = lpeg.Cc("\\hilo{%s}{%s}") * superscript * content * subscript * content / format
+local low = lpeg.Cc("\\low{%s}") * subscript * content / format
+local high = lpeg.Cc("\\high{%s}") * superscript * content / format
+local justtext = (1 - somescript)^1
+local parser = lpeg.Cs((csname + lowhigh + highlow + low + high + sign + any)^0)
+
+chemicals.moleculeparser = parser -- can be used to avoid functioncall
+
+function chemicals.molecule(str)
+ return lpegmatch(parser,str)
+end
+
+function commands.molecule(str)
+ if trace_molecules then
+ local rep = lpegmatch(parser,str)
+ logs.report("chemistry", "molecule %s => %s",str,rep)
+ texsprint(ctxcatcodes,rep)
+ else
+ texsprint(ctxcatcodes,lpegmatch(parser,str))
+ end
+end