/*
    This program does syntax colouring on PL/SQL for display on the web;
    it also supports code folding by means of special embedded comments.

    The conventions are the same as for my similar C to HTML filter; this
    source is encoded using the C filter.  Any comments in dark green
    are actually 'folds' and can be expanded by clicking on them.
 */

#include <stdio.h>

« Constants »
#define QUOTE_COLOR "#ff0000" #define COMMENT_COLOR "#408080" #define FOLD_COLOR "#205050" #ifndef FALSE #define TRUE (0==0) #define FALSE (0!=0) #endif
char *Reserved_Words[] = { « Table of keywords »
"ACCESS", "ELSEIF", "PUBLIC", "ADD", "END", "RAISE", "ALL", "ENTRY", "RANGE", "ALTER", "EXCEPTION", "REAL", "AND", "EXCEPTION_INIT", "RECORD", "ANY", "EXISTS", "RELEASE", "ARRAY", "EXIT", "REM", "ARRAYLEN", "FALSE", "RENAME", "AS", "FETCH", "RESOURCE", "ASC", "FLOAT", "RETURN", "ASSERT", "FOR", "REVERSE", "ASSIGN", "FORM", "REVOKE", "AT", "FORMAT", "ROLLBACK", "AUTHORIZATION", "FROM", "ROWID", "BASE_TABLE", "FUNCTION", "ROWLABEL", "BEGIN", "GENERIC", "ROWNUM", "BETWEEN", "GOTO", "ROWTYPE", "BINARY_INTEGER", "GRANT", "RUN", "BODY", "GROUP", "SAVEPOINT", "BOOLEAN", "HAVING", "SCHEMA", "BY", "IDENTIFIED", "SELECT", "CASE", "IF", "SEPARATE", "CHAR", "IN", "SET", "CHAR_BASE", "INDEX", "SIZE", "CHECK", "INDEXES", "SMALLINT", "CLOSE", "INDICATOR", "SPACE", "CLUSTER", "INSERT", "SPOOL", "CLUSTERS", "INTEGER", "SQL", "COLAUTH", "INTERSECT", "SQLCODE", "COLUMN", "INTO", "SQLERRM", "COLUMNS", "IS", "START", "COMMIT", "LEVEL", "STATEMENT", "COMPRESS", "LIKE", "SUBTYPE", "CONNECT", "LIMITED", "TABAUTH", "CONSTANT", "LOOP", "TABLE", "CRASH", "MINUS", "TABLES", "CREATE", "MLSLABEL", "TABLESPACE", "CURRENT", "NATURAL", "TASK", "CURRVAL", "NEW", "TERMINATE", "CURSOR", "NEXTVAL", "THEN", "DATA_BASE", "NOCOMPRESS", "TO", "DATABASE", "NOT", "TRUE", "DATE", "NULL", "TYPE", "DBA", "NUMBER", "UNFORMAT", "DEBUGOFF", "NUMBER_BASE", "UNION", "DEBUGON", "OF", "UNIQUE", "DECIMAL", "ON", "UPDATE", "DECLARE", "OPEN", "USE", "DEFAULT", "OPTION", "VALUES", "DEFINITION", "OR", "VARCHAR", "DELAY", "ORDER", "VARCHAR2", "DELETE", "OTHERS", "VIEW", "DELTA", "OUT", "VIEWS", "DESC", "PACKAGE", "WHEN", "DIGITS", "PARTITION", "WHERE", "DISPOSE", "PCTFREE", "WHILE", "DISTINCT", "POSITIVE", "WITH", "DO", "PRAGMA", "WORK", "DROP", "PRIOR", "XOR", /* Additions by GT: */ "REPLACE", "PROCEDURE", "ELSE", "ELSIF", "PLS_INTEGER", "ROWCOUNT", "ISOPEN", "FORALL", NULL
}; int IsReservedWord(char *word) { « Is this a keyword to be printed bold? »
} « Support stuff for folding »
static int suppress_newline_hack = FALSE; // An unfortunate hack due to the way <div> inserts an extra blank line. void printchar (char inchar) « quote '<' and '&' with entity references on output. Note that fold descriptors like this comment do not go through this procedure, therefore embedded HTML is allowed! (Useful for embedded diagrams) »
void PrintHeader (void) « Output Javascript and CSS to the header section »
{ « First the Javascript - comes from http://www.netlobo.com/div_hiding.html »
fprintf (stdout, "<script type=\"text/javascript\">\n"); fprintf (stdout, "<!--\n"); fprintf (stdout, "function toggleLayer( whichLayer, summary )\n"); fprintf (stdout, "{\n"); fprintf (stdout, " var elem, vis;\n"); fprintf (stdout, " if( document.getElementById ) // this is the way the standards work\n"); fprintf (stdout, " elem = document.getElementById( whichLayer );\n"); fprintf (stdout, " else if( document.all ) // this is the way old msie versions work\n"); fprintf (stdout, " elem = document.all[whichLayer];\n"); fprintf (stdout, " else if( document.layers ) // this is the way nn4 works\n"); fprintf (stdout, " elem = document.layers[whichLayer];\n"); fprintf (stdout, " vis = elem.style;\n"); fprintf (stdout, " // if the style.display value is blank we try to figure it out here\n"); fprintf (stdout, " if(vis.display==''&&elem.offsetWidth!=undefined&&elem.offsetHeight!=undefined)\n"); fprintf (stdout, " vis.display = (elem.offsetWidth!=0&&elem.offsetHeight!=0)?'block':'none';\n"); fprintf (stdout, " vis.display = (vis.display==''||vis.display=='block')?'none':'block';\n"); fprintf (stdout, "\n"); fprintf (stdout, " if( document.getElementById ) // this is the way the standards work\n"); fprintf (stdout, " elem = document.getElementById( summary );\n"); fprintf (stdout, " else if( document.all ) // this is the way old msie versions work\n"); fprintf (stdout, " elem = document.all[summary];\n"); fprintf (stdout, " else if( document.layers ) // this is the way nn4 works\n"); fprintf (stdout, " elem = document.layers[summary];\n"); fprintf (stdout, " vis = elem.style;\n"); fprintf (stdout, " // if the style.display value is blank we try to figure it out here\n"); fprintf (stdout, " if(vis.display==''&&elem.offsetWidth!=undefined&&elem.offsetHeight!=undefined)\n"); fprintf (stdout, " vis.display = (elem.offsetWidth!=0&&elem.offsetHeight!=0)?'block':'none';\n"); fprintf (stdout, " vis.display = (vis.display==''||vis.display=='block')?'none':'block';\n"); fprintf (stdout, "}\n"); fprintf (stdout, "// -->\n"); fprintf (stdout, "</script>\n"); fprintf (stdout, "\n");
« And then the CSS - derived from Tim Wakeham's page »
fprintf (stdout, "<style>\n"); fprintf (stdout, ".hidecode {\n"); fprintf (stdout, " z-index:99;\n"); fprintf (stdout, " visibility:hidden;\n"); fprintf (stdout, "}\n"); fprintf (stdout, "\n"); fprintf (stdout, ".file {\n"); fprintf (stdout, "}\n"); fprintf (stdout, "\n"); fprintf (stdout, ".file div {\n"); fprintf (stdout, " margin: auto;\n color: #000000;\n"); fprintf (stdout, "}\n"); fprintf (stdout, "\n"); fprintf (stdout, "div p {\n"); fprintf (stdout, " margin-left: 15px;\n color: #000000;\n"); fprintf (stdout, "}\n"); fprintf (stdout, "\n"); fprintf (stdout, "body {\n"); fprintf (stdout, " font-family: Calibri, Arial, Georgia, \"Times New Roman\", Times, serif;\n"); fprintf (stdout, " color: #000000;\n"); fprintf (stdout, "}\n\n"); fprintf (stdout, "h2, h3 {\n"); fprintf (stdout, " margin-bottom: 0px;\n color: #000000;\n"); fprintf (stdout, " }\n"); fprintf (stdout, "\n"); fprintf (stdout, "p {\n color: #000000;\n"); fprintf (stdout, "}\n"); fprintf (stdout, "\n"); fprintf (stdout, "h2 {\n color: #000000;\n"); fprintf (stdout, " }\n"); fprintf (stdout, "\n"); fprintf (stdout, "h2 .link {\n"); fprintf (stdout, " font-size: small;\n color: #000000;\n"); fprintf (stdout, "}\n"); fprintf (stdout, "\n"); fprintf (stdout, ".link a {\n"); fprintf (stdout, " text-decoration: none;\n outline: none;\n"); fprintf (stdout, "}\n"); fprintf (stdout, "\n"); fprintf (stdout, "h2 .link a:hover {\n"); fprintf (stdout, " text-decoration: none;\n"); fprintf (stdout, " }\n"); fprintf (stdout, "\n"); fprintf (stdout, ".data {\n"); fprintf (stdout, " display: none;\n color: #000000;\n"); fprintf (stdout, "}\n"); fprintf (stdout, "\n"); fprintf (stdout, ".data pre {\n"); fprintf (stdout, " overflow: auto;\n color: #000000;\n"); fprintf (stdout, "}\n"); fprintf (stdout, "\n"); fprintf (stdout, ".data p {\n"); fprintf (stdout, " margin-top: 0px;\n color: #000000;\n"); fprintf (stdout, "}\n"); fprintf (stdout, "\n"); fprintf (stdout, ".summary {\n color: #000000;\n"); fprintf (stdout, "}\n"); fprintf (stdout, "\n"); fprintf (stdout, ".summary pre {\n"); fprintf (stdout, " overflow: auto;\n color: #000000;\n"); fprintf (stdout, "}\n"); fprintf (stdout, "\n"); fprintf (stdout, ".summary p {\n"); fprintf (stdout, " margin-top: 0px;\n color: #000000;\n"); fprintf (stdout, "}\n"); fprintf (stdout, "\n"); fprintf (stdout, ".summary a {\n"); /* not sure... */ fprintf (stdout, " text-decoration: none;\n outline: none;\n"); fprintf (stdout, "}\n"); fprintf (stdout, "\n"); fprintf (stdout, ".show {\n"); fprintf (stdout, " text-decoration: none;\n color: #000000;\n"); fprintf (stdout, "}\n"); fprintf (stdout, "\n"); fprintf (stdout, ".show:hover {\n"); fprintf (stdout, " text-decoration: none;\n"); fprintf (stdout, "}\n"); fprintf (stdout, "\n"); fprintf (stdout, ".flinks {\n"); fprintf (stdout, " text-decoration: none;\n color: #000000;\n"); fprintf (stdout, "}\n"); fprintf (stdout, "\n"); fprintf (stdout, ".flinks:hover {\n"); fprintf (stdout, " text-decoration: none;\n color: #000000;\n"); fprintf (stdout, "}\n"); fprintf (stdout, "\n"); fprintf (stdout, "\n"); fprintf (stdout, "\n"); fprintf (stdout, "</style>\n");
}
« Four procedures to output DHTML <div>s to hide/display the nested layers »
int main(int argc, char **argv) { #define NEXTCH {c = fgetc(stdin); \ pend = fgetc(stdin); \ ungetc(pend, stdin); \ } int c = -1, pend = -1, lastch; // HTML header printf("<html><head><title></title>"); PrintHeader(); printf("</head><body><PRE>"); for (;;) { lastch = c; NEXTCH; // C is always the current character, pend is what you will read next. « Loop over input, output it to HTML on stdout »
if (c == EOF) { // end of html break; } else if (lastch == '\n' && c == '/' && pend == '\n') { printf("<HR>\n"); } else if (c == '/' && pend == '*') { « handle C comment *AND FOLDING DIRECTIVES* »
} else if (c == '-' && pend == '-') { « handle ADA-style comment »
} else if (c == '\'') { « handle squote literal »
} else if (c == '"') { « handle dquote literal »
} else if (isdigit(c)) { « handle number - for now, leave untouched. »
} else if (isalpha(c)) { « handle keyword or variable »
} else { // output noise char printchar(c); }
} printf("</PRE></body></html>\n"); }