#!/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 "

File not allowed for viewing: " file "

") (exit)) ) (if (starts-with file "http://" 1) (set 'file (get-url file 10000)) (set 'file (read-file file ))) (unless file (println "

Cannot find file

") (exit)) (define (clean-comment str) (replace {} str "" 0) (replace {} str "") (replace {[text]} str "[&text]") (replace {[/text]} str "[&/text]") ) (define (format-quoted-string str) (replace {} str "" 0) (replace {} str "") (replace ";" str ";&") (replace "{" str "{&") (replace "}" str "}&") (replace {\} str "\&") (replace {[text]} str "[&text]") (replace {[/text]} str "[&/text]") (format {%s} string-color str) ) (define (format-braced-string str) (replace {} str "" 0) (replace {} str "") (replace ";" str ";&") (replace {"} str ""&") (replace {[text]} str "[&text]") (replace {[/text]} str "[&/text]") (format {%s} string-color str) ) (define (format-tagged-string str) (replace {} str "" 0) (replace {} str "") (replace ";" str ";&") (format {%s} 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 "%s%s} $1 keyword-color $2 $3) 0) ;(replace keyword-regex file (println "->" $0 "<-
") 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%s} $1 number-color $2) 0) ; color parens (replace "(" file (format {(} paren-color)) (replace ")" file (format {)} 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 {%s} comment-color $0) 0) (replace "(;;.*)(@.*)(\\s.*\n)" file (append $1 (format {%s} 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 {%s} 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 {} "" title "\n" {} {\n
\n" 
	file "\n
" )) (println {
} {syntax highlighting with newLISP } {and syntax.cgi} {
}) (println {}) (exit) ;; eof