typo-prc.lua /size: 3593 b    last modification: 2023-12-21 09:44
1if not modules then modules = { } end modules ['typo-prc'] = {
2    version   = 1.001,
3    comment   = "companion to typo-prc.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 lpegmatch, patterns, P, C, Cs = lpeg.match, lpeg.patterns, lpeg.P, lpeg.C, lpeg.Cs
10
11-- processors: syntax: processor->data ... not ok yet
12
13local context           = context
14local implement         = interfaces.implement
15
16local formatters        = string.formatters
17
18typesetters.processors  = typesetters.processors or { }
19local processors        = typesetters.processors
20
21local trace_processors  = false
22local report_processors = logs.reporter("processors")
23local registered        = { }
24
25local ctx_applyprocessor      = context.applyprocessor
26local ctx_firstofoneargument  = context.firstofoneargument
27
28trackers.register("typesetters.processors", function(v) trace_processors = v end)
29
30function processors.register(p)
31    registered[p] = true
32end
33
34function processors.reset(p)
35    registered[p] = nil
36end
37
38--~ local splitter = lpeg.splitat("->",true) -- also support =>
39
40local becomes    = P('->')
41local processor  = (1-becomes)^1
42local splitter   = C(processor) * becomes * Cs(patterns.argument + patterns.content)
43
44function processors.split(str,nocheck)
45    local p, s = lpegmatch(splitter,str)
46    if p and (nocheck or registered[p]) then
47        return p, s
48    else
49        return false, str
50    end
51end
52
53function processors.apply(p,s)
54    local str = p
55    if s == nil then
56        p, s = lpegmatch(splitter,p)
57    end
58    if p and registered[p] then
59        if trace_processors then
60            report_processors("applying %s processor %a, argument: %s","known",p,s)
61        end
62        ctx_applyprocessor(p,s)
63    elseif s then
64        if trace_processors then
65            report_processors("applying %s processor %a, argument: %s","unknown",p,s)
66        end
67        context(s)
68    elseif str then
69        if trace_processors then
70            report_processors("applying %s processor, data: %s","ignored",str)
71        end
72        context(str)
73    end
74end
75
76function processors.startapply(p,s)
77    local str = p
78    if s == nil then
79        p, s = lpegmatch(splitter,p)
80    end
81    if p and registered[p] then
82        if trace_processors then
83            report_processors("start applying %s processor %a","known",p)
84        end
85        ctx_applyprocessor(p)
86        context("{")
87        return s
88    elseif p then
89        if trace_processors then
90            report_processors("start applying %s processor %a","unknown",p)
91        end
92        ctx_firstofoneargument()
93        context("{")
94        return s
95    else
96        if trace_processors then
97            report_processors("start applying %s processor","ignored")
98        end
99        ctx_firstofoneargument()
100        context("{")
101        return str
102    end
103end
104
105function processors.stopapply()
106    context("}")
107    if trace_processors then
108        report_processors("stop applying processor")
109    end
110end
111
112function processors.tostring(str)
113    local p, s = lpegmatch(splitter,str)
114    if registered[p] then
115        return formatters["\\applyprocessor{%s}{%s}"](p,s)
116    else
117        return str
118    end
119end
120
121function processors.stripped(str)
122    local p, s = lpegmatch(splitter,str)
123    return s or str
124end
125
126-- interface
127
128implement { name = "registerstructureprocessor", actions = processors.register, arguments = "string" }
129implement { name = "resetstructureprocessor",    actions = processors.reset,    arguments = "string" }
130