-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSConstruct
More file actions
146 lines (121 loc) · 4.93 KB
/
SConstruct
File metadata and controls
146 lines (121 loc) · 4.93 KB
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
import os
import shlex
import subprocess
import sys
import warnings
# check SCons version
EnsureSConsVersion(3, 0)
# we need at least Python 3.5, for example for subprocess.run
if sys.version_info < (3, 5):
raise RuntimeError("These SCons scripts require Python 3.5 or newer. "
"Try running `python3 /usr/bin/scons` or similar.")
# class with helper methods
class Helper(object):
isPDFSizeOptInstalled = None
@staticmethod
def checkPDFSizeOptInstalled(env):
if Helper.checkProgramInstalled(env, "pdfsizeopt"):
Helper.isPDFSizeOptInstalled = True
else:
warnings.warn("pdfsizeopt required for compressing output PDFs. "
"Output PDFs won't be compressed.")
Helper.isPDFSizeOptInstalled = False
# check if a dependency is installed, fail if not (if desired)
@staticmethod
def checkProgramInstalled(env, program, fail=False):
if (not env.GetOption("help")) and (not env.GetOption("clean")):
conf = Configure(env, log_file=None)
result = (conf.CheckProg(program) is not None)
if (not result) and fail:
message = "Program \"{}\" required, but not found in PATH.".format(
program)
if env["REQUIRE_PROGRAMS"]: raise RuntimeError(message)
else: warnings.warn(message)
conf.Finish()
return result
else:
return True
# compress PDF via pdfsizeopt
def compressPDFs(target, source, env):
pdf = target[0].abspath
if Helper.isPDFSizeOptInstalled:
pdfOptimized = "{}.opt".format(pdf)
Helper.runCommand(["pdfsizeopt", "--do-unify-fonts=no",
"--use-pngout=no", "--v=30", pdf, pdfOptimized])
os.remove(pdf)
os.rename(pdfOptimized, pdf)
else:
print("Skipping compression of \"{}\".".format(pdf))
# print and run command line, check=True by default
@staticmethod
def runCommand(args, check=True, **kwargs):
print(" ".join([shlex.quote(arg) for arg in args]))
kwargs["check"] = check
return subprocess.run(args, **kwargs)
# build flags
variables = Variables(None, ARGUMENTS)
variables.Add(BoolVariable("REQUIRE_PROGRAMS",
"Fail if a required program is not installed.", True))
# set up environment, export environment variables of the shell
# (for example needed for custom TeX installations which need PATH)
env = Environment(variables=variables, ENV=os.environ)
# display help about build flags when called with -h
Help(variables.GenerateHelpText(env))
# check if pdfsizeopt is installed
Helper.checkPDFSizeOptInstalled(env)
# use timestamp to decide if a file should be rebuilt
# (otherwise SCons won't rebuild even if it is necessary)
env.Decider("timestamp-newer")
# iterate over all dependent directories
# note: "tex" has to be before "out"
dirTargets = {}
dirs = ["bib", "gfx", "tex", "out"]
createDirs = (not env.GetOption("help")) and (not env.GetOption("clean"))
for dir_ in dirs:
# tell SConscript which its build directory is
env["BUILD_DIR"] = env.Dir(os.path.join("build", dir_))
# create build directory
if createDirs:
env.Execute(Mkdir(env["BUILD_DIR"]))
# execute SConscript
dirTargets[dir_] = env.SConscript(os.path.join(dir_, "SConscript"),
exports=["env", "Helper"])
# clean up dir_
env.Clean(dirTargets[dir_], env["BUILD_DIR"])
# set BUILD_PDF variable
if dir_ == "tex": env["BUILD_PDFS"] = dirTargets[dir_]
# the PDFs depend on everything that is not in tex (these dependencies are
# handled by tex/SConscript) and out
env.Depends(env["BUILD_PDFS"], [dirTargets[dir_] for dir_ in dirs
if dir_ not in ["tex", "out"]])
# build flyer
env.SConscript(os.path.join("flyer", "SConscript"), exports=["env", "Helper"])
# build movie
env.SConscript(os.path.join("movie", "SConscript"), exports=["env", "Helper"])
# dummy targets for starting the presentation with `impressive`
command = r"""
impressive
--transition Crossfade
--transtime 175
--overscan 7
--tracking
{}
out/defenseSlidesPart1.pdf
movie/out/movie_L.mkv
out/defenseSlidesPart2.pdf"""
command = command.strip().replace("\n", " ")
defenseSlideParts = ["out/defenseSlidesPart{}.pdf".format(q) for q in [1, 2]]
env.Command("impressive-debug", defenseSlideParts,
command.format("--fake-fullscreen -g 1920x1080+3286+0"))
env.Command("impressive-fakefull-left", defenseSlideParts,
command.format("--fake-fullscreen -g 1920x1080+0+0"))
env.Command("impressive-fakefull-right", defenseSlideParts,
command.format("--fake-fullscreen -g 1920x1080+1920+0"))
env.Command("impressive-full", defenseSlideParts,
command.format("--fullscreen"))
# dirty fix for Debian bug #893740
# (https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=893740),
# they seem to have reintroduced the Python-2-only syntax "dict.has_key"
# (instead of "in") in SCons/Script/Main.py, line 1111,
# occurs when cleaning, i.e., `scons -c`
os.environ.has_key = (lambda x: x in os.environ)