; ACL2 Version 4.0 -- A Computational Logic for Applicative Common Lisp ; Copyright (C) 2010 University of Texas at Austin ; This version of ACL2 was produced by modifying ACL2 Version 1.9, Copyright ; (C) 1997 Computational Logic, Inc. See the documentation topic NOTES-2-0. ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation; either version 2 of the License, or ; (at your option) any later version. ; 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. ; Written by: Matt Kaufmann and J Strother Moore ; email: Kaufmann@aus.edsr.eds.com and Moore@cs.utexas.edu ; Department of Computer Sciences ; University of Texas at Austin ; Austin, TX 78712-1188 U.S.A. ; Modified 3/2001 for Version_2.6 by Michael N. Bogomolny, to generate ; a distinct HTML file for each doc topic, in support of his search engine. ; Updated 11/2002 for Version_2.7 by Michael N. Bogomolny, to fix a bug ; related to deeply nested doc topics. ; Html driver for ACL2 documentation. Sample usage: ; (write-html-file "acl2-doc") or even (write-html-file). ; NOTE: This could perhaps be improved by putting "next" and "previous" links ; by the "Parent topic" link. ; This file defines the macro write-html-file, which writes an html file. ; It takes all the documentation strings that are available via the ACL2 :DOC ; command and creates the html file. ; Suppose you get an error like this: #|| ACL2 p!>(write-html-file :topics '(STR::STR) :pkg "STR") Writing html file acl2-doc.html, default package "STR". HARD ACL2 ERROR in FMT-VAR: Unbound Fmt Variable. The tilde directive at location 13 in the fmt string below uses the variable #\c. But this variable is not bound in the association list, ((#\p . "SUBSTR") (#\s . "SUBSTR") (#\t . "substr") (#\T . "SUBSTR")), supplied with the fmt string. "see ~st" ||# ; What this kind of error typically means is that there was a link (~l or ~pl ; or ~il) in a :doc string to SUBSTR, yet SUBSTR wasn't documented. With a ; grep you can perhaps figure out what's wrong, e.g., perhaps ~l[substr] was ; supposed to be ~l[substrp]. (in-package "ACL2-USER") (acl2::set-state-ok t) (acl2::program) ; The idea of node names: first apply the character substitution table, then ; deal with the colon. (defconst *html-doc-char-subst-table* '((#\& #\& #\a #\m #\p #\;) (#\< #\& #\l #\t #\;) (#\> #\& #\g #\t #\;)) "Table with entries (char . char-list) for substituting characters.") (defconst *html-doc-char-subst-table-for-anchors* (cons '(#\Space #\-) *html-doc-char-subst-table*) "Table with entries (char . char-list) for substituting characters; also ~ for use with anchors.") (defconst *filename-char-subst-table* '((#\/ #\_ #\s #\l #\a #\s #\h #\_) (#\\ #\_ #\b #\a #\c #\k #\s #\l #\a #\s #\h #\_) (#\& #\_ #\a #\m #\p #\e #\r #\s #\a #\n #\d #\_) (#\Space #\_) (#\: #\_ #\c #\o #\l #\o #\n #\_) (#\< #\_ #\l #\t #\_) (#\> #\_ #\g #\t #\_) (#\* #\_ #\s #\t #\a #\r #\_) (#\? #\_ #\q #\m #\_) (#\@ #\_ #\a #\t #\_) (#\! #\_ #\b #\a #\n #\g #\_) (#\( #\_ #\l #\p #\a #\r #\e #\n #\_) (#\) #\_ #\r #\p #\a #\r #\e #\n #\_) (#\_ #\_ #\u #\n #\d #\e #\r #\s #\c #\o #\r #\e #\_)) "Table with entries (char . char-list) for substituting characters in ~ filenames.") (defun html-string-node-name (pkg-name name) (cond ((equal pkg-name "KEYWORD") (concatenate 'string ":" name)) (pkg-name (concatenate 'string pkg-name "::" name)) (t name))) (defun substring (str lower upper) (acl2::subseq str lower upper)) (defun html-parse-string (x) ; Returns, for x a symbol-name "PKG:NAME" or "PKG::NAME" the pair (mv "PKG" ; "NAME"), where if PKG is "" then the "PKG" returned is "KEYWORD". (let* ((len (length x)) (posn (position #\: x))) (cond ((null posn) (mv nil x)) ((eql posn 0) (mv "KEYWORD" (substring x 1 len))) (t (mv (substring x 0 posn) (substring x (if (eql (char x (+ 1 posn)) #\:) (+ 2 posn) (+ 1 posn)) len)))))) (defun html-node-name (x spack) ; If x is a string, we simply return x. ; If x is a symbol then spack is a symbol. If the symbol-package-names of x ; and agree and are not the keyword package, then we return the symbol-name of ; x. Otherwise we prepend to that name the symbol-package-name of x followed ; by "::", except that we only prepend ":" if that symbol-package-name is ; "KEYWORD". (cond ((stringp x) x) ((symbolp x) (let ((name (symbol-name x)) (pkg-name (acl2::symbol-package-name x))) (cond ((or (equal pkg-name "KEYWORD") (not (eq (acl2::intern-in-package-of-symbol name spack) x))) (html-string-node-name pkg-name name)) (t (html-string-node-name nil name))))) (t (acl2::er acl2::hard 'html-node-name "Apparent attempt to document topic that is neither a string ~ nor a symbol, ~p0." x)))) (defun html-node-name-lst (lst spack) (if lst (cons (html-node-name (car lst) spack) (html-node-name-lst (cdr lst) spack)) nil)) (defun doc-alist1 (raw-doc-alist spack ans) ; Raw-doc-alist is a doc-alist, i.e., a list with entries of the form (name ; section-symbol cites doc). This function returns a corresponding list with ; entries for which name, section-symbol, and the elements of cites have been ; converted by applying html-node-name. (cond ((null raw-doc-alist) (reverse ans)) (t (doc-alist1 (cdr raw-doc-alist) spack (cons (list* (html-node-name (caar raw-doc-alist) spack) (html-node-name (cadar raw-doc-alist) spack) (html-node-name-lst (caddar raw-doc-alist) spack) (cdddar raw-doc-alist)) ans))))) (defun filter-topics1 (topics doc-alist acc) ; At one time we exploited the "fact" that if every topic's section appears ; earlier in doc-alist than it does, in order to guarantee that we include the ; entire cone underneath a topic. But this "fact" isn't true, e.g., for ; arrays and aref1. ; This function is presumably a no-op when writing out the full ACL2 ; documentation. But for a subtree of that documentation, or perhaps user-book ; documentation, this function "installs" new top-level sections. See a ; further comment on this issue in filter-topics. ; !! Should this deal with cites field? (cond ((null doc-alist) (reverse acc)) ((acl2::member-equal (cadar doc-alist) topics) ; section exists (filter-topics1 topics (cdr doc-alist) (cons (car doc-alist) acc))) ((acl2::member-equal (caar doc-alist) topics) ; The section does not exist, so the current topic should be viewed as a ; section. (filter-topics1 topics (cdr doc-alist) (cons (list* (caar doc-alist) (caar doc-alist) (cddar doc-alist)) acc))) (t (filter-topics1 topics (cdr doc-alist) acc)))) (defun extend-with-immediate-subtopics (topics doc-alist changedp) ; !! Should this deal with cites field? (cond ((null doc-alist) (mv topics changedp)) ((acl2::member-equal (caar doc-alist) topics) (extend-with-immediate-subtopics topics (cdr doc-alist) changedp)) ((acl2::member-equal (cadar doc-alist) topics) (extend-with-immediate-subtopics (cons (caar doc-alist) topics) (cdr doc-alist) t)) (t (extend-with-immediate-subtopics topics (cdr doc-alist) changedp)))) (defun all-subtopics (topics doc-alist) (mv-let (extended-topics changedp) (extend-with-immediate-subtopics topics doc-alist nil) (if changedp (all-subtopics extended-topics doc-alist) topics))) (defun filter-topics (topics doc-alist) ; This function is presumably a no-op when writing out a full documentation ; tree. But when topics specifies a subtree of that documentation, this ; function "installs" new top-level sections by replacing the section-symbol of ; an entry (name section-symbol cites doc) with name when that section-symbol ; isn't in the transitive downward closure of topics with respect to ; doc-alist. (if (null topics) doc-alist (filter-topics1 (all-subtopics topics doc-alist) doc-alist nil))) (defun doc-alist (spack topics state) ; Recall that state-global 'documentation-alist is a list with entries of the ; form (name section-symbol cites doc). This function returns a corresponding ; list with entries for which name, section-symbol, and the elements of cites ; have been converted by applying html-node-name with the indicated spack ; argument, a symbol which symbol-package-name is considered the current ; package for purposes of whether a symbol naming a documentation topic needs a ; package prefix. (doc-alist1 (filter-topics topics (acl2::global-val 'acl2::documentation-alist (acl2::w state))) spack nil)) (defun version-subdirectory (acl2-version) ; From "ACL2 Version 1.9" we compute "v1-9". More generally, ; from "ACL2 Version xxx.yyy/zzz..." we compute "vxxx-yyySzzz..." (let* ((expected-initial-str "ACL2 Version ") (k (1- (length expected-initial-str)))) (cond ((not (acl2::terminal-substringp acl2-version expected-initial-str k k)) (acl2::er acl2::hard 'version-subdirectory "State global 'acl2::acl2-version is not of the expected form!")) (t (coerce (cons #\v (coerce (acl2::apply-char-subst-table1 (cdr (nthcdr k (coerce acl2-version 'list))) nil '((#\. #\-) (#\/ #\S))) 'list)) 'string))))) (defconst *html-doc-markup-table* '(("-" nil . "--") ("B" nil . "~st") ("BF" nil . "~%
") ("BID" nil . "") ;begin implementation dependent ("BQ" nil . "~%~%") ("GIF" nil . "") ("BV" nil . "~%~%") ("EV" nil . "") ("C" nil . "~%") ("EID" nil . "") ;end implementation dependent ("EM" nil . "~st") ;emphasis ("EQ" nil . "~st
") ("EF" nil . "
~st
")
;("L" t . "See ~st")
("IL" t . "~st")
("ILC" t . "~st
")
("L" t . "See ~st")
("NL" nil . "~%~%")
;("PL" t . "see ~st")
("PL" t . "see ~st")
("SC" nil . "~sT")
("ST" nil . "~st") ;strong emphasis
("T" nil . "~st")
("TERMINAL" nil . "") ; terminal only, ignore
("WARN" nil . "")
;("CLICK-HERE" t . "Click here")
;("PCLICK-HERE" t . "click here")
("CLICK-HERE" t . "Click here")
("PCLICK-HERE" t . "click here")
;("FLY" t . "
")
;("WALK" t . "
")
("FLY" t . "
")
("LARGE-FLY" t . "
")
("WALK" t . "
")
("LARGE-WALK" t . "
")
("URL" nil . "~st")
)
"Table for use in printing documentation strings, when printing to
an html file. See :DOC markup")
(defun apply-html-subst-table (name anchorp)
(acl2::apply-char-subst-table
name
(if anchorp
*html-doc-char-subst-table-for-anchors*
*html-doc-char-subst-table*)
nil))
(defun apply-filename-subst-table (name)
(acl2::apply-char-subst-table
name
*filename-char-subst-table*
nil))
(defun write-header (current-name title level channel state)
(declare (ignore current-name))
(pprogn (princ$ "
" channel state)
(cond ((null index-file) ; then channel is to the index file
state)
(t (pprogn
(princ$ "
" channel state))))
(newline channel state)
; (princ$ "