"Python utility functions for use by Rivet scripts (and anyone else who wants to)"

def set_process_name(name):
    "Try to rename the process on Linux so it doesn't appear as 'python <scriptpath>'"
    try:
        ## Try to use this: https://code.google.com/p/py-setproctitle/
        import setproctitle
        setproctitle.setproctitle(name)
    except:
        try:
            ## Fall back to a by-hand thing that doesn't work for me...
            import ctypes
            libc = ctypes.cdll.LoadLibrary("libc.so.6")
            libc.prctl(15, name, 0, 0, 0)
        except:
            ## And then give up ;-)
            pass


def import_ET():
    "Try to import the ElementTree XML parser, which has many historical import signatures"
    ET = None
    try:
        import xml.etree.cElementTree as ET
    except ImportError:
        try:
            import cElementTree as ET
        except ImportError:
            try:
                import xml.etree.ElementTree as ET
            except:
                raise ImportError("Can't load the ElementTree XML parser (any of three historical ways)")
    return ET


def htmlify(s, para=False):
    """Modify LaTeX text strings from analysis metadata for inclusion
    in MathJax-enabled web page source code."""
    if not s:
        return s
    t = s.replace("&", "&amp;")\
        .replace("<","&lt;")\
        .replace(">","&gt;")\
        .replace(r"~", " ")
    t = t.replace(r"\pT", r"p_\perp")\
        .replace(r"\degree", r"^\circ")\
        .replace(r"\MeV", r"\text{MeV}")\
        .replace(r"\GeV", r"\text{GeV}")\
        .replace(r"\TeV", r"\text{TeV}")
    # t = t.replace(r"\;", " ")\
    #     .replace(r"\,", " ")\
    #     .replace(r"\!", "")
    if para:
        t = t.replace("\n\n", "</p><p>")
    return t


def texify(s):
    "Insert required TeX escapes"
    if not s:
        return s
    t = s \
        .replace(r"&", r"\&") \
        .replace(r"\\&", r"\&") \
        .replace(r"#", r"\#") \
        # .replace(r"_", r"\_") \
        # .replace(r"^", r"") \
    return t


def texpand(s):
    "Expand some physics-specific TeX macros."
    if not s:
        return s
    t = s \
        .replace(r"\kT", r"\ensuremath{k_\perp}\xspace") \
        .replace(r"\kt", r"\ensuremath{k_\mathrm{T}}\xspace") \
        .replace(r"\pT", r"\ensuremath{p_\perp}\xspace") \
        .replace(r"\pt", r"\ensuremath{p_\mathrm{T}}\xspace") \
        .replace(r"\sqrts", r"\ensuremath{\sqrt{s}}\xspace") \
        .replace(r"\sqrtS", r"\ensuremath{\sqrt{s}}\xspace") \
        .replace(r"\MeV", r"\text{M\eV}\xspace") \
        .replace(r"\GeV", r"\text{G\eV}\xspace") \
        .replace(r"\TeV", r"\text{T\eV}\xspace") \
        .replace(r"\eV", r"\text{e\kern-0.15ex{}V}\xspace")
    return t


def _detex(t):
    t = t.replace(r"\rm", "")
    t = t.replace(r"\it", "")
    t = t.replace(r"\boldmath", "")
    t = t.replace(r"\mathrm{", "{")
    t = t.replace(r"\text{", "{")
    t = t.replace(r"\MeV", "MeV")
    t = t.replace(r"\GeV", "GeV")
    t = t.replace(r"\TeV", "TeV")
    t = t.replace(r"~", " ")
    t = t.replace(r"\,", " ")
    t = t.replace(r"\;", " ")
    t = t.replace(r"\!", "")
    try:
        import pydetex.parsers as pdtp
        #t = texpand(t)
        t = pdtp.unicode_chars_equations(t)
    except:
        t = t.replace("{", "")
        t = t.replace("}", "")
    t = t.replace("$", "")
    return t


def detex(tex):
    """Use pydetex (if available) to modify LaTeX text strings from
    analysis metadata for use as plain text, e.g. as printed to the terminal.

    The argument can either be a string or an iterable of strings.
    """
    if not tex:
        return tex
    import sys
    if sys.version_info[0] < 3:
        # We don't handle non-ASCII chars in Python2 anymore
        return tex

    # from distutils.spawn import find_executable
    # if not find_executable("pandoc"):
    #     return tex

    try:
        tex_is_str = type(tex) in (unicode,str)
    except NameError: # for py3
        tex_is_str = type(tex) is str

    # texheader = r"""
    # \newcommand{\text}[1]{#1}
    # \newcommand{\ensuremath}[1]{#1}
    # \newcommand{\emph}[1]{_#1_}
    # \newcommand{\textrm}[1]{#1}
    # \newcommand{\textit}[1]{_#1_}
    # \newcommand{\textbf}[1]{*#1*}
    # \newcommand{\mathrm}[1]{#1}
    # \newcommand{\mathit}[1]{_#1_}
    # \newcommand{\mathbf}[1]{*#1*}
    # \newcommand{\bm}[1]{*#1*}
    # \newcommand{\frac}[2]{#1/#2}
    # \newcommand{\sqrt}[1]{sqrt(#1)}
    # \newcommand{\hat}[1]{#1hat}
    # \newcommand{\bar}[1]{#1bar}
    # \newcommand{\d}[1]{d#1}
    # \newcommand{\degree}{^\circ }
    # \newcommand{\infty}{oo }
    # \newcommand{\exp}{exp }
    # \newcommand{\log}{log }
    # \newcommand{\ln}{ln }
    # \newcommand{\sin}{sin }
    # \newcommand{\cos}{cos }
    # \newcommand{\tan}{tan }
    # \newcommand{\sinh}{sinh }
    # \newcommand{\cosh}{cosh }
    # \newcommand{\tanh}{tanh }
    # \newcommand{\ell}{l}
    # \newcommand{\varphi}{\phi}
    # \newcommand{\varepsilon}{\epsilon}
    # \newcommand{\sim}{~}
    # \newcommand{\lesssim}{<~ }
    # \newcommand{\gtrsim}{>~ }
    # \newcommand{\neq}{!= }
    # \newcommand{\ge}{>= }
    # \newcommand{\gg}{>> }
    # \newcommand{\le}{<= }
    # \newcommand{\ll}{<< }
    # \newcommand{\pm}{+- }
    # \newcommand{\mp}{-+ }
    # \newcommand{\times}{x }
    # \newcommand{\cdot}{. }
    # \newcommand{\dots}{... }
    # \newcommand{\ldots}{... }
    # \newcommand{\langle}{<}
    # \newcommand{\rangle}{>}
    # \newcommand{\gets}{<- }
    # \newcommand{\to}{-> }
    # \newcommand{\leftarrow}{<- }
    # \newcommand{\rightarrow}{-> }
    # \newcommand{\leftrightarrow}{<-> }
    # \newcommand{\Leftarrow}{<= }
    # \newcommand{\Rightarrow}{=> }
    # \newcommand{\Leftrightarrow}{ }
    # \newcommand{\left}{}
    # \newcommand{\right}{}
    # \newcommand{\!}{}
    # \newcommand{\/}{}
    # \newcommand{\rm}{}
    # \newcommand{\it}{}
    # \newcommand{\,}{ }
    # \newcommand{\;}{ }
    # \newcommand{\ }{ }
    # \newcommand{\unit}[2]{#1 #2}
    # \newcommand{\bar}[1]{#1bar}
    # \newcommand{\pT}{pT }
    # \newcommand{\perp}{T}
    # \newcommand{\ast}{*}
    # \newcommand{\MeV}{MeV }
    # \newcommand{\GeV}{GeV }
    # \newcommand{\TeV}{TeV }
    # """
    # import subprocess
    # pandoc_cmd = ['pandoc','-f','latex','-t','plain','--wrap=none']
    # ### check we have the right wrap option ###
    # x = subprocess.Popen(pandoc_cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    # out, err = x.communicate(b' ')
    # x = x.wait()
    # if x != 0:
    #     pandoc_cmd[-1] = '--no-wrap'
    # texbody = tex if tex_is_str else " @@ ".join(tex)
    # p = subprocess.Popen(pandoc_cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    # # texbody = texbody.replace("$", "")
    # # pandoc reads in UTF-8, need to encode / decode correctly
    # plain, err = p.communicate((texheader + texbody).replace("\n", "").encode('utf-8'))
    # ret = p.wait()
    # if ret != 0:
    #     return tex
    # # pandoc sends UTF-8, need to decode
    # plain = plain.decode('utf-8')
    # plain = plain.replace("\n", "")
    # plain = plain.replace(r"\&", "&")
    # plains = plain.split(" @@ ")

    if tex_is_str:
        return _detex(tex)
    else:
        ss = [_detex(t) for t in tex]
        return ss

# print detex(r"Foo \! $\int \text{bar} \d{x} \sim \; \frac{1}{3} \neq \emph{foo}$ \to \gg bar")
# print detex([r"Foo \! $\int \text{bar} \d{x} \sim", r"\frac{1}{3} \neq \emph{foo}$ \to \gg bar"])
