%option noyywrap

%x esc

%{
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

void print_char(char);
void handle_code(int);
%}

%%

<esc>[0-9]+\;   { handle_code(strtol(yytext, NULL, 10)); }
<esc>[0-9]+m    { handle_code(strtol(yytext, NULL, 10)); BEGIN INITIAL; }
<esc>.          { printf("unexpected char `%c'\n", *yytext); exit(1); }

\x1b\x5b        { BEGIN esc; }
\n              { printf("\\newline\n"); }
.               { print_char(*yytext); }

%%

bool bold;
enum { none, black, red, green, magenta } color;

void handle_code(int code)
{
        switch(code) {
        case 0:  bold = false; color = none; break;
        case 1:  bold = true; break;
        case 30: color = black; break;
        case 31: color = red; break;
        case 32: color = green; break;
        case 35: color = magenta; break;
        default:
                printf("unexpected code: %d\n", code);
                exit(1);
        }
}

void print_char(char c)
{
        printf("{");

        if (bold && color == black)   printf("\\color{grey}");
        if (bold && color == red)     printf("\\color{red}");
        if (bold && color == green)   printf("\\color{green}");
        if (bold && color == magenta) printf("\\color{magenta}");

        switch (c) {
        case '{':
        case '}':
        case '_':
        case '&':
        case '#':
        case '%':
                /* Character needs escaping. */
                printf("\\%c", c);
                break;
        case '^':
        case '~':
                /* Use character code. */
                printf("\\char`\\%c", c);
                break;
        case ' ':
                /* Space is a special case. */
                printf("\\mbox{ }");
                break;
	case '\\':
		/* Backslash is also special. */
		printf("\\textbackslash");
		break;
        default:
                printf("%c", c);
        }

        printf("}");
}

int main(int argc, char **argv)
{
        bold = false;
        color = none;

        printf("\\begin{minipage}{\\linewidth}\n");
        printf("\\small\\ttfamily\\vspace{1em}");
        yylex();
        printf("\\end{minipage}\n");
        return 0;
}
