#!/bin/bash
#
# Copyright (C) 2012-2016 SUSE Linux GmbH
#
# Author:
# Frank Sundermeyer <fsundermeyer at opensuse dot org>
#
# Functions for ../bin/daps
#
#


###########################################################################
#
# ARGUMENT PARSER FOR ALL SUBCOMANDS
#
# Generic parser for the subcommand's command line switches. If a function
# introduces a new switch, it needs to be added here
#
###########################################################################
function parse_args {
    #
    # help is always handled within the function directly
    # everything else is parsed here

    # this functions only parses the getopts arguments and sets
    # variables accordingly.

    local SHORT_OPTS LONG_OPTS SUB_CMD
    SHORT_OPTS=$1
    LONG_OPTS=$2
    SUB_CMD=$3
    shift 3

    C_ARGS=$(getopt -s bash -o "$SHORT_OPTS" -l "$LONG_OPTS" -n "$0" -- "$@")
    if [[ 1 = "$?" ]]; then
        wrong_parameter "$SUB_CMD"
    fi

    eval set -- "$C_ARGS"

    while true ; do
        case "$1" in
            --check)
                P_CHECK=1
                shift
                ;;
            --clean)
                P_CLEAN=1
                shift
                ;;
            --color)
                P_COLOR=1
                shift
                ;;
            --compact)
                P_COMPACT=1
                shift
                ;;
            --cropmarks)
                P_CROPMARKS=1
                shift
                ;;
            --css)
                if [[ $2 != "none" ]]; then
                    sanitize_path "$2" "P_CSS"
                else
                    P_CSS="$2"
                fi
                shift 2
                ;;
            --draft)
                P_DRAFT=1
                shift
                ;;
            --def-file)
                P_DEF_FILE=""
                sanitize_path "$2" "P_DEF_FILE"
                shift 2
                ;;
            --desktopfiles)
                P_DESKTOPFILES=1
                shift
                ;;
            --db5todb4)
                P_DB5TODB4=1
                shift
                ;;
            --db5todb4nh)
                P_DB5TODB4NH=1
                shift
                ;;
            --dbnoconv)
                P_DBNOCONV=1
                shift
                ;;
            --documentfiles)
                P_DOCUMENTFILES=1
                shift
                ;;
            --epub3)
                P_EPUB3=1
                shift
                ;;
            --export-dir)
                P_EXPORT_DIR=""
                sanitize_path "$2" "P_EXPORT_DIR"
                shift 2
                ;;
            --extra-dict)
                P_ASPELL_EXTRA_DICT=""
                sanitize_path "$2" "P_ASPELL_EXTRA_DICT"
                shift 2
                ;;
            --file)
                P_FILE="$2"
                shift 2
                ;;
            --formatter)
                P_FORMATTER="$2"
                shift 2
                ;;
            --gen)
                P_IMAGES_GEN=1
                shift
                ;;
            --grayscale)
                P_GRAYSCALE=1
                shift
                ;;
            -h|--help)
                P_HELP=1
                shift
                ;;
            --html5)
                P_HTML5=1
                shift
                ;;
            --ignore-styleroot)
                P_TXT_IGNORE_STYLEROOT=1
                shift
                ;;
            --imgonly)
                P_LIST_IMG_ONLY=1
                shift
                ;;
            --jsp)
                P_JSP=1
                shift
                ;;
            --lang)
                P_LANG="$2"
                shift 2
                ;;
            --list)
                P_LIST=1
                shift
                ;;
            --locdrop)
                P_IS_LOCDROP=1
                shift
                ;;
            --meta)
                P_META=1
                shift
                ;;
            --modified)
                P_MODIFIED=1
                shift
                ;;
            --name)
                P_NAME="$2"
                shift 2
                ;;
            --nodc)
                P_LIST_NODC=1
                shift
                ;;
            --noent)
                P_LIST_NOENT=1
                shift
                ;;
            --noepub)
                P_NOEPUB=1
                shift
                ;;
            --nogzip)
                P_NOGZIP=1
                shift
                ;;
            --nohtml)
                P_NOHTML=1
                shift
                ;;
            --noimg)
                P_LIST_NOIMG=1
                shift
                ;;
            --nopdf)
                P_NOPDF=1
                shift
                ;;
            --nosearch)
                P_NOSEARCH=1
                shift
                ;;
            --noset)
                P_NOSET=1
                shift
                ;;
            --nostatic)
                P_NOSTATIC=1
                shift
                ;;
            --norefcheck)
                P_NOREFCHECK=1
                shift
                ;;
            --notrans-dir)
                P_NOTRANS_DIR=""
                sanitize_path "$2" "P_NOTRANS_DIR"
                shift 2
                ;;
            --novalid)
                P_NOVALID=1
                shift
                ;;
            --noxml)
                P_LIST_NOXML=1
                shift
                ;;
            --online)
                P_IMAGES_ONLINE=1
                shift
                ;;
            --optipng)
                P_OPTIPNG=1
                shift
                ;;
            --output-dir)
                P_OUTPUT_DIR=""
                sanitize_path "$2" "P_OUTPUT_DIR"
                shift 2
                ;;
            --pagefiles)
                P_PAGEFILES=1
                shift
                ;;
            --param)
                P_PARAMS="$P_PARAMS --param $2"
                shift 2
                ;;
            --pretty)
                P_PRETTY=1
                shift
                ;;
            --remarks)
                P_REMARKS=1
                shift
                ;;
            --rootid)
                P_ROOTID="$2"
                shift 2
                ;;
            --show)
                P_SHOW=1
                shift
                ;;
            --set-date)
                P_SETDATE="$2"
                shift 2
                ;;
            --single)
                P_HTMLSINGLE=1
                shift
                ;;
            --static)
                ccecho -- "warn" "--static is deprecated, since it is the default now."
                shift
                ;;
            --statdir)
                P_STATIC_DIR=""
                sanitize_path "$2" "P_STATIC_DIR"
                shift 2
                ;;
            --stringparam)
                P_STRINGPARAMS="$P_STRINGPARAMS --stringparam $2"
                shift 2
                ;;
            --subdirs)
                P_SUBDIRS=1
                shift
                ;;
            --target)
                P_TARGET="$2"
                shift 2
                ;;
            --trans-files)
                P_TRANS_FILES="$2"
                shift 2
                ;;
            --viewer)
                P_VIEWER="$2"
                shift 2
                ;;
            --xmlonly)
                P_LIST_XML_ONLY=1
                shift
                ;;
            --xsltparam)
                P_XSLTPARAM="$2"
                shift 2
                ;;
            --)
                shift
                break
                ;;
            *)
                wrong_parameter "$SUB_CMD"
                ;;
        esac
    done

    P_REMAIN_ARGS="$*"

}

###########################################################################
#
# INITIALIZE ENVIRONMENT
#
# Create needed directories and links
# Finally export some variables
#
###########################################################################
function init_env {
    # Create the log directory and a link to the DC-file in R_DIR
    # (R_DIR and LOG_DIR are set in bin/daps)

    local DC_COUNT TEST_ROOTID_RESULT

    # create directories

    mkdir -p "$R_DIR"
    if [[ 1 = "$WRITE_LOG" ]]; then
        mkdir -p "$LOG_DIR" || exit_on_error "Cannot create $LOG_DIR"
    fi


    if [[ -n $"$DOCCONF" && ! -f ${R_DIR}/$(basename "$DOCCONF") ]]; then
        ln -sf "$DOCCONF" "${R_DIR}/$(basename "$DOCCONF")"
        if [[ 0 != "$?" && 0 != "$VERBOSITY" ]]; then
            ccecho "warn" "Warning: Cannot create link to $DOCCONF in $R_DIR"
        fi
    fi

    # There should only be one DC-file in $R_DIR
    #
    DC_COUNT=$(find -L "$R_DIR" -maxdepth 1 -name "${CONF_PREFIX}*" -type f | wc -l 2>/dev/null)
    if [[ $DC_COUNT -gt 1 && 0 != "$VERBOSITY" ]]; then
        ccecho "warn" "$R_DIR contains more than one DC-file"
    fi

    # test if ROOTID exist
    #
    if [[ -n "$ROOTID" ]]; then
        EXISTS_ROOTID=$($XSLTPROC --stringparam "rootid=$ROOTID" --xinclude --stylesheet "${DAPSROOT}/daps-xslt/common/check_rootid.xsl" --file "$MAIN" "$XSLTPROCESSOR" 2>/dev/null)
        TEST_ROOTID_RESULT=$?
        if [[ 0 == "$TEST_ROOTID_RESULT"  && "yes" != "$EXISTS_ROOTID" ]]; then
            exit_on_error "Fatal: ROOTID \"$ROOTID\" does not exist."
        elif [[ 0 != $TEST_ROOTID_RESULT && 0 != $VERBOSITY ]]; then
            ccecho "warn" "Warning: Was not able to determine if ROOTID exists."
        fi
    fi

    #
    # The DocBook stylesheets require a 0|1 for REMARKS, but
    # yes|no for DRAFT
    # In order not to add to that confusion we will accept 0|1|yes|no for
    # all of them and export the correct value here. Since META falls
    # into a similar category, we also handle it the same way.
    # We also need to reset the _STR variables that get added to the resulting
    # filename here, when REMARKS, META or DRAFT has been disabled
    #
    # DRAFT must be set to yes|no
    case "$DRAFT" in
        1|yes)
            export DRAFT="yes" ;;
        0|no|"")
            export DRAFT="no" ;;
        *)
            exit_on_error "Wrong value for DRAFT. Must be \"yes\" or \"no\"" ;;
    esac

    # REMARKS must be set to 1|0
    # if enabled (set to 1) implies DRAFT mode
    case "$REMARKS" in
        1|yes)
            export REMARKS=1 DRAFT="yes" ;;
        0|no|"")
            export REMARKS=0 ;;
        *)
            exit_on_error "Invalid value for REMARKS. Must be \"yes\" or \"no\""
            ;;
        esac

    # META must be set to 1|0
    # if enabled (set to 1) implies DRAFT mode
    case "$META" in
        1|yes)
            export META=1 DRAFT="yes" ;;
        0|no|"")
            export META=0 ;;
        *)
            exit_on_error "Invalid value for META. Must be \"yes\" or \"no\""
            ;;
    esac

    # COLOR must be set to 1|0
    # if we are not in a terminal but rather in a pipe, script, etc.
    # disable color output otherwise use the value specified on the
    # command line or in the config
    if [[  -t 1 ]]; then
        case $COLOR in
            "1" | "yes")
                export COLOR=1 ;;
            "0" | "no" | "")
                COLOR=0 ;;
            *)
                exit_on_error "Invalid value for COLOR. Must be \"yes\" or \"no\""
                ;;
        esac
    else
        # No terminal
        COLOR=0
    fi

    # Unset the strings last, because values for DRAFT or REMARKS
    # may have been altered in-between
    [[ "no" = "$DRAFT" ]] && unset DRAFT_STR
    [[ 0 -eq $META ]] && unset META_STR
    [[ 0 -eq $REMARKS ]] && unset REMARK_STR

}

###########################################################################
#
# Get Stylesheet Version
#
###########################################################################

function get_stylesheet {
    #
    # takes an URN to VERSION.xsl as a required parameter

    local STYLE_FILE STYLE_URN STYLE_VERSION

    STYLE_URN=$1

    [[ -z $STYLE_URN ]] && exit_on_error "Function get_stylesheet must be called with an URN"

    # saxon6 (at least on openSUSE) does not properly resolve http Urls
    # (because it does not ask the catalog but rather directly accesses
    # the URl) we need to resolve it via xmlcatalog first
    #
    STYLE_FILE=$(xmlcatalog "$XML_MAIN_CATALOG" "$STYLE_URN")
    STYLE_FILE=${STYLE_FILE##*file://}
    STYLE_VERSION=$($XSLTPROC --stylesheet "$DAPSROOT/daps-xslt/common/get-dbxslt-version.xsl" --file "$STYLE_FILE" "$XSLTPROCESSOR" 2>/dev/null || echo "Not available")
        echo "$STYLE_VERSION"
}


###########################################################################
#
# RUN MAKE
#
# Set up log writing and verbosity
# and call make
#
###########################################################################
function call_make {
    local COLWIDTH CORE_NO DBSTYLE_FILE DBSTYLE_VERS FB_STYLESHEET_VERS
    local LOGFILE MAKE_BIN MAKE_OPTIONS MAKE_CMD PROFVAR STRING SILENT
    local STYLEROOT_VERS SUB_CMD V
    local -a PROFVARIABLES

    # first argument passed to the function is the subcommand

    # Second and optional argument is "silent" - if set all debug and
    # verbosity settings are ignored. This allows to run call_make to set
    # variables (e.g. FILELIST=$(call_make "list-srcfiles")

    # In some cases, additional arguments are passed to this
    # function - they remain in $@ and will be passed "as is" to make
    #
    SUB_CMD=$1
    shift

    if [[ "silent" = "$1" ]]; then
        SILENT="1"
        shift
    fi

    # Check the remaining $@ - if it contains variable definitions (FOO=BAR
    # or FOO="BAR") it's OK, if it contains barewords, exit with an error
    #
    if [[ -n "$@" ]]; then
    for STRING in "$@"; do
        [[ $STRING =~ ^[a-zA-Z][a-zA-Z0-9_]*=..* ]] || exit_on_error "Unknown parameter \"$STRING\"."
    done
    fi

    # set up the final environment
    init_env

    #------
    # the make command
    #

    MAKE_OPTIONS="-f $DAPSROOT/make/selector.mk"
    MAKE_BIN="/usr/bin/make"
    if [[ 1 != "$SILENT" ]]; then
        if [[ 1 = "$DEBUG" || 3 = "$VERBOSITY" ]]; then
            # use remake if installed when in debug or highest verbosity mode
            IS_REMAKE=$(which remake 2>/dev/null)
            [[ -n "$IS_REMAKE" ]] && MAKE_BIN="/usr/bin/remake"
            MAKE_OPTIONS="$MAKE_OPTIONS --debug=b"
        fi
    fi

    # By default the number of parallel jobs for make is set to the number of
    # CPU cores. This can be overwritten with --jobs.
    # If verbosity 3 (-v3) is set, "make -j1" is forced
    #
    if [[ 0 = "$VERBOSITY" || 1 = "$VERBOSITY" || 2 = "$VERBOSITY" ]]; then
        MAKE_OPTIONS="$MAKE_OPTIONS -j${JOBS}"
        [[ 1 != "$DEBUG" || 1 = "$SILENT" ]] && MAKE_OPTIONS="$MAKE_OPTIONS -s"
    else
        # highest verbosity level - use -j1 for a better readability
        MAKE_OPTIONS="$MAKE_OPTIONS -j1"
    fi

    # Is --force set to force a rebuild?
    [[ 1 = "$FORCE_REBUILD" ]] &&  MAKE_OPTIONS="$MAKE_OPTIONS --always-make"

    MAKE_CMD="$MAKE_BIN $MAKE_OPTIONS $SUB_CMD $*"


    # Variable settings summary printed on debug and high verbosity mode
    if [[ 2 -le $VERBOSITY && 1 != "$SILENT" ]]; then
    # list of profiling variables for the debug output
    #
        PROFVARIABLES=(
            PROFARCH
            PROFAUDIENCE
            PROFCONDITION
            PROFCONFORMANCE
            PROFLANG
            PROFOS
            PROFOUTPUTFORMAT
            PROFREVISION
            PROFREVISIONFLAG
            PROFROLE
            PROFSECURITY
            PROFSTATUS
            PROFUSERLEVEL
            PROFVENDOR
            PROFWORDSIZE )

        # column width debug output (for printf)
        COLWIDTH=20

        # get DocBook stylesheet version
        #
        DBSTYLE_VERS=$(get_stylesheet "http://docbook.sourceforge.net/release/xsl/current/VERSION.xsl")

        STYLEROOT_VERS=$(get_stylesheet "file://${STYLEROOT}/VERSION.xsl")
        FB_STYLEROOT_VERS=$(get_stylesheet "file://${FALLBACK_STYLEROOT}/VERSION.xsl")

        echo -e "---------------\n"
        # DAPS version
        printf "%${COLWIDTH}s: %s\n" "$MY_NAME VERSION" "$VERSION"

        echo

        # Directories
        for V in DOC_DIR BUILD_DIR DAPSROOT DOCCONF BOOK; do
            printf "%${COLWIDTH}s: %s\n" "$V" "${!V}"
        done

        echo

        # Profiling
        if [[ -z $PROFILE_URN ]]; then
            printf "%${COLWIDTH}s: %s\n" "PROFILING" "Off"
        else
            printf "%${COLWIDTH}s: %s\n" "PROFILING" "On"
            # show all profiling variables and their values
            for PROFVAR in ${PROFVARIABLES[*]}; do
                [[ -n ${!PROFVAR} ]] && printf "%${COLWIDTH}s: %s\n" "$PROFVAR" "${!PROFVAR}"
            done
        fi

        echo

        # DocBook
        for V in DOCBOOK_VERSION DOCBOOK5_RNG DBSTYLE_VERS; do
            printf "%${COLWIDTH}s: %s\n" "$V" "${!V}"
        done

        echo

        # Styleroot / Fallback styleroot
        if [[ $SUB_CMD =~ text && "yes" == "$TXT_IGNORE_STYLEROOT" || 1 = "$P_TXT_IGNORE_STYLEROOT" ]]; then
            printf "%${COLWIDTH}s: %s\n" "STYLEROOT" "$DOCBOOK_STYLES"
        else
            if [[ -n "$STYLEDEVEL" ]]; then
                printf "%${COLWIDTH}s: %s\n" "STYLEROOT" "$STYLEDEVEL"
            else
                if [[ -n "$STYLEROOT" ]]; then
                    printf "%${COLWIDTH}s: %s\n" "STYLEROOT" "$STYLEROOT"
                else
                   printf "%${COLWIDTH}s: %s\n" "STYLEROOT" "$DOCBOOK_STYLES"
                fi
            fi

            printf "%${COLWIDTH}s: %s\n" "STYLEROOT_VERS" "$STYLEROOT_VERS"

            if [[ -n "$FALLBACK_STYLEROOT" ]]; then
                printf "%${COLWIDTH}s: %s\n" "FALLBACK_STYLEROOT" "$FALLBACK_STYLEROOT"
            else
                # no fallback if STYLEROOT is not set
                if [[ -n "$STYLEROOT" ]]; then
                    printf "%${COLWIDTH}s: %s\n" "FALLBACK_STYLEROOT" "$DOCBOOK_STYLES"
                fi
            fi
            printf "%${COLWIDTH}s: %s\n" "FB_STYLEROOT_VERS" "$FB_STYLEROOT_VERS"
        fi

        # CSS
        printf "%${COLWIDTH}s: %s\n" "EPUB_CSS" "$EPUB_CSS"
        printf "%${COLWIDTH}s: %s\n" "HTML_CSS" "$HTML_CSS"

        echo

        # PDF
        printf "%${COLWIDTH}s: %s\n" "PDF FORMATTER" "$FORMATTER"
        if [[ "fop" = "$FORMATTER" ]]; then
            printf "%${COLWIDTH}s: %s\n" "FORMATTER WRAPPER" "$FOP_WRAPPER"
            printf "%${COLWIDTH}s: %s\n" "FORMATTER CONFIG" "$FOP_CONFIG_FILE"
        elif [[ "xep" = "$FORMATTER" ]]; then
            printf "%${COLWIDTH}s: %s\n" "FORMATTER WRAPPER" "$XEP_WRAPPER"
            printf "%${COLWIDTH}s: %s\n" "FORMATTER CONFIG:" "$XEP_CONFIG_FILE"
        fi

        echo

        # Misc
        for V in MAKE_CMD XSLTPROCESSOR XML_CATALOG_FILES; do
            printf "%${COLWIDTH}s: %s\n" "$V" "${!V}"
        done
        echo -e "\n---------------\n"
    fi

    if [[ 1 = "$WRITE_LOG" ]]; then
        LOGFILE="${LOG_DIR}/make_${SUB_CMD}.log"
        date &> "$LOGFILE"
    fi

    if [[ 0 != "$VERBOSITY" ]]; then
        if [[ 1 = "$WRITE_LOG" ]]; then
            $MAKE_CMD 2>&1 | tee -a "$LOGFILE"
            # see http://www.unix.com/shell-programming-scripting/92163-command-does-not-return-exit-status-due-tee.html
            [[ 0 = "${PIPESTATUS[0]}" ]] || exit 1
        else
            $MAKE_CMD 2>&1
        fi
    else
        if [[ 1 = "$WRITE_LOG" ]]; then
            $MAKE_CMD >> "$LOGFILE" 2>&1
            if [[ 0 = "$?" ]]; then
                # make command successful, only show last line (aka result)
                tail -n 1 "$LOGFILE"
            else
                # an error occured in make
                # show complete logfile except the first line containing the
                # date
                tail -n +2 "$LOGFILE"
                exit 1
            fi
        else
            $MAKE_CMD
        fi
    fi
}

##########################################################
#
# FUNCTION TEMPLATE
#
##########################################################
#    local SHORT_OPTS LONG_OPTS SUB_CMD

    # The subcommand value is passed when calling this function
#    SUB_CMD=$1
#    shift

    # SHORT_OPTS: Value for the getopt -o option
    # LONG_OPTS:  VALUE for the getopt -l option
#    SHORT_OPTS="h"
#    LONG_OPTS="draft,formatter:,help,name:,remarks,rootid:"

    # Call the argument parser
#    parse_args $SHORT_OPTS $LONG_OPTS $SUB_CMD "$@"

    # Reset this functions $@ to what is remaining after having parsed the
    # subcommand switches
#    eval set -- "$P_REMAIN_ARGS"

#    #------ Computing the values returned from the parser -----

#    <REPLACE ME>

#    call_make "$UB_CMD" "$@"


###########################################################################
#
# BUILD PDFS
#
# Subcommand: pdf
#
###########################################################################
function build_pdfs {
    local SHORT_OPTS LONG_OPTS SUB_CMD
    SUB_CMD=$1
    shift

    SHORT_OPTS="h"
    LONG_OPTS="cropmarks,draft,formatter:,help,grayscale,meta,name:,norefcheck,param:,remarks,rootid:,stringparam:,xsltparam:"

    parse_args "$SHORT_OPTS" "$LONG_OPTS" "$SUB_CMD" "$@"
    eval set -- "$P_REMAIN_ARGS"

    #------ Computing the values returned from the parser -----
    if [[ 1 = "$P_HELP" ]]; then
        help_scmd_head "$SUB_CMD" "${HELP_SUBCOMMAND[$SUB_CMD]}"
        help_cropmarks
        help_draft
        help_formatter
        help_grayscale_pdf
        help_help
        help_meta
        help_name
        help_norefcheck
        help_param
        help_remarks
        help_rootid
        help_stringparam
        help_xsltparam "creates the .fo file from the profiled sources"
        echo
        exit 0
    fi

    [[ 1 = "$P_DRAFT" ]]       && DRAFT="yes"
    [[ 1 = "$P_REMARKS" ]]     && REMARKS=1
    # usemeta implies draft mode
    [[ 1 = "$P_META" ]]        && META=1 DRAFT="yes"
    [[ 1 = "$P_CROPMARKS" ]]   && export CROPMARKS=1
    [[ 1 = "$P_GRAYSCALE" ]]   && export GRAYSCALE=1
    [[ 1 = "$P_NOREFCHECK" ]]  && export NOREFCHECK=1
    [[ -n "$P_NAME" ]]         && export PDFNAME="$P_NAME" BOOK="$P_NAME"
    [[ -n "$P_ROOTID" ]]       && export ROOTID="$P_ROOTID"
    [[ -n "$P_PARAMS" ]]       && export PARAMS="$P_PARAMS"
    [[ -n "$P_STRINGPARAMS" ]] && export STRINGPARAMS="$P_STRINGPARAMS"
    [[ -n "$P_XSLTPARAM" ]]    && export XSLTPARAM="$XSLTPARAM $P_XSLTPARAM"

    if [[ -n "$P_FORMATTER" ]]; then
        if [[ xep = "$P_FORMATTER" || fop = "$P_FORMATTER" ]]; then
            export FORMATTER="$P_FORMATTER"
        else
        exit_on_error "Wrong parameter for --formatter: must be \"xep\" or \"fop\"!"
        fi
    fi

    call_make "$SUB_CMD" "$@"
}


###########################################################################
#
# BUILD HTML and JSP
#
# Subcommands: html
#
###########################################################################
function build_html_jsp {
    local SHORT_OPTS LONG_OPTS SUB_CMD
    SUB_CMD=$1
    shift

    SHORT_OPTS="h"
    LONG_OPTS="clean,css:,draft,help,html5,jsp,name:,norefcheck,nostatic,meta,param:,remarks,rootid:,single,statdir:,static,stringparam:,xsltparam:"

    parse_args "$SHORT_OPTS" "$LONG_OPTS" "$SUB_CMD" "$@"
    eval set -- "$P_REMAIN_ARGS"

    #------ Computing the values returned from the parser -----
    if [[ 1 = "$P_HELP" ]]; then
        help_scmd_head "$SUB_CMD" "${HELP_SUBCOMMAND[$SUB_CMD]}"
        help_clean
        help_css
        help_draft
        help_help
        help_html5
        help_jsp
        help_meta
        help_name
        help_norefcheck
        help_nostatic
        help_param
        help_remarks
        help_rootid
        help_single
        help_statdir
        help_stringparam
        help_xsltparam "creates $SUB_CMD from the profiled sources"
        echo
        exit 0
    fi

    [[ 1 = "$P_CLEAN" ]]       && export CLEAN_DIR=1
    [[ -n "$P_CSS" ]]          && export HTML_CSS="$P_CSS"
    [[ 1 = "$P_DRAFT" ]]       && DRAFT="yes"
    [[ 1 = "$P_REMARKS" ]]     && REMARKS=1
    # usemeta implies draft mode
    [[ 1 = "$P_META" ]]        && META=1 DRAFT="yes"
    [[ 1 = "$P_NOSTATIC" ]]    && export STATIC_HTML=0
    [[ 1 = "$P_NOREFCHECK" ]]  && export NOREFCHECK=1
    [[ 1 = "$P_HTML5" ]]       && export HTML5=1
    [[ -n "$P_ROOTID" ]]       && export ROOTID="$P_ROOTID"
    [[ -n "$P_NAME" ]]         && export PDFNAME="$P_NAME" BOOK="$P_NAME"
    [[ -n "$P_STATIC_DIR" ]]   && export STATIC_DIR="$P_STATIC_DIR"
    [[ -n "$P_PARAMS" ]]       && export PARAMS="$P_PARAMS"
    [[ -n "$P_STRINGPARAMS" ]] && export STRINGPARAMS="$P_STRINGPARAMS"
    [[ -n "$P_XSLTPARAM" ]]    && export XSLTPARAM="$XSLTPARAM $P_XSLTPARAM"

    if [[ 1 = "$P_HTMLSINGLE" && 1 = "$P_JSP" ]]; then
    exit_on_error "--single and --jsp are mutually exclusive"
    else
    [[ 1 = "$P_HTMLSINGLE" ]] && export HTMLSINGLE=1
    [[ 1 = "$P_JSP" ]]        && export JSP=1
    fi

    call_make "$SUB_CMD" "$@"
}

###########################################################################
#
# WEBHELP
#
# Subcommands: webhelp
#
###########################################################################
function webhelp {
    local EXTENSION SHORT_OPTS LONG_OPTS SUB_CMD
    SUB_CMD=$1
    shift

    SHORT_OPTS="h"
    LONG_OPTS="clean,css:,draft,help,name:,norefcheck,nosearch,nostatic,param:,remarks,rootid:,static,stringparam:,xsltparam:"

    parse_args "$SHORT_OPTS" "$LONG_OPTS" "$SUB_CMD" "$@"
    eval set -- "$P_REMAIN_ARGS"

    #------ Computing the values returned from the parser -----
    if [[ 1 = "$P_HELP" ]]; then
        help_scmd_head "$SUB_CMD" "${HELP_SUBCOMMAND[$SUB_CMD]}"
        help_clean
        help_css
        help_draft
        help_help
        help_name
        help_norefcheck
        help_nosearch
        help_nostatic
        help_param
        help_remarks
        help_rootid
        help_stringparam
        help_xsltparam "creates Webhelp HTML from the profiled sources"
        echo
        exit 0
    fi

    for EXTENSION in $DOCBOOK_STYLES/extensions/webhelpindexer.jar \
    $DOCBOOK_STYLES/extensions/lucene-analyzers-*.jar \
    $DOCBOOK_STYLES/extensions/lucene-core-*.jar \
    $DOCBOOK_STYLES/extensions/tagsoup-*.jar; do
    if [[ ! -f $EXTENSION ]]; then
            exit_on_error "\nwebhelp only works when a recent snapshot of the DocBook stylesheets is\ninstalled. Your version of the DocBook styles at\n$DOCBOOK_STYLES\nis not webhelp capable."
    fi
    done

    [[ 1 = "$P_CLEAN" ]]       && export CLEAN_DIR=1
    [[ 1 = "$P_DRAFT" ]]       && DRAFT="yes"
    [[ 1 = "$P_REMARKS" ]]     && REMARKS=1
    [[ 1 = "$P_NOSTATIC" ]]    && export STATIC_HTML=0
    [[ 1 = "$P_NOSEARCH" ]]    && export WH_SEARCH="no"
    [[ 1 = "$P_NOREFCHECK" ]]  && export NOREFCHECK=1
    [[ -n "$P_ROOTID" ]]       && export ROOTID="$P_ROOTID"
    [[ -n "$P_NAME" ]]         && export PDFNAME="$P_NAME" BOOK="$P_NAME"
    [[ -n "$P_PARAMS" ]]       && export PARAMS="$P_PARAMS"
    [[ -n "$P_STRINGPARAMS" ]] && export STRINGPARAMS="$P_STRINGPARAMS"
    [[ -n "$P_XSLTPARAM" ]]    && export XSLTPARAM="$XSLTPARAM $P_XSLTPARAM"

    if [[ -n "$P_CSS" ]]; then
        if [[ $P_CSS = "none" || -f "$P_CSS" ]]; then
            export HTML_CSS="$P_CSS"
        else
            exit_on_error "Cannot find CSS file $P_CSS (have you specified a correct path?)."
        fi
    fi

    call_make "$SUB_CMD" "$@"
}

###########################################################################
#
# BUILD ePUB
#
# Subcommands: epub only
#
###########################################################################
function build_epub {
    local SHORT_OPTS LONG_OPTS SUB_CMD
    SUB_CMD=$1
    shift

    SHORT_OPTS="h"
    LONG_OPTS="check,css:,epub3,help,name:,norefcheck,param:,remarks,rootid:,statdir:,stringparam:"

    parse_args "$SHORT_OPTS" "$LONG_OPTS" "$SUB_CMD" "$@"
    eval set -- "$P_REMAIN_ARGS"

    #------ Computing the values returned from the parser -----
    if [[ 1 = "$P_HELP" ]]; then
        help_scmd_head "$SUB_CMD" "${HELP_SUBCOMMAND[$SUB_CMD]}"
        help_check
        help_css
        help_epub3
        help_help
        help_name
        help_norefcheck
        help_param
        help_rootid
        help_statdir
        help_stringparam
        echo
        exit 0
    fi

    [[ 1 = "$P_REMARKS" ]]  && REMARKS=1
    [[ 1 = "$P_EPUB3" ]]  && export EPUB3=1
    [[ 1 = "$P_NOREFCHECK" ]]  && export NOREFCHECK=1
    [[ -n "$P_NAME" ]]      && export PDFNAME="$P_NAME" BOOK="$P_NAME"
    [[ -n "$P_ROOTID" ]]    && export ROOTID="$P_ROOTID"
    [[ -n "$P_STATIC_DIR" ]] && export STATIC_DIR="$P_STATIC_DIR"

    # Checking the result requires a minimum verbosity level of 1
    if [[ 1 = "$P_CHECK" ]]; then
        [[ 0 = "$VERBOSITY" ]] && export VERBOSITY=1
        export RESULTCHECK=1
    fi

    if [[ -n "$P_CSS" ]]; then
        if [[ $P_CSS = "none" || -f "$P_CSS" ]]; then
            export EPUB_CSS="$P_CSS"
        else
            exit_on_error "Cannot find CSS file $P_CSS (have you specified a correct path?)."
        fi
    fi

    call_make "$SUB_CMD" "$@"
}

###########################################################################
#
# BUILD man pages
#
# Subcommands: man only
#
###########################################################################
function build_man {
    local SHORT_OPTS LONG_OPTS SUB_CMD
    SUB_CMD=$1
    shift

    SHORT_OPTS="h"
    LONG_OPTS="help,nogzip,norefcheck,param,rootid:,stringparam:,subdirs"

    parse_args "$SHORT_OPTS" "$LONG_OPTS" "$SUB_CMD" "$@"
    eval set -- "$P_REMAIN_ARGS"

    #------ Computing the values returned from the parser -----
    if [[ 1 = "$P_HELP" ]]; then
        help_scmd_head "$SUB_CMD" "${HELP_SUBCOMMAND[$SUB_CMD]}"
        help_help
        help_nogzip
        help_norefcheck
        help_param
        help_rootid
        help_stringparam
        help_subdirs
        echo
        exit 0
    fi

    [[ -n "$P_NOGZIP" ]]     && export GZIP_MAN="no"
    [[ -n "$P_NOREFCHECK" ]] && export NOREFCHECK="1"
    [[ -n "$P_ROOTID" ]]     && export ROOTID="$P_ROOTID"
    [[ -n "$P_SUBDIRS" ]]    && export MAN_SUBDIRS="yes"

    call_make "$SUB_CMD" "$@"
}
###########################################################################
#
# BUILD text files
#
# Subcommands: text only
#
###########################################################################
function build_text {
    local SHORT_OPTS LONG_OPTS SUB_CMD
    SUB_CMD=$1
    shift

    SHORT_OPTS="h"
    LONG_OPTS="ignore-styleroot,help,name:,norefcheck,param:,rootid:,stringparam:"

    parse_args "$SHORT_OPTS" "$LONG_OPTS" "$SUB_CMD" "$@"
    eval set -- "$P_REMAIN_ARGS"

    #------ Computing the values returned from the parser -----
    if [[ 1 = "$P_HELP" ]]; then
        help_scmd_head "$SUB_CMD" "${HELP_SUBCOMMAND[$SUB_CMD]}"
        help_ignore-styleroot
        help_help
        help_name
        help_norefcheck
        help_param
        help_rootid
        help_stringparam
        echo
        exit 0
    fi

    [[ 1 = "$P_TXT_IGNORE_STYLEROOT" ]] && export TXT_IGNORE_STYLEROOT="yes"
    [[ -n "$P_NAME" ]]         && export PDFNAME="$P_NAME" BOOK="$P_NAME"
    [[ -n "$P_NOREFCHECK" ]]   && export NOREFCHECK=1
    [[ -n "$P_ROOTID" ]]       && export ROOTID="$P_ROOTID"
    [[ -n "$P_STRINGPARAMS" ]] && export STRINGPARAMS="$P_STRINGPARAMS"
    [[ -n "$P_PARAMS" ]]       && export PARAMS="$P_PARAMS"
    [[ -n "$P_XSLTPARAM" ]]    && export XSLTPARAM="$XSLTPARAM $P_XSLTPARAM"

    call_make "$SUB_CMD" "$@"
}

###########################################################################
#
# Generic BUILD function
#
# Subcommands: all commands that does not fit elsewhere
#
###########################################################################
function build_generic {
    local SHORT_OPTS LONG_OPTS SUB_CMD
    SUB_CMD=$1
    shift

    SHORT_OPTS="h"
    LONG_OPTS="help,name:,norefcheck,param:,rootid:,stringparam:"

    parse_args "$SHORT_OPTS" "$LONG_OPTS" "$SUB_CMD" "$@"
    eval set -- "$P_REMAIN_ARGS"

    #------ Computing the values returned from the parser -----
    if [[ 1 = "$P_HELP" ]]; then
        help_scmd_head "$SUB_CMD" "${HELP_SUBCOMMAND[$SUB_CMD]}"
        help_help
        help_name
        help_norefcheck
        help_param
        help_rootid
        help_stringparam
        echo
        exit 0
    fi

    [[ -n "$P_NAME" ]]         && export PDFNAME="$P_NAME" BOOK="$P_NAME"
    [[ -n "$P_NOREFCHECK" ]]   && export NOREFCHECK=1
    [[ -n "$P_ROOTID" ]]       && export ROOTID="$P_ROOTID"
    [[ -n "$P_STRINGPARAMS" ]] && export STRINGPARAMS="$P_STRINGPARAMS"
    [[ -n "$P_PARAMS" ]]       && export PARAMS="$P_PARAMS"
    [[ -n "$P_XSLTPARAM" ]]    && export XSLTPARAM="$XSLTPARAM $P_XSLTPARAM"

    call_make "$SUB_CMD" "$@"
}

###########################################################################
#
# Bigfile
#
# Subcommand: bigfile
#
###########################################################################
function bigfile {
    local SHORT_OPTS LONG_OPTS SUB_CMD
    SUB_CMD=$1
    shift

    SHORT_OPTS="h"
    LONG_OPTS="help,name:,norefcheck,param:,rootid:,stringparam:,novalid"

    parse_args "$SHORT_OPTS" "$LONG_OPTS" "$SUB_CMD" "$@"
    eval set -- "$P_REMAIN_ARGS"

    #------ Computing the values returned from the parser -----
    if [[ 1 = "$P_HELP" ]]; then
        help_scmd_head "$SUB_CMD" "${HELP_SUBCOMMAND[$SUB_CMD]}"
        help_help
        help_name
        help_norefcheck
        help_param
        help_rootid
        help_stringparam
        help_novalid
        echo
        exit 0
    fi

    [[ -n "$P_NAME" ]]         && export PDFNAME="$P_NAME" BOOK="$P_NAME"
    [[ -n "$P_NOREFCHECK" ]]   && export NOREFCHECK=1
    [[ -n "$P_ROOTID" ]]       && export ROOTID="$P_ROOTID"
    [[ -n "$P_STRINGPARAMS" ]] && export STRINGPARAMS="$P_STRINGPARAMS"
    [[ -n "$P_PARAMS" ]]       && export PARAMS="$P_PARAMS"
    [[ -n "$P_XSLTPARAM" ]]    && export XSLTPARAM="$XSLTPARAM $P_XSLTPARAM"

    # If --novalid was called, a validation check is automatically
    # performed
    # Checking the result requires a minimum verbosity level of 1
    if [[ 1 = "$P_NOVALID" ]]; then
        [[ 0 = "$VERBOSITY" ]] && export VERBOSITY=1
        export NOVALID=1
    fi

    call_make "$SUB_CMD" "$@"
}

###########################################################################
#
# PACKAGING locdrop
#
# Subcommand: locdrop only
#
###########################################################################
function build_locdrop {
    local SHORT_OPTS LONG_OPTS SUB_CMD
    SUB_CMD=$1
    shift

    SHORT_OPTS="h"
    LONG_OPTS="def-file:,export-dir:,help,name:,nopdf,optipng,rootid:"

    parse_args "$SHORT_OPTS" "$LONG_OPTS" "$SUB_CMD" "$@"
    eval set -- "$P_REMAIN_ARGS"

    #------ Computing the values returned from the parser -----
    if [[ 1 = "$P_HELP" ]]; then
        help_scmd_head "$SUB_CMD" "${HELP_SUBCOMMAND[$SUB_CMD]}"
        help_def-file
        help_export-dir
        help_help
        help_name
        help_nopdf
        help_rootid
    help_optipng
        echo
        exit 0
    fi

    [[ -n "$P_NAME" ]]       && export PDFNAME="$P_NAME" BOOK="$P_NAME"
    [[ -n "$P_NOPDF" ]]      && export export NOPDF=1
    [[ -n "$P_ROOTID" ]]     && export ROOTID="$P_ROOTID"
    [[ -n "$P_EXPORT_DIR" ]] && export LOCDROP_EXPORT_DIR="$P_EXPORT_DIR"
    [[ 1 = "$P_OPTIPNG" ]]     && export OPTIPNG=1

    if [[ -f "$P_DEF_FILE" ]]; then
        export DEF_FILE="$P_DEF_FILE"
    elif [[ -z "$P_DEF_FILE" ]]; then
    [[ 0 != "$VERBOSITY" ]] && ccecho "warn" "Warning: No DEF file was specified"
    else
        exit_on_error "Cannot find DEF file \"$P_DEF_FILE\""
    fi
    call_make "profile" "$@" || exit_on_error "Profiling failed"
    call_make "$SUB_CMD" "$@"
}

###########################################################################
#
#  PACKAGING online-docs
#
#  Subcommands: online-docs online-localized
#
###########################################################################
function online-docs {
    local CONV_COUNT SHORT_OPTS LONG_OPTS SUB_CMD
    SUB_CMD=$1
    shift

    CONV_COUNT=0

    SHORT_OPTS="h"
    LONG_OPTS="db5todb4,db5todb4nh,dbnoconv,export-dir:,formatter:,help,name:,noepub,nohtml,nopdf,noset,rootid:,optipng"

    parse_args "$SHORT_OPTS" "$LONG_OPTS" "$SUB_CMD" "$@"
    eval set -- "$P_REMAIN_ARGS"

    #------ Computing the values returned from the parser -----
    if [[ 1 = "$P_HELP" ]]; then
        help_scmd_head "$SUB_CMD" "${HELP_SUBCOMMAND[$SUB_CMD]}"
        help_db5todb4
        help_db5todb4nh
        help_dbnoconv
        help_export-dir
        help_formatter
        help_help
        help_name
        help_noepub
        help_nohtml
        help_nopdf
        help_noset
        help_rootid
        help_optipng
        echo
        exit 0
    fi

    [[ -n "$P_NAME" ]]   && export PDFNAME="$P_NAME" BOOK="$P_NAME"
    [[ 1 = "$P_NOEPUB" ]]  && export NOEPUB=1
    [[ 1 = "$P_NOHTML" ]]  && export NOHTML=1
    [[ 1 = "$P_NOPDF" ]]   && export NOPDF=1
    [[ 1 = "$P_NOSET" ]]   && export NOSET=1
    [[ -n "$P_ROOTID" ]] && export ROOTID="$P_ROOTID"
    [[ 1 = "$P_OPTIPNG" ]] && export OPTIPNG=1

    if [[ 1 = "$P_NOHTML" ]]; then
        export NOHTML=1
    else
    # online-docs always builds a single HTML file
        export HTMLSINGLE=1
    fi

    if [[ -n "$P_EXPORT_DIR" ]]; then
        if [[ -d $P_EXPORT_DIR ]]; then
            export OD_EXPORT_DIR="$P_EXPORT_DIR"
        else
            exit_on_error "Export directory \"P_EXPORT_DIR\"\ndoes not exist. Please create it first."
        fi
    fi
    if [[ -n "$P_FORMATTER" ]]; then
        if [[ xep = "$P_FORMATTER" || fop = "$P_FORMATTER" ]]; then
            export FORMATTER="$P_FORMATTER"
        else
        exit_on_error "Wrong parameter for --formatter: must be \"xep\" or \"fop\"!"
        fi
    fi

    case 1 in
        $P_DB5TODB4)
            let CONV_COUNT++
            ;;
        $P_DB5TODB4NH)
            let CONV_COUNT++
            ;;
    esac

    [[ $CONV_COUNT -gt 1 ]] && exit_on_error "The options --db5todb4 and --db5todb4nh exclude each other"

    if [[ 4 = "$DOCBOOK_VERSION" ]]; then
       [[ 1 = "$P_DB5TODB4" || 1 = "$P_DB5TODB4NH" ]] && ccecho "warn" "No DocBook 5 source: --db5todb4/--db5todb4nh is ignored"
    fi

    [[ 1 = "$P_DBNOCONV" ]]    && export DBNOCONV=1
    [[ 1 = "$P_DB5TODB4" ]]    && export DB5TODB4=1
    [[ 1 = "$P_DB5TODB4NH" ]]  && export DB5TODB4NH=1


    call_make "$SUB_CMD" "$@"
}

###########################################################################
#
#  PACKAGING package-src
#
#  Subcommands: package-src only
#
###########################################################################
function package-src {
    local SHORT_OPTS LONG_OPTS SUB_CMD
    SUB_CMD=$1
    shift

    SHORT_OPTS="h"
    LONG_OPTS="def-file:,help,locdrop,name:,optipng,set-date:"

    parse_args "$SHORT_OPTS" "$LONG_OPTS" "$SUB_CMD" "$@"
    eval set -- "$P_REMAIN_ARGS"

    #------ Computing the values returned from the parser -----
    if [[ 1 = "$P_HELP" ]]; then
        help_scmd_head "$SUB_CMD" "${HELP_SUBCOMMAND[$SUB_CMD]}"
        help_def-file
        help_help
        help_locdrop
        help_name
        help_optipng
        help_set-date
        echo
        exit 0
    fi

    [[ 1 = "$P_IS_LOCDROP" ]] && export IS_LOCDROP=1
    [[ -n "$P_NAME" ]]      && export PDFNAME="$P_NAME" BOOK="$P_NAME"
    [[ 1 = "$P_OPTIPNG" ]]    && export OPTIPNG=1

    if [[ -n "$P_DEF_FILE" ]]; then
        if [[ -f $P_DEF_FILE ]]; then
            export DEF_FILE="$P_DEF_FILE"
        else
            exit_on_error "Cannot find DEF file \"$P_DEF_FILE\""
        fi
    else
        [[ 0 != "$VERBOSITY" ]] && ccecho "warn" "Warning: No DEF file was specified"
    fi

    if [[ -n "$P_SETDATE" ]]; then
        SETDATE=$(date -d "$P_SETDATE" +"%b %d %Y" 2>/dev/null) || exit_on_error "Wrong value for set-date: must be in a \"date\" compatible format,\ne.g. \"YYYY-MM-DD\"!"
        export SETDATE
    fi

    call_make "$SUB_CMD" "$@"
}

###########################################################################
#
#  PACKAGE PDF
#
#  Subcommand: package-pdf
#
###########################################################################
function package-pdf {
    local SHORT_OPTS LONG_OPTS SUB_CMD
    SUB_CMD=$1
    shift

    SHORT_OPTS="h"
    LONG_OPTS="cropmarks,desktopfiles,documentfiles,formatter:,grayscale,help,name:,pagefiles,param:,rootid:,set-date:,stringparam:,xsltparam:"

    parse_args "$SHORT_OPTS" "$LONG_OPTS" "$SUB_CMD" "$@"
    eval set -- "$P_REMAIN_ARGS"

    #------ Computing the values returned from the parser -----
    if [[ 1 = "$P_HELP" ]]; then
        help_scmd_head "$SUB_CMD" "${HELP_SUBCOMMAND[$SUB_CMD]}"
        help_cropmarks
        help_desktopfiles
        help_documentfiles
        help_formatter
        help_grayscale_pdf
        help_help
        help_name
        help_param
        help_pagefiles
        help_rootid
        help_set-date
        help_stringparam
        help_xsltparam "creates the .fo file from the profiled sources"
        echo
        exit 0
    fi

    [[ 1 = "$P_DESKTOPFILES" ]]  && export export DESKTOPFILES=1
    [[ 1 = "$P_DOCUMENTFILES" ]] && export export DOCUMENTFILES=1
    [[ 1 = "$P_PAGEFILES" ]]     && export export PAGEFILES=1
    [[ 1 = "$P_CROPMARKS" ]]     && export CROPMARKS=1
    [[ 1 = "$P_GRAYSCALE" ]]     && export GRAYSCALE=1
    [[ -n "$P_NAME" ]]         && export PDFNAME="$P_NAME" BOOK="$P_NAME"
    [[ -n "$P_ROOTID" ]]       && export ROOTID="$P_ROOTID"
    [[ -n "$P_PARAMS" ]]       && export PARAMS="$P_PARAMS"
    [[ -n "$P_STRINGPARAMS" ]] && export STRINGPARAMS="$P_STRINGPARAMS"
    [[ -n "$P_XSLTPARAM" ]]    && export XSLTPARAM="$XSLTPARAM $P_XSLTPARAM"

    if [[ -n "$P_FORMATTER" ]]; then
        if [[ xep = "$P_FORMATTER" || fop = "$P_FORMATTER" ]]; then
            export FORMATTER="$P_FORMATTER"
        else
        exit_on_error "Wrong parameter for --formatter: must be \"xep\" or \"fop\"!"
        fi
    fi

    if [[ -n "$P_SETDATE" ]]; then
        SETDATE=$(date -d "$P_SETDATE" +"%b %d %Y" 2>/dev/null) || exit_on_error "Wrong value for set-date: must be in a \"date\" compatible format,\ne.g. \"YYYY-MM-DD\"!"
        export SETDATE
    fi

    call_make "$SUB_CMD" "$@"
}



###########################################################################
#
#  Package HTML
#
#  Subcommand: package-html
#
###########################################################################
function package-html {
    local SHORT_OPTS LONG_OPTS SUB_CMD
    SUB_CMD=$1
    shift

    SHORT_OPTS="h"
    LONG_OPTS="css:,desktopfiles,documentfiles,help,html5,jsp,name:,pagefiles,param:,rootid:,set-date:,single,statdir:,stringparam:,xsltparam:"

    parse_args "$SHORT_OPTS" "$LONG_OPTS" "$SUB_CMD" "$@"
    eval set -- "$P_REMAIN_ARGS"

    #------ Computing the values returned from the parser -----
    if [[ 1 = "$P_HELP" ]]; then
        help_scmd_head "$SUB_CMD" "${HELP_SUBCOMMAND[$SUB_CMD]}"
        help_css
        help_desktopfiles
        help_documentfiles
        help_help
        help_html5
        help_jsp
        help_name
        help_pagefiles
        help_param
        help_rootid
        help_set-date
        help_single
        help_statdir
        help_stringparam
        help_xsltparam "creates the .html files from the profiled sources"
        echo
        exit 0
    fi


    [[ 1 = "$P_DESKTOPFILES" ]]  && export export DESKTOPFILES=1
    [[ 1 = "$P_DOCUMENTFILES" ]] && export export DOCUMENTFILES=1
    [[ 1 = "$P_PAGEFILES" ]]     && export export PAGEFILES=1
    [[ 1 = "$P_HTML5" ]]         && export HTML5=1
    [[ -n "$P_CSS" ]]          && export HTML_CSS="$P_CSS"
    [[ -n "$P_NAME" ]]         && export PDFNAME="$P_NAME" BOOK="$P_NAME"
    [[ -n "$P_ROOTID" ]]       && export ROOTID="$P_ROOTID"
    [[ -n "$P_STATIC_DIR" ]]   && export STATIC_DIR="$P_STATIC_DIR"
    [[ -n "$P_PARAMS" ]]       && export PARAMS="$P_PARAMS"
    [[ -n "$P_STRINGPARAMS" ]] && export STRINGPARAMS="$P_STRINGPARAMS"
    [[ -n "$P_XSLTPARAM" ]]    && export XSLTPARAM="$XSLTPARAM $P_XSLTPARAM"

    # We always want to start with a clean HTML result directory for
    # package-html
    #
    [[ "package-html" = "$SUB_CMD" ]] && export CLEAN_DIR=1

    if [[ 1 = "$P_HTMLSINGLE" && 1 = "$P_JSP" ]]; then
    exit_on_error "--single and --jsp are mutually exclusive"
    else
    [[ 1 = "$P_HTMLSINGLE" ]] && export HTMLSINGLE=1
    [[ 1 = "$P_JSP" ]]        && export JSP=1
    fi

    if [[ -n "$P_SETDATE" ]]; then
        SETDATE=$(date -d "$P_SETDATE" +"%b %d %Y" 2>/dev/null) || exit_on_error "Wrong value for set-date: must be in a \"date\" compatible format,\ne.g. \"YYYY-MM-DD\"!"
        export SETDATE
    fi

    call_make "$SUB_CMD" "$@"
}

###########################################################################
#
# PACKAGING unpack-locdrop
#
# Subcommand: unpack-locdrop only
#
# unpack a localization drop packages source.
# Files listed in manifest_trans.txt will be extracted from the given tarball
# Files listed in manifest_notrans will be linked/copied from the notrans
# directory specified with --notrans-dir
#
###########################################################################
function unpack-locdrop {
    local SHORT_OPTS LONG_OPTS SUB_CMD
    local ALL_TRANS_FILES ALL_NOTRANS_FILES DCFILE_LIST ENTITIES LINK_NOTRANS_FILES MANIFEST_TRANS MANIFEST_NOTRANS MFT_TRANS_SUFF MFT_NOTRANS_SUFF NO_DCFILE_LIST NO_EXIFTOOL NO_OPTIPNG XML_FILE_LIST
    local -a ALL_MANIFEST_NOTRANS_FILES ALL_MANIFEST_TRANS_FILES

    MFT_TRANS_SUFF=manifest_trans.txt
    MFT_NOTRANS_SUFF=manifest_notrans.txt

    SUB_CMD=$1
    shift

    SHORT_OPTS="h"
    LONG_OPTS="help,notrans-dir:,optipng,output-dir:,trans-files:"

    parse_args "$SHORT_OPTS" "$LONG_OPTS" "$SUB_CMD" "$@"
    eval set -- "$P_REMAIN_ARGS"

    #------ Computing the values returned from the parser -----
    if [[ 1 = "$P_HELP" ]]; then
        help_scmd_head "$SUB_CMD" "${HELP_SUBCOMMAND[$SUB_CMD]}"
        help_trans-files
        help_help
        help_notrans-dir
        help_optipng
        help_output-dir
        echo
        exit 0
    fi

    if [[ -z "$P_TRANS_FILES" ]]; then
    exit_on_error "Fatal: Specifying one or more locdrop tarballs with --trans-files is mandatory."
    fi

    if [[ -z "$P_NOTRANS_DIR" ]]; then
    ccecho "warn" "No notrans-dir was specified. Assuming DC-file directory"
    P_NOTRANS_DIR="$MY_BASEDIR"
    fi

    [[ -z "$P_OUTPUT_DIR" ]] && exit_on_error "Fatal: Specifying an output directory\nwith  --output-dir is mandatory."

    #
    # Extract translated files
    #
    for TAR in $P_TRANS_FILES; do
    if [[ -f $TAR ]]; then
        pushd "$P_OUTPUT_DIR" > /dev/null
        MANIFEST_TRANS=$(tar tfj "$TAR" | grep "$MFT_TRANS_SUFF" 2>/dev/null) || exit_on_error "Could not get manifest of translated files"
        ALL_MANIFEST_TRANS_FILES=( "${ALL_MANIFEST_TRANS_FILES[@]}" "$MANIFEST_TRANS" )
        MANIFEST_NOTRANS=$(tar tfj "$TAR" | grep "$MFT_NOTRANS_SUFF" 2>/dev/null) || exit_on_error "Could not get manifest of non-translated files"
        ALL_MANIFEST_NOTRANS_FILES=( "${ALL_MANIFEST_NOTRANS_FILES[@]}" "$MANIFEST_NOTRANS" )
        tar xfj "$TAR" "$MANIFEST_TRANS" "$MANIFEST_NOTRANS" 2>/dev/null || exit_on_error "Could not extract manifest files from tarball"
        tar xfj "$TAR" $(cat "$MANIFEST_TRANS") 2>/dev/null || exit_on_error "Could not extract manifest files from tarball"
        popd >/dev/null
    else
        exit_on_error "Fatal: $TAR does not exist"
    fi
    done

    pushd "$P_OUTPUT_DIR" > /dev/null

    #
    # Run optipng on images/src/png if --optipng was specified
    #
    which optipng >/dev/null 2>&1 || NO_OPTIPNG="1"
    which exiftool >/dev/null 2>&1 || NO_EXIFTOOL="1"

    if [[ -z $NO_OPTIPNG && -z $NO_EXIFTOOL ]]; then
        if [[ -d images/src/png && 1 -eq $P_OPTIPNG ]]; then
            local j=0
            for IMG in images/src/png/*.png; do
                if [[ -z "$(exiftool -Comment $IMG | grep optipng)" ]]; then
                    let "j += 1"
                    optipng -o2 $IMG >/dev/null 2>&1
                    exiftool -Comment=optipng -overwrite_original -P $IMG >/dev/null
                fi
            done
            if [[ 0 -eq $j ]]; then \
                ccecho "result" "No PNG images needed optimization"
            else
                ccecho "result" "$j PNG images have been optimized."
            fi
        fi
    else
        [[ -n $NO_OPTIPNG ]] && ccecho "error" "Error: Cannot find optipng!"
        [[ -n $NO_EXIFTOOL ]] && ccecho "error" "Error: Cannot find exiftool!"
    fi

    #
    # Now create a complete list of translated/untranslated files
    #
    ALL_TRANS_FILES=$(cat "${ALL_MANIFEST_TRANS_FILES[@]}" | sort -u)
    ALL_NOTRANS_FILES=$(cat "${ALL_MANIFEST_NOTRANS_FILES[@]}" | sort -u)

    # get all files unique to the notrans lists (the ones that have not
    # been translated)
    LINK_NOTRANS_FILES=$(comm -1 -3 <(echo -e "$ALL_TRANS_FILES") <(echo -e "$ALL_NOTRANS_FILES") 2>/dev/null) || exit_on_error "Could not get list of files that have not been translated"

    # Process LINK_NOTRANS_FILES to get the file lists we need
    #  the awk statements matches multiple occurrences on a single line
    #
    DCFILE_LIST=$(awk '{for(i=1;i<=NF;++i)if($i~/DC-[^ ]*/)print $i}' <(echo "$LINK_NOTRANS_FILES") 2>/dev/null) || exit_on_error "Could not get list of DC files"
    NO_DCFILE_LIST=$(awk '{for(i=1;i<=NF;++i)if($i !~ /DC-[^ ]*/)print $i}' <(echo "$LINK_NOTRANS_FILES") 2>/dev/null) || exit_on_error "Could not get list of images that have not been 'translated'"
    XML_FILE_LIST=$(awk -v path="${P_NOTRANS_DIR}/" '{for(i=1;i<=NF;++i)if($i~/xml\/.*\.xml/)print path $i}' <(echo "$LINK_NOTRANS_FILES") 2>/dev/null) || exit_on_error "Could not get list of files that have been translated"

    # Copy remaining DC-files
    #
    for DC in $DCFILE_LIST; do
    if [[ -f ${P_NOTRANS_DIR}/$DC ]]; then
        cp "${P_NOTRANS_DIR}/$DC" .
    else
        ccecho "warn" "File does not exist: ${P_NOTRANS_DIR}/$DC"
    fi
    done

    # Link not translated images and XML files
    #
    for DATA in $NO_DCFILE_LIST; do
    if [[ -f ${P_NOTRANS_DIR}/$DATA ]]; then
        DIR="$(dirname "$DATA")"
        if [[ "." == "$DIR" ]]; then
        ln -sf "${P_NOTRANS_DIR}/$DATA"
        else
        [[ -d "$DIR" ]] || mkdir -p "$DIR"
        # the realpath statement makes sure a realtive path is used
                # for the link (also see
                # https://stackoverflow.com/questions/2564634)
        (cd "$DIR" && ln -sf "$(realpath --relative-to="." "${P_NOTRANS_DIR}/$DATA")")
        fi
    else
        ccecho "warn" "File does not exist: ${P_NOTRANS_DIR}/$DATA"
    fi
    done


    # Get entity files from the notrans sources and link to them
    #
    ENTITIES="$("${LIBEXEC_DIR}/getentityname.py" $XML_FILE_LIST)"
    for ENT in $ENTITIES; do
    if [[ -f ${P_NOTRANS_DIR}/xml/$ENT ]]; then
        (cd xml && ln -sf "$(realpath --relative-to="." "${P_NOTRANS_DIR}/xml/$ENT")")
    else
        ccecho "warn" "Cannot find entity file: ${P_NOTRANS_DIR}/xml/$ENT"
    fi
    done

    popd >/dev/null

    ccecho "result" "Successfully created files in\n$P_OUTPUT_DIR"
    exit 0
}


###########################################################################
#
#  PROFILE First
#
#  Some subcommands (such as projectgraphics and various dist and packaging
#  targets) require an up-tp-date .profiled/*
#  Therefore we call make profile first and then call make a second time
#  with the real target
#
###########################################################################
function profile_first {
    local SHORT_OPTS LONG_OPTS SUB_CMD
    SUB_CMD=$1
    shift

    SHORT_OPTS="h"
    LONG_OPTS="draft,help,name:,remarks,rootid:"

    parse_args "$SHORT_OPTS" "$LONG_OPTS" "$SUB_CMD" "$@"
    eval set -- "$P_REMAIN_ARGS"

    #------ Computing the values returned from the parser -----
    if [[ 1 = "$P_HELP" ]]; then
        help_scmd_head "$SUB_CMD" "${HELP_SUBCOMMAND[$SUB_CMD]}"
        help_draft
        help_name
        help_remarks
        help_rootid
        echo
        exit 0
    fi

    [[ 1 = "$P_DRAFT" ]]    && DRAFT="yes"
    [[ 1 = "$P_REMARKS" ]]  && REMARKS=1
    [[ -n "$P_NAME" ]]      && export PDFNAME="$P_NAME" BOOK="$P_NAME"
    [[ -n "$P_ROOTID" ]]    && export ROOTID="$P_ROOTID"

    # we do not want to write a logfile this time
    WRITE_LOG=0
    call_make "profile" "$@" || exit_on_error "Profiling failed"
    call_make "$SUB_CMD" "$@"
}

###########################################################################
#
#  REMARKS
#
#  Subcommands validate and profiledir behave differently when
#  comments or remarks are enabled
#
###########################################################################
function comments_remarks {
    local SHORT_OPTS LONG_OPTS SUB_CMD
    SUB_CMD=$1
    shift

    SHORT_OPTS="h"
    LONG_OPTS="help,norefcheck,remarks"

    parse_args "$SHORT_OPTS" "$LONG_OPTS" "$SUB_CMD" "$@"
    eval set -- "$P_REMAIN_ARGS"

    #------ Computing the values returned from the parser -----
    if [[ 1 = "$P_HELP" ]]; then
        help_scmd_head "$SUB_CMD" "${HELP_SUBCOMMAND[$SUB_CMD]}"
        help_norefcheck
        help_remarks
        echo
        exit 0
    fi

    [[ 1 = "$P_REMARKS" ]]     && REMARKS=1
    [[ 1 = "$P_NOREFCHECK" ]]  && NOREFCHECK=1

    # we do not want to write a logfile this time
    WRITE_LOG=0
    call_make "$SUB_CMD" "$@"

}

###########################################################################
#
#  FILELISTS
#
#  Subcommands: list-files, list-srcfiles*, list-images-*
#
###########################################################################
function filelists {
    local SHORT_OPTS LONG_OPTS SUB_CMD
    SUB_CMD=$1
    shift

    SHORT_OPTS="h"
    LONG_OPTS="help,imgonly,nodc,noent,noimg,noxml,pretty,rootid:,xmlonly"

    parse_args "$SHORT_OPTS" "$LONG_OPTS" "$SUB_CMD" "$@"
    eval set -- "$P_REMAIN_ARGS"

    #------ Computing the values returned from the parser -----
    if [[ 1 = "$P_HELP" ]]; then
        help_scmd_head "$SUB_CMD" "${HELP_SUBCOMMAND[$SUB_CMD]}"
        help_help
        if [[ $SUB_CMD =~ list-srcfiles ]]; then
            help_imgonly
            help_nodc
            help_noent
            help_noimg
            help_noxml
            help_xmlonly
        fi
        [[ $SUB_CMD != list-file ]] && help_pretty
        help_rootid
        echo
        exit 0
    fi
    [[ 1 = "$P_LIST_NODC" ]]  && export LIST_NODC=1
    [[ 1 = "$P_LIST_NOENT" ]] && export LIST_NOENT=1
    [[ 1 = "$P_LIST_NOIMG" ]] && export LIST_NOIMG=1
    [[ 1 = "$P_LIST_NOXML" ]] && export LIST_NOXML=1
    [[ 1 = "$P_PRETTY" ]]     && export PRETTY_FILELIST=1
    [[ -n "$P_ROOTID" ]]    && export ROOTID="$P_ROOTID"

    # --imgonly and --xmlonly are shortcuts
    #
    if [[ 1 = "$P_LIST_IMG_ONLY" ]]; then
        export LIST_NODC=1 LIST_NOENT=1 LIST_NOXML=1
    elif [[ 1 = "$P_LIST_XML_ONLY" ]]; then
        export LIST_NODC=1 LIST_NOENT=1 LIST_NOIMG=1
    fi

    if [[ $SUB_CMD = list-file && -z $ROOTID ]]; then
    exit_on_error "You need to specify an ID with --rootid with the list-file command."
    fi

    # we do not want to write a logfile this time
    WRITE_LOG=0
    call_make "$SUB_CMD" "$@"
}

###########################################################################
#
#  SHOW NAMES
#
#  function for all targets showing a filename or a directory
#  (pdf-name, htmlsingle-name, etc.)
#
###########################################################################

function show_names {
    local SHORT_OPTS LONG_OPTS SUB_CMD
    SUB_CMD=$1
    shift

    SHORT_OPTS="h"
    LONG_OPTS="cropmarks,draft,formatter:,grayscale,help,jsp,meta,name:,remarks,rootid:,single"

    parse_args "$SHORT_OPTS" "$LONG_OPTS" "$SUB_CMD" "$@"
    eval set -- "$P_REMAIN_ARGS"

    #------ Computing the values returned from the parser -----
    if [[ 1 = "$P_HELP" ]]; then
                help_scmd_head "$SUB_CMD" "${HELP_SUBCOMMAND[$SUB_CMD]}"
                [[ "pdf-name" = "$SUB_CMD" ]] && help_cropmarks
                help_draft
                [[ "pdf-name" = "$SUB_CMD" ]] && help_formatter
                [[ "pdf-name" = "$SUB_CMD" ]] && help_grayscale_pdf
                help_help
                [[ "jsp-dir-name" =  "$SUB_CMD" ]] && help_jsp
                help_meta
                help_name
                help_remarks
                help_rootid
                [[ "html-dir-name" = "$SUB_CMD" ]] && help_single
                echo
                exit 0
    fi

    [[ 1 = "$P_DRAFT" ]]      && DRAFT="yes"
    [[ 1 = "$P_REMARKS" ]]    && REMARKS=1
    # usemeta implies draft mode
    [[ 1 = "$P_META" ]]       && META=1 DRAFT="yes"
    [[ 1 = "$P_CROPMARKS" ]]  && export CROPMARKS=1
    [[ 1 = "$P_GRAYSCALE" ]]  && export GRAYSCALE=1
    [[ -n "$P_ROOTID" ]]      && export ROOTID="$P_ROOTID"
    [[ -n "$P_NAME" ]]        && export PDFNAME="$P_NAME" BOOK="$P_NAME"

    if [[ 1 = "$P_HTMLSINGLE" && 1 = "$P_JSP" ]]; then
    exit_on_error "--single and --jsp are mutually exclusive"
    else
    [[ 1 = "$P_HTMLSINGLE" ]] && export HTMLSINGLE=1
    [[ 1 = "$P_JSP" ]]        && export JSP=1
    fi

    if [[ -n "$P_FORMATTER" ]]; then
        if [[ xep = "$P_FORMATTER" || fop = "$P_FORMATTER" ]]; then
            export FORMATTER="$P_FORMATTER"
        else
        exit_on_error "Wrong parameter for --formatter: must be \"xep\" or \"fop\"!"
        fi
    fi

    # we do not want to write a logfile this time
    WRITE_LOG=0
    call_make "$SUB_CMD" "$@"
}

###########################################################################
#
#  CHECKLINK
#
#  checks http links in file or from rootid
#
###########################################################################

function checklink {
    local SHORT_OPTS LONG_OPTS SUB_CMD

    SUB_CMD=$1
    shift

    SHORT_OPTS="h"
    LONG_OPTS="file:,help,rootid:,show"

    parse_args "$SHORT_OPTS" "$LONG_OPTS" "$SUB_CMD" "$@"
    eval set -- "$P_REMAIN_ARGS"

    #------ Computing the values returned from the parser -----
    if [[ 1 = "$P_HELP" ]]; then
        help_scmd_head "$SUB_CMD" "${HELP_SUBCOMMAND[$SUB_CMD]}"
        help_file
        help_help
        help_rootid
        help_show_check
        cat <<EOF
   NOTES: * Options --file (-f) and --rootid exclude one another.
           * If neither file nor rootid is specified, the rootid
             from the DC-file is used
           * $SUB_CMD follows xi:includes
EOF
    exit 0
    fi

    if [[ -z "$P_ROOTID" && -z "$P_FILE" ]]; then
        if [[ 0 != $VERBOSITY ]]; then
            ccecho "info" "Neither file nor rootid specified, using rootid from DC-file"
        fi
    elif [[ -n "$P_ROOTID" && -n "$P_FILE" ]]; then
        exit_on_error "Options --file (-f) and --rootid exclude one another.\nPlease specify only one of these options"
    fi

    [[ -n "$P_ROOTID" ]]    && export ROOTID="$P_ROOTID"
    [[ -n "$P_SHOW" ]]      && export SHOW=1

    if [[ -n "$P_FILE" ]]; then
        if [[ -f $P_FILE ]]; then
            ROOTID=$($XSLTPROC --stylesheet "$DAPSROOT/daps-xslt/common/get-rootelement-id.xsl" --file "$P_FILE" "$XSLTPROCESSOR") || exit_on_error "Cannot get a rootid from file $FILE"
            export ROOTID
        else
            exit_on_error "File $P_FILE does not exist"
        fi
    fi

    call_make "$SUB_CMD" "$@"
}

###########################################################################
#
#  GETIMAGES
#
#  Gets a list of images from the file specified with -f or --file or
#  the document specified by rootid  and outputs them as:
#   * default:       long list (one file per line)
#   * --compact:  compact list (single line)
#   * --viewer=VIEWER: shows images in VIEWER and prints long list to STDOUT
#
#  the additional option (--modified) will also print the image file's
#  mtime in long lists (this option is ignored with --compact)
#
###########################################################################
function getimages {
    local SHORT_OPTS LONG_OPTS SUB_CMD
    local COMPACT FILE MOD P_FILE SHOW
    local -a IMGLIST

    SUB_CMD=$1
    shift

    # any kind of verbosity is unwanted in this case
    WRITE_LOG=0
    DEBUG=0
    VERBOSITY=0

    SHORT_OPTS="h"
    LONG_OPTS="compact,file:,help,modified,rootid:,show,viewer:"

    parse_args "$SHORT_OPTS" "$LONG_OPTS" "$SUB_CMD" "$@"
    eval set -- "$P_REMAIN_ARGS"

    #------ Computing the values returned from the parser -----
    if [[ 1 = "$P_HELP" ]]; then
        help_scmd_head "$SUB_CMD" "${HELP_SUBCOMMAND[$SUB_CMD]}"
        help_compact
        help_file
        help_modified
        help_rootid
        help_show_images
        help_viewer
        echo -e "    NOTES: * Options --file (-f) and --rootid exclude one another.\n           * If neither file nor rootid is specified, the rootid\n             from the DC-file is used\n           * $SUB_CMD follows xi:includes\n"
    exit 0
    fi

    [[ 1 = "$P_COMPACT" ]]  && COMPACT=1
    [[ 1 = "$P_MODIFIED" ]] && MOD=1
    [[ 1 = "$P_SHOW" ]]     && SHOW=1
    [[ -n "$P_VIEWER" ]]    && IMG_VIEWER="$P_VIEWER"

    # set ROOTID - either directly or via $FILE
    if [[ -z "$P_ROOTID" && -z "$P_FILE" ]]; then
        if [[ 0 != $VERBOSITY ]]; then
            ccecho "info" "Neither file nor rootid specified, using rootid from DC-file"
        fi
    elif [[ -n "$P_ROOTID" && -n "$P_FILE" ]]; then
        exit_on_error "Options --file (-f) and --rootid exclude one another.\nPlease specify only one of these options"
    fi

    [[ -n "$P_ROOTID" ]]    && export ROOTID="$P_ROOTID"

    if [[ -n $P_FILE ]]; then
        if [[ -f $P_FILE ]]; then
            ROOTID=$($XSLTPROC --stylesheet "$DAPSROOT/daps-xslt/common/get-rootelement-id.xsl" --file "$P_FILE" "$XSLTPROCESSOR" 2>/dev/null) || exit_on_error "Cannot get a rootid from file $FILE"
            export ROOTID
        else
            exit_on_error "File $P_FILE does not exist"
        fi
    fi

    # IMG_VIEWER may also be set via config file:
    if [[ $SHOW ]]; then
        if [[ -z "$IMG_VIEWER" ]]; then
            exit_on_error "Please specify an image viewer via command-line (--viewer) or via config file"
        else
            IMG_VIEWER=$(which "$IMG_VIEWER" 2>/dev/null)
            if [[ 0 -lt $? ]]; then # which command failed
                # Viewer was specified on command-line
                if [[ $P_VIEWER ]]; then
                    exit_on_error "Cannot find VIEWER $CMD_IMG_VIEWER"
                # Viewer was specified via config
                else
                    exit_on_error "Cannot find VIEWER $IMG_VIEWER. Please check your config file"
                fi
            fi
        fi
    fi

    # get the image list
    # we can use projectgraphics, since it returns images for a given rootid
    IMGLIST=( $(call_make list-srcfiles silent LIST_NODC=1 LIST_NOENT=1 LIST_NOXML=1) )
    if [[ 0 != $? ]]; then
        exit_on_error "Failed to get list of images"
    fi

    if [[ 0 -lt ${#IMGLIST[@]} ]]; then
        if [[ $COMPACT ]]; then
            echo -e "${IMGLIST[*]}\n"
        else
            for IMAGE in "${IMGLIST[@]}"; do
                if [[ $MOD ]]; then
                MODIFIED=$(stat -c %y "$IMAGE" | cut -d '.' -f1 2>/dev/null)
                echo "${IMAGE} (${MODIFIED})"
                else
                echo "${IMAGE}"
                fi
            done  | column -t
            if [[ $SHOW ]]; then
                $IMG_VIEWER "${IMGLIST[@]}" &
            fi
        fi
    fi
    exit
}

###########################################################################
#
#  SPELLCHECK
#
#  Spellchecks a file specified with -f or --file or
#  the document specified by rootid.
#
###########################################################################
function spellcheck {
    local SHORT_OPTS LONG_OPTS SUB_CMD
    local COUNT FILE LISTMODE LISTOUTPUT SPELLCMD
    local -a FILELIST SKIPLIST

    SUB_CMD=$1
    shift

    SHORT_OPTS="h"
    LONG_OPTS="extra-dict:,file:,help,lang:,list,rootid:"

    parse_args "$SHORT_OPTS" "$LONG_OPTS" "$SUB_CMD" "$@"
    eval set -- "$P_REMAIN_ARGS"

    #------ Computing the values returned from the parser -----
    if [[ 1 = "$P_HELP" ]]; then
        help_scmd_head "$SUB_CMD" "${HELP_SUBCOMMAND[$SUB_CMD]}"
        help_extra-dict
        help_file
        help_help
        help_lang
        help_list
        help_rootid
        echo -e "    NOTES: * Options --file (-f) and --rootid exclude one another.\n           * If neither file nor rootid is specified, the rootid\n             from the DC-file is used\n           * $SUB_CMD follows xi:includes\n"
    exit 0
    fi

    [[ -n "$P_ASPELL_EXTRA_DICT" ]] && ASPELL_EXTRA_DICT="$P_ASPELL_EXTRA_DICT"
    [[ -n "$P_FILE" ]] && FILELIST[0]="$P_FILE"
    [[ 1 = "$P_LIST" ]] && LISTMODE=1

    # set FILELIST if rootid was specified
    if [[ -z "$P_ROOTID" && -z "$P_FILE" ]]; then
        if [[ 0 != $VERBOSITY ]]; then
            ccecho "info" "Neither file nor rootid specified, using rootid from DC-file"
        fi
    elif [[ -n "$P_ROOTID" && -n "$P_FILE" ]]; then
        exit_on_error "Options --file and --rootid exclude one another.\nPlease specify only one of these options"
    fi

    [[ -n "$P_ROOTID" ]] && export ROOTID="$P_ROOTID"

    if [[ -z "${FILELIST[0]}" ]]; then ## --file was not specified
        FILELIST=( $(call_make list-srcfiles silent LIST_NODC=1 LIST_NOENT=1 LIST_NOIMG=1 ) )
        if [[ 0 != $? ]]; then
            exit_on_error "Failed to get filelist for ROOTID \"$ROOTID\""
        fi
    fi

    # Set language - if not specified anywhere try to get from $MAIN
    #
    if [[ -n "$P_LANG" ]]; then
        ASPELL_LANG="$P_LANG"
    else
        if [[ -z "$ASPELL_LANG" ]]; then
            ASPELL_LANG=$($XSLTPROC --stylesheet "${DAPSROOT}/daps-xslt/common/get-language.xsl" --file "$MAIN" "$XSLTPROCESSOR" 2>/dev/null)
            if [[ -n "$ASPELL_LANG" ]]; then
        ccecho "info" "Using language $ASPELL_LANG."
            else
        exit_on_error "Failed to get language from $MAIN. Please specify it with --lang."
            fi
        fi
    fi

    #------------------
    # create spellchecking command
    #
    # first, create skiplist
    #
    COUNT=0
    for SKIP in $ASPELL_SKIP_TAGS; do
        SKIPLIST[$COUNT]="--add-sgml-skip=$SKIP"
        let COUNT++
    done
    # now create the command
    SPELLCMD="/usr/bin/aspell --mode=sgml ${SKIPLIST[*]} --encoding=utf-8 --lang=$ASPELL_LANG"
    if [[ -n "$ASPELL_EXTRA_DICT" ]]; then
        SPELLCMD="$SPELLCMD --extra-dicts=$ASPELL_EXTRA_DICT"
    fi

    # show spellchecker command with --debug
    [[ 1 = "$DEBUG" ]] && echo "DEBUG: $SPELLCMD"

    # do spellchecking on the list of files
    for FILE in "${FILELIST[@]}"; do
        test -f "$FILE" || ccecho "warn" "File $FILE does not exist"
        if [[ 1 = "$LISTMODE" ]]; then
            LISTOUTPUT=$($SPELLCMD list < "$FILE" | sort -u 2>/dev/null)
            [[ -n "$LISTOUTPUT" ]] && echo -e "$FILE\n------------------------------\n$LISTOUTPUT\n"
            LISTOUTPUT=""
        else
            echo "Checking $FILE..."
            $SPELLCMD -c "$FILE"
        fi
    done
    exit
}

###########################################################################
#
# Stylecheck
#
# Performs a stylecheck on rootid
#
###########################################################################
function stylecheck {
    local SHORT_OPTS LONG_OPTS SUB_CMD
    SUB_CMD=$1
    shift

    SHORT_OPTS="h"
    LONG_OPTS="file:,help,name:,rootid:,show"

    parse_args "$SHORT_OPTS" "$LONG_OPTS" "$SUB_CMD" "$@"
    eval set -- "$P_REMAIN_ARGS"

    #------ Computing the values returned from the parser -----
    if [[ 1 = "$P_HELP" ]]; then
        help_scmd_head "$SUB_CMD" "${HELP_SUBCOMMAND[$SUB_CMD]}"
    help_file
        help_help
        help_name
        help_rootid
    help_show_check
        echo -e "    NOTES: * Options --file (-f) and --rootid exclude one another.\n           * If neither file nor rootid is specified, the rootid\n             from the DC-file is used\n           * $SUB_CMD follows xi:includes\n"
        exit 0
    fi

    if [[ -z "$P_ROOTID" && -z "$P_FILE" ]]; then
        if [[ 0 != $VERBOSITY ]]; then
            ccecho "info" "Neither file nor rootid specified, using rootid from DC-file"
        fi
    elif [[ -n "$P_ROOTID" && -n "$P_FILE" ]]; then
        exit_on_error "Options --file (-f) and --rootid exclude one another.\nPlease specify only one of these options"
    fi

    [[ -n "$P_NAME" ]]      && export PDFNAME="$P_NAME" BOOK="$P_NAME"
    [[ -n "$P_ROOTID" ]]    && export ROOTID="$P_ROOTID"
    [[ -n "$P_SHOW" ]]      && export SHOW=1

    if [[ -n "$P_FILE" ]]; then
        if [[ -f $P_FILE ]]; then
            ROOTID=$($XSLTPROC --stylesheet "$DAPSROOT/daps-xslt/common/get-rootelement-id.xsl" --file "$P_FILE" "$XSLTPROCESSOR" 2>/dev/null) || exit_on_error "Cannot get a rootid from file $FILE"
        export ROOTID
        else
            exit_on_error "File $P_FILE does not exist"
        fi
    fi

    call_make "$SUB_CMD" "$@"
}

###########################################################################
#
# XMLformat
#
# Prettyfies the XML sources
#
###########################################################################
function xmlformat {
    local DAPSXMLFORMAT SHORT_OPTS LONG_OPTS SUB_CMD
    SUB_CMD=$1
    shift

    SHORT_OPTS="h"
    LONG_OPTS="file:,help,rootid:"

    parse_args "$SHORT_OPTS" "$LONG_OPTS" "$SUB_CMD" "$@"
    eval set -- "$P_REMAIN_ARGS"

    #------ Computing the values returned from the parser -----
    if [[ 1 = "$P_HELP" ]]; then
        help_scmd_head "$SUB_CMD" "${HELP_SUBCOMMAND[$SUB_CMD]}"
        help_file
        help_help
        help_rootid
        echo -e "    NOTES: * Options --file and --rootid exclude one another.\n           * If neither file nor rootid is specified, the rootid\n             from the DC-file is used\n           * $SUB_CMD follows xi:includes\n           * MAIN is ignored when --file or when a ROOTID is specified\n           * This command will directly alter your source xml files!"
        exit 0
    fi

    if [[ -z "$P_ROOTID" && -z "$P_FILE" ]]; then
        if [[ 0 != $VERBOSITY ]]; then
            ccecho "info" "Neither file nor rootid specified, using rootid from DC-file"
        fi
    elif [[ -n "$P_ROOTID" && -n "$P_FILE" ]]; then
        exit_on_error "Options --file (-f) and --rootid exclude one another.\nPlease specify only one of these options"
    fi

    # define which dpas-xmlformat to use
    #
    if [[ -n "$DAPSROOT" && "$DAPSROOT" != "$DAPSROOT_DEFAULT" ]]; then
        # use daps-xmlformat from DAPSROOT if the latter is set
        DAPSXMLFORMAT="${DAPSROOT}/bin/daps-xmlformat"
    else
        DAPSXMLFORMAT="$(which --skip-alias --skip-functions daps-xmlformat 2>/dev/null)" || exit_on_error "Cannot find a daps-xmlformat executable"
    fi

    # if --file was specified, FILELIST contains just one file
    # if --rootid was specified, we need to get the list of files

    if [[ -n "$P_FILE" ]]; then
        FILELIST[0]="$P_FILE"
    else
        [[ -n "$P_ROOTID" ]] && export ROOTID="$P_ROOTID"
        FILELIST=( $(call_make list-srcfiles silent LIST_NODC=1 LIST_NOENT=1 LIST_NOIMG=1 ) )
        if [[ 0 != $? ]]; then
            exit_on_error "Failed to get filelist for ROOTID \"$ROOTID\""
        fi
    fi

    # run daps-xmlformat
    #
    # ignore $MAIN with --file or --rootid
    #
    echo "Prettifying the following files:"
    for FILE in "${FILELIST[@]}"; do
        if [[ -n "$P_FILE" || -n "$ROOTID" ]]; then
            [[ "$FILE" == "$MAIN" ]] && continue
        fi
        [[ 0 != "$VERBOSITY" ]] && echo -e "  $FILE"
        $DAPSXMLFORMAT -i "$FILE" >/dev/null
    done
}


###########################################################################
#
# Debugging function
#
# Subcommands: dapsenv, nothing, showvariable
#
###########################################################################
function debugging {
    local SHORT_OPTS LONG_OPTS SUB_CMD
    SUB_CMD=$1
    shift

    SHORT_OPTS="h"
    LONG_OPTS="help,name:,rootid:,target:"

    parse_args "$SHORT_OPTS" "$LONG_OPTS" "$SUB_CMD" "$@"
    eval set -- "$P_REMAIN_ARGS"

    #------ Computing the values returned from the parser -----
    if [[ 1 = "$P_HELP" ]]; then
        help_scmd_head "$SUB_CMD" "${HELP_SUBCOMMAND[$SUB_CMD]}"
        help_help
        help_name
        help_rootid
        help_target
        echo
        exit 0
    fi

    [[ -n "$P_NAME" ]]      && export PDFNAME="$P_NAME" BOOK="$P_NAME"
    [[ -n "$P_ROOTID" ]]    && export ROOTID="$P_ROOTID"
    [[ -n "$P_TARGET" ]]    && export TARGET="$P_TARGET"

    call_make "$SUB_CMD" "$@"
}

###########################################################################
#
#  IMAGES
#
#  Generate images. For debugging and testing purposes
#
###########################################################################

function build_images {
    local SHORT_OPTS LONG_OPTS SUB_CMD
    SUB_CMD=$1
    shift

    SHORT_OPTS="h"
    LONG_OPTS="color,gen,grayscale,online,rootid:"

    parse_args "$SHORT_OPTS" "$LONG_OPTS" "$SUB_CMD" "$@"
    eval set -- "$P_REMAIN_ARGS"

    #------ Computing the values returned from the parser -----
    if [[ 1 = "$P_HELP" ]]; then
        help_scmd_head "$SUB_CMD" "${HELP_SUBCOMMAND[$SUB_CMD]}"
        help_color
        help_gen
        help_grayscale_images
        help_help
        help_online
        help_rootid
        echo
        exit 0
    fi

    if [[ -z "$P_COLOR" && -z "$P_IMAGES_GEN" && -z "$P_GRAYSCALE" && -z "$P_IMAGES_ONLINE" ]]; then
    export IMAGES_ALL=1
    else
    [[ -n "$P_COLOR" ]]            && export IMAGES_COLOR=1
    [[ -n "$P_IMAGES_GEN" ]]       && export IMAGES_GEN=1
    [[ -n "$P_GRAYSCALE" ]]        && export IMAGES_GRAYSCALE=1
    [[ -n "$P_IMAGES_ONLINE" ]]    && export IMAGES_ONLINE=1
    fi

    [[ -n "$P_ROOTID" ]]           && export ROOTID="$P_ROOTID"

    call_make "$SUB_CMD" "$@"
}


###########################################################################
#
#  MISC
#
#  various functions
#
###########################################################################

# call make directly
# for functions with no command line options
# do not write a log
function no_opts {
    local CURR_DIR SHORT_OPTS LONG_OPTS SUB_CMD
    local SUB_CMD=$1
    shift

    SHORT_OPTS="h"
    LONG_OPTS="help"

    parse_args "$SHORT_OPTS" "$LONG_OPTS" "$SUB_CMD" "$@"
    eval set -- "$P_REMAIN_ARGS"

    #------ Computing the values returned from the parser -----
    if [[ 1 = "$P_HELP" ]]; then
        help_scmd_head "$SUB_CMD" "${HELP_SUBCOMMAND[$SUB_CMD]}" "0"
        exit 0
    fi

    WRITE_LOG=0
    if [[ $SUB_CMD =~ ^clean.* ]]; then
        #
        # Use the cd commands to avoid errors when running DAPS from
        # one of the directories that get removed
        #
        CURR_DIR=$(pwd 2>/dev/null)
        cd $DOC_DIR > /dev/null
        call_make "$SUB_CMD" "$@"
        [[ -d $CURR_DIR ]] && cd $CURR_DIR
    else
        call_make "$SUB_CMD" "$@"
    fi
}

# error message for deprecated targets
function deprecated {
    local SUB_CMD=$1
    ccecho "error" "${HELP_SUBCOMMAND[$SUB_CMD]}"
    exit 1
}


# error message when specifying an invalid subcommand
function wrong_parameter {
    local SUB_CMD=$1
    echo "Type '$ME $SUB_CMD help' to get a list of valid parameters"
    exit 1;
}

# needed by docmanager
function showenv {
    echo "DOC_DIR=$DOC_DIR;DOCCONF=$DOCCONF"
    exit 0
}

###########################################################################
#
# HELP
#
# There are a lot of options, several functions have in common.
# In order to not have to write the same text again and again, we
# provide a help function for each option
#
###########################################################################

# first line of help
#
function help_scmd_head {
    echo -e "$ME [--global-options] $1 [options]

$2\n"

[[ 0 != $3 ]] && echo -e "  Command options:"
}

function help_check {
    cat <<EOF
    --check                   Validate the resulting document.
                              Implies a verbosity level of at least 1.
                              Default: unset
EOF
}
function help_clean {
    cat <<EOF
    --clean                   Clean up the result directory (delete all files
                              and subdirectories) before building the document.
                              Default: unset
EOF
}
function help_color {
    cat <<EOF
    --color                   Only generate color images.
                              Default: off
EOF
}
function help_compact {
    cat <<EOF
    --compact                 Print the filelist on a single line.
                              Ignored when -s|--show is set.
                              Default: off
EOF
}
function help_cropmarks {
    cat <<EOF
    --cropmarks               Add cropmarks to the PDF. Only available for
                              the XEP formatter, FOP currently does not support
                              cropmarks.
                              Ignored when FOP is used.
                              Default: off
EOF
}
function help_css {
    cat <<EOF
    --css=filename,           Specify a path to a css file.
    --css=none                The special string \"none\" forces DAPS to use
                              no css, even when configured elsewhere
                              (e.g. in a config file).
                              Default: unset
EOF
}

function help_dbnoconv {
    cat <<EOF
    --dbnoconv                Do not convert to NovDoc, but rather keep
                              the source format.
                              Default: Conversion to NovDoc
EOF
}
function help_db5todb4 {
    cat <<EOF
    --db5todb4                Create XML bigfile in DoBook 4 format. This
                              option only applies if the sources are in
                              DocBook5 format.
                              Default: Conversion to NovDoc
EOF
}
function help_db5todb4nh {
    cat <<EOF
    --db5todb4nh              Create XML bigfile in DocBook 4 format without
                              a DOCTYPE header. This option only applies if
                              the sources are in DocBook5 format.
                              Default: Conversion to NovDoc
EOF
}
function help_def-file {
    cat <<EOF
    --def-file=FILE           Specify a DEF-* file containing build
                              information
EOF
}
function help_desktopfiles {
    cat <<EOF
    --desktopfiles            Generate .desktop files.
                              Default: off
EOF
}
function help_documentfiles {
    cat <<EOF
    --documentfiles           Generate .document files.
                              Default: off
EOF
}
function help_draft {
    cat <<EOF
    --draft                   Add a 'DRAFT' watermark to all pages of the book
                              Default: off
EOF
}
function help_epub3 {
    cat <<EOF
    --epub3                   Generate ePUB version 3 eBooks.
                              Default: ePUB version 2
EOF
}
function help_export-dir {
    cat <<EOF
    --export-dir=DIRECTORY    Specify a directory where to copy the results
                              of the $TARGET command. The directory will be
                              created if it does not exist.
                              Default: <BUILD_DIRECTORY>/online-docs
EOF
}
function help_extra-dict {
    cat <<EOF
    --extra-dict=filename     Specify a path to an additional custom
                              dictionary.
                              Default: unset
EOF
}
function help_file {
    cat <<EOF
    --file=FILE               Specify the name of an input file
EOF
}
function help_formatter {
    cat <<EOF
    --formatter=FORMATTER     Specify the PDF formatter to be used. Currently
                              'xep' or 'fop' are supported.
                              Default: 'fop'
EOF
}
function help_gen {
    cat <<EOF
    --gen                     Do all image conversions (images/gen) but
                              do not generate or link the images to
                              images/color or images/grayscale.
                              Default: unset
EOF
}
function help_grayscale_images {
    cat <<EOF
    --grayscale               Only generate grayscale images.
                              Default: off
EOF
}
function help_grayscale_pdf {
    cat <<EOF
    --grayscale               Generate a grayscale PDF for printing.
                              Default: off
EOF
}
function help_help {
    cat <<EOF
    --help, -h                Print this help text
EOF
}
function help_html5 {
    cat <<EOF
    --html5                   HTML builds are generated as XHTML files.
                              Force HTML5 with this switch.
                              Default: unset
EOF
}
function help_ignore-styleroot {
    cat <<EOF
    --ignore-styleroot        Ignore all stylesheet assignments (e.g. the
                              DC-file) and use the original DocBook stylesheets
                              instead. Use this option if your custom
                              stylesheets produce text output you are not
                              satisfied with.
                              Default: unset
EOF
}
function help_imgonly {
    cat <<EOF
    --imgonly                 Only list images files.
                              Shortcut for --nodc --noent --noxml.
EOF
}
function help_jsp {
    cat <<EOF
    --jsp                     Creates JSP output. Requires custom stylesheets
                              (not available with the standard DocBook
                              stylesheets).
                              Default: off
EOF
}
function help_lang {
    cat <<EOF
    --lang                    Specify a language to use for spellchecking.
                              See \"man aspell \" for details.
                              Default: en_US
EOF
}
function help_list {
    cat <<EOF
    --list                    Dumps a sorted list of misspelled words to
                              standard output instead of starting the
                              interactive spellchecker.
EOF
}
function help_locdrop {
    cat <<EOF
    --locdrop                 Use this option to create a source tarball
                              from a previous locdrop after translation.
                              If set, will include the files manifest_*.txt
                              in the source tarball.
                              Default: off
EOF
}
function help_meta {
    cat <<EOF
    --meta                    If set, prints additional status information
                              (filename, maintainer and status) for each file.
                              Implies draft mode.
                              Default: off
EOF
}
function help_modified {
    cat <<EOF
    --modified                Print the image modification time.
                              Ignored when --compact is set.
                              Default: off
EOF
}
function help_name {
    cat <<EOF
    --name=BOOKNAME           File- and directory names for generated content
                              are derived from BOOKNAME.
                              Default: generated by stripping 'DC-' from the
                              doc config filename
EOF
}
function help_nodc {
    cat <<EOF
    --nodc                    Exclude DC-file from list.
                              Default: unset
EOF
}
function help_noent {
    cat <<EOF
    --noent                   Exclude Entity files from list.
                              Default: unset
EOF
}
function help_noepub {
    cat <<EOF
    --noepub                  Deactivates creating the ePUB output
                              Default: ePUB output is created.
EOF
}
function help_nogzip {
    cat <<EOF
    --nogzip                  If specified, man pages will not be compressed
                              with gzip.
                              Default: unset
EOF
}
function help_nohtml {
    cat <<EOF
    --nohtml                  Deactivates creating the package-html tarball.
                              Default: Package-html tarball iscreated.
EOF
}
function help_noimg {
    cat <<EOF
    --noimg                   Exclude images from list.
                              Default: unset
EOF
}
function help_nohelp {
    cat <<EOF

No further help for subcommand \"$1\" available.
EOF
}
function help_nopdf {
    cat <<EOF
    --nopdf                   Deactivates creating the color-pdf. Useful when
                              "locdropping" a complete set where you
                              want to deliver separate PDFs for each book
                              rather than one huge PDF for the whole set.
                              Default: PDF is created
EOF
}
function help_norefcheck {
    cat <<EOF
    --norefcheck              Disables checking internal links
                              (ID/IDREF/IDREFS) and thus allows to build
                              or validate with e.g. xref-links pointing
                              to non-existing IDs.
                              This option only affects DocBook5 sources and is
                              ignored when processing DocBook4.
                              Default: unset
EOF
}
function help_nosearch {
    cat <<EOF
    --nosearch                Deactivates creating the search tab in webhtml
                              builds.
                              Default: enabled
EOF
}
function help_noset {
    cat <<EOF
    --noset                   Creates a bigfile for the given book (specified
                              by the rootid) rather than the complete set.
                              Links in the bigfile that point to external
                              targets, are replaced by text-only pointers.
                              Default: off
EOF
}
function help_nostatic {
    cat <<EOF
    --nostatic                Normally images and css files in HTML builds
                              are copied from elsewhere in the file system.
                              Use this option to link these files in order
                              to save disk space. Note that this eventually
                              produces nested links which may cause errors
                              with CSS and Javascript.
EOF
}
function help_notrans-dir {
    cat <<EOF
    --notrans-dir=DIRECTORY   Relative or absolute path to the directory
                              containing the untranslated sources. Links
                              pointing to this directory are created for all
                              files listed in manifest_notrans.txt.
                              Optional. If not specified, the dirname of the
                              DC-file is used.
                              Default: DC-file directory
EOF
}
function help_novalid {
    cat <<EOF
    --novalid                 Do not perform a validation check on the
                              (profiled) sources. However, they need to be
                              well-formed.
                              Implies a validation check on the resulting
                              bigfile.
                              Default: unset
EOF
}
function help_noxml {
    cat <<EOF
    --noxml                   Exclude XML files from list.
                              Default: unset
EOF
}
function help_online {
    cat <<EOF
    --online                  Only generate images used for HTML builds.
                              Default: off
EOF
}
function help_optipng {
    cat <<EOF
    --optipng                 Optimize PNG images by reducing the color
                              palette (using optipng), Modfies the original
                              sources!
                              Default: off
EOF
}
function help_output-dir {
    cat <<EOF
    --output-dir=DIRECTORY    Output directory in which to unpack the files
                              from the localization drop. Mandatory.
                              Default: unset
EOF
}
function help_pagefiles {
    cat <<EOF
    --pagefiles               Generate .page files.
                              Default: off
EOF
}
function help_param {
    cat <<EOF
    --param="KEY=VALUE"       Add an xslt processor parameter.
                              Useful to temporarily overwrite/set style sheet
                              parameters such as margins.
                              This parameter can be specified multiple times.
                              Default: unset
EOF
}
function help_pretty {
    cat <<EOF
    --pretty                  Pretty print file lists (one filename per line)
EOF
}
function help_remarks {
    cat <<EOF
    --remarks                 Include remarks (<remark>...</remark>) in book
                              Implies draft mode.
                              Default: off
EOF
}
function help_rootid {
    cat <<EOF
    --rootid=ID               Specify a ROOTID to build only parts of a book
                              (parts or chapters). Default: Usually set
                              in the DC-file; if not set the complete set
                              defined in \$MAIN will be built
EOF
}
function help_set-date {
    cat <<EOF
    --set-date=YYYY/MM/DD     Set a publication date. If not set, the current
                              date will automatically be chosen.
                              Default: current date
EOF
}
function help_show_images {
    cat <<EOF
    --show                    Show images with an image viewer that either
                              has been specified with --viewer or by setting
                              IMG_VIEWER in the config file
                              Default: off
EOF
}
function help_show_check {
    cat <<EOF
    --show                    Show the result of the check command
                              in a browser. Uses \$BROWSER if defined,
                              otherwise xdg-open.
                              Default: off
EOF
}
function help_single {
    cat <<EOF
    --single                  Creates a single file HTML output (opposed to
                              the default, which generates chunked HTML,
                              consisting of several HTML pages.
                              Default: off
EOF
}
function help_statdir {
    cat <<EOF
    --statdir=DIRECTORY       Specify a DIRECTORY containing resource files
                              (CSS, images, Javascript etc.).
                              DEFAULT: \$STYLEROOT/static
EOF
}
function help_subdirs {
    cat <<EOF
    --subdirs                 Man pages are created in a man/ directory.
                              To also enable the subdirectories man1/, man2/,
                              etc., specify this parameter.
                              Default: off
EOF
}
function help_stringparam {
    cat <<EOF
    --stringparam="KEY=VALUE" Add an xslt processor parameter.
                              Useful to temporarily overwrite/set style sheet
                              parameters such as margins.
                              This parameter can be specified multiple times.
                              Default: unset
EOF
}
function help_target {
    cat <<EOF
    --target=TARGET           Specify a potential target (such as jsp or
                              color-pdf) in order to retrieve correct values
                              for target-specific values.
                              Default: same as daps subcommand
EOF
}
function help_trans-files {
    cat <<EOF
    --trans-files="<LIST>"    Specify one or more tarballs with translated
                              files (semicolon-separeted) for a single
                              language.
                              Default: unset
EOF
}
function help_viewer {
    cat <<EOF
    --viewer=VIEWER           Image viewer to be used.
                              Default: IMG_VIEWER setting from config file
EOF
}
function help_xmlonly {
    cat <<EOF
    --xmlonly                 Only list XML files.
                              Shortcut for --nodc --noent --noimg.
EOF
}
function help_xsltparam {
    cat <<EOF
    --xsltparam=STRING        ** Deprecated **
                              Use --param and/or --stringparam instead.
EOF
}
