if not modules then modules = { } end modules ['meta-tex'] = { version = 1.001, comment = "companion to meta-tex.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", copyright = "PRAGMA ADE / ConTeXt Development Team", license = "see context related readme files" } local tostring = tostring local format, gsub, find, match = string.format, string.gsub, string.find, string.match local formatters = string.formatters local P, S, R, C, Cs, lpegmatch = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cs, lpeg.match metapost = metapost or { } local implement = interfaces.implement -- local left = P("[") -- local right = P("]") -- local space = P(" ") -- local argument = left * C((1-right)^1) * right -- local pattern = (argument + space)^0 -- function metapost.sometxt(optional,str) -- if optional == "" then -- context.sometxta(str) -- else -- local one, two = lpegmatch(pattern,optional) -- if two then -- context.sometxtc(one,two,str) -- elseif one then -- context.sometxtb(one,str) -- else -- context.sometxta(str) -- end -- end -- end local pattern = Cs((P([[\"]]) + P([["]])/"\\quotedbl{}" + P(1))^0) -- or \char function metapost.escaped(str) context(lpegmatch(pattern,str)) end implement { name = "metapostescaped", actions = metapost.escaped, arguments = "string" } local simplify = true -- local function strip(n,e) -- -- get rid of e(0) -- -- get rid of e(+*) -- e = gsub(e,"^+","") -- -- remove leading zeros -- e = gsub(e,"^([+-]*)0+(%d)","%1%2") -- if not simplify then -- -- take it as it is -- elseif n == "1" then -- return format("10^{%s}",e) -- end -- return format("%s\\times10^{%s}",n,e) -- end -- -- function metapost.format_n(fmt,...) -- fmt = gsub(fmt,"@","%%") -- local initial, hasformat, final = match(fmt,"^(.-)(%%.-[%a])(.-)$") -- if hasformat then -- str = format(fmt,...) -- str = gsub(str,"(.-)e(.-)$",strip) -- str = format("%s\\mathematics{%s}%s",initial,str,final) -- elseif not find(fmt,"%%") then -- str = format("%"..fmt,...) -- str = gsub(str,"(.-)e(.-)$",strip) -- str = format("\\mathematics{%s}",str) -- end -- context(str) -- end -- todo: proper lpeg -- local function strip(n,e) -- -- get rid of e(0) -- -- get rid of e(+*) -- e = gsub(e,"^+","") -- -- remove leading zeros -- e = gsub(e,"^([+-]*)0+(%d)","%1%2") -- if not simplify then -- -- take it as it is -- elseif n == "1" then -- return format("\\mathematics{10^{%s}}",e) -- end -- return format("\\mathematics{%s\\times10^{%s}}",n,e) -- end -- -- function metapost.format_n(fmt,...) -- fmt = gsub(fmt,"@","%%") -- if find(fmt,"%%") then -- str = format(fmt,...) -- else -- yes or no -- str = format("%"..fmt,...) -- end -- str = gsub(str,"([%-%+]-[%.%d]+)e([%-%+]-[%.%d]+)",strip) -- context(str) -- end -- -- function metapost.format_v(fmt,str) -- metapost.format_n(fmt,metapost.untagvariable(str,false)) -- end -- -- -- local number = C((S("+-")^0 * R("09","..")^1)) local enumber = number * S("eE") * number local cleaner = Cs((P("@@")/"@" + P("@")/"%%" + P(1))^0) context = context or { exponent = function(...) print(...) end } function metapost.format_string(fmt,...) context(lpegmatch(cleaner,fmt),...) end function metapost.format_number(fmt,num) if not num then num = fmt fmt = "%e" end local number = tonumber(num) if number then local base, exponent = lpegmatch(enumber,formatters[lpegmatch(cleaner,fmt)](number)) if base and exponent then context.MPexponent(base,exponent) else context(number) end else context(tostring(num)) end end -- This is experimental and will change! function metapost.svformat(fmt,str) metapost.format_string(fmt,metapost.untagvariable(str,false)) end function metapost.nvformat(fmt,str) metapost.format_number(fmt,metapost.untagvariable(str,false)) end implement { name = "metapostformatted", actions = metapost.svformat, arguments = { "string", "string" } } implement { name = "metapostgraphformat", actions = metapost.nvformat, arguments = { "string", "string" } } -- kind of new local f_exponent = formatters["\\MPexponent{%s}{%s}"] local mpformatters = table.setmetatableindex(function(t,k) local v = formatters[lpegmatch(cleaner,k)] t[k] = v return v end) function metapost.texexp(num,bfmt,efmt) local number = tonumber(num) if number then local base, exponent = lpegmatch(enumber,format("%e",number)) if base and exponent then if bfmt then -- base = formatters[lpegmatch(cleaner,bfmt)](base) base = mpformatters[bfmt](base) else base = format("%f",base) end if efmt then -- exponent = formatters[lpegmatch(cleaner,efmt)](exponent) exponent = mpformatters[efmt](exponent) else exponent = format("%i",exponent) end return f_exponent(base,exponent) elseif bfmt then -- return formatters[lpegmatch(cleaner,bfmt)](number) return mpformatters[bfmt](number) else return number end else return num end end -- not in context a namespace if _LUAVERSION < 5.2 then utilities.strings.formatters.add(formatters,"texexp", [[texexp(...)]], "local texexp = metapost.texexp") else utilities.strings.formatters.add(formatters,"texexp", [[texexp(...)]], { texexp = metapost.texexp }) end -- print(string.formatters["%!3.3!texexp!"](10.4345E30)) -- print(string.formatters["%3!texexp!"](10.4345E30,"%2.3f","%2i")) -- print(string.formatters["%2!texexp!"](10.4345E30,"%2.3f")) -- print(string.formatters["%1!texexp!"](10.4345E30)) -- print(string.formatters["%!texexp!"](10.4345E30)) -- local function test(fmt,n) -- logs.report("mp format test","fmt: %s, n: %s, result: %s, \\exponent{%s}{%s}",fmt,n, -- formatters[lpegmatch(cleaner,fmt)](n), -- lpegmatch(enumber,formatters[lpegmatch(cleaner,fmt)](n)) -- ) -- end -- -- test("@j","1e-8") -- test("@j",1e-8) -- test("@j","1e+8") -- test("@j","1e-10") -- test("@j",1e-10) -- test("@j","1e+10") -- test("@j","1e-12") -- test("@j","1e+12") -- test("@j","1e-0") -- test("@j","1e+0") -- test("@j","1") -- test("@j test","1") -- test("@j","-1") -- test("@j","1e-102") -- test("@1.4j","1e+102") -- test("@j","1.2e+102") -- test("@j","1.23e+102") -- test("@j","1.234e+102") local f_textext = formatters[ [[textext("%s")]] ] local f_mthtext = formatters[ [[textext("\mathematics{%s}")]] ] local f_exptext = formatters[ [[textext("\mathematics{%s\times10^{%s}}")]] ] -- local cleaner = Cs((P("\\")/"\\\\" + P("@@")/"@" + P("@")/"%%" + P(1))^0) local mpprint = mp.print function mp.format(fmt,str) -- bah, this overloads mp.format in mlib-lua.lua fmt = lpegmatch(cleaner,fmt) mpprint(f_textext(formatters[fmt](metapost.untagvariable(str,false)))) end function mp.formatted(fmt,...) -- svformat fmt = lpegmatch(cleaner,fmt) mpprint(f_textext(formatters[fmt](...))) end function mp.graphformat(fmt,num) -- nvformat fmt = lpegmatch(cleaner,fmt) local number = tonumber(num) if number then local base, exponent = lpegmatch(enumber,number) if base and exponent then mpprint(f_exptext(base,exponent)) else mpprint(f_mthtext(num)) end else mpprint(f_textext(tostring(num))) end end