util-fmt.lua /size: 3379 b    last modification: 2023-12-21 09:44
1if not modules then modules = { } end modules ['util-fmt'] = {
2    version   = 1.001,
3    comment   = "companion to luat-lib.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
9utilities            = utilities or { }
10utilities.formatters = utilities.formatters or { }
11local formatters     = utilities.formatters
12
13local concat, format = table.concat, string.format
14local tostring, type, unpack = tostring, type, unpack
15local strip = string.strip
16
17local lpegmatch = lpeg.match
18local stripper  = lpeg.patterns.stripzeros
19
20function formatters.stripzeros(str)
21    return lpegmatch(stripper,str)
22end
23
24function formatters.formatcolumns(result,between,header)
25    if result and #result > 0 then
26        local widths    = { }
27        local numbers   = { }
28        local templates = { }
29        local first     = result[1]
30        local n         = #first
31              between   = between or "   "
32        --
33        for i=1,n do
34            widths[i] = 0
35        end
36        for i=1,#result do
37            local r = result[i]
38            for j=1,n do
39                local rj = r[j]
40                local tj = type(rj)
41                if tj == "number" then
42                    numbers[j] = true
43                    rj = tostring(rj)
44                elseif tj ~= "string" then
45                    rj = tostring(rj)
46                    r[j] = rj
47                end
48                local w = #rj
49                if w > widths[j] then
50                    widths[j] = w
51                end
52            end
53        end
54        if header then
55            for i=1,#header do
56                local h = header[i]
57                for j=1,n do
58                    local hj = tostring(h[j])
59                    h[j] = hj
60                    local w = #hj
61                    if w > widths[j] then
62                        widths[j] = w
63                    end
64                end
65            end
66        end
67        for i=1,n do
68            local w = widths[i]
69            if numbers[i] then
70                if w > 80 then
71                    templates[i] = "%s" .. between
72                else
73                    templates[i] = "% " .. w .. "i" .. between
74                end
75            else
76                if w > 80 then
77                    templates[i] = "%s" .. between
78                elseif w > 0 then
79                    templates[i] = "%-" .. w .. "s" .. between
80                else
81                    templates[i] = "%s"
82                end
83            end
84        end
85        local template = strip(concat(templates))
86        for i=1,#result do
87            local str = format(template,unpack(result[i]))
88            result[i] = strip(str)
89        end
90        if header then
91            for i=1,n do
92                local w = widths[i]
93                if w > 80 then
94                    templates[i] = "%s" .. between
95                elseif w > 0 then
96                    templates[i] = "%-" .. w .. "s" .. between
97                else
98                    templates[i] = "%s"
99                end
100            end
101            local template = strip(concat(templates))
102            for i=1,#header do
103                local str = format(template,unpack(header[i]))
104                header[i] = strip(str)
105            end
106        end
107    end
108    return result, header
109end
110