#!/bin/bash

# saxoncat: wrapper for lib-saxon-java, arbortext catalog classes, docbook stylesheets
# Maintainer: Mark Johnson <mrj@debian.org>

# saxoncat wrapper script, version 6.4.4, Copyright (C) 2001 Mark Johnson
# This is free software; see the GPL version 2 or later. NO warranty.

# TODO: 
#       (1) Option for Saxon version & associated extension version
#       (2) Detect option clashing/redundancies
#       (3) Clean up variables, write a manpage

## ----------------------------------------------------------------------
## exit on erroneous subcommand
set -e

## ----------------------------------------------------------------------
## get script name
script=$(basename $0)

## ----------------------------------------------------------------------
## print help message
function usage_message
{
    cat >&2 <<'END'
Usage: saxoncat [options] source-doc stylesheet {param=value}...  or
       saxoncat [options] -k source-doc {param=value}...          or
       saxoncat [options] source-doc docbook {param=value}...

  Accepts options for saxon and uses options to set system properties 
  for the arbortext-catalog classes.

DocBook Usage:
  * Using 'docbook' as the stylesheet argument will automagically use the
    docbook html stylesheets and load the saxon extensions. (The extensions
    enable callouts, numbered program listings, and the direct inclusion of
    text. See the docbook-xsl-stylesheets docs for details.)
  * Using both '-k' and '-X' options is equivalent to a 'docbook' stylesheet arg.

$STYLESHEET Env Variable:
  * If no stylesheet is specified and $STYLESHEET is set, its value will be used
    as the stylesheet argument.

'$SAXON_PARAMS' Env Variable:
  * You can also specify stylesheet parameters by setting a 'SAXON_PARAMS' 
    environment variable.

Help options
  -h                      Print abbreviated synopsis 
 --help                   Print this help message
 --help-examples          Print common usage examples
 --help-saxon             Print Saxon XSLT processor options
                           (See /usr/share/doc/lib-saxon-java/doc/index.html)
General Options:
  -v                      Verbose. Print all messages.
  -k                      docbook html stylesheets | specify a stylesheet
  -X                      Use DocBook extension classes (callouts, line numbers, ...)
  -j  <java_interpreter>  Specify alternate java interpreter
  -D  <property=value>    System property assignment (passed to java interpreter)
 --CP <classpath_prefix>  Prepend entries to CLASSPATH
  -g                      Use gij, the GNU interpreter for Java bytecode

Catalog Parsing Options: (See /usr/share/doc/arbortext-catalog/docs/README.htm)

  -d <NUM>               Debug, or parsing verbosity. NUM=[0-3] 
                          (equivalent to -D xml.catalog.debug=<NUM>)
  -c <file1[:file2...]>  Catalogs to parse before system catalogs 
                          (equivalent to 
                           '-S -D xml.catalog.files=YOUR_CATALOG_FILES:/etc/sgml/catalog')
  -C <file1[:file2...]>  Catalogs to parse (do NOT parse system catalogs) 
                          (equivalent to '-S -D xml.catalog.files=YOUR_CATALOG_FILES')
  -s                     Prefer document system ids to catalog SYSTEM entries
                          (equivalent to '-D xml.catalog.override=false')
  -S                     Disable all catalog parsing 
END
    exit 0;
}
## ----------------------------------------------------------------------
## print some examples

function usage_examples
{
    cat >&2 <<'END'

Usage examples:  saxoncat [options] source-doc stylesheet {param=value}...  or
                 saxoncat [options] -k source-doc {param=value}...
                 saxoncat [options] source-doc docbook {param=value}...

 -Basic:         saxoncat -o foo.html foo.xml style.xsl

 -DocBook HTML:    .   .   .   .   .  saxoncat -k foo.xml 

    ...  with extensions:  .   .   .  saxoncat -kX foo.xml or saxon foo.xml docbook 

    ...  verbose catalog parsing:  .  saxoncat -d 3 -kX foo.xml 

    ...  passing stylesheet params:

              saxoncat -kX foo.xml html.stylesheet=style.css     or
              saxoncat foo.xml docbook html.stylesheet=style.css 
END
    exit 0;
}
## ----------------------------------------------------------------------
## print simplified synopsis when no arguments
function usage_synopsis
{
    cat >&2 <<'END'

Usage:   saxoncat [options] source-doc stylesheet {param=value}... or 
         saxoncat [options] -k source-doc {param=value}...         or
         saxoncat [options] source-doc docbook {param=value}...

 Note: The option '-k' is equivalent to a stylesheet argument with value:
       '/usr/share/sgml/docbook/stylesheet/xsl/nwalsh/html/chunk.xsl'
       Furthermore, a stylesheet argument of 'docbook' is same as '-kX'.

Common Options:   -k                 use docbook html stylesheets 
                  -X                 use docBook extension classes
                  -o                 output document name
                  -S                 disable catalog parsing
                  -g                 use GNU gij java interpreter

Try  saxoncat --help-examples   for usage examples
     saxoncat --help            for complete list of options 
END
    exit 2;
}
## ----------------------------------------------------------------------
## print error message
function usage_error
{
    echo -e >&2 "$script: $@";
    exit 2;
}
## ----------------------------------------------------------------------
## print saxon's usage message 
function saxon_usage () 
{
   cat >&2 <<'END'

Options for SAXON 6.3

Usage:   saxon [options] source-doc style-doc {param=value}...

Options: 
  -a              Use xml-stylesheet PI, not style-doc argument 
  -ds|dt          Use [standard]|[tinytree] data structure (default ) 
  -o filename     Send output to named file or directory 
  -m classname    Use specified Emitter class for xsl:message output 
  -r classname    Use specified URIResolver class 
  -t              Display version and timing information 
  -T              Set standard TraceListener
  -TL classname   Set a specific TraceListener
  -u              Names are URLs not filenames 
  -w0|w1|w2       [Recover silently] | [report & continue (default)] | [exit] 
                  on recoverable errors 
  -x classname    Use specified SAX parser for source file 
  -y classname    Use specified SAX parser for stylesheet 

END
exit 0;
}


## ---------------------------------------------------------------------
## Function that checks args for equal signs

function check_arg () { valid_arg_type="$1"

    # Determine arg_type of current $arg
    # if arg contains "=", then it's a param
    [ -z `echo $arg | grep ".*=.*"` ] && arg_type="stylesheet" || arg_type="param"

    # arg is OK, set $param or $stylesheet to $arg
    if [ "$arg_type" = "$valid_arg_type" ]; then
	eval `echo -e "${valid_arg_type}=${arg}"`
	return 0
	
    elif [ arg_type="param" ]; then
	# paran args with no "=" get error message
	echo -e  "\nYour argument '$arg' isn't of the form \"param=value\" 
and therefore might be a stylesheet. Since you've already 
specified a stylesheet you may wish to cancel this run. \n  "
	echo -ne "Abort now? [Y/n]  "
	read input;
	if ! [ "$input" = "n" -o "$input" = "N" ]; then
	    usage_error "Processing cancelled."
	    exit 2;
	fi
	return 0
    else
	# remaining case: stylesheet arg not OK
	return 1
    fi
    return 0
} 


## ----------------------------------------------------------------------
## set default values
use_catalogs=true
use_gij=false
dbextensions=false
dbchunk=false
verbose=false
print_saxon_usage=false
dbextensions=false

arg_type=''
stylesheet=''
params=''
saxon_opts=''
user_props=''
user_cp_prefix=''
cp_flag=''

cat_files_prop=''
cat_debug_prop=''
cat_override_prop=''
## ----------------------------------------------------------------------
## set variables
system_catalog="/etc/sgml/catalog"
java="/usr/bin/java"
gij="/usr/bin/gij"
dbstyle_home="/usr/share/sgml/docbook/stylesheet/xsl/nwalsh"
java_rep="/usr/share/java"

cat_file_list=$system_catalog
cat_debug_level="1"
cat_override_val="true"

dbchunk_stylesheet=$dbstyle_home"/html/chunk.xsl"
saxon_jar=$java_rep"/saxon.jar"
saxon_ext_jars=$dbstyle_home"/extensions/saxon644.jar"
catalog_jars=$java_rep"/catalog.jar:"$java_rep"/saxon-catalog.jar"
crimson_jar=$java_rep"/crimson.jar"

catalog_parse_class="-x cz.kosek.CatalogXMLReader"
saxon_style_class="com.icl.saxon.StyleSheet"
trans_prop="-Djavax.xml.transform.TransformerFactory=com.icl.saxon.TransformerFactoryImpl"

saxon_help_cmd="$java $saxon_style_class -?"

## ----------------------------------------------------------------------
## get command line options & arguments
sax_option_list="atTuo:m:x:y:" 
shortopts="hvSskXgD:d:C:c:"$sax_option_list
longopts="help,help-saxon,help-examples,CP:,ds,dt,TL:,w0,w1,w2"

user_input=`getopt -a -n saxoncat -l $longopts -o $shortopts -- "$@"`

eval set -- "$user_input"
while test "X$1" != "X--"; do
    case "$1" in
	-v  ) verbose=true ;; 
	-d  ) cat_debug_level=$2;  shift ;; 
	-c  ) cat_file_list=$2:$system_catalog; shift ;;
	-C  ) cat_file_list=$2; shift ;;
	-s  ) cat_override_val=false ;;
	-S  ) use_catalogs=false ;;
	-g  ) use_gij=true; java=$gij ;;
	-D  ) user_props="$1$2 "${user_props}; shift ;;
	-k  ) dbchunk=true ;;
	-X  ) dbextensions=true ;;
	-o | -m | -x | -y | --TL ) 
	    saxon_opts=" "`eval echo "$1"|tr -s '-'`" $2"${saxon_opts}
	    shift ;; 
	-a | -t | -T | -u | -o | -m | -x | -y | -T ) 
	    saxon_opts=" $1"${saxon_opts} ;;
	--ds | --dt | --w0 | --w1 | --w2 ) 
	    saxon_opts=$saxon_opts" "`eval echo "$1"|tr -s '-'` ;;
	--CP ) user_cp_prefix=" $2": ; shift ;;
	-h  ) usage_synopsis ;;
	--help ) usage_message ;;
	--help-saxon ) saxon_usage ;;
	--help-examples ) usage_examples ;;
    esac
    shift
done
shift # get rid of the '--'


## ----------------------------------------------------------------------
## get source file/print synosis if no input
[ -z "$1" ] && usage_synopsis
source_doc="$1"; shift


## ----------------------------------------------------------------------
## get or set stylesheet arg

! [ "$1" = "docbook" ] || { dbchunk=true; dbextensions=true; shift; }

if $dbchunk ; then
    stylesheet=$dbchunk_stylesheet
    
else
    if [ -n "$1" ]; then
	arg=$1; 
	check_arg stylesheet 
	if [ "$?" = "0" ]; then 
	    shift;
	else
	    [ -n "$SAXON_STYLESHEET" ] && { stylesheet=$SAXON_STYLESHEET; shift; }
	fi
    fi
fi

# check: if still no stylesheet arg, print error message
[ -n "$stylesheet" ] || usage_error "Stylesheet argument is missing."


## ----------------------------------------------------------------------
# check param=val args
for arg in "$@"; do
    check_arg param && params="$params $param"
    shift
done

[ -n "$SAXON_PARAMS" ] && params="$SAXON_PARAMS $params"


## ----------------------------------------------------------------------
## Load DocBook extension classes?
dbextensions=true && params="use.extensions=1 "$params

## ----------------------------------------------------------------------
## Parse catalogs?
$use_catalogs || catalog_parse_class=''
saxon_opts=${catalog_parse_class}${saxon_opts}

## ----------------------------------------------------------------------
## collect properties (make a readable command line)

cat_files_prop="-Dxml.catalog.files="$cat_file_list
cat_debug_prop="-Dxml.catalog.debug="$cat_debug_level
cat_override_prop="-Dxml.catalog.override="$cat_override_val

xml_catalog_props=$cat_files_prop" "$cat_debug_prop" "$cat_override_prop
properties=$user_props" "$xml_catalog_props" "$trans_prop

## ----------------------------------------------------------------------
## set classpath
export CLASSPATH=${user_cp_prefix}$saxon_jar:$catalog_jars:$crimson_jar:$saxon_ext_jars

## ----------------------------------------------------------------------
## Commandline

if [ "$use_gij" = "true" ]; then 
    cp_flag="-I"
else
    cp_flag="-cp "
fi

cmd_line="$java ${cp_flag}${CLASSPATH} $properties $saxon_style_class $saxon_opts $source_doc $stylesheet $params $*"


## ----------------------------------------------------------------------
## Messages
if $verbose; then
    echo
    echo "Sourcefile             "$source_doc
    echo "Stylesheet:            "$stylesheet
     [ -n "$params" ] && echo "Params:                "$params
#    $dbchunk && echo "DocBook chunking:      "$dbchunk
    echo "Java interpreter:      "$java
    echo "Use catalogs:          "$use_catalogs
    if $use_catalogs ; then 
	echo "Catalog file list:     "$cat_file_list
	echo "Catalog debug level:   "$cat_debug_level
	echo "Prefer catalog sysids  "$cat_override_val
    fi
    [ -n "$user_props" ] &&  echo "User Properties:       "$user_props
    [ -n "$saxon_opts" ] &&  echo "Saxon options:         "$saxon_opts
    echo "CLASSPATH:             "$CLASSPATH
    echo
    echo "Command issued: "
    echo "$cmd_line"
    echo
fi

## ----------------------------------------------------------------------
## just Do It

eval $cmd_line 
exit 0
## ----------------------------------------------------------------------

