-- convert peu source into html format

--Handles of the controls
atom  Browse,save,useCSS,saveCSSfile,convert
sequence in, out
in = {}
out = {}
integer use_css,create_css_file

global constant -- needed for syncolor.e
        NORMAL_COLOR  = 1,
        COMMENT_COLOR = 2,
        KEYWORD_COLOR = 3,
        BUILTIN_COLOR = 4,
        STRING_COLOR  = 5,
        BRACKET_COLOR = {6, 7, 8}

include keywordp.e
include syncolor.e

constant
        tags =
                {
                "", -- normal
                "<font color=\"#FF0055\">", -- comment
                "<font color=\"#0000FF\">", -- keyword
                "<font color=\"#FF00FF\">", -- builtin
                "<font color=\"#00A033\">", -- string
                "<font color=\"#993333\">", -- bracket #1
                "<font color=\"#330033\">", -- bracket #2
                "<font color=\"#0000FF\">"  -- bracket #3
                },
        end_tags =
                {""} & repeat("</font>",length(tags)-1), -- same for all
        tags_css =
                {
                "", -- normal, nothing needed
                "<span class=comment>",  -- comment
                "<span class=keyword>",  -- keyword
                "<span class=builtin>",  -- builtin
                "<span class=string>",   -- string
                "<span class=bracket1>", -- bracket #1
                "<span class=bracket2>", -- bracket #2
                "<span class=bracket3>"  -- bracket #3
                },
        end_tags_css =
                {""} & repeat("</span>",length(tags_css)-1) -- same for all

constant
        DOCTYPE = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Final//EN\">\n",
        REST =
                "<body>\n" &
                "<!-- Generated with eu2html by Martin Stachon -->\n" &
                "<code>\n" &
                "<pre>\n",
        HEADER =
                DOCTYPE &
                "<html>\n" &
                REST,
        CSS_FILE =
                ".comment  {color:#FF0055}\n"&
                ".keyword  {color:#0000FF}\n"&
                ".builtin  {color:#FF00FF}\n"&
                ".string   {color:#00A033}\n"&
                ".bracket1 {color:#993333}\n"&
                ".bracket2 {color:#330033}\n"&
                ".bracket3 {color:#0000FF}\n",
        CSS_STYLE=
                ".comment  {color:#808080;font-weight:bold}\n"&
                ".keyword  {color:green;font-weight:bold}\n"&
                ".builtin  {color:brown;font-weight:bold}\n"&
                ".string   {color:blue;font-weight:bold}\n"&
                ".bracket1 {color:#ff00ff;font-weight:bold}\n"&
                ".bracket2 {color:#ff0f00;font-weight:bold}\n"&
                ".bracket3 {color:#00FFFF;font-weight:bold}\n",
        HEADER_CSS =
                DOCTYPE &
                "<html>\n" &
                "<head>\n" &
                "<style>\n" &
                "<!--\n" & -- comment it, so old
                CSS_STYLE &
                "-->\n" & -- broswers will ignore this
                "</style>\n" &
                "</head>\n" &
                REST,
        HEADER_CSS_FILE =
                DOCTYPE &
                "<html>\n" &
                "<head>\n" &
                "<link rel=\"stylesheet\" type=\"text/css\" href=\"euphoria.css\">"&
                "</head>" &
                REST,
        FOOTER =
                "\n</pre>\n" &
                "</code>\n" &
                "</body>\n" &
                "</html>"

use_css         = 0
create_css_file = 0
--***************************************************************************

function detag(sequence line)
        -- convert <> to < > in Eu code,
        -- so they cannot be interpreted as HTML tags
        sequence result
        result = ""
        for i=1 to length(line) do
                if    line[i] = '<' then result &= "<"
                elsif line[i] = '>' then result &= ">"
                else  result &= line[i]
                end if
        end for
        return result
end function

function process_line(sequence line)
        sequence result,col
        result = ""
        col = SyntaxColor(line)
        if use_css then
                for i=1 to length(col) do
                        result &= tags_css[col[i][1]] & detag(col[i][2]) & end_tags_css[col[i][1]]
                end for
        else
                for i=1 to length(col) do
                        result &= tags[col[i][1]] & detag(col[i][2]) & end_tags[col[i][1]]
                end for
        end if
        result &= '\n'
        return result
end function

procedure process_file(integer in, integer out)
        object line
        sequence html_line
        integer counter
        counter = 0
        if use_css then
                if create_css_file then
                        puts(out, HEADER_CSS_FILE)
                else
                        puts(out, HEADER_CSS)
                end if
        else
                puts(out, HEADER)
        end if
        while 1 do
                line = gets(in)
                if atom(line) then exit end if
                if line[length(line)] != '\n' then line &= '\n' end if
                html_line = process_line(line)
                puts(out, html_line)
        end while
end procedure

procedure main(sequence infile;outfile)
        integer in_fn, out_fn, css_fn

        in_fn = open(infile, "r")
        if in_fn = -1 then
                puts(1,"Error : Cannot open input file!\n")
                abort(1)
        end if
        
        out_fn = open(outfile, "w")
        
        if out_fn = -1 then
                puts(1,"Error : Cannot open output file!\n")
                abort(1)
        end if
        if create_css_file and use_css then
                css_fn = open("euphoria.css", "w")
                puts(css_fn, CSS_FILE)
                close(css_fn)
        end if
        init_class() -- syncolor init
        process_file(in_fn, out_fn)
        close(in_fn)
        puts(out_fn,FOOTER)
        close(out_fn)
        puts(1,"Done!\n")
end procedure

use_css=1
--create_css_file=1

-- main program
sequence cmd=command_line()
-- check if bind version
if match("peu",cmd[1])
then -- interpreter
 if length(cmd)<4
 then puts(1,"Use : peu eu2html source output\n") abort(1)
 else main(cmd[3],cmd[4])
 end if
else -- bind
 if length(cmd)<3
 then puts(1,"Use : peu eu2html source output\n") abort(1)
 else main(cmd[2],cmd[3])
 end if
end if
abort(0)