| #!/bin/bash -p |
| ############################################################################### |
| # BRLTTY - A background process providing access to the console screen (when in |
| # text mode) for a blind person using a refreshable braille display. |
| # |
| # Copyright (C) 1995-2023 by The BRLTTY Developers. |
| # |
| # BRLTTY comes with ABSOLUTELY NO WARRANTY. |
| # |
| # This is free software, placed under the terms of the |
| # GNU Lesser General Public License, as published by the Free Software |
| # Foundation; either version 2.1 of the License, or (at your option) any |
| # later version. Please see the file LICENSE-LGPL for details. |
| # |
| # Web Page: http://brltty.app/ |
| # |
| # This software is maintained by Dave Mielke <dave@mielke.cc>. |
| ############################################################################### |
| |
| defaultOutputRoot="doc-ktb" |
| |
| . "`dirname "${0}"`/brltty-prologue.sh" |
| addProgramOption s string.directory sourceRoot "top-level directory of source tree" "the location of this script" |
| addProgramOption b string.directory buildRoot "top-level directory of build tree" "the source tree" |
| addProgramOption o string.directory outputRoot "top-level directory of output tree" "${defaultOutputRoot}" |
| addProgramOption k flag keepFiles "don't remove intermediate files" |
| parseProgramArguments "${@}" |
| |
| set -e |
| umask 022 |
| shopt -s nullglob |
| |
| [ -n "${sourceRoot}" ] || sourceRoot="$(dirname "${0}")" |
| verifyInputDirectory "${sourceRoot}" |
| sourceRoot="$(cd "${sourceRoot}" && pwd)" |
| |
| [ -n "${buildRoot}" ] || buildRoot="${sourceRoot}" |
| buildRoot="$(cd "${buildRoot}" && pwd)" |
| |
| [ -n "${outputRoot}" ] || outputRoot="${defaultOutputRoot}" |
| verifyOutputDirectory "${outputRoot}" |
| |
| unset HOME |
| export XDG_CONFIG_HOME=/ |
| export XDG_CONFIG_DIRS=/ |
| |
| readonly newLine=$'\n' |
| |
| lineGroups=() |
| newLineGroup() { |
| local variable="${1}" |
| |
| local group="lineGroup${#lineGroups[*]}" |
| lineGroups+=("${group}") |
| setVariable "${variable}" "${group}" |
| |
| declare -g -a "${group}" |
| eval "${group}=()" |
| } |
| |
| addLineToGroup() { |
| local group="${1}" |
| local line="${2}" |
| |
| eval "${group}+="'("${line}")' |
| } |
| |
| newDocLines() { |
| newLineGroup docLines |
| } |
| |
| beginTocEntries() { |
| local variable="${1}" |
| |
| newLineGroup "${variable}" |
| newDocLines |
| |
| addLineToGroup "${!variable}" "<ul>" |
| } |
| |
| endTocEntries() { |
| local group="${1}" |
| |
| addLineToGroup "${group}" "</ul>" |
| } |
| |
| addTocEntry() { |
| local group="${1}" |
| local title="${2}" |
| local anchor="${3}" |
| |
| addLineToGroup "${group}" "<li><a href=\"#${anchor}\">${title}</a></li>" |
| } |
| |
| addDocLine() { |
| local line="${1}" |
| |
| addLineToGroup "${docLines}" "${line}" |
| } |
| |
| addSectionTerminator() { |
| addDocLine "<hr />" |
| } |
| |
| addAnchor() { |
| local anchor="${1}" |
| |
| addDocLine "<a name=\"${anchor}\"></a>" |
| } |
| |
| beginDocument() { |
| local title="${1}" |
| |
| newDocLines |
| headerLevel=0 |
| |
| addDocLine "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" |
| addDocLine "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">" |
| |
| addDocLine "<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"en\" xml:lang=\"en\">" |
| addDocLine "<head>" |
| addDocLine "<title>${title}</title>" |
| addDocLine "</head>" |
| addDocLine "<body>" |
| } |
| |
| endDocument() { |
| local file="${1}" |
| |
| addDocLine "</body>" |
| addDocLine "</html>" |
| |
| exec 3>"${file}" |
| local group |
| |
| for group in "${lineGroups[@]}" |
| do |
| eval set -- '"${'"${group}"'[@]}"' |
| local line |
| |
| for line |
| do |
| echo >&3 "${line}" |
| done |
| done |
| exec 3>&- |
| } |
| |
| beginSection() { |
| local title="${1}" |
| |
| local anchor="${title,,?}" |
| anchor="${anchor//[^a-zA-Z_0-9]/-}" |
| addAnchor "${anchor}" |
| |
| headerLevel=$((headerLevel + 1)) |
| addDocLine "<h${headerLevel}>${title}</h${headerLevel}>" |
| |
| if ((headerLevel == 1)) |
| then |
| beginTocEntries tocSections |
| addSectionTerminator |
| else |
| addTocEntry "${tocSections}" "${title}" "${anchor}" |
| fi |
| } |
| |
| endSection() { |
| if ((headerLevel == 1)) |
| then |
| endTocEntries "${tocSections}" |
| else |
| addSectionTerminator |
| fi |
| |
| headerLevel=$((headerLevel - 1)) |
| } |
| |
| beginLayoutList() { |
| layoutListed=false |
| } |
| |
| endLayoutList() { |
| ! "${layoutListed}" || { |
| addDocLine "</ul>" |
| } |
| } |
| |
| beginLayoutEntry() { |
| local prefix="${1}" |
| local outputExtension="${2}" |
| |
| local layout="${inputFile##*/}" |
| layout="${layout%.*}" |
| |
| outputFile="${outputRoot}/${prefix}-${layout}.${outputExtension}" |
| } |
| |
| endLayoutEntry() { |
| local category="${1}" |
| |
| exec 4<"${outputFile%.*}.${plainTextExtension}" |
| local description |
| read -r -u 4 description |
| exec 4<&- |
| |
| description="${description} " |
| description="${description#*: }" |
| [ -z "${category}" ] || description="${description#${category} }" |
| description="${description% }" |
| |
| local prefix="All Models" |
| [ -z "${description}" ] || { |
| if [ "${description}" = "${description#(}" ] |
| then |
| prefix="" |
| else |
| prefix="${prefix} " |
| fi |
| } |
| description="${prefix}${description}" |
| |
| "${layoutListed}" || { |
| layoutListed=true |
| addDocLine "<ul>" |
| } |
| |
| addDocLine "<li><a href=\"${outputFile##*/}\">${description}</a></li>" |
| } |
| |
| listKeyTable() { |
| local driver="${1}" |
| |
| local input="${inputFile##*/}" |
| local output="${outputFile%.*}" |
| local name="${output##*/}" |
| |
| local command=( "${keyTableLister}" -D"${buildRoot}/lib" -T"${sourceRoot}/${tablesSubdirectory}" ) |
| [ -n "${driver}" ] && command+=( -b "${driver}" ) |
| "${command[@]}" -l "${input}" >"${output}.${plainTextExtension}" || { |
| rm -f "${output}.${plainTextExtension}" |
| return 1 |
| } |
| |
| "${command[@]}" -r "${input}" >"${output}.${reStructuredTextExtension}" |
| sed -e "2a\\${newLine}* \`Help Screen Version <${name}.${plainTextExtension}>\`_" -i "${output}.${reStructuredTextExtension}" |
| |
| rst2html --config "${sourceRoot}/docutils.conf" "${output}.${reStructuredTextExtension}" "${output}.${hypertextExtension}" |
| "${keepFiles}" || rm "${output}.${reStructuredTextExtension}" |
| } |
| |
| listBrailleKeyTables() { |
| beginSection "Braille Device Key Bindings" |
| addDocLine "The driver automatically selects the appropriate key table for the device model being used." |
| addDocLine "Click on the driver's name for general information about it." |
| addDocLine "Click on the device model for its key bindings." |
| |
| local tocDrivers |
| beginTocEntries tocDrivers |
| |
| addDocLine "<dl>" |
| local driverDirectory |
| |
| for driverDirectory in "${driversDirectory}/"* |
| do |
| [ -d "${driverDirectory}" ] || continue |
| |
| local driverName="${driverDirectory##*/}" |
| local driverCode="$(sed -n '/^DRIVER_CODE *=/s/^.*= *\([^ ]*\).*$/\1/p' "${driverDirectory}/Makefile.in")" |
| |
| local header="${driverName}" |
| local inputFile="${driverDirectory}/README" |
| |
| [ ! -f "${inputFile}" ] || { |
| local outputFile="${outputRoot}/${braillePrefix}-${driverCode}.${plainTextExtension}" |
| cp -a -- "${inputFile}" "${outputFile}" |
| header="<a href=\"${outputFile##*/}\">${header}</a>" |
| } |
| |
| local anchor="${braillePrefix}-${driverCode}" |
| addTocEntry "${tocDrivers}" "${driverName}" "${anchor}" |
| |
| addDocLine "<dt>" |
| addAnchor "${anchor}" |
| addDocLine "${header}" |
| addDocLine "</dt><dd>" |
| |
| beginLayoutList |
| set -- "${tablesDirectory}/${brailleSubdirectory}/${driverCode}/"*".${keyTableExtension}" |
| |
| if [ "${#}" -gt 0 ] |
| then |
| for inputFile |
| do |
| beginLayoutEntry "${braillePrefix}-${driverCode}" "${hypertextExtension}" |
| listKeyTable "${driverCode}" || continue |
| endLayoutEntry "${driverName}" |
| done |
| else |
| set -- "${tablesDirectory}/${brailleSubdirectory}/${driverCode}/"*".${plainTextExtension}" |
| |
| for inputFile |
| do |
| beginLayoutEntry "${braillePrefix}-${driverCode}" "${plainTextExtension}" |
| cp -a -- "${inputFile}" "${outputFile}" |
| endLayoutEntry "${driverName}" |
| done |
| fi |
| |
| endLayoutList |
| addDocLine "</dd>" |
| done |
| |
| addDocLine "</dl>" |
| endTocEntries "${tocDrivers}" |
| endSection |
| } |
| |
| listKeyboardKeyTables() { |
| beginSection "Keyboard Key Tables" |
| addDocLine "In order to use one of these keyboard tables," |
| addDocLine "you need to explicitly specify it in one of the following ways:" |
| |
| addDocLine "<ul>" |
| addDocLine "<li>Use BRLTTY's <tt>-k</tt> (or <tt>--keyboard-table=</tt>) command line option.</li>" |
| addDocLine "<li>Use the <tt>keyboard-table</tt> configuration file (<tt>brltty.conf</tt>) directive.</li>" |
| addDocLine "</ul>" |
| |
| beginLayoutList |
| set -- "${tablesDirectory}/${keyboardSubdirectory}/"*".${keyTableExtension}" |
| |
| local inputFile |
| for inputFile |
| do |
| beginLayoutEntry "${keyboardPrefix}" "${hypertextExtension}" |
| listKeyTable || continue |
| endLayoutEntry |
| done |
| |
| endLayoutList |
| endSection |
| } |
| |
| driversSubdirectory="Drivers/Braille" |
| driversDirectory="${sourceRoot}/${driversSubdirectory}" |
| |
| tablesSubdirectory="Tables" |
| tablesDirectory="${sourceRoot}/${tablesSubdirectory}" |
| |
| brailleSubdirectory="Input" |
| keyboardSubdirectory="Keyboard" |
| |
| braillePrefix="brl" |
| keyboardPrefix="kbd" |
| |
| plainTextExtension="txt" |
| reStructuredTextExtension="rst" |
| hypertextExtension="html" |
| keyTableExtension="ktb" |
| |
| keyTableLister="${buildRoot}/Programs/brltty-ktb" |
| make -C "${keyTableLister%/*}" -s "${keyTableLister##*/}" |
| |
| documentTitle="Key Binding Lists" |
| beginDocument "${documentTitle}" |
| |
| beginSection "${documentTitle}" |
| listBrailleKeyTables |
| listKeyboardKeyTables |
| endSection |
| |
| endDocument "${outputRoot}/index.${hypertextExtension}" |
| exit 0 |