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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
-- luacheck: ignore ly log self luatexbase internalversion font fonts tex token kpse status
local err, warn, info, log = luatexbase.provides_module({
name = "lyluatex-lib",
version = '1.0f', --LYLUATEX_VERSION
date = "2019/05/27", --LYLUATEX_DATE
description = "Module lyluatex-lib.",
author = "The Gregorio Project − (see Contributors.md)",
copyright = "2015-2019 - jperon and others",
license = "MIT",
})
local lib = {}
lib.TEX_UNITS = {'bp', 'cc', 'cm', 'dd', 'in', 'mm', 'pc', 'pt', 'sp', 'em',
'ex'}
-------------------------
-- General tool functions
function lib.basename(str)
--[[
Given the full path to a file, return only the file name (without path).
If there is no slash, return the full name.
--]]
return str:gsub(".*/(.*)", "%1") or str
end
function lib.contains(table_var, value)
--[[
Returns the key if the given table contains the given value, or nil.
A value of 'false' (string) is considered equal to false (Boolean).
--]]
for k, v in pairs(table_var) do
if v == value then return k
elseif v == 'false' and value == false then return k
end
end
end
function lib.contains_key(table_var, key)
-- Returs true if the given key is present in the table, nil otherwise.
for k in pairs(table_var) do
if k == key then return true end
end
end
function lib.convert_unit(value)
--[[
Convert a LaTeX unit, if possible.
TODO: Understand what this *really* does, what is accepted and returned.
--]]
if not value then return 0
elseif value == '' then return false
elseif value:match('\\') then
local n, u = value:match('^%d*%.?%d*'), value:match('%a+')
if n == '' then n = 1 end
return tonumber(n) * tex.dimen[u] / tex.sp("1pt")
else return ('%f'):format(tonumber(value) or tex.sp(value) / tex.sp("1pt"))
end
end
function lib.dirname(str)
--[[
Given the full path to a file, return only the path (without file name),
including the last slash. If there is no slash, return an empty string.
--]]
return str:gsub("(.*/).*", "%1") or ''
end
local fontdata = fonts.hashes.identifiers
function lib.fontinfo(id)
--[[
Return a LuaTeX font object based on the given ID
--]]
return fontdata[id] or font.fonts[id]
end
function lib.max(a, b)
a, b = tonumber(a), tonumber(b)
if a > b then return a else return b end
end
function lib.min(a, b)
a, b = tonumber(a), tonumber(b)
if a < b then return a else return b end
end
function lib.mkdirs(str)
local path
if str:sub(1, 1) == '/' then path = '' else path = '.' end
for dir in str:gmatch('([^%/]+)') do
path = path .. '/' .. dir
lfs.mkdir(path)
end
end
function lib.orderedpairs(t)
local key
local i = 0
local orderedIndex = {}
for k in pairs(t) do table.insert(orderedIndex, k) end
table.sort(orderedIndex)
return function ()
i = i + 1
key = orderedIndex[i]
if key then return key, t[key] end
end
end
function lib.readlinematching(s, f)
if f then
local result = ''
while result and not result:find(s) do result = f:read() end
f:close()
return result
end
end
function lib.splitext(str, ext)
--[[
If 'ext' is supplied return str stripped of the given extension,
otherwise return the base and extension (if any)
--]]
return ext and (str:match('(.*)%.'..ext..'$') or str)
or (str:match('(.*)%.(%w*)$') or str)
end
------------------------------------
-- Engine, version, TeX distribution
local tex_engine = {}
setmetatable(tex_engine, tex_engine)
function tex_engine:__call()
--[[
Defines the properties extracted from the first line of jobname.log.
--]]
local f = io.open(tex.jobname..'.log')
if not f then return end
self.engine, self.engine_version, self.dist, self.dist_version, self.format, self.format_version =
f:read():match(
'This is ([^,]*), Version ([^%(]*) %(([^%)]*) ([^%)]*)%)%s+%(format=([^%)]*) ([^)]*)%)'
)
f:close()
return self
end
function tex_engine:__index(k) return rawget(self(), k) end
lib.tex_engine = tex_engine
return lib
|