1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
|
#!/usr/bin/env newlisp
# - syntax.cgi - this utility formats a newLISP source file as an HTML
# file with syntax highlighting
#
# comment following line out when not using as CGI utilty
# for CGI files to convert which are local must end with .txt
# v.1.7 - switch for using as commandline or cgi utility
# v.1.9 - fixed highlighting problem with escaped quotes
# v.2.0 - fixed \r\n translation
# v.2.1 - more compatible CGI
# v.2.3 - changed syntax for write-line
# v.2.4 - added handling of < ? ... > XML tag
# v.2.5 - generate more compliant HTML 4.01 transitional
# v.2.6 - handle number scientific format with e
# v.2.7 - improved keyword regex
# v.2.8 - scientific format with E
# v.2.9 - support for newLISPdoc tag color
# v.3.0 - correctly highlight & and ^ keywords
# v.3.1 - change additional 'nil' arg in 'starts-with' to 1
# v.3.2 - replace 'name' with 'term' and make compatible with older versions
# v.3.3 - added utf-8 meta tag in header
# v.3.4 - fontsize 150% for iPad or iPhone
#
# formats newLISP source files with syntax highlighting in HTML
#
# use on the command line or as cgi file together with a webserver
#
# EXAMPLE command line (set 'cgi-use nil):
#
# ./syntaxi.cgi mysource.lsp > mysource.lsp.html
#
# formats mysorce.lsp and redirects output to a new file mysource.lsp.html
#
# EXAMPLE webserver CGI (tested on Apache) local files must end in txt for security
#
# http://www.mysite.com/syntax.cgi?mysource.lsp.txt
#
# returns mysorce.lsp HTML formatted to the requesting client (browser)
#
# EXAMPLE webserver CGI with other site URL
#
# http://www.mysite.com/syntax.cgi?http://othersite/afile.lsp
#
# displays afile.lsp formateed from other site
#
# the following situations are not handled correctly:
# - nested curly braces for strings like {abd{def}ghi}
# - multiline quoted strings, use [text] [/text] instead
# - multiline braced strings, use [text] [/text] instead
# - comments starting with # but not starting at beginning of line
# use ; as comment starter when comment appears after code
(define cgi-use true)
; make compatible with versions prior to 10.1.11
(when (< (sys-info -2) 10111)
(constant (global 'term) name))
(when cgi-use
(print "Content-Type: text/html\r\n\r\n")
(set 'iPad (find "iPad" (env "HTTP_USER_AGENT") 1))
(set 'iPhone (find "iPhone" (env "HTTP_USER_AGENT") 1))
)
(define keyword-color "#0000AA") ; newLISP keywords
(define tag-color "#308080") ; newLISPdoc tags
(define string-color "#008800") ; single line quoted and braced strings
(define long-string-color "#008800") ; multiline for [text], [/text] tags
(define paren-color "#AA0000") ; parenthesis
(define comment-color "#555555") ; comments
(define number-color "#665500") ; numbers
(define function-name-color "#000088") ; not implemented yet for func in (define (func x y z) ...)
(set 'keywords (map term (filter (fn (x) (primitive? (eval x))) (sort (symbols) > ))))
(push "nil" keywords)
(push "true" keywords)
(set 'keyword-regex (join keywords "|"))
(replace "&" keyword-regex "&&")
(replace "?" keyword-regex "\\?")
(replace "^" keyword-regex "\\^")
(replace "$" keyword-regex "\\$")
(replace "!" keyword-regex "\\!")
(replace "+" keyword-regex "\\+")
(replace "*" keyword-regex "\\*")
(replace "||" keyword-regex "|\\|")
(set 'keyword-regex (append {(\G|\s+|\(|\))(} keyword-regex {)(\s+|\(|\))}))
(set 'file (if cgi-use
(or (read-line) (env "QUERY_STRING"))
(main-args 2)))
(set 'title file)
(when cgi-use
(when (and (not (starts-with file "http://" 1)) (not (ends-with file ".txt")))
(println "<h3>File not allowed for viewing: " file "</h3>")
(exit))
)
(if (starts-with file "http://" 1)
(set 'file (get-url file 10000))
(set 'file (read-file file )))
(unless file
(println "<h3>Cannot find file</h3>")
(exit))
(define (clean-comment str)
(replace {<font color='#......'>} str "" 0)
(replace {</font>} str "")
(replace {[text]} str "[&text]")
(replace {[/text]} str "[&/text]")
)
(define (format-quoted-string str)
(replace {<font color='#......'>} str "" 0)
(replace {</font>} str "")
(replace ";" str ";&")
(replace "{" str "{&")
(replace "}" str "}&")
(replace {\} str "\&")
(replace {[text]} str "[&text]")
(replace {[/text]} str "[&/text]")
(format {<font color='%s'>%s</font>} string-color str)
)
(define (format-braced-string str)
(replace {<font color='#......'>} str "" 0)
(replace {</font>} str "")
(replace ";" str ";&")
(replace {"} str ""&")
(replace {[text]} str "[&text]")
(replace {[/text]} str "[&/text]")
(format {<font color='%s'>%s</font>} string-color str)
)
(define (format-tagged-string str)
(replace {<font color='#......'>} str "" 0)
(replace {</font>} str "")
(replace ";" str ";&")
(format {<font color='%s'>%s</font>} string-color str)
)
; replace special HTML characters
(replace "\r\n" file "\n")
(replace "&" file "&&")
(replace "<(\\w)" file (append "<&" $1) 0)
(replace "(\\w)>" file (append $1 ">&") 0)
(replace "/>" file "/>&" 0)
(replace "</" file "<&/" 0)
(replace "<!" file "<&!" 0)
(replace "<\\?" file "<&?" 0)
; replace escaped quotes
(replace "\092\034" file "\&"&")
; color keywords
(replace keyword-regex file (format {%s<font color='%s'>%s</font>%s} $1 keyword-color $2 $3) 0)
;(replace keyword-regex file (println "->" $0 "<-<br>") 0)
;(exit)
; color numbers
(replace
; <-- lead --><---- hex ---->|<- oct ->|<------- decimal ----- and ----- scientific -->
{(\s+|\(|\))(0x[0-9a-fA-F]+|[+-]?0\d+|([+-]?(0|[1-9]\d*)(\.\d*)?|\.\d+)([eE][+-]?\d+)?)} file
(format {%s<font color='%s'>%s</font>} $1 number-color $2) 0)
; color parens
(replace "(" file (format {<font color='%s'>(</font>} paren-color))
(replace ")" file (format {<font color='%s'>)</font>} paren-color))
; color braced strings
(replace "{.*?}" file (format-braced-string $0) 0) ; no multiline string
; color quoted strings
(replace {".*?"} file (format-quoted-string $0) 0) ; no multiline strings
; color ; comments
(replace ";.*" file (clean-comment $0) 0)
(replace ";.*" file (format {<font color='%s'>%s</font>} comment-color $0) 0)
(replace "(;;.*)(@.*)(\\s.*\n)" file (append $1 (format {<font color='%s'>%s</font>} tag-color $2) $3) 512)
; color # comments
(set 'buff "")
(dolist (lne (parse file "\n"))
(replace "^\\s*#.*" lne (clean-comment $0) 0)
(replace "^\\s*#.*" lne (format {<font color='%s'>%s</font>} comment-color $0) 0)
(if (< (sys-info -2) 9909)
(write-line lne buff)
(write-line buff lne)))
(set 'file buff)
; color tagged strings
(replace {\[text\].*?\[/text\]} file (format-tagged-string $0) 4) ; handles multiline strings
; xlate back special characters
(replace "&&" file "&") ; ampersand
(replace "<&" file "<") ; less
(replace ">&" file ">") ; greater
(replace {"&} file """) ; quotes
(replace {;&} file ";") ; semicolon
(replace {{&} file "{") ; left curly brace
(replace {}&} file "}") ; right curly brace
(replace {[&} file "[") ; left bracket
(replace {\&} file "\") ; back slash
; add pre and post tags
(println (append
{<!DOCTYPE HTML PUBLIC "4.01 Transitional">}
"<html><head><title>" title "</title>\n"
{<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />}
{<style type="text/css">}
(if (or iPad iPhone)
{pre {font-size: 150%}}
{pre {font-size: 100%}} )
"</style></head><body>\n<pre>\n"
file "\n</pre>"
))
(println {<center><font face='Arial' size='-2' color='#444444'>}
{syntax highlighting with <a href="http://newlisp.org">newLISP</a> }
{and <a href="http://newlisp.org/syntax.cgi?code/syntax-cgi.txt">syntax.cgi</a>}
{</font></center>})
(println {</body></html>})
(exit)
;; eof
|