meta-tex.lua /size: 4778 b    last modification: 2020-07-01 14:35
1if not modules then modules = { } end modules ['meta-tex'] = {
2    version   = 1.001,
3    comment   = "companion to meta-tex.mkiv",
4    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
5    copyright = "PRAGMA ADE / ConTeXt Development Team",
6    license   = "see context related readme files"
7}
8
9local tostring, tonumber = tostring, tonumber
10local format = string.format
11local formatters = string.formatters
12local P, S, R, C, Cs, lpegmatch = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cs, lpeg.match
13
14metapost        = metapost or { }
15local metapost  = metapost
16local context   = context
17
18local implement = interfaces.implement
19
20do
21
22    local pattern = Cs((P([[\"]]) + P([["]])/"\\quotedbl{}" + P(1))^0) -- or \char
23
24    function metapost.escaped(str)
25        context(lpegmatch(pattern,str))
26    end
27
28    implement {
29        name      = "metapostescaped",
30        actions   = metapost.escaped,
31        arguments = "string"
32    }
33
34end
35
36do
37
38    local simplify = true
39    local number   = C((S("+-")^0 * R("09","..")^1))
40    local enumber  = number * S("eE") * number
41    local cleaner  = Cs((P("@@")/"@" + P("@")/"%%" + P(1))^0)
42
43    local function format_string(fmt,...)
44        context(lpegmatch(cleaner,fmt),...)
45    end
46
47    local function format_number(fmt,num)
48        if not num then
49            num = fmt
50            fmt = "%e"
51        end
52        local number = tonumber(num)
53        if number then
54            local base, exponent = lpegmatch(enumber,formatters[lpegmatch(cleaner,fmt)](number))
55            if base and exponent then
56                context.MPexponent(base,exponent)
57            else
58                context(number)
59            end
60        else
61            context(tostring(num))
62        end
63    end
64
65    -- This is experimental and will change!
66
67    metapost.format_string = format_string
68    metapost.format_number = format_number
69
70    function metapost.svformat(fmt,str)
71        format_string(fmt,metapost.untagvariable(str,false))
72    end
73
74    function metapost.nvformat(fmt,str)
75        format_number(fmt,metapost.untagvariable(str,false))
76    end
77
78    local f_exponent = formatters["\\MPexponent{%s}{%s}"]
79
80    -- can be a weak one: mpformatters
81
82    local mpformatters = table.setmetatableindex(function(t,k)
83        local v = formatters[lpegmatch(cleaner,k)]
84        t[k] = v
85        return v
86    end)
87
88    function metapost.texexp(num,bfmt,efmt)
89        local number = tonumber(num)
90        if number then
91            local base, exponent = lpegmatch(enumber,format("%e",number))
92            if base and exponent then
93                if bfmt then
94                 -- base = formatters[lpegmatch(cleaner,bfmt)](base)
95                    base = mpformatters[bfmt](base)
96                else
97                    base = format("%f",base)
98                end
99                if efmt then
100                 -- exponent = formatters[lpegmatch(cleaner,efmt)](exponent)
101                    exponent = mpformatters[efmt](exponent)
102                else
103                    exponent = format("%i",exponent)
104                end
105                return f_exponent(base,exponent)
106            elseif bfmt then
107             -- return formatters[lpegmatch(cleaner,bfmt)](number)
108                return mpformatters[bfmt](number)
109            else
110                return number
111            end
112        else
113            return num
114        end
115    end
116
117    implement {
118        name      = "metapostformatted",
119        actions   = metapost.svformat,
120        arguments = "2 strings",
121    }
122
123    implement {
124        name      = "metapostgraphformat",
125        actions   = metapost.nvformat,
126        arguments = "2 strings",
127    }
128
129    utilities.strings.formatters.add(formatters,"texexp", [[texexp(...)]],      { texexp = metapost.texexp })
130
131    local f_textext = formatters[ [[textext("%s")]] ]
132    local f_mthtext = formatters[ [[textext("\mathematics{%s}")]] ]
133    local f_exptext = formatters[ [[textext("\mathematics{%s\times10^{%s}}")]] ]
134
135    local mpprint   = mp.print
136
137    function mp.format(fmt,str) -- bah, this overloads mp.format in mlib-lua.lua
138        fmt = lpegmatch(cleaner,fmt)
139        mpprint(f_textext(formatters[fmt](metapost.untagvariable(str,false))))
140    end
141
142    function mp.formatted(fmt,...) -- svformat
143        fmt = lpegmatch(cleaner,fmt)
144        mpprint(f_textext(formatters[fmt](...)))
145    end
146
147    function mp.graphformat(fmt,num) -- nvformat
148        fmt = lpegmatch(cleaner,fmt)
149        local number = tonumber(num)
150        if number then
151            local base, exponent = lpegmatch(enumber,number)
152            if base and exponent then
153                mpprint(f_exptext(base,exponent))
154            else
155                mpprint(f_mthtext(num))
156            end
157        else
158            mpprint(f_textext(tostring(num)))
159        end
160    end
161
162end
163