mirror of
https://git.rtems.org/rtems-docs/
synced 2025-05-15 05:46:49 +08:00

It appears the support for texlive packages on some hosts is variable. This patch lets us add missing packages to our source tree so a PDF can be built on those hosts. The quality of the PDFs created may vary as some short cuts may have been take. For example lato is a font and only the sty file as been added and not the actual font which means it's use will default to another font.
334 lines
11 KiB
Python
334 lines
11 KiB
Python
import sys, os, re
|
|
from waflib.Build import BuildContext
|
|
|
|
import latex
|
|
|
|
sphinx_min_version = (1, 3)
|
|
|
|
def cmd_spell(ctx):
|
|
from waflib import Options
|
|
from sys import argv
|
|
from subprocess import call
|
|
|
|
Options.commands = None # stop warnings about knowing commands.
|
|
|
|
if not ctx.env.BIN_ASPELL:
|
|
ctx.fatal("'aspell' is required please install and re-run configure.")
|
|
|
|
if len(argv) < 3:
|
|
ctx.fatal("Please supply at least one file name")
|
|
|
|
files = argv[2:]
|
|
|
|
path = ctx.path.parent.abspath()
|
|
|
|
# XXX: add error checking eg check if file exists.
|
|
for file in files:
|
|
cmd = ctx.env.BIN_ASPELL + \
|
|
["-c",
|
|
"--personal=%s/common/spell/dict/rtems" % path,
|
|
"--extra-dicts=%s/common/spell/en_GB-ise-w_accents.multi" % path,
|
|
file]
|
|
print("running:", cmd)
|
|
call(cmd)
|
|
|
|
|
|
def cmd_linkcheck(ctx, conf_dir=".", source_dir="."):
|
|
ctx_rule = "${BIN_SPHINX_BUILD} -b linkcheck -c %s -j %d " + \
|
|
"-d build/doctrees %s build/linkcheck" % (conf_dir,
|
|
ctx.options.jobs,
|
|
source_dir)
|
|
ctx(
|
|
rule = ctx_rule,
|
|
cwd = ctx.path.abspath(),
|
|
source = ctx.path.ant_glob('**/*.rst'),
|
|
target = "linkcheck/output.txt"
|
|
)
|
|
|
|
class spell(BuildContext):
|
|
__doc__ = "Check spelling. Supply a list of files or a glob (*.rst)"
|
|
cmd = 'spell'
|
|
fun = 'cmd_spell'
|
|
|
|
class linkcheck(BuildContext):
|
|
__doc__ = "Check all external URL references."
|
|
cmd = 'linkcheck'
|
|
fun = 'cmd_linkcheck'
|
|
|
|
def check_sphinx_version(ctx, minver):
|
|
version = ctx.cmd_and_log(ctx.env.BIN_SPHINX_BUILD +
|
|
['--version']).split(" ")[-1:][0].strip()
|
|
try:
|
|
ver = tuple(map(int, re.split('[\D]', version)))
|
|
except:
|
|
ctx.fatal("Sphinx version cannot be checked: %s" % version)
|
|
if ver < minver:
|
|
ctx.fatal("Sphinx version is too old: %s" % ".".join(map(str, ver)))
|
|
return ver
|
|
|
|
def sphinx_verbose(ctx):
|
|
return ' '.join(ctx.env.SPHINX_VERBOSE)
|
|
|
|
def is_top_build(ctx):
|
|
from_top = False
|
|
if ctx.env['BUILD_FROM_TOP'] and ctx.env['BUILD_FROM_TOP'] == 'yes':
|
|
from_top = True
|
|
return from_top
|
|
|
|
def build_dir_setup(ctx, buildtype):
|
|
where = buildtype
|
|
if is_top_build(ctx):
|
|
where = os.path.join(ctx.path.name, where)
|
|
bnode = ctx.bldnode.find_node(where)
|
|
if bnode is None:
|
|
ctx.bldnode.make_node(where).mkdir()
|
|
build_dir = ctx.path.get_bld().relpath()
|
|
output_node = ctx.path.get_bld().make_node(buildtype)
|
|
output_dir = output_node.abspath()
|
|
doctrees = os.path.join(os.path.dirname(output_dir), 'doctrees', buildtype)
|
|
return build_dir, output_node, output_dir, doctrees
|
|
|
|
def pdf_resources(ctx, buildtype):
|
|
local_packages = latex.local_packages()
|
|
if local_packages is not None:
|
|
packages_base = ctx.path.parent.find_dir('common/latex')
|
|
if packages_base is None:
|
|
ctx.fatal('Latex package directory not found')
|
|
base = packages_base.path_from(ctx.path)
|
|
srcs = [os.path.join(base, p) for p in local_packages]
|
|
fnode = ctx.path.get_bld().make_node(buildtype)
|
|
fnode.mkdir()
|
|
ctx(
|
|
features = "subst",
|
|
is_copy = True,
|
|
source = srcs,
|
|
target = [fnode.make_node(p) for p in local_packages]
|
|
)
|
|
|
|
def html_resources(ctx, buildtype):
|
|
for dir_name in ["_static", "_templates"]:
|
|
files = ctx.path.parent.find_node("common").ant_glob("%s/*" % dir_name)
|
|
fnode = ctx.path.get_bld().make_node(os.path.join(buildtype, dir_name))
|
|
fnode.mkdir() # dirs
|
|
ctx(
|
|
features = "subst",
|
|
is_copy = True,
|
|
source = files,
|
|
target = [fnode.make_node(x.name) for x in files]
|
|
)
|
|
|
|
# copy images
|
|
# ctx.path.get_bld().make_node("images").mkdir()
|
|
# files = ctx.path.parent.ant_glob("images/**")
|
|
# ctx(
|
|
# features = "subst",
|
|
# is_copy = True,
|
|
# source = files,
|
|
# target = [x.srcpath().replace("../", "") for x in files]
|
|
# )
|
|
|
|
|
|
def cmd_configure(ctx):
|
|
ctx.find_program("sphinx-build", var="BIN_SPHINX_BUILD", mandatory = True)
|
|
ctx.find_program("aspell", var = "BIN_ASPELL", mandatory = False)
|
|
|
|
ctx.start_msg("Checking if Sphinx is at least %s.%s" % sphinx_min_version)
|
|
ver = check_sphinx_version(ctx, sphinx_min_version)
|
|
ctx.end_msg("yes (%s)" % ".".join(map(str, ver)))
|
|
|
|
ctx.start_msg("Sphinx Verbose: ")
|
|
if 'SPHINX_VERBOSE' not in ctx.env:
|
|
ctx.env.append_value('SPHINX_VERBOSE', ctx.options.sphinx_verbose)
|
|
level = sphinx_verbose(ctx)
|
|
if level == '-Q':
|
|
level = 'quiet'
|
|
ctx.end_msg(level)
|
|
|
|
#
|
|
# Optional builds.
|
|
#
|
|
ctx.env.BUILD_PDF = 'no'
|
|
if ctx.options.pdf:
|
|
check_tex = not ctx.env.PDFLATEX
|
|
if check_tex:
|
|
ctx.load('tex')
|
|
if not ctx.env.PDFLATEX or not ctx.env.MAKEINDEX:
|
|
ctx.fatal('The programs pdflatex and makeindex are required for PDF output')
|
|
if 'PDFLATEXFLAGS' not in ctx.env or \
|
|
'-shell-escape' not in ctx.env['PDFLATEXFLAGS']:
|
|
ctx.env.append_value('PDFLATEXFLAGS', '-shell-escape')
|
|
latex.configure_tests(ctx)
|
|
else:
|
|
ctx.msg('Check for Tex packages', 'skipping, already checked')
|
|
ctx.env.BUILD_PDF = 'yes'
|
|
|
|
ctx.envBUILD_SINGLEHTML = 'no'
|
|
if ctx.options.singlehtml:
|
|
ctx.env.BUILD_SINGLEHTML = 'yes'
|
|
ctx.find_program("inliner", var = "BIN_INLINER", mandatory = False)
|
|
if not ctx.env.BIN_INLINER:
|
|
ctx.fatal("Node inliner is required install with 'npm install -g inliner' " +
|
|
"(https://github.com/remy/inliner)")
|
|
|
|
def doc_pdf(ctx, source_dir, conf_dir):
|
|
buildtype = 'latex'
|
|
build_dir, output_node, output_dir, doctrees = build_dir_setup(ctx, buildtype)
|
|
pdf_resources(ctx, buildtype)
|
|
rule = "${BIN_SPHINX_BUILD} %s -b %s -c %s -d %s %s %s" % \
|
|
(sphinx_verbose(ctx), buildtype, conf_dir,
|
|
doctrees, source_dir, output_dir)
|
|
ctx(
|
|
rule = rule,
|
|
cwd = ctx.path,
|
|
source = ctx.path.ant_glob('**/*.rst'),
|
|
target = ctx.path.find_or_declare("%s/%s.tex" % (buildtype,
|
|
ctx.path.name))
|
|
)
|
|
ctx(
|
|
features = 'tex',
|
|
cwd = output_dir,
|
|
type = 'pdflatex',
|
|
source = "%s/%s.tex" % (buildtype, ctx.path.name),
|
|
prompt = 0
|
|
)
|
|
ctx.install_files('${PREFIX}',
|
|
'%s/%s.pdf' % (buildtype, ctx.path.name),
|
|
cwd = output_node,
|
|
quiet = True)
|
|
|
|
def doc_singlehtml(ctx, source_dir, conf_dir):
|
|
|
|
#
|
|
# Use a run command to handle stdout and stderr output from inliner. Using
|
|
# a standard rule in the build context locks up.
|
|
#
|
|
def run(task):
|
|
src = task.inputs[0].abspath()
|
|
tgt = task.outputs[0].abspath()
|
|
cmd = '%s %s' % (task.env.BIN_INLINER[0], src)
|
|
so = open(tgt, 'w')
|
|
se = open(tgt + '.err', 'w')
|
|
r = task.exec_command(cmd, stdout = so, stderr = se)
|
|
so.close()
|
|
se.close()
|
|
#
|
|
# The inliner does not handle internal href's correctly and places the
|
|
# input's file name in the href. Strip these.
|
|
#
|
|
with open(tgt, 'r') as i:
|
|
before = i.read()
|
|
after = before.replace('index.html', '')
|
|
i.close()
|
|
with open(tgt, 'w') as o:
|
|
o.write(after)
|
|
o.close()
|
|
return r
|
|
|
|
buildtype = 'singlehtml'
|
|
build_dir, output_node, output_dir, doctrees = build_dir_setup(ctx, buildtype)
|
|
html_resources(ctx, buildtype)
|
|
rule = "${BIN_SPHINX_BUILD} %s -b %s -c %s -d %s %s %s" % \
|
|
(sphinx_verbose(ctx), buildtype, conf_dir,
|
|
doctrees, source_dir, output_dir)
|
|
ctx(
|
|
rule = rule,
|
|
cwd = ctx.path,
|
|
source = ctx.path.ant_glob('**/*.rst'),
|
|
target = ctx.path.find_or_declare("%s/index.html" % (buildtype)),
|
|
install_path = None
|
|
)
|
|
ctx(
|
|
rule = run,
|
|
inliner = ctx.env.BIN_INLINER,
|
|
source = "%s/index.html" % buildtype,
|
|
target = "%s/%s.html" % (buildtype, ctx.path.name),
|
|
install_path = '${PREFIX}'
|
|
)
|
|
|
|
def doc_html(ctx, conf_dir, source_dir):
|
|
buildtype = 'html'
|
|
build_dir, output_node, output_dir, doctrees = build_dir_setup(ctx, buildtype)
|
|
html_resources(ctx, buildtype)
|
|
rule = "${BIN_SPHINX_BUILD} %s -b %s -c %s -d %s %s %s" % \
|
|
(sphinx_verbose(ctx), buildtype, conf_dir,
|
|
doctrees, source_dir, output_dir)
|
|
ctx(
|
|
rule = rule,
|
|
cwd = ctx.path,
|
|
source = ctx.path.ant_glob('**/*.rst'),
|
|
target = ctx.path.find_or_declare('%s/index.html' % buildtype),
|
|
install_path = None
|
|
)
|
|
ctx.install_files('${PREFIX}/%s' % (ctx.path.name),
|
|
output_node.ant_glob('**/*', quiet = True),
|
|
cwd = output_node,
|
|
relative_trick = True,
|
|
quiet = True)
|
|
|
|
def cmd_build(ctx, conf_dir = ".", source_dir = "."):
|
|
srcnode = ctx.srcnode.abspath()
|
|
|
|
if ctx.env.BUILD_PDF == 'yes':
|
|
doc_pdf(ctx, source_dir, conf_dir)
|
|
|
|
if ctx.env.BUILD_SINGLEHTML == 'yes':
|
|
doc_singlehtml(ctx, source_dir, conf_dir)
|
|
|
|
doc_html(ctx, source_dir, conf_dir)
|
|
|
|
def cmd_options(ctx):
|
|
ctx.add_option('--sphinx-verbose',
|
|
action = 'store',
|
|
default = "-Q",
|
|
help = "Sphinx verbose.")
|
|
ctx.add_option('--pdf',
|
|
action='store_true',
|
|
default = False,
|
|
help = "Build PDF.")
|
|
ctx.add_option('--singlehtml',
|
|
action='store_true',
|
|
default = False,
|
|
help = "Build Single HTML file, requires Node Inliner")
|
|
|
|
def cmd_options_path(ctx):
|
|
cmd_options(ctx)
|
|
ctx.add_option('--rtems-path-py',
|
|
type = 'string',
|
|
help = "Full path to py/ in RTEMS source repository.")
|
|
|
|
def cmd_configure_path(ctx):
|
|
if not ctx.options.rtems_path_py:
|
|
ctx.fatal("--rtems-path-py is required")
|
|
|
|
ctx.env.RTEMS_PATH = ctx.options.rtems_path_py
|
|
|
|
cmd_configure(ctx)
|
|
|
|
|
|
CONF_FRAG = """
|
|
sys.path.append(os.path.abspath('../../common/'))
|
|
sys.path.append('%s')
|
|
templates_path = ['_templates']
|
|
html_static_path = ['_static']
|
|
"""
|
|
|
|
# XXX: fix this ugly hack. No time to waste on it.
|
|
def cmd_build_path(ctx):
|
|
def run(task):
|
|
|
|
with open("conf.py") as fp:
|
|
conf = "import sys, os\nsys.path.append(os.path.abspath('../../common/'))\n"
|
|
conf += fp.read()
|
|
|
|
task.inputs[0].abspath()
|
|
task.outputs[0].write(conf + (CONF_FRAG % ctx.env.RTEMS_PATH))
|
|
|
|
ctx(
|
|
rule = run,
|
|
source = [ctx.path.parent.find_node("common/conf.py"),
|
|
ctx.path.find_node("./conf.py")],
|
|
target = ctx.path.get_bld().make_node('conf.py')
|
|
)
|
|
|
|
cmd_build(ctx, conf_dir = "build", source_dir = "build")
|