Jump to content

Module:Chem2

Permanently protected module
From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Christian75 (talk | contribs) at 21:48, 10 June 2015 (Created page with 'local c = {} -- module's table local am = {} -- Elements with wiki links am.H="H"; am.He="He"; am.Li="Li"; am.Be="[[Beryll...'). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
(diff) ← Previous revision | Latest revision (diff) | Newer revision → (diff)

local c = {} -- module's table


local am = {}  -- Elements with wiki links
am.H="[[Hydrogen|H]]"; am.He="[[Helium|He]]";
am.Li="[[Lithium|Li]]"; am.Be="[[Beryllium|Be]]"; am.B="[[Boron|B]]"; am.C="[[Carbon|C]]"; am.N="[[Nitrogen|N]]"; am.O="[[Oxygen|O]]"; am.F="[[Fluorine|F]]"; am.Ne="[[Neon|Ne]]" am.Phen="[[phenanthroline|Phen]]";

am.Ph="[[phenyl|Ph]]";

local T_ELEM = 0   -- token types
local T_NUM = 1
local T_O = 2      -- open '('
local T_C = 3      -- close ')'
local T_PM = 4     -- + or –
local T_MINUS = 5  -- - 
local T_WATER = 6  -- .xH2O x number
local T_CRYSTAL = 9 -- .x
local T_REST = 7   -- small letters and random crap like ☃
local T_CHARGE = 8 -- charge (x+), (x-), (x–)
local T_SUF_CHARGE = 10 -- suffix and charge
local T_SUF_CHARGE2 = 12 -- suffix and (charge)
local T_SPECIAL = 14  -- starting with \ e.g. \d for double bond =
local T_SPECIAL2 = 16  -- starting with \ e.g. \d for double bond =

function su(a, b) -- like template su
   return "<span style=\"display:inline-block; margin-bottom:-0.3em; vertical-align:-0.4em; line-height:1.2em; font-size:70%; text-align:left;\">" .. a .. "<br />" .. b .. "</span>";
end


function item(f) -- (iterator) returns one token (type, value) at a time from the formula 'f'
   local i = 1
   return function ()
	local t, x = nil, nil
	if i <= f:len() then
                              x = f:match('^%u%l*', i); t = T_ELEM;         -- matching letters like Aaaaa
		if not x then x = f:match('^%d+[%+|%-]', i); t = T_SUF_CHARGE; end        -- matching x+, x-
		if not x then x = f:match('^%d+%(%d*[+|%-]%)', i); t = T_SUF_CHARGE2; end        -- matching x(x+/-), x(+/-)
		if not x then x = f:match('^%(%d*[%+|%-]%)', i); t = T_CHARGE; end        -- matching (x+) (xx+), (x-) (xx-)
		if not x then x = f:match('^%d+', i); t = T_NUM; end        -- matching number
		if not x then x = f:match('^[(|{|%[]', i); t = T_O; end     -- matching ({[
		if not x then x = f:match('^[)|}|%]]', i); t = T_C; end           -- matching )}]
                if not x then x = f:match('^[+]', i); t = T_PM; end        -- matching '+', xxxxx væk: '–' (long –)
                if not x then x = f:match('^-', i); t = T_MINUS; end        -- matching - (short)
                if not x then x = f:match('^–', i); t = T_MINUS; end        -- matching - (long) - stange output
                if not x then x = f:match('^%.[0-9]*H2O', i); t = T_WATER; end -- Crystal water
                if not x then x = f:match('^%.[0-9]+', i); t = T_CRYSTAL; end -- Crystal
                if not x then x = f:match('^\.{%d+}', i); t = T_SPECIAL2; end -- \y[x]
                if not x then x = f:match('^\.', i); t = T_SPECIAL; end -- \x
		if not x then x = f:match('^.', i); t = T_REST; end  --Resten en ad gangen
		if x then i = i + x:len(); else i = i + 999; error("Invalid character in formula!!!!!!! : "..f) end
		end
	return t, x
	end
   end

function c.mm(frame) -- molar mass of the formula 'f'
   local f = frame.args[1]
   local config = frame.args

   local link = frame.args['link']

   local sum, cur = {0}, {0}  -- stacks to handle '()' ; 'cur' awaits to be multiplied (or not)
   local sumO = 0
   local formel = ''
   local t, x

   local link = config.link or ""

   if not (link == nil or link == '') then formel = formel .. "[[" .. link .. "|"; end   -- wikilink start [[link|
 
   for t, x in item(f) do 
            if     t == T_ELEM then if not config.auto then formel = formel .. x elseif am[x] then formel = formel .. am[x]; am[x] = x;
                      else formel = formel .. x end

	elseif     t == T_REST  then formel = formel .. x;
	elseif t == T_NUM   then formel = formel .. "<span style=\"display:inline-block; margin-bottom:-0.3em; vertical-align:-0.4em; line-height:1.2em; font-size:70%; text-align:right;\">" .. x .."</span>";    -- su|w=70%|a=r|p={{{1}}}|b={{{2}}}}}
	elseif t == T_O       then formel = formel .. x; sumO = sumO + 1;        -- ( {
	elseif t == T_C       then formel = formel .. x; sumO = sumO -1;         -- ) }
--        elseif t == T_PM      then formel = formel .. "aaaa" ..  "<sup>" .. string.gsub(x, "-", "–") .. "</sup>";
        elseif t == T_PM      then formel = formel .. "<sup>" .. x .. "</sup>";
        elseif t == T_MINUS   then formel = formel .. "<sup>–</sup>";

       elseif t == T_SUF_CHARGE then 
         formel = formel .. su(string.gsub(string.match(x, "[%+|%-|–]"), "-", "–"), string.match(x, "%d+"));

---x
       elseif t == T_SUF_CHARGE2 then 
          formel = formel .. su(string.sub(string.gsub(string.match(x, "%(%d*[+|%-]"), "-", "–"), 2, -1), string.match(x, "%d+"))
                                                             

       elseif t == T_CHARGE then formel = formel .. "<sup>"; if string.match(x, "%d+") then formel = formel .. string.match(x, "%d+"); end formel = formel .. string.gsub(string.match(x, "[%-|%–|%+]"), "-", "–") .. "</sup>";  -- can not concatenat a nil value from string.match(x, "%d+");

        elseif t == T_WATER then formel = formel .. '&nbsp;<span style="font-weight:bold;">&middot;</span>&#32;' .. "[[Water of crystallization|H<sub>2</sub>O]]";
        elseif t == T_CRYSTAL then formel = formel .. '&nbsp;<span style="font-weight:bold;">&middot;</span>&#32;' .. string.gsub( x, ".", ' ', 1 );

        elseif t == T_SPECIAL then 
          if x == "\s" then formel = formel .. "–"       -- single bond
          elseif x == "\d" then formel = formel .. "="   -- double bond
          elseif x == "\t" then formel = formel .. "a≡" end   -- double bond

        elseif t == T_SPECIAL2 then    -- \y{x}
          if string.sub(x, 1, 1) == "h" then formel = formel .. "η<sup>" .. string.match(x, '%d+') .. "</sup>"

  else formel = formel .. x end
          
 	else error('unreachable - ???') end -- in fact, unreachable
   end

   if      sumO > 0 then formel = formel .. "'<span style=\"display:none;font-size:100%\" class=\"error citation-comment\">   Too many (</span>'\";"
    elseif sumO < 0 then formel = formel .. "'<span style=\"display:none;font-size:100%\" class=\"error citation-comment\">   Too many )</span>'\";"
   end

   if not (link == nil or link == '') then formel = formel .. "]]"; end   -- wikilink closing ]]

   return formel
end



return c -- exports c.mm()