-
Notifications
You must be signed in to change notification settings - Fork 17
/
l3build-typesetting.lua
239 lines (215 loc) · 6.38 KB
/
l3build-typesetting.lua
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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
--[[
File l3build-typesetting.lua Copyright (C) 2018-2024 The LaTeX Project
It may be distributed and/or modified under the conditions of the
LaTeX Project Public License (LPPL), either version 1.3c of this
license or (at your option) any later version. The latest version
of this license is in the file
https://www.latex-project.org/lppl.txt
This file is part of the "l3build bundle" (The Work in LPPL)
and all files in that bundle must be distributed together.
-----------------------------------------------------------------------
The development version of the bundle can be found at
https://github.com/latex3/l3build
for those people who are interested.
--]]
--
-- Auxiliary functions for typesetting: need to be generally available
--
local ipairs = ipairs
local pairs = pairs
local print = print
local gsub = string.gsub
local os_type = os.type
function dvitopdf(name, dir, engine, hide)
runcmd(
set_epoch_cmd(epoch, forcecheckepoch) ..
"dvips " .. name .. dviext
.. (hide and (" > " .. os_null) or "")
.. os_concat ..
"ps2pdf " .. ps2pdfopts .. " " .. name .. psext
.. (hide and (" > " .. os_null) or ""),
dir
)
end
function biber(name,dir)
if fileexists(dir .. "/" .. name .. ".bcf") then
return
runcmd(biberexe .. " " .. biberopts .. " " .. name,dir,{"BIBINPUTS"})
end
return 0
end
function bibtex(name,dir)
dir = dir or "."
if fileexists(dir .. "/" .. name .. ".aux") then
-- LaTeX always generates an .aux file, so there is a need to
-- look inside it for a \citation line
local grep
if os_type == "windows" then
grep = "\\\\"
else
grep = "\\\\\\\\"
end
if run(dir,
os_grepexe .. " \"^" .. grep .. "citation{\" " .. name .. ".aux > "
.. os_null
) + run(dir,
os_grepexe .. " \"^" .. grep .. "bibdata{\" " .. name .. ".aux > "
.. os_null
) == 0 then
local errorlevel = runcmd(bibtexexe .. " " .. bibtexopts .. " " .. name,
dir,{"BIBINPUTS","BSTINPUTS"})
-- BibTeX(8) signals warnings with errorlevel 1
if errorlevel > 1 then return errorlevel else return 0 end
end
end
return 0
end
function makeindex(name,dir,inext,outext,logext,style)
dir = dir or "."
if fileexists(dir .. "/" .. name .. inext) then
if style == "" then style = nil end
return runcmd(makeindexexe .. " " .. makeindexopts
.. " -o " .. name .. outext
.. (style and (" -s " .. style) or "")
.. " -t " .. name .. logext .. " " .. name .. inext,
dir,
{"INDEXSTYLE"})
end
return 0
end
function tex(file,dir,cmd)
dir = dir or "."
cmd = cmd or typesetexe .. " " .. typesetopts
return runcmd(cmd .. " \"" .. typesetcmds
.. "\\input " .. file .. "\"",
dir,{"TEXINPUTS","LUAINPUTS"})
end
local function typesetpdf(file,dir)
dir = dir or "."
local name = jobname(file)
print("Typesetting " .. name)
local fn = typeset
local cmd = typesetexe .. " " .. typesetopts
if specialtypesetting and specialtypesetting[file] then
fn = specialtypesetting[file].func or fn
cmd = specialtypesetting[file].cmd or cmd
end
local errorlevel = fn(file,dir,cmd)
if errorlevel ~= 0 then
print(" ! Compilation failed")
return errorlevel
end
return 0
end
function typeset(file,dir,exe)
dir = dir or "."
local errorlevel = tex(file,dir,exe)
if errorlevel ~= 0 then
return errorlevel
end
local name = jobname(file)
errorlevel = biber(name,dir) + bibtex(name,dir)
if errorlevel ~= 0 then
return errorlevel
end
for i = 2,typesetruns do
errorlevel =
makeindex(name,dir,".glo",".gls",".glg",glossarystyle) +
makeindex(name,dir,".idx",".ind",".ilg",indexstyle) +
tex(file,dir,exe)
if errorlevel ~= 0 then break end
end
return errorlevel
end
-- A hook to allow additional typesetting of demos
function typeset_demo_tasks()
return 0
end
local function docinit()
-- Set up
dep_install(typesetdeps)
unpack({sourcefiles, typesetsourcefiles}, {sourcefiledir, docfiledir})
cleandir(typesetdir)
for _,file in pairs(typesetfiles) do
cp(file, unpackdir, typesetdir)
end
for _,filetype in pairs(
{bibfiles, docfiles, typesetfiles, typesetdemofiles}
) do
for _,file in pairs(filetype) do
cp(file, docfiledir, typesetdir)
end
end
for _,file in pairs(sourcefiles) do
cp(file, sourcefiledir, typesetdir)
end
for _,file in pairs(typesetsuppfiles) do
cp(file, supportdir, typesetdir)
end
-- Main loop for doc creation
local errorlevel = typeset_demo_tasks()
if errorlevel ~= 0 then
return errorlevel
end
return docinit_hook()
end
function docinit_hook() return 0 end
-- Typeset all required documents
-- Uses a set of dedicated auxiliaries that need to be available to others
function doc(files)
local errorlevel = 0
if not options["rerun"] then
errorlevel = docinit()
end
if errorlevel ~= 0 then return errorlevel end
local done = {}
local files_unknown = {}
if files and next(files) then
for _, file in pairs(files) do
files_unknown[file] = true
end
end
for _,typesetfiles in ipairs({typesetdemofiles,typesetfiles}) do
for _,glob in pairs(typesetfiles) do
local destpath,globstub = splitpath(glob)
destpath = docfiledir .. gsub(gsub(destpath,"^./",""),"^.","")
for _,p in ipairs(tree(typesetdir,globstub)) do
local path,srcname = splitpath(p.cwd)
local name = jobname(srcname)
if not done[name] then
local typeset = true
-- Allow for command line selection of files
if files and next(files) then
typeset = false
for _,file in pairs(files) do
if name == file then
files_unknown[file] = nil
typeset = true
break
end
end
end
-- Now know if we should typeset this source
if typeset then
errorlevel = typesetpdf(srcname,path)
if errorlevel ~= 0 then
return errorlevel
else
done[name] = true
local pdfname = jobname(srcname) .. pdfext
rm(pdfname,destpath)
cp(pdfname,path,destpath)
end
end
end
end
end
end
if next(files_unknown) then
for file, _ in pairs(files_unknown) do
print("Unknown doc name \"" .. file .. "\"")
end
return 1
end
return 0
end