#!/usr/bin/newlisp # newlispdoc - generates html documentation from newLISP source files # Copyright (C) 1992-2007 Lutz Mueller # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2, 1991, # as published by the Free Software Foundation. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ;; @module newlispdoc ;; @description Generates documentation and hightligted source from newLISP source files. ;; @version 1.3 - handle remote files specified in URLs in a url-file ;; @author Lutz Mueller, 2006, 2007 ;; @location http://newlisp.org ;; ;;

Usage:

;; The -s switch can be used to generate highlighted source files. ;;
;;    newlispdoc afile.lsp bfile.lsp
;;    newlispdoc -s afile.lsp bfile.lsp
;;    newlispdoc -s *.lsp
;;
;;    ; or on Win32
;;    newlisp newlispdoc afile.lsp bfile.lsp
;;    newlisp newlispdoc -s afile.lsp bfile.lsp
;;    newlisp newlispdoc -s *.lsp
;; 
;; newlispdoc can take a file of URLs and generate documentation and syntax ;; highlighted source from remote files: ;;
;;    newlispdoc -url file-with-urls.txt 10000
;;    newlispdoc -s -url file-with-urls.txt 10000
;;
;;    ; or on Win32
;;    newlisp newlispdoc -url file-with-urls.txt 10000
;;    newlisp newlispdoc -s -url file-with-urls.txt 10000
;; 
;; file-with-urls.txt contains one URL per line in the file. A URLstarts either ;; with http:// or file:// - This allows mixing remote and local files. An optional ;; timeout of 10 seconds is specified after the url file name. If no timeout is specified ;; newlispdoc assumes 5 seconds. ;; ;; Execute from within the same directory of the source files when ;; no url file is given. ;; ;; For each file a file with the same name and extension '.html' is generated ;; and written to the current directory. A file 'index.htm' is written as ;; an index for all other files generated. If the '-s' switch is specified, ;; a file with the extension '.src.html' is generated for each file. ;; ;; Please read @link http://newlisp.org/newLISPdoc.html newLISPdoc.htm to learn ;; about tagging of newLISP source code for newlispdoc. ;; (set 'version "1.3") ; get list of files from command line (set 'files (2 (main-args))) (if (empty? files) (begin (println "USAGE: newlispdoc [-s] ") (println "USAGE: newlispdoc [-s] -url ") (exit -1))) (set 'prolog1 [text] %s [/text]) (set 'stylesheet [text]

Modules

[/text]) (set 'prolog3 {

Module index

}) (set 'epilog [text]

- ∂ -

generated with newLISP  and newLISPdoc
[/text]) ; ---------- routines for generating syntax-highlighted file .src.html ------------------ (define keyword-color "#0000AA") ; newLISP keywords (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 name (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 "|\\|") (set 'keyword-regex (append {(\s+|\(|\))(} keyword-regex {)(\s+|\(|\))})) (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) ) (define (write-syntax-highlight src-file outputfile) ; replace special HTML characters (replace "\r\n" src-file "\n") (replace "&" src-file "&&") (replace "<(\\w)" src-file (append "<&" $1) 0) (replace "(\\w)>" src-file (append $1 ">&") 0) (replace "/>" src-file "/>&" 0) (replace "%s%s} $1 keyword-color $2 $3) 0) ; color numbers (replace {(\s+|\(|\))(0x[0-9a-fA-F]+|[+-]?\d+\.\d+|[+-]?\d+|\.\d+)} src-file (format {%s%s} $1 number-color $2) 0) ; color parens (replace "(" src-file (format {(} paren-color)) (replace ")" src-file (format {)} paren-color)) ; color braced strings (replace "{.*?}" src-file (format-braced-string $0) 0) ; no multiline string ; color quoted strings (replace {".*?"} src-file (format-quoted-string $0) 0) ; no multiline strings ; color ; comments (replace ";.*" src-file (clean-comment $0) 0) (replace ";.*" src-file (format {%s} comment-color $0) 0) ; color # comments (set 'buff "") (dolist (lne (parse src-file "\n")) (replace "^\\s*#.*" lne (clean-comment $0) 0) (replace "^\\s*#.*" lne (format {%s} comment-color $0) 0) (write-line lne buff)) (set 'src-file buff) ; color tagged strings (replace {\[text\].*?\[/text\]} src-file (format-tagged-string $0) 4) ; handles multiline strings ; xlate back special characters (replace "&&" src-file "&") ; ampersand (replace "<&" src-file "<") ; less (replace ">&" src-file ">") ; greater (replace {"&} src-file """) ; quotes (replace {;&} src-file ";") ; semicolon (replace {{&} src-file "{") ; left curly brace (replace {}&} src-file "}") ; right curly brace (replace {[&} src-file "[") ; left bracket (replace {\&} src-file "\") ; back slash ; add pre and post tags (write-file (string outputfile ".src.html") (append "
\n" src-file "\n
" {
} {syntax highlighting with newLISP } {and newLISPdoc} {
})) ) ;---------------------------------- End syntax highlighting routines ------------------------ ; get command line switch -s for generating syntax highlighted source (let (pos (find "-s" files)) (if pos (begin (pop files pos) (set 'source-link true)))) ; get command line switch -url for retrieving files via http from remote location (let (pos (find "-url" files)) (if pos (begin (pop files pos) (set 'url-file (files pos)) (set 'time-out (int (last files) 5000))))) ; if url-file is specified make a list of all urls (if url-file (set 'files (parse (read-file url-file) "\\s+" 0))) (if (= (last files) "") (pop files -1)) (set 'indexpage "") ; buffer for modules index page (write-buffer indexpage (format prolog1 "Modules")) (write-buffer indexpage stylesheet) ; reformat (define (protect-html text) (replace "

" text "[h1]") (replace "

" text "[h2]") (replace "

" text "[h3]") (replace "

" text "[h4]") (replace "

" text "[/h1]") (replace "" text "[/h2]") (replace "" text "[/h3]") (replace "" text "[/h4]") (replace "" text "[i]") (replace "" text "[/i]") (replace "" text "[em]") (replace "" text "[/em]") (replace "" text "[b]") (replace "" text "[/b]") (replace "" text "[tt]") (replace "" text "[/tt]") (replace "

" text "[p]") (replace "

" text "[/p]") (replace "
" text "[br]") (replace "
" text "[br/]") (replace "
" text "[pre]")
	(replace "
" text "[/pre]") (replace "
" text "[center]") (replace "
" text "[/center]") (replace "
  • " text "[li]") (replace "
  • " text "[/li]") (replace "" text "[/ul]") (replace "
      " text "[ul]") (replace "" text "[/blockquote]") (replace "
      " text "[blockquote]") ) (define (unprotect-html text) (replace "[h1]" text "

      ") (replace "[h2]" text "

      ") (replace "[h3]" text "

      ") (replace "[h4]" text "

      ") (replace "[/h1]" text "

      ") (replace "[/h2]" text "") (replace "[/h3]" text "") (replace "[/h4]" text "") (replace "[i]" text "") (replace "[/i]" text "") (replace "[em]" text "") (replace "[/em]" text "") (replace "[b]" text "") (replace "[/b]" text "") (replace "[tt]" text "") (replace "[/tt]" text "") (replace "[p]" text "

      ") (replace "[/p]" text "

      ") (replace "[br]" text "
      ") (replace "[br/]" text "
      ") (replace "[pre]" text "
      ")
      	(replace "[/pre]" text "
      ") (replace "[center]" text "
      ") (replace "[/center]" text "
      ") (replace "[li]" text "
    • ") (replace "[/li]" text "
    • ") (replace "[ul]" text "
        ") (replace "[/ul]" text "
      ") (replace "[blockquote]" text "
      ") (replace "[/blockquote]" text "
      ") ) ; format the example tags (define (format-example text) (replace "<" text "<") (replace ">" text ">") (string "

      example:
      " (replace ";;" text "") "
      \n") ) ; write the module tag link on the index page ; put source link on doc page if -s flag (define (format-module text desc filename , module) (set 'module (string "

      Module: " text "

      ")) (write-buffer indexpage (string {} module "\n" )) (write-buffer indexpage (string "

      " desc "

      \n")) (if source-link (string {source} module) (string "
      " module)) ) ; write the function name links on the index page under the module (define (format-func-link func-name file-name) (let (names (if (find ":" func-name) (parse func-name ":") (list "" func-name))) (write-buffer indexpage (string {} (names 1) {    })) (string (names 0) "_" (names 1)) ) ) ; format the syntax line (define (format-syntax text file-name, tag) (replace "<([^<]*?)>" text (string "" $1 "") 0) (replace {^ *\((.*?) (.*?\))} text (string "(" $1 " " $2) 0) (replace {^ *\(([^ ]*?)\)} text (string "(" $1 ")") 0) (string (unless (= old-syntax $1) (begin (set 'old-syntax $1) (set 'tag (format-func-link $1 file-name)) (set 'tag (string {})) (string "

      - § -

      \n" tag "

      " old-syntax "

      \n")) "") "syntax: " (trim text) "
      \n") ) (define (format-parameter param text) ; (replace "<([^<]*?)>" param (string "" $1 "") 0) ; (replace "<([^<]*?)>" text (string "" $1 "") 0) (string "parameter: " (format-text (trim param)) " - " (format-text text) "
      \n") ) (define (format-return text) (string "

      return: " (format-text text) "

      \n") ) (define (format-text text) (replace "<([^<]*?)>" text (string "" $1 "") 0) (replace "'([^\\s].*?[^\\s])'" text (string "" $1 "") 0) ) ;---------------------------------- End newlisdoc formatting subroutines ---------------- ; MAIN function (dolist (fle files) (println fle) (set 'html "") (set 'original (read-file fle time-out)) (if (not original) (begin (println "Could not read " fle) (exit 1))) (if (starts-with original "ERR:") (println "Could not read " fle " " original)) (set 'outfile (last (parse fle "\\\\|/" 0))) (set 'page (parse (replace "\r\n" original "\n") "\n")) (set 'page (filter (fn (ln) (or (starts-with ln ";;") (= (length (trim ln)) 0))) page)) (set 'page (join page "\n")) (if (find ";; *@module " page 0) (begin (replace ";; @example *\n(.*?)\n\\s*\n" page (format-example $1) 4) (set 'page (protect-html page)) (set 'desc "") (replace ";; *@description (.*?)\n" page (begin (set 'desc $1) (string "

      " desc "

      \n") ) 0) (replace ";; *@module (.*?)\n" page (format-module $1 desc outfile) 0) (replace ";; *@author (.*?)\n" page (string "Author: " $1 "
      \n") 0) (replace ";; *@version (.*?)\n" page (string "Version: " $1 "
      \n") 0) (replace ";; *@location (.*?)\n" page (string {Location: } $1 "
      \n") 0) (replace ";; *@syntax (.*?)\n" page (format-syntax $1 outfile) 0) (replace ";; *@param (.*?) (.*?)\n" page (format-parameter $1 $2) 0) (replace ";; *@return (.*?)\n" page (format-return $1) 0) (replace ";;\\s*\n" page "

      \n" 0) (replace ";;(.*\n)" page (format-text $1) 0) (replace {@link ([^ ]*?) ([^ ]*?)\s} page (string {} $2 { }) 0) (set 'page (unprotect-html page)) (write-buffer html (format prolog1 outfile)) (write-buffer html stylesheet) (write-buffer html prolog3) (write-buffer html page) (write-buffer html epilog) (write-file (string outfile ".html") html) ; write syntax highlighted source (if source-link (write-syntax-highlight original outfile)) )) ) ; write the modules index page (write-buffer indexpage epilog) (write-file "index.html" indexpage) (exit)