lang-lab.lmt /size: 6642 b    last modification: 2024-01-16 10:22
1if not modules then modules = { } end modules ['lang-lab'] = {
2    version   = 1.001,
3    comment   = "companion to lang-lab.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 format, find = string.format, string.find
10local next, rawget, type = next, rawget, type
11local lpegmatch = lpeg.match
12local formatters = string.formatters
13
14local prtcatcodes = catcodes.numbers.prtcatcodes -- todo: use different method
15
16local trace_labels  = false  trackers.register("languages.labels", function(v) trace_labels = v end)
17local report_labels = logs.reporter("languages","labels")
18
19languages.labels        = languages.labels or { }
20local labels            = languages.labels
21
22local context           = context
23local implement         = interfaces.implement
24
25local variables         = interfaces.variables
26local settings_to_array = utilities.parsers.settings_to_array
27
28local splitter = lpeg.splitat(":")
29
30local function split(tag)
31    return lpegmatch(splitter,tag)
32end
33
34labels.split = split
35
36-- We don't store labels at the \LUA\ end because we want to obey grouping. Otherwise we
37-- would need to start using tables that relate to the group level.
38
39local contextsprint      = context.sprint
40
41local f_setlabeltextpair = formatters["\\setlabeltextpair{%s}{%s}{%s}{%s}{%s}"]
42local f_key_key          = formatters["\\v!%s:\\v!%s"]
43local f_key_raw          = formatters["\\v!%s:%s"]
44local f_raw_key          = formatters["%s:\\v!%s"]
45local f_raw_raw          = formatters["%s:%s"]
46local f_key              = formatters["\\v!%s"]
47local f_raw              = formatters["%s"]
48
49local function definelanguagelabels(data,class,tag,rawtag)
50    for language, text in next, data.labels do
51        if text == "" then
52            -- skip
53        elseif type(text) == "table" then
54            contextsprint(prtcatcodes,f_setlabeltextpair(class,language,tag,text[1],text[2]))
55            if trace_labels then
56                report_labels("language %a, defining label %a as %a and %a",language,rawtag,text[1],text[2])
57            end
58        else
59            contextsprint(prtcatcodes,f_setlabeltextpair(class,language,tag,text,""))
60            if trace_labels then
61                report_labels("language %a, defining label %a as %a",language,rawtag,text)
62            end
63        end
64    end
65end
66
67-- local function definelanguagelabels(data,class,tag,rawtag)
68--     local setlabeltextopair = context.setlabeltextpair
69--     context.pushcatcodes("prt")
70--     for language, text in next, data.labels do
71--         if text == "" then
72--             -- skip
73--         elseif type(text) == "table" then
74--             setlabeltextopair(class,language,tag,text[1],text[2])
75--             if trace_labels then
76--                 report_labels("language %a, defining label %a as %a and %a",language,rawtag,text[1],text[2])
77--             end
78--         else
79--             setlabeltextopair(class,language,tag,text,"")
80--             if trace_labels then
81--                 report_labels("language %a, defining label %a as %a",language,rawtag,text)
82--             end
83--         end
84--     end
85--     context.popcatcodes()
86-- end
87
88function labels.define(class,name,prefixed)
89    local list = languages.data.labels[name]
90    if list then
91        report_labels("defining label set %a",name)
92        for tag, data in next, list do
93            tag = variables[tag] or tag
94            if not data.hidden then
95                local key = tag
96                if prefixed then
97                    local first, second = lpegmatch(splitter,tag)
98                    if second then
99                        if rawget(variables,first) then
100                            if rawget(variables,second) then
101                                key = f_key_key(first,second)
102                            else
103                                key = f_key_raw(first,second)
104                            end
105                        elseif rawget(variables,second) then
106                            key = f_raw_key(first,second)
107                        else
108                            key = f_raw_raw(first,second)
109                        end
110                    elseif rawget(variables,rawtag) then
111                        key = f_key(tag)
112                    end
113                end
114             -- report_labels("defining class %a, key %a, tag %a",class,key,tag)
115                definelanguagelabels(data,class,key,tag)
116            end
117        end
118    else
119        report_labels("unknown label set %a",name)
120    end
121end
122
123-- function labels.check()
124--     for category, list in next, languages.data.labels do
125--         for tag, specification in next, list do
126--             for language, text in next, specification.labels do
127--                 if type(text) == "string" and find(text,",") then
128--                     report_labels("warning: label with comma found, category %a, language %a, tag %a, text %a",
129--                         category, language, tag, text)
130--                 end
131--             end
132--         end
133--     end
134-- end
135--
136-- labels.check()
137
138-- interface
139
140interfaces.implement {
141    name      = "definelabels",
142    actions   = labels.define,
143    arguments = { "string",  "string", "boolean" }
144}
145
146-- function commands.setstrippedtextprefix(str)
147--     context(string.strip(str))
148-- end
149
150-- list       : { "a", "b", "c" }
151-- separator  : ", "
152-- last       : " and "
153
154-- text       : "a,b,c"
155-- separators : "{, },{ and }"
156
157local function concatcommalist(settings) -- it's too easy to forget that this one is there
158    local list = settings.list or settings_to_array(settings.text or "")
159    local size = #list
160    local command = settings.command and context[settings.command] or context
161    if size > 1 then
162        local separator, last = " ", " "
163        if settings.separators then
164            local set = settings_to_array(settings.separators)
165            separator = set[1] or settings.separator or separator
166            last      = set[2] or settings.last      or last
167        else
168            separator = settings.separator or separator
169            last      = settings.last      or last
170        end
171        command(list[1])
172        for i=2,size-1 do
173            context(separator)
174            command(list[i])
175        end
176        context(last)
177    end
178    if size > 0 then
179        command(list[size])
180    end
181end
182
183implement {
184    name      = "concatcommalist",
185    actions   = concatcommalist,
186    arguments = {
187        {
188            { "text" },
189            { "separators" },
190            { "separator" },
191            { "last" },
192        }
193    }
194}
195