diff options
author | Karl Berry <karl@freefriends.org> | 2016-04-22 22:14:39 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2016-04-22 22:14:39 +0000 |
commit | fc4466b32ed330a956ac603b00fd145524cff49a (patch) | |
tree | 2c50e2b8de13aa9233b2c76dffe201558f169e86 /Master/texmf-dist/tex/context/base/chem-str.lua | |
parent | 50e2368597d5f6fe2057195d0ae6a9f2044923e4 (diff) |
context (22apr16)
git-svn-id: svn://tug.org/texlive/trunk@40691 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/context/base/chem-str.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/chem-str.lua | 882 |
1 files changed, 0 insertions, 882 deletions
diff --git a/Master/texmf-dist/tex/context/base/chem-str.lua b/Master/texmf-dist/tex/context/base/chem-str.lua deleted file mode 100644 index d724394bb1d..00000000000 --- a/Master/texmf-dist/tex/context/base/chem-str.lua +++ /dev/null @@ -1,882 +0,0 @@ -if not modules then modules = { } end modules ['chem-str'] = { - version = 1.001, - comment = "companion to chem-str.mkiv", - author = "Hans Hagen and Alan Braslau", - copyright = "PRAGMA ADE / ConTeXt Development Team", - license = "see context related readme files" -} - --- The original \PPCHTEX\ code was written in pure \TEX\, although later we made --- the move from \PICTEX\ to \METAPOST\. The current implementation is a mix between --- \TEX\, \LUA\ and \METAPOST. Although the first objective is to get a compatible --- but better implementation, later versions might provide more. --- --- Well, the later version has arrived as Alan took it upon him to make the code --- deviate even further from the original implementation. The original (early \MKII) --- variant operated within the boundaries of \PICTEX\ and as it supported MetaPost as --- alternative output. As a consequence it still used a stepwise graphic construction --- approach. As we used \TEX\ for parsing, the syntax was more rigid than it is now. --- This new variant uses a more mathematical and metapostisch approach. In the process --- more rendering variants have been added and alignment has been automated. As a result --- the current user interface is slightly different from the old one but hopefully users --- will like the added value. - --- directive_strictorder: one might set this to off when associated texts are disordered too - -local trace_structure = false trackers .register("chemistry.structure", function(v) trace_structure = v end) -local trace_metapost = false trackers .register("chemistry.metapost", function(v) trace_metapost = v end) -local trace_boundingbox = false trackers .register("chemistry.boundingbox", function(v) trace_boundingbox = v end) -local trace_textstack = false trackers .register("chemistry.textstack", function(v) trace_textstack = v end) -local directive_strictorder = true directives.register("chemistry.strictorder", function(v) directive_strictorder = v end) -local directive_strictindex = false directives.register("chemistry.strictindex", function(v) directive_strictindex = v end) - -local report_chemistry = logs.reporter("chemistry") - -local format, gmatch, match, lower, gsub = string.format, string.gmatch, string.match, string.lower, string.gsub -local concat, insert, remove, unique, sorted = table.concat, table.insert, table.remove, table.unique, table.sorted -local processor_tostring = typesetters and typesetters.processors.tostring -local settings_to_array = utilities.parsers.settings_to_array -local settings_to_array_with_repeat = utilities.parsers.settings_to_array_with_repeat - -local lpegmatch = lpeg.match -local P, R, S, C, Cs, Ct, Cc, Cmt = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Cs, lpeg.Ct, lpeg.Cc, lpeg.Cmt - -local variables = interfaces and interfaces.variables -local commands = commands -local context = context -local implement = interfaces.implement - -local formatters = string.formatters -local texgetcount = tex.getcount - -local v_default = variables.default -local v_small = variables.small -local v_medium = variables.medium -local v_big = variables.big -local v_normal = variables.normal -local v_fit = variables.fit -local v_on = variables.on -local v_none = variables.none - -local mpnamedcolor = attributes.colors.mpnamedcolor -local topoints = number.topoints -local todimen = string.todimen - -local trialtypesetting = context.trialtypesetting - -chemistry = chemistry or { } -local chemistry = chemistry - -chemistry.instance = "chemistry" -chemistry.format = "metafun" -chemistry.method = "double" -chemistry.structures = 0 - -local common_keys = { - b = "line", - r = "line", - sb = "line", - sr = "line", - rd = "line", - rh = "line", - rb = "line", - rbd = "line", - cc = "line", - ccd = "line", - line = "line", - dash = "line", - arrow = "line", - c = "fixed", - cd = "fixed", - z = "text", - zt = "text", - zlt = "text", - zrt = "text", - rz = "text", - rt = "text", - lrt = "text", - rrt = "text", - label = "text", - zln = "number", - zrn = "number", - rn = "number", - lrn = "number", - rrn = "number", - zn = "number", - number = "number", - mov = "transform", - mark = "transform", - move = "transform", - diff = "transform", - off = "transform", - adj = "transform", - sub = "transform", -} - -local front_keys = { - bb = "line", - eb = "line", - rr = "line", - lr = "line", - lsr = "line", - rsr = "line", - lrd = "line", - rrd = "line", - lrh = "line", - rrh = "line", - lrbd = "line", - rrbd = "line", - lrb = "line", - rrb = "line", - lrz = "text", - rrz = "text", - lsub = "transform", - rsub = "transform", -} - -local one_keys = { - db = "line", - tb = "line", - bb = "line", - dr = "line", - hb = "line", - bd = "line", - bw = "line", - oe = "line", - sd = "line", - rdb = "line", - ldb = "line", - ldd = "line", - rdd = "line", - ep = "line", - es = "line", - ed = "line", - et = "line", - au = "line", - ad = "line", - cz = "text", - rot = "transform", - dir = "transform", - rm = "transform", - mir = "transform", -} - -local ring_keys = { - db = "line", - hb = "line", - br = "line", - lr = "line", - rr = "line", - lsr = "line", - rsr = "line", - lrd = "line", - rrd = "line", - lrb = "line", - rrb = "line", - lrh = "line", - rrh = "line", - lrbd = "line", - rrbd = "line", - dr = "line", - eb = "line", - er = "line", - ed = "line", - au = "line", - ad = "line", - s = "line", - ss = "line", - mid = "line", - mids = "line", - midz = "text", - lrz = "text", - rrz = "text", - crz = "text", - rot = "transform", - mir = "transform", - adj = "transform", - lsub = "transform", - rsub = "transform", - rm = "transform", -} - --- table.setmetatableindex(front_keys,common_keys) --- table.setmetatableindex(one_keys,common_keys) --- table.setmetatableindex(ring_keys,common_keys) - --- or (faster but not needed here): - -front_keys = table.merged(front_keys,common_keys) -one_keys = table.merged(one_keys,common_keys) -ring_keys = table.merged(ring_keys,common_keys) - -local syntax = { - carbon = { max = 4, keys = one_keys, }, - alkyl = { max = 4, keys = one_keys, }, - newmanstagger = { max = 6, keys = one_keys, }, - newmaneclipsed = { max = 6, keys = one_keys, }, - one = { max = 8, keys = one_keys, }, - three = { max = 3, keys = ring_keys, }, - four = { max = 4, keys = ring_keys, }, - five = { max = 5, keys = ring_keys, }, - six = { max = 6, keys = ring_keys, }, - seven = { max = 7, keys = ring_keys, }, - eight = { max = 8, keys = ring_keys, }, - nine = { max = 9, keys = ring_keys, }, - fivefront = { max = 5, keys = front_keys, }, - sixfront = { max = 6, keys = front_keys, }, - chair = { max = 6, keys = front_keys, }, - boat = { max = 6, keys = front_keys, }, - pb = { direct = 'chem_pb;' }, - pe = { direct = 'chem_pe;' }, - save = { direct = 'chem_save;' }, - restore = { direct = 'chem_restore;' }, - chem = { direct = formatters['chem_symbol("\\chemicaltext{%s}");'], arguments = 1 }, - space = { direct = 'chem_symbol("\\chemicalsymbol[space]");' }, - plus = { direct = 'chem_symbol("\\chemicalsymbol[plus]");' }, - minus = { direct = 'chem_symbol("\\chemicalsymbol[minus]");' }, - gives = { direct = formatters['chem_symbol("\\chemicalsymbol[gives]{%s}{%s}");'], arguments = 2 }, - equilibrium = { direct = formatters['chem_symbol("\\chemicalsymbol[equilibrium]{%s}{%s}");'], arguments = 2 }, - mesomeric = { direct = formatters['chem_symbol("\\chemicalsymbol[mesomeric]{%s}{%s}");'], arguments = 2 }, - opencomplex = { direct = 'chem_symbol("\\chemicalsymbol[opencomplex]");' }, - closecomplex = { direct = 'chem_symbol("\\chemicalsymbol[closecomplex]");' }, - reset = { direct = 'chem_reset;' }, - mp = { direct = formatters['%s'], arguments = 1 }, -- backdoor MP code - dangerous! -} - -chemistry.definitions = chemistry.definitions or { } -local definitions = chemistry.definitions - -storage.register("chemistry/definitions",definitions,"chemistry.definitions") - -function chemistry.undefine(name) - definitions[lower(name)] = nil -end - -function chemistry.define(name,spec,text) - name = lower(name) - local dn = definitions[name] - if not dn then - dn = { } - definitions[name] = dn - end - dn[#dn+1] = { - spec = settings_to_array_with_repeat(spec,true), - text = settings_to_array_with_repeat(text,true), - } -end - -local metacode, variant, keys, max, txt, pstack, sstack, align -local molecule = chemistry.molecule -- or use lpegmatch(chemistry.moleculeparser,...) - -local function fetch(txt) - local st = stack[txt] - local t = st.text[st.n] - while not t and txt > 1 do - txt = txt - 1 - st = stack[txt] - t = st.text[st.n] - end - if t then - if trace_textstack then - report_chemistry("fetching from stack %a, slot %a, data %a",txt,st.n,t) - end - st.n = st.n + 1 - end - return txt, t -end - -local remapper = { - ["+"] = "p", - ["-"] = "m", -} - -local dchrs = R("09") -local sign = S("+-") -local digit = dchrs / tonumber -local amount = (sign^-1 * (dchrs^0 * P('.'))^-1 * dchrs^1) / tonumber -local single = digit -local range = digit * P("..") * digit -local set = Ct(digit^2) -local colon = P(":") -local equal = P("=") -local other = 1 - digit - colon - equal -local remapped = sign / remapper -local operation = Cs(other^1) -local special = (colon * C(other^1)) + Cc("") -local text = (equal * C(P(1)^0)) + Cc(false) - -local pattern = - (amount + Cc(1)) - * (remapped + Cc("")) - * Cs(operation/lower) - * Cs(special/lower) * ( - range * Cc(false) * text + - Cc(false) * Cc(false) * set * text + - single * Cc(false) * Cc(false) * text + - Cc(false) * Cc(false) * Cc(false) * text - ) - --- local n, operation, index, upto, set, text = lpegmatch(pattern,"RZ1357") - --- print(lpegmatch(pattern,"RZ=x")) -- 1 RZ false false false x --- print(lpegmatch(pattern,"RZ1=x")) -- 1 RZ 1 false false x --- print(lpegmatch(pattern,"RZ1..3=x")) -- 1 RZ 1 3 false x --- print(lpegmatch(pattern,"RZ13=x")) -- 1 RZ false false table x - -local f_initialize = 'if unknown context_chem : input mp-chem.mpiv ; fi ;' -local f_start_structure = formatters['chem_start_structure(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s);'] -local f_set_trace_bounds = formatters['chem_trace_boundingbox := %l ;'] -local f_stop_structure = 'chem_stop_structure;' -local f_start_component = 'chem_start_component;' -local f_stop_component = 'chem_stop_component;' -local f_line = formatters['chem_%s%s(%s,%s,%s,%s,%s);'] -local f_set = formatters['chem_set(%s);'] -local f_number = formatters['chem_%s%s(%s,%s,"\\chemicaltext{%s}");'] -local f_text = f_number -local f_empty_normal = formatters['chem_%s(%s,%s,"");'] -local f_empty_center = formatters['chem_c%s(%s,%s,"");'] -local f_transform = formatters['chem_%s(%s,%s,%s);'] - -local prepareMPvariable = commands and commands.prepareMPvariable - -local function process(level,spec,text,n,rulethickness,rulecolor,offset,default_variant) - insert(stack,{ spec = spec, text = text, n = n }) - local txt = #stack - local m = #metacode - local saved_rulethickness = rulethickness - local saved_rulecolor = rulecolor - local saved_align = align - local current_variant = default_variant or "six" - for i=1,#spec do - local step = spec[i] - local s = lower(step) - local n = current_variant .. ":" .. s - local d = definitions[n] - if not d then - n = s - d = definitions[n] - end - if d then - if trace_structure then - report_chemistry("level %a, step %a, definition %a, snippets %a",level,step,n,#d) - end - for i=1,#d do - local di = d[i] - current_variant = process(level+1,di.spec,di.text,1,rulethickness,rulecolor,offset,current_variant) -- offset? - end - else - local factor, osign, operation, special, index, upto, set, text = lpegmatch(pattern,step) - if trace_structure then - local set = set and concat(set," ") or "-" - report_chemistry("level %a, step %a, factor %a, osign %a, operation %a, special %a, index %a, upto %a, set %a, text %a", - level,step,factor,osign,operation,special,index,upto,set,text) - end - if operation == "rulecolor" then - local t = text - if not t then - txt, t = fetch(txt) - end - if t == v_default or t == v_normal or t == "" then - rulecolor = saved_rulecolor - elseif t then - rulecolor = mpnamedcolor(t) - end - elseif operation == "rulethickness" then - local t = text - if not t then - txt, t = fetch(txt) - end - if t == v_default or t == v_normal or t == t_medium or t == "" then - rulethickness = saved_rulethickness - elseif t == v_small then - rulethickness = topoints(1/1.2 * todimen(saved_rulethickness)) - elseif t == v_big then - rulethickness = topoints(1.2 * todimen(saved_rulethickness)) - elseif t then - -- rulethickness = topoints(todimen(t)) -- mp can't handle sp - rulethickness = topoints(tonumber(t) * todimen(saved_rulethickness)) - end - elseif operation == "symalign" then - local t = text - if not t then - txt, t = fetch(txt) - end - if t == v_default or t == v_normal then - align = saved_align - elseif t and t ~= "" then - align = "." .. t - end - elseif operation == "pb" then - insert(pstack,variant) - m = m + 1 ; metacode[m] = syntax.pb.direct - if keys[special] == "text" and index then - if keys["c"..special] == "text" then -- can be option: auto ... - m = m + 1 ; metacode[m] = f_empty_center(special,variant,index) - else - m = m + 1 ; metacode[m] = f_empty_normal(special,variant,index) - end - end - elseif operation == "pe" then - variant = remove(pstack) - local ss = syntax[variant] - keys, max = ss.keys, ss.max - m = m + 1 ; metacode[m] = syntax.pe.direct - m = m + 1 ; metacode[m] = f_set(variant) - current_variant = variant - elseif operation == "save" then - insert(sstack,variant) - m = m + 1 ; metacode[m] = syntax.save.direct - elseif operation == "restore" then - if #sstack > 0 then - variant = remove(sstack) - else - report_chemistry("restore without save") - end - local ss = syntax[variant] - keys, max = ss.keys, ss.max - m = m + 1 ; metacode[m] = syntax.restore.direct - m = m + 1 ; metacode[m] = f_set(variant) - current_variant = variant - elseif operation then - local ss = syntax[operation] - local what = keys[operation] - local ns = 0 - if set then - local sv = syntax[current_variant] - local ms = sv and sv.max - set = unique(set) - ns = #set - if directive_strictorder then - if what == "line" then - set = sorted(set) - end - if directive_strictindex and ms then - for i=ns,1,-1 do - local si = set[i] - if si > ms then - report_chemistry("level %a, operation %a, max nofsteps %a, ignoring %a",level,operation,ms,si) - set[i] = nil - ns = ns - 1 - else - break - end - end - end - else - if directive_strictindex and ms then - local t, nt = { }, 0 - for i=1,ns do - local si = set[i] - if si > ms then - report_chemistry("level %a, operation %a, max nofsteps %a, ignoring %a",level,operation,ms,si) - set[i] = nil - else - nt = nt + 1 - t[nt] = si - end - end - ns = nt - set = t - end - end - end - if ss then - local ds = ss.direct - if ds then - local sa = ss.arguments - if sa == 1 then - local one ; txt, one = fetch(txt) - m = m + 1 ; metacode[m] = ds(one or "") - elseif sa == 2 then - local one ; txt, one = fetch(txt) - local two ; txt, two = fetch(txt) - m = m + 1 ; metacode[m] = ds(one or "",two or "") - else - m = m + 1 ; metacode[m] = ds - end - elseif ss.keys then - variant, keys, max = s, ss.keys, ss.max - m = m + 1 ; metacode[m] = f_set(variant) - current_variant = variant - end - elseif what == "line" then - local s = osign - if s ~= "" then - s = "." .. s - end - if set then - -- condense consecutive numbers in a set to a range - local sf, st = set[1] - for i=1,ns do - if i > 1 and set[i] ~= set[i-1]+1 then - m = m + 1 ; metacode[m] = f_line(operation,s,variant,sf,st,rulethickness,rulecolor) - sf = set[i] - end - st = set[i] - end - m = m + 1 ; metacode[m] = f_line(operation,s,variant,sf,st,rulethickness,rulecolor) - elseif upto then - m = m + 1 ; metacode[m] = f_line(operation,s,variant,index,upto,rulethickness,rulecolor) - elseif index then - m = m + 1 ; metacode[m] = f_line(operation,s,variant,index,index,rulethickness,rulecolor) - else - m = m + 1 ; metacode[m] = f_line(operation,s,variant,1,max,rulethickness,rulecolor) - end - elseif what == "number" then - if set then - for i=1,ns do - local si = set[i] - m = m + 1 ; metacode[m] = f_number(operation,align,variant,si,si) - end - elseif upto then - for i=index,upto do - local si = set[i] - m = m + 1 ; metacode[m] = f_number(operation,align,variant,si,si) - end - elseif index then - m = m + 1 ; metacode[m] = f_number(operation,align,variant,index,index) - else - for i=1,max do - m = m + 1 ; metacode[m] = f_number(operation,align,variant,i,i) - end - end - elseif what == "text" then - if set then - for i=1,ns do - local si = set[i] - local t = text - if not t then txt, t = fetch(txt) end - if t then - t = molecule(processor_tostring(t)) --- local p, t = processors.split(t) --- m = m + 1 ; metacode[m] = f_text(operation,p or align,variant,si,t) - m = m + 1 ; metacode[m] = f_text(operation,align,variant,si,t) - end - end - elseif upto then - for i=index,upto do - local t = text - if not t then txt, t = fetch(txt) end - if t then - t = molecule(processor_tostring(t)) - m = m + 1 ; metacode[m] = f_text(operation,align,variant,i,t) - end - end - elseif index == 0 then - local t = text - if not t then txt, t = fetch(txt) end - if t then - t = molecule(processor_tostring(t)) - m = m + 1 ; metacode[m] = f_text(operation,align,variant,index,t) - end - elseif index then - local t = text - if not t then txt, t = fetch(txt) end - if t then - t = molecule(processor_tostring(t)) - m = m + 1 ; metacode[m] = f_text(operation,align,variant,index,t) - end - else - for i=1,max do - local t = text - if not t then txt, t = fetch(txt) end - if t then - t = molecule(processor_tostring(t)) - m = m + 1 ; metacode[m] = f_text(operation,align,variant,i,t) - end - end - end - elseif what == "transform" then - if osign == "m" then - factor = -factor - end - if set then - for i=1,ns do - local si = set[i] - m = m + 1 ; metacode[m] = f_transform(operation,variant,si,factor) - end - elseif upto then - for i=index,upto do - m = m + 1 ; metacode[m] = f_transform(operation,variant,i,factor) - end - else - m = m + 1 ; metacode[m] = f_transform(operation,variant,index or 1,factor) - end - elseif what == "fixed" then - m = m + 1 ; metacode[m] = f_transform(operation,variant,rulethickness,rulecolor) - elseif trace_structure then - report_chemistry("level %a, ignoring undefined operation %s",level,operation) - end - end - end - end - remove(stack) - return current_variant -end - --- the size related values are somewhat special but we want to be --- compatible --- --- rulethickness in points - -local function checked(d,bondlength,unit,scale) - if d == v_none then - return 0 - end - local n = tonumber(d) - if not n then - -- assume dimen - elseif n >= 10 or n <= -10 then - return bondlength * unit * n / 1000 - else - return bondlength * unit * n - end - local n = todimen(d) - if n then - return scale * n - else - return v_fit - end -end - -local function calculated(height,bottom,top,bondlength,unit,scale) - local scaled = 0 - if height == v_none then - -- this always wins - height = "0pt" - bottom = "0pt" - top = "0pt" - elseif height == v_fit then - height = "true" - bottom = bottom == v_fit and "true" or topoints(checked(bottom,bondlength,unit,scale)) - top = top == v_fit and "true" or topoints(checked(top, bondlength,unit,scale)) - else - height = checked(height,bondlength,unit,scale) - if bottom == v_fit then - if top == v_fit then - bottom = height / 2 - top = bottom - else - top = checked(top,bondlength,unit,scale) - bottom = height - top - end - elseif top == v_fit then - bottom = checked(bottom,bondlength,unit,scale) - top = height - bottom - else - bottom = checked(bottom,bondlength,unit,scale) - top = checked(top, bondlength,unit,scale) - local ratio = height / (bottom+top) - bottom = bottom * ratio - top = top * ratio - end - scaled = height - top = topoints(top) - bottom = topoints(bottom) - height = topoints(height) - end - return height, bottom, top, scaled -end - -function chemistry.start(settings) - -- - local width = settings.width or v_fit - local height = settings.height or v_fit - local unit = settings.unit or 655360 - local bondlength = settings.factor or 3 - local rulethickness = settings.rulethickness or 65536 - local rulecolor = settings.rulecolor or "" - local axiscolor = settings.framecolor or "" - local scale = settings.scale or "normal" - local rotation = settings.rotation or 0 - local offset = settings.offset or 0 - local left = settings.left or v_fit - local right = settings.right or v_fit - local top = settings.top or v_fit - local bottom = settings.bottom or v_fit - -- - align = settings.symalign or "auto" - if trace_structure then - report_chemistry("unit %p, bondlength %s, symalign %s",unit,bondlength,align) - end - if align ~= "" then - align = "." .. align - end - if trace_structure then - report_chemistry("%s scale %a, rotation %a, width %s, height %s, left %s, right %s, top %s, bottom %s","asked",scale,rotation,width,height,left,right,top,bottom) - end - if scale == v_small then - scale = 1/1.2 - elseif scale == v_normal or scale == v_medium or scale == 0 then - scale = 1 - elseif scale == v_big then - scale = 1.2 - else - scale = tonumber(scale) - if not scale or scale == 0 then - scale = 1 - elseif scale >= 10 then - scale = scale / 1000 - elseif scale < .01 then - scale = .01 - end - end - -- - unit = scale * unit - -- - local sp_width = 0 - local sp_height = 0 - -- - width, left, right, sp_width = calculated(width, left, right,bondlength,unit,scale) - height, bottom, top, sp_height = calculated(height,bottom,top, bondlength,unit,scale) - -- - if width ~= "true" and height ~= "true" and trialtypesetting() then - if trace_structure then - report_chemistry("skipping trial run") - end - context.hrule(sp_width,sp_height,0) -- maybe depth - return - end - -- - chemistry.structures = chemistry.structures + 1 - -- - rotation = tonumber(rotation) or 0 - -- - metacode = { } - -- - if trace_structure then - report_chemistry("%s scale %a, rotation %a, width %s, height %s, left %s, right %s, top %s, bottom %s","used",scale,rotation,width,height,left,right,top,bottom) - end - metacode[#metacode+1] = f_start_structure( - chemistry.structures, - left, right, top, bottom, - rotation, topoints(unit), bondlength, scale, topoints(offset), - tostring(settings.axis == v_on), topoints(rulethickness), tostring(axiscolor) - ) - metacode[#metacode+1] = f_set_trace_bounds(trace_boundingbox) ; - -- - variant, keys, stack, pstack, sstack = "one", { }, { }, { }, { } -end - -function chemistry.stop() - if metacode then - metacode[#metacode+1] = f_stop_structure - local mpcode = concat(metacode,"\n") - if trace_metapost then - report_chemistry("metapost code:\n%s", mpcode) - end - if metapost.instance(chemistry.instance) then - f_initialize = nil - end - metapost.graphic { - instance = chemistry.instance, - format = chemistry.format, - method = chemistry.method, - data = mpcode, - definitions = f_initialize, - } - t_initialize = "" - metacode = nil - end -end - -function chemistry.component(spec,text,rulethickness,rulecolor) - if metacode then - local spec = settings_to_array_with_repeat(spec,true) -- no lower? - local text = settings_to_array_with_repeat(text,true) - metacode[#metacode+1] = f_start_component - process(1,spec,text,1,rulethickness,rulecolor) - metacode[#metacode+1] = f_stop_component - end -end - -statistics.register("chemical formulas", function() - if chemistry.structures > 0 then - return format("%s chemical structure formulas",chemistry.structures) -- no timing needed, part of metapost - end -end) - --- interfaces - -implement { - name = "undefinechemical", - actions = chemistry.undefine, - arguments = "string" -} - -implement { - name = "definechemical", - actions = chemistry.define, - arguments = { "string", "string", "string" } -} - -implement { - name = "startchemical", - actions = chemistry.start, - arguments = { - { - { "width" }, - { "height" }, - { "left" }, - { "right" }, - { "top" }, - { "bottom" }, - { "scale" }, - { "rotation" }, - { "symalign" }, - { "axis" }, - { "framecolor" }, - { "rulethickness" }, - { "offset" }, - { "unit" }, - { "factor" } - } - } -} - -implement { - name = "stopchemical", - actions = chemistry.stop, -} - -implement { - name = "chemicalcomponent", - actions = chemistry.component, - arguments = { "string", "string", "string", "string" } -} - --- todo: top / bottom --- maybe add "=" for double and "≡" for triple? - -local inline = { - ["single"] = "\\chemicalsinglebond", ["-"] = "\\chemicalsinglebond", - ["double"] = "\\chemicaldoublebond", ["--"] = "\\chemicaldoublebond", - ["triple"] = "\\chemicaltriplebond", ["---"] = "\\chemicaltriplebond", - ["gives"] = "\\chemicalgives", ["->"] = "\\chemicalgives", - ["equilibrium"] = "\\chemicalequilibrium", ["<->"] = "\\chemicalequilibrium", - ["mesomeric"] = "\\chemicalmesomeric", ["<>"] = "\\chemicalmesomeric", - ["plus"] = "\\chemicalplus", ["+"] = "\\chemicalplus", - ["minus"] = "\\chemicalminus", - ["space"] = "\\chemicalspace", -} - -local ctx_chemicalinline = context.chemicalinline - -function chemistry.inlinechemical(spec) - local spec = settings_to_array_with_repeat(spec,true) - for i=1,#spec do - local s = spec[i] - local inl = inline[lower(s)] - if inl then - context(inl) -- could be a fast context.sprint - else - ctx_chemicalinline(molecule(s)) - end - end -end - -implement { - name = "inlinechemical", - actions = chemistry.inlinechemical, - arguments = "string" -} |