#!/bin/bash
#
# Converts LaTeX, combined EPS/LaTeX, EPIC, and PiCTeX pictures to (normal)
# EPS or PDF pictures
#
# Copyright 2007-2009,2011,2012 Christian Schneider <software(at)chschneider(dot)eu>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3 as
# published by the Free Software Foundation, not 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, see <http://www.gnu.org/licenses/>.
#
# WARNING: THIS IS ALPHA SOFTWARE AND MAY CONTAIN SERIOUS BUGS!

########################################################################
# configuration part
########################################################################

# debugging
#set -x

# version
VERSION="0.2.3-alpha"

# trapping ...
TMPDIR=""
trap '[[ -z "${TMPDIR}" ]] || rm -rf "${TMPDIR}"; exit 4' \
  1 2 3 4 5 7 9 10 12 15

########################################################################
# functions
########################################################################

# initialize variables
INFILE=""
OUTFILE=""
if [[ -z "${FONTSIZE}" ]]; then
  FONTSIZE="10pt"
fi
if [[ -z "${PACKAGES}" ]]; then
  PACKAGES="xcolor graphicx combinedgraphics"
fi
if [[ -z "${MACRO}" ]]; then
  MACRO="\\includecombinedgraphics"
fi
NOSKIPEXT="false"
SUBFIGUREMARK=""
SUBFIGUREMARKPOS="0,0"

exit_error () {
  echo "ERROR: ${1}" >&2
  [[ -z "${TMPDIR}" ]] || rm -rf "${TMPDIR}"
  exit 1
}

print_help () {
  echo "${0##*/} [-f|--fontsize <size>] [-p|--package <package>] \\" >&2
  echo "         [-m|--macro <macro>] [-n|--no-skip-ext] \\" >&2
  echo "         [-s|--subfiguremark <mark>] \\ " >&2
  echo "         [-r|--relative-pos (<x>,<y>)] <input file> <output file>" >&2
  echo >&2
  echo "Converts combined EPS/LaTeX and PDF/LaTeX graphics to normal" >&2
  echo "(E)PS or PDF with text part included." >&2
  echo >&2
  echo "Supported parameters:" >&2
  echo "  -f|--fontsize      font size; typically 10pt, 11pt, or 12pt" >&2
  echo "                     (default: \`${FONTSIZE}')" >&2
  echo "  -p|--package       package loaded right after the class; the" >&2
  echo "                     package name may be preceeded by options in" >&2
  echo "                     square brackets; this option may be specified" >&2
  echo "                     multiple times (loaded by default:" >&2
  echo "                     \`${PACKAGES}')" >&2
  echo "  -m|--macro         LaTeX macro used to include picture (default:" >&2
  echo "                     \`${MACRO}')" >&2
  echo "  -n|--no-skip-ext   do not skip extension of input file upon" >&2
  echo "                     passing it to the LaTeX macro" >&2
  echo "  -s|--subfiguremark adds a mark in the upper left corner of the" >&2
  echo "                     picture (useful for marking subfigures)" >&2
  echo "  -r|--relative-pos  relative position of subfigure mark (default:" >&2
  echo "                     \`${SUBFIGUREMARKPOS}')" >&2
  echo "  -v|--version       print version number" >&2
  echo "  -h|--help          this help" >&2
  echo >&2
  echo "The <input file> must be the LaTeX part of the graphics.  By" >&2
  echo "default, its extension is removed before passing it to the LaTeX" >&2
  echo "macro (see also the option \`-n' above)." >&2
  echo >&2
  echo "The format of the <output file> is determined by its extension:" >&2
  echo "  *.eps              generates an EPS picture" >&2
  echo "  *.pdf              generates a PDF picture" >&2
  echo >&2
  echo "The following environmental variables may be set to overwrite some" >&2
  echo "of the above defaults (must not be empty!):" >&2
  echo "  FONTSIZE           the default font size (see \`-f' parameter)" >&2
  echo "  PACKAGES           the list packages loaded (see \`-p' parameter)" >&2
  echo "  MACRO              the default include macro (see \`-m' parameter)" >&2
  echo >&2
  echo "IMPORTANT NOTE:" >&2
  echo "  When combined EPS/LaTeX or PDF/LaTeX graphics are converted," >&2
  echo "  the vector graphics part must exist in a format that LaTeX can" >&2
  echo "  process for the chosen output format.  This normally means that" >&2
  echo "  for EPS output the vector graphics part must be an EPS file and" >&2
  echo "  for PDF output it must be a PDF file.  (PNG and JPG will also be" >&2
  echo "  accepted for PDF output, though they are -- strictly speaking --" >&2
  echo "  not vector graphics formats)." >&2
  echo >&2
  echo "Simple example: conversion of \`foo.tex'/\`foo.eps' to \`bar.eps'." >&2
  echo "  ${0##*/} foo.tex bar.eps" >&2
  echo >&2
  echo "Complicated example: the font is replaced by 12pt cmbright and the" >&2
  echo "final EPS will have a width of 86mm." >&2
  echo "  ${0##*/} -p cmbright -f 12pt \\" >&2
  echo "    -m '\\includecombinedgraphics[textfont=\\normalsize,vecwidth=86mm]' \\" >&2
  echo "    foo.tex bar.eps" >&2
  echo >&2
  echo "Example for converting other input formats, e.g., EPIC:" >&2
  echo "  ${0##*/} -p epic -m '\\input' -n foo.epic bar.eps" >&2
  echo >&2
  echo "(c) 2007-2009,2011,2012 Christian Schneider." >&2
  echo "Version: ${VERSION}" >&2
  echo "License: GNU GPL v3" >&2
  echo "This is alpha software.  USE ON YOUR OWN RISK." >&2
  echo "Please report bugs to <software(at)chschneider(dot)eu>." >&2
  exit 2
}

########################################################################
# parse command line parameters and do some tests
########################################################################

# parse options
while (( ${#} > 0 )); do
  case "${1}" in
    -h|--help)
      print_help
      ;;
    -v|--version)
      echo "${VERSION}"
      exit
      ;;
    -f|--fontsize)
      shift || exit_error "Font size expected."
      FONTSIZE="${1}"
      ;;
    -p|--packages)
      shift || exit_error "Package name expected."
      PACKAGES="${PACKAGES} ${1}"
      ;;
    -m|--macro)
      shift || exit_error "Macro name expected."
      MACRO="${1}"
      ;;
    -n|--no-skip-ext)
      NOSKIPEXT="true"
      ;;
    -s|--subfiguremark)
      shift || exit_error "Subfigure mark expected."
      SUBFIGUREMARK="${1}"
      ;;
    -r|--relative-pos)
      shift || exit_error "Position of subfigure mark expected."
      SUBFIGUREMARKPOS="${1}"
      ;;
    *)
      if [[ -z "${INFILE}" ]]; then
        INFILE="${1}"
      else
        if [[ -z "${OUTFILE}" ]]; then
          OUTFILE="${1}"
        else
          exit_error "Too many parameters: \`${1}'."
        fi
      fi
      ;;
  esac
  shift
done

# tests for input file
[[ -z "${INFILE}" ]] && exit_error "No parameters specified."
[[ -e "${INFILE}" ]] || exit_error "Input file does not exist."
[[ -f "${INFILE}" ]] || exit_error "Input file is not a regular file."
[[ -r "${INFILE}" ]] || exit_error "Input file not readable."

# tests for output file
[[ -z "${OUTFILE}" ]] && exit_error "Output file not specified."
# to prevent user from overwriting the EPS portion of a combined EPS/LaTeX
[[ -e "${OUTFILE}" ]] && exit_error "Output file \`${OUTFILE}' already exists."
case "${OUTFILE##*.}" in
  eps|pdf)
    ;;
  *)
    exit_error "Output file has unknown extension."
    ;;
esac

########################################################################
# main part
########################################################################

# create secure temporary directory
TMPDIR="$(mktemp -d "tmp.XXXXXX" 2>/dev/null)"
[[ -z "${TMPDIR}" ]] && exit_error "Unable to create temporary directory."

## write LaTeX file
{
  echo '\documentclass'["${FONTSIZE}"']{article}'

  for OP in ${PACKAGES}; do
    if [[ "${OP#[}" == "${OP}" ]]; then
      OP="{${OP}}"
    else
      OP="${OP/]/]{}}"
    fi
    echo '\usepackage'"${OP}"
  done

  echo
  echo '\newbox\myfigbox'
  echo '\def\createfigurebox{%'
  echo '  \setbox\myfigbox=\hbox{%'
if [[ "${NOSKIPEXT}" == "false" ]]; then
  echo '    '"${MACRO}"'{'"${INFILE%.*}"'}%'
else
  echo '    '"${MACRO}"'{'"${INFILE}"'}%'
fi
  echo '  }%'
  echo '}'
  echo '\createfigurebox'
  echo

  if [[ ! -z "${SUBFIGUREMARK}" ]]; then
    echo '\def\subfiguremark#1{\xsubfiguremark%'
    echo '  ['"${SUBFIGUREMARKPOS}"']{'"${SUBFIGUREMARK}"'}{#1}}'
  else
    echo '\def\subfiguremark#1{#1}'
  fi

cat << EOF

%% this is for LaTeX
\paperwidth=\wd\myfigbox
\textwidth=\wd\myfigbox
\paperheight=\ht\myfigbox
\textheight=\ht\myfigbox

%% this is for the output device
\pdfpagewidth=\wd\myfigbox
\pdfpageheight=\ht\myfigbox
\special{papersize=\the\wd\myfigbox,\the\ht\myfigbox}

\pagestyle{empty}

\voffset=-1in
\oddsidemargin=0pt
\evensidemargin=0pt
\marginparwidth=0pt
\marginparpush=0pt
\marginparsep=0pt

\hoffset=-1in
\topmargin=0pt
\headsep=0pt
\headheight=0pt
\topskip=0pt
\footskip=0pt
\parindent=0pt

\makeatletter
\newbox\ud@tempbox
\newdimen\ud@tempheight
\newdimen\ud@tempwidth
\newcommand*{\xsubfiguremark}[3][0,0]{%
  \begingroup%
    \setbox\ud@tempbox=\hbox{#3}%
    \ud@tempheight=\ht\ud@tempbox%
    \ud@tempwidth=\wd\ud@tempbox%
    \unitlength=0.01\ud@tempwidth%
    \setbox\ud@tempbox=\hbox{\raise-\ud@tempheight\box\ud@tempbox}%
    \setbox\ud@tempbox=\hbox{\box\ud@tempbox%
      \begin{picture}(0,0)(100,0)%
        \put(#1){\makebox(0,0)[tl]{#2}}%
      \end{picture}%
    }%
    \setbox\ud@tempbox=\hbox{\raise\ud@tempheight\box\ud@tempbox}%
    \leavevmode\box\ud@tempbox%
  \endgroup%
}
\makeatother

\begin{document}%
   %% do it again (workaround for \rotatebox problem in PDF generation)
  \createfigurebox%
  \subfiguremark{\box\myfigbox}%
\end{document}
EOF
} > "${TMPDIR}/tmp.tex" || exit_error "Unable to write LaTeX file."

## output LaTeX file
echo
echo "##### beginning of debugging output: LaTeX file to be compiled #####"
cat "${TMPDIR}/tmp.tex"
echo "##### end of debugging output: LaTeX file to be compiled #####"
echo

# create (E)PS file
case "${OUTFILE##*.}" in
  eps)
    TEXINPUTS="${INFILE%/*}:.:${TMPDIR}:${TEXINPUTS}" \
      latex -interaction=nonstopmode \
        -output-directory "${TMPDIR}" "${TMPDIR}/tmp.tex" || \
      exit_error "Problem generating the DVI file."
    TEXPICTS="${INFILE%/*}:.:${TMPDIR}:${TEXPICTS}" \
      dvips -o "${TMPDIR}/tmp.eps" "${TMPDIR}/tmp.dvi" || \
      exit_error "Problem generating the EPS file."
    mv "${TMPDIR}/tmp.eps" "${OUTFILE}"
    ;;
  pdf)
    pdflatex -interaction=nonstopmode \
      -output-directory "${TMPDIR}" "${TMPDIR}/tmp.tex" || \
      exit_error "Problem generating the PDF file."
    mv "${TMPDIR}/tmp.pdf" "${OUTFILE}"
    ;;
esac

# clean up
rm -rf "${TMPDIR}"

# finish
exit 0
