#!/bin/sh
#  _   _ _         _ 
# | |_(_) | __ ___| |_ ___  _____   ____ _ 
# | __| | |/ /|_  / __/ _ \/ __\ \ / / _` |
# | |_| |   <  / /| || (_) \__ \\ V / (_| |
#  \__|_|_|\_\/___|\__\___/|___/ \_/ \__, |
#                                    |___/
# 2021 (C) Pablo
# Free use of this software is granted under the terms of the GPL-3.0 License

puts() 
{
  printf "\033[1m\033[38;5;%sm[%s]\033[m %s\n" "$3" "$1" "$2"
}

error()
{
  puts "ERROR" "$1" "9"

  if [ -n "$2" ]
  then
    exit "$2"
  else
    exit 1
  fi
}

message()
{
  puts "TIKZTOSVG" "$1" "2"
}

showHelp()
{
  man tikztosvg
  exit 0
}

showVersion()
{
  echo 0.3.0
  exit 0
}

# The default list of packages and libraries that should be imported
packages="tikz tikz-cd pgfplots amsmath amssymb"
libraries=""

# The default TeX engine
texengine='lualatex'

# Parsing the arguments
while [ $# -gt 1 ]
do
  case "$1" in
    -h|--help)
      showHelp
      ;;
    -v|--version)
      showVersion
      ;;
    -p|--package)
      case "$2" in
        "")
          error "Unnexpected EOF"
          ;;
        # Check if the name of the package is valid
        *" "*) 
          error "Invalid package name. LaTeX package names cannot contain scapes!" 
          ;;
        *)
          packages="$packages $2"
          shift
          shift
      esac
      ;;
    -l|--library)
      case "$2" in
        "")
          error "Unnexpected EOF"
          ;;
        # Check if the name of the package is valid
        *" "*) 
          error "Invalid library name. TikZ library names cannot contain scapes!" 
          ;;
        *)
          libraries="$libraries $2"
          shift
          shift
      esac
      ;;
    -o|--output)
      if [ -n "$output" ]
      then
        error "The output path was specified multiple times"
      elif [ -z "$2" ]
      then
        error "Unexpected EOF"
      else
        output="$2"
        shift
        shift
      fi
      ;;
    -q|--quit)
      quiet=1
      shift
      ;;
    --lualatex)
      shift
      ;;
    --xelatex)
      if command -v xelatex > /dev/null
      then
        texengine='xelatex'
      else
        error "Couldn't find xelatex: required by the --xelatex option"
      fi
      shift
      ;;
    --pdflatex)
      if command -v pdflatex > /dev/null
      then
        texengine='pdflatex'
      else
        error "Couldn't find pdflatex: required by the --pdflatex option"
      fi
      shift
      ;;
    *) 
      error "Unexpected token: \"$1\""
      ;;
  esac
done

case "$1" in
  -h|--help)
    showHelp
    ;;
  -v|--version)
    showVersion
    ;;
  '')
    error "No input path provided"
    ;;
  -)
    input=/dev/stdin
    ;;
  *)
    input="$1"
    ;;
esac

case "$output" in
  # Set the output to stdout
  -)
    quiet=1
    output=/dev/stdout
    ;;

  # If no output path is provided, use the basename of the input
  '') 
    output="$(dirname "$input")/$(basename "$input" | cut -d "." -f1).svg" 
    ;;

  # If the output path is provided, but it resolves to directory, output a 
  # a file with the same basename as the input in the target directory
  */) 
    output="$output$(basename "$input" | cut -d "." -f1).svg" 
    ;;
esac

tmp_dir="$(mktemp -d)"
tex_file="$tmp_dir/tmp.tex"

# Generate the LaTeX document
printf '\\documentclass[crop,tikz,multi=false]{standalone}\n' > "$tex_file"

for package in $packages
do
  printf '\\usepackage{%s}\n' "$package" >> "$tex_file"
done

for library in $libraries
do
  printf '\\usetikzlibrary{%s}\n' "$library" >> "$tex_file"
done

printf '\\begin{document}\n' >> "$tex_file"


if ! cat "$input" >> "$tex_file"
then
  rm "$tmp_dir" -r
  error "File not found: $input"
fi

printf "\\\end{document}\n" >> "$tex_file"

if [ -z "$quiet" ]
then
  message "Rendering the LaTeX document. . ."
  $texengine -halt-on-error -output-directory="$tmp_dir" "$tex_file"
else
  $texengine -halt-on-error -output-directory="$tmp_dir" "$tex_file" 1> /dev/null 2>&1
fi

# TODO: Make this less horrible?
S=$?
if [ $S -ne 0 ]
then
  rm "$tmp_dir" -r
  if [ -z "$quiet" ]
  then
    error "$texengine exited with code $S" $S
  else
    exit $S
  fi
fi

if [ -z "$quiet" ]
then
  message "Converting the output to SVG. . ."
fi

pdf2svg "$tmp_dir/tmp.pdf" "$output" 1

# TODO: Make this less horrible?
S=$?
if [ $S -ne 0 ]
then
  rm "$tmp_dir" -r
  if [ -z "$quiet" ]
  then
    error "pdf2svg exited with code $S" $S
  else
    exit $S
  fi
fi

if [ -z "$quiet" ]
then
  message "Done!"
fi

rm "$tmp_dir" -rf