/*
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 »
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 »void UnexpandedStart (int seq)
{
stack[++top] = seq;
if (top > 0) fprintf (stdout, /* terminate link from previous block because nested links are bad! */
"</a>");
fprintf (stdout,
"<a href=\"javascript:toggleLayer('expanded_%d','unexpanded_%d')\" class=\"show\">",
seq, seq, seq);
}
void UnexpandedFinish (void)
{
fprintf (stdout,
"<div class=\"show\" id=\"unexpanded_%d\"></div>",
stack[top]);
fprintf (stdout, "</a>");
}
void ExpandedStart (void)
{
int seq = stack[top];
if (top > 0) fprintf (stdout, /* terminate link from previous block because nested links are bad! */
"</a>"
"</font>");
fprintf (stdout,
"<div class=\"data\" id=\"expanded_%d\">"
"<font color=\"#000000\">"
"<a href=\"javascript:toggleLayer('expanded_%d','unexpanded_%d')\" class=\"show\">",
seq, seq, seq);
}
void ExpandedFinish (void)
{
--top;
fprintf (stdout, "</a>"
"</font>"
"</div>");
if (top >= 0) {
int seq = stack[top];
fprintf (stdout, /* re-instate link to allow collapse of previous block */
"<font color=\"#000000\">"
"<a href=\"javascript:toggleLayer('expanded_%d','unexpanded_%d')\" class=\"show\">",
seq, seq, seq);
} else {
fprintf (stdout, "<font color=\"#000000\">");
}
}
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 » }
printf("</PRE></body></html>\n");
}