#!/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 RespLexer(RegexLexer):
    name = 'Resp'
    aliases = ['resp']
    filenames = ['*.resp']
    mimetypes = ['text/x-resp', 'application/x-resp']

    keywords = [ 'def', 'def-type', 'fn', 'if', 'let', 'match' ]
    builtins = [ 'Tup' ]

    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 RespStyleDark(Style):
    default_style = "#FFF"
    background_color = "#222"
    styles = {
        Comment:                '#9BF',
        Keyword:                '#AFA',
        Name:                   '#DDD',
        Text:                   '#DDD',
        String:                 '#F88',
        Keyword.Type:           '#BCE',
        Punctuation:            '#AAA',
        Number:                 '#F88'
    }

class RespStyleLight(Style):
    default_style = "#FFF"
    background_color = "#EEE"
    styles = {
        Comment:                '#36A',
        Keyword:                '#181',
        Name:                   '#000',
        Text:                   '#000',
        String:                 '#944',
        Keyword.Type:           '#236',
        Punctuation:            '#111',
        Number:                 '#944'
    }

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 = RespStyleDark
    formatter = HtmlFormatter(style=style)
elif re.match('.*\.tex$', sys.argv[2]):
    style = RespStyleLight
    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, '''.highlight { margin: 0; padding: 1ex; border-width: 0; }</style>
    </head>
    <body>
    '''
    print >>outfile, highlight(text, RespLexer(), 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, RespLexer(), formatter)
    out = out.replace('[fn', '[@PYlambda')
    out = out.replace('[Fn', '[@PYbiglambda')
    print >>outfile, out
    print >>outfile, '\\end{document}'
    outfile.close()