#! /bin/sh

# Generic script to convert sgml to other formats.
#
# Just what the world needs: another sgml wrapper.
#
# Written by Dave Benson, 9/2000.

usage="usage: $0 INPUT FORMAT:OUTPUT FORMAT:OUTPUT ...

Convert a sgml file to a number of output files, possibly in
different formats.

Postscript, PDF and plain text all cause files to get created.
HTML and HTML1 create directories (because of the image files).

Output formats:
   PS          Generate postscript.
   HTML1       Generate one big HTML file.
   HTML        Generate many linked HTML files.
   TXT         Generate plain text.
   PDF         Generate PDF.
   TEX         Generate JadeTeX.
   RTF         Generate RTF (Rich Text Format -- used on windows).
   DVI         Generate DVI (generated by TeX).

Other hackery:
  - dia diagrams are recognized and converted automatically.
  - replace gifs with less evil, patent-free image format (PNG).
"

input="$1"
shift

# whether to clean up temporary directories.  (XXX: Should be a flag)
cleanup=1

if test "x$input" = "x" ||
   test "x$input" = "x--help" ; then
  echo "$usage" 1>&2
  exit 1
fi

remove_sgml_extension_script='s/\.sgml$//; s/\.SGML$//; s/\.sgm$//; s/\.SGM\$//'

sgml_base=`basename $input | sed -e "$remove_sgml_extension_script"`

origdir=`pwd`
srcbase=`basename $input`
case "$input" in
  /*)
    srcdir=`dirname $input`
    ;;
  */*)
    srcdir=`dirname $input`
    ;;
  ../*)
    srcdir=`dirname $input`
    ;;
  *)
    srcdir=`pwd`
    ;;
esac

# test for egrep and fgrep.
if test -r "/usr/xpg4/bin/grep" ; then
  egrep="/usr/xpg4/bin/grep -E"
  fgrep="/usr/xpg4/bin/grep -F"
else
  egrep="grep -E"
  fgrep="grep -F"
fi

#=====================================================================
# SGML *loves* gif files.  How ghastly.

# Replace DIA with any extension, which you just jam
# between these two script fragments.
hide_dia_perl_script_prefix='s/\bdia"/'
hide_dia_perl_script_suffix='"/g'

# Replace GIF files with royalty-free alternative.
legalize_it_perl_script='s/SRC="(.*)\.gif"/SRC="$1.png"/'

#=====================================================================
# Make tweaked versions of all the files.

# Make a directory to work in.
workdir="/tmp/sgml-converter-$$"
trap "rm -rf \"$workdir\"" 1 2 15
mkdir "$workdir" || {
  echo "$0: could not begin processing in $workdir; sorry." 1>&2
  exit 1
}

# HACK: get a list of all the sgml files.
sgml_deps=`grep '<!entity' $input | perl -ne '/"([^"]+)"/ && print "$1\n"'`

# Copy SGML into temporary directory for further inspection.
cp "$input" "$workdir" || {
  echo "$0: error copying files." 1>&2
  test "$cleanup" = 1 && rm -rf "$workdir"
  exit 1
}
sgml_files="$workdir/$srcbase"
for sgml_file in $sgml_deps ; do
  cp $srcdir/$sgml_file $workdir || {
    echo "$0: error copying file $sgml_file." 1>&2
    test "$cleanup" = 1 && rm -rf "$workdir"
    exit 1
  }
  sgml_files="$sgml_files $workdir/$sgml_file"
done

# HACK:  Find a list of all DIA diagrams.
dia_diagrams=`perl -ne 'if (/(?:imagedata)/ && /fileref=(\\S+)/)
                          {
			    \$dia = \$1;
			    \$dia =~ s/^"//; \$dia =~ s/"$//;
			    if (\$dia =~ /dia\$/)
			      {
				print "\$dia\\n";
			      }
			  }' $sgml_files`


#=====================================================================
#      Figure out what to do.

# Whether to produce eps files from the dia diagrams.
dia_output_eps=0

# Whether to render sgml with s/dia/eps/
sgml_with_eps=0

# Whether to produce png files.
dia_output_png=0

# Whether to render sgml with s/dia/gif/
sgml_with_gif=0

# Whether to render HTML (many pages)
render_html=0

# Whether to render HTML (one page)
render_html1=0

# Whether to render PS.
render_ps=0

# Whether to render PDF.
render_pdf=0

# Whether to render RTF.
render_rtf=0

# Whether to render text.
render_text=0

# Whether to render JadeTeX
render_jadetex=0

# Whether to render DVI files.
render_dvi=0

# Whether any images even need to be considered.
has_images=0

for type_file in "$@" ; do
  echo $type_file | $fgrep -q : || {
    echo "$0: every output spec must be of the form TYPE:FILE;" \
    		"at $type_file" 1>&2
    test "$cleanup" = 1 && rm -rf "$workdir"
    exit 1
  }
  extension=`echo "$type_file" | sed -e 's/:.*$//' | tr a-z A-Z`
  case "$extension" in
    PS | PDF | TEX | DVI)
      dia_output_eps=1
      sgml_with_eps=1
      ;;
    HTML | HTML1)
      dia_output_png=1
      sgml_with_gif=1
      ;;
    TXT)
      # use eps, since there is no change that'll be available
      # in a text rendering...
      sgml_with_eps=1
      ;;
    RTF)
      # XXX: I have no idea what's best here really...
      #      Anyone know the right stuff about RTF?
      sgml_with_eps=1
      dia_output_eps=1
      ;;
    *)
      echo "$id: unknown format \`$extension'" 1>&2
      test "$cleanup" = 1 && rm -rf "$workdir"
      exit 1
      ;;
  esac
  case "$extension" in
    PS)            render_ps=1      ;;
    PDF)           render_pdf=1     ;;
    HTML)          render_html=1    ;;
    HTML1)         render_html1=1   ;;
    RTF)           render_rtf=1     ;;
    JADETEX | TEX) render_jadetex=1 ;;
    DVI)           render_dvi=1     ;;
    TEXT | TXT)    render_text=1    ;;

    *)             echo "$0: unknown format: $format" 1>&2 
                   test "$cleanup" = 1 && rm -rf "$workdir"
                   exit 1
		   ;;
  esac
done

#=====================================================================
# Convert the `dia' diagrams.
if dia --help 2>&1 | grep -q 'export-to-ps' ; then
  eps_to_png=$dia_output_png
  dia_output_png=0
  if test "$dia_output_eps" = 0 ; then
    dia_output_eps=$eps_to_png
  fi
  dia_output_export_ps_flag=--export-to-ps
else
  eps_to_png=0
  dia_output_export_ps_flag=--export
fi

# `dia' in filter mode requires the X server, perhaps for no reason,
# perhaps for font data.
#
# In any event, we run this from cron often, which doesn't have
# any X server -- so we start are own Xvfb.
#
# TODO:
#  -- this should be done only if the user's X server is needed but not working.
xvfb=`which Xvfb`
if test -x "$xvfb" ; then
  # don't bother if there are no dia diagrams.
  test "x$dia_diagrams" = "x" || {
    number=""
    for tens in 1 2 3 4 ; do
      for ones in 0 1 2 3 4 5 6 7 8 9 ; do
	num=$tens$ones
	if test -e "/tmp/.X11-unix/X$num" ; then
	  continue
	else
	  number="$num"
	  break
	fi
      done
    done
    if test "x$number" = x ; then
      echo "$0: couldn't allocate virtual X server slot" 1>&2
      exit 1
    fi
    rm -f /tmp/diaxserver-$$
    sh -c "echo \$\$ > /tmp/diaxserver-$$ ; exec Xvfb :$number" &
    DISPLAY=":$number.0"
    export DISPLAY

    for t in 1 2 3 4 5 ; do
      test -e /tmp/diaxserver-$$ && break
      sleep 1
    done
    test -e /tmp/diaxserver-$$ || {
      echo "$0: couldn't get pid of virtual x server" 1>&2
      exit 1
    }
  }
fi

for d in $dia_diagrams ; do
  dia_basename=`echo $d | sed -e 's/\.dia$//'`
  has_images=1
  if test "$dia_output_eps" = 1 ; then
    output_eps="$workdir/$dia_basename.eps"
    eps_images="$eps_images $output_eps"
    dia "$dia_output_export_ps_flag=$output_eps" \
        "$srcdir/$dia_basename.dia" > "$workdir/dia.output" 2>&1 || {
      echo "$0: dia failed." 1>&2
      sed -e "s/^/dia output: /" < "$workdir/dia.output" 1>&2
      test "$cleanup" = 1 && rm -rf "$workdir"
      kill `cat /tmp/diaxserver-$$`
      rm /tmp/diaxserver-$$
      exit 1
    }
  fi
  if test "$dia_output_png" = 1 ; then
    output_png="$workdir/$dia_basename.png"
    png_images="$png_images $output_png"
    dia "--export=$workdir/$dia_basename.png" "$srcdir/$dia_basename.dia" \
         > /dev/null 2>&1 || {
      echo "$0: dia failed." 1>&2
      test "$cleanup" = 1 && rm -rf "$workdir"
      kill `cat /tmp/diaxserver-$$`
      rm /tmp/diaxserver-$$
      exit 1
    }
  fi
  if test "$eps_to_png" = 1 ; then
    output_png="$workdir/$dia_basename.png"
    png_images="$png_images $output_png"
    convert "$workdir/$dia_basename.eps" "$output_png" || {
      echo "$0: error running imagemagick (since you have an old dia)" 1>&2
      test "$cleanup" = 1 && rm -rf "$workdir"
      kill `cat /tmp/diaxserver-$$`
      rm /tmp/diaxserver-$$
      exit 1
    }
  fi
done

if test -e /tmp/diaxserver-$$ ; then
  kill `cat /tmp/diaxserver-$$`
  rm /tmp/diaxserver-$$
fi


#=====================================================================
# Convert the sgml files to use the converted dia files.
cd "$workdir" || exit 1
if test "$sgml_with_eps" = 1 ; then
  mkdir eps-sgml || exit 1
  dia_to_eps="$hide_dia_perl_script_prefix"eps"$hide_dia_perl_script_suffix"
  for file in *.sgml ; do
    perl -p -e "$dia_to_eps" < "$file" > "eps-sgml/$file" || {
      echo "$0: error \`converting' sgml to sgml w/ eps files." 1>&2
      test "$cleanup" = 1 && rm -rf "$workdir"
      exit 1
    }
  done
  test "x$eps_images" = "x" || {
    cp $eps_images eps-sgml || {
      echo "$0: error copying eps files into eps-sgml" 1>&2
      test "$cleanup" = 1 && rm -rf "$workdir"
      exit 1
    }
  }
fi

if test "$sgml_with_gif" = 1 ; then
  mkdir gif-sgml || exit 1
  dia_to_gif="$hide_dia_perl_script_prefix"gif"$hide_dia_perl_script_suffix"
  for file in *.sgml ; do
    perl -p -e "$dia_to_gif" < "$file" > "gif-sgml/$file" || {
      echo "$0: error \`converting' sgml to sgml w/ gif files." 1>&2
      test "$cleanup" = 1 && rm -rf "$workdir"
      exit 1
    }
  done
fi

#===================================================================== 
# Render in each of the needed formats.
cd "$workdir"
if test "$render_html" = 1 ; then
  cd "$workdir/gif-sgml" || exit 1
  sgmltools -b html "$sgml_base.sgml" || {
    echo "$0: error converting to html." 1>&2
    exit 1
  }
  mv "$sgml_base" "$workdir/html" || {
    echo "$0: internal error moving html direcotry in $workdir" 1>&2
    test "$cleanup" = 1 && rm -rf "$workdir"
    exit 1
  }
  cd "$workdir"
  perl -p -i -e "$legalize_it_perl_script" html/*.html || {
    echo "$0: error substituting png's back in html" 1>&2
    test "$cleanup" = 1 && rm -rf "$workdir"
    exit 1
  }
  if test "$has_images" = 1 ; then
    cp $png_images "html" || {
      echo "$0: error copying images into html directory" 1>&2
      test "$cleanup" = 1 && rm -rf "$workdir"
      exit 1
    }
  fi
fi

if test "$render_html1" = 1 ; then
  cd "$workdir/gif-sgml" || exit 1
  sgmltools -b html -j '-Vnochunks -Vrootchunk' "$sgml_base.sgml" || {
    echo "$0: error converting to html." 1>&2
    test "$cleanup" = 1 && rm -rf "$workdir"
    exit 1
  }
  mv "$sgml_base" "$workdir/html1" || {
    echo "$0: internal error moving html1 directory in $workdir" 1>&2
    test "$cleanup" = 1 && rm -rf "$workdir"
    exit 1
  }
  cd "$workdir"
  perl -p -i -e "$legalize_it_perl_script" html1/*.html || {
    echo "$0: error substituting png's back in html1" 1>&2
    test "$cleanup" = 1 && rm -rf "$workdir"
    exit 1
  }
  if test "$has_images" = 1 ; then
    cp $png_images "html1" || {
      echo "$0: error copying images into html1 directory" 1>&2
      test "$cleanup" = 1 && rm -rf "$workdir"
      exit 1
    }
  fi
fi

if test "$render_text" = 1 ; then
  cd "$workdir/eps-sgml" || exit 1
  # the WWW_HOME stops lynx from printing lines like:
  #     Looking up  'Not-Configured-Yet' first.
  WWW_HOME=/tmp sgmltools -b txt "$sgml_base.sgml" || {
    echo "$0: error converting to text." 1>&2
    test "$cleanup" = 1 && rm -rf "$workdir"
    exit 1
  }
  mv "$sgml_base.txt" "$workdir/output.txt" || {
    echo "$0: internal error moving text file in $workdir" 1>&2
    test "$cleanup" = 1 && rm -rf "$workdir"
    exit 1
  }
fi

if test "$render_rtf" = 1 ; then
  cd "$workdir/eps-sgml" || exit 1
  sgmltools -b rtf "$sgml_base.sgml" || {
    echo "$0: error converting to rff." 1>&2
    test "$cleanup" = 1 && rm -rf "$workdir"
    exit 1
  }
  mv "$sgml_base.rtf" "$workdir/output.rtf" || {
    echo "$0: internal error moving rtf file in $workdir" 1>&2
    test "$cleanup" = 1 && rm -rf "$workdir"
    exit 1
  }
fi

if test "$render_ps" = 1 ||
   test "$render_pdf" = 1 ||
   test "$render_dvi" = 1 ||
   test "$render_jadetex" = 1 ; then
  cd "$workdir/eps-sgml" || exit 1
  if test "$has_images" = 1 ; then
    cp "$workdir/"*.eps .
  fi
  sgmltools -b jadetex "$sgml_base.sgml" || {
    echo "$0: error converting to jadetex." 1>&2
    test "$cleanup" = 1 && rm -rf "$workdir"
    exit 1
  }
  mv "$sgml_base.tex" "$workdir/output.tex" || {
    echo "$0: internal error moving tex file in $workdir" 1>&2
    test "$cleanup" = 1 && rm -rf "$workdir"
    exit 1
  }
fi

if test "$render_ps" = 1 ||
   test "$render_pdf" = 1 ||
   test "$render_dvi" = 1 ; then
  # Convert jadetex to dvi (using jadetex, of course.)
  cd "$workdir" || exit 1
  # Running it thrice gets rid of missing crossrefs.
  # (And twice doesn't do it.  The Table Of Contents winds up with
  #  no page numbers).
  jadetex output.tex < /dev/null > tex.processing.output 2>&1 > /dev/null
  jadetex output.tex < /dev/null > tex.processing.output 2>&1 > /dev/null
  jadetex output.tex < /dev/null > tex.processing.output 2>&1 > /dev/null
fi

if test "$render_ps" = 1 ||
   test "$render_pdf" = 1 ; then
  cd "$workdir" || exit 1
  dvips -q -f < output.dvi > output.ps || {
    echo "$0: error running dvips" 1>&2
    test "$cleanup" = 1 && rm -rf "$workdir"
    exit 1
  }
fi

if test "$render_pdf" = 1 ; then
  cd "$workdir" || exit 1
  ps2pdf output.ps output.pdf || {
    echo "$0: error running ps2pdf" 1>&2
    test "$cleanup" = 1 && rm -rf "$workdir"
    exit 1
  }
fi

# Reconsider the arguments.
cd $origdir
for type_file in "$@" ; do
  extension=`echo "$type_file" | sed -e 's/:.*$//' | tr a-z A-Z`
  filename=`echo "$type_file" | sed -e 's/^.*://'`
  if test -d "$filename" ; then
    rm -rf "$filename" || {
      echo "$0: couldn't destroy $filename" 1>&2
      test "$cleanup" = 1 && rm -rf "$workdir"
      exit 1
    }
  elif test -e "$filename" ; then
    rm -f "$filename" || {
      echo "$0: couldn't destroy $filename" 1>&2
      test "$cleanup" = 1 && rm -rf "$workdir"
      exit 1
    }
  fi
  case "$extension" in
    PS) cp "$workdir"/output.ps "$filename" ;;
    PDF) cp "$workdir"/output.pdf "$filename" ;;
    RTF) cp "$workdir"/output.rtf "$filename" ;;
    HTML) cp -r "$workdir"/html "$filename" ;;
    HTML1) cp -r "$workdir"/html1 "$filename" ;;
    TEXT | TXT) cp "$workdir"/output.txt "$filename" ;;
    DVI) cp "$workdir"/output.dvi "$filename" ;;
    JADETEX | TEX) cp "$workdir"/output.tex "$filename" ;;
    *)
      echo "$id: unknown format \`$format'" 1>&2
      test "$cleanup" = 1 && rm -rf "$workdir"
      exit 1
      ;;
  esac
  test $? = 0 || {
    echo "$0: error copying $extension file to $filename." 1>&2
    test "$cleanup" = 1 && rm -rf "$workdir"
    exit 1
  }
done

test "$cleanup" = 1 && rm -rf "$workdir"


