singe/build-docs.sh

131 lines
5.8 KiB
Bash
Executable file

#!/usr/bin/env bash
# Build the three books in every language they are kept in: the user manual (docs/Manual.adoc,
# which ships inside the binary), the programming reference (docs/Reference.adoc), and the
# beginner's course (docs/Learn.adoc), in English and in each translation, a folder under docs/
# holding a locale.adoc (docs/fr, docs/it, docs/de, docs/es). Produces .builddir/<Book>.html and
# .pdf for English and .builddir/<language>/<Book>.html and .pdf for each translation (a language's
# books sit together, so the links between them work), and then packs the two books that do not
# ship in the binary, with the lesson files and the license, into .builddir/Singe-Docs-v<version>.zip
# and .builddir/Singe-Docs-v<version>-<language>.zip, the optional documentation downloads. The
# version comes from CMakeLists.txt. Last, the ZeroBrane Studio package's API in every language,
# zbstudio/packages/singe/api*.lua, is made again from the Reference (util/zbstudioApi.py).
#
# ./build-docs.sh the books as they ship
# ./build-docs.sh preview the same, with PREVIEW across every page, for proofreaders, all of it
# under .builddir/preview so neither a release nor the binary's own
# copies of the manual (rendered by CMake into .builddir) are touched;
# the downloads are named -preview so they cannot be mistaken for a
# release, and they carry the Manual too, which a release download
# leaves to the binary.
set -euo pipefail
here=$(cd "$(dirname "$0")" && pwd)
preview=
suffix=
if [[ "${1:-}" == "preview" ]]; then
preview=1
suffix=-preview
elif [[ -n "${1:-}" ]]; then
echo "usage: $0 [preview]" >&2
exit 2
fi
books=(Manual Learn Reference)
# English is docs/ itself; every other language is a folder of docs/ with its captions in it.
languages=(en)
for locale in "$here"/docs/*/locale.adoc; do
languages+=("$(basename "$(dirname "$locale")")")
done
for language in "${languages[@]}"; do
for book in "${books[@]}"; do
doc=$here/docs/$book.adoc
if [[ $language != en ]]; then
doc=$here/docs/$language/$book.adoc
fi
if [[ ! -f $doc ]]; then
echo "error: $doc not found" >&2
exit 1
fi
done
done
for tool in asciidoctor asciidoctor-pdf zip; do
if ! command -v "$tool" > /dev/null; then
echo "error: $tool not found (gem install asciidoctor asciidoctor-pdf rouge)" >&2
exit 1
fi
done
# The version, from the four numbers of the project() line: patch 1 means a beta and tweak says
# which, so 3.00.1.2 is the books' "3.00b2", exactly as the binary is named.
read -r major minor patch tweak <<< "$(sed -n 's/^project(singe2 VERSION \([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\1 \2 \3 \4/p' "$here/CMakeLists.txt")"
if [[ $patch == 1 ]]; then
version="${major}.${minor}b${tweak}"
else
version="${major}.${minor}"
fi
# compress deflates the PDFs' streams, which takes most of them to under half their size. The
# watermark, when asked for: a page background for the PDFs, a head snippet for the HTML.
pdfOpts=(-a compress)
# The HTML pages carry their pictures inside them (data-uri), so a page is one file wherever it is
# copied and the download needs no images folder beside it.
htmlOpts=(-a data-uri)
out=$here/.builddir
if [[ -n $preview ]]; then
pdfOpts+=(-a "page-background-image=image:$here/docs/images/preview.svg[fit=fill]")
htmlOpts+=(-a docinfo=shared -a "docinfodir=$here/docs/preview")
out=$here/.builddir/preview
fi
built=()
for language in "${languages[@]}"; do
src=$here/docs
dest=$out
name=Singe-Docs-v$version
if [[ $language != en ]]; then
src=$here/docs/$language
dest=$out/$language
name=Singe-Docs-v$version-$language
fi
mkdir -p "$dest"
for book in "${books[@]}"; do
asciidoctor "${htmlOpts[@]}" -a revnumber="$version" "$src/$book.adoc" -o "$dest/$book.html"
asciidoctor-pdf "${pdfOpts[@]}" -a revnumber="$version" "$src/$book.adoc" -o "$dest/$book.pdf"
built+=("$dest/$book.html" "$dest/$book.pdf")
done
# The documentation download: everything but the user manual, which the binary carries, except
# in a preview, where the Manual goes to the proofreaders with the rest. The README's lines marked
# @PREVIEW@ are kept for a preview and dropped for a release. Built in a staging folder so the zip
# has one top-level directory and no stray build files.
stage=$out/$name$suffix
rm -rf "$stage" "$stage.zip"
mkdir -p "$stage/learn"
cp "$dest/Reference.pdf" "$dest/Reference.html" "$dest/Learn.pdf" "$dest/Learn.html" "$stage/"
previewLines=/^@PREVIEW@/d
if [[ -n $preview ]]; then
cp "$dest/Manual.pdf" "$dest/Manual.html" "$stage/"
previewLines=s/^@PREVIEW@//
fi
cp -r "$here/docs/learn/." "$stage/learn/"
cp "$here/COPYING" "$stage/"
sed -e "s/@VERSION@/$version/" -e "$previewLines" "$src/downloadReadme.txt" > "$stage/README.txt"
(cd "$out" && zip -q -r "$name$suffix.zip" "$name$suffix")
rm -rf "$stage"
built+=("$stage.zip")
done
# ZeroBrane Studio's autocompletion and tooltips are made from the Reference, so they are made again
# with it, from the names a Singe built here defines; the next build embeds them. Without that
# Singe or python3 they stay as they are, and this says so. A preview leaves them alone.
if [[ -z $preview ]]; then
if command -v python3 > /dev/null && [[ -x $here/.builddir/Singe-v$version-Linux-x86_64 ]]; then
python3 "$here/util/zbstudioApi.py"
else
echo "note: ZeroBrane Studio API left as it was (needs python3 and .builddir/Singe-v$version-Linux-x86_64)"
fi
fi
echo "built:"
ls -la "${built[@]}"