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