summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/meta-tex.lua
blob: c2f72bcf3c782e4f63a1444ef256bfa92709788b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
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, tonumber = tostring, tonumber
local format = string.format
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 metapost  = metapost
local context   = context

local implement = interfaces.implement

do

    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"
    }

end

do

    local simplify = true
    local number   = C((S("+-")^0 * R("09","..")^1))
    local enumber  = number * S("eE") * number
    local cleaner  = Cs((P("@@")/"@" + P("@")/"%%" + P(1))^0)

    local function format_string(fmt,...)
        context(lpegmatch(cleaner,fmt),...)
    end

    local function 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!

    metapost.format_string = format_string
    metapost.format_number = format_number

    function metapost.svformat(fmt,str)
        format_string(fmt,metapost.untagvariable(str,false))
    end

    function metapost.nvformat(fmt,str)
        format_number(fmt,metapost.untagvariable(str,false))
    end

    local f_exponent = formatters["\\MPexponent{%s}{%s}"]

    -- can be a weak one: mpformatters

    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

    implement {
        name      = "metapostformatted",
        actions   = metapost.svformat,
        arguments = "2 strings",
    }

    implement {
        name      = "metapostgraphformat",
        actions   = metapost.nvformat,
        arguments = "2 strings",
    }

    utilities.strings.formatters.add(formatters,"texexp", [[texexp(...)]],      { texexp = metapost.texexp })

    local f_textext = formatters[ [[textext("%s")]] ]
    local f_mthtext = formatters[ [[textext("\mathematics{%s}")]] ]
    local f_exptext = formatters[ [[textext("\mathematics{%s\times10^{%s}}")]] ]

    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

end