==================================
Install a MathJax Server for ILIAS
==================================

A MathJax server for ILIAS can be installed on every machine that is accessible from the ILIAS server
via HTTP. To run a MathJax server you have to install the following components:

    https://github.com/mathjax/MathJax-node
    https://github.com/tiarno/mathjax-server

You need a MathJax server if you want to support LaTeX in PDF files generated by ILIAS. Depending on the engines you have chosen
in Administration/PDF generation, Mathjax-node must produce different outputs: PhantomJS works with SVG which is supported
by all versions of the MathJax-node, but TCPDF requires PNG images, which are supported up to MathJax-node 0.5.2 with the
additional Apache Batik library:

    https://github.com/mathjax/MathJax-node/releases/tag/0.5.2
    https://xmlgraphics.apache.org/batik/download.html

If you face problems with the following guide, please look at the original documentation
of the components above.

Quick Installation Guide for Linux
----------------------------------

The MathJax server is a node.js application. You can install the main components with the node.js package
manager (npm) that is available in many linux distributions. For example on a Ubuntu system you get
node.js and npm with:

    apt install nodejs
    apt install npm

Please check the installed versions with those required on https://github.com/mathjax/MathJax-node

    node --version
    npm --version

If the versions are older than required, have a look at https://github.com/nodesource/distributions
to see how you can install specific versions not provided by your linux distribution.

Having the correct nodejs and npm versions available, execute the following commands to install the MathJax Server:

    cd /opt
    mkdir mathjax
    cd mathjax

    # If you DON'T NEED PNG then install the newest stable release from GitGub
    npm install mathjax-node
    npm install https://github.com/tiarno/mathjax-server

    # IF you NEED PNG then please install the following versions in this order (to prevent updates to newer versions)
    npm install mathjax@2.7
    npm install mathjax-node@0.5.2
    npm install https://github.com/tiarno/mathjax-server#9c55118d90ae798c26949adae3e435e1670436bb

    # the following link is needed due to an outdated reference in mathjax-server
    cd node_modules
    ln -s mathjax-node MathJax-node

For creating PNG images with MathJax-node 0.5.2 you need to additionally install Apache Batic:

    mkdir /opt/mathjax/node_modules/mathjax-node/batik
    cd /opt/mathjax/node_modules/mathjax-node/batik

Download Batik from http://xmlgraphics.apache.org/batik/download.html and unpack it here
(see README.md in the batik directory):

    wget http://www-eu.apache.org/dist/xmlgraphics/batik/binaries/batik-bin-1.8.zip
    unzip batik-bin-1.8.zip

After upacking you will have a version specific subdirectory, e.g. batik-1.8, and need to create two links:

    ln -s batik-1.8/batik-rasterizer-1.8.jar batik-rasterizer.jar
    ln -s batik-1.8/lib lib

Finally create a javascript file /opt/mathjax/mathjax.js with the following content:

    var server = require('./node_modules/mathjax-server/index.js');
    server.start(8003);

Now start the server on its configured port (8003):

    cd /opt/mathjax
    node mathjax.js

You may also want to create a startup script in /etc/init.d and link it in the run level directories.
See the documentation of your linux distribution for details.
The following startup script is a proposal. It doesn't use a PID file to determine the running status
of the service, because that may conflict with other node.js based services on the same machine. Instead
it starts the service with an own user and group 'mathjax' that have to be created before. The status
check looks for a process with this user.

useradd mathjax
groupadd mathjax
chown -R mathjax:mathjax /opt/mathjax
touch /etc/init.d/mathjax
chmod +x /etc/init.d/mathjax

Edit /etc/init.d/mathjax and copy the following script in it. Adjust DAEMON path if necesessary (whereis node).

#! /bin/sh
### BEGIN INIT INFO
# Provides:          mathjax
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start MathJax server
# Description:       Start and stop the MathJax tex rendering server
### END INIT INFO

# Author: fred.neumann@fau.de

# A pidfile is not created because it may conflict with other node.js services
# Instead the running process is searched by the username (--user)
# Therefore the mathjax user should only be used by this script
# The shell used with --startas is needed for output redirection to the log file
# It will automatically stop when the service terminates

DESC="MathJax server"
NAME=mathjax
DIRECTORY=/opt/mathjax
USER="mathjax"
GROUP="mathjax"
#Set the correct node path! (whereis node)
DAEMON=/usr/bin/node
SCRIPT=/opt/mathjax/mathjax.js
LOGFILE=/var/log/mathjax.log
SCRIPTNAME=/etc/init.d/$NAME

#
# Function that starts the server
#
do_start()
{
        # Ensure that the logfile can be written by the server
        touch $LOGFILE
        chown $USER:$GROUP $LOGFILE

        # Return
        #   0 if daemon has been started
        #   1 if daemon was already running
        #   2 if daemon could not be started
        start-stop-daemon --start --test --exec $DAEMON --user $USER > /dev/null \
                || return 1
        start-stop-daemon --start --background --chuid "$USER:$GROUP" --chdir $DIRECTORY --exec $DAEMON --user $USER \
                --startas /bin/sh \
                -- -c "$DAEMON $SCRIPT >>$LOGFILE 2>&1" \
                || return 2
}

#
# Function that stops the server
#
do_stop()
{
        # Return
        #   0 if daemon has been stopped
        #   1 if daemon was already stopped
        #   2 if daemon could not be stopped
        #   other if a failure occurred
        start-stop-daemon --stop --user $USER
        return $?
}

#
# Handling the call parameters
#
case "$1" in
  start)
        echo "Start $DESC ..."
        do_start
        case "$?" in
                0|1)    echo "* $DESC is running." ;;
                *)      echo "* $DESC could not be started!" ;;
        esac
        ;;
  stop)
        echo "Stop $DESC ..."
        do_stop
        case "$?" in
                0|1)    echo "* $DESC is stopped." ;;
                *)      echo "* $DESC could not be stopped!" ;;
        esac
        ;;
  status)
        if [ `ps --no-headers --user $USER | wc -l` = 0 ]; then
                echo " * $DESC is not running."
        else
                echo " * $DESC is running."
        fi
        ;;
  restart)
        echo  "Restarting $DESC ..."
        do_stop
        case "$?" in
          0|1)
                do_start
                case "$?" in
                        0) echo "* $DESC is restarted." ;;
                        1) echo "* $DESC is still running!" ;;
                        *) echo "* $DESC could not be started!" ;;
                esac
                ;;
          *)
                 echo "* $DESC could not be stopped!"
                ;;
        esac
        ;;
  *)
        echo "Usage: $SCRIPTNAME {start|stop|status|restart}" >&2
        exit 3
        ;;
esac

### End of the script.

Create this script as 'mathjax' in /etc.init.d with excecute permission. Then call the following
command to link it in the runlevel directories:

    update-rc.d mathjax defaults

You may also want to do a periodic check if the server is still running and eventually restart it.
For that purpose create the following script in /etc/cron.hourly with execute permission:

#!/bin/bash
#Set the correct nodepath! (whereis node)
nodepath=/usr/bin/node
scriptpath=/opt/mathjax/mathjax.js

code="${nodepath} ${scriptpath}"

status=$(ps aux | grep ${scriptpath})

if [[ $status == *${code}* ]];
then
    echo "Mathjax is already running...exit now..."
    exit
else
    echo "Mathjax is down...try to start..."
    date >>/var/log/mathjax.log
    /etc/init.d/mathjax start >>/var/log/mathjax.log
fi

### End of the script.
