HandBrake-docs/build-docs
Bradley Sepos cc0e6b0e75 build: Refactor document generation to be faster and support partials.
Article header and footer are now partials, making them easy to exclude from license files.
2016-03-25 21:17:45 -04:00

158 lines
5.4 KiB
Bash
Executable File

#!/bin/bash
# vars
SELF="${BASH_SOURCE[0]}"
BASE_DIR=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd -P)
BASE_DIR="${BASE_DIR:-$(pwd)}"
CONFIG="${BASE_DIR}/config.yaml"
DOCS_DIR="${BASE_DIR}/docs"
SOURCE_DIR="${BASE_DIR}/source"
TEMPLATE_DIR="${BASE_DIR}/templates"
TOOLS_DIR="${BASE_DIR}/tools"
# dependencies
MARKDOWN="${BASE_DIR}/tools/discount/markdown"
if [[ "${1}" == "--markdown" ]]; then # TODO: remove ugly hack
MARKDOWN="${2}"
fi
DEPS=("${MARKDOWN}")
# creates bash variables from yaml records
# https://gist.github.com/pkuczynski/8665367
function parse_yaml {
local prefix=$2
local s='[[:space:]]*' w='[a-zA-Z0-9_]*' fs=$(echo @|tr @ '\034')
sed -ne "s|^\($s\)\($w\)$s:$s\"\(.*\)\"$s\$|\1$fs\2$fs\3|p" \
-e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|p" $1 |
awk -F$fs '{
indent = length($1)/2;
vname[indent] = $2;
for (i in vname) {if (i > indent) {delete vname[i]}}
if (length($3) > 0) {
vn=""; for (i=0; i<indent; i++) {vn=(vn)(vname[i])("_")}
printf("%s%s%s=\"%s\"\n", "'$prefix'",vn, $2, $3);
}
}'
}
# checks for required external tools
function check_dependencies { # takes 1 argument
DEPS=("${1}");
ERROR=false
for DEP in ${DEPS[@]}; do
if echo "${DEP}" | grep '/' >/dev/null 2>&1 && [[ ! -x "${DEP}" ]]; then
ERROR=true
elif ! hash "${DEP}" >/dev/null 2>&1; then
ERROR=true
fi
done
if [[ "${ERROR}" == true ]]; then
echo "Error: Unable to find command '${DEP#$BASE_DIR/}'." >&2
return 1
fi
}
# builds document(s) from a single source file
function build_source {
local SOURCE YAML META_Title META_Project META_Project_URL META_Project_Version META_Language META_Language_Code META_Text_Encoding META_Authors META_Copyright META_License META_License_URL
SOURCE="${1}"
DEST="${SOURCE%.markdown}"
DEST_NAME="${DEST##*/}"
# check for yaml header
META=false
if head -n 1 "${SOURCE}" | grep '^---$' >/dev/null 2>&1; then
META=true
fi
if [[ "${META}" == true ]]; then
# split yaml and markdown
awk '{ drop = 0; } /^---$/ { if (NR==1) { drop = 1 } else if (NR>1) { exit } else { drop = 0; next } } drop == 0 { print }' "${SOURCE}" > "${DEST}.yaml"
mv "${SOURCE}" "${DEST}.markdown.temp"
tail -n +$(wc -l "${DEST}.yaml" | awk '{ print $1+3 }') "${DEST}.markdown.temp" > "${SOURCE}"
rm -f "${DEST}.markdown.temp"
# parse yaml
eval $(parse_yaml "${DEST}.yaml" "META_")
fi
# generate document using template
DOCUMENT_Content="${DEST}.html.temp"
"${MARKDOWN}" -fdlextra -ffencedcode -ffootnote -fgithubtags "${SOURCE}" > "${DOCUMENT_Content}"
cp "${TEMPLATE_Document}" "${DEST}.html"
if [[ "${DEST_NAME}" == "license" ]] || [[ "${DEST_NAME}" == "license-summary" ]]; then
sed -E \
-e 's|{{[ ]*template\.header[ ]*}}||g' \
-e 's|{{[ ]*template\.footer[ ]*}}||g' \
-i .sedbak "${DEST}.html"
fi
sed -E \
-e '/{{[ ]*template\.header[ ]*}}/r '"${TEMPLATE_Header}"'' -e '/{{[ ]*template\.header[ ]*}}/d' \
-e '/{{[ ]*document\.content[ ]*}}/r '"${DOCUMENT_Content}"'' -e '/{{[ ]*document\.content[ ]*}}/d' \
-e '/{{[ ]*template\.footer[ ]*}}/r '"${TEMPLATE_Footer}"'' -e '/{{[ ]*template\.footer[ ]*}}/d' \
-i .sedbak "${DEST}.html"
sed -E \
-e 's|{{[ ]*meta\.title[ ]*}}|'"${META_Title:-}"'|g' \
-e 's|{{[ ]*meta\.project[ ]*}}|'"${META_Project:-}"'|g' \
-e 's|{{[ ]*meta\.project-url[ ]*}}|'"${META_Project_URL:-}"'|g' \
-e 's|{{[ ]*meta\.project-version[ ]*}}|'"${META_Project_Version:-}"'|g' \
-e 's|{{[ ]*meta\.language[ ]*}}|'"${META_Language:-}"'|g' \
-e 's|{{[ ]*meta\.language-code[ ]*}}|'"${META_Language_Code:-}"'|g' \
-e 's|{{[ ]*meta\.text-encoding[ ]*}}|'"${META_Text_Encoding:-}"'|g' \
-e 's|{{[ ]*meta\.authors[ ]*}}|'"${META_Authors:-}"'|g' \
-e 's|{{[ ]*meta\.copyright[ ]*}}|'"${META_Copyright:-}"'|g' \
-e 's|{{[ ]*meta\.license[ ]*}}|'"${META_License:-}"'|g' \
-e 's|{{[ ]*meta\.license-abbr[ ]*}}|'"${META_License_Abbr:-}"'|g' \
-e 's|{{[ ]*meta\.license-url[ ]*}}|'"${META_License_URL:-}"'|g' \
-e 's|{{[ ]*base\.relpath[ ]*}}|'"${BASE_RELPATH:-}"'|g' \
-i .sedbak "${DEST}.html"
# clean up
rm -f "${DEST}.markdown"
rm -f "${DEST}.yaml"
rm -f "${DEST}.html.temp"
rm -f "${DEST}.html.sedbak"
}
# base directory (absolute)
cd "${BASE_DIR}"
# check deps
check_dependencies "${DEPS[@]}" || exit 1
# parse config
if [[ -e "${CONFIG}" ]]; then
eval $(parse_yaml "${CONFIG}" "CONFIG_")
else
echo "Configuration file not found." >&2
exit 1
fi
# check template
TEMPLATE_DIR+="/${CONFIG_Template}"
if [[ ! -d "${TEMPLATE_DIR}" ]] || [[ ! -e "${TEMPLATE_DIR}/document.html" ]]; then
echo "Template '${CONFIG_Template}' not found." >&2
exit 1
fi
# template vars
TEMPLATE_Document="${TEMPLATE_DIR}/document.html"
TEMPLATE_Header="${TEMPLATE_DIR}/header.html"
TEMPLATE_Footer="${TEMPLATE_DIR}/footer.html"
# clean
rm -rf "${DOCS_DIR}"/*
# build
cp -R "${TEMPLATE_DIR}"/fonts "${TEMPLATE_DIR}"/style "${SOURCE_DIR}"/* "${DOCS_DIR}"/
SOURCES=($(find "${DOCS_DIR}" | sed 's/^\.\///' | grep -i '.markdown'))
for SOURCE in ${SOURCES[@]}; do
BASE_RELPATH="${SOURCE#$DOCS_DIR/}" # strip abs prefix
BASE_RELPATH="${BASE_RELPATH//[^\/]}" # leave only slashes
BASE_RELPATH="${BASE_RELPATH//[\/]/../}" # slashes to dirs
build_source "${SOURCE}"
done
# done
exit 0