#!/bin/sh

#
# Written by Aleksey Cheusov <vle@gmx.net>
#

sysconfdir=/etc

if test -r $HOME/.coloritrc; then
   config_file=$HOME/.coloritrc
else if test -r "$sysconfdir/colorit.conf"; then
   config_file="$sysconfdir/colorit.conf"
else
   echo "configuration file is not readable" > "/dev/stderr"
   exit 1
fi fi

usage (){
   echo -en "\
colorit is intended to markup stdin or input files\n\
and output result to stdout\n\
\n\
usage: colorit [OPTIONS] [files...]\n\
OPTIONS:\n\
 -h  --help      display this screen\n\
 -V  --verbose   display version\n\
 -c  --config    specify a configuration file\n\
 -P  --pager     specify pager (- for none). The default is \"less -r\"\n\
     --pp        specify preprocessor (- for none). The default is \"m4\"\n\
"
}

version (){
    echo -en "\
colorit 0.0.1\n\
"
}

pager='less -r'
pp='m4'

while test $# -ne 0; do
    case $1 in
	-h|--help)
	    usage
	    exit 0;;
	-V|--version)
	    version
	    exit 0;;
	-c|--config)
	    config_file=$2
	    shift;;
	-P|--pager)
	    pager=$2
	    shift;;
	--pp)
	    pp=$2;
	    shift;;
	--)
	    shift
	    break;;
	-*)
	    echo "unknown argument '$1'" 1>&2
	    break;;
	*)
	    break;;
    esac
    shift
done

if test "_$pager" = "_-"; then
   pager=
fi

if test "_$pp" = "_-"; then
   pp=
fi

convert_files_to_stdout (){
    gawk -v config_file="$config_file" -v pp="$pp" '
    BEGIN {
	for (i=1; i <= ARGC; ++i){
	    if (ARGV [i] == "--help"){
		usage()
		exit 1
	    }
	    if (ARGV [i] == "--version"){
		version()
		exit 1
	    }
	    if (ARGV [i] == "--config" || ARGV [i] == "-c"){
		config_file = ARGV [i + 1]
		ARGV [i] = ARGV [i + 1] = ""
		++i
		continue
	    }
	    if (ARGV [i] == "--pager" || ARGV [i] == "-P"){
		pager = ARGV [i + 1]
		ARGV [i] = ARGV [i + 1] = ""
		++i
		continue
	    }
	}
    }

    BEGIN {
	mark_count = 0
    }

    function do_esc (s){
	gsub(/\\033/, "\033", s)
	return s
    }

    function do_unquote (s) {
	if (s ~ /^".*"$/ || s ~ /^`.*`$/){
	    return substr(s, 2, length(s)-2)
	}else{
	    return s
	}
    }

    function process_config_mark (       ok, arr){
	ok = match($0, /mark +("[^"]+"|`[^`]+`|[^ ]+) +("[^"]+"|`[^`]+`|[^ ]+) +("[^"]+"|`[^`]+`|[^ ]+) *$/, arr)

	if (ok){
	    mark_re  [mark_count] = do_unquote(arr [1])
	    mark_beg [mark_count] = do_esc(do_unquote(arr [2]))
	    mark_end [mark_count] = do_esc(do_unquote(arr [3]))

	    ++mark_count
	    return 1
	}else{
	    return 0
	}
    }

    function process_config_line (){
	sub(/^#.*$/, "")
	if (NF == 0)
	    return

	if ($1 == "mark"){
	    if (!process_config_mark()){
		print "missing arguments to `mark` at line:\n`" $0 "`" > "/dev/stderr"
		exit 1
	    }
	}else{
	    print "unexpected command `" $1 "`" > "/dev/stderr"
	    exit 2
	}
    }

    function process_config (){
	if (pp == ""){
	    while (0 < (ret = (pipe | getline))){
		process_config_line()
	    }
	}else{
	    pipe = pp " -DHOME=" ENVIRON ["HOME"] " <\"" config_file "\""

	    while (0 < (ret = (pipe | getline))){
		process_config_line()
	    }

	    close(pipe)
	}
    }

    BEGIN {
	process_config()
    }

    {
	for (i=0; i < mark_count; ++i){
	    gsub(mark_re [i], mark_beg [i] "&" mark_end [i])
	}

	print $0
    } ' "$@"
}

if test "$pager"; then
   eval convert_files_to_stdout "$@" | $pager
else
   convert_files_to_stdout "$@"
fi
