3 # comment following line out when using as CGI utilty
4 # in this case files to convert which are local must end with .txt
9 # v.1.7 - switch for using as commandline or cgi utility
10 # v.1.9 - fixed highlighting problem with escaped quotes
11 # v.2.0 - fixed \r\n translation
12 # v.2.1 - more compatible CGI
14 # formats newLISP source files with syntax highlighting in HTML
16 # use on the command line or as cgi file together with a webserver
18 # EXAMPLE command line:
20 # ./syntaxi.cgi mysource.lsp > mysource.lsp.html
22 # formats mysorce.lsp and redirects output to a new file mysource.lsp.html
24 # EXAMPLE webserver CGI (tested on Apache) local files must end in txt for security
26 # http://www.mysite.com/syntax.cgi?mysource.lsp.txt
28 # returns mysorce.lsp HTML formatted to the requesting client (browser)
30 # EXAMPLE webserver CGI with other site URL
32 # http://www.mysite.com/syntax.cgi?http://othersite/afile.lsp
34 # displays afile.lsp formateed from other site
36 # the following situations are not handled correctly:
37 # - nested curly braces for strings like {abd{def}ghi}
38 # - multiline quoted strings, use [text] [/text] instead
39 # - multiline braced strings, use [text] [/text] instead
40 # - comments starting with # but not starting at beginning of line
41 # use ; as comment starter when comment appears after code
44 (print "Content-type: text/html\r\n\r\n"))
46 (define keyword-color "#0000AA") ; newLISP keywords
47 (define string-color "#008800") ; single line quoted and braced strings
48 (define long-string-color "#008800") ; multiline for [text], [/text] tags
49 (define paren-color "#AA0000") ; parenthesis
50 (define comment-color "#555555") ; comments
51 (define number-color "#665500") ; numbers
53 (define function-name-color "#000088") ; not implemented yet for func in (define (func x y z) ...)
55 (set 'keywords (map name (filter (fn (x) (primitive? (eval x))) (sort (symbols) > ))))
57 (push "true" keywords)
58 (set 'keyword-regex (join keywords "|"))
59 (replace "?" keyword-regex "\\?")
60 (replace "$" keyword-regex "\\$")
61 (replace "!" keyword-regex "\\!")
62 (replace "+" keyword-regex "\\+")
63 (replace "*" keyword-regex "\\*")
64 (replace "||" keyword-regex "|\\|")
65 (set 'keyword-regex (append {(\s+|\(|\))(} keyword-regex {)(\s+|\(|\))}))
67 (set 'file (if cgi-use
68 (or (read-line) (env "QUERY_STRING"))
73 (if (and (not (starts-with file "http://" nil)) (not (ends-with file ".txt")))
75 (println "<h3>File not allowed for viewing: " file "</h3>")
80 (if (starts-with file "http://" nil)
81 (set 'file (get-url file 10000))
82 (set 'file (read-file file )))
86 (println "<h3>Cannot find file</h3>")
89 (define (clean-comment str)
90 (replace {<font color='#......'>} str "" 0)
91 (replace {</font>} str "")
92 (replace {[text]} str "[&text]")
93 (replace {[/text]} str "[&/text]")
96 (define (format-quoted-string str)
97 (replace {<font color='#......'>} str "" 0)
98 (replace {</font>} str "")
99 (replace ";" str ";&")
100 (replace "{" str "{&")
101 (replace "}" str "}&")
102 (replace {\} str "\&")
103 (replace {[text]} str "[&text]")
104 (replace {[/text]} str "[&/text]")
105 (format {<font color='%s'>%s</font>} string-color str)
108 (define (format-braced-string str)
109 (replace {<font color='#......'>} str "" 0)
110 (replace {</font>} str "")
111 (replace ";" str ";&")
112 (replace {"} str ""&")
113 (replace {[text]} str "[&text]")
114 (replace {[/text]} str "[&/text]")
115 (format {<font color='%s'>%s</font>} string-color str)
118 (define (format-tagged-string str)
119 (replace {<font color='#......'>} str "" 0)
120 (replace {</font>} str "")
121 (replace ";" str ";&")
122 (format {<font color='%s'>%s</font>} string-color str)
125 ; replace special HTML characters
126 (replace "\r\n" file "\n")
127 (replace "&" file "&&")
128 (replace "<(\\w)" file (append "<&" $1) 0)
129 (replace "(\\w)>" file (append $1 ">&") 0)
130 (replace "/>" file "/>&" 0)
131 (replace "</" file "<&/" 0)
132 (replace "<!" file "<&!" 0)
133 ; replace escaped quotes
134 (replace "\092\034" file "\&"&")
137 (replace keyword-regex file (format {%s<font color='%s'>%s</font>%s} $1 keyword-color $2 $3) 0)
140 (replace {(\s+|\(|\))(0x[0-9a-fA-F]+|[+-]?\d+\.\d+|[+-]?\d+|\.\d+)} file
141 (format {%s<font color='%s'>%s</font>} $1 number-color $2) 0)
145 (replace "(" file (format {<font color='%s'>(</font>} paren-color))
146 (replace ")" file (format {<font color='%s'>)</font>} paren-color))
148 ; color braced strings
149 (replace "{.*?}" file (format-braced-string $0) 0) ; no multiline string
150 ; color quoted strings
151 (replace {".*?"} file (format-quoted-string $0) 0) ; no multiline strings
154 (replace ";.*" file (clean-comment $0) 0)
155 (replace ";.*" file (format {<font color='%s'>%s</font>} comment-color $0) 0)
159 (dolist (lne (parse file "\n"))
160 (replace "^\\s*#.*" lne (clean-comment $0) 0)
161 (replace "^\\s*#.*" lne (format {<font color='%s'>%s</font>} comment-color $0) 0)
162 (write-line lne buff))
165 ; color tagged strings
166 (replace {\[text\].*?\[/text\]} file (format-tagged-string $0) 4) ; handles multiline strings
168 ; xlate back special characters
169 (replace "&&" file "&") ; ampersand
170 (replace "<&" file "<") ; less
171 (replace ">&" file ">") ; greater
172 (replace {"&} file """) ; quotes
173 (replace {;&} file ";") ; semicolon
174 (replace {{&} file "{") ; left curly brace
175 (replace {}&} file "}") ; right curly brace
176 (replace {[&} file "[") ; left bracket
177 (replace {\&} file "\") ; back slash
180 ; add pre and post tags
181 (println (append "<html><body><pre>\n" file "\n</pre>" ))
183 (println {<center><font face='Arial' size='-2' color='#444444'>}
184 {syntax highlighting with <a href="http://newlisp.org">newLISP</a> }
185 {and <a href="http://newlisp.org/syntax.cgi?code/syntax-cgi.txt">syntax.cgi</a>}
188 (println {</body></html>})