"""
This module supports embedded TeX expressions in matplotlib via dvipng
and dvips for the raster and postscript backends.  The tex and
dvipng/dvips information is cached in ~/.matplotlib/tex.cache for reuse between
sessions

Requirements:

* latex
* \*Agg backends: dvipng
* PS backend: latex w/ psfrag, dvips, and Ghostscript 8.51
  (older versions do not work properly)

Backends:

* \*Agg
* PS
* PDF

For raster output, you can get RGBA numpy arrays from TeX expressions
as follows::

  texmanager = TexManager()
  s = ('\\TeX\\ is Number '
       '$\\displaystyle\\sum_{n=1}^\\infty\\frac{-e^{i\pi}}{2^n}$!')
  Z = self.texmanager.get_rgba(s, size=12, dpi=80, rgb=(1,0,0))

To enable tex rendering of all text in your matplotlib figure, set
text.usetex in your matplotlibrc file (http://matplotlib.sf.net/matplotlibrc)
or include these two lines in your script::

  from matplotlib import rc
  rc('text', usetex=True)

"""

from __future__ import print_function

import copy
import glob
import os
import shutil
import sys
import warnings

from hashlib import md5

import distutils.version
import numpy as np
import matplotlib as mpl
from matplotlib import rcParams
from matplotlib._png import read_png
from matplotlib.cbook import mkdirs
from matplotlib.compat.subprocess import Popen, PIPE, STDOUT
import matplotlib.dviread as dviread
import re

DEBUG = False

if sys.platform.startswith('win'):
    cmd_split = '&'
else:
    cmd_split = ';'


def dvipng_hack_alpha():
    try:
        p = Popen(['dvipng', '-version'], stdin=PIPE, stdout=PIPE,
                  stderr=STDOUT, close_fds=(sys.platform != 'win32'))
    except OSError:
        mpl.verbose.report('No dvipng was found', 'helpful')
        return False
    stdin, stdout = p.stdin, p.stdout
    for line in stdout:
        if line.startswith(b'dvipng '):
            version = line.split()[-1]
            mpl.verbose.report('Found dvipng version %s' % version,
                               'helpful')
            version = version.decode('ascii')
            version = distutils.version.LooseVersion(version)
            return version < distutils.version.LooseVersion('1.6')
    mpl.verbose.report('Unexpected response from dvipng -version', 'helpful')
    return False


class TexManager:
    """
    Convert strings to dvi files using TeX, caching the results to a
    working dir
    """

    oldpath = mpl.get_home()
    if oldpath is None:
        oldpath = mpl.get_data_path()
    oldcache = os.path.join(oldpath, '.tex.cache')

    cachedir = mpl.get_cachedir()
    if cachedir is not None:
        texcache = os.path.join(cachedir, 'tex.cache')
    else:
        # Should only happen in a restricted environment (such as Google App
        # Engine). Deal with this gracefully by not creating a cache directory.
        texcache = None

    if os.path.exists(oldcache):
        if texcache is not None:
            try:
                shutil.move(oldcache, texcache)
            except IOError as e:
                warnings.warn('File could not be renamed: %s' % e)
            else:
                warnings.warn("""\
Found a TeX cache dir in the deprecated location "%s".
    Moving it to the new default location "%s".""" % (oldcache, texcache))
        else: