#!/bin/bash

#     gen_trbdf  -- generates `trbdf' program
#     Copyright (C) 2000, 2001, 2003 Anton Kirilov Zinoviev

#     This program is free software; you can redistribute it and/or modify
#     it under the terms of the GNU General Public License as published by
#     the Free Software Foundation; either version 2 of the License, or
#     (at your option) any later version.

#     This program is distributed in the hope that it will be useful,
#     but WITHOUT ANY WARRANTY; without even the implied warranty of
#     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#     GNU General Public License for more details.

#     You should have received a copy of the GNU General Public License
#     along with this program; if not, write to the Free Software
#     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

#     Contact the author by e-mail: anton@lml.bas.bg, zinoviev@fmi.uni-sofia.bg

cat <<"PART"
#!/bin/bash

#     trbdf  -- translates BDF fonts from one codeset to other
#     Copyright (C) 2000, 2001, 2003 Anton Kirilov Zinoviev

#     This program is free software; you can redistribute it and/or modify
#     it under the terms of the GNU General Public License as published by
#     the Free Software Foundation; either version 2 of the License, or
#     (at your option) any later version.

#     This program is distributed in the hope that it will be useful,
#     but WITHOUT ANY WARRANTY; without even the implied warranty of
#     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#     GNU General Public License for more details.

#     You should have received a copy of the GNU General Public License
#     along with `bash' interpreter; if not, write to the Free Software
#     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

#     Contact the author by e-mail: anton@lml.bas.bg, zinoviev@fmi.uni-sofia.bg

function err() {
    echo -e $1 1>&2
    echo "trbdf: Try \`trbdf --help' for more information." 1>&2
    exit 2
}

function get_opt() {
    case $1 in
    -)
	op=arg;;
    --*)
	op=`expr $1 : '\(.*\)=.*' '|' $1`;;
    -*)
	op=`expr $1 : '\(-.\).*'`;;
    *)
	op=arg;;
    esac
}

function get_arg() {
    case $1 in
    -)
	arg='-'
	shift;;
    --*)
	arg=`expr $1 : '[^=]*=\(.*\)'`
	if [ -z "$arg" ]; then 
	    arg=$2
	    shift; shift;
	else
	    shift;
	fi;;
    -*)
	arg=`expr $1 : '-.\(.*\)'`
	if [ -z "$arg" ]; then 
	    arg=$2
	    shift; shift;
	else
	    shift;
	fi;;
    *)
	arg=$1
	shift;;
    esac
    if [ -z "$arg" ]; then
	err "trbdf: Option \`${op}' requires an argument."
    fi
    args="$*"
}

function no_arg() {
    case $1 in
    --*)
	local x=`expr $1 : '[^=]*=\(.*\)'`
	if [ -n "$x" ]; then 
	    err "trbdf: Option \`$1' doesn't allow an argument."
	fi;;
    -*)
	local x=`expr $1 : '-.\(.*\)'`
	if [ -n "$x" ]; then
	    x=-$x
	fi;;
    *) ;;
    esac
    shift
    args="$x $*"
}

PART

cat $1| 
while read a b c; do
    echo "function $a() {"
    echo "cat <<\"EOF\""
    cat $3/$a
    echo "EOF"
    echo "}"
    echo
done

cat <<"PART"
fromcs=cp1251
tocs=cp1251
usefb=yes
foundry=""

while [ -n "$1" ]; do
    get_opt $*
    case $op in
    -C|--copyright)
	no_arg $* ; set -- $args
	cat<<"EOF"
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with "bash" interpreter; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
EOF
	exit;;
    -h|--help)
	no_arg $* ; set -- $args
	cat<<"EOF"
trbdf 1.5
Usage: trbdf [OPTION]... [BDF-FONT]

       -C, --copyright     display copying conditions and warranty information
       -s, --gen-script    generates translating script for given pair codesets
       -l, --list          list all known codesets
       -h, --help          display this help and exit
-f BEFORE, --from=BEFORE   codeset of the source
 -t AFTER, --to=AFTER      codeset of the output
    --foundry=FOUNDRY      Set the given FOUNDRY of the fonts
           --no-fallback   do not try to approximate the missing symbols

If none of -C, -s, -l, -h and their equivalents is given BDF-FONT will be read 
assuming it is in codeset BEFORE.  On standard output it will be translated so 
to use codeset AFTER.  If there is no BDF-FONT given "trbdf" will act as filter.
If you have to translate more than 2-3 fonts, it is recommended to use the
option -s.  Both BEFORE and AFTER are case insensitive and default to "cp1251".
EOF
	exit;;
    -l|--list)
	no_arg $* ; set -- $args
PART

echo "        echo \"Known codesets:  \""
echo -n "        echo '"

cat $1 | 
while read a b c; do
    echo -n "$a  "
done
echo "'"
echo "        exit;;"

cat<<"PART"
    -f|--from)
	get_arg $* ; set -- $args
	fromcs=$arg;;
    -t|--to)
	get_arg $* ; set -- $args
	tocs=$arg;;
    --no-fallback)
	no_arg $* ; set -- $args
        usefb=no;;
    --foundry)
	get_arg $* ; set -- $args
	foundry="$arg";;
    -s|--gen-script)
	no_arg $* ; set -- $args
	gen=yes;;
    arg)
	get_arg $* ; set -- $args
	[ -n "$file" ] && err "trbdf: Extra operand."
	file="${arg}";;
    *)
	err "trbdf: Unknown option \`$1'." ;;
    esac
done

[ -z "$file" ] && file="-"

fromcs=`echo ${fromcs}|tr A-Z a-z`
tocs=`echo ${tocs}|tr A-Z a-z`

case ${fromcs} in
PART

cat $1 |
while read a b c d; do
    echo "$a)"
    echo "    fromregistry=\"$b\""
    echo "    fromencoding=\"$c\""
    echo "    fromcs=\"$a\";;"
done

cat <<"PART"
*)
    err "trbdf: Unknown codeset \`${fromcs}'.\ntrbdf: Try trbdf --list";;
esac

case ${tocs} in
PART

cat $1 |
while read a b c; do
    echo "$a)"
    echo "    toregistry=\"$b\""
    echo "    toencoding=\"$c\""
    echo "    tocs=\"$a\";;"
done

cat <<"PART"
*)
    err "trbdf: Unknown codeset \`${tocs}'.\ntrbdf: Try trbdf --list";;
esac

tmpfile=/tmp/csrec.$$

[ -f ${tmpfile}.1 ] && err "trbdf: The file ${tmpfile}.1 exists !? Try again."
touch ${tmpfile}.1

[ -f ${tmpfile}.2 ] && err "trbdf: The file ${tmpfile}.2 exists !? Try again."
touch ${tmpfile}.2

trap "rm ${tmpfile}.1 ${tmpfile}.2; exit 2" HUP INT TERM

{
cat <<EOF
BEGIN {
EOF

${fromcs} |
awk '{printf "tu[%s]=\"%s\";\n", $1, $2;}'

${tocs} |
awk '{printf "ut[\"%s\"]=%s;\n", $2, $1;}'

cat <<EOF

PART

cat $2 | awk '{
    split($0,a);
    for(i=2;i<=NF;i++)
	{
	    if (a[1] ~ /00[01][0-9A-F]/ || a[1] ~ /2010/) {
		    alt1[a[i]] = a[1] " " alt1[a[i]];
		    weight1[a[i]] = i-1 " " weight1[a[i]];
	    } else {
		    alt2[a[i]] = a[1] " " alt2[a[i]];
		    weight2[a[i]] = i+100 " " weight2[a[i]];
	    }
	}
}
END {
    for(i in alt1)
	{
	    printf "alt1[\"%s\"] = \"%s\";\n", i, alt1[i];
	    printf "weight1[\"%s\"] = \"%s\";\n", i, weight1[i];
	}
    for(i in alt2)
	{
	    printf "alt2[\"%s\"] = \"%s\";\n", i, alt2[i];
	    printf "weight2[\"%s\"] = \"%s\";\n", i, weight2[i];
	}
}'

cat $4 | awk '{
    printf "adobe[\"%s\"] = \"%s\";\n", $1, $2;
}'

cat <<"PART"

print "#!/usr/bin/awk -f";
print;
print "BEGIN {";

for(i in tu)
    {
EOF

if [ "$usefb" = yes ]; then
    printf "	split(tu[i] \" \" alt1[tu[i]] \" \" alt2[tu[i]], a);\n"
    printf "	split(0 \" \" weight1[tu[i]] \" \" weight2[tu[i]], w);\n"
else
    printf "	split(tu[i] \" \" alt1[tu[i]], a);\n"
    printf "	split(0 \" \" weight1[tu[i]], w);\n"
fi

cat <<"EOF"
	for(j in a)
	  {
	    if(ut[a[j]]!="")
	      {
		if(adobe[a[j]]!="PRINTED")
		  {
		    if(adobe[a[j]]!="")
		      {
			printf "dd[%s] = \"%s\";\n", ut[a[j]], adobe[a[j]];
		      }
		    else
		      {
			printf "dd[%s] = \"uni%s\";\n", ut[a[j]], a[j];
		      }
		    adobe[a[j]] = "PRINTED";
		  }
	      }
	  }
	k=0;
	for(j in a)
	  {
	    if(ut[a[j]]!="")
	      {
		if(k==0)
		  {
		    printf "alt[%s] = \"", i;
		  }
		printf "%s ", ut[a[j]];
		k++;
	      }
	  }
	if(k!=0)
	  {
	    printf "\";\n";
	  }
	k=0;
	for(j in a)
	  {
	    if(ut[a[j]]!="")
	      {
		if(k==0)
		  {
		    printf "weight[%s] = \"", i;
		  }
		printf "%s ", w[j];
		k++;
	      }
	  }
	if(k!=0)
	  {
	    printf "\";\n";
	  }
    }

print "}";
}
EOF
} >${tmpfile}.1

awk -f ${tmpfile}.1 >${tmpfile}.2

cat >>${tmpfile}.2 <<"EOF"

/^STARTFONT / {
  print;
EOF
echo "  print \"COMMENT This font was automaticaly reencoded from ${fromregistry}-${fromencoding} to ${toregistry}-${toencoding}.\";" >>${tmpfile}.2
cat >>${tmpfile}.2 <<"EOF"
  print "COMMENT by trbdf utility (ftp://lml.bas.bg/home/anton/linux/trscripts-1.5.tar.gz)";
  print "COMMENT The COMMENTs below (if any) are from the original font.";
  print "COMMENT ---------------------------------------------------------";
  next;
}

/^STARTPROPERTIES /, /^ENDPROPERTIES/ {
  if($1=="FONT")
    {
      sub(/^FONT +/, "");
      sub(/^"/, "");
      nfields=split($0, field, "-");
      if((n=index(field[15], "["))!=0)
	{
	  hint = substr(field[15], n);
	}
      else
	{
	  hint = "";
        }
EOF
echo "      field[14]=\"${toregistry}\";" >>${tmpfile}.2
echo "      field[15]=\"${toencoding}\" hint;" >>${tmpfile}.2
if [ -n "$foundry" ]; then
    echo "  field[2]=\"${foundry}\";" >>${tmpfile}.2
fi
cat >>${tmpfile}.2 <<"EOF"
      numprops++;
      property[numprops] = "FONT \"" field[1];
      for(i=2; i<=nfields; i++)
        property[numprops] = property[numprops] "-" field[i];
      property[numprops] = property[numprops] "\"";
      next;
    }
  if($1=="DEFAULT_CHAR") {
    next;
  }
  if($1=="CHARSET_REGISTRY") {
    numprops++;
EOF
echo "    property[numprops] = \"CHARSET_REGISTRY \\\"${toregistry}\\\"\";" >>${tmpfile}.2
cat >>${tmpfile}.2 <<"EOF"
    next;
  }
  if($1=="CHARSET_ENCODING") {
    numprops++;
EOF
echo "    property[numprops] = \"CHARSET_ENCODING \\\"${toencoding}\\\"\";" >>${tmpfile}.2
cat >>${tmpfile}.2 <<"EOF"
    next;
  }
EOF
if [ -n "$foundry" ]; then
    cat >>${tmpfile}.2 <<"EOF"
  if($1=="FOUNDRY") {
    numprops++;
EOF
    echo "    property[numprops] = \"FOUNDRY \\\"${foundry}\\\"\";" >>${tmpfile}.2
    cat >>${tmpfile}.2 <<"EOF"
    next;
  }
EOF
fi
cat >>${tmpfile}.2 <<"EOF"
  if($1=="STARTPROPERTIES") {
    next;
  }
  if($1=="ENDPROPERTIES") {
    print "STARTPROPERTIES " numprops + 1;
    for(i=1;i<=numprops;i++) {
      print property[i];
    }
    print "DEFAULT_CHAR 63";
    print "ENDPROPERTIES";
    next;
  }
  numprops++;
  property[numprops] = $0;
  next;
}

/^FONT / {
  sub(/^FONT +/, "");
  sub(/^"/, "");
  nfields=split($0, field, "-");
  if((n=index(field[15], "["))!=0)
    {
      hint = substr(field[15], n);
    }
  else
    {
      hint = "";
    }
EOF
echo "  field[14]=\"${toregistry}\";" >>${tmpfile}.2
echo "  field[15]=\"${toencoding}\" hint;" >>${tmpfile}.2
if [ -n "$foundry" ]; then
    echo "  field[2]=\"${foundry}\";" >>${tmpfile}.2
fi
cat >>${tmpfile}.2 <<"EOF"
  printf "FONT " field[1];
  for(i=2; i<=nfields; i++)
    printf "-%s", field[i];
  printf "\n";
  next;
}

/^CHARS / {
  count=0;
  next;
}

/^STARTCHAR /, /^ENDCHAR/ {
  if($1=="STARTCHAR")
    {
      store = "";
      next;
    }
  if($1=="ENCODING")
    {
      encoding=$2;
      next;
    }
  if($1=="ENDCHAR")
    {
      nalts = split(alt[encoding], a);
      split(weight[encoding], w);
      for(i=1;i<=nalts;i++)
	{
	  if(fntw[a[i]]=="")
	    count++;
	  if(fntw[a[i]]=="" || fntw[a[i]] > w[i])
	    {
	      fntch[a[i]] = store;
	      fntw[a[i]] = w[i];
	    }
	}
      next;
    }
  store = store $0 "\n";
  next;
}

/^ENDFONT/ {
  printf "CHARS %s\n", count;
  for(i in fntch)
    {
      printf "STARTCHAR %s\n", dd[i];
      printf "ENCODING %s\n", i;
      printf "%s", fntch[i];
      printf "ENDCHAR\n";
    }
  print "ENDFONT";
  next;
}

{
  print;
}

EOF

if [ "$gen" = yes ] ; then
    cat ${tmpfile}.2
else
    awk -f ${tmpfile}.2 <${file}
fi

rm ${tmpfile}.[12]

PART
