#!/bin/bash
#
# Copyright (C) 2012-2015 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
                ;;
            --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
                ;;
            --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
                ;;
            --notrans-dir)
                P_NOTRANS_DIR=""
                sanitize_path "$2" "P_NOTRANS_DIR"
                shift 2
                ;;
            --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
                ;;
            --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)
    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

}

###########################################################################
#
# RUN MAKE
#
# Set up log writing and verbosity
# and call make
#
###########################################################################
function call_make {
    local CORE_NO DBSTYLE_FILE DBSTYLE_VERS LOGFILE MAKE_BIN
    local MAKE_OPTIONS MAKE_CMD STRING SUB_CMD

    # first argument passed to the function is the subcommand
    # 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

    # 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 = "$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
    if [[ 0 = "$VERBOSITY" || 1 = "$VERBOSITY" || 2 = "$VERBOSITY" ]]; then
        # calculate Number of CPUs (cores) for -j option, set to "1" if empty
        CORE_NO=$(egrep -s -m1 "cpu cores\s*:" /proc/cpuinfo 2>/dev/null | sed 's/cpu cores\s*:\s*//')
        [[ -z "$CORE_NO" ]] && CORE_NO=1
        MAKE_OPTIONS="$MAKE_OPTIONS -j${CORE_NO}"
        [[ 1 != $DEBUG ]] && 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 ]]; then
        # get stylesheet version (ticket #151)
        # 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
        #
        DBSTYLE_FILE=$(xmlcatalog "$XML_MAIN_CATALOG" http://docbook.sourceforge.net/release/xsl/current/VERSION.xsl)
        DBSTYLE_FILE=${DBSTYLE_FILE##*file://}
        DBSTYLE_VERS=$($XSLTPROC --stylesheet "$DAPSROOT/daps-xslt/common/get-dbxslt-version.xsl" --file "$DBSTYLE_FILE" "$XSLTPROCESSOR" 2>/dev/null || echo "Not available")

        cat <<EOF
---------------
           DOC_DIR: $DOC_DIR
         BUILD_DIR: $BUILD_DIR
          DAPSROOT: $DAPSROOT
           DOCCONF: $DOCCONF
              BOOK: $BOOK

EOF

        if [[ -n "$STYLEDEVEL" ]]; then
            echo "         STYLEROOT: $STYLEDEVEL"
        else
            if [[ -n "$STYLEROOT" ]]; then
                echo "         STYLEROOT: $STYLEROOT"
            else
                echo "         STYLEROOT: $DOCBOOK_STYLES"
            fi
        fi

        cat <<EOF
FALLBACK_STYLEROOT: $FALLBACK_STYLEROOT
          EPUB_CSS: $EPUB_CSS
          HTML_CSS: $HTML_CSS

     PDF FORMATTER: $FORMATTER
EOF

        if [[ "fop" = "$FORMATTER" ]]; then
            cat <<EOF
 FORMATTER WRAPPER: $FOP_WRAPPER
  FORMATTER CONFIG: $FOP_CONFIG_FILE
EOF
        elif [[ "xep" = "$FORMATTER" ]]; then
            cat <<EOF
  FORMATTER WRAPPER: $XEP_WRAPPER
  FORMATTER CONFIG: $XEP_CONFIG_FILE
EOF
        fi

        cat <<EOF
           MAKECMD: $MAKE_CMD
     XSLTPROCESSOR: $XSLTPROCESSOR
 XML_CATALOG_FILES: $XML_CATALOG_FILES

      DAPS VERSION: $VERSION
DB-STYLESHEET-VERS: $DBSTYLE_VERS
---------------
EOF
    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:,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_SUBCMD"
	help_cropmarks
        help_draft
        help_formatter
	help_grayscale_pdf
        help_help
        help_meta
        help_name
	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
    [[ -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:,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_SUBCMD"
        help_clean
        help_css
        help_draft
        help_help
        help_html5
	help_jsp
        help_meta
        help_name
        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_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:,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_SUBCMD"
        help_clean
        help_css
        help_draft
        help_help
        help_name
        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"
    [[ -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:,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_SUBCMD"
        help_check
        help_css
	help_epub3
        help_help
        help_name
	help_param
        help_rootid
        help_statdir
	help_stringparam
        echo
        exit 0
    fi

    [[ 1 = "$P_REMARKS" ]]  && REMARKS=1
    [[ 1 = "$P_EPUB3" ]]  && export EPUB3=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 ePUBs requires a minimum verbosity level of 1
    if [[ 1 = "$P_CHECK" ]]; then
        [[ 0 = "$VERBOSITY" ]] && export VERBOSITY=1
        export EPUBCHECK="yes"
    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,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_SUBCMD"
        help_help
        help_nogzip
	help_param
        help_rootid
	help_stringparam
        help_subdirs
        echo
        exit 0
    fi

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

    call_make "$SUB_CMD" "$@"
}


###########################################################################
#
# Generic BUILD function
#
# Subcommands: every 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:,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_SUBCMD"
        help_help
        help_name
	help_param
        help_rootid
	help_stringparam
        echo
        exit 0
    fi

    [[ -n "$P_NAME" ]]         && export PDFNAME="$P_NAME" BOOK="$P_NAME"
    [[ -n "$P_ROOTID" ]]       && export ROOTID="$P_ROOTID"
    [[ -n "$P_STRINGPARAMS" ]] && export STRINGPARAMS="$P_STRINGPARAMS"
    [[ -n "$P_XSLTPARAM" ]]    && export XSLTPARAM="$XSLTPARAM $P_XSLTPARAM"

    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_SUBCMD"
        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 "$SUB_CMD" "$@"
}

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

    SHORT_OPTS="h"
    LONG_OPTS="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_SUBCMD"
        help_export-dir
        help_formatter
        help_help
        help_name
        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

    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_SUBCMD"
        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,rootid:,set-date:,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_SUBCMD"
        help_cropmarks
        help_desktopfiles
        help_documentfiles
        help_formatter
        help_grayscale_pdf
        help_help
        help_name
        help_pagefiles
        help_rootid
        help_set-date
        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_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,rootid:,set-date:,single,statdir:,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_SUBCMD"
        help_css
        help_desktopfiles
        help_documentfiles
        help_help
        help_html5
    help_jsp
        help_name
        help_pagefiles
        help_rootid
        help_set-date
    help_single
        help_statdir
        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_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 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="trans-files:,help,notrans-dir:,output-dir:"

    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_SUBCMD"
        help_trans-files
        help_help
        help_notrans-dir
        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")
        ALL_MANIFEST_TRANS_FILES=( "${ALL_MANIFEST_TRANS_FILES[@]}" "$MANIFEST_TRANS" )
        MANIFEST_NOTRANS=$(tar tfj "$TAR" | grep "$MFT_NOTRANS_SUFF")
        ALL_MANIFEST_NOTRANS_FILES=( "${ALL_MANIFEST_NOTRANS_FILES[@]}" "$MANIFEST_NOTRANS" )
        tar xfj "$TAR" "$MANIFEST_TRANS" "$MANIFEST_NOTRANS"
        tar xfj "$TAR" $(cat "$MANIFEST_TRANS")
        popd >/dev/null
    else
        exit_on_error "Fatal: $TAR does not exist"
    fi
    done

    pushd "$P_OUTPUT_DIR" > /dev/null

    #
    # 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"))

    # 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"))
    NO_DCFILE_LIST=$(awk '{for(i=1;i<=NF;++i)if($i !~ /DC-[^ ]*/)print $i}' <(echo "$LINK_NOTRANS_FILES"))
    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"))

    # 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" >&2
    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" >&2
    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" >&2
    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_SUBCMD"
        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,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_SUBCMD"
        help_remarks
        echo
    exit 0
    fi

    [[ 1 = "$P_REMARKS" ]]  && REMARKS=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,nodc,noent,noimg,noxml,pretty,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_SUBCMD"
        help_help
    if [[ $SUB_CMD =~ list-srcfiles ]]; then
            help_nodc
            help_noent
            help_noimg
            help_noxml
    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"

    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_SUBCMD"
        [[ "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_SUBCMD"
        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_SUBCMD"
        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") || 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 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)
                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 ASPELL_EXTRA_DICT 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_SUBCMD"
        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_FILE" ]] && FILELIST[0]="$P_FILE"
    [[ 1 = "$P_LIST" ]] && LISTMODE=1

    # extra dictionary
    # check and absolutize path
    if [[ -n "$P_ASPELL_EXTRA_DICT" ]]; then
        if [[ -e $P_ASPELL_EXTRA_DICT ]]; then
            sanitize_path "$P_ASPELL_EXTRA_DICT" "ASPELL_EXTRA_DICT"
        else
            exit_on_error "Path to extra dictionary \"$P_ASPELL_EXTRA_DICT\" is not valid"
        fi
    fi

    # 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 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

    # 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)
            [[ -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_SUBCMD"
    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") || 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" "$@"
}


###########################################################################
#
# 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_SUBCMD"
        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_SUBCMD"
        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 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_SUBCMD" "0"
        exit 0
    fi

    WRITE_LOG=0
    call_make "$SUB_CMD" "$@"
}

# error message for deprecated targets
function deprecated {
    local SUB_CMD=$1
    ccecho "error" "$HELP_SUBCMD"
    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 {
    cat <<EOF
$ME [--global-options] $1 [options]

$2
EOF

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

function help_check {
    cat <<EOF
    --check                   Validate the resulting ePUB document.
                              Useful when developing stylesheets. 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_draft {
    cat <<EOF
    --draft                   Add a 'DRAFT' watermark to all pages of the book
                              Default: off
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_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_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_nogzip {
    cat <<EOF
    --nogzip                  If specified, man pages will not be compressed
                              with gzip.
                              Default: unset
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: off
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_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_xsltparam {
    cat <<EOF
    --xsltparam=STRING        ** Deprecated **
                              Use --param and/or --stringparam instead.
                                            
                              Add one or more xslt processor parameters in
                              the form of
                              \"--stringparam KEY=VALUE --param KEY=VALUE\".
                              The given string will be passed unmodified to the
                              xslt processor call that
                              $1.
                              Useful to temporarily overwrite style sheet
                              parameters such as margins.
                              Note: You MUST quote the string with double
                              quotes: --xsltparam=\"STRING\"
                              Default: unset
EOF
}
