#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import pygments
import re
from pygments import highlight
from pygments.lexers import SchemeLexer
from pygments.formatters import HtmlFormatter, LatexFormatter
from pygments.lexer import RegexLexer, bygroups
from pygments.token import *
from pygments.style import Style

#from pygments.styles import STYLE_MAP
#print STYLE_MAP.keys()

class TuplrLexer(RegexLexer):
    name = 'Tuplr'
    aliases = ['tuplr', 'tpr']
    filenames = ['*.tpr']
    mimetypes = ['text/x-tuplr', 'application/x-tuplr']

    keywords = [ 'fn', 'def', 'if', 'match', 'ns', 'type' ]
    builtins = [ 'cons', 'car', 'cdr' ]

    valid_name = r'[.a-zA-Z0-9!$%&*+,/:<=>?@^_~|-]+'

    tokens = {
        'root' : [
            # types
            (r':?[A-Z][a-zA-Z.]*|:\([A-Z][a-zA-Z.\ ]*\)', Keyword.Type),

            # line comments
            (r';.*$', Comment.Single),

            # whitespace
            (r'\s+', Text),

            # numbers
            (r'-?\d+\.\d+', Number.Float),
            (r'-?\d+', Number.Integer),

            # strings, symbols and characters
            (r'"(\\\\|\\"|[^"])*"', String),
            (r"'" + valid_name, String.Symbol),
            (r"#\\([()/'\".'_!ยง$%& ?=+-]{1}|[a-zA-Z0-9]+)", String.Char),

            # constants
            (r'(#t|#f)', Name.Constant),

            # highlight keywords
            ('(%s)' % '|'.join([
                re.escape(entry) + ' ' for entry in keywords]),
                Keyword
            ),

            # highlight builtins
            ("(?<=\()(%s)" % '|'.join([
                re.escape(entry) + ' ' for entry in builtins]),
                Name.Builtin
            ),

            # remaining functions
            (r'(?<=\()' + valid_name, Name.Function),
            
            # remaining variables
            (valid_name, Name.Variable),

            # parenthesis
            (r'(\(|\))', Punctuation),
        ],
    }

class TuplrStyleDark(Style):
    default_style = "#FFF"
    background_color = "#222"
    styles = {
        Comment:                '#79E',
        Keyword:                '#EE5',
        Name:                   '#DDD',
        Text:                   '#DDD',
        String:                 '#F88',
        Keyword.Type:           '#5E5',
        Punctuation:            '#AAA',
        Number:                 '#F88'
    }

class TuplrStyleLight(Style):
    default_style = "#FFF"
    background_color = "#EEE"
    styles = {
        Comment:                '#57C',
        Keyword:                '#AA0',
        Name:                   '#777',
        Text:                   '#777',
        String:                 '#D66',
        Keyword.Type:           '#3C3',
        Punctuation:            '#888',
        Number:                 '#D66'
    }

if len(sys.argv) != 3:
    print 'USAGE: %s IN OUT' % sys.argv[0]
    sys.exit(1)

infile = open(sys.argv[1], 'r')
text = infile.read()
infile.close()


if re.match('.*\.html$', sys.argv[2]):
    style = TuplrStyleDark
    formatter = HtmlFormatter(style=style)
elif re.match('.*\.tex$', sys.argv[2]):
    style = TuplrStyleLight
    formatter = LatexFormatter(style=style)

if re.match('.*\.html$', sys.argv[2]):
    outfile = open(sys.argv[2], 'w')
    print >>outfile, '''<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
      <title>%s</title>
      <style type="text/css">''' % sys.argv[1]
    print >>outfile, formatter.get_style_defs('.highlight')
    print >>outfile, '''  </style>
    </head>
    <body>
    '''
    print >>outfile, highlight(text, TuplrLexer(), formatter)
    print >>outfile, '''</body>
    </html>
    '''
    outfile.close()

if re.match('.*\.tex$', sys.argv[2]):
    outfile = open(sys.argv[2], 'w')
    print >>outfile, '''\\documentclass[10pt]{article}
\\usepackage{fancyvrb}
\\usepackage{color}'''
    print >>outfile, formatter.get_style_defs()
    print >>outfile, '\\newcommand\\PYlambda{$\\lambda$}'
    print >>outfile, '\\newcommand\\PYbiglambda{$\\Lambda$}'
    print >>outfile, '\\begin{document}'
    out = highlight(text, TuplrLexer(), formatter)
    out = out.replace('[fn', '[@PYlambda')
    out = out.replace('[Fn', '[@PYbiglambda')
    print >>outfile, out
    print >>outfile, '\\end{document}'
    outfile.close()