summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/typo-prc.lua
blob: 2704149db9947e530bbe784416cccc454e28596f (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
if not modules then modules = { } end modules ['typo-prc'] = {
    version   = 1.001,
    comment   = "companion to typo-prc.mkiv",
    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
    copyright = "PRAGMA ADE / ConTeXt Development Team",
    license   = "see context related readme files"
}

local lpegmatch, patterns, P, C, Cs = lpeg.match, lpeg.patterns, lpeg.P, lpeg.C, lpeg.Cs

-- processors: syntax: processor->data ... not ok yet

local context           = context
local implement         = interfaces.implement

local formatters        = string.formatters

typesetters.processors  = typesetters.processors   or { }
local processors        = typesetters.processors

local trace_processors  = false
local report_processors = logs.reporter("processors")
local registered        = { }

local ctx_applyprocessor      = context.applyprocessor
local ctx_firstofoneargument  = context.firstofoneargument

trackers.register("typesetters.processors", function(v) trace_processors = v end)

function processors.register(p)
    registered[p] = true
end

function processors.reset(p)
    registered[p] = nil
end

--~ local splitter = lpeg.splitat("->",true) -- also support =>

local becomes    = P('->')
local processor  = (1-becomes)^1
local splitter   = C(processor) * becomes * Cs(patterns.argument + patterns.content)

function processors.split(str,nocheck)
    local p, s = lpegmatch(splitter,str)
    if p and (nocheck or registered[p]) then
        return p, s
    else
        return false, str
    end
end

function processors.apply(p,s)
    local str = p
    if s == nil then
        p, s = lpegmatch(splitter,p)
    end
    if p and registered[p] then
        if trace_processors then
            report_processors("applying %s processor %a, argument: %s","known",p,s)
        end
        ctx_applyprocessor(p,s)
    elseif s then
        if trace_processors then
            report_processors("applying %s processor %a, argument: %s","unknown",p,s)
        end
        context(s)
    elseif str then
        if trace_processors then
            report_processors("applying %s processor, data: %s","ignored",str)
        end
        context(str)
    end
end

function processors.startapply(p,s)
    local str = p
    if s == nil then
        p, s = lpegmatch(splitter,p)
    end
    if p and registered[p] then
        if trace_processors then
            report_processors("start applying %s processor %a","known",p)
        end
        ctx_applyprocessor(p)
        context("{")
        return s
    elseif p then
        if trace_processors then
            report_processors("start applying %s processor %a","unknown",p)
        end
        ctx_firstofoneargument()
        context("{")
        return s
    else
        if trace_processors then
            report_processors("start applying %s processor","ignored")
        end
        ctx_firstofoneargument()
        context("{")
        return str
    end
end

function processors.stopapply()
    context("}")
    if trace_processors then
        report_processors("stop applying processor")
    end
end

function processors.tostring(str)
    local p, s = lpegmatch(splitter,str)
    if registered[p] then
        return formatters["\\applyprocessor{%s}{%s}"](p,s)
    else
        return str
    end
end

function processors.stripped(str)
    local p, s = lpegmatch(splitter,str)
    return s or str
end

-- interface

implement { name = "registerstructureprocessor", actions = processors.register, arguments = "string" }
implement { name = "resetstructureprocessor",    actions = processors.reset,    arguments = "string" }