function svnmore() {
    svn cat "$@" 2>&1 | more
}

function catman() {
    [ -s "$@" ] || {
        echo "Missing or empty file: $@" 1>&2
        return 1
    }
    unzip -p "$@" META-INF/MANIFEST.MF
}
function hms() {
    local strin strdec
    local strh strm strs
    [ $# = 1 ] || {
        echo 'SYNTAX: hms ss||ss.dec||mm:ss|mm:ss.dec|hh:mm:ss|hh:mm:ss.dec' 1>&2
        return 2
    }
    strin="$1"; shift
    case "$strin" in *.*) strdec=${strin##*.}; strin=${strin%%.*};; esac
    case $strin in
        *[^0-9:]*)
            echo 'SYNTAX: hms ss||ss.dec||mm:ss|mm:ss.dec|hh:mm:ss|hh:mm:ss.dec' 1>&2
            return 2;;
    esac
    case "$strin" in
        *:*:*) strh=${strin%%:*}; strs=${strin##*:}
               strin=${strin%:*}; strm=${strin##*:};;
        *:*) strm=${strin%%:*}; strs=${strin##*:};;
        *) strs=$strin;;
    esac
    case "$strs" in 0[0-9]) strs=${strs#0};; esac
    case "$strm" in 0[0-9]) strm=${strm#0};; esac
    case "$strh" in 0[0-9]) strh=${strh#0};; esac
    #echo "($strh/$strm/$strs $strdec)"
    [ -n "$strm" ] && ((strs = strs + 60 * strm))
    [ -n "$strh" ] && ((strs = strs + 60 * 60 * strh))
    echo "$strs${strdec:+.$strdec}"
    return 0
}

function backup() {
    for arg in "$@"; do
        [ -e "${arg}.orig" ] && {
            read -p "Overwrite '${arg}' [Y]? "
            case "$REPLY" in '');; [Yy]*);; *)
                echo 'Skipping '${arg}'.'; continue;;
            esac
        }
        cp -fav "$arg" "${arg}.orig"
    done
}

function study() {
    local DO_NUMBER DO_TRIM DO_CONCISE DO_MARKED
    local -a marks
    while [ $# -gt 0 ]; do
        case "$1" in -*);; *) break;; esac
        case "$1" in *h*)
            echo 'SYNTAX: study [-cnmt] file...
  -c: Concise by skipping blank and comment lines
  -h: display this Help banner
  -m: prompt only for Marked lines (lines preceded with *)
  -n: output line Numbers 
  -t: Trim leading and training whitespace'
            return 0;;
        esac
        case "$1" in *c*) DO_CONCISE=true;; esac
        case "$1" in *n*) DO_NUMBER=true;; esac
        case "$1" in *t*) DO_TRIM=true;; esac
        case "$1" in *m*) DO_MARKED=true;; esac
        case "$1" in -*[^cmnt]*)
            echo 'study only supports switches -n and -t' 1>&2
            return 2;;
        esac
        shift
    done
    [ $# -gt 0 ] || {
        echo 'You must specify at least one input file path' 1>&2
        return 2
    }
    for f in "$@"; do
        [ -f "$f" ] || {
            echo "study No such file: $f" 1>&2
            return 1
        }
        [ -r "$f" ] || {
            echo "study Can't read file: $f" 1>&2
            return 1
        }
    done
    local N absDataPath absDirPath
    local -i lines line nextLine

    if [ -n "$URL_HANDLER" ]; then
        type -t "$URL_HANDLER" > /dev/null || {
            echo "URL_HANDER from env, '$URL_HANDLER', inaccessible.  Fix the setting." 1>&2
            return 3
        }
    else
        URL_HANDLER=xdg-open
        type -t "$URL_HANDLER" > /dev/null || {
            URL_HANDLER=gnome-open
            type -t "$URL_HANDLER" > /dev/null || {
                URL_HANDLER=
                echo 'URL-handling disabled because no URL handler found.  Set env. URL_HANDLER if you have one.'
            }
        }
    fi

    for f in "$@"; do
        # Absolutize the file path in URL
        absDataPath="$(readlink -f $f)"
        absDirPath=$(dirname $absDataPath)
        [ -n "$DO_MARKED" ] && {
            marks=()
            ((line = 0))
            while read; do
                ((line = line + 1))
                # Trimmed LINE:
                TLINE=$(IPUT="$REPLY" perl -we '$_ = $ENV{"IPUT"}; s/^\s+//; s/\s+$//; print;')
                case "$TLINE" in '*'*) marks[line]=true;; esac
            done < $f
            echo "${marks[@]}"
        }

        ((line = 0))
        [ -n "$DO_NUMBER" ] && lines=$(wc -l $f | perl -awe 'print "$F[0]\n";')
        echo -n "File '$f'.  Hit ENTER to display each line.  Q to quit.  N for next file.\n-----------------------------------------------------------"
        while read; do
            ((line = line + 1))
            ((nextLine = line + 1))
            LINE="$REPLY"
            # Trimmed LINE:
            TLINE=$(IPUT="$LINE" perl -we '$_ = $ENV{"IPUT"}; s/^\s+//; s/\s+$//; print;')
            if [ -n "$DO_TRIM" ]; then
                OUT_LINE="$TLINE"
            else
                OUT_LINE="$LINE"
            fi
            URL=
            [ -n "$URL_HANDLER" ] && case "$OUT_LINE" in
                http:/*|https:/*|file:/*)
                    URL="$OUT_LINE"
                    ;;
                file:*)
                    URL="file:${absDirPath}/${OUT_LINE#file:}"
                    ;;
            esac

            [ -n "$DO_MARKED" ] && {
                if [ -n "${marks[$line]}" ]; then
                    [ -n "$DO_NUMBER" ] && echo -n "  $line/$lines"
                elif [ -n "${marks[$nextLine]}" ]; then
                    echo -n "\n$OUT_LINE"
                    continue
                else
                    [ -n "$DO_CONCISE" ] ||
                      case "$TLINE" in '##'*);; ''|'#'*) echo -n "\n$OUT_LINE";; esac
                    continue
                fi
            }
            case "$TLINE" in '##'*) continue;; ''|'#'*)
                [ -n "$DO_CONCISE" ] || echo -n "\n$OUT_LINE"
                continue
                ;;
            esac
            [ -n "$DO_MARKED" ] || {
                [ -n "$DO_NUMBER" ] && echo -n "  $line/$lines"
            }
            echo -n ' ?  '
            read -n 1 < /dev/tty
            case "$REPLY" in [Nn]*) break;; [Qq]*) echo; break 2;; '');; *) echo;; esac
            [ -n "$URL" ] && $URL_HANDLER "$URL" > /dev/null 2>&1
            echo -n "$OUT_LINE"
        done < $f
        echo
    done
}

trimInto_TRIMMED() {
    unset _TRIMMED
    local var="$*"
    # remove leading whitespace characters
    var="${var#"${var%%[![:space:]]*}"}"
    # remove trailing whitespace characters
    _TRIMMED="${var%"${var##*[![:space:]]}"}"   
    [ "$_TRIMMED" != "$*" ]
}

function lstail () {
    local TAIL_SWITCH
    [ $# -gt 0 ] && case "$1" in -[0-9]*) TAIL_SWITCH="$1"; shift;; esac
    ls -ltr "$@" | tail $TAIL_SWITCH
}
