diff options
author | Camm Maguire <camm@debian.org> | 2017-06-08 18:34:51 -0400 |
---|---|---|
committer | Camm Maguire <camm@debian.org> | 2017-06-08 18:34:51 -0400 |
commit | 81cb7ac75232d52ce469d0561a7ddf726d152943 (patch) | |
tree | 4b79103baf2a3000de9cddaac5a0a7d7967d0ffc | |
parent | 092176848cbfd27b96c323cc30c54dff4c4a6872 (diff) | |
parent | a05da9c852a6df26adc51eca7ece778c062192d9 (diff) |
acl2 (7.4dfsg-3) unstable; urgency=medium
* build-dep latest gcl
* revert mxgot for mips64
[dgit import unpatched acl2 7.4dfsg-3]
112 files changed, 29808 insertions, 0 deletions
diff --git a/debian/README.Debian.in b/debian/README.Debian.in new file mode 100644 index 0000000..72e138f --- /dev/null +++ b/debian/README.Debian.in @@ -0,0 +1,51 @@ +ACL2 for Debian +--------------- + +This is a binary distribution of ACL2(h), the now default hons-enabled +version of ACL2. + +A few modifications to the source package were made to ensure DFSG +compliance (in consultation with upstream): + +Removed sparc binary inadvertently included in upstream: + books/workshops/2003/schmaltz-al-sammane-et-al/support/acl2link + +Removed rfc file with non-dfsg licence: + books/centaur/quicklisp/bundle/software/rfc2388-20130720-git/doc/rfc2388.txt + +Removed files in orig tarball that are removed by clean target: + books/workshops/1999/ivy/ivy-v2/ivy-sources/arithmetic.lisp.bak + books/workshops/1999/ivy/ivy-v2/ivy-sources/util/checker.orig + books/workshops/1999/ivy/ivy-v2/ivy-sources/util/make-saved-ivy.orig + books/workshops/1999/ivy/ivy-v2/ivy-sources/util/sivy.orig + books/workshops/1999/ivy/ivy-v2/ivy-sources/util/ivy.orig + +Added katex sources to debian/missing-sources: + debian/missing-sources/books/xdoc/fancy/lib/katex/katex.js + debian/missing-sources/books/xdoc/fancy/lib/katex/katex.min.css + debian/missing-sources/books/xdoc/fancy/lib/katex/src/* + +Added source to debian/missing-sources to remove a lintian false positive: + debian/missing-sources/books/workshops/2000/shumsky/slides2_files/script.js + +As ACL2 is not typically installed into a directory tree other than +that in which is was compiled, the directory layout in this binary +package may be unfamiliar to experienced ACL2 users. In consultation +with the original authors, we have attempted to select a layout for +the binary distribution which would both conform to Debian policy as +well as the spirit of the ACL2 source tree. It has been requested +that the Debian ACL2 package maintain a table of source and binary +file locations. This is included here below. Any files in the Debian +package(s) not in this list are Debian specific utilities/scripts used +in package maintenance. The first entry on each line is the location +in the source tree. Where a directory is specified here, the entire +directory has been mapped to its new location. The second entry on +the line is the new location once the acl2 packages have been +installed, and the last entry is the package name containing the file +or directory. + +----------------------------------------------------------------------------- +@PLIST@ +----------------------------------------------------------------------------- + + -- Camm Maguire <camm@debian.org>, Tue, 20 Oct 2015 15:05:46 +0000 diff --git a/debian/TODO b/debian/TODO new file mode 100644 index 0000000..70a87e9 --- /dev/null +++ b/debian/TODO @@ -0,0 +1,2 @@ +nonstd books +workshop books diff --git a/debian/acl2-books-certs.lintian-overrides.in b/debian/acl2-books-certs.lintian-overrides.in new file mode 100644 index 0000000..c0a5171 --- /dev/null +++ b/debian/acl2-books-certs.lintian-overrides.in @@ -0,0 +1 @@ +acl2-books-certs binary: extra-license-file usr/share/@PD@/books/centaur/aignet/copying.cert
\ No newline at end of file diff --git a/debian/acl2-customization.lisp b/debian/acl2-customization.lisp new file mode 100644 index 0000000..30573f2 --- /dev/null +++ b/debian/acl2-customization.lisp @@ -0,0 +1,2 @@ +(f-put-global 'old-certification-dir "/fix/t1/camm/debian/acl2/acl2-2.9.3" state) +(f-put-global 'new-certification-dir "/usr/share/acl2-2.9.3" state) diff --git a/debian/acl2-emacs.emacsen-install b/debian/acl2-emacs.emacsen-install new file mode 100644 index 0000000..8042397 --- /dev/null +++ b/debian/acl2-emacs.emacsen-install @@ -0,0 +1,45 @@ +#! /bin/sh -e +# /usr/lib/emacsen-common/packages/install/acl2 + +# Written by Jim Van Zandt <jrv@vanzandt.mv.com>, borrowing heavily +# from the install scripts for gettext by Santiago Vila +# <sanvila@ctv.es> and octave by Dirk Eddelbuettel <edd@debian.org>. + +FLAVOR=$1 +PACKAGE=acl2 + +if [ ${FLAVOR} = emacs ]; then exit 0; fi + +echo install/${PACKAGE}: Handling install for emacsen flavor ${FLAVOR} + +#FLAVORTEST=`echo $FLAVOR | cut -c-6` +#if [ ${FLAVORTEST} = xemacs ] ; then +# SITEFLAG="-no-site-file" +#else +# SITEFLAG="--no-site-file" +#fi +FLAGS="${SITEFLAG} -q -batch -l path.el -f batch-byte-compile" + +ELDIR=/usr/share/emacs/site-lisp/${PACKAGE} +ELCDIR=/usr/share/${FLAVOR}/site-lisp/${PACKAGE} + +# Install-info-altdir does not actually exist. +# Maybe somebody will write it. +if test -x /usr/sbin/install-info-altdir; then + echo install/${PACKAGE}: install Info links for ${FLAVOR} + install-info-altdir --quiet --section "" "" --dirname=${FLAVOR} /usr/info/${PACKAGE}.info.gz +fi + +install -m 755 -d ${ELCDIR} +cd ${ELDIR} +FILES=`ls -1 *.el |grep -v ^load` +cp ${FILES} ${ELCDIR} +cd ${ELCDIR} + +cat << EOF > path.el +(setq load-path (cons "." load-path) byte-compile-warnings nil) +EOF +${FLAVOR} ${FLAGS} ${FILES} +rm -f *.el path.el + +exit 0 diff --git a/debian/acl2-emacs.emacsen-remove b/debian/acl2-emacs.emacsen-remove new file mode 100644 index 0000000..bfc0749 --- /dev/null +++ b/debian/acl2-emacs.emacsen-remove @@ -0,0 +1,15 @@ +#!/bin/sh -e +# /usr/lib/emacsen-common/packages/remove/acl2 + +FLAVOR=$1 +PACKAGE=acl2 + +if [ ${FLAVOR} != emacs ]; then + if test -x /usr/sbin/install-info-altdir; then + echo remove/${PACKAGE}: removing Info links for ${FLAVOR} + install-info-altdir --quiet --remove --dirname=${FLAVOR} /usr/info/acl2.info.gz + fi + + echo remove/${PACKAGE}: purging byte-compiled files for ${FLAVOR} + rm -rf /usr/share/${FLAVOR}/site-lisp/${PACKAGE} +fi diff --git a/debian/acl2-emacs.emacsen-startup.in b/debian/acl2-emacs.emacsen-startup.in new file mode 100644 index 0000000..e25fd6f --- /dev/null +++ b/debian/acl2-emacs.emacsen-startup.in @@ -0,0 +1,30 @@ +;; -*-emacs-lisp-*- +;; +;; Emacs startup file for the Debian GNU/Linux acl2 package +;; +;; Originally contributed by Nils Naumann <naumann@unileoben.ac.at> +;; Modified by Dirk Eddelbuettel <edd@debian.org> +;; Adapted for dh-make by Jim Van Zandt <jrv@vanzandt.mv.com> + +;; The acl2 package follows the Debian/GNU Linux 'emacsen' policy and +;; byte-compiles its elisp files for each 'emacs flavor' (emacs19, +;; xemacs19, emacs20, xemacs20...). The compiled code is then +;; installed in a subdirectory of the respective site-lisp directory. +;; We have to add this to the load-path: +(setq load-path (cons (concat "/usr/share/" + (symbol-name debian-emacs-flavor) + "/site-lisp/acl2") load-path )) + +(autoload 'run-acl2 + "top-start-inferior-acl2" + "Open communication between acl2 running in shell and prooftree." t) + +(defvar *acl2-interface-dir* "/usr/share/emacs/site-lisp/acl2/") +;(when (boundp 'tags-table-list);FIXME xemacs +; (setq tags-table-list (cons "/usr/share/acl2-@VR@" tags-table-list))) + +(autoload 'start-proof-tree + (concat *acl2-interface-dir* "top-start-shell-acl2") + "Enable proof tree logging in a prooftree buffer." + t) + diff --git a/debian/acl2-infix.examples b/debian/acl2-infix.examples new file mode 100644 index 0000000..ca72613 --- /dev/null +++ b/debian/acl2-infix.examples @@ -0,0 +1 @@ +books/interface/infix/doinfix diff --git a/debian/acl2-infix.postinst.old b/debian/acl2-infix.postinst.old new file mode 100644 index 0000000..2cea29b --- /dev/null +++ b/debian/acl2-infix.postinst.old @@ -0,0 +1,11 @@ +#!/bin/sh + +set -e + +if [ "$1" = "configure" ] ; then + + texhash + +fi + +#DEBHELPER# diff --git a/debian/acl2-infix.postrm.old b/debian/acl2-infix.postrm.old new file mode 100644 index 0000000..8a729e9 --- /dev/null +++ b/debian/acl2-infix.postrm.old @@ -0,0 +1,11 @@ +#!/bin/sh + +set -e + +if [ "$1" = "remove" ] || [ "$1" = "purge" ] ; then + + [ "$(which texhash)" = "" ] || texhash + +fi + +#DEBHELPER# diff --git a/debian/acl2.1 b/debian/acl2.1 new file mode 100644 index 0000000..7568087 --- /dev/null +++ b/debian/acl2.1 @@ -0,0 +1,35 @@ +.\" Hey, EMACS: -*- nroff -*- +.\" First parameter, NAME, should be all caps +.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection +.\" other parameters are allowed: see man(7), man(1) +.TH ACL2 1 "October 26, 2002" +.\" Please adjust this date whenever revising the manpage. +.\" +.\" Some roff macros, for reference: +.\" .nh disable hyphenation +.\" .hy enable hyphenation +.\" .ad l left justify +.\" .ad b justify to both left and right margins +.\" .nf disable filling +.\" .fi enable filling +.\" .br insert line break +.\" .sp <n> insert n+1 empty lines +.\" for manpage-specific macros, see man(7) +.SH NAME +acl2 \- A Computational Logic +.SH SYNOPSIS +.B acl2 +.SH DESCRIPTION +This manual page documents briefly the +.B acl2 +command. +This manual page was written for the Debian GNU/Linux distribution +because the original program does not have a manual page. Instead, it +has documentation in the GNU Info format as well as in html format. +These are included in the acl2-doc package. The documentation can +also be found at the project's website, +http://www.cs.utexas.edu/users/moore/acl2, both in html form and in +postscript. +.SH AUTHOR +This manual page was written by Camm Maguire, <camm@enhanced.com>, +for the Debian GNU/Linux system (but may be used by others). diff --git a/debian/acl2.dirs b/debian/acl2.dirs new file mode 100644 index 0000000..e772481 --- /dev/null +++ b/debian/acl2.dirs @@ -0,0 +1 @@ +usr/bin diff --git a/debian/acl2.docs b/debian/acl2.docs new file mode 100644 index 0000000..7d2907b --- /dev/null +++ b/debian/acl2.docs @@ -0,0 +1,2 @@ +debian/mini-proveall.out +debian/test.log diff --git a/debian/acl2.manpages b/debian/acl2.manpages new file mode 100644 index 0000000..6684947 --- /dev/null +++ b/debian/acl2.manpages @@ -0,0 +1 @@ +debian/acl2.1 diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..54907d6 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,931 @@ +acl2 (7.4dfsg-3) unstable; urgency=medium + + * build-dep latest gcl + * revert mxgot for mips64 + + -- Camm Maguire <camm@debian.org> Thu, 08 Jun 2017 22:34:51 +0000 + +acl2 (7.4dfsg-2) unstable; urgency=medium + + * Set GCL_MULTIPROCESS_MEMORY_POOL for certifications + * build-dep latest gcl for mips64el fix + * Bug fix: "build fails on mips (mips-aql-05)", thanks to Héctor Orón + Martínez (Closes: #863224). + * mxgot .acl2 files patch + + -- Camm Maguire <camm@debian.org> Sun, 28 May 2017 12:14:24 +0000 + +acl2 (7.4dfsg-1) unstable; urgency=medium + + * New upstream release + + -- Camm Maguire <camm@debian.org> Mon, 08 May 2017 16:58:52 +0000 + +acl2 (7.2dfsg-3) unstable; urgency=medium + + * build-dep against latest gcl + * upstream pathname patch + + -- Camm Maguire <camm@debian.org> Sat, 15 Oct 2016 11:39:07 +0000 + +acl2 (7.2dfsg-2) unstable; urgency=medium + + * Bug fix: "FTBFS in kfreebsd-amd64", thanks to Andreas Beckmann + (Closes: #815312). Reduce GCL_MEM_MULTIPLE setting. + * Bug fix: "FTBFS in stretch (looks like the same problem in maxima)", + thanks to Santiago Vila (Closes: #819447). + + -- Camm Maguire <camm@debian.org> Tue, 03 May 2016 15:05:07 +0000 + +acl2 (7.2dfsg-1) unstable; urgency=medium + + * New upstream release + * Bug fix: "Please do not hide the output from tests", thanks to + Santiago Vila (Closes: #819446). + * Bug fix: "FTBFS in stretch (looks like the same problem in maxima)", + thanks to Santiago Vila (Closes: #819447). + + -- Camm Maguire <camm@debian.org> Wed, 13 Apr 2016 13:11:10 +0000 + +acl2 (7.1dfsg-2) unstable; urgency=medium + + * rebuild latest gcl, tail recursive equal works around setrlimit bug on + s390 + + -- Camm Maguire <camm@debian.org> Tue, 27 Oct 2015 19:33:53 +0000 + +acl2 (7.1dfsg-1) unstable; urgency=medium + + * Bug fix: "[acl2] Some sources are not included in your package", + thanks to Bastien ROUCARIÈS (Closes: #787368). + Repackage to add missing sources and delete questionable files. + Removed files in orig tarball that are removed by clean target: + books/workshops/1999/ivy/ivy-v2/ivy-sources/arithmetic.lisp.bak + books/workshops/1999/ivy/ivy-v2/ivy-sources/util/checker.orig + books/workshops/1999/ivy/ivy-v2/ivy-sources/util/make-saved-ivy.orig + books/workshops/1999/ivy/ivy-v2/ivy-sources/util/sivy.orig + books/workshops/1999/ivy/ivy-v2/ivy-sources/util/ivy.orig + Removed sparc binary inadvertently included in upstream: + books/workshops/2003/schmaltz-al-sammane-et-al/support/acl2link + Added katex sources to debian/missing-sources: + debian/missing-sources/books/xdoc/fancy/lib/katex/katex.js + debian/missing-sources/books/xdoc/fancy/lib/katex/katex.min.css + debian/missing-sources/books/xdoc/fancy/lib/katex/src/* + Removed rfc file with non-dfsg licence: + books/centaur/quicklisp/bundle/software/rfc2388-20130720-git/doc/rfc2388.txt + Added source to debian/missing-sources to remove a lintian false positive: + debian/missing-sources/books/workshops/2000/shumsky/slides2_files/script.js + * build-dep latest gcl + * updated README.Debian.in + * remove clisp scripts from acl2-books-source + * remove .gitignore from acl2-doc + * added lintian override for (non) extra-license-file + books/centaur/aignet/copying.cert + + -- Camm Maguire <camm@debian.org> Wed, 21 Oct 2015 02:21:10 +0000 + +acl2 (7.1-3) unstable; urgency=medium + + * don't pre-allocate contiguous blocks in acl2.lisp + * build-dep latest gcl + * revert code-block-reserve to default set by upstream + + -- Camm Maguire <camm@debian.org> Fri, 09 Oct 2015 01:09:05 +0000 + +acl2 (7.1-2) unstable; urgency=medium + + * build-dep latest gcl + * 50M code-block-reserve on amd64 + + -- Camm Maguire <camm@debian.org> Mon, 28 Sep 2015 15:57:09 +0000 + +acl2 (7.1-1) unstable; urgency=medium + + * New upstream release + * build-dep latest gcl + + -- Camm Maguire <camm@debian.org> Fri, 29 May 2015 14:33:46 +0000 + +acl2 (7.0-1) unstable; urgency=medium + + * New upstream release + + -- Camm Maguire <camm@debian.org> Fri, 16 Jan 2015 10:35:45 -0500 + +acl2 (6.5-5) unstable; urgency=medium + + * fix syntax error in debian/rules + + -- Camm Maguire <camm@debian.org> Sun, 26 Oct 2014 12:51:22 -0400 + +acl2 (6.5-4) unstable; urgency=medium + + * restore tick output for slow autobuilders + + -- Camm Maguire <camm@debian.org> Sat, 25 Oct 2014 09:01:06 -0400 + +acl2 (6.5-3) unstable; urgency=medium + + * build-dep latest gcl + * abort centaur/vl/top cert if insufficient memory (mips autobuild) + + -- Camm Maguire <camm@debian.org> Fri, 24 Oct 2014 14:07:33 -0400 + +acl2 (6.5-2) unstable; urgency=medium + + * build-dep latest gcl + + -- Camm Maguire <camm@debian.org> Wed, 20 Aug 2014 00:37:33 +0000 + +acl2 (6.5-1) unstable; urgency=low + + * New upstream release + + -- Camm Maguire <camm@debian.org> Tue, 05 Aug 2014 16:04:06 +0000 + +acl2 (6.4-5) unstable; urgency=low + + * rebuild against latest gcl + * lintian cleanups + + -- Camm Maguire <camm@debian.org> Fri, 25 Jul 2014 15:25:39 +0000 + +acl2 (6.4-4) unstable; urgency=low + + * parse and use parallel keyword in DEB_BUILD_OPTIONS + + -- Camm Maguire <camm@debian.org> Thu, 15 May 2014 18:49:32 +0000 + +acl2 (6.4-3) unstable; urgency=low + + * set HOME in rule to build saved_acl2.c + * Bug fix: "not buildable on buildds on some architectures", thanks to + Ivo De Decker (Closes: #747286). + + -- Camm Maguire <camm@debian.org> Fri, 09 May 2014 15:38:15 +0000 + +acl2 (6.4-2) unstable; urgency=low + + * certify-books run with -j 8 -l 2.95 + * Bug fix: "Process running beyond build (missing escape in + debian/rules)", thanks to Michael Tautschnig (Closes: #746203). + * build-dep latest gcl + + -- Camm Maguire <camm@debian.org> Wed, 07 May 2014 18:31:48 +0000 + +acl2 (6.4-1) unstable; urgency=low + + * New upstream release + + -- Camm Maguire <camm@debian.org> Mon, 13 Jan 2014 16:14:44 +0000 + +acl2 (6.3-6) unstable; urgency=low + + * rebuild against latest gcl + + -- Camm Maguire <camm@debian.org> Fri, 15 Nov 2013 16:11:57 +0000 + +acl2 (6.3-5) unstable; urgency=low + + * rebuild against latest gcl + + -- Camm Maguire <camm@debian.org> Fri, 18 Oct 2013 16:10:57 +0000 + +acl2 (6.3-4) unstable; urgency=low + + * set HOME for mini-proveall make + + -- Camm Maguire <camm@debian.org> Tue, 15 Oct 2013 14:12:15 +0000 + +acl2 (6.3-3) unstable; urgency=low + + * set HOME to $(pwd) + + -- Camm Maguire <camm@debian.org> Mon, 14 Oct 2013 15:09:48 +0000 + +acl2 (6.3-2) unstable; urgency=low + + * build dep against latest gcl + + -- Camm Maguire <camm@debian.org> Sat, 12 Oct 2013 01:46:31 +0000 + +acl2 (6.3-1) unstable; urgency=low + + * New upstream release + + -- Camm Maguire <camm@debian.org> Wed, 02 Oct 2013 20:19:51 +0000 + +acl2 (6.2-8) unstable; urgency=low + + * Allow certification failures for 1) dlopen machines, as we cannot + control the surpassed 1024 maximum dlopen limit, and 2) machines with + an insufficient hard limit on data segment size (e.g. kfreebsd-i386, or any + machine which cannot brk 1Gb). + * add build-dep on texinfo + * add upstream certificate relocation patch to other-events.lisp + + -- Camm Maguire <camm@debian.org> Mon, 09 Sep 2013 15:27:04 +0000 + +acl2 (6.2-7) unstable; urgency=low + + * build-dep against latest gcl + * again allow optimize-maximum-pages in elementary-bounders.acl2 + + -- Camm Maguire <camm@debian.org> Tue, 06 Aug 2013 11:30:55 +0000 + +acl2 (6.2-6) unstable; urgency=low + + * fix elementary-bounders.acl2 + + -- Camm Maguire <camm@debian.org> Mon, 29 Jul 2013 18:54:53 +0000 + +acl2 (6.2-5) unstable; urgency=low + + * (setq si::*optimize-maximum-pages* nil) in elementary-bounders.acl2 + * build-dep against latest gcl + + -- Camm Maguire <camm@debian.org> Sat, 27 Jul 2013 12:49:46 +0000 + +acl2 (6.2-4) unstable; urgency=low + + * build-dep against latest gcl + + -- Camm Maguire <camm@debian.org> Tue, 23 Jul 2013 18:11:51 +0000 + +acl2 (6.2-3) unstable; urgency=low + + * build-dep against latest gcl + + -- Camm Maguire <camm@debian.org> Sat, 20 Jul 2013 02:21:17 +0000 + +acl2 (6.2-2) unstable; urgency=low + + * Add (in-package :acl2) preceeding save-exec in final cert image + modification stage to support #-native-reloc targets + + -- Camm Maguire <camm@debian.org> Mon, 15 Jul 2013 16:34:41 +0000 + +acl2 (6.2-1) unstable; urgency=low + + * New upstream release + + -- Camm Maguire <camm@debian.org> Thu, 11 Jul 2013 22:02:56 +0000 + +acl2 (6.1-6) unstable; urgency=low + + * build-dep against latest gcl + + -- Camm Maguire <camm@debian.org> Tue, 02 Jul 2013 16:10:25 +0000 + +acl2 (6.1-5) unstable; urgency=low + + * reinstate skipped books and build depend on latest gcl + + -- Camm Maguire <camm@debian.org> Fri, 21 Jun 2013 23:14:46 +0000 + +acl2 (6.1-4) unstable; urgency=low + + * skip books/centaur/vl/transforms/xf-sizing.lisp, which takes too much memory + + -- Camm Maguire <camm@debian.org> Sun, 26 May 2013 03:50:49 +0000 + +acl2 (6.1-3) unstable; urgency=low + + * skip books/centaur/defrstobj/basic-tests.lisp, which takes too much memory + + -- Camm Maguire <camm@debian.org> Thu, 23 May 2013 13:20:29 +0000 + +acl2 (6.1-2) unstable; urgency=low + + * skip elementary-bounders.lisp certification, which takes too much memory + + -- Camm Maguire <camm@debian.org> Tue, 21 May 2013 17:15:51 +0000 + +acl2 (6.1-1) unstable; urgency=low + + * New upstream release + + -- Camm Maguire <camm@debian.org> Tue, 23 Apr 2013 14:52:39 +0000 + +acl2 (6.0-3) unstable; urgency=low + + * Lintian cleanups + * certify centaur books with memory adjustments (lint.acl2, top.acl2) + + -- Camm Maguire <camm@debian.org> Thu, 17 Jan 2013 23:12:05 +0000 + +acl2 (6.0-2) unstable; urgency=low + + * HOME="/tmp" environment for make DOC + + -- Camm Maguire <camm@debian.org> Sun, 13 Jan 2013 17:54:15 +0000 + +acl2 (6.0-1) unstable; urgency=low + + * New upstream release + + -- Camm Maguire <camm@debian.org> Mon, 07 Jan 2013 21:45:40 +0000 + +acl2 (5.0-1) unstable; urgency=low + + * New upstream release + * books retrieved separately from http://acl2-books.googlecode.com/files/books-5.0.tar.gz + * Bug fix: "Should build-depend on emacs23 | emacs24", thanks to + svante.signell@telia.com</a>; (Closes: #682719). + + -- Camm Maguire <camm@debian.org> Fri, 24 Aug 2012 18:45:28 +0000 + +acl2 (4.3-3) unstable; urgency=low + + * Bug fix: "unowned file /usr/local/share/texmf/ls-R after purge (policy + 6.8, 9.1.2)", thanks to Andreas Beckmann (Closes: #669380). + * Bug fix: "FTBFS: | /«PKGBUILDDIR»/books/tools/defsum.c:7456:5: error: + expected expression before ')' token", thanks to Lucas + Nussbaum (Closes: #669442). Build-dep on latest gcl + + -- Camm Maguire <camm@debian.org> Fri, 20 Apr 2012 12:59:26 +0000 + +acl2 (4.3-2) unstable; urgency=low + + * remove special NO_STRIP for ppc + * multiply-stacks by 4 on #-native-reloc + * Bug fix: "Please add support for build-arch and build-indep targets", + thanks to Niels Thykier (Closes: #647919). + + -- Camm Maguire <camm@debian.org> Fri, 20 Jan 2012 14:18:55 +0000 + +acl2 (4.3-1) unstable; urgency=low + + * New upstream release + + -- Camm Maguire <camm@debian.org> Mon, 09 Jan 2012 21:41:00 +0000 + +acl2 (4.1-5) unstable; urgency=low + + * build depend on latest gcl + * turn off si::*optimize-maximum-pages* in reverse-by-separation.acl2 + * remove unnecessary patch from serialize-tests.lisp + + -- Camm Maguire <camm@debian.org> Fri, 05 Nov 2010 16:19:11 +0000 + +acl2 (4.1-4) unstable; urgency=low + + * build dep on latest gcl + + -- Camm Maguire <camm@debian.org> Wed, 27 Oct 2010 20:47:24 +0000 + +acl2 (4.1-3) unstable; urgency=low + + * build-dep latest gcl + * Bug fix: "FTBFS on mips: Terminated", thanks to Cyril Brulebois + (Closes: #599946). + * Bug fix: "FTBFS on mipsel: Unrecoverable error: Segmentation + violation..", thanks to Cyril Brulebois (Closes: #599998). + + -- Camm Maguire <camm@debian.org> Wed, 20 Oct 2010 16:15:56 +0000 + +acl2 (4.1-2) unstable; urgency=low + + * build-dep latest gcl + * Bug fix: "FTBFS (powerpc): ls: cannot access + tiny.cert: No such file or directory", thanks to Philipp Kern (Closes: + #597278). + + -- Camm Maguire <camm@debian.org> Thu, 23 Sep 2010 12:44:54 +0000 + +acl2 (4.1-1) unstable; urgency=low + + * New upstream release + + -- Camm Maguire <camm@debian.org> Sun, 05 Sep 2010 00:27:43 +0000 + +acl2 (4.0-3) unstable; urgency=low + + * compile nats to avoid invocation stack overflow on #-native-reloc + machines + + -- Camm Maguire <camm@debian.org> Fri, 09 Jul 2010 13:00:12 +0000 + +acl2 (4.0-2) unstable; urgency=low + + * Work around absence of HOME in buildd environments. + + -- Camm Maguire <camm@debian.org> Thu, 08 Jul 2010 16:14:04 +0000 + +acl2 (4.0-1) unstable; urgency=low + + * New upstream release + + -- Camm Maguire <camm@debian.org> Wed, 07 Jul 2010 21:49:46 +0000 + +acl2 (3.6.1-2) unstable; urgency=low + + * Bug fix: "acl2 depends on old / broken emacs22 package", thanks to + Andreas Barth (Closes: #585405). + * lintian fixes + + -- Camm Maguire <camm@debian.org> Thu, 10 Jun 2010 14:09:37 +0000 + +acl2 (3.6.1-1) unstable; urgency=low + + * New upstream release + + -- Camm Maguire <camm@debian.org> Sun, 06 Jun 2010 19:58:55 +0000 + +acl2 (3.6-4) unstable; urgency=low + + * Bug fix: "FTBFS [hppa] - **CERTIFICATION FAILED** for ram2b.lisp", + thanks to dann frazier (Closes: #564247). + + -- Camm Maguire <camm@debian.org> Mon, 11 Jan 2010 17:44:36 +0000 + +acl2 (3.6-3) unstable; urgency=low + + * Bug fix: "FTBFS on kfreebsd-i386: /bin/sh: line 1: 42209 Segmentation + fault gcl < workxxx", thanks to Cyril Brulebois (Closes: #563604). + + -- Camm Maguire <camm@debian.org> Mon, 04 Jan 2010 18:12:16 +0000 + +acl2 (3.6-2) unstable; urgency=low + + * Bug fix: "FTBFS [alpha, hppa] - getprop.cert: No such file or + directory", thanks to dann frazier (Closes: #562207). Build-depend on + gcl >= 2.6.7-51. + * Bug fix: "adds non-existent TAGS file to tag file list", thanks to + Timo Juhani Lindfors (Closes: #505812). Don't automatically load tags + table. + + -- Camm Maguire <camm@debian.org> Sun, 03 Jan 2010 13:26:38 +0000 + +acl2 (3.6-1) unstable; urgency=low + + * New upstream release + + [ Camm Maguire ] + * Bug fix: "replacing libreadline5-dev build dependency with + libreadline-dev", thanks to Matthias Klose (Closes: #553715). + + -- Camm Maguire <camm@debian.org> Tue, 15 Dec 2009 03:53:25 +0000 + +acl2 (3.4-2) unstable; urgency=low + + * New maintainer address + * sparc sgc workaround -- disable sgc here only + + -- Camm Maguire <camm@debian.org> Mon, 23 Feb 2009 01:54:24 +0000 + +acl2 (3.4-1) unstable; urgency=low + + * New upstream release + * Bug fix: "acl2-status.txt should contain :INITIALIZED.", thanks to + Lucas Nussbaum (Closes: #494328). New release works around compiler + issue. + * Bug fix: "FTBFS when converted to new source format 3.0 (quilt)", + thanks to hertzog@debian.org</a>; (Closes: #482594). patches -> + dpatches + + -- Camm Maguire <camm@enhanced.com> Sun, 24 Aug 2008 21:26:46 +0000 + +acl2 (3.3-1.1) unstable; urgency=low + + * Non-maintainer upload. + * Build depend on time, so that it works with shells other than bash + (Closes: #459060). + + -- Peter Eisentraut <petere@debian.org> Sat, 05 Apr 2008 18:49:49 +0200 + +acl2 (3.3-1) unstable; urgency=low + + * New upstream release + * build-dep on latest gcl to get arm build + * Bug fix: "acl2's idea of the system book path is wrong", thanks to + Sami Liedes (Closes: #440353). Apply suggested fix to wrapper script, + Thanks! + * Bug fix: "acl2-emacs: please prefer emacs22", thanks to Tatsuya + Kinoshita (Closes: #434915). prefer emacs22 + * Bug fix: "acl2: not binNMU safe", thanks to Lior Kaplan (Closes: + #430471). Apply suggested patch, Thanks! + * build-dep texlive-latex-recommended + + -- Camm Maguire <camm@enhanced.com> Mon, 03 Dec 2007 10:10:09 -0500 + +acl2 (3.2-1) unstable; urgency=low + + * New upstream release + + -- Camm Maguire <camm@enhanced.com> Thu, 17 May 2007 10:41:35 -0400 + +acl2 (3.1-1) unstable; urgency=low + + * New upstream release + + -- Camm Maguire <camm@enhanced.com> Mon, 4 Dec 2006 10:35:42 -0500 + +acl2 (3.0.1-8) unstable; urgency=low + + * Fix dlopen.lisp.in + + -- Camm Maguire <camm@enhanced.com> Thu, 19 Oct 2006 12:52:10 -0400 + +acl2 (3.0.1-7) unstable; urgency=low + + * Build dep on libxmu-dev libxaw7-dev + + -- Camm Maguire <camm@enhanced.com> Wed, 18 Oct 2006 16:36:26 -0400 + +acl2 (3.0.1-6) unstable; urgency=low + + * really change dlopen + * build dep on gcl_2.6.7-27 + + -- Camm Maguire <camm@enhanced.com> Tue, 17 Oct 2006 18:19:47 -0400 + +acl2 (3.0.1-5) unstable; urgency=low + + * Add user::*fast-acl2-gcl-build* and user::*acl2-keep-tmp-files* + parameters to dlopen following upstream + * Build-Depend on gcl_2.6.7-26 + + -- Camm Maguire <camm@enhanced.com> Mon, 16 Oct 2006 18:05:05 -0400 + +acl2 (3.0.1-4) unstable; urgency=low + + * Build-Depend on gcl_2.6.7-25 + + -- Camm Maguire <camm@enhanced.com> Thu, 12 Oct 2006 14:41:53 -0400 + +acl2 (3.0.1-3) unstable; urgency=low + + * Build-Depend on gcl_2.6.7-23 + * Newer standards + + -- Camm Maguire <camm@enhanced.com> Wed, 11 Oct 2006 11:09:29 -0400 + +acl2 (3.0.1-2) unstable; urgency=low + + * rebuild against newer gcl + + -- Camm Maguire <camm@enhanced.com> Wed, 30 Aug 2006 18:53:50 -0400 + +acl2 (3.0.1-1) unstable; urgency=low + + * New upstream release + + -- Camm Maguire <camm@enhanced.com> Wed, 2 Aug 2006 17:02:24 +0000 + +acl2 (3.0-1) unstable; urgency=low + + * New upstream release + * acl2-books-source and acl2-books-certs depend on mathcing version of + acl2, Closes: #339032. + * Fix emacs startup for xemacs -- remove error only, no autosetup of + tags table for xemacs, appears impossible. Closes: #349401 + + -- Camm Maguire <camm@enhanced.com> Sat, 10 Jun 2006 17:42:09 +0000 + +acl2 (2.9.4-1) unstable; urgency=low + + * New upstream release + + -- Camm Maguire <camm@enhanced.com> Wed, 23 Nov 2005 23:31:29 +0000 + +acl2 (2.9.3-7) unstable; urgency=low + + * build depend on >= gcl-2.6.7-11 to get default maxpage fix for amd64, + Closes: #323666. + + -- Camm Maguire <camm@enhanced.com> Thu, 20 Oct 2005 12:46:17 +0000 + +acl2 (2.9.3-6) unstable; urgency=low + + * build depend on >= gcl-2.6.7-10 to get ppc gcc configure fix + + -- Camm Maguire <camm@enhanced.com> Thu, 13 Oct 2005 18:36:11 +0000 + +acl2 (2.9.3-5) unstable; urgency=low + + * build depend on >= gcl 2.6.7-8 for 64bit fasd data/fixnum fix + + -- Camm Maguire <camm@enhanced.com> Wed, 5 Oct 2005 19:15:41 +0000 + +acl2 (2.9.3-4) unstable; urgency=low + + * build depend on >= gcl 2.6.7-8 for 64bit bignum/fixnum fix + + -- Camm Maguire <camm@enhanced.com> Sun, 2 Oct 2005 11:23:30 +0000 + +acl2 (2.9.3-3) unstable; urgency=low + + * Build-depend on gcl >= 2.6.7-7 to get dlopen fix needed for mips, + alpha, hppa, and ia64 + * rework build strategy switching based on the native-reloc feature in + the installed gcl. + + -- Camm Maguire <camm@enhanced.com> Thu, 29 Sep 2005 18:32:02 +0000 + +acl2 (2.9.3-2) unstable; urgency=high + + * Depend on gcl 2.6.7-6 or greater with its own binutils included, + remove dependency on binutils-dev + + -- Camm Maguire <camm@enhanced.com> Tue, 20 Sep 2005 19:49:42 +0000 + +acl2 (2.9.3-1) unstable; urgency=low + + * New upstream release + * probe-file -> truename *infix-directory* patch for gcl 2.6.7 + + -- Camm Maguire <camm@enhanced.com> Fri, 12 Aug 2005 20:57:23 +0000 + +acl2 (2.9.2-1) unstable; urgency=low + + * New upstream release + + -- Camm Maguire <camm@enhanced.com> Mon, 25 Apr 2005 14:00:42 +0000 + +acl2 (2.9.1-1) unstable; urgency=high + + * New upstream release + * Bug fix: "acl2: :system dir is wrong", thanks to Patrick Calhoun + (Closes: #284780). Apologies, had inadvertently reverted previous + fix. Now include a GNUmakefile patch setting ACL2_BOOKS_DIR. + + -- Camm Maguire <camm@enhanced.com> Tue, 22 Feb 2005 18:34:32 +0000 + +acl2 (2.9-3) unstable; urgency=low + + * Update README.Debian regarding building auxiliary workshops and + non-std packages + + -- Camm Maguire <camm@enhanced.com> Sat, 8 Jan 2005 19:03:36 +0000 + +acl2 (2.9-2) unstable; urgency=high + + * Don't strip saved_acl2 on powerpc, see #210809. + + -- Camm Maguire <camm@enhanced.com> Fri, 5 Nov 2004 21:39:50 +0000 + +acl2 (2.9-1) unstable; urgency=high + + * New upstream release + * Remove nullification of allocation list from debian/patches.in + * Add debian/dlopen.lisp for building on ia64,mips(el),alpha and hppa + * Revert to upstream build procedure on all other platforms + * doc-notes.txt is gone (from acl2-emacs.doc) + * mv nsaved_acl2.gcl saved_acl2 for backward compatibility with 2.8, as + we provide our own shell script wrapper. + * Remove debian/acl2-doc.info in favor of compile-time generated command + line arguments to dh_installinfo + + -- Camm Maguire <camm@enhanced.com> Mon, 25 Oct 2004 13:29:46 +0000 + +acl2 (2.8-6) unstable; urgency=low + + * acl2 suggests acl2-emacs + + -- Camm Maguire <camm@enhanced.com> Thu, 7 Oct 2004 14:40:35 +0000 + +acl2 (2.8-5) unstable; urgency=low + + * Bug fix: "acl2-emacs: ACL2 emacs mode produces an error on acl2 + defstobjs definition", thanks to David (Closes: #260112). Small patch + to acl2-mode.el added to debian/patches. + * Build depend on latest gcl for performance and stability improvements. + + -- Camm Maguire <camm@enhanced.com> Fri, 17 Sep 2004 13:11:05 +0000 + +acl2 (2.8-4) unstable; urgency=low + + * Bug fix: "FTBFS: missing Build-Depends binutils-dev", thanks to Goswin + von Brederlow (Closes: #251695). Make build-depends on binutils-dev + valid for all platforms + + -- Camm Maguire <camm@enhanced.com> Mon, 31 May 2004 18:32:56 +0000 + +acl2 (2.8-3) unstable; urgency=low + + * move doc-notes.txt to acl2-emacs + * copyright and control file clarifications + * removal of Debian specific files from distribution list in READE.Debian + * addition of arithmetic-axioms.txt and fast-notes.txt to acl2-doc + * Removal of .final certificate extension from list in README.Debian + * doc-base rephrasing + * (setq *acl2-allocation-alist* nil) in debian/patches.in for enhanced + performance with recent gcl + + -- Camm Maguire <camm@enhanced.com> Tue, 11 May 2004 20:45:14 +0000 + +acl2 (2.8-2) unstable; urgency=low + + * Bug fix: "acl2: :system dir is wrong", thanks to Cesar Eduardo Barros + (Closes: #246721). Supply final system directory in POST variable in + debian/rules. + + -- Camm Maguire <camm@enhanced.com> Fri, 30 Apr 2004 18:54:36 +0000 + +acl2 (2.8-1) unstable; urgency=low + + * New upstream release + * Bug fix: "Inefficient packaging of arch independent data", thanks to + Steve McIntyre (Closes: #232883). Split package into several + components. + + -- Camm Maguire <camm@enhanced.com> Fri, 16 Apr 2004 03:35:25 +0000 + +acl2 (2.7-9) unstable; urgency=low + + * Build depend on latest gcl to try SAFE_FREAD fix for m68k and SGC + runtime check as alpha libc bug workaround + * echo any failed mini-proveall results + * require full test to succeed for build to complete + + -- Camm Maguire <camm@enhanced.com> Thu, 12 Feb 2004 15:08:14 +0000 + +acl2 (2.7-8) unstable; urgency=low + + * Fix bad directory names pertaining to earlier version + * Capitalize ACL2 in doc-base file + * Cleanup copyright file + * Replace build directory with install directory in cert files + * Apply fix to proof-checker-b.lisp + * Add a placeholder manpage + * remove dh-make template files + * newer standards + * dh_compat 4 + * cleanup gcl build dependencies + * build-depend on >= gcl-2.6.1-23 for readline fixes + * debian/patches mechanism to build cert files with correct pathnames at + time of installation + * README.Debian clarifying ACL2 vs. ACL2(r) + * Patch to banner indicating binary includes corrected proof-checker.lisp + * Remove Makefiles from distribution, replace with .acl2 files as + discussed with upstream + * Add bdd/bit-vector-reader.lsp and bdd/be/* files to distribution as + requested by upstream + * Add TAGS file for source perusal, and modify tags-table-list in + emacs startup file + * distribute lisp files in interface/infix + * Protect interface/infix/sloop.lisp with #-gcl and restore to + distribution and makefile + * doinfix an acl2 example + * Add emacs/doc-notes.txt as acl2 doc file + * Add note in man page about availability of online documentation + * Add .txt and .html files from books/textbook to acl2-doc package + * mv CLI.sty into /usr/share/texmf/tex/latex, run texhash on postinst + and postrm, and depend on tetex-extra + * updated fsf address in copyright file + * gathered all patches outside the debian/ subdir into patches.in, so + that apt-get -q source acl2 will produce a pristine tree for the user + as requested upstream. + * Add table of source and binary file locations in README.Debian as + requested by upstream + * Updated watch file for new upstream links + + -- Camm Maguire <camm@enhanced.com> Thu, 5 Feb 2004 15:22:05 +0000 + +acl2 (2.7-7) unstable; urgency=low + + * More verbose testing output to overcome autobuild timeout problems + + -- Camm Maguire <camm@enhanced.com> Tue, 10 Dec 2002 13:20:34 -0500 + +acl2 (2.7-6) unstable; urgency=low + + * new gcl for m68k, Closes: #171593 + + -- Camm Maguire <camm@enhanced.com> Thu, 5 Dec 2002 08:30:11 -0500 + +acl2 (2.7-5) unstable; urgency=low + + * New gcl fixes for arm + * cat to build log failed cert output + + -- Camm Maguire <camm@enhanced.com> Mon, 25 Nov 2002 10:13:16 -0500 + +acl2 (2.7-4) unstable; urgency=low + + * Fix bad patch + + -- Camm Maguire <camm@enhanced.com> Thu, 21 Nov 2002 23:40:09 -0500 + +acl2 (2.7-3) unstable; urgency=low + + * New gcl on m68k to fix cache flushes, Closes: #170084 + * Book certification failures not fatal for now + + -- Camm Maguire <camm@enhanced.com> Thu, 21 Nov 2002 17:53:51 -0500 + +acl2 (2.7-2) unstable; urgency=low + + * Build-depends on tetex-base + + -- Camm Maguire <camm@enhanced.com> Tue, 19 Nov 2002 20:11:39 -0500 + +acl2 (2.7-1) unstable; urgency=low + + * New upstream release + * new modules linear-a linear-b and non-linear + * certify all books + + -- Camm Maguire <camm@enhanced.com> Mon, 18 Nov 2002 20:26:16 -0500 + +acl2 (2.6-15) unstable; urgency=low + + * Correct final pathnames in certs + * remove TMP1.lisp + + -- Camm Maguire <camm@enhanced.com> Sun, 17 Nov 2002 16:36:09 -0500 + +acl2 (2.6-14) unstable; urgency=low + + * Fix bad diff, Closes #169493 + + -- Camm Maguire <camm@enhanced.com> Sun, 17 Nov 2002 12:28:46 -0500 + +acl2 (2.6-13) unstable; urgency=low + + * Fix acl2 path issue in infix subbuild + + -- Camm Maguire <camm@enhanced.com> Sun, 17 Nov 2002 08:58:20 -0500 + +acl2 (2.6-12) unstable; urgency=low + + * Turn off default-system-p in final image + * tests in build target to avoid fakeroot bug on ia64, better here + anyway + * increased files distributed as recommended by upstream + * emacs interface fixes to support all Debian emacs flavors + + -- Camm Maguire <camm@enhanced.com> Sat, 16 Nov 2002 23:22:25 -0500 + +acl2 (2.6-11) unstable; urgency=low + + * Build-depends on binutils-dev for arches using bfd + + -- Camm Maguire <camm@enhanced.com> Wed, 13 Nov 2002 21:35:22 -0500 + +acl2 (2.6-10) unstable; urgency=low + + * Added missing Build-deps: Closes: #168968 + + -- Camm Maguire <camm@enhanced.com> Wed, 13 Nov 2002 14:04:32 -0500 + +acl2 (2.6-9) unstable; urgency=low + + * gcl >= -67 for ppc and m68k + + -- Camm Maguire <camm@enhanced.com> Wed, 13 Nov 2002 12:02:44 -0500 + +acl2 (2.6-8) unstable; urgency=low + + * New portable gcl build mechanism for acl2, Closes: #167618 + + -- Camm Maguire <camm@enhanced.com> Sun, 10 Nov 2002 12:48:44 -0500 + +acl2 (2.6-7) unstable; urgency=low + + * Add test targets + * acl2-mode.el fix, Closes: #167356 + + -- Camm Maguire <camm@enhanced.com> Sun, 10 Nov 2002 12:48:37 -0500 + +acl2 (2.6-6) unstable; urgency=low + + * Better (less restrictive) gcl Build-Depends + * Newer standards + * acl2-doc in section doc + + -- Camm Maguire <camm@enhanced.com> Thu, 31 Oct 2002 21:49:44 -0500 + +acl2 (2.6-5) unstable; urgency=low + + * Patch acl2-mode.el to handle differing xemacs/emacs behavior, + Closes: #167012 + + -- Camm Maguire <camm@enhanced.com> Wed, 30 Oct 2002 11:58:20 -0500 + +acl2 (2.6-4) unstable; urgency=low + + * Rerelease to use new gcl with fixes on ia64, hppa and arm + + -- Camm Maguire <camm@enhanced.com> Tue, 29 Oct 2002 20:30:42 -0500 + +acl2 (2.6-3) unstable; urgency=low + + * Add emacs21 | emacsen, debhelper to Build-Deps + + -- Camm Maguire <camm@enhanced.com> Mon, 28 Oct 2002 18:40:07 -0500 + +acl2 (2.6-2) unstable; urgency=low + + * Fix emacsen and info post-install + + -- Camm Maguire <camm@enhanced.com> Sat, 26 Oct 2002 21:34:36 -0400 + +acl2 (2.6-1) unstable; urgency=low + + * Initial Release. + + -- Camm Maguire <camm@enhanced.com> Sat, 26 Oct 2002 11:58:58 -0400 + + diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..ec63514 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +9 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..4bb58e9 --- /dev/null +++ b/debian/control @@ -0,0 +1,113 @@ +Source: acl2 +Section: math +Priority: optional +Maintainer: Camm Maguire <camm@debian.org> +Build-Depends: gcl ( >= 2.6.12-49), libgmp3-dev, libreadline-dev, emacs24 | emacsen, debhelper ( >= 5), texlive-latex-recommended, libxmu-dev, libxaw7-dev, time, tex-common, texinfo +Standards-Version: 3.9.8 + +Package: acl2 +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Recommends: acl2-source, acl2-books +Suggests: acl2-emacs +Description: Computational Logic for Applicative Common Lisp: main binary + ACL2 is both a programming language in which you can model computer + systems and a tool to help you prove properties of those models. + . + This package contains the base ACL2 binary. + +Package: acl2-source +Architecture: all +Conflicts: acl2 (<= 2.7-9) +Replaces: acl2 (<= 2.7-9) +Depends: ${misc:Depends} +Description: Computational Logic for Applicative Common Lisp: source files + ACL2 is both a programming language in which you can model computer + systems and a tool to help you prove properties of those models. + . + This package contains the lisp source files to the main ACL2 binary. + +Package: acl2-emacs +Architecture: all +Depends: acl2 (>= ${source:Version}), emacs24 | emacsen, ${misc:Depends} +Conflicts: acl2 (<= 2.7-9) +Replaces: acl2 (<= 2.7-9) +Description: Computational Logic for Applicative Common Lisp: emacs interface + ACL2 is both a programming language in which you can model computer + systems and a tool to help you prove properties of those models. + . + This package contains an emacs interface to ACL2. + +Package: acl2-infix +Architecture: any +Recommends: acl2-infix-source (= ${source:Version}) +Depends: acl2 (= ${binary:Version}), texlive-latex-recommended, ${misc:Depends} +Conflicts: acl2 (<= 2.7-9) +Replaces: acl2 (<= 2.7-9) +Description: Computational Logic for Applicative Common Lisp: infix interface + ACL2 is both a programming language in which you can model computer + systems and a tool to help you prove properties of those models. + . + This package contains utilities and libraries to access ACL2 via an + infix notation similar to that used in many non-lisp programming + languages. + +Package: acl2-infix-source +Architecture: all +Depends: ${misc:Depends} +Conflicts: acl2 (<= 2.7-9) +Replaces: acl2 (<= 2.7-9) +Description: Computational Logic for Applicative Common Lisp: infix source + ACL2 is both a programming language in which you can model computer + systems and a tool to help you prove properties of those models. + . + This package contains the source files to the infix interface to + ACL2. + +Package: acl2-books +Architecture: any +Depends: acl2 (= ${binary:Version}), acl2-books-certs (= ${source:Version}), acl2-books-source (= ${source:Version}), ${misc:Depends} +Conflicts: acl2 (<= 2.7-9) +Replaces: acl2 (<= 2.7-9) +Description: Computational Logic for Applicative Common Lisp: compiled libraries + ACL2 is both a programming language in which you can model computer + systems and a tool to help you prove properties of those models. + . + This package contains numerous precompiled and precertified libraries + for use in proving theorems with ACL2. Serious users will no doubt + want to install this package. + +Package: acl2-books-source +Architecture: all +Depends: acl2 (>= ${source:Version}), ${misc:Depends} +Conflicts: acl2 (<= 2.7-9) +Replaces: acl2 (<= 2.7-9) +Description: Computational Logic for Applicative Common Lisp: library sources + ACL2 is both a programming language in which you can model computer + systems and a tool to help you prove properties of those models. + . + This package contains source lisp files to the compiled libraries + supplied in the ACL2-books package. + +Package: acl2-books-certs +Architecture: all +Depends: acl2 (>= ${source:Version}), ${misc:Depends} +Conflicts: acl2 (<= 2.7-9) +Replaces: acl2 (<= 2.7-9) +Description: Computational Logic for Applicative Common Lisp: library certificates + ACL2 is both a programming language in which you can model computer + systems and a tool to help you prove properties of those models. + . + This file contains certification records for the various precompiled + libraries supplied in the ACL2-books package. ACL2 essentially + requires that all included books be certified before use. + +Package: acl2-doc +Depends: ${misc:Depends}, dpkg (>= 1.15.4) | install-info +Architecture: all +Section: doc +Description: Computational Logic for Applicative Common Lisp: documentation + ACL2 is both a programming language in which you can model computer + systems and a tool to help you prove properties of those models. + . + This package contains the documentation for ACL2. diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..f30c079 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,205 @@ +This package was debianized by Camm Maguire <camm@debian.org> on +Sat, 26 Oct 2002 11:58:58 -0400. + +It was downloaded from ftp://ftp.cs.utexas.edu:/pub/moore/acl2/v2-8/ + +Upstream Authors: + + Matt Kaufmann,kaufmann@cs.utexas.edu (main program) + J Strother Moore,moore@cs.utexas.edu (main program) + + University of Texas at Austin (books, partial) + Computational Logic, Inc.,mksmith@acm.org,msmith17@austin.rr.com (books, partial) + John R. Cowles, University of Wyoming (books, partial) + Bishop Brock and J Strother Moore (books, partial) + Panagiotis Manolios and J Strother Moore (books, partial) + Georgia Institute of Technology (books, partial) + Jared Davis,jared@cs.utexas.edu (books, partial) + Panagiotis Manolios,manolios@cc.gatech.edu (books, partial) + Daron Vroon,vroon@cc.gatech.edu (books, partial) + Matt Kaufmann,kaufmann@cs.utexas.edu (books, partial) + +Copyright: + +All files in acl2_6.0.orig.tar.gz, (e.g. all sub-directories outside of "books/"): + +Copyright (c) 2012, Regents of the University of Texas +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +o Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +o Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +o Neither the name of the University of Texas, Austin nor the names of + its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +All files in acl2_6.0.orig-books.tar.gz, (e.g. the contents of the "books/" sub-directory): + + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + +The ACL2 XDOC FANCY VIEWER files are licensed as follows: + + + ACL2 XDOC FANCY VIEWER + License Information + + +Scope of this LICENSE file: + + An XDOC manual has both Viewer Files for displaying topics and Content Files + that store the actual topic data. This LICENSE file describes the copyright + and licensing of the Viewer Files, only. + + The topics in Content Files, such as xindex.js, xdata.js, and (in some + cases) xdata.db, are usually derived from ACL2 books and/or other source + code files. These topics are typically subject to their own copyright and + licensing terms, which are beyond the scope of this LICENSE. + + +Copyright for main source files: + + XDOC Documentation System for ACL2 + Copyright (C) 2009-2013 Centaur Technology + + Contact: + Centaur Technology Formal Verification Group + 7600-C N. Capital of Texas Highway, Suite 300, Austin, TX 78731, USA. + http://www.centtech.com/ + + 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., 51 + Franklin Street, Suite 500, Boston, MA 02110-1335, USA. + + Original author: Jared Davis <jared@centtech.com> + +Copyrights for Supporting Libraries: (within the "lib" directory) + + Hogan: + Copyright 2011 Twitter, Inc. + Released under Apache License + http://twitter.github.io/hogan.js/ + + jQuery: + Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors + Released under the MIT license. + http://jquery.com/ + + jquery.base64.js: + Copyright 2012 Yannick Albert + Released under MIT license. + https://github.com/yckart/jquery.base64.js + + PowerTip: + Copyright 2013 Steven Benner + Released under MIT license. + http://stevenbenner.github.com/jquery-powertip/ + + LazyLoad: + Copyright 2011 Ryan Grove + Released under MIT license. + https://github.com/rgrove/lazyload + + Typeahead: + Copyright 2013 Twitter, Inc. and other contributors + Released under MIT license. + https://github.com/twitter/typeahead + + +Copyrights for other supporting files: + + Original XDOC Images + Copyright 2009-2013 Centaur Technology + License: GNU General Public License + + - leaf.png + - plus.png + - minus.png + - expand_subtopics.png + - collapse_subtopics.png + - favicon.png + - xdoc-home.png + - xdoc-logo.png + + Oxygen Icon Set Images + http://www.oxygen-icons.org/ + Released under GNU General Public License + Accessed 2012-08-13 from: + http://kde-look.org/content/show.php/Oxygen+Icons?content=74184 + + - printer.png + - download.png + - view_flat.png (adapted) + - view_tree.png (adapted) + + External Link Image: + Released under GNU General Public License + Accessed 2013-07-26 from + http://commons.wikimedia.org/wiki/File:Icon_External_Link.png + + - Icon_External_Link.png + + + ACL2 Tour Images (.gif files within the images/ directory) + Copyright 2012 Regents of the University of Texas + Released under a BSD-style license (distributed with ACL2) + + + +On Debian GNU/Linux systems, the complete text of the Apache license can +be found in /usr/share/common-licenses/Apache-2.0. + +On Debian GNU/Linux systems, the complete text of the GNU General +Public License Version 2 can be found in +/usr/share/common-licenses/GPL-2. + diff --git a/debian/dlopen.lisp.in b/debian/dlopen.lisp.in new file mode 100644 index 0000000..7090f2a --- /dev/null +++ b/debian/dlopen.lisp.in @@ -0,0 +1,135 @@ +(in-package 'compiler) +(defun make-user-init (files outn) + + (let* ((c (pathname outn)) + (c (merge-pathnames c (make-pathname :directory '(:current)))) + (o (merge-pathnames (make-pathname :type "o") c)) + (c (merge-pathnames (make-pathname :type "c") c))) + + (with-open-file (st c :direction :output) + (format st "#include ~a~%~%" *cmpinclude*) + + (format st "#define load2(a) do {") + (format st "printf(\"Loading %s...\\n\",(a));") + (format st "load(a);") + (format st "printf(\"Finished %s...\\n\",(a));} while(0)~%~%") + + (let ((p nil)) + (dolist (tem files) + (when (equal (pathname-type tem) "o") + (let ((tem (namestring tem))) + (push (list (si::find-init-name tem) tem) p)))) + + (setq p (nreverse p)) + + (dolist (tem p) + (format st "extern void ~a(void);~%" (car tem))) + (format st "~%") + + (format st "typedef struct {void (*fn)(void);char *s;} Fnlst;~%") + (format st "#define NF ~a~%" (length p)) + (format st "static Fnlst my_fnlst[NF]={") + (dolist (tem p) + (when (not (eq tem (car p))) + (format st ",~%")) + (format st "{~a,\"~a\"}" (car tem) (cadr tem))) + (format st "};~%~%") + + (format st "static int user_init_run;~%") + (format st "#define my_load(a_,b_) {if (!user_init_run && (a_) && (b_)) gcl_init_or_load1((a_),(b_));(a_)=0;(b_)=0;}~%~%") + + (format st "object user_init(void) {~%") + (format st "user_init_run=1;~%") + (dolist (tem files) + (let ((tem (namestring tem))) + (cond ((equal (cadr (car p)) tem) + (format st "gcl_init_or_load1(~a,\"~a\");~%" + (car (car p)) tem) + (setq p (cdr p))) + (t + (format st "load2(\"~a\");~%" tem))))) + (format st "return Cnil;}~%~%") + + (format st "int user_match(const char *s,int n) {~%") + (format st " Fnlst *f;~%") + (format st " for (f=my_fnlst;f<my_fnlst+NF;f++){~%") + (format st " if (f->s && !strncmp(s,f->s,n)) {~%") + (format st " my_load(f->fn,f->s);~%") + (format st " return 1;~%") + (format st " }~%") + (format st " }~%") + (format st " return 0;~%") + (format st "}~%~%"))) + + (compiler-cc c o) + (delete-file c) + + o)) +(in-package 'user) +(let ((si::*collect-binary-modules* t) ;; Collect a list of names of each object file loaded + si::*binary-modules* + (compiler::*default-system-p* t));; .o files to be linked in via ld + ;; must be compiled with :system-p t + + + (let ((com (quote ;; This is a command to build acl2 which will be run twice -- + ;; once in stock gcl, compiling files, loading and recording same + ;; once in an image which is linked via ld from the results of the above + ;; redirecting each load to an initialization of the .o file already + ;; linked into the image by ld + (progn + (load "init.lisp") + (let* ((la (find-symbol "LOAD-ACL2" "ACL2")) ;; acl2::load-acl2 doesn't exist at read-time + (olf (symbol-function la)) + (si::*collect-binary-modules* t)) ;; make sure the second pass watches for + ;; .o loads, for the purpose of triggering an error + (unless (probe-file "axioms.o") ;; no sense to compile twice + (funcall (symbol-function (find-symbol "COMPILE-ACL2" "ACL2"))) + (delete-package "ACL2-PC")) ;; prevent package error when loading after compiling + (funcall olf) ;; must load-acl2 to establish the symbols below + (defparameter user::*fast-acl2-gcl-build* t) + (defparameter user::*acl2-keep-tmp-files* :no-pid) + (let ((sa (find-symbol "SAVE-ACL2" "ACL2")) + (ia (find-symbol "INITIALIZE-ACL2" "ACL2")) + (ib (find-symbol "INCLUDE-BOOK" "ACL2")) + (ap2f (find-symbol "*ACL2-PASS-2-FILES*" "ACL2")) + (ocf (symbol-function 'compiler::compile)) + (osf (symbol-function 'si::save-system))) + (setf (symbol-function 'compiler::compile) ;; For now, run closures interpreted + (lambda (x) (symbol-function x))) ;; At some point, could compile saved + ;; gazonk files without loading (i.e. + ;; returning interpreted code) on first pass + ;; then don't compile by load -> initialize + ;; on second pass. Cannot load via dlopen + ;; more than 1024 files at once, and this is + ;; the only relocation mechanism currently + ;; available on ia64,alpha,mips,hppa + ;; On first attempt, failure on initizlization of + ;; acl2_gazonk3558.o + (setf (symbol-function la) (lambda () nil)) ;; save-acl2 calls load-acl2, but we can't load + ;; twice when initializing in reality. + (setf (symbol-function 'si::save-system) ;; Restore all moved functions on save-system + (lambda (x) + (setf (symbol-function 'compiler::compile) ocf) + (setf (symbol-function la) olf) + (setf (symbol-function 'si::save-system) osf) + (when si::*binary-modules* ;; Saving when a .o has been loaded is a no-no + (error "Loading binary modules prior to image save in dlopen image: ~S~%" + si::*binary-modules*)) + (funcall osf x))) + (let* ((no-save si::*binary-modules*)) ;; Don't call save-system on first pass + (funcall (symbol-function sa) + (list ia (list 'quote ib) ap2f (concatenate 'string (namestring (truename "")) "books/")) ;; save-acl2 + nil + no-save)))))))) + + (eval com) ;; first evaluate the command in gcl + (compiler::link ;; link in the .o files with ld + (remove-duplicates si::*binary-modules* :test (function equal)) ;; collected here + "saved_acl2" ;; new image + (format nil "~S" com) ;; run the build sequence again in this image + ;; with load redirected to initialize + "" + nil))) +(good-bye) + diff --git a/debian/lintian.overrides.old b/debian/lintian.overrides.old new file mode 100644 index 0000000..ff0908b --- /dev/null +++ b/debian/lintian.overrides.old @@ -0,0 +1,2 @@ +extra-license-file: acl2-books-source +extra-license-file: acl2-books-certs diff --git a/debian/missing-sources/books/workshops/2000/shumsky/slides2_files/script.js b/debian/missing-sources/books/workshops/2000/shumsky/slides2_files/script.js new file mode 100644 index 0000000..0c1a13b --- /dev/null +++ b/debian/missing-sources/books/workshops/2000/shumsky/slides2_files/script.js @@ -0,0 +1 @@ +This file is in original source format. diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/katex.js b/debian/missing-sources/books/xdoc/fancy/lib/katex/katex.js new file mode 100644 index 0000000..4a8eb8a --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/katex.js @@ -0,0 +1 @@ +This is a minified file compiled from source files found in the src subdirectory. diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/katex.min.css b/debian/missing-sources/books/xdoc/fancy/lib/katex/katex.min.css new file mode 100644 index 0000000..4a8eb8a --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/katex.min.css @@ -0,0 +1 @@ +This is a minified file compiled from source files found in the src subdirectory. diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/.arcconfig b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/.arcconfig new file mode 100644 index 0000000..1a22a80 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/.arcconfig @@ -0,0 +1,5 @@ +{ + "project_id": "KaTeX", + "conduit_uri": "https://phabricator.khanacademy.org/", + "lint.engine": "ArcanistConfigurationDrivenLintEngine" +} diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/.arclint b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/.arclint new file mode 100644 index 0000000..153cbe3 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/.arclint @@ -0,0 +1,9 @@ +{ + "linters": { + "katex-linter": { + "type": "script-and-regex", + "script-and-regex.script": "make lint || true", + "script-and-regex.regex": "/^(?P<file>\\S+): line (?P<line>\\d+), col \\d+, (?P<message>.*)$/m" + } + } +} diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/.jshintrc b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/.jshintrc new file mode 100644 index 0000000..c8c6370 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/.jshintrc @@ -0,0 +1,68 @@ +{ + "bitwise" : true, + "camelcase" : true, + "curly" : true, + "eqeqeq" : false, + "es3" : true, + "forin" : false, + "immed" : true, + "indent" : 4, + "latedef" : false, + "newcap" : true, + "noarg" : true, + "noempty" : true, + "nonbsp" : true, + "nonew" : true, + "plusplus" : false, + "quotmark" : "double", + "undef" : true, + "unused" : "vars", + "strict" : false, + "trailing" : true, + "maxparams" : 7, + "maxdepth" : 6, + + "asi" : false, + "boss" : false, + "debug" : false, + "eqnull" : true, + "esnext" : false, + "evil" : false, + "expr" : true, + "funcscope" : false, + "globalstrict" : false, + "iterator" : false, + "lastsemic" : false, + "laxbreak" : true, + "laxcomma" : false, + "loopfunc" : false, + "maxerr" : 50, + "multistr" : false, + "notypeof" : false, + "proto" : true, + "scripturl" : false, + "smarttabs" : false, + "shadow" : false, + "sub" : false, + "supernew" : false, + "validthis" : false, + "noyield" : false, + + "browser" : true, + "couch" : false, + "devel" : false, + "dojo" : false, + "jquery" : false, + "mootools" : false, + "node" : true, + "nonstandard" : false, + "prototypejs" : false, + "rhino" : false, + "worker" : false, + "wsh" : false, + "yui" : false, + "globals": { + "JSON": false, + "console": true + } +} diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/.travis.yml b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/.travis.yml new file mode 100644 index 0000000..78e1c01 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +node_js: +- "0.11" +- "0.10" diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/CONTRIBUTING.md b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/CONTRIBUTING.md new file mode 100644 index 0000000..d252839 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/CONTRIBUTING.md @@ -0,0 +1,123 @@ +# Contributing to KaTeX + +We welcome pull requests to KaTeX. If you'd like to add a new symbol, or try to +tackle adding a larger feature, keep reading. If you have any questions, or want +help solving a problem, feel free to stop by our [gitter channel](https://gitter.im/Khan/KaTeX). + +## Helpful contributions + +If you'd like to contribute, try contributing new symbols or functions that +KaTeX doesn't currently support. The wiki has a page which lists [all of the +supported +functions](https://github.com/Khan/KaTeX/wiki/Function-Support-in-KaTeX) as +well as a page that describes how to [examine TeX commands and where to find +rules](https://github.com/Khan/KaTeX/wiki/Examining-TeX) which can be quite +useful when adding new commands. You +can check there to see if we don't support a function you like, or try your +function in the interactive demo at +[http://khan.github.io/KaTeX/](http://khan.github.io/KaTeX/). + +#### Single symbols + +There are many individual symbols that KaTeX doesn't yet support. Read through +the [symbols.js](src/symbols.js) file for more information on how to add a +symbol. + +To figure out the unicode symbol for the symbol you are trying to add, try using +the symbol in MathJax to see what unicode symbol it outputs. An interactive +MathJax shell can be found [here](http://fiddle.jshell.net/YpqVp/41/show/). + +To figure out what group your symbol falls into, look through the symbols list +to find other symbols of a similar kind. (e.g. if you were adding `\neq`, look +for `=`). If you cannot find anything similar, or are unsure, you can try using +your symbol in TeX surrounded by other different kinds of symbols, and seeing +whether your spacing matches the spacing that TeX produces. + +Once your symbol works, check the JavaScript console to make sure you don't get +a message like "Can't find character metrics for _" when you render your symbol. +If you do, check out [extract_ttfs.py](metrics/extract_ttfs.py). + +#### Adding new functions + +Most functions are handled in the [functions.js](src/functions.js) file. Read +the comments in there to get started. If the function you want to add has +similar output to an existing function, see if you can add a new line to that +file to get it to work. + +If your function isn't similar to an existing function, you'll need to add a +line to `functions.js` as well as adding an output function in +[buildHTML.js](src/buildHTML.js) and [buildMathML.js](src/buildMathML.js). + +## Testing + +Local testing can be done by running the node server in `server.js`. Run `make +setup` to install dependencies, and then `make serve` to start the server. + +This will host an interactive editor at +[http://localhost:7936/](http://localhost:7936/) to play around with and test +changes. + +#### Jasmine tests + +The JavaScript parser and some of the tree +builder is tested with Jasmine. These tests can be run either using node with +`make test`, or in the browser by visiting +[http://localhost:7936/test/test.html](http://localhost:7936/test/test.html). + +The Jasmine tests should be run after every change, even the addition of small +symbols. However, [Travis](https://travis-ci.org/Khan/KaTeX/) will run these +tests when you submit a pull request, in case you forget. + +If you make any changes to Parser.js, add Jasmine tests to ensure they work. + +#### Screenshot tests + +To ensure the final output looks good, we screenshot different expressions. +These tests can be run by using the +[Screenshotter docker](https://github.com/Khan/KaTeX/tree/master/dockers/Screenshotter). + +The screenshot tests should be run if you add anything more significant than +individual symbols. These tests are not automatically run, so please remember! +If the new images are different (meaning they are not byte-by-byte the same as +the old ones), inspect them visually. If there are no visible changes, that is +okay. If things change in a way consistent with your additions, explain what +changed and why. Otherwise, figure out what is causing the changes and fix it! + +If you add a feature that is dependent on the final output looking the way you +created it, add a screenshot test. See +[ss_data.json](test/screenshotter/ss_data.json). + +#### Testing in other browsers + +KaTeX supports all major browsers, including IE 8 and newer. Unfortunately, it +is hard to test new changes in many browsers. If you can, please test your +changes in as many browsers as possible. In particular, if you make CSS changes, +try to test in IE 8, using [modern.ie](http://modern.ie) VMs. + +## Style guide + +Code + + - 4 spaces for indentation + - 80 character line length + - commas last + - declare variables in the outermost scope that they are used + - camelCase for variables in JavaScript + - snake_case for variables in Python + +In general, try to make your code blend in with the surrounding code. + +## Pull Requests + + - link back to the original issue(s) whenever possible + - new commands should be added to the [wiki](https://github.com/Khan/KaTeX/wiki/Function-Support-in-KaTeX) + - commits should be squashed before merging + - large pull requests should be broken into separate pull requests (or multiple logically cohesive commits), if possible + +## CLA + +In order to contribute to KaTeX, you must first sign the CLA, found at www.khanacademy.org/r/cla + +## License + +KaTeX is licenced under the [MIT License](http://opensource.org/licenses/MIT). diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/LICENSE.txt b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/LICENSE.txt new file mode 100644 index 0000000..f7b2d38 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/LICENSE.txt @@ -0,0 +1,27 @@ +The MIT License (MIT) + +Copyright (c) 2015 Khan Academy + +This software also uses portions of the underscore.js project, which is +MIT licensed with the following copyright: + +Copyright (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative +Reporters & Editors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/Makefile b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/Makefile new file mode 100644 index 0000000..5855e23 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/Makefile @@ -0,0 +1,95 @@ +.PHONY: build dist lint setup copy serve clean metrics test zip contrib +build: setup lint build/katex.min.js build/katex.min.css contrib zip compress + +dist: build + rm -rf dist/ + cp -R build/katex/ dist/ + +# Export these variables for use in contrib Makefiles +export BUILDDIR = $(realpath build) +export BROWSERIFY = $(realpath ./node_modules/.bin/browserify) +export UGLIFYJS = $(realpath ./node_modules/.bin/uglifyjs) \ + --mangle \ + --beautify \ + ascii_only=true,beautify=false + +setup: + npm install + +lint: katex.js server.js cli.js $(wildcard src/*.js) $(wildcard test/*.js) $(wildcard contrib/*/*.js) $(wildcard dockers/*/*.js) + ./node_modules/.bin/jshint $^ + +build/katex.js: katex.js $(wildcard src/*.js) + $(BROWSERIFY) $< --standalone katex > $@ + +build/katex.min.js: build/katex.js + $(UGLIFYJS) < $< > $@ + +build/katex.less.css: static/katex.less $(wildcard static/*.less) + ./node_modules/.bin/lessc $< $@ + +build/katex.min.css: build/katex.less.css + ./node_modules/.bin/cleancss -o $@ $< + +.PHONY: build/fonts +build/fonts: + rm -rf $@ + mkdir $@ + for font in $(shell grep "font" static/katex.less | grep -o "KaTeX_\w\+" | cut -d" " -f 2 | sort | uniq); do \ + cp static/fonts/$$font* $@; \ + done + +contrib: build/contrib + +.PHONY: build/contrib +build/contrib: + mkdir -p build/contrib + @# Since everything in build/contrib is put in the built files, make sure + @# there's nothing in there we don't want. + rm -rf build/contrib/* + $(MAKE) -C contrib/auto-render + +.PHONY: build/katex +build/katex: build/katex.min.js build/katex.min.css build/fonts README.md build/contrib + mkdir -p build/katex + rm -rf build/katex/* + cp -r $^ build/katex + +build/katex.tar.gz: build/katex + cd build && tar czf katex.tar.gz katex/ + +build/katex.zip: build/katex + rm -f $@ + cd build && zip -rq katex.zip katex/ + +zip: build/katex.tar.gz build/katex.zip + +compress: build/katex.min.js build/katex.min.css + @$(eval JSSIZE!=gzip -c build/katex.min.js | wc -c) + @$(eval CSSSIZE!=gzip -c build/katex.min.css | wc -c) + @$(eval TOTAL!=echo ${JSSIZE}+${CSSSIZE} | bc) + @printf "Minified, gzipped js: %6d\n" "${JSSIZE}" + @printf "Minified, gzipped css: %6d\n" "${CSSSIZE}" + @printf "Total: %6d\n" "${TOTAL}" + +serve: + node server.js + +test: + ./node_modules/.bin/jasmine-node test/katex-spec.js + ./node_modules/.bin/jasmine-node contrib/auto-render/auto-render-spec.js + +PERL=perl +PYTHON=$(shell python2 --version >/dev/null 2>&1 && echo python2 || echo python) + +metrics: + cd metrics && $(PERL) ./mapping.pl | $(PYTHON) ./extract_tfms.py | $(PYTHON) ./extract_ttfs.py | $(PYTHON) ./format_json.py > ../src/fontMetricsData.js + +extended_metrics: + cd metrics && $(PERL) ./mapping.pl | $(PYTHON) ./extract_tfms.py | $(PYTHON) ./extract_ttfs.py | $(PYTHON) ./format_json.py --width > ../src/fontMetricsData.js + +clean: + rm -rf build/* + +screenshots: + dockers/Screenshotter/screenshotter.sh diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/README.md b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/README.md new file mode 100644 index 0000000..8964d3b --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/README.md @@ -0,0 +1,68 @@ +# [<img src="https://khan.github.io/KaTeX/katex-logo.svg" width="130" alt="KaTeX">](https://khan.github.io/KaTeX/) [![Build Status](https://travis-ci.org/Khan/KaTeX.svg?branch=master)](https://travis-ci.org/Khan/KaTeX) + +[![Join the chat at https://gitter.im/Khan/KaTeX](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Khan/KaTeX?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + +KaTeX is a fast, easy-to-use JavaScript library for TeX math rendering on the web. + + * **Fast:** KaTeX renders its math synchronously and doesn't need to reflow the page. See how it compares to a competitor in [this speed test](http://jsperf.com/katex-vs-mathjax/). + * **Print quality:** KaTeX’s layout is based on Donald Knuth’s TeX, the gold standard for math typesetting. + * **Self contained:** KaTeX has no dependencies and can easily be bundled with your website resources. + * **Server side rendering:** KaTeX produces the same output regardless of browser or environment, so you can pre-render expressions using Node.js and send them as plain HTML. + +KaTeX supports all major browsers, including Chrome, Safari, Firefox, Opera, and IE 8 - IE 11. A list of supported commands can be on the [wiki](https://github.com/Khan/KaTeX/wiki/Function-Support-in-KaTeX). + +## Usage + +You can [download KaTeX](https://github.com/khan/katex/releases) and host it on your server or include the `katex.min.js` and `katex.min.css` files on your page directly from a CDN: + +```html +<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/KaTeX/0.3.0/katex.min.css"> +<script src="//cdnjs.cloudflare.com/ajax/libs/KaTeX/0.3.0/katex.min.js"></script> +``` + +#### In-browser rendering + +Call `katex.render` with a TeX expression and a DOM element to render into: + +```js +katex.render("c = \\pm\\sqrt{a^2 + b^2}", element); +``` + +If KaTeX can't parse the expression, it throws a `katex.ParseError` error. + +#### Server side rendering or rendering to a string + +To generate HTML on the server or to generate an HTML string of the rendered math, you can use `katex.renderToString`: + +```js +var html = katex.renderToString("c = \\pm\\sqrt{a^2 + b^2}"); +// '<span class="katex">...</span>' +``` + +Make sure to include the CSS and font files, but there is no need to include the JavaScript. Like `render`, `renderToString` throws if it can't parse the expression. + +#### Rendering options + +You can provide an object of options as the last argument to `katex.render` and `katex.renderToString`. Available options are: + +- `displayMode`: `boolean`. If `true` the math will be rendered in display mode, which will put the math in display style (so `\int` and `\sum` are large, for example), and will center the math on the page on its own line. If `false` the math will be rendered in inline mode. (default: `false`) +- `throwOnError`: `boolean`. If `true`, KaTeX will throw a `ParseError` when it encounters an unsupported command. If `false`, KaTeX will render the unsupported command as text in the color given by `errorColor`. (default: `true`) +- `errorColor`: `string`. A color string given in the format `"#XXX"` or `"#XXXXXX"`. This option determines the color which unsupported commands are rendered in. (default: `#cc0000`) + +For example: + +```js +katex.render("c = \\pm\\sqrt{a^2 + b^2}", element, { displayMode: true }); +``` + +#### Automatic rendering of math on a page + +Math on the page can be automatically rendered using the auto-render extension. See [the Auto-render README](contrib/auto-render/README.md) for more information. + +## Contributing + +See [CONTRIBUTING.md](CONTRIBUTING.md) + +## License + +KaTeX is licensed under the [MIT License](http://opensource.org/licenses/MIT). diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/bower.json b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/bower.json new file mode 100644 index 0000000..0c9c133 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/bower.json @@ -0,0 +1,35 @@ +{ + "name": "KaTeX", + "version": "0.6.0-pre", + "main": [ + "dist/katex.min.js", + "dist/katex.min.css" + ], + "homepage": "http://khan.github.io/KaTeX/", + "description": "Fast math typesetting for the web.", + "moduleType": [ + "amd", + "globals", + "node" + ], + "license": "MIT", + "repository": { + "type": "git", + "url": "git://github.com/Khan/KaTeX.git" + }, + "ignore": [ + "**/.*", + "/*.txt", + "/*.js", + "/*.md", + "/package.json", + "/Makefile", + "/build", + "/test", + "/src", + "/contrib", + "/dockers", + "/metrics", + "/static" + ] +} diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/build/.gitkeep b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/build/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/build/.gitkeep diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/cli.js b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/cli.js new file mode 100755 index 0000000..c8f89c1 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/cli.js @@ -0,0 +1,31 @@ +#!/usr/bin/env node +// Simple CLI for KaTeX. +// Reads TeX from stdin, outputs HTML to stdout. + +var katex = require("./"); +var input = ""; + +// Skip the first two args, which are just "node" and "cli.js" +var args = process.argv.slice(2); + +if (args.indexOf("--help") != -1) { + console.log(process.argv[0] + " " + process.argv[1] + + " [ --help ]" + + " [ --display-mode ]"); + + console.log("\n" + + "Options:"); + console.log(" --help Display this help message"); + console.log(" --display-mode Render in display mode (not inline mode)"); + process.exit(); +} + +process.stdin.on("data", function(chunk) { + input += chunk.toString(); +}); + +process.stdin.on("end", function() { + var options = { displayMode: args.indexOf("--display-mode") != -1 }; + var output = katex.renderToString(input, options); + console.log(output); +}); diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/contrib/auto-render/Makefile b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/contrib/auto-render/Makefile new file mode 100644 index 0000000..5ae1753 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/contrib/auto-render/Makefile @@ -0,0 +1,9 @@ +.PHONY: build + +build: $(BUILDDIR)/contrib/auto-render.min.js + +$(BUILDDIR)/contrib/auto-render.min.js: $(BUILDDIR)/auto-render.js + $(UGLIFYJS) < $< > $@ + +$(BUILDDIR)/auto-render.js: auto-render.js + $(BROWSERIFY) $< --standalone renderMathInElement > $@ diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/contrib/auto-render/README.md b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/contrib/auto-render/README.md new file mode 100644 index 0000000..49d9b77 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/contrib/auto-render/README.md @@ -0,0 +1,63 @@ +# Auto-render extension + +This is an extension to automatically render all of the math inside of text. It +searches all of the text nodes in a given element for the given delimiters, and +renders the math in place. + +### Usage + +This extension isn't part of KaTeX proper, so the script should be separately +included in the page: + +```html +<script src="/path/to/auto-render.min.js"></script> +``` + +Then, call the exposed `renderMathInElement` function in a script tag +before the close body tag: + +```html +<body> + ... + <script> + renderMathInElement(document.body); + </script> +</body> +``` + +See [index.html](index.html) for an example. + +### API + +This extension exposes a single function, `window.renderMathInElement`, with +the following API: + +```js +function renderMathInElement(elem, options) +``` + +`elem` is an HTML DOM element. The function will recursively search for text +nodes inside this element and render the math in them. + +`options` is an optional object argument with the following keys: + + - `delimiters`: This is a list of delimiters to look for math. Each delimiter + has three properties: + + - `left`: A string which starts the math expression (i.e. the left delimiter). + - `right`: A string which ends the math expression (i.e. the right delimiter). + - `display`: A boolean of whether the math in the expression should be + rendered in display mode or not. + + The default value is: +```js +[ + {left: "$$", right: "$$", display: true}, + {left: "\\[", right: "\\]", display: true}, + {left: "\\(", right: "\\)", display: false} +] +``` + + - `ignoredTags`: This is a list of DOM node types to ignore when recursing + through. The default value is + `["script", "noscript", "style", "textarea", "pre", "code"]`. diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/contrib/auto-render/auto-render-spec.js b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/contrib/auto-render/auto-render-spec.js new file mode 100644 index 0000000..36408f8 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/contrib/auto-render/auto-render-spec.js @@ -0,0 +1,240 @@ +/* global beforeEach: false */ +/* global jasmine: false */ +/* global expect: false */ +/* global it: false */ +/* global describe: false */ + +var splitAtDelimiters = require("./splitAtDelimiters"); + +beforeEach(function() { + jasmine.addMatchers({ + toSplitInto: function() { + return { + compare: function(actual, left, right, result) { + var message = { + pass: true, + message: "'" + actual + "' split correctly" + }; + + var startData = [{type: "text", data: actual}]; + + var split = splitAtDelimiters(startData, left, right, false); + + if (split.length !== result.length) { + message.pass = false; + message.message = "Different number of splits: " + + split.length + " vs. " + result.length + " (" + + JSON.stringify(split) + " vs. " + + JSON.stringify(result) + ")"; + return message; + } + + for (var i = 0; i < split.length; i++) { + var real = split[i]; + var correct = result[i]; + + var good = true; + var diff; + + if (real.type !== correct.type) { + good = false; + diff = "type"; + } else if (real.data !== correct.data) { + good = false; + diff = "data"; + } else if (real.display !== correct.display) { + good = false; + diff = "display"; + } + + if (!good) { + message.pass = false; + message.message = "Difference at split " + + (i + 1) + ": " + JSON.stringify(real) + + " vs. " + JSON.stringify(correct) + + " (" + diff + " differs)"; + break; + } + } + + return message; + } + }; + } + }); +}); + +describe("A delimiter splitter", function() { + it("doesn't split when there are no delimiters", function() { + expect("hello").toSplitInto("(", ")", [{type: "text", data: "hello"}]); + }); + + it("doesn't create a math node when there's only a left delimiter", function() { + expect("hello ( world").toSplitInto( + "(", ")", + [ + {type: "text", data: "hello "}, + {type: "text", data: "( world"} + ]); + }); + + it("doesn't split when there's only a right delimiter", function() { + expect("hello ) world").toSplitInto( + "(", ")", + [ + {type: "text", data: "hello ) world"} + ]); + }); + + it("splits when there are both delimiters", function() { + expect("hello ( world ) boo").toSplitInto( + "(", ")", + [ + {type: "text", data: "hello "}, + {type: "math", data: " world ", + rawData: "( world )", display: false}, + {type: "text", data: " boo"} + ]); + }); + + it("splits on multi-character delimiters", function() { + expect("hello [[ world ]] boo").toSplitInto( + "[[", "]]", + [ + {type: "text", data: "hello "}, + {type: "math", data: " world ", + rawData: "[[ world ]]", display: false}, + {type: "text", data: " boo"} + ]); + }); + + it("splits mutliple times", function() { + expect("hello ( world ) boo ( more ) stuff").toSplitInto( + "(", ")", + [ + {type: "text", data: "hello "}, + {type: "math", data: " world ", + rawData: "( world )", display: false}, + {type: "text", data: " boo "}, + {type: "math", data: " more ", + rawData: "( more )", display: false}, + {type: "text", data: " stuff"} + ]); + }); + + it("leaves the ending when there's only a left delimiter", function() { + expect("hello ( world ) boo ( left").toSplitInto( + "(", ")", + [ + {type: "text", data: "hello "}, + {type: "math", data: " world ", + rawData: "( world )", display: false}, + {type: "text", data: " boo "}, + {type: "text", data: "( left"} + ]); + }); + + it("doesn't split when close delimiters are in {}s", function() { + expect("hello ( world { ) } ) boo").toSplitInto( + "(", ")", + [ + {type: "text", data: "hello "}, + {type: "math", data: " world { ) } ", + rawData: "( world { ) } )", display: false}, + {type: "text", data: " boo"} + ]); + + expect("hello ( world { { } ) } ) boo").toSplitInto( + "(", ")", + [ + {type: "text", data: "hello "}, + {type: "math", data: " world { { } ) } ", + rawData: "( world { { } ) } )", display: false}, + {type: "text", data: " boo"} + ]); + }); + + it("doesn't split at escaped delimiters", function() { + expect("hello ( world \\) ) boo").toSplitInto( + "(", ")", + [ + {type: "text", data: "hello "}, + {type: "math", data: " world \\) ", + rawData: "( world \\) )", display: false}, + {type: "text", data: " boo"} + ]); + + /* TODO(emily): make this work maybe? + expect("hello \\( ( world ) boo").toSplitInto( + "(", ")", + [ + {type: "text", data: "hello \\( "}, + {type: "math", data: " world ", + rawData: "( world )", display: false}, + {type: "text", data: " boo"} + ]); + */ + }); + + it("splits when the right and left delimiters are the same", function() { + expect("hello $ world $ boo").toSplitInto( + "$", "$", + [ + {type: "text", data: "hello "}, + {type: "math", data: " world ", + rawData: "$ world $", display: false}, + {type: "text", data: " boo"} + ]); + }); + + it("remembers which delimiters are display-mode", function() { + var startData = [{type: "text", data: "hello ( world ) boo"}]; + + expect(splitAtDelimiters(startData, "(", ")", true)).toEqual( + [ + {type: "text", data: "hello "}, + {type: "math", data: " world ", + rawData: "( world )", display: true}, + {type: "text", data: " boo"} + ]); + }); + + it("works with more than one start datum", function() { + var startData = [ + {type: "text", data: "hello ( world ) boo"}, + {type: "math", data: "math", rawData: "(math)", display: true}, + {type: "text", data: "hello ( world ) boo"} + ]; + + expect(splitAtDelimiters(startData, "(", ")", false)).toEqual( + [ + {type: "text", data: "hello "}, + {type: "math", data: " world ", + rawData: "( world )", display: false}, + {type: "text", data: " boo"}, + {type: "math", data: "math", rawData: "(math)", display: true}, + {type: "text", data: "hello "}, + {type: "math", data: " world ", + rawData: "( world )", display: false}, + {type: "text", data: " boo"} + ]); + }); + + it("doesn't do splitting inside of math nodes", function() { + var startData = [ + {type: "text", data: "hello ( world ) boo"}, + {type: "math", data: "hello ( world ) boo", + rawData: "(hello ( world ) boo)", display: true} + ]; + + expect(splitAtDelimiters(startData, "(", ")", false)).toEqual( + [ + {type: "text", data: "hello "}, + {type: "math", data: " world ", + rawData: "( world )", display: false}, + {type: "text", data: " boo"}, + {type: "math", data: "hello ( world ) boo", + rawData: "(hello ( world ) boo)", display: true} + ]); + }); +}); diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/contrib/auto-render/auto-render.js b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/contrib/auto-render/auto-render.js new file mode 100644 index 0000000..d0408c6 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/contrib/auto-render/auto-render.js @@ -0,0 +1,109 @@ +/* global katex */ + +var splitAtDelimiters = require("./splitAtDelimiters"); + +var splitWithDelimiters = function(text, delimiters) { + var data = [{type: "text", data: text}]; + for (var i = 0; i < delimiters.length; i++) { + var delimiter = delimiters[i]; + data = splitAtDelimiters( + data, delimiter.left, delimiter.right, + delimiter.display || false); + } + return data; +}; + +var renderMathInText = function(text, delimiters) { + var data = splitWithDelimiters(text, delimiters); + + var fragment = document.createDocumentFragment(); + + for (var i = 0; i < data.length; i++) { + if (data[i].type === "text") { + fragment.appendChild(document.createTextNode(data[i].data)); + } else { + var span = document.createElement("span"); + var math = data[i].data; + try { + katex.render(math, span, { + displayMode: data[i].display + }); + } catch (e) { + if (!(e instanceof katex.ParseError)) { + throw e; + } + console.error( + "KaTeX auto-render: Failed to parse `" + data[i].data + + "` with ", + e + ); + fragment.appendChild(document.createTextNode(data[i].rawData)); + continue; + } + fragment.appendChild(span); + } + } + + return fragment; +}; + +var renderElem = function(elem, delimiters, ignoredTags) { + for (var i = 0; i < elem.childNodes.length; i++) { + var childNode = elem.childNodes[i]; + if (childNode.nodeType === 3) { + // Text node + var frag = renderMathInText(childNode.textContent, delimiters); + i += frag.childNodes.length - 1; + elem.replaceChild(frag, childNode); + } else if (childNode.nodeType === 1) { + // Element node + var shouldRender = ignoredTags.indexOf( + childNode.nodeName.toLowerCase()) === -1; + + if (shouldRender) { + renderElem(childNode, delimiters, ignoredTags); + } + } + // Otherwise, it's something else, and ignore it. + } +}; + +var defaultOptions = { + delimiters: [ + {left: "$$", right: "$$", display: true}, + {left: "\\[", right: "\\]", display: true}, + {left: "\\(", right: "\\)", display: false} + // LaTeX uses this, but it ruins the display of normal `$` in text: + // {left: "$", right: "$", display: false} + ], + + ignoredTags: [ + "script", "noscript", "style", "textarea", "pre", "code" + ] +}; + +var extend = function(obj) { + // Adapted from underscore.js' `_.extend`. See LICENSE.txt for license. + var source, prop; + for (var i = 1, length = arguments.length; i < length; i++) { + source = arguments[i]; + for (prop in source) { + if (Object.prototype.hasOwnProperty.call(source, prop)) { + obj[prop] = source[prop]; + } + } + } + return obj; +}; + +var renderMathInElement = function(elem, options) { + if (!elem) { + throw new Error("No element provided to render"); + } + + options = extend({}, defaultOptions, options); + + renderElem(elem, options.delimiters, options.ignoredTags); +}; + +module.exports = renderMathInElement; diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/contrib/auto-render/index.html b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/contrib/auto-render/index.html new file mode 100644 index 0000000..566c147 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/contrib/auto-render/index.html @@ -0,0 +1,47 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="UTF-8"> + <title>Auto-render test</title> + <script src="/katex.js" type="text/javascript"></script> + <link href="/katex.css" rel="stylesheet" type="text/css"> + <script src="./auto-render.js" type="text/javascript"></script> + <style type="text/css"> + body { + margin: 0px; + padding: 0px; + font-size: 36px; + } + + #test > .blue { + color: blue; + } + </style> + </head> + <body> + <div id="test"> + This is some text $math \frac12$ other text $\unsupported$ + <span class="blue"> + Other node \[ displaymath \frac{1}{2} \] blah $$ \int_2^3 $$ + </span> + and some <!-- comment --> more text \(and math\) blah. And $math with a + \$ sign$. + <pre> + Stuff in a $pre tag$ + </pre> + </div> + <script> + renderMathInElement( + document.getElementById("test"), + { + delimiters: [ + {left: "$$", right: "$$", display: true}, + {left: "\\[", right: "\\]", display: true}, + {left: "$", right: "$", display: false}, + {left: "\\(", right: "\\)", display: false} + ] + } + ); + </script> + </body> +</html> diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/contrib/auto-render/splitAtDelimiters.js b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/contrib/auto-render/splitAtDelimiters.js new file mode 100644 index 0000000..eb107b9 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/contrib/auto-render/splitAtDelimiters.js @@ -0,0 +1,101 @@ +var findEndOfMath = function(delimiter, text, startIndex) { + // Adapted from + // https://github.com/Khan/perseus/blob/master/src/perseus-markdown.jsx + var index = startIndex; + var braceLevel = 0; + + var delimLength = delimiter.length; + + while (index < text.length) { + var character = text[index]; + + if (braceLevel <= 0 && + text.slice(index, index + delimLength) === delimiter) { + return index; + } else if (character === "\\") { + index++; + } else if (character === "{") { + braceLevel++; + } else if (character === "}") { + braceLevel--; + } + + index++; + } + + return -1; +}; + +var splitAtDelimiters = function(startData, leftDelim, rightDelim, display) { + var finalData = []; + + for (var i = 0; i < startData.length; i++) { + if (startData[i].type === "text") { + var text = startData[i].data; + + var lookingForLeft = true; + var currIndex = 0; + var nextIndex; + + nextIndex = text.indexOf(leftDelim); + if (nextIndex !== -1) { + currIndex = nextIndex; + finalData.push({ + type: "text", + data: text.slice(0, currIndex) + }); + lookingForLeft = false; + } + + while (true) { + if (lookingForLeft) { + nextIndex = text.indexOf(leftDelim, currIndex); + if (nextIndex === -1) { + break; + } + + finalData.push({ + type: "text", + data: text.slice(currIndex, nextIndex) + }); + + currIndex = nextIndex; + } else { + nextIndex = findEndOfMath( + rightDelim, + text, + currIndex + leftDelim.length); + if (nextIndex === -1) { + break; + } + + finalData.push({ + type: "math", + data: text.slice( + currIndex + leftDelim.length, + nextIndex), + rawData: text.slice( + currIndex, + nextIndex + rightDelim.length), + display: display + }); + + currIndex = nextIndex + rightDelim.length; + } + + lookingForLeft = !lookingForLeft; + } + + finalData.push({ + type: "text", + data: text.slice(currIndex) + }); + } else { + finalData.push(startData[i]); + } + } + + return finalData; +}; + +module.exports = splitAtDelimiters; diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/dockers/MathJaxFonts/Dockerfile b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/dockers/MathJaxFonts/Dockerfile new file mode 100644 index 0000000..dc5b4e5 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/dockers/MathJaxFonts/Dockerfile @@ -0,0 +1,61 @@ +FROM ubuntu:14.04 +MAINTAINER xymostech <xymostech@gmail.com> + +# Install things +RUN apt-get -qq update && apt-get -qqy install \ + git \ + dvipng \ + default-jre \ + default-jdk \ + texlive \ + wget \ + fontforge \ + mftrace \ + fonttools \ + optipng \ + advancecomp \ + man-db \ + build-essential \ + unzip \ + zlib1g-dev \ + python-fontforge \ + ruby \ + woff-tools \ + pkg-config \ + libharfbuzz-dev \ + libfreetype6-dev || true +RUN gem install ttfunk --version 1.1.1 + +# Download yuicompressor +RUN mkdir /usr/share/yui-compressor/ +RUN wget "https://github.com/yui/yuicompressor/releases/download/v2.4.8/yuicompressor-2.4.8.jar" -O /usr/share/yui-compressor/yui-compressor.jar + +# Download batik-ttf2svg.jar +RUN wget "https://archive.apache.org/dist/xmlgraphics/batik/batik-1.7.zip" +RUN unzip -qq batik-1.7.zip +RUN mv batik-1.7/batik-ttf2svg.jar /usr/share/java/ + +# Download and compile ttf2eof (note we add a patch to make it compile) +RUN wget "https://ttf2eot.googlecode.com/files/ttf2eot-0.0.2-2.tar.gz" +RUN tar -xzf ttf2eot-0.0.2-2.tar.gz +RUN sed -i "1s/^/#include <cstddef>/" ttf2eot-0.0.2-2/OpenTypeUtilities.h +RUN make -C ttf2eot-0.0.2-2/ +RUN mv ttf2eot-0.0.2-2/ttf2eot /usr/bin/ + +# Download and compile ttfautohint +RUN wget "http://download.savannah.gnu.org/releases/freetype/ttfautohint-1.3.tar.gz" +RUN tar -xzf ttfautohint-1.3.tar.gz +RUN cd ttfautohint-1.3/ && ./configure --without-qt +RUN make -C ttfautohint-1.3/ +RUN mv ttfautohint-1.3/frontend/ttfautohint /usr/bin + +# Download and compile woff2_compress +RUN git clone "https://code.google.com/p/font-compression-reference/" woff2_compress +RUN make -C woff2_compress/woff2/ +RUN mv woff2_compress/woff2/woff2_compress /usr/bin/ + +# Download and setup MathJax-dev +RUN git clone "https://github.com/khan/MathJax-dev.git" +RUN cp MathJax-dev/default.cfg MathJax-dev/custom.cfg +RUN make -C MathJax-dev custom.cfg.pl + diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/dockers/MathJaxFonts/README.md b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/dockers/MathJaxFonts/README.md new file mode 100644 index 0000000..1451bdc --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/dockers/MathJaxFonts/README.md @@ -0,0 +1,55 @@ +### How to generate MathJax fonts +--------------------------------- + +It's really simple (now)! Just make a docker image from the included Dockerfile +using a command like + + sudo docker build --tag=mathjaxfonts . + +from within this directory (note you need to have docker installed and running +for this to work). This will build a docker image with the mathjaxfonts tag, +which you can then use to run dockers based on them. Then, run a mathjaxfonts +docker with + + sudo docker run --interactive --tty --name mjf mathjaxfonts /bin/bash + +We name this docker "mjf" so we can reference it later when we want to copy the +files off. (If you get an error about the name being in use, perhaps because you +are trying to create another docker, you can either delete the old docker with + + sudo docker rm mjf + +or use a different name.) This will get you into the docker in the root +directory. From there, cd into the `/MathJax-dev/fonts/OTF/TeX` directory, and +run + + make ttf eot woff woff2 + +to build all of the fonts that we need. Finally, leave the docker and copy all +the files off with the `copy_fonts.sh` script: + + ./copy_fonts.sh mjf + +And you're good to go! Don't forget to update the font metrics with `make +metrics`. + +### General Docker Help +----------------------- + +When you quit the docker, it will stop the docker from running. If you want to +reattach to the docker, you can start it again with + + sudo docker start mjf + +and then attach with + + sudo docker attach mjf + +Alternatively, if you want to detach from the docker when you're done instead of +quitting and stopping it, you can detach with `C-p C-q`, and then re-attach with + + sudo docker attach mjf + +To see a list of your current dockers, you can run + + docker ps diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/dockers/MathJaxFonts/copy_fonts.sh b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/dockers/MathJaxFonts/copy_fonts.sh new file mode 100755 index 0000000..d1cc082 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/dockers/MathJaxFonts/copy_fonts.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash + +set -e + +if [ -z "$1" ]; then + echo "Usage: $(basename $0) <docker name>" + echo " If you followed the README, the docker name would be 'mjf'" + exit 1 +else + DOCKER_NAME="$1" +fi + +mkdir fonts + +used_fonts=( + KaTeX_AMS-Regular + KaTeX_Caligraphic-Bold + KaTeX_Caligraphic-Regular + KaTeX_Fraktur-Bold + KaTeX_Fraktur-Regular + KaTeX_Main-Bold + KaTeX_Main-Italic + KaTeX_Main-Regular + KaTeX_Math-BoldItalic + KaTeX_Math-Italic + KaTeX_Math-Regular + KaTeX_SansSerif-Bold + KaTeX_SansSerif-Italic + KaTeX_SansSerif-Regular + KaTeX_Script-Regular + KaTeX_Size1-Regular + KaTeX_Size2-Regular + KaTeX_Size3-Regular + KaTeX_Size4-Regular + KaTeX_Typewriter-Regular +) + +for filetype in ttf eot woff woff2; do + echo "Copying $filetype" + docker cp "$DOCKER_NAME":/MathJax-dev/fonts/OTF/TeX/"$filetype" fonts + + for font in ${used_fonts[*]}; do + mv fonts/"$filetype"/"$font"* fonts/ + done + + rm -rf fonts/"$filetype" +done diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/dockers/Screenshotter/README.md b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/dockers/Screenshotter/README.md new file mode 100644 index 0000000..a4de12b --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/dockers/Screenshotter/README.md @@ -0,0 +1,63 @@ +# How to generate screenshotter images + +## Automatic generation of screen shots + +Now you too can generate screenshots from your own computer, and (hopefully) +have them look mostly the same as the current ones! Make sure you have docker +installed and running. +If all you want is (re)create +all the snapshots for all the browsers, then you can do so by running the +`screenshotter.sh` script: + + dockers/Screenshotter/screenshotter.sh + +It will fetch all required selenium docker images, and use them to +take screenshots. + +## Manual generation + +If you are creating screenshots on a regular basis, you can keep the +docker containers with the selenium setups running. Essentially you +are encouraged to reproduce the steps from `screenshotter.sh` +manually. Example run for Firefox: + + container=$(docker run -d -P selenium/standalone-firefox:2.46.0) + node dockers/Screenshotter/screenshotter.js -b firefox -c ${container} + # possibly repeat the above command as often as you need, then eventually + docker stop ${container} + docker rm ${container} + +For Chrome, simply replace both occurrences of `firefox` with `chrome`. + +## Use without docker + +It is possible to run `screenshotter.js` without the use of Docker: + + npm install selenium-webdriver + node dockers/Screenshotter/screenshotter.js + +This will generate screenshots using the Firefox installed on your system. +Browsers other than Firefox can be targeted using the `--browser` option. +For a complete list of options pass `--help` as an argument to +`screenshotter.js`. Using these it should be possible to have the script +connect to almost any Selenium web driver you might have access to. + +Note that screenshots taken without Docker are very likely to disagree +from the ones stored in the repository, due to different versions of +various software components being used. The screenshots taken in this +fashion are well suited for visual inspection, but for exact binary +comparisons it would be neccessary to carefully set up the environment +to match the one used by the Docker approach. + +## Choosing the list of test cases + +Both `screenshotter.js` and `screenshotter.sh` will accept +an `--include` option (short `-i`) which can be used to specify +a list of test cases to be processed, as a comma separated list. +Conversely, the `--exclude` option (short `-x`) can be used +to specify a list of cases which are not being processed. + +Examples: + + node dockers/Screenshotter/screenshotter.js -i Sqrt,SqrtRoot + dockers/Screenshotter/screenshotter.sh --exclude=GreekLetters diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/dockers/Screenshotter/screenshotter.js b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/dockers/Screenshotter/screenshotter.js new file mode 100644 index 0000000..ddb27cc --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/dockers/Screenshotter/screenshotter.js @@ -0,0 +1,296 @@ +"use strict"; + +var childProcess = require("child_process"); +var fs = require("fs"); +var http = require("http"); +var jspngopt = require("jspngopt"); +var net = require("net"); +var pako = require("pako"); +var path = require("path"); +var selenium = require("selenium-webdriver"); + +var app = require("../../server"); +var data = require("../../test/screenshotter/ss_data"); + +var dstDir = path.normalize( + path.join(__dirname, "..", "..", "test", "screenshotter", "images")); + +////////////////////////////////////////////////////////////////////// +// Process command line arguments + +var opts = require("nomnom") + .option("browser", { + abbr: "b", + "default": "firefox", + help: "Name of the browser to use" + }) + .option("container", { + abbr: "c", + type: "string", + help: "Name or ID of a running docker container to contact" + }) + .option("seleniumURL", { + full: "selenium-url", + help: "Full URL of the Selenium web driver" + }) + .option("seleniumIP", { + full: "selenium-ip", + help: "IP address of the Selenium web driver" + }) + .option("seleniumPort", { + full: "selenium-port", + "default": 4444, + help: "Port number of the Selenium web driver" + }) + .option("katexURL", { + full: "katex-url", + help: "Full URL of the KaTeX development server" + }) + .option("katexIP", { + full: "katex-ip", + "default": "localhost", + help: "Full URL of the KaTeX development server" + }) + .option("katexPort", { + full: "katex-port", + help: "Port number of the KaTeX development server" + }) + .option("include", { + abbr: "i", + help: "Comma-separated list of test cases to process" + }) + .option("exclude", { + abbr: "x", + help: "Comma-separated list of test cases to exclude" + }) + .parse(); + +var listOfCases; +if (opts.include) { + listOfCases = opts.include.split(","); +} else { + listOfCases = Object.keys(data); +} +if (opts.exclude) { + var exclude = opts.exclude.split(","); + listOfCases = listOfCases.filter(function(key) { + return exclude.indexOf(key) === -1; + }); +} + +var seleniumURL = opts.seleniumURL; +var seleniumIP = opts.seleniumIP; +var seleniumPort = opts.seleniumPort; +var katexURL = opts.katexURL; +var katexIP = opts.katexIP; +var katexPort = opts.katexPort; + +////////////////////////////////////////////////////////////////////// +// Work out connection to selenium docker container + +function check(err) { + if (!err) { + return; + } + console.error(err); + console.error(err.stack); + process.exit(1); +} + +function dockerCmd() { + var args = Array.prototype.slice.call(arguments); + return childProcess.execFileSync( + "docker", args, { encoding: "utf-8" }).replace(/\n$/, ""); +} + +if (!seleniumURL && opts.container) { + try { + // When using boot2docker, seleniumIP and katexIP are distinct. + seleniumIP = childProcess.execFileSync( + "boot2docker", ["ip"], { encoding: "utf-8" }).replace(/\n$/, ""); + var config = childProcess.execFileSync( + "boot2docker", ["config"], { encoding: "utf-8" }); + config = (/^HostIP = "(.*)"$/m).exec(config); + if (!config) { + console.error("Failed to find HostIP"); + process.exit(2); + } + katexIP = config[1]; + } catch(e) { + seleniumIP = katexIP = dockerCmd( + "inspect", "-f", "{{.NetworkSettings.Gateway}}", opts.container); + } + seleniumPort = dockerCmd("port", opts.container, seleniumPort); + seleniumPort = seleniumPort.replace(/^.*:/, ""); +} +if (!seleniumURL && seleniumIP) { + seleniumURL = "http://" + seleniumIP + ":" + seleniumPort + "/wd/hub"; +} +if (seleniumURL) { + console.log("Selenium driver at " + seleniumURL); +} else { + console.log("Selenium driver in local session"); +} + +process.nextTick(startServer); +var attempts = 0; + +////////////////////////////////////////////////////////////////////// +// Start up development server + +var devServer = null; +var minPort = 32768; +var maxPort = 61000; + +function startServer() { + if (katexURL || katexPort) { + process.nextTick(tryConnect); + return; + } + var port = Math.floor(Math.random() * (maxPort - minPort)) + minPort; + var server = http.createServer(app).listen(port); + server.once("listening", function() { + devServer = server; + katexPort = port; + attempts = 0; + process.nextTick(tryConnect); + }); + server.on("error", function(err) { + if (devServer !== null) { // error after we started listening + throw err; + } else if (++attempts > 50) { + throw new Error("Failed to start up dev server"); + } else { + process.nextTick(startServer); + } + }); +} + +////////////////////////////////////////////////////////////////////// +// Wait for container to become ready + +function tryConnect() { + if (!katexURL) { + katexURL = "http://" + katexIP + ":" + katexPort + "/"; + console.log("KaTeX URL is " + katexURL); + } + if (!seleniumIP) { + process.nextTick(buildDriver); + return; + } + var sock = net.connect({ + host: seleniumIP, + port: +seleniumPort + }); + sock.on("connect", function() { + sock.end(); + attempts = 0; + process.nextTick(buildDriver); + }).on("error", function() { + if (++attempts > 50) { + throw new Error("Failed to connect selenium server."); + } + setTimeout(tryConnect, 200); + }); +} + +////////////////////////////////////////////////////////////////////// +// Build the web driver + +var driver; +function buildDriver() { + var builder = new selenium.Builder().forBrowser(opts.browser); + if (seleniumURL) { + builder.usingServer(seleniumURL); + } + driver = builder.build(); + setSize(targetW, targetH); +} + +////////////////////////////////////////////////////////////////////// +// Set the screen size + +var targetW = 1024, targetH = 768; +function setSize(reqW, reqH) { + return driver.manage().window().setSize(reqW, reqH).then(function() { + return driver.takeScreenshot(); + }).then(function(img) { + img = imageDimensions(img); + var actualW = img.width; + var actualH = img.height; + if (actualW === targetW && actualH === targetH) { + process.nextTick(takeScreenshots); + return; + } + if (++attempts > 5) { + throw new Error("Failed to set window size correctly."); + } + return setSize(targetW + reqW - actualW, targetH + reqH - actualH); + }, check); +} + +function imageDimensions(img) { + var buf = new Buffer(img, "base64"); + return { + buf: buf, + width: buf.readUInt32BE(16), + height: buf.readUInt32BE(20) + }; +} + +////////////////////////////////////////////////////////////////////// +// Take the screenshots + +var countdown = listOfCases.length; + +function takeScreenshots() { + listOfCases.forEach(takeScreenshot); +} + +function takeScreenshot(key) { + var itm = data[key]; + if (!itm) { + console.error("Test case " + key + " not known!"); + return; + } + var url = katexURL + "test/screenshotter/test.html?" + itm.query; + driver.get(url); + driver.takeScreenshot().then(function haveScreenshot(img) { + img = imageDimensions(img); + if (img.width !== targetW || img.height !== targetH) { + throw new Error("Excpected " + targetW + " x " + targetH + + ", got " + img.width + "x" + img.height); + } + if (key === "Lap" && opts.browser === "firefox" && + img.buf[0x32] === 0xf8) { + /* There is some strange non-determinism with this case, + * causing slight vertical shifts. The first difference + * is at offset 0x32, where one file has byte 0xf8 and + * the other has something else. By using a different + * output file name for one of these cases, we accept both. + */ + key += "_alt"; + } + var file = path.join(dstDir, key + "-" + opts.browser + ".png"); + var deferred = new selenium.promise.Deferred(); + var opt = new jspngopt.Optimizer({ + pako: pako + }); + var buf = opt.bufferSync(img.buf); + fs.writeFile(file, buf, function(err) { + if (err) { + deferred.reject(err); + } + else { + deferred.fulfill(); + } + }); + return deferred.promise; + }).then(function() { + console.log(key); + if (--countdown === 0) { + // devServer.close(cb) will take too long. + process.exit(0); + } + }, check); +} diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/dockers/Screenshotter/screenshotter.sh b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/dockers/Screenshotter/screenshotter.sh new file mode 100755 index 0000000..d2cb1a5 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/dockers/Screenshotter/screenshotter.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +# This script does a one-shot creation of screenshots, creating needed +# docker containers and removing them afterwards. During development, +# it might be desirable to avoid the overhead for starting and +# stopping the containers. Developers are encouraged to manage +# suitable containers themselves, calling the screenshotter.js script +# directly. + +status=0 +for browserTag in firefox:2.46.0 chrome:2.46.0; do + browser=${browserTag%:*} + image=selenium/standalone-${browserTag} + echo "Starting container for ${image}" + container=$(docker run -d -P ${image}) + [[ ${container} ]] || continue + echo "Container ${container:0:12} started, creating screenshots..." + if node "$(dirname "$0")"/screenshotter.js \ + --browser="${browser}" --container="${container}" "$@"; then + res=Done + else + res=Failed + status=1 + fi + echo "${res} taking screenshots, stopping and removing ${container:0:12}" + docker stop ${container} >/dev/null && docker rm ${container} >/dev/null +done +exit ${status} diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/dockers/texcmp/Dockerfile b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/dockers/texcmp/Dockerfile new file mode 100644 index 0000000..c109565 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/dockers/texcmp/Dockerfile @@ -0,0 +1,11 @@ +# convert from PDF to PNG with -flatten looks really bad on 14.04 LTS +FROM ubuntu:15.04 + +MAINTAINER Martin von Gagern <gagern@ma.tum.de> + +# Disable regular updates, but keep security updates +RUN sed -i 's/^\(deb.*updates\)/#\1/' /etc/apt/sources.list && apt-get update + +# Install all required packages, but try not to pull in TOO much +RUN apt-get -qy --no-install-recommends install \ + texlive-latex-base etoolbox imagemagick ghostscript nodejs diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/dockers/texcmp/README.md b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/dockers/texcmp/README.md new file mode 100644 index 0000000..89fb1c3 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/dockers/texcmp/README.md @@ -0,0 +1,82 @@ +# How to compare against LaTeX + +The tools in this directory can be used to create reference images +using LaTeX, and to compare them against the screenshots taken from a +browser. + +## Execution environment + +### Docker environment + +If you don't want to ensure the presence of all required tools, or +want to make sure that you create reproducible results, simply run + + dockers/texcmp/texcmp.sh + +from the root of your KaTeX directory tree. +This will build a suitable docker image unless such an image already +exists. It will then use a container based on that image to generate +all the images described below. + +Note that the files and directories created in the source tree from +within the docker will be owned by root, so you might have trouble +deleting them later on. Be sure you can obtain superuser permissions +on your computer or know someone who can, just to be safe. + +### Native environment + +If you want to avoid the overhead of creating a docker container, or +the even larger overhead of setting up docker and creating the initial +image, then you may instead execute the commands + + cd dockers/texcmp + npm install + node texcmp.js + +from the root of your KaTeX directory tree. Required tools include the +`pdflatex` tool of a standard TeX distribution as well as the +`convert` tool from ImageMagick. + +Note that this approach will use `/tmp/texcmp` as a temporary directory. +The use of a single directory name here can lead to conflicts if +multiple developers on the same machine try to use that directory. + +Also note that different software configurations can lead to different results, +so if reproducibility is desired, the Docker approach should be chosen. + +## Generated files + +After running either of the above commands, you will find two +(possibly new) subdirectories inside `test/screenshotter`, +called `tex` and `diff`. + +### Rasterized documents + +`test/screenshotter/tex` will contain images created by `pdflatex` by +plugging the test case formula in question into the template +`test/screenshotter/test.tex`. This is essentially our reference of +how LaTeX renders a given input. + +### Difference images + +`test/screenshotter/diff` will contain images depicting the difference +between the LaTeX rendering and the Firefox screenshot. Black areas +indicate overlapping print. Green areas are black in LaTeX but white +in Firefox, while it's the other way round for red areas. Colored +input is first converted to grayscale, before being subject to the +coloring just described. The pictures will be aligned in such a way +as to maximize the overlap between the two versions (i.e. the amount +of black output). The result will then be trimmed so it can easily be +pasted into bug reports. + +## Command line arguments + +Both `texcmp.sh` and `texcmp.js` will accept the names of test cases +on the command line. This can be useful if one particular test case +is affected by current development, so that the effects on it can be +seen more quickly. + +Examples: + + dockers/texcmp/texcmp.sh Sqrt SqrtRoot + node dockers/texcmp/texcmp.js Baseline diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/dockers/texcmp/package.json b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/dockers/texcmp/package.json new file mode 100644 index 0000000..751ef01 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/dockers/texcmp/package.json @@ -0,0 +1,10 @@ +{ + "name": "texcmp", + "description": "KaTeX helper to compare LaTeX output against screenshots", + "license": "MIT", + "dependencies": { + "ndarray-fft": "1.0.0", + "pngparse": "2.0.1", + "q": "1.4.1" + } +} diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/dockers/texcmp/texcmp.js b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/dockers/texcmp/texcmp.js new file mode 100644 index 0000000..5872fd6 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/dockers/texcmp/texcmp.js @@ -0,0 +1,252 @@ +"use strict"; + +var childProcess = require("child_process"); +var fs = require("fs"); +var path = require("path"); +var Q = require("q"); // To debug, pass Q_DEBUG=1 in the environment +var pngparse = require("pngparse"); +var fft = require("ndarray-fft"); +var ndarray = require("ndarray-fft/node_modules/ndarray"); + +var data = require("../../test/screenshotter/ss_data"); + +// Adapt node functions to Q promises +var readFile = Q.denodeify(fs.readFile); +var writeFile = Q.denodeify(fs.writeFile); +var mkdir = Q.denodeify(fs.mkdir); + +var todo; +if (process.argv.length > 2) { + todo = process.argv.slice(2); +} else { + todo = Object.keys(data).filter(function(key) { + return !data[key].nolatex; + }); +} + +// Dimensions used when we do the FFT-based alignment computation +var alignWidth = 2048; // should be at least twice the width resp. height +var alignHeight = 2048; // of the screenshots, and a power of two. + +// Compute required resolution to match test.html. 16px default font, +// scaled to 4em in test.html, and to 1.21em in katex.css. Corresponding +// LaTeX font size is 10pt. There are 72.27pt per inch. +var pxPerEm = 16 * 4 * 1.21; +var pxPerPt = pxPerEm / 10; +var dpi = pxPerPt * 72.27; + +var tmpDir = "/tmp/texcmp"; +var ssDir = path.normalize( + path.join(__dirname, "..", "..", "test", "screenshotter")); +var imagesDir = path.join(ssDir, "images"); +var teximgDir = path.join(ssDir, "tex"); +var diffDir = path.join(ssDir, "diff"); +var template; + +Q.all([ + readFile(path.join(ssDir, "test.tex"), "utf-8"), + ensureDir(tmpDir), + ensureDir(teximgDir), + ensureDir(diffDir) +]).spread(function(data) { + template = data; + // dirs have been created, template has been read, now rasterize. + return Q.all(todo.map(processTestCase)); +}).done(); + +// Process a single test case: rasterize, then create diff +function processTestCase(key) { + var itm = data[key]; + var tex = "$" + itm.tex + "$"; + if (itm.display) { + tex = "\\[" + itm.tex + "\\]"; + } + if (itm.pre) { + tex = itm.pre.replace("<br>", "\\\\") + tex; + } + if (itm.post) { + tex = tex + itm.post.replace("<br>", "\\\\"); + } + tex = template.replace(/\$.*\$/, tex.replace(/\$/g, "$$$$")); + var texFile = path.join(tmpDir, key + ".tex"); + var pdfFile = path.join(tmpDir, key + ".pdf"); + var pngFile = path.join(teximgDir, key + "-pdflatex.png"); + var browserFile = path.join(imagesDir, key + "-firefox.png"); + var diffFile = path.join(diffDir, key + ".png"); + + // Step 1: write key.tex file + var fftLatex = writeFile(texFile, tex).then(function() { + // Step 2: call "pdflatex key" to create key.pdf + return execFile("pdflatex", [ + "-interaction", "nonstopmode", key + ], {cwd: tmpDir}); + }).then(function() { + console.log("Typeset " + key); + // Step 3: call "convert ... key.pdf key.png" to create key.png + return execFile("convert", [ + "-density", dpi, "-units", "PixelsPerInch", "-flatten", + pdfFile, pngFile + ]); + }).then(function() { + console.log("Rasterized " + key); + // Step 4: apply FFT to that + return readPNG(pngFile).then(fftImage); + }); + // Step 5: apply FFT to reference image as well + var fftBrowser = readPNG(browserFile).then(fftImage); + + return Q.all([fftBrowser, fftLatex]).spread(function(browser, latex) { + // Now we have the FFT result from both + // Step 6: find alignment which maximizes overlap. + // This uses a FFT-based correlation computation. + var x, y; + var real = createMatrix(); + var imag = createMatrix(); + + // Step 6a: (real + i*imag) = latex * conjugate(browser) + for (y = 0; y < alignHeight; ++y) { + for (x = 0; x < alignWidth; ++x) { + var br = browser.real.get(y, x); + var bi = browser.imag.get(y, x); + var lr = latex.real.get(y, x); + var li = latex.imag.get(y, x); + real.set(y, x, br * lr + bi * li); + imag.set(y, x, br * li - bi * lr); + } + } + + // Step 6b: (real + i*imag) = inverseFFT(real + i*imag) + fft(-1, real, imag); + + // Step 6c: find position where the (squared) absolute value is maximal + var offsetX = 0; + var offsetY = 0; + var maxSquaredNorm = -1; // any result is greater than initial value + for (y = 0; y < alignHeight; ++y) { + for (x = 0; x < alignWidth; ++x) { + var or = real.get(y, x); + var oi = imag.get(y, x); + var squaredNorm = or * or + oi * oi; + if (maxSquaredNorm < squaredNorm) { + maxSquaredNorm = squaredNorm; + offsetX = x; + offsetY = y; + } + } + } + + // Step 6d: Treat negative offsets in a non-cyclic way + if (offsetY > (alignHeight / 2)) { + offsetY -= alignHeight; + } + if (offsetX > (alignWidth / 2)) { + offsetX -= alignWidth; + } + console.log("Positioned " + key + ": " + offsetX + ", " + offsetY); + + // Step 7: use these offsets to compute difference illustration + var bx = Math.max(offsetX, 0); // browser left padding + var by = Math.max(offsetY, 0); // browser top padding + var lx = Math.max(-offsetX, 0); // latex left padding + var ly = Math.max(-offsetY, 0); // latex top padding + var uw = Math.max(browser.width + bx, latex.width + lx); // union width + var uh = Math.max(browser.height + by, latex.height + ly); // u. height + return execFile("convert", [ + // First image: latex rendering, converted to grayscale and padded + "(", pngFile, "-grayscale", "Rec709Luminance", + "-extent", uw + "x" + uh + "-" + lx + "-" + ly, + ")", + // Second image: browser screenshot, to grayscale and padded + "(", browserFile, "-grayscale", "Rec709Luminance", + "-extent", uw + "x" + uh + "-" + bx + "-" + by, + ")", + // Third image: the per-pixel minimum of the first two images + "(", "-clone", "0-1", "-compose", "darken", "-composite", ")", + // First image is red, second green, third blue channel of result + "-channel", "RGB", "-combine", + "-trim", // remove everything that has the same color as the corners + diffFile // output file name + ]); + }).then(function() { + console.log("Compared " + key); + }); +} + +// Create a directory, but ignore error if the directory already exists. +function ensureDir(dir) { + return mkdir(dir).fail(function(err) { + if (err.code !== "EEXIST") { + throw err; + } + }); +} + +// Execute a given command, and return a promise to its output. +// Don't denodeify here, since fail branch needs access to stderr. +function execFile(cmd, args, opts) { + var deferred = Q.defer(); + childProcess.execFile(cmd, args, opts, function(err, stdout, stderr) { + if (err) { + console.error("Error executing " + cmd + " " + args.join(" ")); + console.error(stdout + stderr); + err.stdout = stdout; + err.stderr = stderr; + deferred.reject(err); + } else { + deferred.resolve(stdout); + } + }); + return deferred.promise; +} + +// Read given file and parse it as a PNG file. +function readPNG(file) { + var deferred = Q.defer(); + var onerror = deferred.reject.bind(deferred); + var stream = fs.createReadStream(file); + stream.on("error", onerror); + pngparse.parseStream(stream, function(err, image) { + if (err) { + onerror(err); + return; + } + deferred.resolve(image); + }); + return deferred.promise; +} + +// Take a parsed image data structure and apply FFT transformation to it +function fftImage(image) { + var real = createMatrix(); + var imag = createMatrix(); + var idx = 0; + var nchan = image.channels; + var alphachan = 1 - (nchan % 2); + var colorchan = nchan - alphachan; + for (var y = 0; y < image.height; ++y) { + for (var x = 0; x < image.width; ++x) { + var c; + var v = 0; + for (c = 0; c < colorchan; ++c) { + v += 255 - image.data[idx++]; + } + for (c = 0; c < alphachan; ++c) { + v += image.data[idx++]; + } + real.set(y, x, v); + } + } + fft(1, real, imag); + return { + real: real, + imag: imag, + width: image.width, + height: image.height + }; +} + +// Create a new matrix of preconfigured dimensions, initialized to zero +function createMatrix() { + var array = new Float64Array(alignWidth * alignHeight); + return new ndarray(array, [alignWidth, alignHeight]); +} diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/dockers/texcmp/texcmp.sh b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/dockers/texcmp/texcmp.sh new file mode 100755 index 0000000..558c88d --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/dockers/texcmp/texcmp.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +set -x +imgname=katex/texcmp +tag=1.1 +imgid=$(docker images | awk "/${imgname//\//\\/} *${tag//./\\.}/{print \$3}") +cd "$(dirname "$0")" || exit $? +npm install || exit $? +if [[ -z ${imgid} ]]; then + docker build -t "${imgname}:${tag}" . || exit $? +fi +base=$(cd ../..; pwd) +docker run --rm \ + -v "${base}":/KaTeX \ + -w /KaTeX/dockers/texcmp \ + "${imgname}:${tag}" \ + nodejs texcmp.js "$@" diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/katex.js b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/katex.js new file mode 100644 index 0000000..8fdae0a --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/katex.js @@ -0,0 +1,73 @@ +/** + * This is the main entry point for KaTeX. Here, we expose functions for + * rendering expressions either to DOM nodes or to markup strings. + * + * We also expose the ParseError class to check if errors thrown from KaTeX are + * errors in the expression, or errors in javascript handling. + */ + +var ParseError = require("./src/ParseError"); +var Settings = require("./src/Settings"); + +var buildTree = require("./src/buildTree"); +var parseTree = require("./src/parseTree"); +var utils = require("./src/utils"); + +/** + * Parse and build an expression, and place that expression in the DOM node + * given. + */ +var render = function(expression, baseNode, options) { + utils.clearNode(baseNode); + + var settings = new Settings(options); + + var tree = parseTree(expression, settings); + var node = buildTree(tree, expression, settings).toNode(); + + baseNode.appendChild(node); +}; + +// KaTeX's styles don't work properly in quirks mode. Print out an error, and +// disable rendering. +if (typeof document !== "undefined") { + if (document.compatMode !== "CSS1Compat") { + typeof console !== "undefined" && console.warn( + "Warning: KaTeX doesn't work in quirks mode. Make sure your " + + "website has a suitable doctype."); + + render = function() { + throw new ParseError("KaTeX doesn't work in quirks mode."); + }; + } +} + +/** + * Parse and build an expression, and return the markup for that. + */ +var renderToString = function(expression, options) { + var settings = new Settings(options); + + var tree = parseTree(expression, settings); + return buildTree(tree, expression, settings).toMarkup(); +}; + +/** + * Parse an expression and return the parse tree. + */ +var generateParseTree = function(expression, options) { + var settings = new Settings(options); + return parseTree(expression, settings); +}; + +module.exports = { + render: render, + renderToString: renderToString, + /** + * NOTE: This method is not currently recommended for public use. + * The internal tree representation is unstable and is very likely + * to change. Use at your own risk. + */ + __parse: generateParseTree, + ParseError: ParseError +}; diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/lint_blacklist.txt b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/lint_blacklist.txt new file mode 100644 index 0000000..9e3af45 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/lint_blacklist.txt @@ -0,0 +1,8 @@ +.git + +# Autogenerated code +build/** +node_modules/** + +# Third party code +test/jasmine/** diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/metrics/README.md b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/metrics/README.md new file mode 100644 index 0000000..4531461 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/metrics/README.md @@ -0,0 +1,21 @@ +### How to generate new metrics +------------------------------- + +There are several requirements for generating the metrics used by KaTeX. + +- You need to have an installation of TeX which supports kpathsea. You can check + this by running `tex --version`, and seeing if it has a line that looks like + > kpathsea version 6.2.0 + +- You need the JSON module for perl. You can install this either from CPAN + (possibly using the `cpan` command line tool) or with your package manager. + +- You need the python module fonttools. You can install this either from PyPi + (using `easy_install` or `pip`) or with your package manager. + +Once you have these things, run + + make metrics + +which should generate new metrics and place them into `fontMetricsData.json`. +You're done! diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/metrics/extract_tfms.py b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/metrics/extract_tfms.py new file mode 100755 index 0000000..fc5edc4 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/metrics/extract_tfms.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python + +import collections +import json +import parse_tfm +import subprocess +import sys + + +def find_font_path(font_name): + try: + font_path = subprocess.check_output(['kpsewhich', font_name]) + except OSError: + raise RuntimeError("Couldn't find kpsewhich program, make sure you" + + " have TeX installed") + except subprocess.CalledProcessError: + raise RuntimeError("Couldn't find font metrics: '%s'" % font_name) + return font_path.strip() + + +def main(): + mapping = json.load(sys.stdin) + + fonts = [ + 'cmbsy10.tfm', + 'cmbx10.tfm', + 'cmex10.tfm', + 'cmmi10.tfm', + 'cmmib10.tfm', + 'cmr10.tfm', + 'cmsy10.tfm', + 'cmti10.tfm', + 'msam10.tfm', + 'msbm10.tfm', + 'eufm10.tfm', + 'cmtt10.tfm', + 'rsfs10.tfm', + 'cmss10.tfm', + ] + + # Extracted by running `\font\a=<font>` and then `\showthe\skewchar\a` in + # TeX, where `<font>` is the name of the font listed here. The skewchar + # will be printed out in the output. If it outputs `-1`, that means there + # is no skewchar, so we use `None` here. + font_skewchar = { + 'cmbsy10': None, + 'cmbx10': None, + 'cmex10': None, + 'cmmi10': 127, + 'cmmib10': None, + 'cmr10': None, + 'cmsy10': 48, + 'cmti10': None, + 'msam10': None, + 'msbm10': None, + 'eufm10': None, + 'cmtt10': None, + 'rsfs10': None, + 'cmss10': None, + } + + font_name_to_tfm = {} + + for font_name in fonts: + font_basename = font_name.split('.')[0] + font_path = find_font_path(font_name) + font_name_to_tfm[font_basename] = parse_tfm.read_tfm_file(font_path) + + families = collections.defaultdict(dict) + + for family, chars in mapping.iteritems(): + for char, char_data in chars.iteritems(): + char_num = int(char) + + font = char_data['font'] + tex_char_num = int(char_data['char']) + yshift = float(char_data['yshift']) + + if family == "Script-Regular": + tfm_char = font_name_to_tfm[font].get_char_metrics(tex_char_num, + fix_rsfs=True) + else: + tfm_char = font_name_to_tfm[font].get_char_metrics(tex_char_num) + + height = round(tfm_char.height + yshift / 1000.0, 5) + depth = round(tfm_char.depth - yshift / 1000.0, 5) + italic = round(tfm_char.italic_correction, 5) + width = round(tfm_char.width, 5) + + skewkern = 0.0 + if (font_skewchar[font] and + font_skewchar[font] in tfm_char.kern_table): + skewkern = round( + tfm_char.kern_table[font_skewchar[font]], 5) + + families[family][char_num] = { + 'height': height, + 'depth': depth, + 'italic': italic, + 'skew': skewkern, + 'width': width + } + + sys.stdout.write( + json.dumps(families, separators=(',', ':'), sort_keys=True)) + +if __name__ == '__main__': + main() diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/metrics/extract_ttfs.py b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/metrics/extract_ttfs.py new file mode 100755 index 0000000..f2bf7c9 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/metrics/extract_ttfs.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python + +from fontTools.ttLib import TTFont +import sys +import json + +# map of characters to extract +metrics_to_extract = { + # Font name + "AMS-Regular": { + u"\u21e2": None, # \dashrightarrow + u"\u21e0": None, # \dashleftarrow + }, + "Main-Regular": { + # Skew and italic metrics can't be easily parsed from the TTF. Instead, + # we map each character to a "base character", which is a character + # from the same font with correct italic and skew metrics. A character + # maps to None if it doesn't have a base. + + u"\u2260": None, # \neq + u"\u2245": None, # \cong + u"\u0020": None, # space + u"\u00a0": None, # nbsp + u"\u2026": None, # \ldots + u"\u22ef": None, # \cdots + u"\u22f1": None, # \ddots + u"\u22ee": None, # \vdots + u"\u22ee": None, # \vdots + u"\u22a8": None, # \models + u"\u22c8": None, # \bowtie + u"\u2250": None, # \doteq + u"\u23b0": None, # \lmoustache + u"\u23b1": None, # \rmoustache + u"\u27ee": None, # \lgroup + u"\u27ef": None, # \rgroup + u"\u27f5": None, # \longleftarrow + u"\u27f8": None, # \Longleftarrow + u"\u27f6": None, # \longrightarrow + u"\u27f9": None, # \Longrightarrow + u"\u27f7": None, # \longleftrightarrow + u"\u27fa": None, # \Longleftrightarrow + u"\u21a6": None, # \mapsto + u"\u27fc": None, # \longmapsto + u"\u21a9": None, # \hookleftarrow + u"\u21aa": None, # \hookrightarrow + u"\u21cc": None, # \rightleftharpoons + }, + "Size1-Regular": { + u"\u222c": u"\u222b", # \iint, based on \int + u"\u222d": u"\u222b", # \iiint, based on \int + }, + "Size2-Regular": { + u"\u222c": u"\u222b", # \iint, based on \int + u"\u222d": u"\u222b", # \iiint, based on \int + }, +} + + +def main(): + start_json = json.load(sys.stdin) + + for font, chars in metrics_to_extract.iteritems(): + fontInfo = TTFont("../static/fonts/KaTeX_" + font + ".ttf") + glyf = fontInfo["glyf"] + unitsPerEm = float(fontInfo["head"].unitsPerEm) + + # We keep ALL Unicode cmaps, not just fontInfo["cmap"].getcmap(3, 1). + # This is playing it extra safe, since it reports inconsistencies. + # Platform 0 is Unicode, platform 3 is Windows. For platform 3, + # encoding 1 is UCS-2 and encoding 10 is UCS-4. + cmap = [t.cmap for t in fontInfo["cmap"].tables + if (t.platformID == 0) + or (t.platformID == 3 and t.platEncID in (1, 10))] + + for char, base_char in chars.iteritems(): + code = ord(char) + names = set(t.get(code) for t in cmap) + if not names: + sys.stderr.write( + "Codepoint {} of font {} maps to no name\n" + .format(code, font)) + continue + if len(names) != 1: + sys.stderr.write( + "Codepoint {} of font {} maps to multiple names: {}\n" + .format(code, font, ", ".join(sorted(names)))) + continue + name = names.pop() + + height = depth = italic = skew = width = 0 + glyph = glyf[name] + if glyph.numberOfContours: + height = glyph.yMax + depth = -glyph.yMin + width = glyph.xMax - glyph.xMin + if base_char: + base_char_str = str(ord(base_char)) + base_metrics = start_json[font][base_char_str] + italic = base_metrics["italic"] + skew = base_metrics["skew"] + width = base_metrics["width"] + + start_json[font][str(code)] = { + "height": height / unitsPerEm, + "depth": depth / unitsPerEm, + "italic": italic, + "skew": skew, + "width": width + } + + sys.stdout.write( + json.dumps(start_json, separators=(',', ':'), sort_keys=True)) + +if __name__ == "__main__": + main() diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/metrics/format_json.py b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/metrics/format_json.py new file mode 100644 index 0000000..5f6ac8d --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/metrics/format_json.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python + +import sys +import json + +props = ['depth', 'height', 'italic', 'skew'] + +if len(sys.argv) > 1: + if sys.argv[1] == '--width': + props.append('width') + +data = json.load(sys.stdin) +sep = "module.exports = {\n" +for font in sorted(data): + sys.stdout.write(sep + json.dumps(font)) + sep = ": {\n " + for glyph in sorted(data[font], key=int): + sys.stdout.write(sep + json.dumps(glyph) + ": ") + + values = [value if value != 0.0 else 0 for value in + [data[font][glyph][key] for key in props]] + + sys.stdout.write(json.dumps(values)) + sep = ",\n " + sep = "\n},\n" +sys.stdout.write("\n}};\n") diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/metrics/mapping.pl b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/metrics/mapping.pl new file mode 100755 index 0000000..bc779f5 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/metrics/mapping.pl @@ -0,0 +1,1106 @@ +#! /usr/bin/perl + +# Adapted from the MathJax-dev repository file /fonts/OTF/TeX/makeFF under the +# Apache 2 license + +# We use this file to recover the mapping from TeX fonts to KaTeX fonts, to +# accurately extract the metrics from the corresponding .tfm (TeX font metric) +# files + +use JSON; + +$map{cmr10} = { + "Main-Regular" => [ + [0,1] => 0x393, # \Gamma, \Delta + 2 => 0x398, # \Theta + 3 => 0x39B, # \Lambda + 4 => 0x39E, # \Xi + 5 => 0x3A0, # \Pi + 6 => 0x3A3, # \Sigma + [7,8] => 0x3A5, # \Upsilon, \Phi + [9,0xA] => 0x3A8, # \Psi, \Omega + + 0x10 => 0x131, # \imath (roman) + 0x11 => 0x237, # \jmath (roman) + 0x12 => 0x60, # \grave + 0x12 => 0x2CB, # \grave + 0x12 => [0x300,-500,0], # \grave (combining) + 0x13 => 0xB4, # \acute + 0x13 => 0x2CA, # \acute + 0x13 => [0x301,-500,0], # \acute (combining) + 0x14 => 0x2C7, # \check + 0x14 => [0x30C,-500,0], # \check (combining) + 0x15 => 0x2D8, # \breve + 0x15 => [0x306,-500,0], # \breve (combining) + 0x16 => 0xAF, # \bar + 0x16 => 0x2C9, # \bar + 0x16 => [0x304,-500,0], # \bar (combining) + 0x17 => [0xB0,-125,0], # ring above + 0x17 => [0x2DA,-125,0], # ring above + 0x17 => [0x30A,-625,0], # ring above (combining) + + [0x21,0x2F] => 0x21, # !, ", #, $, %, &, ', (, ), *, +, comma, -, ., / + 0x22 => 0x201D, # " + 0x27 => 0x2019, # ' + [0x30,0x39] => 0x30, # 0-9 + [0x3A,0x3B] => 0x3A, # :, ; + 0x3D => 0x3D, # = + [0x3F,0x40] => 0x3F, # ?, @ + [0x41,0x5A] => 0x41, # A-Z + 0x5B => 0x5B, # [ + 0x5C => 0x201C, # `` + [0x5D,0x5E] => 0x5D, # ], ^ + 0x5E => 0x2C6, # \hat + 0x5E => [0x302,-500,0], # \hat (combining) + 0x5F => [0x2D9,111,0], # \dot + 0x5F => [0x307,-389,0], # \dot (combining) + 0x60 => 0x2018, # ` + [0x61,0x7A] => 0x61, # a-z + [0x7B,0x7C] => 0x2013, # \endash, \emdash + 0x7B => [0x5F,0,-310], # underline + 0x7D => [0x30B,-500,0], # double acute (combining) + 0x7E => [0x7E,0,-350], # ~ + 0x7E => 0x2DC, # \tilde + 0x7E => [0x303,-500,0], # \tilde (combining) + 0x7F => 0xA8, # \ddot + 0x7F => [0x308,-500,0], # \ddot (combining) + ], +}; + +$map{cmmi10} = { + "Math-Regular" => [ + [0,1] => 0x393, # \Gamma, \Delta + 2 => 0x398, # \Theta + 3 => 0x39B, # \Lambda + 4 => 0x39E, # \Xi + 5 => 0x3A0, # \Pi + 6 => 0x3A3, # \Sigma + [7,8] => 0x3A5, # \Upsilon, \Phi + [9,0xA] => 0x3A8, # \Psi, \Omega + + [0xB,0xE] => 0x3B1, # \alpha, \beta, \gamma, \delta + 0xF => 0x3F5, # \elpsilon + [0x10,0x18] => 0x3B6, # \zeta, \eta, \theta, \iota, \kappa, \lambda, \mu, \nu, \xi + [0x19,0x1A] => 0x3C0, # \pi, \rho + [0x1B,0x1D] => 0x3C3, # \sigma, \tau, \upsilon + 0x1E => 0x3D5, # \phi + [0x1F,0x21] => 0x3C7, # \chi, \psi, \omega + 0x22 => 0x3B5, # \varepsilon + 0x23 => 0x3D1, # \vartheta + 0x24 => 0x3D6, # \varpi + 0x25 => 0x3F1, # \varrho + 0x26 => 0x3C2, # \varsigma + 0x27 => 0x3C6, # \varphi + + [0x41,0x5A] => 0x41, # A-Z + [0x61,0x7A] => 0x61, # a - z + 0x6F => 0x3BF, # omicron + ], + + "Math-Italic" => [ + [0,1] => 0x393, # \Gamma, \Delta + 2 => 0x398, # \Theta + 3 => 0x39B, # \Lambda + 4 => 0x39E, # \Xi + 5 => 0x3A0, # \Pi + 6 => 0x3A3, # \Sigma + [7,8] => 0x3A5, # \Upsilon, \Phi + [9,0xA] => 0x3A8, # \Psi, \Omega + + [0xB,0xE] => 0x3B1, # \alpha, \beta, \gamma, \delta + 0xF => 0x3F5, # \elpsilon + [0x10,0x18] => 0x3B6, # \zeta, \eta, \theta, \iota, \kappa, \lambda, \mu, \nu, \xi + [0x19,0x1A] => 0x3C0, # \pi, \rho + [0x1B,0x1D] => 0x3C3, # \sigma, \tau, \upsilon + 0x1E => 0x3D5, # \phi + [0x1F,0x21] => 0x3C7, # \chi, \psi, \omega + 0x22 => 0x3B5, # \varepsilon + 0x23 => 0x3D1, # \vartheta + 0x24 => 0x3D6, # \varpi + 0x25 => 0x3F1, # \varrho + 0x26 => 0x3C2, # \varsigma + 0x27 => 0x3C6, # \varphi + + [0x41,0x5A] => 0x41, # A-Z + [0x61,0x7A] => 0x61, # a - z + 0x6F => 0x3BF, # omicron + ], + + "Main-Regular" => [ + 0x28 => 0x21BC, # \leftharpoonup + 0x29 => 0x21BD, # \leftharpoondown + 0x2A => 0x21C0, # \rightharpoonup + 0x2B => 0x21C1, # \rightharpoondown + + 0x2E => 0x25B9, # \triangleright + 0x2F => 0x25C3, # \triangleleft + + 0x3C => 0x3C, # < + 0x3D => 0x2215, # / + 0x3E => 0x3E, # > + 0x3F => 0x22C6, # \star + 0x40 => 0x2202, # \partial + + [0x5B,0x5D] => 0x266D, # \flat, \natural, \sharp + 0x5E => 0x2323, # \smile + 0x5F => 0x2322, # \frown + 0x60 => 0x2113, # \ell + + 0x7D => 0x2118, # \wp + 0x7E => [0x20D7,-653,0],# \vec + ], + + "Main-Italic" => [ + 0x7B => 0x131, # \imath + 0x7C => 0x237, # \jmath + ], + + "Caligraphic-Regular" => [ + [0x30,0x39] => 0x30, # Oldstyle 0-9 + ], +}; + +$map{cmsy10} = { + "Main-Regular" => [ + 0 => 0x2212, # - + 1 => 0x22C5, # \cdot + 2 => 0xD7, # \times + 3 => 0x2217, # \ast + 4 => 0xF7, # \div + 5 => 0x22C4, # \diamond + 6 => 0xB1, # \pm + 7 => 0x2213, # \mp + [8,0xC] => 0x2295, # \oplus, \ominus, \otimes, \oslash, \odot + 0xD => 0x25EF, # \bigcirc + [0xE,0xF] => 0x2218, # \circ, \bullet + + 0x10 => 0x224D, # \asymp + 0x11 => 0x2261, # \equiv + [0x12,0x13] => 0x2286, # \subseteq, \supseteq + [0x14,0x15] => 0x2264, # \leq, \geq + [0x16,0x17] => 0x2AAF, # \preceq, \succeq + 0x18 => 0x223C, # \sim + 0x19 => 0x2248, # \approx + [0x1A,0x1B] => 0x2282, # \subset, \supset + [0x1C,0x1D] => 0x226A, # \ll, \gg + [0x1E,0x1F] => 0x227A, # \prec, \succ + + 0x20 => 0x2190, # \leftarrow + 0x21 => 0x2192, # \rightarrow + 0x22 => 0x2191, # \uparrow + 0x23 => 0x2193, # \downarrow + 0x24 => 0x2194, # \leftrightarrow + 0x25 => 0x2197, # \nearrow + 0x26 => 0x2198, # \searrow + 0x27 => 0x2243, # \simeq + + 0x28 => 0x21D0, # \Leftarrow + 0x29 => 0x21D2, # \Rightarrow + 0x2A => 0x21D1, # \Uparrow + 0x2B => 0x21D3, # \Downarrow + 0x2C => 0x21D4, # \Leftrightarrow + 0x2D => 0x2196, # \nwarrow + 0x2E => 0x2199, # \swarrow + 0x2F => 0x221D, # \propto + + 0x30 => 0x2032, # \prime + 0x31 => 0x221E, # \infty + 0x32 => 0x2208, # \in + 0x33 => 0x220B, # \ni + 0x34 => 0x25B3, # \bigtriangleup and \triangle + 0x35 => 0x25BD, # \bigtriangledown + 0x36 => [0x338,-778,0], # \not (combining) + + 0x38 => 0x2200, # \forall + 0x39 => 0x2203, # \exists + 0x3A => 0xAC, # \neg + 0x3B => 0x2205, # \emptyset + 0x3C => 0x211C, # \Re + 0x3D => 0x2111, # \Im + 0x3E => 0x22A4, # \top + 0x3F => 0x22A5, # \bot + + 0x40 => 0x2135, # \aleph + + 0x5B => 0x222A, # \cup + 0x5C => 0x2229, # \cap + 0x5D => 0x228E, # \uplus + [0x5E,0x5F] => 0x2227, # \wedge, \vee + + [0x60,0x61] => 0x22A2, # \vdash, \dashv + [0x62,0x63] => 0x230A, # \lfloor, \rfloor + [0x64,0x65] => 0x2308, # \lceil, \rceil + 0x66 => 0x7B, # { + 0x67 => 0x7D, # } + [0x68,0x69] => 0x27E8, # \langle, \rangle + 0x6A => 0x7C, # | + 0x6A => 0x2223, # \vert + 0x6B => 0x2225, # \Vert + 0x6C => 0x2195, # \updownarrow + 0x6D => 0x21D5, # \Updownarrow + 0x6E => 0x5C, # \backslash + 0x6E => 0x2216, # \setminus + 0x6F => 0x2240, # \wr + + 0x70 => [0x221A,0,760], # \surd ### adjust position so font doesn't have a large depth + 0x71 => 0x2A3F, # \amalg + 0x72 => 0x2207, # \nabla + 0x73 => 0x222B, # \int + 0x74 => 0x2294, # \sqcup + 0x75 => 0x2293, # \sqcap + [0x76,0x77] => 0x2291, # \sqsubseteq, \sqsupseteq + + [0x79,0x7A] => 0x2020, # \dagger, \ddagger + + 0x7C => 0x2663, # \clubsuit + 0x7D => 0x2662, # \diamondsuit + 0x7E => 0x2661, # \heartsuit + 0x7F => 0x2660, # \spadesuit + ], + + "Math-Italic" => [ + 0x36 => 0x2F # \not + ], + + "Caligraphic-Regular" => [ + [0x41,0x5A] => 0x41, # A-Z + ], +}; + +$map{cmex10} = { + "Size1" => [ + 0 => [0x28,0,810], # ( + 1 => [0x29,0,810], # ) + 2 => [0x5B,0,810], # [ + 3 => [0x5D,0,810], # ] + 4 => [0x230A,0,810], # \lfloor + 5 => [0x230B,0,810], # \rfloor + 6 => [0x2308,0,810], # \lceil + 7 => [0x2309,0,810], # \rceil + 8 => [0x7B,0,810], # { + 9 => [0x7D,0,810], # } + 0xA => [0x27E8,0,810], # \langle + 0xB => [0x27E9,0,810], # \rangle + 0xC => [0x2223,0,606], # \vert + 0xD => [0x2225,0,606], # \Vert + 0xE => [0x2F,0,810], # / + 0xF => [0x5C,0,810], # \ + + 0x46 => [0x2A06,0,750], # \bigsqcup + 0x48 => [0x222E,0,805], # \oint + 0x4A => [0x2A00,0,750], # \bigodot + 0x4C => [0x2A01,0,750], # \bigoplus + 0x4E => [0x2A02,0,750], # \bigotimes + + 0x50 => [0x2211,0,750], # \sum + 0x51 => [0x220F,0,750], # \prod + 0x52 => [0x222B,0,805], # \int + 0x53 => [0x22C3,0,750], # \bigcup + 0x54 => [0x22C2,0,750], # \bigcap + 0x55 => [0x2A04,0,750], # \biguplus + 0x56 => [0x22C0,0,750], # \bigwedge + 0x57 => [0x22C1,0,750], # \bigvee + + 0x60 => [0x2210,0,750], # \coprod + 0x62 => 0x2C6, # \widehat + 0x62 => [0x302,-556,0], # \widehat (combining) + 0x65 => 0x2DC, # \widetilde + 0x65 => [0x303,-556,0], # \widetilde (combining) + + 0x70 => [0x221A,0,810], # surd + 0x3F => [0x23D0,0,601], # arrow extension + 0x77 => [0x2016,0,601], # Arrow extension (non-standard) + 0x78 => [0x2191,0,600], # uparrow top + 0x79 => [0x2193,0,600], # downarrow bottom + 0x7E => [0x21D1,0,600], # Uparrow top + 0x7F => [0x21D3,0,600], # Downarrow bottom + ], + + "Size2" => [ + 0x10 => [0x28,0,1110], # ( + 0x11 => [0x29,0,1110], # ) + 0x2E => [0x2F,0,1110], # / + 0x2F => [0x5C,0,1110], # \ + 0x44 => [0x27E8,0,1110],# \langle + 0x45 => [0x27E9,0,1110],# \rangle + + 0x47 => [0x2A06,0,950], # \bigsqcup + 0x49 => [0x222E,0,1360],# \oint + 0x4B => [0x2A00,0,950], # \bigodot + 0x4D => [0x2A01,0,950], # \bigoplus + 0x4F => [0x2A02,0,950], # \bigotimes + + 0x58 => [0x2211,0,950], # \sum + 0x59 => [0x220F,0,950], # \prod + 0x5A => [0x222B,0,1360],# \int + 0x5B => [0x22C3,0,950], # \bigcup + 0x5C => [0x22C2,0,950], # \bigcap + 0x5D => [0x2A04,0,950], # \biguplus + 0x5E => [0x22C0,0,950], # \bigwedge + 0x5F => [0x22C1,0,950], # \bigvee + 0x61 => [0x2210,0,950], # \coprod + + 0x63 => 0x2C6, # \widehat + 0x63 => [0x302,-1000,0],# \widehat (combining) + 0x66 => 0x2DC, # \widetilde + 0x66 => [0x303,-1000,0],# \widetilde (combining) + + 0x68 => [0x5B,0,1110], # [ + 0x69 => [0x5D,0,1110], # ] + 0x6A => [0x230A,0,1110],# \lfloor + 0x6B => [0x230B,0,1110],# \rfloor + 0x6C => [0x2308,0,1110],# \lceil + 0x6D => [0x2309,0,1110],# \rceil + 0x6E => [0x7B,0,1110], # { + 0x6F => [0x7D,0,1110], # } + 0x71 => [0x221A,0,1110],# surd + ], + + "Size3" => [ + 0x12 => [0x28,0,1410], # ( + 0x13 => [0x29,0,1410], # ) + 0x14 => [0x5B,0,1410], # [ + 0x15 => [0x5D,0,1410], # ] + 0x16 => [0x230A,0,1410],# \lfloor + 0x17 => [0x230B,0,1410],# \rfloor + 0x18 => [0x2308,0,1410],# \lceil + 0x19 => [0x2309,0,1410],# \rceil + 0x1A => [0x7B,0,1410], # { + 0x1B => [0x7D,0,1410], # } + 0x1C => [0x27E8,0,1410],# \langle + 0x1D => [0x27E9,0,1410],# \rangle + 0x1E => [0x2F,0,1410], # / + 0x1F => [0x5C,0,1410], # \ + 0x64 => 0x2C6, # \widehat + 0x64 => [0x302,-1444,0],# \widehat (combining) + 0x67 => 0x2DC, # \widetilde + 0x67 => [0x303,-1444,0],# \widetilde (combining) + 0x72 => [0x221A,0,1410],# surd + ], + + "Size4" => [ + 0x20 => [0x28,0,1710], # ( + 0x21 => [0x29,0,1710], # ) + 0x22 => [0x5B,0,1710], # [ + 0x23 => [0x5D,0,1710], # ] + 0x24 => [0x230A,0,1710],# \lfloor + 0x25 => [0x230B,0,1710],# \rfloor + 0x26 => [0x2308,0,1710],# \lceil + 0x27 => [0x2309,0,1710],# \rceil + 0x28 => [0x7B,0,1710], # { + 0x29 => [0x7D,0,1710], # } + 0x2A => [0x27E8,0,1710],# \langle + 0x2B => [0x27E9,0,1710],# \rangle + 0x2C => [0x2F,0,1710], # / + 0x2D => [0x5C,0,1710], # \ + 0x73 => [0x221A,0,1710],# surd + + 0x30 => [0x239B,0,1115],# left paren upper hook + 0x31 => [0x239E,0,1115],# right paren upper hook + 0x32 => [0x23A1,0,1115],# left square bracket upper corner + 0x33 => [0x23A4,0,1115],# right square bracket upper corner + 0x34 => [0x23A3,0,1115],# left square bracket lower corner + 0x35 => [0x23A6,0,1115],# right square bracket lower hook + 0x36 => [0x23A2,0,601], # left square bracket extension + 0x37 => [0x23A5,0,601], # right square bracket extension + 0x38 => [0x23A7,0,900], # left curly brace upper hook + 0x39 => [0x23AB,0,900], # right curly brace upper hook + 0x3A => 0x23A9, # left curly brace lower hook + 0x3B => 0x23AD, # right curly brace lower hook + 0x3C => [0x23A8,0,1150],# left curly brace middle + 0x3D => [0x23AC,0,1150],# right curly brace middle + 0x3E => [0x23AA,0,300], # curly brace extension + + 0x40 => [0x239D,0,1115],# left paren lower hook + 0x41 => [0x23A0,0,1115],# right paren lower hook + 0x42 => [0x239C,0,600], # left paren extension + 0x43 => [0x239F,0,600], # right paren extension + + 0x74 => [0x23B7,0,915], # radical bottom + 0x75 => [0xE000,0,605], # radical extension (PUA) + 0x76 => [0xE001,0,565], # radical top (PUA) + [0x7A,0x7D] => 0xE150, # \braceld, \bracerd, \bracelu, \braceru (PUA) + ], +}; + +$map{cmti10} = { + "Main-Italic" => [ + [0,1] => 0x393, # \Gamma, \Delta + 2 => 0x398, # \Theta + 3 => 0x39B, # \Lambda + 4 => 0x39E, # \Xi + 5 => 0x3A0, # \Pi + 6 => 0x3A3, # \Sigma + [7,8] => 0x3A5, # \Upsilon, \Phi + [9,0xA] => 0x3A8, # \Psi, \Omega + + 0x12 => [0x300,-511,0], # \grave (combining) + 0x13 => [0x301,-511,0], # \acute (combining) + 0x14 => [0x30C,-511,0], # \check (combining) + 0x15 => [0x306,-511,0], # \breve (combining) + 0x16 => [0x304,-511,0], # \bar (combining) + 0x17 => [0x30A,-671,0], # ring above (combining) + + [0x21,0x23] => 0x21, # !, ", #, + 0x22 => 0x201D, # " + 0x24 => 0xA3, # pound sign + [0x25,0x2F] => 0x25, # %, &, ', (, ), *, +, comma, -, ., / + 0x27 => 0x2019, # ' + [0x30,0x39] => 0x30, # 0-9 + [0x3A,0x3B] => 0x3A, # :, ; + 0x3D => 0x3D, # = + [0x3F,0x40] => 0x3F, # ?, @ + [0x41,0x5A] => 0x41, # A-Z + 0x5B => 0x5B, # [ + 0x5C => 0x201C, # `` + [0x5D,0x5E] => 0x5D, # ], ^ + 0x5E => [0x302,-511,0], # \hat (combining) + 0x5F => [0x307,-409,0], # \dot (combining) + 0x60 => 0x2018, # ` + [0x61,0x7A] => 0x61, # a-z + [0x7B,0x7C] => 0x2013, # \endash, \emdash + 0x7B => [0x5F,0,-310], # underline + 0x7D => [0x30B,-511,0], # double acute (combining) + 0x7E => [0x7E,0,-350], # ~ + 0x7E => [0x303,-511,0], # \tilde (combining) + 0x7F => [0x308,-511,0], # \ddot (combining) + ], +}; + +$map{cmbx10} = { + "Main-Bold" => [ + [0,1] => 0x393, # \Gamma, \Delta + 2 => 0x398, # \Theta + 3 => 0x39B, # \Lambda + 4 => 0x39E, # \Xi + 5 => 0x3A0, # \Pi + 6 => 0x3A3, # \Sigma + [7,8] => 0x3A5, # \Upsilon, \Phi + [9,0xA] => 0x3A8, # \Psi, \Omega + + 0x10 => 0x131, # \imath (roman bold) + 0x11 => 0x237, # \jmath (roman bold) + 0x12 => 0x60, # \grave + 0x12 => 0x2CB, # \grave + 0x12 => [0x300,-575,0], # \grave (combining) + 0x13 => 0xB4, # \acute + 0x13 => 0x2CA, # \acute + 0x13 => [0x301,-575,0], # \acute (combining) + 0x14 => 0x2C7, # \check + 0x14 => [0x30C,-575,0], # \check (combining) + 0x15 => 0x2D8, # \breve + 0x15 => [0x306,-575,0], # \breve (combining) + 0x16 => 0xAF, # \bar + 0x16 => 0x2C9, # \bar + 0x16 => [0x304,-575,0], # \bar (combining) + 0x17 => [0xB0,-147,0], # ring above + 0x17 => [0x2DA,-147,0], # ring above + 0x17 => [0x30A,-722,0], # ring above (combining) + + [0x21,0x2F] => 0x21, # !, ", #, $, %, &, ', (, ), *, +, comma, -, ., / + 0x22 => 0x201D, # " + 0x27 => 0x2019, # ' + [0x30,0x39] => 0x30, # 0-9 + [0x3A,0x3B] => 0x3A, # :, ; + 0x3D => 0x3D, # = + [0x3F,0x40] => 0x3F, # ?, @ + [0x41,0x5A] => 0x41, # A-Z + 0x5B => 0x5B, # [ + 0x5C => 0x201C, # `` + [0x5D,0x5E] => 0x5D, # ], ^ + 0x5E => 0x2C6, # \hat + 0x5E => [0x302,-575,0], # \hat (combining) + 0x5F => [0x2D9,128,0], # \dot + 0x5F => [0x307,-447,0], # \dot (combining) + 0x60 => 0x2018, # ` + [0x61,0x7A] => 0x61, # a-z + [0x7B,0x7C] => 0x2013, # \endash, \emdash + 0x7B => [0x5F,0,-310], # underline + 0x7D => [0x30B,-575,0], # double acute (combining) + 0x7E => [0x7E,0,-350], # ~ + 0x7E => 0x2DC, # \tilde + 0x7E => [0x303,-575,0], # \tilde (combining) + 0x7F => 0xA8, # \ddot + 0x7F => [0x308,-575,0], # \ddot (combining) + ], +}; + +$map{cmmib10} = { + "Math-BoldItalic" => [ + [0,1] => 0x393, # \Gamma, \Delta + 2 => 0x398, # \Theta + 3 => 0x39B, # \Lambda + 4 => 0x39E, # \Xi + 5 => 0x3A0, # \Pi + 6 => 0x3A3, # \Sigma + [7,8] => 0x3A5, # \Upsilon, \Phi + [9,0xA] => 0x3A8, # \Psi, \Omega + + [0xB,0xE] => 0x3B1, # \alpha, \beta, \gamma, \delta + 0xF => 0x3F5, # \elpsilon + [0x10,0x18] => 0x3B6, # \zeta, \eta, \theta, \iota, \kappa, \lambda, \mu, \nu, \xi + [0x19,0x1A] => 0x3C0, # \pi, \rho + [0x1B,0x1D] => 0x3C3, # \sigma, \tau, \upsilon + 0x1E => 0x3D5, # \phi + [0x1F,0x21] => 0x3C7, # \chi, \psi, \omega + 0x22 => 0x3B5, # \varepsilon + 0x23 => 0x3D1, # \vartheta + 0x24 => 0x3D6, # \varpi + 0x25 => 0x3F1, # \varrho + 0x26 => 0x3C2, # \varsigma + 0x27 => 0x3C6, # \varphi + + [0x41,0x5A] => 0x41, # A-Z + [0x61,0x7A] => 0x61, # a - z + 0x6F => 0x3BF, # omicron + ], + + "Main-Bold" => [ + 0x28 => 0x21BC, # \leftharpoonup + 0x29 => 0x21BD, # \leftharpoondown + 0x2A => 0x21C0, # \rightharpoonup + 0x2B => 0x21C1, # \rightharpoondown + + 0x2E => 0x25B9, # \triangleright + 0x2F => 0x25C3, # \triangleleft + + 0x3C => 0x3C, # < + 0x3D => 0x2215, # / + 0x3E => 0x3E, # > + 0x3F => 0x22C6, # \star + 0x40 => 0x2202, # \partial + + [0x5B,0x5D] => 0x266D, # \flat, \natural, \sharp + 0x5E => 0x2323, # \smile + 0x5F => 0x2322, # \frown + 0x60 => 0x2113, # \ell + 0x68 => 0x210F, # \hbar (bar added below) + + 0x7D => 0x2118, # \wp + 0x7E => [0x20D7,-729,0],# \vec + ], +}; + +$map{cmbsy10} = { + "Main-Bold" => [ + 0 => 0x2212, # - + 1 => 0x22C5, # \cdot + 2 => 0xD7, # \times + 3 => 0x2217, # \ast + 4 => 0xF7, # \div + 5 => 0x22C4, # \diamond + 6 => 0xB1, # \pm + 7 => 0x2213, # \mp + [8,0xC] => 0x2295, # \oplus, \ominus, \otimes, \oslash, \odot + 0xD => 0x25EF, # \bigcirc + [0xE,0xF] => 0x2218, # \circ, \bullet + + 0x10 => 0x224D, # \asymp + 0x11 => 0x2261, # \equiv + [0x12,0x13] => 0x2286, # \subseteq, \supseteq + [0x14,0x15] => 0x2264, # \leq, \geq + [0x16,0x17] => 0x2AAF, # \preceq, \succeq + 0x18 => 0x223C, # \sim + 0x19 => 0x2248, # \approx + [0x1A,0x1B] => 0x2282, # \subset, \supset + [0x1C,0x1D] => 0x226A, # \ll, \gg + [0x1E,0x1F] => 0x227A, # \prec, \succ + + 0x20 => 0x2190, # \leftarrow + 0x21 => 0x2192, # \rightarrow + 0x22 => 0x2191, # \uparrow + 0x23 => 0x2193, # \downarrow + 0x24 => 0x2194, # \leftrightarrow + 0x25 => 0x2197, # \nearrow + 0x26 => 0x2198, # \searrow + 0x27 => 0x2243, # \simeq + + 0x28 => 0x21D0, # \Leftarrow + 0x29 => 0x21D2, # \Rightarrow + 0x2A => 0x21D1, # \Uparrow + 0x2B => 0x21D3, # \Downarrow + 0x2C => 0x21D4, # \Leftrightarrow + 0x2D => 0x2196, # \nwarrow + 0x2E => 0x2199, # \swarrow + 0x2F => 0x221D, # \propto + + 0x30 => 0x2032, # \prime + 0x31 => 0x221E, # \infty + 0x32 => 0x2208, # \in + 0x33 => 0x220B, # \ni + 0x34 => 0x25B3, # \bigtriangleup and \triangle + 0x35 => 0x25BD, # \bigtriangledown + 0x36 => [0x338,-894,0], # \not (combining) + + 0x38 => 0x2200, # \forall + 0x39 => 0x2203, # \exists + 0x3A => 0xAC, # \neg + 0x3B => 0x2205, # \emptyset + 0x3C => 0x211C, # \Re + 0x3D => 0x2111, # \Im + 0x3E => 0x22A4, # \top + 0x3F => 0x22A5, # \bot + + 0x40 => 0x2135, # \aleph + + 0x5B => 0x222A, # \cup + 0x5C => 0x2229, # \cap + 0x5D => 0x228E, # \uplus + [0x5E,0x5F] => 0x2227, # \wedge, \vee + + [0x60,0x61] => 0x22A2, # \vdash, \dashv + [0x62,0x63] => 0x230A, # \lfloor, \rfloor + [0x64,0x65] => 0x2308, # \lceil, \rceil + 0x66 => 0x7B, # { + 0x67 => 0x7D, # } + [0x68,0x69] => 0x27E8, # \langle, \rangle + 0x6A => 0x7C, # | + 0x6A => 0x2223, # \vert + 0x6B => 0x2225, # \Vert + 0x6C => 0x2195, # \updownarrow + 0x6D => 0x21D5, # \Updownarrow + 0x6E => 0x5C, # \backslash + 0x6E => 0x2216, # \setminus + 0x6F => 0x2240, # \wr + + 0x70 => [0x221A,0,760], # \surd ### adjust position so font doesn't have a large depth + 0x71 => 0x2A3F, # \amalg + 0x72 => 0x2207, # \nabla + 0x73 => 0x222B, # \int + 0x74 => 0x2294, # \sqcup + 0x75 => 0x2293, # \sqcap + [0x76,0x77] => 0x2291, # \sqsubseteq, \sqsupseteq + + [0x79,0x7A] => 0x2020, # \dagger, \ddagger + + 0x7C => 0x2663, # \clubsuit + 0x7D => 0x2662, # \diamondsuit + 0x7E => 0x2661, # \heartsuit + 0x7F => 0x2660, # \spadesuit + ], + + "Math-BoldItalic" => [ + 0x36 => 0x2F # \not + ], +}; + +$map{msam10} = { + "Main-Regular" => [ + 0x5C => 0x2220, # \angle + ], + + "Main-Bold" => [ + 0x5C => 0x2220, # \angle (emboldened below) + ], + + "AMS" => [ + 0x00 => 0x22A1, # \boxdot + 0x01 => 0x229E, # \boxplus + 0x02 => 0x22A0, # \boxtimes + 0x03 => 0x25A1, # \square + 0x04 => 0x25A0, # \blacksquare + 0x05 => 0x22C5, # \centerdot + 0x06 => 0x25CA, # \lozenge + 0x07 => 0x29EB, # \blacklozenge + 0x08 => 0x21BB, # \circlearrowright + 0x09 => 0x21BA, # \circlearrowleft + 0x0A => 0x21CC, # \rightleftharpoons + 0x0B => 0x21CB, # \leftrightharpoons + 0x0C => 0x229F, # \boxminus + 0x0D => 0x22A9, # \Vdash + 0x0E => 0x22AA, # \Vvdash + 0x0F => 0x22A8, # \vDash + 0x10 => 0x21A0, # \twoheadrightarrow + 0x11 => 0x219E, # \twoheadleftarrow + 0x12 => 0x21C7, # \leftleftarrows + 0x13 => 0x21C9, # \rightrightarrows + 0x14 => 0x21C8, # \upuparrows + 0x15 => 0x21CA, # \downdownarrows + 0x16 => 0x21BE, # \upharpoonright + 0x17 => 0x21C2, # \downharpoonright + 0x18 => 0x21BF, # \upharpoonleft + 0x19 => 0x21C3, # \downharpoonleft + 0x1A => 0x21A3, # \rightarrowtail + 0x1B => 0x21A2, # \leftarrowtail + 0x1C => 0x21C6, # \leftrightarrows + 0x1D => 0x21C4, # \rightleftarrows + 0x1E => 0x21B0, # \Lsh + 0x1F => 0x21B1, # \Rsh + 0x20 => 0x21DD, # \rightsquigarrow + 0x21 => 0x21AD, # \leftrightsquigarrow + 0x22 => 0x21AB, # \looparrowleft + 0x23 => 0x21AC, # \looparrowright + 0x24 => 0x2257, # \circeq + 0x25 => 0x227F, # \succsim + 0x26 => 0x2273, # \gtrsim + 0x27 => 0x2A86, # \gtrapprox + 0x28 => 0x22B8, # \multimap + 0x29 => 0x2234, # \therefore + 0x2A => 0x2235, # \because + 0x2B => 0x2251, # \doteqdot + 0x2C => 0x225C, # \triangleq + 0x2D => 0x227E, # \precsim + 0x2E => 0x2272, # \lesssim + 0x2F => 0x2A85, # \lessapprox + 0x30 => 0x2A95, # \eqslantless + 0x31 => 0x2A96, # \eqslantgtr + 0x32 => 0x22DE, # \curlyeqprec + 0x33 => 0x22DF, # \curlyeqsucc + 0x34 => 0x227C, # \preccurlyeq + 0x35 => 0x2266, # \leqq + 0x36 => 0x2A7D, # \leqslant + 0x37 => 0x2276, # \lessgtr + 0x38 => 0x2035, # \backprime + 0x39 => 0x2212, # dahsed arrow extension + 0x3A => 0x2253, # \risingdotseq + 0x3B => 0x2252, # \fallingdotseq + 0x3C => 0x227D, # \succcurlyeq + 0x3D => 0x2267, # \geqq + 0x3E => 0x2A7E, # \geqslant + 0x3F => 0x2277, # \gtrless + 0x40 => 0x228F, # \sqsubset + 0x41 => 0x2290, # \sqsupset + 0x42 => 0x22B3, # \vartriangleright + 0x43 => 0x22B2, # \vartriangleleft + 0x44 => 0x22B5, # \trianglerighteq + 0x45 => 0x22B4, # \trianglelefteq + 0x46 => 0x2605, # \bigstar + 0x47 => 0x226C, # \between + 0x48 => 0x25BC, # \blacktriangledown + 0x49 => 0x25B6, # \blacktriangleright + 0x4A => 0x25C0, # \blacktriangleleft + 0x4B => 0x2192, # rightarrow + 0x4C => 0x2190, # leftarrow + 0x4D => 0x25B3, # \vartriangle + 0x4E => 0x25B2, # \blacktriangle + 0x4F => 0x25BD, # \triangledown + 0x50 => 0x2256, # \eqcirc + 0x51 => 0x22DA, # \lesseqgtr + 0x52 => 0x22DB, # \gtreqless + 0x53 => 0x2A8B, # \lesseqqgtr + 0x54 => 0x2A8C, # \gtreqqless + 0x55 => 0x00A5, # yen + 0x56 => 0x21DB, # \Rrightarrow + 0x57 => 0x21DA, # \Lleftarrow + 0x58 => 0x2713, # checkmark + 0x59 => 0x22BB, # \veebar + 0x5A => 0x22BC, # \barwedge + 0x5B => 0x2A5E, # \doublebarwedge + 0x5C => 0x2220, # \angle + 0x5D => 0x2221, # \measuredangle + 0x5E => 0x2222, # \sphericalangle + 0x5F => 0x221D, # \varpropto + 0x60 => 0x2323, # \smallsmile + 0x61 => 0x2322, # \smallfrown + 0x62 => 0x22D0, # \Subset + 0x63 => 0x22D1, # \Supset + 0x64 => 0x22D3, # \Cup + 0x65 => 0x22D2, # \Cap + 0x66 => 0x22CF, # \curlywedge + 0x67 => 0x22CE, # \curlyvee + 0x68 => 0x22CB, # \leftthreetimes + 0x69 => 0x22CC, # \rightthreetimes + 0x6A => 0x2AC5, # \subseteqq + 0x6B => 0x2AC6, # \supseteqq + 0x6C => 0x224F, # \bumpeq + 0x6D => 0x224E, # \Bumpeq + 0x6E => 0x22D8, # \lll + 0x6F => 0x22D9, # \ggg + 0x70 => 0x250C, # \ulcorner + 0x71 => 0x2510, # \urcorner + 0x72 => 0x00AE, # registered sign + 0x73 => 0x24C8, # \circledS + 0x74 => 0x22D4, # \pitchfork + 0x75 => 0x2214, # \dotplus + 0x76 => 0x223D, # \backsim + 0x77 => 0x22CD, # \backsimeq + 0x78 => 0x2514, # \llcorner + 0x79 => 0x2518, # \lrcorner + 0x7A => 0x2720, # maltese cross + 0x7B => 0x2201, # \complement + 0x7C => 0x22BA, # \intercal + 0x7D => 0x229A, # \circledcirc + 0x7E => 0x229B, # \circledast + 0x7F => 0x229D, # \circleddash + ], +}; + +$map{msbm10} = { + "Size4" => [ + 0x5B => 0x2C6, # \widehat + 0x5B => [0x302,-1889,0],# \widehat (combining) + 0x5D => 0x2DC, # \widetilde + 0x5D => [0x303,-1889,0],# \widetilde (combining) + ], + + "Main-Regular" => [ + 0x7E => 0x210F, # \hbar + ], + + "Main-Italic" => [ + 0x7D => 0x210F, # \hbar (with slant) + ], + + "AMS" => [ + 0x00 => 0xE00C, # \lvertneqq + 0x01 => 0xE00D, # \gvertneqq + 0x02 => 0x2270, # \nleq + 0x03 => 0x2271, # \ngeq + 0x04 => 0x226E, # \nless + 0x05 => 0x226F, # \ngtr + 0x06 => 0x2280, # \nprec + 0x07 => 0x2281, # \nsucc + 0x08 => 0x2268, # \lneqq + 0x09 => 0x2269, # \gneqq + 0x0A => 0xE010, # \nleqslant + 0x0B => 0xE00F, # \ngeqslant + 0x0C => 0x2A87, # \lneq + 0x0D => 0x2A88, # \gneq + 0x0E => 0x22E0, # \npreceq + 0x0F => 0x22E1, # \nsucceq + 0x10 => 0x22E8, # \precnsim + 0x11 => 0x22E9, # \succnsim + 0x12 => 0x22E6, # \lnsim + 0x13 => 0x22E7, # \gnsim + 0x14 => 0xE011, # \nleqq + 0x15 => 0xE00E, # \ngeqq + 0x16 => 0x2AB5, # \precneqq + 0x17 => 0x2AB6, # \succneqq + 0x18 => 0x2AB9, # \precnapprox + 0x19 => 0x2ABA, # \succnapprox + 0x1A => 0x2A89, # \lnapprox + 0x1B => 0x2A8A, # \gnapprox + 0x1C => 0x2241, # \nsim + 0x1D => 0x2246, # \ncong + 0x1E => 0x2571, # \diagup + 0x1F => 0x2572, # \diagdown + 0x20 => 0xE01A, # \varsubsetneq + 0x21 => 0xE01B, # \varsupsetneq + 0x22 => 0xE016, # \nsubseteqq + 0x23 => 0xE018, # \nsupseteqq + 0x24 => 0x2ACB, # \subsetneqq + 0x25 => 0x2ACC, # \supsetneqq + 0x26 => 0xE017, # \varsubsetneqq + 0x27 => 0xE019, # \varsupsetneqq + 0x28 => 0x228A, # \subsetneq + 0x29 => 0x228B, # \supsetneq + 0x2A => 0x2288, # \nsubseteq + 0x2B => 0x2289, # \nsupseteq + 0x2C => 0x2226, # \nparallel + 0x2D => 0x2224, # \nmid + 0x2E => 0xE006, # \nshortmid + 0x2F => 0xE007, # \nshortparallel + 0x30 => 0x22AC, # \nvdash + 0x31 => 0x22AE, # \nVdash + 0x32 => 0x22AD, # \nvDash + 0x33 => 0x22AF, # \nVDash + 0x34 => 0x22ED, # \ntrianglerighteq + 0x35 => 0x22EC, # \ntrianglelefteq + 0x36 => 0x22EA, # \ntriangleleft + 0x37 => 0x22EB, # \ntriangleright + 0x38 => 0x219A, # \nleftarrow + 0x39 => 0x219B, # \nrightarrow + 0x3A => 0x21CD, # \nLeftarrow + 0x3B => 0x21CF, # \nRightarrow + 0x3C => 0x21CE, # \nLeftrightarrow + 0x3D => 0x21AE, # \nleftrightarrow + 0x3E => 0x22C7, # \divideontimes + 0x3F => 0x2205, # \varnothing + 0x40 => 0x2204, # \nexists + + [0x41,0x5A] => 0x41, # A-Z + 0x5C => 0x2C6, # \widehat + 0x5C => [0x302,-2333,0],# \widehat (combining) + 0x5E => 0x2DC, # \widetilde + 0x5E => [0x303,-2333,0],# \widetilde (combining) + + 0x60 => 0x2132, # \Finv + 0x61 => 0x2141, # \Game + 0x66 => 0x2127, # \mho + 0x67 => 0x00F0, # \eth + 0x68 => 0x2242, # minus-tilde + 0x69 => 0x2136, # \beth + 0x6A => 0x2137, # \gimel + 0x6B => 0x2138, # \daleth + 0x6C => 0x22D6, # \lessdot + 0x6D => 0x22D7, # \gtrdot + 0x6E => 0x22C9, # \ltimes + 0x6F => 0x22CA, # \rtimes + 0x70 => 0x2223, # \shortmid + 0x71 => 0x2225, # \shortparallel + 0x72 => 0x2216, # \smallsetminus + 0x73 => 0x223C, # \thicksim + 0x74 => 0x2248, # \thickapprox + 0x75 => 0x224A, # \approxeq + 0x76 => 0x2AB8, # \succapprox + 0x77 => 0x2AB7, # \precapprox + 0x78 => 0x21B6, # \curvearrowleft + 0x79 => 0x21B7, # \curvearrowright + 0x7A => 0x03DD, # \digamma + 0x7B => 0x03F0, # \varkappa + 0x7A => 0xE008, # \digamma (non-standard, for IE) + 0x7B => 0xE009, # \varkappa (non-standard, for IE) + 0x7C => 0x006B, # \Bbbk + 0x7D => 0x210F, # \hslash + 0x7E => 0x0127, # \hbar + 0x7F => 0x220D, # \backepsilon + ], +}; + +$map{eufm10} = { + "Fraktur-Regular" => [ + [0,7] => 0xE300, # variants + 0x12 => 0x2018, # left quote + 0x13 => 0x2019, # right quote + 0x21 => 0x21, # ! + [0x26,0x2F] => 0x26, # &, ', (, ), *, +, comma, -, ., / + [0x30,0x39] => 0x30, # 0-9 + [0x3A,0x3B] => 0x3A, # :, ; + 0x3D => 0x3D, # = + 0x3F => 0x3F, # ? + [0x41,0x5A] => 0x41, # A-Z + 0x5B => 0x5B, # [ + [0x5D,0x5E] => 0x5D, # ], ^ + [0x61,0x7A] => 0x61, # a-z + 0x7D => 0x22, # " + ], +}; + +$map{cmtt10} = { + "Typewriter-Regular" => [ + [0,1] => 0x393, # \Gamma, \Delta + 2 => 0x398, # \Theta + 3 => 0x39B, # \Lambda + 4 => 0x39E, # \Xi + 5 => 0x3A0, # \Pi + 6 => 0x3A3, # \Sigma + [7,8] => 0x3A5, # \Upsilon, \Phi + [9,0xA] => 0x3A8, # \Psi, \Omega + 0xD => 0x2032, # ' + + 0x10 => 0x131, # \imath (roman) + 0x11 => 0x237, # \jmath (roman) + 0x12 => [0x300,-525,0], # \grave (combining) + 0x13 => [0x301,-525,0], # \acute (combining) + 0x14 => [0x30C,-525,0], # \check (combining) + 0x15 => [0x306,-525,0], # \breve (combining) + 0x16 => [0x304,-525,0], # \bar (combining) + 0x17 => [0x30A,-525,0], # ring above (combining) + + [0x21,0x7F] => 0x21, + + 0x27 => 2018, # left quote + 0x60 => 2019, # right quote + 0x5E => [0x302,-525,0], # \hat (combining) + 0x7E => [0x303,-525,0], # \tilde (combining) + 0x7F => [0x308,-525,0], # \ddot (combining) + ], +}; + +$map{rsfs10} = { + "Script-Regular" => [ + [0x41,0x5A] => 0x41, # A-Z + ], +}; + +$map{cmss10} = { + "SansSerif-Regular" => [ + [0,1] => 0x393, # \Gamma, \Delta + 2 => 0x398, # \Theta + 3 => 0x39B, # \Lambda + 4 => 0x39E, # \Xi + 5 => 0x3A0, # \Pi + 6 => 0x3A3, # \Sigma + [7,8] => 0x3A5, # \Upsilon, \Phi + [9,0xA] => 0x3A8, # \Psi, \Omega + + 0x10 => 0x131, # \imath (roman) + 0x11 => 0x237, # \jmath (roman) + 0x12 => [0x300,-500,0], # \grave (combining) + 0x13 => [0x301,-500,0], # \acute (combining) + 0x14 => [0x30C,-500,0], # \check (combining) + 0x15 => [0x306,-500,0], # \breve (combining) + 0x16 => [0x304,-500,0], # \bar (combining) + 0x17 => [0x30A,-542,0], # ring above (combining) + + [0x21,0x2F] => 0x21, # !, ", #, $, %, &, ', (, ), *, +, comma, -, ., / + 0x22 => 0x201D, # " + 0x27 => 0x2019, # ' + [0x30,0x39] => 0x30, # 0-9 + [0x3A,0x3B] => 0x3A, # :, ; + 0x3D => 0x3D, # = + [0x3F,0x40] => 0x3F, # ?, @ + [0x41,0x5A] => 0x41, # A-Z + 0x5B => 0x5B, # [ + 0x5C => 0x201C, # `` + [0x5D,0x5E] => 0x5D, # ], ^ + 0x5E => [0x302,-500,0], # \hat (combining) + 0x5F => [0x307,-389,0], # \dot (combining) + 0x60 => 0x2018, # ` + [0x61,0x7A] => 0x61, # a-z + [0x7B,0x7C] => 0x2013, # \endash, \emdash + 0x7B => [0x5F,0,-350], # underline + 0x7D => [0x30B,-500,0], # double acute (combining) + 0x7E => [0x7E,0,-350], # ~ + 0x7E => [0x303,-500,0], # \tilde (combining) + 0x7F => [0x308,-500,0], # \ddot (combining) + ], +}; + +foreach $cmfont (keys %map) { + foreach $mjfont (keys %{$map{$cmfont}}) { + $style = $mjfont; $style =~ s/.*?(-|$)//; $style = "Regular" unless $style; + $family = $mjfont; $family =~ s/-.*//; + $fontname = "$family-$style"; + @{$reverse{$fontname}{$cmfont}} = @{$map{$cmfont}{$mjfont}}; + } +} + +my %output; + +sub add_to_output { + my ($mjfont,$cmfont,$from,$to) = @_; + + my $xshift = 0, $yshift = 0; + + if (ref($to) eq "ARRAY") { + $xshift = $to->[1]; + $yshift = $to->[2]; + $to = $to->[0]; + } + + $data = { + "font" => $cmfont, + "char" => $from, + "xshift" => $xshift, + "yshift" => $yshift + }; + + if (defined($output{$mjfont}{$to})) { + print STDERR "Duplicate mapping $to for $mjfont: " . + $output{$mjfont}{$to}{font} . ":" . + $output{$mjfont}{$to}{char} . " vs. $cmfont:$from\n"; + die "Duplicate mapping!"; # disable this line to see all of them + } + $output{$mjfont}{$to} = $data; +} + +foreach $mjfont (keys %reverse) { + foreach $cmfont (keys %{$reverse{$mjfont}}) { + @remap = @{$reverse{$mjfont}{$cmfont}}; + while (defined($item = shift(@remap))) { + $remap = shift(@remap); + + if (ref($item) eq "ARRAY") { + foreach $from ($item->[0]...$item->[1]) { + $to = $from - $item->[0] + $remap; + add_to_output($mjfont, $cmfont, $from, $to); + } + } else { + add_to_output($mjfont, $cmfont, $item, $remap); + } + } + } +} + +print(encode_json(\%output)); diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/metrics/parse_tfm.py b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/metrics/parse_tfm.py new file mode 100644 index 0000000..56f2db0 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/metrics/parse_tfm.py @@ -0,0 +1,211 @@ +class CharInfoWord(object): + def __init__(self, word): + b1, b2, b3, b4 = (word >> 24, + (word & 0xff0000) >> 16, + (word & 0xff00) >> 8, + word & 0xff) + + self.width_index = b1 + self.height_index = b2 >> 4 + self.depth_index = b2 & 0x0f + self.italic_index = (b3 & 0b11111100) >> 2 + self.tag = b3 & 0b11 + self.remainder = b4 + + def has_ligkern(self): + return self.tag == 1 + + def ligkern_start(self): + return self.remainder + + +class LigKernProgram(object): + def __init__(self, program): + self.program = program + + def execute(self, start, next_char): + curr_instruction = start + while True: + instruction = self.program[curr_instruction] + (skip, inst_next_char, op, remainder) = instruction + + if inst_next_char == next_char: + if op < 128: + # Don't worry about ligatures for now, we only need kerns + return None + else: + return 256 * (op - 128) + remainder + elif skip >= 128: + return None + else: + curr_instruction += 1 + skip + + +class TfmCharMetrics(object): + def __init__(self, width, height, depth, italic, kern_table): + self.width = width + self.height = height + self.depth = depth + self.italic_correction = italic + self.kern_table = kern_table + + +class TfmFile(object): + def __init__(self, start_char, end_char, char_info, width_table, + height_table, depth_table, italic_table, ligkern_table, + kern_table): + self.start_char = start_char + self.end_char = end_char + self.char_info = char_info + self.width_table = width_table + self.height_table = height_table + self.depth_table = depth_table + self.italic_table = italic_table + self.ligkern_program = LigKernProgram(ligkern_table) + self.kern_table = kern_table + + def get_char_metrics(self, char_num, fix_rsfs=False): + """Return glyph metrics for a unicode code point. + + Arguments: + char_num: a unicode code point + fix_rsfs: adjust for rsfs10.tfm's different indexing system + """ + if char_num < self.start_char or char_num > self.end_char: + raise RuntimeError("Invalid character number") + + if fix_rsfs: + # all of the char_nums contained start from zero in rsfs10.tfm + info = self.char_info[char_num - self.start_char] + else: + info = self.char_info[char_num + self.start_char] + + char_kern_table = {} + if info.has_ligkern(): + for char in range(self.start_char, self.end_char + 1): + kern = self.ligkern_program.execute(info.ligkern_start(), char) + if kern: + char_kern_table[char] = self.kern_table[kern] + + return TfmCharMetrics( + self.width_table[info.width_index], + self.height_table[info.height_index], + self.depth_table[info.depth_index], + self.italic_table[info.italic_index], + char_kern_table) + + +class TfmReader(object): + def __init__(self, f): + self.f = f + + def read_byte(self): + return ord(self.f.read(1)) + + def read_halfword(self): + b1 = self.read_byte() + b2 = self.read_byte() + return (b1 << 8) | b2 + + def read_word(self): + b1 = self.read_byte() + b2 = self.read_byte() + b3 = self.read_byte() + b4 = self.read_byte() + return (b1 << 24) | (b2 << 16) | (b3 << 8) | b4 + + def read_fixword(self): + word = self.read_word() + + neg = False + if word & 0x80000000: + neg = True + word = (-word & 0xffffffff) + + return (-1 if neg else 1) * word / float(1 << 20) + + def read_bcpl(self, length): + str_length = self.read_byte() + data = self.f.read(length - 1) + return data[:str_length] + + +def read_tfm_file(file_name): + with open(file_name, 'rb') as f: + reader = TfmReader(f) + + # file_size + reader.read_halfword() + header_size = reader.read_halfword() + + start_char = reader.read_halfword() + end_char = reader.read_halfword() + + width_table_size = reader.read_halfword() + height_table_size = reader.read_halfword() + depth_table_size = reader.read_halfword() + italic_table_size = reader.read_halfword() + + ligkern_table_size = reader.read_halfword() + kern_table_size = reader.read_halfword() + + # extensible_table_size + reader.read_halfword() + # parameter_table_size + reader.read_halfword() + + # checksum + reader.read_word() + # design_size + reader.read_fixword() + + if header_size > 2: + # coding_scheme + reader.read_bcpl(40) + + if header_size > 12: + # font_family + reader.read_bcpl(20) + + for i in range(header_size - 17): + reader.read_word() + + char_info = [] + for i in range(start_char, end_char + 1): + char_info.append(CharInfoWord(reader.read_word())) + + width_table = [] + for i in range(width_table_size): + width_table.append(reader.read_fixword()) + + height_table = [] + for i in range(height_table_size): + height_table.append(reader.read_fixword()) + + depth_table = [] + for i in range(depth_table_size): + depth_table.append(reader.read_fixword()) + + italic_table = [] + for i in range(italic_table_size): + italic_table.append(reader.read_fixword()) + + ligkern_table = [] + for i in range(ligkern_table_size): + skip = reader.read_byte() + next_char = reader.read_byte() + op = reader.read_byte() + remainder = reader.read_byte() + + ligkern_table.append((skip, next_char, op, remainder)) + + kern_table = [] + for i in range(kern_table_size): + kern_table.append(reader.read_fixword()) + + # There is more information, like the ligkern, kern, extensible, and + # param table, but we don't need these for now + + return TfmFile(start_char, end_char, char_info, width_table, + height_table, depth_table, italic_table, + ligkern_table, kern_table) diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/package.json b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/package.json new file mode 100644 index 0000000..ae4dd41 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/package.json @@ -0,0 +1,37 @@ +{ + "name": "katex", + "version": "0.6.0-pre", + "description": "Fast math typesetting for the web.", + "main": "katex.js", + "repository": { + "type": "git", + "url": "git://github.com/Khan/KaTeX.git" + }, + "files": [ + "katex.js", + "cli.js", + "src/" + ], + "license": "MIT", + "devDependencies": { + "browserify": "^10.2.4", + "clean-css": "~2.2.15", + "express": "~3.3.3", + "jasmine-node": "2.0.0-beta4", + "js-yaml": "^3.3.1", + "jshint": "^2.5.6", + "jspngopt": "^0.1.0", + "less": "~1.7.5", + "pako": "0.2.7", + "nomnom": "^1.8.1", + "selenium-webdriver": "^2.46.1", + "uglify-js": "~2.4.15" + }, + "bin": "cli.js", + "scripts": { + "test": "make lint test" + }, + "dependencies": { + "match-at": "^0.1.0" + } +} diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/server.js b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/server.js new file mode 100644 index 0000000..ed5c20e --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/server.js @@ -0,0 +1,79 @@ +var fs = require("fs"); +var path = require("path"); + +var browserify = require("browserify"); +var express = require("express"); +var less = require("less"); + +var app = express(); + +if (require.main === module) { + app.use(express.logger()); +} + +var serveBrowserified = function(file, standaloneName) { + return function(req, res, next) { + var options = {}; + if (standaloneName) { + options.standalone = standaloneName; + } + var b = browserify([file], options); + var stream = b.bundle(); + + var body = ""; + stream.on("data", function(s) { body += s; }); + stream.on("error", function(e) { next(e); }); + stream.on("end", function() { + res.setHeader("Content-Type", "text/javascript"); + res.send(body); + }); + }; +}; + +app.get("/katex.js", serveBrowserified("./katex", "katex")); +app.get("/test/katex-spec.js", serveBrowserified("./test/katex-spec")); +app.get("/contrib/auto-render/auto-render.js", + serveBrowserified("./contrib/auto-render/auto-render", + "renderMathInElement")); + +app.get("/katex.css", function(req, res, next) { + fs.readFile("static/katex.less", {encoding: "utf8"}, function(err, data) { + if (err) { + next(err); + return; + } + + var parser = new less.Parser({ + paths: ["./static"], + filename: "katex.less" + }); + + parser.parse(data, function(err, tree) { + if (err) { + next(err); + return; + } + + res.setHeader("Content-Type", "text/css"); + res.send(tree.toCSS()); + }); + }); +}); + +app.use(express["static"](path.join(__dirname, "static"))); +app.use(express["static"](path.join(__dirname, "build"))); +app.use("/test", express["static"](path.join(__dirname, "test"))); +app.use("/contrib", express["static"](path.join(__dirname, "contrib"))); + +app.use(function(err, req, res, next) { + console.error(err.stack); + res.setHeader("Content-Type", "text/plain"); + res.send(500, err.stack); +}); + +if (require.main === module) { + app.listen(7936); + console.log("Serving on http://0.0.0.0:7936/ ..."); +} + +module.exports = app; diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/Lexer.js b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/Lexer.js new file mode 100644 index 0000000..05784ca --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/Lexer.js @@ -0,0 +1,162 @@ +/** + * The Lexer class handles tokenizing the input in various ways. Since our + * parser expects us to be able to backtrack, the lexer allows lexing from any + * given starting point. + * + * Its main exposed function is the `lex` function, which takes a position to + * lex from and a type of token to lex. It defers to the appropriate `_innerLex` + * function. + * + * The various `_innerLex` functions perform the actual lexing of different + * kinds. + */ + +var matchAt = require("match-at"); + +var ParseError = require("./ParseError"); + +// The main lexer class +function Lexer(input) { + this._input = input; +} + +// The resulting token returned from `lex`. +function Token(text, data, position) { + this.text = text; + this.data = data; + this.position = position; +} + +/* The following tokenRegex + * - matches typical whitespace (but not NBSP etc.) using its first group + * - matches symbol combinations which result in a single output character + * - does not match any control character \x00-\x1f except whitespace + * - does not match a bare backslash + * - matches any ASCII character except those just mentioned + * - does not match the BMP private use area \uE000-\uF8FF + * - does not match bare surrogate code units + * - matches any BMP character except for those just described + * - matches any valid Unicode surrogate pair + * - matches a backslash followed by one or more letters + * - matches a backslash followed by any BMP character, including newline + * Just because the Lexer matches something doesn't mean it's valid input: + * If there is no matching function or symbol definition, the Parser will + * still reject the input. + */ +var tokenRegex = new RegExp( + "([ \r\n\t]+)|(" + // whitespace + "---?" + // special combinations + "|[!-\\[\\]-\u2027\u202A-\uD7FF\uF900-\uFFFF]" + // single codepoint + "|[\uD800-\uDBFF][\uDC00-\uDFFF]" + // surrogate pair + "|\\\\(?:[a-zA-Z]+|[^\uD800-\uDFFF])" + // function name + ")" +); + +var whitespaceRegex = /\s*/; + +/** + * This function lexes a single normal token. It takes a position and + * whether it should completely ignore whitespace or not. + */ +Lexer.prototype._innerLex = function(pos, ignoreWhitespace) { + var input = this._input; + if (pos == input.length) { + return new Token("EOF", null, pos); + } + var match = matchAt(tokenRegex, input, pos); + if (match === null) { + throw new ParseError( + "Unexpected character: '" + input[pos] + "'", + this, pos); + } else if (match[2]) { // matched non-whitespace + return new Token(match[2], null, pos + match[2].length); + } else if (ignoreWhitespace) { + return this._innerLex(pos + match[1].length, true); + } else { // concatenate whitespace to a single space + return new Token(" ", null, pos + match[1].length); + } +}; + +// A regex to match a CSS color (like #ffffff or BlueViolet) +var cssColor = /#[a-z0-9]+|[a-z]+/i; + +/** + * This function lexes a CSS color. + */ +Lexer.prototype._innerLexColor = function(pos) { + var input = this._input; + + // Ignore whitespace + var whitespace = matchAt(whitespaceRegex, input, pos)[0]; + pos += whitespace.length; + + var match; + if ((match = matchAt(cssColor, input, pos))) { + // If we look like a color, return a color + return new Token(match[0], null, pos + match[0].length); + } else { + throw new ParseError("Invalid color", this, pos); + } +}; + +// A regex to match a dimension. Dimensions look like +// "1.2em" or ".4pt" or "1 ex" +var sizeRegex = /(-?)\s*(\d+(?:\.\d*)?|\.\d+)\s*([a-z]{2})/; + +/** + * This function lexes a dimension. + */ +Lexer.prototype._innerLexSize = function(pos) { + var input = this._input; + + // Ignore whitespace + var whitespace = matchAt(whitespaceRegex, input, pos)[0]; + pos += whitespace.length; + + var match; + if ((match = matchAt(sizeRegex, input, pos))) { + var unit = match[3]; + // We only currently handle "em" and "ex" units + if (unit !== "em" && unit !== "ex") { + throw new ParseError("Invalid unit: '" + unit + "'", this, pos); + } + return new Token(match[0], { + number: +(match[1] + match[2]), + unit: unit + }, pos + match[0].length); + } + + throw new ParseError("Invalid size", this, pos); +}; + +/** + * This function lexes a string of whitespace. + */ +Lexer.prototype._innerLexWhitespace = function(pos) { + var input = this._input; + + var whitespace = matchAt(whitespaceRegex, input, pos)[0]; + pos += whitespace.length; + + return new Token(whitespace[0], null, pos); +}; + +/** + * This function lexes a single token starting at `pos` and of the given mode. + * Based on the mode, we defer to one of the `_innerLex` functions. + */ +Lexer.prototype.lex = function(pos, mode) { + if (mode === "math") { + return this._innerLex(pos, true); + } else if (mode === "text") { + return this._innerLex(pos, false); + } else if (mode === "color") { + return this._innerLexColor(pos); + } else if (mode === "size") { + return this._innerLexSize(pos); + } else if (mode === "whitespace") { + return this._innerLexWhitespace(pos); + } +}; + +module.exports = Lexer; diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/Options.js b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/Options.js new file mode 100644 index 0000000..7b2e5c9 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/Options.js @@ -0,0 +1,189 @@ +/** + * This file contains information about the options that the Parser carries + * around with it while parsing. Data is held in an `Options` object, and when + * recursing, a new `Options` object can be created with the `.with*` and + * `.reset` functions. + */ + +/** + * This is the main options class. It contains the style, size, color, and font + * of the current parse level. It also contains the style and size of the parent + * parse level, so size changes can be handled efficiently. + * + * Each of the `.with*` and `.reset` functions passes its current style and size + * as the parentStyle and parentSize of the new options class, so parent + * handling is taken care of automatically. + */ +function Options(data) { + this.style = data.style; + this.color = data.color; + this.size = data.size; + this.phantom = data.phantom; + this.font = data.font; + + if (data.parentStyle === undefined) { + this.parentStyle = data.style; + } else { + this.parentStyle = data.parentStyle; + } + + if (data.parentSize === undefined) { + this.parentSize = data.size; + } else { + this.parentSize = data.parentSize; + } +} + +/** + * Returns a new options object with the same properties as "this". Properties + * from "extension" will be copied to the new options object. + */ +Options.prototype.extend = function(extension) { + var data = { + style: this.style, + size: this.size, + color: this.color, + parentStyle: this.style, + parentSize: this.size, + phantom: this.phantom, + font: this.font + }; + + for (var key in extension) { + if (extension.hasOwnProperty(key)) { + data[key] = extension[key]; + } + } + + return new Options(data); +}; + +/** + * Create a new options object with the given style. + */ +Options.prototype.withStyle = function(style) { + return this.extend({ + style: style + }); +}; + +/** + * Create a new options object with the given size. + */ +Options.prototype.withSize = function(size) { + return this.extend({ + size: size + }); +}; + +/** + * Create a new options object with the given color. + */ +Options.prototype.withColor = function(color) { + return this.extend({ + color: color + }); +}; + +/** + * Create a new options object with "phantom" set to true. + */ +Options.prototype.withPhantom = function() { + return this.extend({ + phantom: true + }); +}; + +/** + * Create a new options objects with the give font. + */ +Options.prototype.withFont = function(font) { + return this.extend({ + font: font + }); +}; + +/** + * Create a new options object with the same style, size, and color. This is + * used so that parent style and size changes are handled correctly. + */ +Options.prototype.reset = function() { + return this.extend({}); +}; + +/** + * A map of color names to CSS colors. + * TODO(emily): Remove this when we have real macros + */ +var colorMap = { + "katex-blue": "#6495ed", + "katex-orange": "#ffa500", + "katex-pink": "#ff00af", + "katex-red": "#df0030", + "katex-green": "#28ae7b", + "katex-gray": "gray", + "katex-purple": "#9d38bd", + "katex-blueA": "#c7e9f1", + "katex-blueB": "#9cdceb", + "katex-blueC": "#58c4dd", + "katex-blueD": "#29abca", + "katex-blueE": "#1c758a", + "katex-tealA": "#acead7", + "katex-tealB": "#76ddc0", + "katex-tealC": "#5cd0b3", + "katex-tealD": "#55c1a7", + "katex-tealE": "#49a88f", + "katex-greenA": "#c9e2ae", + "katex-greenB": "#a6cf8c", + "katex-greenC": "#83c167", + "katex-greenD": "#77b05d", + "katex-greenE": "#699c52", + "katex-goldA": "#f7c797", + "katex-goldB": "#f9b775", + "katex-goldC": "#f0ac5f", + "katex-goldD": "#e1a158", + "katex-goldE": "#c78d46", + "katex-redA": "#f7a1a3", + "katex-redB": "#ff8080", + "katex-redC": "#fc6255", + "katex-redD": "#e65a4c", + "katex-redE": "#cf5044", + "katex-maroonA": "#ecabc1", + "katex-maroonB": "#ec92ab", + "katex-maroonC": "#c55f73", + "katex-maroonD": "#a24d61", + "katex-maroonE": "#94424f", + "katex-purpleA": "#caa3e8", + "katex-purpleB": "#b189c6", + "katex-purpleC": "#9a72ac", + "katex-purpleD": "#715582", + "katex-purpleE": "#644172", + "katex-mintA": "#f5f9e8", + "katex-mintB": "#edf2df", + "katex-mintC": "#e0e5cc", + "katex-grayA": "#fdfdfd", + "katex-grayB": "#f7f7f7", + "katex-grayC": "#eeeeee", + "katex-grayD": "#dddddd", + "katex-grayE": "#cccccc", + "katex-grayF": "#aaaaaa", + "katex-grayG": "#999999", + "katex-grayH": "#555555", + "katex-grayI": "#333333", + "katex-kaBlue": "#314453", + "katex-kaGreen": "#639b24" +}; + +/** + * Gets the CSS color of the current options object, accounting for the + * `colorMap`. + */ +Options.prototype.getColor = function() { + if (this.phantom) { + return "transparent"; + } else { + return colorMap[this.color] || this.color; + } +}; + +module.exports = Options; diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/ParseError.js b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/ParseError.js new file mode 100644 index 0000000..320f0bd --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/ParseError.js @@ -0,0 +1,40 @@ +/** + * This is the ParseError class, which is the main error thrown by KaTeX + * functions when something has gone wrong. This is used to distinguish internal + * errors from errors in the expression that the user provided. + */ +function ParseError(message, lexer, position) { + var error = "KaTeX parse error: " + message; + + if (lexer !== undefined && position !== undefined) { + // If we have the input and a position, make the error a bit fancier + + // Prepend some information + error += " at position " + position + ": "; + + // Get the input + var input = lexer._input; + // Insert a combining underscore at the correct position + input = input.slice(0, position) + "\u0332" + + input.slice(position); + + // Extract some context from the input and add it to the error + var begin = Math.max(0, position - 15); + var end = position + 15; + error += input.slice(begin, end); + } + + // Some hackery to make ParseError a prototype of Error + // See http://stackoverflow.com/a/8460753 + var self = new Error(error); + self.name = "ParseError"; + self.__proto__ = ParseError.prototype; + + self.position = position; + return self; +} + +// More hackery +ParseError.prototype.__proto__ = Error.prototype; + +module.exports = ParseError; diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/Parser.js b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/Parser.js new file mode 100644 index 0000000..bb044d3 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/Parser.js @@ -0,0 +1,749 @@ +var functions = require("./functions"); +var environments = require("./environments"); +var Lexer = require("./Lexer"); +var symbols = require("./symbols"); +var utils = require("./utils"); + +var parseData = require("./parseData"); +var ParseError = require("./ParseError"); + +/** + * This file contains the parser used to parse out a TeX expression from the + * input. Since TeX isn't context-free, standard parsers don't work particularly + * well. + * + * The strategy of this parser is as such: + * + * The main functions (the `.parse...` ones) take a position in the current + * parse string to parse tokens from. The lexer (found in Lexer.js, stored at + * this.lexer) also supports pulling out tokens at arbitrary places. When + * individual tokens are needed at a position, the lexer is called to pull out a + * token, which is then used. + * + * The parser has a property called "mode" indicating the mode that + * the parser is currently in. Currently it has to be one of "math" or + * "text", which denotes whether the current environment is a math-y + * one or a text-y one (e.g. inside \text). Currently, this serves to + * limit the functions which can be used in text mode. + * + * The main functions then return an object which contains the useful data that + * was parsed at its given point, and a new position at the end of the parsed + * data. The main functions can call each other and continue the parsing by + * using the returned position as a new starting point. + * + * There are also extra `.handle...` functions, which pull out some reused + * functionality into self-contained functions. + * + * The earlier functions return `ParseResult`s, which contain a ParseNode and a + * new position. + * + * The later functions (which are called deeper in the parse) sometimes return + * ParseFuncOrArgument, which contain a ParseResult as well as some data about + * whether the parsed object is a function which is missing some arguments, or a + * standalone object which can be used as an argument to another function. + */ + +/** + * Main Parser class + */ +function Parser(input, settings) { + // Make a new lexer + this.lexer = new Lexer(input); + // Store the settings for use in parsing + this.settings = settings; +} + +var ParseNode = parseData.ParseNode; +var ParseResult = parseData.ParseResult; + +/** + * An initial function (without its arguments), or an argument to a function. + * The `result` argument should be a ParseResult. + */ +function ParseFuncOrArgument(result, isFunction) { + this.result = result; + // Is this a function (i.e. is it something defined in functions.js)? + this.isFunction = isFunction; +} + +/** + * Checks a result to make sure it has the right type, and throws an + * appropriate error otherwise. + */ +Parser.prototype.expect = function(result, text) { + if (result.text !== text) { + throw new ParseError( + "Expected '" + text + "', got '" + result.text + "'", + this.lexer, result.position + ); + } +}; + +/** + * Main parsing function, which parses an entire input. + * + * @return {?Array.<ParseNode>} + */ +Parser.prototype.parse = function(input) { + // Try to parse the input + this.mode = "math"; + var parse = this.parseInput(0); + return parse.result; +}; + +/** + * Parses an entire input tree. + */ +Parser.prototype.parseInput = function(pos) { + // Parse an expression + var expression = this.parseExpression(pos, false); + // If we succeeded, make sure there's an EOF at the end + this.expect(expression.peek, "EOF"); + return expression; +}; + +var endOfExpression = ["}", "\\end", "\\right", "&", "\\\\", "\\cr"]; + +/** + * Parses an "expression", which is a list of atoms. + * + * @param {boolean} breakOnInfix Should the parsing stop when we hit infix + * nodes? This happens when functions have higher precendence + * than infix nodes in implicit parses. + * + * @param {?string} breakOnToken The token that the expression should end with, + * or `null` if something else should end the expression. + * + * @return {ParseResult} + */ +Parser.prototype.parseExpression = function(pos, breakOnInfix, breakOnToken) { + var body = []; + var lex = null; + // Keep adding atoms to the body until we can't parse any more atoms (either + // we reached the end, a }, or a \right) + while (true) { + lex = this.lexer.lex(pos, this.mode); + if (endOfExpression.indexOf(lex.text) !== -1) { + break; + } + if (breakOnToken && lex.text === breakOnToken) { + break; + } + var atom = this.parseAtom(pos); + if (!atom) { + if (!this.settings.throwOnError && lex.text[0] === "\\") { + var errorNode = this.handleUnsupportedCmd(lex.text); + body.push(errorNode); + + pos = lex.position; + continue; + } + + break; + } + if (breakOnInfix && atom.result.type === "infix") { + break; + } + body.push(atom.result); + pos = atom.position; + } + var res = new ParseResult(this.handleInfixNodes(body), pos); + res.peek = lex; + return res; +}; + +/** + * Rewrites infix operators such as \over with corresponding commands such + * as \frac. + * + * There can only be one infix operator per group. If there's more than one + * then the expression is ambiguous. This can be resolved by adding {}. + * + * @returns {Array} + */ +Parser.prototype.handleInfixNodes = function (body) { + var overIndex = -1; + var func; + var funcName; + + for (var i = 0; i < body.length; i++) { + var node = body[i]; + if (node.type === "infix") { + if (overIndex !== -1) { + throw new ParseError("only one infix operator per group", + this.lexer, -1); + } + overIndex = i; + funcName = node.value.replaceWith; + func = functions[funcName]; + } + } + + if (overIndex !== -1) { + var numerNode, denomNode; + + var numerBody = body.slice(0, overIndex); + var denomBody = body.slice(overIndex + 1); + + if (numerBody.length === 1 && numerBody[0].type === "ordgroup") { + numerNode = numerBody[0]; + } else { + numerNode = new ParseNode("ordgroup", numerBody, this.mode); + } + + if (denomBody.length === 1 && denomBody[0].type === "ordgroup") { + denomNode = denomBody[0]; + } else { + denomNode = new ParseNode("ordgroup", denomBody, this.mode); + } + + var value = this.callFunction( + funcName, [numerNode, denomNode], null); + return [new ParseNode(value.type, value, this.mode)]; + } else { + return body; + } +}; + +// The greediness of a superscript or subscript +var SUPSUB_GREEDINESS = 1; + +/** + * Handle a subscript or superscript with nice errors. + */ +Parser.prototype.handleSupSubscript = function(pos, symbol, name) { + var group = this.parseGroup(pos); + + if (!group) { + var lex = this.lexer.lex(pos, this.mode); + + if (!this.settings.throwOnError && lex.text[0] === "\\") { + return new ParseResult( + this.handleUnsupportedCmd(lex.text), + lex.position); + } else { + throw new ParseError( + "Expected group after '" + symbol + "'", this.lexer, pos); + } + } else if (group.isFunction) { + // ^ and _ have a greediness, so handle interactions with functions' + // greediness + var funcGreediness = functions[group.result.result].greediness; + if (funcGreediness > SUPSUB_GREEDINESS) { + return this.parseFunction(pos); + } else { + throw new ParseError( + "Got function '" + group.result.result + "' with no arguments " + + "as " + name, + this.lexer, pos); + } + } else { + return group.result; + } +}; + +/** + * Converts the textual input of an unsupported command into a text node + * contained within a color node whose color is determined by errorColor + */ + Parser.prototype.handleUnsupportedCmd = function(text) { + var textordArray = []; + + for (var i = 0; i < text.length; i++) { + textordArray.push(new ParseNode("textord", text[i], "text")); + } + + var textNode = new ParseNode( + "text", + { + body: textordArray, + type: "text" + }, + this.mode); + + var colorNode = new ParseNode( + "color", + { + color: this.settings.errorColor, + value: [textNode], + type: "color" + }, + this.mode); + + return colorNode; + }; + +/** + * Parses a group with optional super/subscripts. + * + * @return {?ParseResult} + */ +Parser.prototype.parseAtom = function(pos) { + // The body of an atom is an implicit group, so that things like + // \left(x\right)^2 work correctly. + var base = this.parseImplicitGroup(pos); + + // In text mode, we don't have superscripts or subscripts + if (this.mode === "text") { + return base; + } + + // Handle an empty base + var currPos; + if (!base) { + currPos = pos; + base = undefined; + } else { + currPos = base.position; + } + + var superscript; + var subscript; + var result; + while (true) { + // Lex the first token + var lex = this.lexer.lex(currPos, this.mode); + + if (lex.text === "\\limits" || lex.text === "\\nolimits") { + // We got a limit control + if (!base || base.result.type !== "op") { + throw new ParseError("Limit controls must follow a math operator", + this.lexer, currPos); + } + else { + var limits = lex.text === "\\limits"; + base.result.value.limits = limits; + base.result.value.alwaysHandleSupSub = true; + currPos = lex.position; + } + } else if (lex.text === "^") { + // We got a superscript start + if (superscript) { + throw new ParseError( + "Double superscript", this.lexer, currPos); + } + result = this.handleSupSubscript( + lex.position, lex.text, "superscript"); + currPos = result.position; + superscript = result.result; + } else if (lex.text === "_") { + // We got a subscript start + if (subscript) { + throw new ParseError( + "Double subscript", this.lexer, currPos); + } + result = this.handleSupSubscript( + lex.position, lex.text, "subscript"); + currPos = result.position; + subscript = result.result; + } else if (lex.text === "'") { + // We got a prime + var prime = new ParseNode("textord", "\\prime", this.mode); + + // Many primes can be grouped together, so we handle this here + var primes = [prime]; + currPos = lex.position; + // Keep lexing tokens until we get something that's not a prime + while ((lex = this.lexer.lex(currPos, this.mode)).text === "'") { + // For each one, add another prime to the list + primes.push(prime); + currPos = lex.position; + } + // Put them into an ordgroup as the superscript + superscript = new ParseNode("ordgroup", primes, this.mode); + } else { + // If it wasn't ^, _, or ', stop parsing super/subscripts + break; + } + } + + if (superscript || subscript) { + // If we got either a superscript or subscript, create a supsub + return new ParseResult( + new ParseNode("supsub", { + base: base && base.result, + sup: superscript, + sub: subscript + }, this.mode), + currPos); + } else { + // Otherwise return the original body + return base; + } +}; + +// A list of the size-changing functions, for use in parseImplicitGroup +var sizeFuncs = [ + "\\tiny", "\\scriptsize", "\\footnotesize", "\\small", "\\normalsize", + "\\large", "\\Large", "\\LARGE", "\\huge", "\\Huge" +]; + +// A list of the style-changing functions, for use in parseImplicitGroup +var styleFuncs = [ + "\\displaystyle", "\\textstyle", "\\scriptstyle", "\\scriptscriptstyle" +]; + +/** + * Parses an implicit group, which is a group that starts at the end of a + * specified, and ends right before a higher explicit group ends, or at EOL. It + * is used for functions that appear to affect the current style, like \Large or + * \textrm, where instead of keeping a style we just pretend that there is an + * implicit grouping after it until the end of the group. E.g. + * small text {\Large large text} small text again + * It is also used for \left and \right to get the correct grouping. + * + * @return {?ParseResult} + */ +Parser.prototype.parseImplicitGroup = function(pos) { + var start = this.parseSymbol(pos); + + if (!start || !start.result) { + // If we didn't get anything we handle, fall back to parseFunction + return this.parseFunction(pos); + } + + var func = start.result.result; + var body; + + if (func === "\\left") { + // If we see a left: + // Parse the entire left function (including the delimiter) + var left = this.parseFunction(pos); + // Parse out the implicit body + body = this.parseExpression(left.position, false); + // Check the next token + this.expect(body.peek, "\\right"); + var right = this.parseFunction(body.position); + return new ParseResult( + new ParseNode("leftright", { + body: body.result, + left: left.result.value.value, + right: right.result.value.value + }, this.mode), + right.position); + } else if (func === "\\begin") { + // begin...end is similar to left...right + var begin = this.parseFunction(pos); + var envName = begin.result.value.name; + if (!environments.hasOwnProperty(envName)) { + throw new ParseError( + "No such environment: " + envName, + this.lexer, begin.result.value.namepos); + } + // Build the environment object. Arguments and other information will + // be made available to the begin and end methods using properties. + var env = environments[envName]; + var args = []; + var newPos = this.parseArguments( + begin.position, "\\begin{" + envName + "}", env, args); + var context = { + pos: newPos, + mode: this.mode, + envName: envName, + parser: this, + lexer: this.lexer, + positions: args.pop() + }; + var result = env.handler(context, args); + var endLex = this.lexer.lex(result.position, this.mode); + this.expect(endLex, "\\end"); + var end = this.parseFunction(result.position); + if (end.result.value.name !== envName) { + throw new ParseError( + "Mismatch: \\begin{" + envName + "} matched " + + "by \\end{" + end.result.value.name + "}", + this.lexer, end.namepos); + } + result.position = end.position; + return result; + } else if (utils.contains(sizeFuncs, func)) { + // If we see a sizing function, parse out the implict body + body = this.parseExpression(start.result.position, false); + return new ParseResult( + new ParseNode("sizing", { + // Figure out what size to use based on the list of functions above + size: "size" + (utils.indexOf(sizeFuncs, func) + 1), + value: body.result + }, this.mode), + body.position); + } else if (utils.contains(styleFuncs, func)) { + // If we see a styling function, parse out the implict body + body = this.parseExpression(start.result.position, true); + return new ParseResult( + new ParseNode("styling", { + // Figure out what style to use by pulling out the style from + // the function name + style: func.slice(1, func.length - 5), + value: body.result + }, this.mode), + body.position); + } else { + // Defer to parseFunction if it's not a function we handle + return this.parseFunction(pos); + } +}; + +/** + * Parses an entire function, including its base and all of its arguments + * + * @return {?ParseResult} + */ +Parser.prototype.parseFunction = function(pos) { + var baseGroup = this.parseGroup(pos); + + if (baseGroup) { + if (baseGroup.isFunction) { + var func = baseGroup.result.result; + var funcData = functions[func]; + if (this.mode === "text" && !funcData.allowedInText) { + throw new ParseError( + "Can't use function '" + func + "' in text mode", + this.lexer, baseGroup.position); + } + + var args = []; + var newPos = this.parseArguments( + baseGroup.result.position, func, funcData, args); + var result = this.callFunction(func, args, args.pop()); + return new ParseResult( + new ParseNode(result.type, result, this.mode), + newPos); + } else { + return baseGroup.result; + } + } else { + return null; + } +}; + +/** + * Call a function handler with a suitable context and arguments. + */ +Parser.prototype.callFunction = function(name, args, positions) { + var context = { + funcName: name, + parser: this, + lexer: this.lexer, + positions: positions + }; + return functions[name].handler(context, args); +}; + +/** + * Parses the arguments of a function or environment + * + * @param {string} func "\name" or "\begin{name}" + * @param {{numArgs:number,numOptionalArgs:number|undefined}} funcData + * @param {Array} args list of arguments to which new ones will be pushed + * @return the position after all arguments have been parsed + */ +Parser.prototype.parseArguments = function(pos, func, funcData, args) { + var totalArgs = funcData.numArgs + funcData.numOptionalArgs; + if (totalArgs === 0) { + return pos; + } + + var newPos = pos; + var baseGreediness = funcData.greediness; + var positions = [newPos]; + + for (var i = 0; i < totalArgs; i++) { + var argType = funcData.argTypes && funcData.argTypes[i]; + var arg; + if (i < funcData.numOptionalArgs) { + if (argType) { + arg = this.parseSpecialGroup(newPos, argType, true); + } else { + arg = this.parseOptionalGroup(newPos); + } + if (!arg) { + args.push(null); + positions.push(newPos); + continue; + } + } else { + if (argType) { + arg = this.parseSpecialGroup(newPos, argType); + } else { + arg = this.parseGroup(newPos); + } + if (!arg) { + var lex = this.lexer.lex(newPos, this.mode); + + if (!this.settings.throwOnError && lex.text[0] === "\\") { + arg = new ParseFuncOrArgument( + new ParseResult( + this.handleUnsupportedCmd(lex.text), + lex.position), + false); + } else { + throw new ParseError( + "Expected group after '" + func + "'", this.lexer, pos); + } + } + } + var argNode; + if (arg.isFunction) { + var argGreediness = + functions[arg.result.result].greediness; + if (argGreediness > baseGreediness) { + argNode = this.parseFunction(newPos); + } else { + throw new ParseError( + "Got function '" + arg.result.result + "' as " + + "argument to '" + func + "'", + this.lexer, arg.result.position - 1); + } + } else { + argNode = arg.result; + } + args.push(argNode.result); + positions.push(argNode.position); + newPos = argNode.position; + } + + args.push(positions); + + return newPos; +}; + + +/** + * Parses a group when the mode is changing. Takes a position, a new mode, and + * an outer mode that is used to parse the outside. + * + * @return {?ParseFuncOrArgument} + */ +Parser.prototype.parseSpecialGroup = function(pos, innerMode, optional) { + var outerMode = this.mode; + // Handle `original` argTypes + if (innerMode === "original") { + innerMode = outerMode; + } + + if (innerMode === "color" || innerMode === "size") { + // color and size modes are special because they should have braces and + // should only lex a single symbol inside + var openBrace = this.lexer.lex(pos, outerMode); + if (optional && openBrace.text !== "[") { + // optional arguments should return null if they don't exist + return null; + } + this.expect(openBrace, optional ? "[" : "{"); + var inner = this.lexer.lex(openBrace.position, innerMode); + var data; + if (innerMode === "color") { + data = inner.text; + } else { + data = inner.data; + } + var closeBrace = this.lexer.lex(inner.position, outerMode); + this.expect(closeBrace, optional ? "]" : "}"); + return new ParseFuncOrArgument( + new ParseResult( + new ParseNode(innerMode, data, outerMode), + closeBrace.position), + false); + } else if (innerMode === "text") { + // text mode is special because it should ignore the whitespace before + // it + var whitespace = this.lexer.lex(pos, "whitespace"); + pos = whitespace.position; + } + + // By the time we get here, innerMode is one of "text" or "math". + // We switch the mode of the parser, recurse, then restore the old mode. + this.mode = innerMode; + var res; + if (optional) { + res = this.parseOptionalGroup(pos); + } else { + res = this.parseGroup(pos); + } + this.mode = outerMode; + return res; +}; + +/** + * Parses a group, which is either a single nucleus (like "x") or an expression + * in braces (like "{x+y}") + * + * @return {?ParseFuncOrArgument} + */ +Parser.prototype.parseGroup = function(pos) { + var start = this.lexer.lex(pos, this.mode); + // Try to parse an open brace + if (start.text === "{") { + // If we get a brace, parse an expression + var expression = this.parseExpression(start.position, false); + // Make sure we get a close brace + var closeBrace = this.lexer.lex(expression.position, this.mode); + this.expect(closeBrace, "}"); + return new ParseFuncOrArgument( + new ParseResult( + new ParseNode("ordgroup", expression.result, this.mode), + closeBrace.position), + false); + } else { + // Otherwise, just return a nucleus + return this.parseSymbol(pos); + } +}; + +/** + * Parses a group, which is an expression in brackets (like "[x+y]") + * + * @return {?ParseFuncOrArgument} + */ +Parser.prototype.parseOptionalGroup = function(pos) { + var start = this.lexer.lex(pos, this.mode); + // Try to parse an open bracket + if (start.text === "[") { + // If we get a brace, parse an expression + var expression = this.parseExpression(start.position, false, "]"); + // Make sure we get a close bracket + var closeBracket = this.lexer.lex(expression.position, this.mode); + this.expect(closeBracket, "]"); + return new ParseFuncOrArgument( + new ParseResult( + new ParseNode("ordgroup", expression.result, this.mode), + closeBracket.position), + false); + } else { + // Otherwise, return null, + return null; + } +}; + +/** + * Parse a single symbol out of the string. Here, we handle both the functions + * we have defined, as well as the single character symbols + * + * @return {?ParseFuncOrArgument} + */ +Parser.prototype.parseSymbol = function(pos) { + var nucleus = this.lexer.lex(pos, this.mode); + + if (functions[nucleus.text]) { + // If there exists a function with this name, we return the function and + // say that it is a function. + return new ParseFuncOrArgument( + new ParseResult(nucleus.text, nucleus.position), + true); + } else if (symbols[this.mode][nucleus.text]) { + // Otherwise if this is a no-argument function, find the type it + // corresponds to in the symbols map + return new ParseFuncOrArgument( + new ParseResult( + new ParseNode(symbols[this.mode][nucleus.text].group, + nucleus.text, this.mode), + nucleus.position), + false); + } else { + return null; + } +}; + +Parser.prototype.ParseNode = ParseNode; + +module.exports = Parser; diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/Settings.js b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/Settings.js new file mode 100644 index 0000000..6440145 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/Settings.js @@ -0,0 +1,28 @@ +/** + * This is a module for storing settings passed into KaTeX. It correctly handles + * default settings. + */ + +/** + * Helper function for getting a default value if the value is undefined + */ +function get(option, defaultValue) { + return option === undefined ? defaultValue : option; +} + +/** + * The main Settings object + * + * The current options stored are: + * - displayMode: Whether the expression should be typeset by default in + * textstyle or displaystyle (default false) + */ +function Settings(options) { + // allow null options + options = options || {}; + this.displayMode = get(options.displayMode, false); + this.throwOnError = get(options.throwOnError, true); + this.errorColor = get(options.errorColor, "#cc0000"); +} + +module.exports = Settings; diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/Style.js b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/Style.js new file mode 100644 index 0000000..43d5e26 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/Style.js @@ -0,0 +1,126 @@ +/** + * This file contains information and classes for the various kinds of styles + * used in TeX. It provides a generic `Style` class, which holds information + * about a specific style. It then provides instances of all the different kinds + * of styles possible, and provides functions to move between them and get + * information about them. + */ + +/** + * The main style class. Contains a unique id for the style, a size (which is + * the same for cramped and uncramped version of a style), a cramped flag, and a + * size multiplier, which gives the size difference between a style and + * textstyle. + */ +function Style(id, size, multiplier, cramped) { + this.id = id; + this.size = size; + this.cramped = cramped; + this.sizeMultiplier = multiplier; +} + +/** + * Get the style of a superscript given a base in the current style. + */ +Style.prototype.sup = function() { + return styles[sup[this.id]]; +}; + +/** + * Get the style of a subscript given a base in the current style. + */ +Style.prototype.sub = function() { + return styles[sub[this.id]]; +}; + +/** + * Get the style of a fraction numerator given the fraction in the current + * style. + */ +Style.prototype.fracNum = function() { + return styles[fracNum[this.id]]; +}; + +/** + * Get the style of a fraction denominator given the fraction in the current + * style. + */ +Style.prototype.fracDen = function() { + return styles[fracDen[this.id]]; +}; + +/** + * Get the cramped version of a style (in particular, cramping a cramped style + * doesn't change the style). + */ +Style.prototype.cramp = function() { + return styles[cramp[this.id]]; +}; + +/** + * HTML class name, like "displaystyle cramped" + */ +Style.prototype.cls = function() { + return sizeNames[this.size] + (this.cramped ? " cramped" : " uncramped"); +}; + +/** + * HTML Reset class name, like "reset-textstyle" + */ +Style.prototype.reset = function() { + return resetNames[this.size]; +}; + +// IDs of the different styles +var D = 0; +var Dc = 1; +var T = 2; +var Tc = 3; +var S = 4; +var Sc = 5; +var SS = 6; +var SSc = 7; + +// String names for the different sizes +var sizeNames = [ + "displaystyle textstyle", + "textstyle", + "scriptstyle", + "scriptscriptstyle" +]; + +// Reset names for the different sizes +var resetNames = [ + "reset-textstyle", + "reset-textstyle", + "reset-scriptstyle", + "reset-scriptscriptstyle" +]; + +// Instances of the different styles +var styles = [ + new Style(D, 0, 1.0, false), + new Style(Dc, 0, 1.0, true), + new Style(T, 1, 1.0, false), + new Style(Tc, 1, 1.0, true), + new Style(S, 2, 0.7, false), + new Style(Sc, 2, 0.7, true), + new Style(SS, 3, 0.5, false), + new Style(SSc, 3, 0.5, true) +]; + +// Lookup tables for switching from one style to another +var sup = [S, Sc, S, Sc, SS, SSc, SS, SSc]; +var sub = [Sc, Sc, Sc, Sc, SSc, SSc, SSc, SSc]; +var fracNum = [T, Tc, S, Sc, SS, SSc, SS, SSc]; +var fracDen = [Tc, Tc, Sc, Sc, SSc, SSc, SSc, SSc]; +var cramp = [Dc, Dc, Tc, Tc, Sc, Sc, SSc, SSc]; + +// We only export some of the styles. Also, we don't export the `Style` class so +// no more styles can be generated. +module.exports = { + DISPLAY: styles[D], + TEXT: styles[T], + SCRIPT: styles[S], + SCRIPTSCRIPT: styles[SS] +}; diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/buildCommon.js b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/buildCommon.js new file mode 100644 index 0000000..ee23186 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/buildCommon.js @@ -0,0 +1,447 @@ +/** + * This module contains general functions that can be used for building + * different kinds of domTree nodes in a consistent manner. + */ + +var domTree = require("./domTree"); +var fontMetrics = require("./fontMetrics"); +var symbols = require("./symbols"); +var utils = require("./utils"); + +var greekCapitals = [ + "\\Gamma", + "\\Delta", + "\\Theta", + "\\Lambda", + "\\Xi", + "\\Pi", + "\\Sigma", + "\\Upsilon", + "\\Phi", + "\\Psi", + "\\Omega" +]; + +var dotlessLetters = [ + "\u0131", // dotless i, \imath + "\u0237" // dotless j, \jmath +]; + +/** + * Makes a symbolNode after translation via the list of symbols in symbols.js. + * Correctly pulls out metrics for the character, and optionally takes a list of + * classes to be attached to the node. + */ +var makeSymbol = function(value, style, mode, color, classes) { + // Replace the value with its replaced value from symbol.js + if (symbols[mode][value] && symbols[mode][value].replace) { + value = symbols[mode][value].replace; + } + + var metrics = fontMetrics.getCharacterMetrics(value, style); + + var symbolNode; + if (metrics) { + symbolNode = new domTree.symbolNode( + value, metrics.height, metrics.depth, metrics.italic, metrics.skew, + classes); + } else { + // TODO(emily): Figure out a good way to only print this in development + typeof console !== "undefined" && console.warn( + "No character metrics for '" + value + "' in style '" + + style + "'"); + symbolNode = new domTree.symbolNode(value, 0, 0, 0, 0, classes); + } + + if (color) { + symbolNode.style.color = color; + } + + return symbolNode; +}; + +/** + * Makes a symbol in Main-Regular or AMS-Regular. + * Used for rel, bin, open, close, inner, and punct. + */ +var mathsym = function(value, mode, color, classes) { + // Decide what font to render the symbol in by its entry in the symbols + // table. + // Have a special case for when the value = \ because the \ is used as a + // textord in unsupported command errors but cannot be parsed as a regular + // text ordinal and is therefore not present as a symbol in the symbols + // table for text + if (value === "\\" || symbols[mode][value].font === "main") { + return makeSymbol(value, "Main-Regular", mode, color, classes); + } else { + return makeSymbol( + value, "AMS-Regular", mode, color, classes.concat(["amsrm"])); + } +}; + +/** + * Makes a symbol in the default font for mathords and textords. + */ +var mathDefault = function(value, mode, color, classes, type) { + if (type === "mathord") { + return mathit(value, mode, color, classes); + } else if (type === "textord") { + return makeSymbol( + value, "Main-Regular", mode, color, classes.concat(["mathrm"])); + } else { + throw new Error("unexpected type: " + type + " in mathDefault"); + } +}; + +/** + * Makes a symbol in the italic math font. + */ +var mathit = function(value, mode, color, classes) { + if (/[0-9]/.test(value.charAt(0)) || + // glyphs for \imath and \jmath do not exist in Math-Italic so we + // need to use Main-Italic instead + utils.contains(dotlessLetters, value) || + utils.contains(greekCapitals, value)) { + return makeSymbol( + value, "Main-Italic", mode, color, classes.concat(["mainit"])); + } else { + return makeSymbol( + value, "Math-Italic", mode, color, classes.concat(["mathit"])); + } +}; + +/** + * Makes either a mathord or textord in the correct font and color. + */ +var makeOrd = function(group, options, type) { + var mode = group.mode; + var value = group.value; + if (symbols[mode][value] && symbols[mode][value].replace) { + value = symbols[mode][value].replace; + } + + var classes = ["mord"]; + var color = options.getColor(); + + var font = options.font; + if (font) { + if (font === "mathit" || utils.contains(dotlessLetters, value)) { + return mathit(value, mode, color, classes); + } else { + var fontName = fontMap[font].fontName; + if (fontMetrics.getCharacterMetrics(value, fontName)) { + return makeSymbol(value, fontName, mode, color, classes.concat([font])); + } else { + return mathDefault(value, mode, color, classes, type); + } + } + } else { + return mathDefault(value, mode, color, classes, type); + } +}; + +/** + * Calculate the height, depth, and maxFontSize of an element based on its + * children. + */ +var sizeElementFromChildren = function(elem) { + var height = 0; + var depth = 0; + var maxFontSize = 0; + + if (elem.children) { + for (var i = 0; i < elem.children.length; i++) { + if (elem.children[i].height > height) { + height = elem.children[i].height; + } + if (elem.children[i].depth > depth) { + depth = elem.children[i].depth; + } + if (elem.children[i].maxFontSize > maxFontSize) { + maxFontSize = elem.children[i].maxFontSize; + } + } + } + + elem.height = height; + elem.depth = depth; + elem.maxFontSize = maxFontSize; +}; + +/** + * Makes a span with the given list of classes, list of children, and color. + */ +var makeSpan = function(classes, children, color) { + var span = new domTree.span(classes, children); + + sizeElementFromChildren(span); + + if (color) { + span.style.color = color; + } + + return span; +}; + +/** + * Makes a document fragment with the given list of children. + */ +var makeFragment = function(children) { + var fragment = new domTree.documentFragment(children); + + sizeElementFromChildren(fragment); + + return fragment; +}; + +/** + * Makes an element placed in each of the vlist elements to ensure that each + * element has the same max font size. To do this, we create a zero-width space + * with the correct font size. + */ +var makeFontSizer = function(options, fontSize) { + var fontSizeInner = makeSpan([], [new domTree.symbolNode("\u200b")]); + fontSizeInner.style.fontSize = (fontSize / options.style.sizeMultiplier) + "em"; + + var fontSizer = makeSpan( + ["fontsize-ensurer", "reset-" + options.size, "size5"], + [fontSizeInner]); + + return fontSizer; +}; + +/** + * Makes a vertical list by stacking elements and kerns on top of each other. + * Allows for many different ways of specifying the positioning method. + * + * Arguments: + * - children: A list of child or kern nodes to be stacked on top of each other + * (i.e. the first element will be at the bottom, and the last at + * the top). Element nodes are specified as + * {type: "elem", elem: node} + * while kern nodes are specified as + * {type: "kern", size: size} + * - positionType: The method by which the vlist should be positioned. Valid + * values are: + * - "individualShift": The children list only contains elem + * nodes, and each node contains an extra + * "shift" value of how much it should be + * shifted (note that shifting is always + * moving downwards). positionData is + * ignored. + * - "top": The positionData specifies the topmost point of + * the vlist (note this is expected to be a height, + * so positive values move up) + * - "bottom": The positionData specifies the bottommost point + * of the vlist (note this is expected to be a + * depth, so positive values move down + * - "shift": The vlist will be positioned such that its + * baseline is positionData away from the baseline + * of the first child. Positive values move + * downwards. + * - "firstBaseline": The vlist will be positioned such that + * its baseline is aligned with the + * baseline of the first child. + * positionData is ignored. (this is + * equivalent to "shift" with + * positionData=0) + * - positionData: Data used in different ways depending on positionType + * - options: An Options object + * + */ +var makeVList = function(children, positionType, positionData, options) { + var depth; + var currPos; + var i; + if (positionType === "individualShift") { + var oldChildren = children; + children = [oldChildren[0]]; + + // Add in kerns to the list of children to get each element to be + // shifted to the correct specified shift + depth = -oldChildren[0].shift - oldChildren[0].elem.depth; + currPos = depth; + for (i = 1; i < oldChildren.length; i++) { + var diff = -oldChildren[i].shift - currPos - + oldChildren[i].elem.depth; + var size = diff - + (oldChildren[i - 1].elem.height + + oldChildren[i - 1].elem.depth); + + currPos = currPos + diff; + + children.push({type: "kern", size: size}); + children.push(oldChildren[i]); + } + } else if (positionType === "top") { + // We always start at the bottom, so calculate the bottom by adding up + // all the sizes + var bottom = positionData; + for (i = 0; i < children.length; i++) { + if (children[i].type === "kern") { + bottom -= children[i].size; + } else { + bottom -= children[i].elem.height + children[i].elem.depth; + } + } + depth = bottom; + } else if (positionType === "bottom") { + depth = -positionData; + } else if (positionType === "shift") { + depth = -children[0].elem.depth - positionData; + } else if (positionType === "firstBaseline") { + depth = -children[0].elem.depth; + } else { + depth = 0; + } + + // Make the fontSizer + var maxFontSize = 0; + for (i = 0; i < children.length; i++) { + if (children[i].type === "elem") { + maxFontSize = Math.max(maxFontSize, children[i].elem.maxFontSize); + } + } + var fontSizer = makeFontSizer(options, maxFontSize); + + // Create a new list of actual children at the correct offsets + var realChildren = []; + currPos = depth; + for (i = 0; i < children.length; i++) { + if (children[i].type === "kern") { + currPos += children[i].size; + } else { + var child = children[i].elem; + + var shift = -child.depth - currPos; + currPos += child.height + child.depth; + + var childWrap = makeSpan([], [fontSizer, child]); + childWrap.height -= shift; + childWrap.depth += shift; + childWrap.style.top = shift + "em"; + + realChildren.push(childWrap); + } + } + + // Add in an element at the end with no offset to fix the calculation of + // baselines in some browsers (namely IE, sometimes safari) + var baselineFix = makeSpan( + ["baseline-fix"], [fontSizer, new domTree.symbolNode("\u200b")]); + realChildren.push(baselineFix); + + var vlist = makeSpan(["vlist"], realChildren); + // Fix the final height and depth, in case there were kerns at the ends + // since the makeSpan calculation won't take that in to account. + vlist.height = Math.max(currPos, vlist.height); + vlist.depth = Math.max(-depth, vlist.depth); + return vlist; +}; + +// A table of size -> font size for the different sizing functions +var sizingMultiplier = { + size1: 0.5, + size2: 0.7, + size3: 0.8, + size4: 0.9, + size5: 1.0, + size6: 1.2, + size7: 1.44, + size8: 1.73, + size9: 2.07, + size10: 2.49 +}; + +// A map of spacing functions to their attributes, like size and corresponding +// CSS class +var spacingFunctions = { + "\\qquad": { + size: "2em", + className: "qquad" + }, + "\\quad": { + size: "1em", + className: "quad" + }, + "\\enspace": { + size: "0.5em", + className: "enspace" + }, + "\\;": { + size: "0.277778em", + className: "thickspace" + }, + "\\:": { + size: "0.22222em", + className: "mediumspace" + }, + "\\,": { + size: "0.16667em", + className: "thinspace" + }, + "\\!": { + size: "-0.16667em", + className: "negativethinspace" + } +}; + +/** + * Maps TeX font commands to objects containing: + * - variant: string used for "mathvariant" attribute in buildMathML.js + * - fontName: the "style" parameter to fontMetrics.getCharacterMetrics + */ +// A map between tex font commands an MathML mathvariant attribute values +var fontMap = { + // styles + "mathbf": { + variant: "bold", + fontName: "Main-Bold" + }, + "mathrm": { + variant: "normal", + fontName: "Main-Regular" + }, + + // "mathit" is missing because it requires the use of two fonts: Main-Italic + // and Math-Italic. This is handled by a special case in makeOrd which ends + // up calling mathit. + + // families + "mathbb": { + variant: "double-struck", + fontName: "AMS-Regular" + }, + "mathcal": { + variant: "script", + fontName: "Caligraphic-Regular" + }, + "mathfrak": { + variant: "fraktur", + fontName: "Fraktur-Regular" + }, + "mathscr": { + variant: "script", + fontName: "Script-Regular" + }, + "mathsf": { + variant: "sans-serif", + fontName: "SansSerif-Regular" + }, + "mathtt": { + variant: "monospace", + fontName: "Typewriter-Regular" + } +}; + +module.exports = { + fontMap: fontMap, + makeSymbol: makeSymbol, + mathsym: mathsym, + makeSpan: makeSpan, + makeFragment: makeFragment, + makeVList: makeVList, + makeOrd: makeOrd, + sizingMultiplier: sizingMultiplier, + spacingFunctions: spacingFunctions +}; diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/buildHTML.js b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/buildHTML.js new file mode 100644 index 0000000..5bc3cf2 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/buildHTML.js @@ -0,0 +1,1362 @@ +/** + * This file does the main work of building a domTree structure from a parse + * tree. The entry point is the `buildHTML` function, which takes a parse tree. + * Then, the buildExpression, buildGroup, and various groupTypes functions are + * called, to produce a final HTML tree. + */ + +var ParseError = require("./ParseError"); +var Style = require("./Style"); + +var buildCommon = require("./buildCommon"); +var delimiter = require("./delimiter"); +var domTree = require("./domTree"); +var fontMetrics = require("./fontMetrics"); +var utils = require("./utils"); + +var makeSpan = buildCommon.makeSpan; + +/** + * Take a list of nodes, build them in order, and return a list of the built + * nodes. This function handles the `prev` node correctly, and passes the + * previous element from the list as the prev of the next element. + */ +var buildExpression = function(expression, options, prev) { + var groups = []; + for (var i = 0; i < expression.length; i++) { + var group = expression[i]; + groups.push(buildGroup(group, options, prev)); + prev = group; + } + return groups; +}; + +// List of types used by getTypeOfGroup, +// see https://github.com/Khan/KaTeX/wiki/Examining-TeX#group-types +var groupToType = { + mathord: "mord", + textord: "mord", + bin: "mbin", + rel: "mrel", + text: "mord", + open: "mopen", + close: "mclose", + inner: "minner", + genfrac: "mord", + array: "mord", + spacing: "mord", + punct: "mpunct", + ordgroup: "mord", + op: "mop", + katex: "mord", + overline: "mord", + rule: "mord", + leftright: "minner", + sqrt: "mord", + accent: "mord" +}; + +/** + * Gets the final math type of an expression, given its group type. This type is + * used to determine spacing between elements, and affects bin elements by + * causing them to change depending on what types are around them. This type + * must be attached to the outermost node of an element as a CSS class so that + * spacing with its surrounding elements works correctly. + * + * Some elements can be mapped one-to-one from group type to math type, and + * those are listed in the `groupToType` table. + * + * Others (usually elements that wrap around other elements) often have + * recursive definitions, and thus call `getTypeOfGroup` on their inner + * elements. + */ +var getTypeOfGroup = function(group) { + if (group == null) { + // Like when typesetting $^3$ + return groupToType.mathord; + } else if (group.type === "supsub") { + return getTypeOfGroup(group.value.base); + } else if (group.type === "llap" || group.type === "rlap") { + return getTypeOfGroup(group.value); + } else if (group.type === "color") { + return getTypeOfGroup(group.value.value); + } else if (group.type === "sizing") { + return getTypeOfGroup(group.value.value); + } else if (group.type === "styling") { + return getTypeOfGroup(group.value.value); + } else if (group.type === "delimsizing") { + return groupToType[group.value.delimType]; + } else { + return groupToType[group.type]; + } +}; + +/** + * Sometimes, groups perform special rules when they have superscripts or + * subscripts attached to them. This function lets the `supsub` group know that + * its inner element should handle the superscripts and subscripts instead of + * handling them itself. + */ +var shouldHandleSupSub = function(group, options) { + if (!group) { + return false; + } else if (group.type === "op") { + // Operators handle supsubs differently when they have limits + // (e.g. `\displaystyle\sum_2^3`) + return group.value.limits && + (options.style.size === Style.DISPLAY.size || group.value.alwaysHandleSupSub); + } else if (group.type === "accent") { + return isCharacterBox(group.value.base); + } else { + return null; + } +}; + +/** + * Sometimes we want to pull out the innermost element of a group. In most + * cases, this will just be the group itself, but when ordgroups and colors have + * a single element, we want to pull that out. + */ +var getBaseElem = function(group) { + if (!group) { + return false; + } else if (group.type === "ordgroup") { + if (group.value.length === 1) { + return getBaseElem(group.value[0]); + } else { + return group; + } + } else if (group.type === "color") { + if (group.value.value.length === 1) { + return getBaseElem(group.value.value[0]); + } else { + return group; + } + } else { + return group; + } +}; + +/** + * TeXbook algorithms often reference "character boxes", which are simply groups + * with a single character in them. To decide if something is a character box, + * we find its innermost group, and see if it is a single character. + */ +var isCharacterBox = function(group) { + var baseElem = getBaseElem(group); + + // These are all they types of groups which hold single characters + return baseElem.type === "mathord" || + baseElem.type === "textord" || + baseElem.type === "bin" || + baseElem.type === "rel" || + baseElem.type === "inner" || + baseElem.type === "open" || + baseElem.type === "close" || + baseElem.type === "punct"; +}; + +var makeNullDelimiter = function(options) { + return makeSpan([ + "sizing", "reset-" + options.size, "size5", + options.style.reset(), Style.TEXT.cls(), + "nulldelimiter" + ]); +}; + +/** + * This is a map of group types to the function used to handle that type. + * Simpler types come at the beginning, while complicated types come afterwards. + */ +var groupTypes = {}; + +groupTypes.mathord = function(group, options, prev) { + return buildCommon.makeOrd(group, options, "mathord"); +}; + +groupTypes.textord = function(group, options, prev) { + return buildCommon.makeOrd(group, options, "textord"); +}; + +groupTypes.bin = function(group, options, prev) { + var className = "mbin"; + // Pull out the most recent element. Do some special handling to find + // things at the end of a \color group. Note that we don't use the same + // logic for ordgroups (which count as ords). + var prevAtom = prev; + while (prevAtom && prevAtom.type === "color") { + var atoms = prevAtom.value.value; + prevAtom = atoms[atoms.length - 1]; + } + // See TeXbook pg. 442-446, Rules 5 and 6, and the text before Rule 19. + // Here, we determine whether the bin should turn into an ord. We + // currently only apply Rule 5. + if (!prev || utils.contains(["mbin", "mopen", "mrel", "mop", "mpunct"], + getTypeOfGroup(prevAtom))) { + group.type = "textord"; + className = "mord"; + } + + return buildCommon.mathsym( + group.value, group.mode, options.getColor(), [className]); +}; + +groupTypes.rel = function(group, options, prev) { + return buildCommon.mathsym( + group.value, group.mode, options.getColor(), ["mrel"]); +}; + +groupTypes.open = function(group, options, prev) { + return buildCommon.mathsym( + group.value, group.mode, options.getColor(), ["mopen"]); +}; + +groupTypes.close = function(group, options, prev) { + return buildCommon.mathsym( + group.value, group.mode, options.getColor(), ["mclose"]); +}; + +groupTypes.inner = function(group, options, prev) { + return buildCommon.mathsym( + group.value, group.mode, options.getColor(), ["minner"]); +}; + +groupTypes.punct = function(group, options, prev) { + return buildCommon.mathsym( + group.value, group.mode, options.getColor(), ["mpunct"]); +}; + +groupTypes.ordgroup = function(group, options, prev) { + return makeSpan( + ["mord", options.style.cls()], + buildExpression(group.value, options.reset()) + ); +}; + +groupTypes.text = function(group, options, prev) { + return makeSpan(["text", "mord", options.style.cls()], + buildExpression(group.value.body, options.reset())); +}; + +groupTypes.color = function(group, options, prev) { + var elements = buildExpression( + group.value.value, + options.withColor(group.value.color), + prev + ); + + // \color isn't supposed to affect the type of the elements it contains. + // To accomplish this, we wrap the results in a fragment, so the inner + // elements will be able to directly interact with their neighbors. For + // example, `\color{red}{2 +} 3` has the same spacing as `2 + 3` + return new buildCommon.makeFragment(elements); +}; + +groupTypes.supsub = function(group, options, prev) { + // Superscript and subscripts are handled in the TeXbook on page + // 445-446, rules 18(a-f). + + // Here is where we defer to the inner group if it should handle + // superscripts and subscripts itself. + if (shouldHandleSupSub(group.value.base, options)) { + return groupTypes[group.value.base.type](group, options, prev); + } + + var base = buildGroup(group.value.base, options.reset()); + var supmid, submid, sup, sub; + + if (group.value.sup) { + sup = buildGroup(group.value.sup, + options.withStyle(options.style.sup())); + supmid = makeSpan( + [options.style.reset(), options.style.sup().cls()], [sup]); + } + + if (group.value.sub) { + sub = buildGroup(group.value.sub, + options.withStyle(options.style.sub())); + submid = makeSpan( + [options.style.reset(), options.style.sub().cls()], [sub]); + } + + // Rule 18a + var supShift, subShift; + if (isCharacterBox(group.value.base)) { + supShift = 0; + subShift = 0; + } else { + supShift = base.height - fontMetrics.metrics.supDrop; + subShift = base.depth + fontMetrics.metrics.subDrop; + } + + // Rule 18c + var minSupShift; + if (options.style === Style.DISPLAY) { + minSupShift = fontMetrics.metrics.sup1; + } else if (options.style.cramped) { + minSupShift = fontMetrics.metrics.sup3; + } else { + minSupShift = fontMetrics.metrics.sup2; + } + + // scriptspace is a font-size-independent size, so scale it + // appropriately + var multiplier = Style.TEXT.sizeMultiplier * + options.style.sizeMultiplier; + var scriptspace = + (0.5 / fontMetrics.metrics.ptPerEm) / multiplier + "em"; + + var supsub; + if (!group.value.sup) { + // Rule 18b + subShift = Math.max( + subShift, fontMetrics.metrics.sub1, + sub.height - 0.8 * fontMetrics.metrics.xHeight); + + supsub = buildCommon.makeVList([ + {type: "elem", elem: submid} + ], "shift", subShift, options); + + supsub.children[0].style.marginRight = scriptspace; + + // Subscripts shouldn't be shifted by the base's italic correction. + // Account for that by shifting the subscript back the appropriate + // amount. Note we only do this when the base is a single symbol. + if (base instanceof domTree.symbolNode) { + supsub.children[0].style.marginLeft = -base.italic + "em"; + } + } else if (!group.value.sub) { + // Rule 18c, d + supShift = Math.max(supShift, minSupShift, + sup.depth + 0.25 * fontMetrics.metrics.xHeight); + + supsub = buildCommon.makeVList([ + {type: "elem", elem: supmid} + ], "shift", -supShift, options); + + supsub.children[0].style.marginRight = scriptspace; + } else { + supShift = Math.max( + supShift, minSupShift, + sup.depth + 0.25 * fontMetrics.metrics.xHeight); + subShift = Math.max(subShift, fontMetrics.metrics.sub2); + + var ruleWidth = fontMetrics.metrics.defaultRuleThickness; + + // Rule 18e + if ((supShift - sup.depth) - (sub.height - subShift) < + 4 * ruleWidth) { + subShift = 4 * ruleWidth - (supShift - sup.depth) + sub.height; + var psi = 0.8 * fontMetrics.metrics.xHeight - + (supShift - sup.depth); + if (psi > 0) { + supShift += psi; + subShift -= psi; + } + } + + supsub = buildCommon.makeVList([ + {type: "elem", elem: submid, shift: subShift}, + {type: "elem", elem: supmid, shift: -supShift} + ], "individualShift", null, options); + + // See comment above about subscripts not being shifted + if (base instanceof domTree.symbolNode) { + supsub.children[0].style.marginLeft = -base.italic + "em"; + } + + supsub.children[0].style.marginRight = scriptspace; + supsub.children[1].style.marginRight = scriptspace; + } + + return makeSpan([getTypeOfGroup(group.value.base)], + [base, supsub]); +}; + +groupTypes.genfrac = function(group, options, prev) { + // Fractions are handled in the TeXbook on pages 444-445, rules 15(a-e). + // Figure out what style this fraction should be in based on the + // function used + var fstyle = options.style; + if (group.value.size === "display") { + fstyle = Style.DISPLAY; + } else if (group.value.size === "text") { + fstyle = Style.TEXT; + } + + var nstyle = fstyle.fracNum(); + var dstyle = fstyle.fracDen(); + + var numer = buildGroup(group.value.numer, options.withStyle(nstyle)); + var numerreset = makeSpan([fstyle.reset(), nstyle.cls()], [numer]); + + var denom = buildGroup(group.value.denom, options.withStyle(dstyle)); + var denomreset = makeSpan([fstyle.reset(), dstyle.cls()], [denom]); + + var ruleWidth; + if (group.value.hasBarLine) { + ruleWidth = fontMetrics.metrics.defaultRuleThickness / + options.style.sizeMultiplier; + } else { + ruleWidth = 0; + } + + // Rule 15b + var numShift; + var clearance; + var denomShift; + if (fstyle.size === Style.DISPLAY.size) { + numShift = fontMetrics.metrics.num1; + if (ruleWidth > 0) { + clearance = 3 * ruleWidth; + } else { + clearance = 7 * fontMetrics.metrics.defaultRuleThickness; + } + denomShift = fontMetrics.metrics.denom1; + } else { + if (ruleWidth > 0) { + numShift = fontMetrics.metrics.num2; + clearance = ruleWidth; + } else { + numShift = fontMetrics.metrics.num3; + clearance = 3 * fontMetrics.metrics.defaultRuleThickness; + } + denomShift = fontMetrics.metrics.denom2; + } + + var frac; + if (ruleWidth === 0) { + // Rule 15c + var candiateClearance = + (numShift - numer.depth) - (denom.height - denomShift); + if (candiateClearance < clearance) { + numShift += 0.5 * (clearance - candiateClearance); + denomShift += 0.5 * (clearance - candiateClearance); + } + + frac = buildCommon.makeVList([ + {type: "elem", elem: denomreset, shift: denomShift}, + {type: "elem", elem: numerreset, shift: -numShift} + ], "individualShift", null, options); + } else { + // Rule 15d + var axisHeight = fontMetrics.metrics.axisHeight; + + if ((numShift - numer.depth) - (axisHeight + 0.5 * ruleWidth) < + clearance) { + numShift += + clearance - ((numShift - numer.depth) - + (axisHeight + 0.5 * ruleWidth)); + } + + if ((axisHeight - 0.5 * ruleWidth) - (denom.height - denomShift) < + clearance) { + denomShift += + clearance - ((axisHeight - 0.5 * ruleWidth) - + (denom.height - denomShift)); + } + + var mid = makeSpan( + [options.style.reset(), Style.TEXT.cls(), "frac-line"]); + // Manually set the height of the line because its height is + // created in CSS + mid.height = ruleWidth; + + var midShift = -(axisHeight - 0.5 * ruleWidth); + + frac = buildCommon.makeVList([ + {type: "elem", elem: denomreset, shift: denomShift}, + {type: "elem", elem: mid, shift: midShift}, + {type: "elem", elem: numerreset, shift: -numShift} + ], "individualShift", null, options); + } + + // Since we manually change the style sometimes (with \dfrac or \tfrac), + // account for the possible size change here. + frac.height *= fstyle.sizeMultiplier / options.style.sizeMultiplier; + frac.depth *= fstyle.sizeMultiplier / options.style.sizeMultiplier; + + // Rule 15e + var delimSize; + if (fstyle.size === Style.DISPLAY.size) { + delimSize = fontMetrics.metrics.delim1; + } else { + delimSize = fontMetrics.metrics.getDelim2(fstyle); + } + + var leftDelim, rightDelim; + if (group.value.leftDelim == null) { + leftDelim = makeNullDelimiter(options); + } else { + leftDelim = delimiter.customSizedDelim( + group.value.leftDelim, delimSize, true, + options.withStyle(fstyle), group.mode); + } + if (group.value.rightDelim == null) { + rightDelim = makeNullDelimiter(options); + } else { + rightDelim = delimiter.customSizedDelim( + group.value.rightDelim, delimSize, true, + options.withStyle(fstyle), group.mode); + } + + return makeSpan( + ["mord", options.style.reset(), fstyle.cls()], + [leftDelim, makeSpan(["mfrac"], [frac]), rightDelim], + options.getColor()); +}; + +groupTypes.array = function(group, options, prev) { + var r, c; + var nr = group.value.body.length; + var nc = 0; + var body = new Array(nr); + + // Horizontal spacing + var pt = 1 / fontMetrics.metrics.ptPerEm; + var arraycolsep = 5 * pt; // \arraycolsep in article.cls + + // Vertical spacing + var baselineskip = 12 * pt; // see size10.clo + // Default \arraystretch from lttab.dtx + // TODO(gagern): may get redefined once we have user-defined macros + var arraystretch = utils.deflt(group.value.arraystretch, 1); + var arrayskip = arraystretch * baselineskip; + var arstrutHeight = 0.7 * arrayskip; // \strutbox in ltfsstrc.dtx and + var arstrutDepth = 0.3 * arrayskip; // \@arstrutbox in lttab.dtx + + var totalHeight = 0; + for (r = 0; r < group.value.body.length; ++r) { + var inrow = group.value.body[r]; + var height = arstrutHeight; // \@array adds an \@arstrut + var depth = arstrutDepth; // to each tow (via the template) + + if (nc < inrow.length) { + nc = inrow.length; + } + + var outrow = new Array(inrow.length); + for (c = 0; c < inrow.length; ++c) { + var elt = buildGroup(inrow[c], options); + if (depth < elt.depth) { + depth = elt.depth; + } + if (height < elt.height) { + height = elt.height; + } + outrow[c] = elt; + } + + var gap = 0; + if (group.value.rowGaps[r]) { + gap = group.value.rowGaps[r].value; + switch (gap.unit) { + case "em": + gap = gap.number; + break; + case "ex": + gap = gap.number * fontMetrics.metrics.emPerEx; + break; + default: + console.error("Can't handle unit " + gap.unit); + gap = 0; + } + if (gap > 0) { // \@argarraycr + gap += arstrutDepth; + if (depth < gap) { + depth = gap; // \@xargarraycr + } + gap = 0; + } + } + + outrow.height = height; + outrow.depth = depth; + totalHeight += height; + outrow.pos = totalHeight; + totalHeight += depth + gap; // \@yargarraycr + body[r] = outrow; + } + + var offset = totalHeight / 2 + fontMetrics.metrics.axisHeight; + var colDescriptions = group.value.cols || []; + var cols = []; + var colSep; + var colDescrNum; + for (c = 0, colDescrNum = 0; + // Continue while either there are more columns or more column + // descriptions, so trailing separators don't get lost. + c < nc || colDescrNum < colDescriptions.length; + ++c, ++colDescrNum) { + + var colDescr = colDescriptions[colDescrNum] || {}; + + var firstSeparator = true; + while (colDescr.type === "separator") { + // If there is more than one separator in a row, add a space + // between them. + if (!firstSeparator) { + colSep = makeSpan(["arraycolsep"], []); + colSep.style.width = + fontMetrics.metrics.doubleRuleSep + "em"; + cols.push(colSep); + } + + if (colDescr.separator === "|") { + var separator = makeSpan( + ["vertical-separator"], + []); + separator.style.height = totalHeight + "em"; + separator.style.verticalAlign = + -(totalHeight - offset) + "em"; + + cols.push(separator); + } else { + throw new ParseError( + "Invalid separator type: " + colDescr.separator); + } + + colDescrNum++; + colDescr = colDescriptions[colDescrNum] || {}; + firstSeparator = false; + } + + if (c >= nc) { + continue; + } + + var sepwidth; + if (c > 0 || group.value.hskipBeforeAndAfter) { + sepwidth = utils.deflt(colDescr.pregap, arraycolsep); + if (sepwidth !== 0) { + colSep = makeSpan(["arraycolsep"], []); + colSep.style.width = sepwidth + "em"; + cols.push(colSep); + } + } + + var col = []; + for (r = 0; r < nr; ++r) { + var row = body[r]; + var elem = row[c]; + if (!elem) { + continue; + } + var shift = row.pos - offset; + elem.depth = row.depth; + elem.height = row.height; + col.push({type: "elem", elem: elem, shift: shift}); + } + + col = buildCommon.makeVList(col, "individualShift", null, options); + col = makeSpan( + ["col-align-" + (colDescr.align || "c")], + [col]); + cols.push(col); + + if (c < nc - 1 || group.value.hskipBeforeAndAfter) { + sepwidth = utils.deflt(colDescr.postgap, arraycolsep); + if (sepwidth !== 0) { + colSep = makeSpan(["arraycolsep"], []); + colSep.style.width = sepwidth + "em"; + cols.push(colSep); + } + } + } + body = makeSpan(["mtable"], cols); + return makeSpan(["mord"], [body], options.getColor()); +}; + +groupTypes.spacing = function(group, options, prev) { + if (group.value === "\\ " || group.value === "\\space" || + group.value === " " || group.value === "~") { + // Spaces are generated by adding an actual space. Each of these + // things has an entry in the symbols table, so these will be turned + // into appropriate outputs. + return makeSpan( + ["mord", "mspace"], + [buildCommon.mathsym(group.value, group.mode)] + ); + } else { + // Other kinds of spaces are of arbitrary width. We use CSS to + // generate these. + return makeSpan( + ["mord", "mspace", + buildCommon.spacingFunctions[group.value].className]); + } +}; + +groupTypes.llap = function(group, options, prev) { + var inner = makeSpan( + ["inner"], [buildGroup(group.value.body, options.reset())]); + var fix = makeSpan(["fix"], []); + return makeSpan( + ["llap", options.style.cls()], [inner, fix]); +}; + +groupTypes.rlap = function(group, options, prev) { + var inner = makeSpan( + ["inner"], [buildGroup(group.value.body, options.reset())]); + var fix = makeSpan(["fix"], []); + return makeSpan( + ["rlap", options.style.cls()], [inner, fix]); +}; + +groupTypes.op = function(group, options, prev) { + // Operators are handled in the TeXbook pg. 443-444, rule 13(a). + var supGroup; + var subGroup; + var hasLimits = false; + if (group.type === "supsub" ) { + // If we have limits, supsub will pass us its group to handle. Pull + // out the superscript and subscript and set the group to the op in + // its base. + supGroup = group.value.sup; + subGroup = group.value.sub; + group = group.value.base; + hasLimits = true; + } + + // Most operators have a large successor symbol, but these don't. + var noSuccessor = [ + "\\smallint" + ]; + + var large = false; + if (options.style.size === Style.DISPLAY.size && + group.value.symbol && + !utils.contains(noSuccessor, group.value.body)) { + + // Most symbol operators get larger in displaystyle (rule 13) + large = true; + } + + var base; + var baseShift = 0; + var slant = 0; + if (group.value.symbol) { + // If this is a symbol, create the symbol. + var style = large ? "Size2-Regular" : "Size1-Regular"; + base = buildCommon.makeSymbol( + group.value.body, style, "math", options.getColor(), + ["op-symbol", large ? "large-op" : "small-op", "mop"]); + + // Shift the symbol so its center lies on the axis (rule 13). It + // appears that our fonts have the centers of the symbols already + // almost on the axis, so these numbers are very small. Note we + // don't actually apply this here, but instead it is used either in + // the vlist creation or separately when there are no limits. + baseShift = (base.height - base.depth) / 2 - + fontMetrics.metrics.axisHeight * + options.style.sizeMultiplier; + + // The slant of the symbol is just its italic correction. + slant = base.italic; + } else { + // Otherwise, this is a text operator. Build the text from the + // operator's name. + // TODO(emily): Add a space in the middle of some of these + // operators, like \limsup + var output = []; + for (var i = 1; i < group.value.body.length; i++) { + output.push(buildCommon.mathsym(group.value.body[i], group.mode)); + } + base = makeSpan(["mop"], output, options.getColor()); + } + + if (hasLimits) { + // IE 8 clips \int if it is in a display: inline-block. We wrap it + // in a new span so it is an inline, and works. + base = makeSpan([], [base]); + + var supmid, supKern, submid, subKern; + // We manually have to handle the superscripts and subscripts. This, + // aside from the kern calculations, is copied from supsub. + if (supGroup) { + var sup = buildGroup( + supGroup, options.withStyle(options.style.sup())); + supmid = makeSpan( + [options.style.reset(), options.style.sup().cls()], [sup]); + + supKern = Math.max( + fontMetrics.metrics.bigOpSpacing1, + fontMetrics.metrics.bigOpSpacing3 - sup.depth); + } + + if (subGroup) { + var sub = buildGroup( + subGroup, options.withStyle(options.style.sub())); + submid = makeSpan( + [options.style.reset(), options.style.sub().cls()], + [sub]); + + subKern = Math.max( + fontMetrics.metrics.bigOpSpacing2, + fontMetrics.metrics.bigOpSpacing4 - sub.height); + } + + // Build the final group as a vlist of the possible subscript, base, + // and possible superscript. + var finalGroup, top, bottom; + if (!supGroup) { + top = base.height - baseShift; + + finalGroup = buildCommon.makeVList([ + {type: "kern", size: fontMetrics.metrics.bigOpSpacing5}, + {type: "elem", elem: submid}, + {type: "kern", size: subKern}, + {type: "elem", elem: base} + ], "top", top, options); + + // Here, we shift the limits by the slant of the symbol. Note + // that we are supposed to shift the limits by 1/2 of the slant, + // but since we are centering the limits adding a full slant of + // margin will shift by 1/2 that. + finalGroup.children[0].style.marginLeft = -slant + "em"; + } else if (!subGroup) { + bottom = base.depth + baseShift; + + finalGroup = buildCommon.makeVList([ + {type: "elem", elem: base}, + {type: "kern", size: supKern}, + {type: "elem", elem: supmid}, + {type: "kern", size: fontMetrics.metrics.bigOpSpacing5} + ], "bottom", bottom, options); + + // See comment above about slants + finalGroup.children[1].style.marginLeft = slant + "em"; + } else if (!supGroup && !subGroup) { + // This case probably shouldn't occur (this would mean the + // supsub was sending us a group with no superscript or + // subscript) but be safe. + return base; + } else { + bottom = fontMetrics.metrics.bigOpSpacing5 + + submid.height + submid.depth + + subKern + + base.depth + baseShift; + + finalGroup = buildCommon.makeVList([ + {type: "kern", size: fontMetrics.metrics.bigOpSpacing5}, + {type: "elem", elem: submid}, + {type: "kern", size: subKern}, + {type: "elem", elem: base}, + {type: "kern", size: supKern}, + {type: "elem", elem: supmid}, + {type: "kern", size: fontMetrics.metrics.bigOpSpacing5} + ], "bottom", bottom, options); + + // See comment above about slants + finalGroup.children[0].style.marginLeft = -slant + "em"; + finalGroup.children[2].style.marginLeft = slant + "em"; + } + + return makeSpan(["mop", "op-limits"], [finalGroup]); + } else { + if (group.value.symbol) { + base.style.top = baseShift + "em"; + } + + return base; + } +}; + +groupTypes.katex = function(group, options, prev) { + // The KaTeX logo. The offsets for the K and a were chosen to look + // good, but the offsets for the T, E, and X were taken from the + // definition of \TeX in TeX (see TeXbook pg. 356) + var k = makeSpan( + ["k"], [buildCommon.mathsym("K", group.mode)]); + var a = makeSpan( + ["a"], [buildCommon.mathsym("A", group.mode)]); + + a.height = (a.height + 0.2) * 0.75; + a.depth = (a.height - 0.2) * 0.75; + + var t = makeSpan( + ["t"], [buildCommon.mathsym("T", group.mode)]); + var e = makeSpan( + ["e"], [buildCommon.mathsym("E", group.mode)]); + + e.height = (e.height - 0.2155); + e.depth = (e.depth + 0.2155); + + var x = makeSpan( + ["x"], [buildCommon.mathsym("X", group.mode)]); + + return makeSpan( + ["katex-logo", "mord"], [k, a, t, e, x], options.getColor()); +}; + +groupTypes.overline = function(group, options, prev) { + // Overlines are handled in the TeXbook pg 443, Rule 9. + + // Build the inner group in the cramped style. + var innerGroup = buildGroup(group.value.body, + options.withStyle(options.style.cramp())); + + var ruleWidth = fontMetrics.metrics.defaultRuleThickness / + options.style.sizeMultiplier; + + // Create the line above the body + var line = makeSpan( + [options.style.reset(), Style.TEXT.cls(), "overline-line"]); + line.height = ruleWidth; + line.maxFontSize = 1.0; + + // Generate the vlist, with the appropriate kerns + var vlist = buildCommon.makeVList([ + {type: "elem", elem: innerGroup}, + {type: "kern", size: 3 * ruleWidth}, + {type: "elem", elem: line}, + {type: "kern", size: ruleWidth} + ], "firstBaseline", null, options); + + return makeSpan(["overline", "mord"], [vlist], options.getColor()); +}; + +groupTypes.sqrt = function(group, options, prev) { + // Square roots are handled in the TeXbook pg. 443, Rule 11. + + // First, we do the same steps as in overline to build the inner group + // and line + var inner = buildGroup(group.value.body, + options.withStyle(options.style.cramp())); + + var ruleWidth = fontMetrics.metrics.defaultRuleThickness / + options.style.sizeMultiplier; + + var line = makeSpan( + [options.style.reset(), Style.TEXT.cls(), "sqrt-line"], [], + options.getColor()); + line.height = ruleWidth; + line.maxFontSize = 1.0; + + var phi = ruleWidth; + if (options.style.id < Style.TEXT.id) { + phi = fontMetrics.metrics.xHeight; + } + + // Calculate the clearance between the body and line + var lineClearance = ruleWidth + phi / 4; + + var innerHeight = + (inner.height + inner.depth) * options.style.sizeMultiplier; + var minDelimiterHeight = innerHeight + lineClearance + ruleWidth; + + // Create a \surd delimiter of the required minimum size + var delim = makeSpan(["sqrt-sign"], [ + delimiter.customSizedDelim("\\surd", minDelimiterHeight, + false, options, group.mode)], + options.getColor()); + + var delimDepth = (delim.height + delim.depth) - ruleWidth; + + // Adjust the clearance based on the delimiter size + if (delimDepth > inner.height + inner.depth + lineClearance) { + lineClearance = + (lineClearance + delimDepth - inner.height - inner.depth) / 2; + } + + // Shift the delimiter so that its top lines up with the top of the line + var delimShift = -(inner.height + lineClearance + ruleWidth) + delim.height; + delim.style.top = delimShift + "em"; + delim.height -= delimShift; + delim.depth += delimShift; + + // We add a special case here, because even when `inner` is empty, we + // still get a line. So, we use a simple heuristic to decide if we + // should omit the body entirely. (note this doesn't work for something + // like `\sqrt{\rlap{x}}`, but if someone is doing that they deserve for + // it not to work. + var body; + if (inner.height === 0 && inner.depth === 0) { + body = makeSpan(); + } else { + body = buildCommon.makeVList([ + {type: "elem", elem: inner}, + {type: "kern", size: lineClearance}, + {type: "elem", elem: line}, + {type: "kern", size: ruleWidth} + ], "firstBaseline", null, options); + } + + if (!group.value.index) { + return makeSpan(["sqrt", "mord"], [delim, body]); + } else { + // Handle the optional root index + + // The index is always in scriptscript style + var root = buildGroup( + group.value.index, + options.withStyle(Style.SCRIPTSCRIPT)); + var rootWrap = makeSpan( + [options.style.reset(), Style.SCRIPTSCRIPT.cls()], + [root]); + + // Figure out the height and depth of the inner part + var innerRootHeight = Math.max(delim.height, body.height); + var innerRootDepth = Math.max(delim.depth, body.depth); + + // The amount the index is shifted by. This is taken from the TeX + // source, in the definition of `\r@@t`. + var toShift = 0.6 * (innerRootHeight - innerRootDepth); + + // Build a VList with the superscript shifted up correctly + var rootVList = buildCommon.makeVList( + [{type: "elem", elem: rootWrap}], + "shift", -toShift, options); + // Add a class surrounding it so we can add on the appropriate + // kerning + var rootVListWrap = makeSpan(["root"], [rootVList]); + + return makeSpan(["sqrt", "mord"], [rootVListWrap, delim, body]); + } +}; + +groupTypes.sizing = function(group, options, prev) { + // Handle sizing operators like \Huge. Real TeX doesn't actually allow + // these functions inside of math expressions, so we do some special + // handling. + var inner = buildExpression(group.value.value, + options.withSize(group.value.size), prev); + + var span = makeSpan(["mord"], + [makeSpan(["sizing", "reset-" + options.size, group.value.size, + options.style.cls()], + inner)]); + + // Calculate the correct maxFontSize manually + var fontSize = buildCommon.sizingMultiplier[group.value.size]; + span.maxFontSize = fontSize * options.style.sizeMultiplier; + + return span; +}; + +groupTypes.styling = function(group, options, prev) { + // Style changes are handled in the TeXbook on pg. 442, Rule 3. + + // Figure out what style we're changing to. + var style = { + "display": Style.DISPLAY, + "text": Style.TEXT, + "script": Style.SCRIPT, + "scriptscript": Style.SCRIPTSCRIPT + }; + + var newStyle = style[group.value.style]; + + // Build the inner expression in the new style. + var inner = buildExpression( + group.value.value, options.withStyle(newStyle), prev); + + return makeSpan([options.style.reset(), newStyle.cls()], inner); +}; + +groupTypes.font = function(group, options, prev) { + var font = group.value.font; + return buildGroup(group.value.body, options.withFont(font), prev); +}; + +groupTypes.delimsizing = function(group, options, prev) { + var delim = group.value.value; + + if (delim === ".") { + // Empty delimiters still count as elements, even though they don't + // show anything. + return makeSpan([groupToType[group.value.delimType]]); + } + + // Use delimiter.sizedDelim to generate the delimiter. + return makeSpan( + [groupToType[group.value.delimType]], + [delimiter.sizedDelim( + delim, group.value.size, options, group.mode)]); +}; + +groupTypes.leftright = function(group, options, prev) { + // Build the inner expression + var inner = buildExpression(group.value.body, options.reset()); + + var innerHeight = 0; + var innerDepth = 0; + + // Calculate its height and depth + for (var i = 0; i < inner.length; i++) { + innerHeight = Math.max(inner[i].height, innerHeight); + innerDepth = Math.max(inner[i].depth, innerDepth); + } + + // The size of delimiters is the same, regardless of what style we are + // in. Thus, to correctly calculate the size of delimiter we need around + // a group, we scale down the inner size based on the size. + innerHeight *= options.style.sizeMultiplier; + innerDepth *= options.style.sizeMultiplier; + + var leftDelim; + if (group.value.left === ".") { + // Empty delimiters in \left and \right make null delimiter spaces. + leftDelim = makeNullDelimiter(options); + } else { + // Otherwise, use leftRightDelim to generate the correct sized + // delimiter. + leftDelim = delimiter.leftRightDelim( + group.value.left, innerHeight, innerDepth, options, + group.mode); + } + // Add it to the beginning of the expression + inner.unshift(leftDelim); + + var rightDelim; + // Same for the right delimiter + if (group.value.right === ".") { + rightDelim = makeNullDelimiter(options); + } else { + rightDelim = delimiter.leftRightDelim( + group.value.right, innerHeight, innerDepth, options, + group.mode); + } + // Add it to the end of the expression. + inner.push(rightDelim); + + return makeSpan( + ["minner", options.style.cls()], inner, options.getColor()); +}; + +groupTypes.rule = function(group, options, prev) { + // Make an empty span for the rule + var rule = makeSpan(["mord", "rule"], [], options.getColor()); + + // Calculate the shift, width, and height of the rule, and account for units + var shift = 0; + if (group.value.shift) { + shift = group.value.shift.number; + if (group.value.shift.unit === "ex") { + shift *= fontMetrics.metrics.xHeight; + } + } + + var width = group.value.width.number; + if (group.value.width.unit === "ex") { + width *= fontMetrics.metrics.xHeight; + } + + var height = group.value.height.number; + if (group.value.height.unit === "ex") { + height *= fontMetrics.metrics.xHeight; + } + + // The sizes of rules are absolute, so make it larger if we are in a + // smaller style. + shift /= options.style.sizeMultiplier; + width /= options.style.sizeMultiplier; + height /= options.style.sizeMultiplier; + + // Style the rule to the right size + rule.style.borderRightWidth = width + "em"; + rule.style.borderTopWidth = height + "em"; + rule.style.bottom = shift + "em"; + + // Record the height and width + rule.width = width; + rule.height = height + shift; + rule.depth = -shift; + + return rule; +}; + +groupTypes.accent = function(group, options, prev) { + // Accents are handled in the TeXbook pg. 443, rule 12. + var base = group.value.base; + + var supsubGroup; + if (group.type === "supsub") { + // If our base is a character box, and we have superscripts and + // subscripts, the supsub will defer to us. In particular, we want + // to attach the superscripts and subscripts to the inner body (so + // that the position of the superscripts and subscripts won't be + // affected by the height of the accent). We accomplish this by + // sticking the base of the accent into the base of the supsub, and + // rendering that, while keeping track of where the accent is. + + // The supsub group is the group that was passed in + var supsub = group; + // The real accent group is the base of the supsub group + group = supsub.value.base; + // The character box is the base of the accent group + base = group.value.base; + // Stick the character box into the base of the supsub group + supsub.value.base = base; + + // Rerender the supsub group with its new base, and store that + // result. + supsubGroup = buildGroup( + supsub, options.reset(), prev); + } + + // Build the base group + var body = buildGroup( + base, options.withStyle(options.style.cramp())); + + // Calculate the skew of the accent. This is based on the line "If the + // nucleus is not a single character, let s = 0; otherwise set s to the + // kern amount for the nucleus followed by the \skewchar of its font." + // Note that our skew metrics are just the kern between each character + // and the skewchar. + var skew; + if (isCharacterBox(base)) { + // If the base is a character box, then we want the skew of the + // innermost character. To do that, we find the innermost character: + var baseChar = getBaseElem(base); + // Then, we render its group to get the symbol inside it + var baseGroup = buildGroup( + baseChar, options.withStyle(options.style.cramp())); + // Finally, we pull the skew off of the symbol. + skew = baseGroup.skew; + // Note that we now throw away baseGroup, because the layers we + // removed with getBaseElem might contain things like \color which + // we can't get rid of. + // TODO(emily): Find a better way to get the skew + } else { + skew = 0; + } + + // calculate the amount of space between the body and the accent + var clearance = Math.min(body.height, fontMetrics.metrics.xHeight); + + // Build the accent + var accent = buildCommon.makeSymbol( + group.value.accent, "Main-Regular", "math", options.getColor()); + // Remove the italic correction of the accent, because it only serves to + // shift the accent over to a place we don't want. + accent.italic = 0; + + // The \vec character that the fonts use is a combining character, and + // thus shows up much too far to the left. To account for this, we add a + // specific class which shifts the accent over to where we want it. + // TODO(emily): Fix this in a better way, like by changing the font + var vecClass = group.value.accent === "\\vec" ? "accent-vec" : null; + + var accentBody = makeSpan(["accent-body", vecClass], [ + makeSpan([], [accent])]); + + accentBody = buildCommon.makeVList([ + {type: "elem", elem: body}, + {type: "kern", size: -clearance}, + {type: "elem", elem: accentBody} + ], "firstBaseline", null, options); + + // Shift the accent over by the skew. Note we shift by twice the skew + // because we are centering the accent, so by adding 2*skew to the left, + // we shift it to the right by 1*skew. + accentBody.children[1].style.marginLeft = 2 * skew + "em"; + + var accentWrap = makeSpan(["mord", "accent"], [accentBody]); + + if (supsubGroup) { + // Here, we replace the "base" child of the supsub with our newly + // generated accent. + supsubGroup.children[0] = accentWrap; + + // Since we don't rerun the height calculation after replacing the + // accent, we manually recalculate height. + supsubGroup.height = Math.max(accentWrap.height, supsubGroup.height); + + // Accents should always be ords, even when their innards are not. + supsubGroup.classes[0] = "mord"; + + return supsubGroup; + } else { + return accentWrap; + } +}; + +groupTypes.phantom = function(group, options, prev) { + var elements = buildExpression( + group.value.value, + options.withPhantom(), + prev + ); + + // \phantom isn't supposed to affect the elements it contains. + // See "color" for more details. + return new buildCommon.makeFragment(elements); +}; + +/** + * buildGroup is the function that takes a group and calls the correct groupType + * function for it. It also handles the interaction of size and style changes + * between parents and children. + */ +var buildGroup = function(group, options, prev) { + if (!group) { + return makeSpan(); + } + + if (groupTypes[group.type]) { + // Call the groupTypes function + var groupNode = groupTypes[group.type](group, options, prev); + var multiplier; + + // If the style changed between the parent and the current group, + // account for the size difference + if (options.style !== options.parentStyle) { + multiplier = options.style.sizeMultiplier / + options.parentStyle.sizeMultiplier; + + groupNode.height *= multiplier; + groupNode.depth *= multiplier; + } + + // If the size changed between the parent and the current group, account + // for that size difference. + if (options.size !== options.parentSize) { + multiplier = buildCommon.sizingMultiplier[options.size] / + buildCommon.sizingMultiplier[options.parentSize]; + + groupNode.height *= multiplier; + groupNode.depth *= multiplier; + } + + return groupNode; + } else { + throw new ParseError( + "Got group of unknown type: '" + group.type + "'"); + } +}; + +/** + * Take an entire parse tree, and build it into an appropriate set of HTML + * nodes. + */ +var buildHTML = function(tree, options) { + // buildExpression is destructive, so we need to make a clone + // of the incoming tree so that it isn't accidentally changed + tree = JSON.parse(JSON.stringify(tree)); + + // Build the expression contained in the tree + var expression = buildExpression(tree, options); + var body = makeSpan(["base", options.style.cls()], expression); + + // Add struts, which ensure that the top of the HTML element falls at the + // height of the expression, and the bottom of the HTML element falls at the + // depth of the expression. + var topStrut = makeSpan(["strut"]); + var bottomStrut = makeSpan(["strut", "bottom"]); + + topStrut.style.height = body.height + "em"; + bottomStrut.style.height = (body.height + body.depth) + "em"; + // We'd like to use `vertical-align: top` but in IE 9 this lowers the + // baseline of the box to the bottom of this strut (instead staying in the + // normal place) so we use an absolute value for vertical-align instead + bottomStrut.style.verticalAlign = -body.depth + "em"; + + // Wrap the struts and body together + var htmlNode = makeSpan(["katex-html"], [topStrut, bottomStrut, body]); + + htmlNode.setAttribute("aria-hidden", "true"); + + return htmlNode; +}; + +module.exports = buildHTML; diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/buildMathML.js b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/buildMathML.js new file mode 100644 index 0000000..2408ba3 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/buildMathML.js @@ -0,0 +1,519 @@ +/** + * This file converts a parse tree into a cooresponding MathML tree. The main + * entry point is the `buildMathML` function, which takes a parse tree from the + * parser. + */ + +var buildCommon = require("./buildCommon"); +var fontMetrics = require("./fontMetrics"); +var mathMLTree = require("./mathMLTree"); +var ParseError = require("./ParseError"); +var symbols = require("./symbols"); +var utils = require("./utils"); + +var makeSpan = buildCommon.makeSpan; +var fontMap = buildCommon.fontMap; + +/** + * Takes a symbol and converts it into a MathML text node after performing + * optional replacement from symbols.js. + */ +var makeText = function(text, mode) { + if (symbols[mode][text] && symbols[mode][text].replace) { + text = symbols[mode][text].replace; + } + + return new mathMLTree.TextNode(text); +}; + +/** + * Returns the math variant as a string or null if none is required. + */ +var getVariant = function(group, options) { + var font = options.font; + if (!font) { + return null; + } + + var mode = group.mode; + if (font === "mathit") { + return "italic"; + } + + var value = group.value; + if (utils.contains(["\\imath", "\\jmath"], value)) { + return null; + } + + if (symbols[mode][value] && symbols[mode][value].replace) { + value = symbols[mode][value].replace; + } + + var fontName = fontMap[font].fontName; + if (fontMetrics.getCharacterMetrics(value, fontName)) { + return fontMap[options.font].variant; + } + + return null; +}; + +/** + * Functions for handling the different types of groups found in the parse + * tree. Each function should take a parse group and return a MathML node. + */ +var groupTypes = {}; + +groupTypes.mathord = function(group, options) { + var node = new mathMLTree.MathNode( + "mi", + [makeText(group.value, group.mode)]); + + var variant = getVariant(group, options); + if (variant) { + node.setAttribute("mathvariant", variant); + } + return node; +}; + +groupTypes.textord = function(group, options) { + var text = makeText(group.value, group.mode); + + var variant = getVariant(group, options) || "normal"; + + var node; + if (/[0-9]/.test(group.value)) { + // TODO(kevinb) merge adjacent <mn> nodes + // do it as a post processing step + node = new mathMLTree.MathNode("mn", [text]); + if (options.font) { + node.setAttribute("mathvariant", variant); + } + } else { + node = new mathMLTree.MathNode("mi", [text]); + node.setAttribute("mathvariant", variant); + } + + return node; +}; + +groupTypes.bin = function(group) { + var node = new mathMLTree.MathNode( + "mo", [makeText(group.value, group.mode)]); + + return node; +}; + +groupTypes.rel = function(group) { + var node = new mathMLTree.MathNode( + "mo", [makeText(group.value, group.mode)]); + + return node; +}; + +groupTypes.open = function(group) { + var node = new mathMLTree.MathNode( + "mo", [makeText(group.value, group.mode)]); + + return node; +}; + +groupTypes.close = function(group) { + var node = new mathMLTree.MathNode( + "mo", [makeText(group.value, group.mode)]); + + return node; +}; + +groupTypes.inner = function(group) { + var node = new mathMLTree.MathNode( + "mo", [makeText(group.value, group.mode)]); + + return node; +}; + +groupTypes.punct = function(group) { + var node = new mathMLTree.MathNode( + "mo", [makeText(group.value, group.mode)]); + + node.setAttribute("separator", "true"); + + return node; +}; + +groupTypes.ordgroup = function(group, options) { + var inner = buildExpression(group.value, options); + + var node = new mathMLTree.MathNode("mrow", inner); + + return node; +}; + +groupTypes.text = function(group, options) { + var inner = buildExpression(group.value.body, options); + + var node = new mathMLTree.MathNode("mtext", inner); + + return node; +}; + +groupTypes.color = function(group, options) { + var inner = buildExpression(group.value.value, options); + + var node = new mathMLTree.MathNode("mstyle", inner); + + node.setAttribute("mathcolor", group.value.color); + + return node; +}; + +groupTypes.supsub = function(group, options) { + var children = [buildGroup(group.value.base, options)]; + + if (group.value.sub) { + children.push(buildGroup(group.value.sub, options)); + } + + if (group.value.sup) { + children.push(buildGroup(group.value.sup, options)); + } + + var nodeType; + if (!group.value.sub) { + nodeType = "msup"; + } else if (!group.value.sup) { + nodeType = "msub"; + } else { + nodeType = "msubsup"; + } + + var node = new mathMLTree.MathNode(nodeType, children); + + return node; +}; + +groupTypes.genfrac = function(group, options) { + var node = new mathMLTree.MathNode( + "mfrac", + [buildGroup(group.value.numer, options), + buildGroup(group.value.denom, options)]); + + if (!group.value.hasBarLine) { + node.setAttribute("linethickness", "0px"); + } + + if (group.value.leftDelim != null || group.value.rightDelim != null) { + var withDelims = []; + + if (group.value.leftDelim != null) { + var leftOp = new mathMLTree.MathNode( + "mo", [new mathMLTree.TextNode(group.value.leftDelim)]); + + leftOp.setAttribute("fence", "true"); + + withDelims.push(leftOp); + } + + withDelims.push(node); + + if (group.value.rightDelim != null) { + var rightOp = new mathMLTree.MathNode( + "mo", [new mathMLTree.TextNode(group.value.rightDelim)]); + + rightOp.setAttribute("fence", "true"); + + withDelims.push(rightOp); + } + + var outerNode = new mathMLTree.MathNode("mrow", withDelims); + + return outerNode; + } + + return node; +}; + +groupTypes.array = function(group, options) { + return new mathMLTree.MathNode( + "mtable", group.value.body.map(function(row) { + return new mathMLTree.MathNode( + "mtr", row.map(function(cell) { + return new mathMLTree.MathNode( + "mtd", [buildGroup(cell, options)]); + })); + })); +}; + +groupTypes.sqrt = function(group, options) { + var node; + if (group.value.index) { + node = new mathMLTree.MathNode( + "mroot", [ + buildGroup(group.value.body, options), + buildGroup(group.value.index, options) + ]); + } else { + node = new mathMLTree.MathNode( + "msqrt", [buildGroup(group.value.body, options)]); + } + + return node; +}; + +groupTypes.leftright = function(group, options) { + var inner = buildExpression(group.value.body, options); + + if (group.value.left !== ".") { + var leftNode = new mathMLTree.MathNode( + "mo", [makeText(group.value.left, group.mode)]); + + leftNode.setAttribute("fence", "true"); + + inner.unshift(leftNode); + } + + if (group.value.right !== ".") { + var rightNode = new mathMLTree.MathNode( + "mo", [makeText(group.value.right, group.mode)]); + + rightNode.setAttribute("fence", "true"); + + inner.push(rightNode); + } + + var outerNode = new mathMLTree.MathNode("mrow", inner); + + return outerNode; +}; + +groupTypes.accent = function(group, options) { + var accentNode = new mathMLTree.MathNode( + "mo", [makeText(group.value.accent, group.mode)]); + + var node = new mathMLTree.MathNode( + "mover", + [buildGroup(group.value.base, options), + accentNode]); + + node.setAttribute("accent", "true"); + + return node; +}; + +groupTypes.spacing = function(group) { + var node; + + if (group.value === "\\ " || group.value === "\\space" || + group.value === " " || group.value === "~") { + node = new mathMLTree.MathNode( + "mtext", [new mathMLTree.TextNode("\u00a0")]); + } else { + node = new mathMLTree.MathNode("mspace"); + + node.setAttribute( + "width", buildCommon.spacingFunctions[group.value].size); + } + + return node; +}; + +groupTypes.op = function(group) { + var node; + + // TODO(emily): handle big operators using the `largeop` attribute + + if (group.value.symbol) { + // This is a symbol. Just add the symbol. + node = new mathMLTree.MathNode( + "mo", [makeText(group.value.body, group.mode)]); + } else { + // This is a text operator. Add all of the characters from the + // operator's name. + // TODO(emily): Add a space in the middle of some of these + // operators, like \limsup. + node = new mathMLTree.MathNode( + "mi", [new mathMLTree.TextNode(group.value.body.slice(1))]); + } + + return node; +}; + +groupTypes.katex = function(group) { + var node = new mathMLTree.MathNode( + "mtext", [new mathMLTree.TextNode("KaTeX")]); + + return node; +}; + +groupTypes.font = function(group, options) { + var font = group.value.font; + return buildGroup(group.value.body, options.withFont(font)); +}; + +groupTypes.delimsizing = function(group) { + var children = []; + + if (group.value.value !== ".") { + children.push(makeText(group.value.value, group.mode)); + } + + var node = new mathMLTree.MathNode("mo", children); + + if (group.value.delimType === "open" || + group.value.delimType === "close") { + // Only some of the delimsizing functions act as fences, and they + // return "open" or "close" delimTypes. + node.setAttribute("fence", "true"); + } else { + // Explicitly disable fencing if it's not a fence, to override the + // defaults. + node.setAttribute("fence", "false"); + } + + return node; +}; + +groupTypes.styling = function(group, options) { + var inner = buildExpression(group.value.value, options); + + var node = new mathMLTree.MathNode("mstyle", inner); + + var styleAttributes = { + "display": ["0", "true"], + "text": ["0", "false"], + "script": ["1", "false"], + "scriptscript": ["2", "false"] + }; + + var attr = styleAttributes[group.value.style]; + + node.setAttribute("scriptlevel", attr[0]); + node.setAttribute("displaystyle", attr[1]); + + return node; +}; + +groupTypes.sizing = function(group, options) { + var inner = buildExpression(group.value.value, options); + + var node = new mathMLTree.MathNode("mstyle", inner); + + // TODO(emily): This doesn't produce the correct size for nested size + // changes, because we don't keep state of what style we're currently + // in, so we can't reset the size to normal before changing it. Now + // that we're passing an options parameter we should be able to fix + // this. + node.setAttribute( + "mathsize", buildCommon.sizingMultiplier[group.value.size] + "em"); + + return node; +}; + +groupTypes.overline = function(group, options) { + var operator = new mathMLTree.MathNode( + "mo", [new mathMLTree.TextNode("\u203e")]); + operator.setAttribute("stretchy", "true"); + + var node = new mathMLTree.MathNode( + "mover", + [buildGroup(group.value.body, options), + operator]); + node.setAttribute("accent", "true"); + + return node; +}; + +groupTypes.rule = function(group) { + // TODO(emily): Figure out if there's an actual way to draw black boxes + // in MathML. + var node = new mathMLTree.MathNode("mrow"); + + return node; +}; + +groupTypes.llap = function(group, options) { + var node = new mathMLTree.MathNode( + "mpadded", [buildGroup(group.value.body, options)]); + + node.setAttribute("lspace", "-1width"); + node.setAttribute("width", "0px"); + + return node; +}; + +groupTypes.rlap = function(group, options) { + var node = new mathMLTree.MathNode( + "mpadded", [buildGroup(group.value.body, options)]); + + node.setAttribute("width", "0px"); + + return node; +}; + +groupTypes.phantom = function(group, options, prev) { + var inner = buildExpression(group.value.value, options); + return new mathMLTree.MathNode("mphantom", inner); +}; + +/** + * Takes a list of nodes, builds them, and returns a list of the generated + * MathML nodes. A little simpler than the HTML version because we don't do any + * previous-node handling. + */ +var buildExpression = function(expression, options) { + var groups = []; + for (var i = 0; i < expression.length; i++) { + var group = expression[i]; + groups.push(buildGroup(group, options)); + } + return groups; +}; + +/** + * Takes a group from the parser and calls the appropriate groupTypes function + * on it to produce a MathML node. + */ +var buildGroup = function(group, options) { + if (!group) { + return new mathMLTree.MathNode("mrow"); + } + + if (groupTypes[group.type]) { + // Call the groupTypes function + return groupTypes[group.type](group, options); + } else { + throw new ParseError( + "Got group of unknown type: '" + group.type + "'"); + } +}; + +/** + * Takes a full parse tree and settings and builds a MathML representation of + * it. In particular, we put the elements from building the parse tree into a + * <semantics> tag so we can also include that TeX source as an annotation. + * + * Note that we actually return a domTree element with a `<math>` inside it so + * we can do appropriate styling. + */ +var buildMathML = function(tree, texExpression, options) { + var expression = buildExpression(tree, options); + + // Wrap up the expression in an mrow so it is presented in the semantics + // tag correctly. + var wrapper = new mathMLTree.MathNode("mrow", expression); + + // Build a TeX annotation of the source + var annotation = new mathMLTree.MathNode( + "annotation", [new mathMLTree.TextNode(texExpression)]); + + annotation.setAttribute("encoding", "application/x-tex"); + + var semantics = new mathMLTree.MathNode( + "semantics", [wrapper, annotation]); + + var math = new mathMLTree.MathNode("math", [semantics]); + + // You can't style <math> nodes, so we wrap the node in a span. + return makeSpan(["katex-mathml"], [math]); +}; + +module.exports = buildMathML; diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/buildTree.js b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/buildTree.js new file mode 100644 index 0000000..03ade9e --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/buildTree.js @@ -0,0 +1,40 @@ +var buildHTML = require("./buildHTML"); +var buildMathML = require("./buildMathML"); +var buildCommon = require("./buildCommon"); +var Options = require("./Options"); +var Settings = require("./Settings"); +var Style = require("./Style"); + +var makeSpan = buildCommon.makeSpan; + +var buildTree = function(tree, expression, settings) { + settings = settings || new Settings({}); + + var startStyle = Style.TEXT; + if (settings.displayMode) { + startStyle = Style.DISPLAY; + } + + // Setup the default options + var options = new Options({ + style: startStyle, + size: "size5" + }); + + // `buildHTML` sometimes messes with the parse tree (like turning bins -> + // ords), so we build the MathML version first. + var mathMLNode = buildMathML(tree, expression, options); + var htmlNode = buildHTML(tree, options); + + var katexNode = makeSpan(["katex"], [ + mathMLNode, htmlNode + ]); + + if (settings.displayMode) { + return makeSpan(["katex-display"], [katexNode]); + } else { + return katexNode; + } +}; + +module.exports = buildTree; diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/delimiter.js b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/delimiter.js new file mode 100644 index 0000000..9b122fa --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/delimiter.js @@ -0,0 +1,539 @@ +/** + * This file deals with creating delimiters of various sizes. The TeXbook + * discusses these routines on page 441-442, in the "Another subroutine sets box + * x to a specified variable delimiter" paragraph. + * + * There are three main routines here. `makeSmallDelim` makes a delimiter in the + * normal font, but in either text, script, or scriptscript style. + * `makeLargeDelim` makes a delimiter in textstyle, but in one of the Size1, + * Size2, Size3, or Size4 fonts. `makeStackedDelim` makes a delimiter out of + * smaller pieces that are stacked on top of one another. + * + * The functions take a parameter `center`, which determines if the delimiter + * should be centered around the axis. + * + * Then, there are three exposed functions. `sizedDelim` makes a delimiter in + * one of the given sizes. This is used for things like `\bigl`. + * `customSizedDelim` makes a delimiter with a given total height+depth. It is + * called in places like `\sqrt`. `leftRightDelim` makes an appropriate + * delimiter which surrounds an expression of a given height an depth. It is + * used in `\left` and `\right`. + */ + +var ParseError = require("./ParseError"); +var Style = require("./Style"); + +var buildCommon = require("./buildCommon"); +var fontMetrics = require("./fontMetrics"); +var symbols = require("./symbols"); +var utils = require("./utils"); + +var makeSpan = buildCommon.makeSpan; + +/** + * Get the metrics for a given symbol and font, after transformation (i.e. + * after following replacement from symbols.js) + */ +var getMetrics = function(symbol, font) { + if (symbols.math[symbol] && symbols.math[symbol].replace) { + return fontMetrics.getCharacterMetrics( + symbols.math[symbol].replace, font); + } else { + return fontMetrics.getCharacterMetrics( + symbol, font); + } +}; + +/** + * Builds a symbol in the given font size (note size is an integer) + */ +var mathrmSize = function(value, size, mode) { + return buildCommon.makeSymbol(value, "Size" + size + "-Regular", mode); +}; + +/** + * Puts a delimiter span in a given style, and adds appropriate height, depth, + * and maxFontSizes. + */ +var styleWrap = function(delim, toStyle, options) { + var span = makeSpan( + ["style-wrap", options.style.reset(), toStyle.cls()], [delim]); + + var multiplier = toStyle.sizeMultiplier / options.style.sizeMultiplier; + + span.height *= multiplier; + span.depth *= multiplier; + span.maxFontSize = toStyle.sizeMultiplier; + + return span; +}; + +/** + * Makes a small delimiter. This is a delimiter that comes in the Main-Regular + * font, but is restyled to either be in textstyle, scriptstyle, or + * scriptscriptstyle. + */ +var makeSmallDelim = function(delim, style, center, options, mode) { + var text = buildCommon.makeSymbol(delim, "Main-Regular", mode); + + var span = styleWrap(text, style, options); + + if (center) { + var shift = + (1 - options.style.sizeMultiplier / style.sizeMultiplier) * + fontMetrics.metrics.axisHeight; + + span.style.top = shift + "em"; + span.height -= shift; + span.depth += shift; + } + + return span; +}; + +/** + * Makes a large delimiter. This is a delimiter that comes in the Size1, Size2, + * Size3, or Size4 fonts. It is always rendered in textstyle. + */ +var makeLargeDelim = function(delim, size, center, options, mode) { + var inner = mathrmSize(delim, size, mode); + + var span = styleWrap( + makeSpan(["delimsizing", "size" + size], + [inner], options.getColor()), + Style.TEXT, options); + + if (center) { + var shift = (1 - options.style.sizeMultiplier) * + fontMetrics.metrics.axisHeight; + + span.style.top = shift + "em"; + span.height -= shift; + span.depth += shift; + } + + return span; +}; + +/** + * Make an inner span with the given offset and in the given font. This is used + * in `makeStackedDelim` to make the stacking pieces for the delimiter. + */ +var makeInner = function(symbol, font, mode) { + var sizeClass; + // Apply the correct CSS class to choose the right font. + if (font === "Size1-Regular") { + sizeClass = "delim-size1"; + } else if (font === "Size4-Regular") { + sizeClass = "delim-size4"; + } + + var inner = makeSpan( + ["delimsizinginner", sizeClass], + [makeSpan([], [buildCommon.makeSymbol(symbol, font, mode)])]); + + // Since this will be passed into `makeVList` in the end, wrap the element + // in the appropriate tag that VList uses. + return {type: "elem", elem: inner}; +}; + +/** + * Make a stacked delimiter out of a given delimiter, with the total height at + * least `heightTotal`. This routine is mentioned on page 442 of the TeXbook. + */ +var makeStackedDelim = function(delim, heightTotal, center, options, mode) { + // There are four parts, the top, an optional middle, a repeated part, and a + // bottom. + var top, middle, repeat, bottom; + top = repeat = bottom = delim; + middle = null; + // Also keep track of what font the delimiters are in + var font = "Size1-Regular"; + + // We set the parts and font based on the symbol. Note that we use + // '\u23d0' instead of '|' and '\u2016' instead of '\\|' for the + // repeats of the arrows + if (delim === "\\uparrow") { + repeat = bottom = "\u23d0"; + } else if (delim === "\\Uparrow") { + repeat = bottom = "\u2016"; + } else if (delim === "\\downarrow") { + top = repeat = "\u23d0"; + } else if (delim === "\\Downarrow") { + top = repeat = "\u2016"; + } else if (delim === "\\updownarrow") { + top = "\\uparrow"; + repeat = "\u23d0"; + bottom = "\\downarrow"; + } else if (delim === "\\Updownarrow") { + top = "\\Uparrow"; + repeat = "\u2016"; + bottom = "\\Downarrow"; + } else if (delim === "[" || delim === "\\lbrack") { + top = "\u23a1"; + repeat = "\u23a2"; + bottom = "\u23a3"; + font = "Size4-Regular"; + } else if (delim === "]" || delim === "\\rbrack") { + top = "\u23a4"; + repeat = "\u23a5"; + bottom = "\u23a6"; + font = "Size4-Regular"; + } else if (delim === "\\lfloor") { + repeat = top = "\u23a2"; + bottom = "\u23a3"; + font = "Size4-Regular"; + } else if (delim === "\\lceil") { + top = "\u23a1"; + repeat = bottom = "\u23a2"; + font = "Size4-Regular"; + } else if (delim === "\\rfloor") { + repeat = top = "\u23a5"; + bottom = "\u23a6"; + font = "Size4-Regular"; + } else if (delim === "\\rceil") { + top = "\u23a4"; + repeat = bottom = "\u23a5"; + font = "Size4-Regular"; + } else if (delim === "(") { + top = "\u239b"; + repeat = "\u239c"; + bottom = "\u239d"; + font = "Size4-Regular"; + } else if (delim === ")") { + top = "\u239e"; + repeat = "\u239f"; + bottom = "\u23a0"; + font = "Size4-Regular"; + } else if (delim === "\\{" || delim === "\\lbrace") { + top = "\u23a7"; + middle = "\u23a8"; + bottom = "\u23a9"; + repeat = "\u23aa"; + font = "Size4-Regular"; + } else if (delim === "\\}" || delim === "\\rbrace") { + top = "\u23ab"; + middle = "\u23ac"; + bottom = "\u23ad"; + repeat = "\u23aa"; + font = "Size4-Regular"; + } else if (delim === "\\lgroup") { + top = "\u23a7"; + bottom = "\u23a9"; + repeat = "\u23aa"; + font = "Size4-Regular"; + } else if (delim === "\\rgroup") { + top = "\u23ab"; + bottom = "\u23ad"; + repeat = "\u23aa"; + font = "Size4-Regular"; + } else if (delim === "\\lmoustache") { + top = "\u23a7"; + bottom = "\u23ad"; + repeat = "\u23aa"; + font = "Size4-Regular"; + } else if (delim === "\\rmoustache") { + top = "\u23ab"; + bottom = "\u23a9"; + repeat = "\u23aa"; + font = "Size4-Regular"; + } else if (delim === "\\surd") { + top = "\ue001"; + bottom = "\u23b7"; + repeat = "\ue000"; + font = "Size4-Regular"; + } + + // Get the metrics of the four sections + var topMetrics = getMetrics(top, font); + var topHeightTotal = topMetrics.height + topMetrics.depth; + var repeatMetrics = getMetrics(repeat, font); + var repeatHeightTotal = repeatMetrics.height + repeatMetrics.depth; + var bottomMetrics = getMetrics(bottom, font); + var bottomHeightTotal = bottomMetrics.height + bottomMetrics.depth; + var middleHeightTotal = 0; + var middleFactor = 1; + if (middle !== null) { + var middleMetrics = getMetrics(middle, font); + middleHeightTotal = middleMetrics.height + middleMetrics.depth; + middleFactor = 2; // repeat symmetrically above and below middle + } + + // Calcuate the minimal height that the delimiter can have. + // It is at least the size of the top, bottom, and optional middle combined. + var minHeight = topHeightTotal + bottomHeightTotal + middleHeightTotal; + + // Compute the number of copies of the repeat symbol we will need + var repeatCount = Math.ceil( + (heightTotal - minHeight) / (middleFactor * repeatHeightTotal)); + + // Compute the total height of the delimiter including all the symbols + var realHeightTotal = + minHeight + repeatCount * middleFactor * repeatHeightTotal; + + // The center of the delimiter is placed at the center of the axis. Note + // that in this context, "center" means that the delimiter should be + // centered around the axis in the current style, while normally it is + // centered around the axis in textstyle. + var axisHeight = fontMetrics.metrics.axisHeight; + if (center) { + axisHeight *= options.style.sizeMultiplier; + } + // Calculate the depth + var depth = realHeightTotal / 2 - axisHeight; + + // Now, we start building the pieces that will go into the vlist + + // Keep a list of the inner pieces + var inners = []; + + // Add the bottom symbol + inners.push(makeInner(bottom, font, mode)); + + var i; + if (middle === null) { + // Add that many symbols + for (i = 0; i < repeatCount; i++) { + inners.push(makeInner(repeat, font, mode)); + } + } else { + // When there is a middle bit, we need the middle part and two repeated + // sections + for (i = 0; i < repeatCount; i++) { + inners.push(makeInner(repeat, font, mode)); + } + inners.push(makeInner(middle, font, mode)); + for (i = 0; i < repeatCount; i++) { + inners.push(makeInner(repeat, font, mode)); + } + } + + // Add the top symbol + inners.push(makeInner(top, font, mode)); + + // Finally, build the vlist + var inner = buildCommon.makeVList(inners, "bottom", depth, options); + + return styleWrap( + makeSpan(["delimsizing", "mult"], [inner], options.getColor()), + Style.TEXT, options); +}; + +// There are three kinds of delimiters, delimiters that stack when they become +// too large +var stackLargeDelimiters = [ + "(", ")", "[", "\\lbrack", "]", "\\rbrack", + "\\{", "\\lbrace", "\\}", "\\rbrace", + "\\lfloor", "\\rfloor", "\\lceil", "\\rceil", + "\\surd" +]; + +// delimiters that always stack +var stackAlwaysDelimiters = [ + "\\uparrow", "\\downarrow", "\\updownarrow", + "\\Uparrow", "\\Downarrow", "\\Updownarrow", + "|", "\\|", "\\vert", "\\Vert", + "\\lvert", "\\rvert", "\\lVert", "\\rVert", + "\\lgroup", "\\rgroup", "\\lmoustache", "\\rmoustache" +]; + +// and delimiters that never stack +var stackNeverDelimiters = [ + "<", ">", "\\langle", "\\rangle", "/", "\\backslash", "\\lt", "\\gt" +]; + +// Metrics of the different sizes. Found by looking at TeX's output of +// $\bigl| // \Bigl| \biggl| \Biggl| \showlists$ +// Used to create stacked delimiters of appropriate sizes in makeSizedDelim. +var sizeToMaxHeight = [0, 1.2, 1.8, 2.4, 3.0]; + +/** + * Used to create a delimiter of a specific size, where `size` is 1, 2, 3, or 4. + */ +var makeSizedDelim = function(delim, size, options, mode) { + // < and > turn into \langle and \rangle in delimiters + if (delim === "<" || delim === "\\lt") { + delim = "\\langle"; + } else if (delim === ">" || delim === "\\gt") { + delim = "\\rangle"; + } + + // Sized delimiters are never centered. + if (utils.contains(stackLargeDelimiters, delim) || + utils.contains(stackNeverDelimiters, delim)) { + return makeLargeDelim(delim, size, false, options, mode); + } else if (utils.contains(stackAlwaysDelimiters, delim)) { + return makeStackedDelim( + delim, sizeToMaxHeight[size], false, options, mode); + } else { + throw new ParseError("Illegal delimiter: '" + delim + "'"); + } +}; + +/** + * There are three different sequences of delimiter sizes that the delimiters + * follow depending on the kind of delimiter. This is used when creating custom + * sized delimiters to decide whether to create a small, large, or stacked + * delimiter. + * + * In real TeX, these sequences aren't explicitly defined, but are instead + * defined inside the font metrics. Since there are only three sequences that + * are possible for the delimiters that TeX defines, it is easier to just encode + * them explicitly here. + */ + +// Delimiters that never stack try small delimiters and large delimiters only +var stackNeverDelimiterSequence = [ + {type: "small", style: Style.SCRIPTSCRIPT}, + {type: "small", style: Style.SCRIPT}, + {type: "small", style: Style.TEXT}, + {type: "large", size: 1}, + {type: "large", size: 2}, + {type: "large", size: 3}, + {type: "large", size: 4} +]; + +// Delimiters that always stack try the small delimiters first, then stack +var stackAlwaysDelimiterSequence = [ + {type: "small", style: Style.SCRIPTSCRIPT}, + {type: "small", style: Style.SCRIPT}, + {type: "small", style: Style.TEXT}, + {type: "stack"} +]; + +// Delimiters that stack when large try the small and then large delimiters, and +// stack afterwards +var stackLargeDelimiterSequence = [ + {type: "small", style: Style.SCRIPTSCRIPT}, + {type: "small", style: Style.SCRIPT}, + {type: "small", style: Style.TEXT}, + {type: "large", size: 1}, + {type: "large", size: 2}, + {type: "large", size: 3}, + {type: "large", size: 4}, + {type: "stack"} +]; + +/** + * Get the font used in a delimiter based on what kind of delimiter it is. + */ +var delimTypeToFont = function(type) { + if (type.type === "small") { + return "Main-Regular"; + } else if (type.type === "large") { + return "Size" + type.size + "-Regular"; + } else if (type.type === "stack") { + return "Size4-Regular"; + } +}; + +/** + * Traverse a sequence of types of delimiters to decide what kind of delimiter + * should be used to create a delimiter of the given height+depth. + */ +var traverseSequence = function(delim, height, sequence, options) { + // Here, we choose the index we should start at in the sequences. In smaller + // sizes (which correspond to larger numbers in style.size) we start earlier + // in the sequence. Thus, scriptscript starts at index 3-3=0, script starts + // at index 3-2=1, text starts at 3-1=2, and display starts at min(2,3-0)=2 + var start = Math.min(2, 3 - options.style.size); + for (var i = start; i < sequence.length; i++) { + if (sequence[i].type === "stack") { + // This is always the last delimiter, so we just break the loop now. + break; + } + + var metrics = getMetrics(delim, delimTypeToFont(sequence[i])); + var heightDepth = metrics.height + metrics.depth; + + // Small delimiters are scaled down versions of the same font, so we + // account for the style change size. + + if (sequence[i].type === "small") { + heightDepth *= sequence[i].style.sizeMultiplier; + } + + // Check if the delimiter at this size works for the given height. + if (heightDepth > height) { + return sequence[i]; + } + } + + // If we reached the end of the sequence, return the last sequence element. + return sequence[sequence.length - 1]; +}; + +/** + * Make a delimiter of a given height+depth, with optional centering. Here, we + * traverse the sequences, and create a delimiter that the sequence tells us to. + */ +var makeCustomSizedDelim = function(delim, height, center, options, mode) { + if (delim === "<" || delim === "\\lt") { + delim = "\\langle"; + } else if (delim === ">" || delim === "\\gt") { + delim = "\\rangle"; + } + + // Decide what sequence to use + var sequence; + if (utils.contains(stackNeverDelimiters, delim)) { + sequence = stackNeverDelimiterSequence; + } else if (utils.contains(stackLargeDelimiters, delim)) { + sequence = stackLargeDelimiterSequence; + } else { + sequence = stackAlwaysDelimiterSequence; + } + + // Look through the sequence + var delimType = traverseSequence(delim, height, sequence, options); + + // Depending on the sequence element we decided on, call the appropriate + // function. + if (delimType.type === "small") { + return makeSmallDelim(delim, delimType.style, center, options, mode); + } else if (delimType.type === "large") { + return makeLargeDelim(delim, delimType.size, center, options, mode); + } else if (delimType.type === "stack") { + return makeStackedDelim(delim, height, center, options, mode); + } +}; + +/** + * Make a delimiter for use with `\left` and `\right`, given a height and depth + * of an expression that the delimiters surround. + */ +var makeLeftRightDelim = function(delim, height, depth, options, mode) { + // We always center \left/\right delimiters, so the axis is always shifted + var axisHeight = + fontMetrics.metrics.axisHeight * options.style.sizeMultiplier; + + // Taken from TeX source, tex.web, function make_left_right + var delimiterFactor = 901; + var delimiterExtend = 5.0 / fontMetrics.metrics.ptPerEm; + + var maxDistFromAxis = Math.max( + height - axisHeight, depth + axisHeight); + + var totalHeight = Math.max( + // In real TeX, calculations are done using integral values which are + // 65536 per pt, or 655360 per em. So, the division here truncates in + // TeX but doesn't here, producing different results. If we wanted to + // exactly match TeX's calculation, we could do + // Math.floor(655360 * maxDistFromAxis / 500) * + // delimiterFactor / 655360 + // (To see the difference, compare + // x^{x^{\left(\rule{0.1em}{0.68em}\right)}} + // in TeX and KaTeX) + maxDistFromAxis / 500 * delimiterFactor, + 2 * maxDistFromAxis - delimiterExtend); + + // Finally, we defer to `makeCustomSizedDelim` with our calculated total + // height + return makeCustomSizedDelim(delim, totalHeight, true, options, mode); +}; + +module.exports = { + sizedDelim: makeSizedDelim, + customSizedDelim: makeCustomSizedDelim, + leftRightDelim: makeLeftRightDelim +}; diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/domTree.js b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/domTree.js new file mode 100644 index 0000000..f9416bf --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/domTree.js @@ -0,0 +1,269 @@ +/** + * These objects store the data about the DOM nodes we create, as well as some + * extra data. They can then be transformed into real DOM nodes with the + * `toNode` function or HTML markup using `toMarkup`. They are useful for both + * storing extra properties on the nodes, as well as providing a way to easily + * work with the DOM. + * + * Similar functions for working with MathML nodes exist in mathMLTree.js. + */ + +var utils = require("./utils"); + +/** + * Create an HTML className based on a list of classes. In addition to joining + * with spaces, we also remove null or empty classes. + */ +var createClass = function(classes) { + classes = classes.slice(); + for (var i = classes.length - 1; i >= 0; i--) { + if (!classes[i]) { + classes.splice(i, 1); + } + } + + return classes.join(" "); +}; + +/** + * This node represents a span node, with a className, a list of children, and + * an inline style. It also contains information about its height, depth, and + * maxFontSize. + */ +function span(classes, children, height, depth, maxFontSize, style) { + this.classes = classes || []; + this.children = children || []; + this.height = height || 0; + this.depth = depth || 0; + this.maxFontSize = maxFontSize || 0; + this.style = style || {}; + this.attributes = {}; +} + +/** + * Sets an arbitrary attribute on the span. Warning: use this wisely. Not all + * browsers support attributes the same, and having too many custom attributes + * is probably bad. + */ +span.prototype.setAttribute = function(attribute, value) { + this.attributes[attribute] = value; +}; + +/** + * Convert the span into an HTML node + */ +span.prototype.toNode = function() { + var span = document.createElement("span"); + + // Apply the class + span.className = createClass(this.classes); + + // Apply inline styles + for (var style in this.style) { + if (Object.prototype.hasOwnProperty.call(this.style, style)) { + span.style[style] = this.style[style]; + } + } + + // Apply attributes + for (var attr in this.attributes) { + if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) { + span.setAttribute(attr, this.attributes[attr]); + } + } + + // Append the children, also as HTML nodes + for (var i = 0; i < this.children.length; i++) { + span.appendChild(this.children[i].toNode()); + } + + return span; +}; + +/** + * Convert the span into an HTML markup string + */ +span.prototype.toMarkup = function() { + var markup = "<span"; + + // Add the class + if (this.classes.length) { + markup += " class=\""; + markup += utils.escape(createClass(this.classes)); + markup += "\""; + } + + var styles = ""; + + // Add the styles, after hyphenation + for (var style in this.style) { + if (this.style.hasOwnProperty(style)) { + styles += utils.hyphenate(style) + ":" + this.style[style] + ";"; + } + } + + if (styles) { + markup += " style=\"" + utils.escape(styles) + "\""; + } + + // Add the attributes + for (var attr in this.attributes) { + if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) { + markup += " " + attr + "=\""; + markup += utils.escape(this.attributes[attr]); + markup += "\""; + } + } + + markup += ">"; + + // Add the markup of the children, also as markup + for (var i = 0; i < this.children.length; i++) { + markup += this.children[i].toMarkup(); + } + + markup += "</span>"; + + return markup; +}; + +/** + * This node represents a document fragment, which contains elements, but when + * placed into the DOM doesn't have any representation itself. Thus, it only + * contains children and doesn't have any HTML properties. It also keeps track + * of a height, depth, and maxFontSize. + */ +function documentFragment(children, height, depth, maxFontSize) { + this.children = children || []; + this.height = height || 0; + this.depth = depth || 0; + this.maxFontSize = maxFontSize || 0; +} + +/** + * Convert the fragment into a node + */ +documentFragment.prototype.toNode = function() { + // Create a fragment + var frag = document.createDocumentFragment(); + + // Append the children + for (var i = 0; i < this.children.length; i++) { + frag.appendChild(this.children[i].toNode()); + } + + return frag; +}; + +/** + * Convert the fragment into HTML markup + */ +documentFragment.prototype.toMarkup = function() { + var markup = ""; + + // Simply concatenate the markup for the children together + for (var i = 0; i < this.children.length; i++) { + markup += this.children[i].toMarkup(); + } + + return markup; +}; + +/** + * A symbol node contains information about a single symbol. It either renders + * to a single text node, or a span with a single text node in it, depending on + * whether it has CSS classes, styles, or needs italic correction. + */ +function symbolNode(value, height, depth, italic, skew, classes, style) { + this.value = value || ""; + this.height = height || 0; + this.depth = depth || 0; + this.italic = italic || 0; + this.skew = skew || 0; + this.classes = classes || []; + this.style = style || {}; + this.maxFontSize = 0; +} + +/** + * Creates a text node or span from a symbol node. Note that a span is only + * created if it is needed. + */ +symbolNode.prototype.toNode = function() { + var node = document.createTextNode(this.value); + var span = null; + + if (this.italic > 0) { + span = document.createElement("span"); + span.style.marginRight = this.italic + "em"; + } + + if (this.classes.length > 0) { + span = span || document.createElement("span"); + span.className = createClass(this.classes); + } + + for (var style in this.style) { + if (this.style.hasOwnProperty(style)) { + span = span || document.createElement("span"); + span.style[style] = this.style[style]; + } + } + + if (span) { + span.appendChild(node); + return span; + } else { + return node; + } +}; + +/** + * Creates markup for a symbol node. + */ +symbolNode.prototype.toMarkup = function() { + // TODO(alpert): More duplication than I'd like from + // span.prototype.toMarkup and symbolNode.prototype.toNode... + var needsSpan = false; + + var markup = "<span"; + + if (this.classes.length) { + needsSpan = true; + markup += " class=\""; + markup += utils.escape(createClass(this.classes)); + markup += "\""; + } + + var styles = ""; + + if (this.italic > 0) { + styles += "margin-right:" + this.italic + "em;"; + } + for (var style in this.style) { + if (this.style.hasOwnProperty(style)) { + styles += utils.hyphenate(style) + ":" + this.style[style] + ";"; + } + } + + if (styles) { + needsSpan = true; + markup += " style=\"" + utils.escape(styles) + "\""; + } + + var escaped = utils.escape(this.value); + if (needsSpan) { + markup += ">"; + markup += escaped; + markup += "</span>"; + return markup; + } else { + return escaped; + } +}; + +module.exports = { + span: span, + documentFragment: documentFragment, + symbolNode: symbolNode +}; diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/environments.js b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/environments.js new file mode 100644 index 0000000..17b993e --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/environments.js @@ -0,0 +1,183 @@ +var fontMetrics = require("./fontMetrics"); +var parseData = require("./parseData"); +var ParseError = require("./ParseError"); + +var ParseNode = parseData.ParseNode; +var ParseResult = parseData.ParseResult; + +/** + * Parse the body of the environment, with rows delimited by \\ and + * columns delimited by &, and create a nested list in row-major order + * with one group per cell. + */ +function parseArray(parser, pos, result) { + var row = [], body = [row], rowGaps = []; + while (true) { + var cell = parser.parseExpression(pos, false, null); + row.push(new ParseNode("ordgroup", cell.result, parser.mode)); + pos = cell.position; + var next = cell.peek.text; + if (next === "&") { + pos = cell.peek.position; + } else if (next === "\\end") { + break; + } else if (next === "\\\\" || next === "\\cr") { + var cr = parser.parseFunction(pos); + rowGaps.push(cr.result.value.size); + pos = cr.position; + row = []; + body.push(row); + } else { + throw new ParseError("Expected & or \\\\ or \\end", + parser.lexer, cell.peek.position); + } + } + result.body = body; + result.rowGaps = rowGaps; + return new ParseResult( + new ParseNode(result.type, result, parser.mode), pos); +} + +/* + * An environment definition is very similar to a function definition: + * it is declared with a name or a list of names, a set of properties + * and a handler containing the actual implementation. + * + * The properties include: + * - numArgs: The number of arguments after the \begin{name} function. + * - argTypes: (optional) Just like for a function + * - allowedInText: (optional) Whether or not the environment is allowed inside + * text mode (default false) (not enforced yet) + * - numOptionalArgs: (optional) Just like for a function + * A bare number instead of that object indicates the numArgs value. + * + * The handler function will receive two arguments + * - context: information and references provided by the parser + * - args: an array of arguments passed to \begin{name} + * The context contains the following properties: + * - pos: the current position of the parser. + * - envName: the name of the environment, one of the listed names. + * - parser: the parser object + * - lexer: the lexer object + * - positions: the positions associated with these arguments from args. + * The handler must return a ParseResult. + */ + +function defineEnvironment(names, props, handler) { + if (typeof names === "string") { + names = [names]; + } + if (typeof props === "number") { + props = { numArgs: props }; + } + // Set default values of environments + var data = { + numArgs: props.numArgs || 0, + argTypes: props.argTypes, + greediness: 1, + allowedInText: !!props.allowedInText, + numOptionalArgs: props.numOptionalArgs || 0, + handler: handler + }; + for (var i = 0; i < names.length; ++i) { + module.exports[names[i]] = data; + } +} + +// Arrays are part of LaTeX, defined in lttab.dtx so its documentation +// is part of the source2e.pdf file of LaTeX2e source documentation. +defineEnvironment("array", { + numArgs: 1 +}, function(context, args) { + var colalign = args[0]; + var lexer = context.lexer; + var positions = context.positions; + colalign = colalign.value.map ? colalign.value : [colalign]; + var cols = colalign.map(function(node) { + var ca = node.value; + if ("lcr".indexOf(ca) !== -1) { + return { + type: "align", + align: ca + }; + } else if (ca === "|") { + return { + type: "separator", + separator: "|" + }; + } + throw new ParseError( + "Unknown column alignment: " + node.value, + lexer, positions[1]); + }); + var res = { + type: "array", + cols: cols, + hskipBeforeAndAfter: true // \@preamble in lttab.dtx + }; + res = parseArray(context.parser, context.pos, res); + return res; +}); + +// The matrix environments of amsmath builds on the array environment +// of LaTeX, which is discussed above. +defineEnvironment([ + "matrix", + "pmatrix", + "bmatrix", + "Bmatrix", + "vmatrix", + "Vmatrix" +], { +}, function(context) { + var delimiters = { + "matrix": null, + "pmatrix": ["(", ")"], + "bmatrix": ["[", "]"], + "Bmatrix": ["\\{", "\\}"], + "vmatrix": ["|", "|"], + "Vmatrix": ["\\Vert", "\\Vert"] + }[context.envName]; + var res = { + type: "array", + hskipBeforeAndAfter: false // \hskip -\arraycolsep in amsmath + }; + res = parseArray(context.parser, context.pos, res); + if (delimiters) { + res.result = new ParseNode("leftright", { + body: [res.result], + left: delimiters[0], + right: delimiters[1] + }, context.mode); + } + return res; +}); + +// A cases environment (in amsmath.sty) is almost equivalent to +// \def\arraystretch{1.2}% +// \left\{\begin{array}{@{}l@{\quad}l@{}} … \end{array}\right. +defineEnvironment("cases", { +}, function(context) { + var res = { + type: "array", + arraystretch: 1.2, + cols: [{ + type: "align", + align: "l", + pregap: 0, + postgap: fontMetrics.metrics.quad + }, { + type: "align", + align: "l", + pregap: 0, + postgap: 0 + }] + }; + res = parseArray(context.parser, context.pos, res); + res.result = new ParseNode("leftright", { + body: [res.result], + left: "\\{", + right: "." + }, context.mode); + return res; +}); diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/fontMetrics.js b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/fontMetrics.js new file mode 100644 index 0000000..87c337f --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/fontMetrics.js @@ -0,0 +1,147 @@ +/* jshint unused:false */ + +var Style = require("./Style"); + +/** + * This file contains metrics regarding fonts and individual symbols. The sigma + * and xi variables, as well as the metricMap map contain data extracted from + * TeX, TeX font metrics, and the TTF files. These data are then exposed via the + * `metrics` variable and the getCharacterMetrics function. + */ + +// These font metrics are extracted from TeX by using +// \font\a=cmmi10 +// \showthe\fontdimenX\a +// where X is the corresponding variable number. These correspond to the font +// parameters of the symbol fonts. In TeX, there are actually three sets of +// dimensions, one for each of textstyle, scriptstyle, and scriptscriptstyle, +// but we only use the textstyle ones, and scale certain dimensions accordingly. +// See the TeXbook, page 441. +var sigma1 = 0.025; +var sigma2 = 0; +var sigma3 = 0; +var sigma4 = 0; +var sigma5 = 0.431; +var sigma6 = 1; +var sigma7 = 0; +var sigma8 = 0.677; +var sigma9 = 0.394; +var sigma10 = 0.444; +var sigma11 = 0.686; +var sigma12 = 0.345; +var sigma13 = 0.413; +var sigma14 = 0.363; +var sigma15 = 0.289; +var sigma16 = 0.150; +var sigma17 = 0.247; +var sigma18 = 0.386; +var sigma19 = 0.050; +var sigma20 = 2.390; +var sigma21 = 1.01; +var sigma21Script = 0.81; +var sigma21ScriptScript = 0.71; +var sigma22 = 0.250; + +// These font metrics are extracted from TeX by using +// \font\a=cmex10 +// \showthe\fontdimenX\a +// where X is the corresponding variable number. These correspond to the font +// parameters of the extension fonts (family 3). See the TeXbook, page 441. +var xi1 = 0; +var xi2 = 0; +var xi3 = 0; +var xi4 = 0; +var xi5 = 0.431; +var xi6 = 1; +var xi7 = 0; +var xi8 = 0.04; +var xi9 = 0.111; +var xi10 = 0.166; +var xi11 = 0.2; +var xi12 = 0.6; +var xi13 = 0.1; + +// This value determines how large a pt is, for metrics which are defined in +// terms of pts. +// This value is also used in katex.less; if you change it make sure the values +// match. +var ptPerEm = 10.0; + +// The space between adjacent `|` columns in an array definition. From +// `\showthe\doublerulesep` in LaTeX. +var doubleRuleSep = 2.0 / ptPerEm; + +/** + * This is just a mapping from common names to real metrics + */ +var metrics = { + xHeight: sigma5, + quad: sigma6, + num1: sigma8, + num2: sigma9, + num3: sigma10, + denom1: sigma11, + denom2: sigma12, + sup1: sigma13, + sup2: sigma14, + sup3: sigma15, + sub1: sigma16, + sub2: sigma17, + supDrop: sigma18, + subDrop: sigma19, + axisHeight: sigma22, + defaultRuleThickness: xi8, + bigOpSpacing1: xi9, + bigOpSpacing2: xi10, + bigOpSpacing3: xi11, + bigOpSpacing4: xi12, + bigOpSpacing5: xi13, + ptPerEm: ptPerEm, + emPerEx: sigma5 / sigma6, + doubleRuleSep: doubleRuleSep, + + // TODO(alpert): Missing parallel structure here. We should probably add + // style-specific metrics for all of these. + delim1: sigma20, + getDelim2: function(style) { + if (style.size === Style.TEXT.size) { + return sigma21; + } else if (style.size === Style.SCRIPT.size) { + return sigma21Script; + } else if (style.size === Style.SCRIPTSCRIPT.size) { + return sigma21ScriptScript; + } + throw new Error("Unexpected style size: " + style.size); + } +}; + +// This map contains a mapping from font name and character code to character +// metrics, including height, depth, italic correction, and skew (kern from the +// character to the corresponding \skewchar) +// This map is generated via `make metrics`. It should not be changed manually. +var metricMap = require("./fontMetricsData"); + +/** + * This function is a convenience function for looking up information in the + * metricMap table. It takes a character as a string, and a style. + * + * Note: the `width` property may be undefined if fontMetricsData.js wasn't + * built using `Make extended_metrics`. + */ +var getCharacterMetrics = function(character, style) { + var metrics = metricMap[style][character.charCodeAt(0)]; + if (metrics) { + return { + depth: metrics[0], + height: metrics[1], + italic: metrics[2], + skew: metrics[3], + width: metrics[4] + }; + } +}; + +module.exports = { + metrics: metrics, + getCharacterMetrics: getCharacterMetrics +}; diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/fontMetricsData.js b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/fontMetricsData.js new file mode 100644 index 0000000..a9f9015 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/fontMetricsData.js @@ -0,0 +1,1751 @@ +module.exports = { +"AMS-Regular": { + "65": [0, 0.68889, 0, 0], + "66": [0, 0.68889, 0, 0], + "67": [0, 0.68889, 0, 0], + "68": [0, 0.68889, 0, 0], + "69": [0, 0.68889, 0, 0], + "70": [0, 0.68889, 0, 0], + "71": [0, 0.68889, 0, 0], + "72": [0, 0.68889, 0, 0], + "73": [0, 0.68889, 0, 0], + "74": [0.16667, 0.68889, 0, 0], + "75": [0, 0.68889, 0, 0], + "76": [0, 0.68889, 0, 0], + "77": [0, 0.68889, 0, 0], + "78": [0, 0.68889, 0, 0], + "79": [0.16667, 0.68889, 0, 0], + "80": [0, 0.68889, 0, 0], + "81": [0.16667, 0.68889, 0, 0], + "82": [0, 0.68889, 0, 0], + "83": [0, 0.68889, 0, 0], + "84": [0, 0.68889, 0, 0], + "85": [0, 0.68889, 0, 0], + "86": [0, 0.68889, 0, 0], + "87": [0, 0.68889, 0, 0], + "88": [0, 0.68889, 0, 0], + "89": [0, 0.68889, 0, 0], + "90": [0, 0.68889, 0, 0], + "107": [0, 0.68889, 0, 0], + "165": [0, 0.675, 0.025, 0], + "174": [0.15559, 0.69224, 0, 0], + "240": [0, 0.68889, 0, 0], + "295": [0, 0.68889, 0, 0], + "710": [0, 0.825, 0, 0], + "732": [0, 0.9, 0, 0], + "770": [0, 0.825, 0, 0], + "771": [0, 0.9, 0, 0], + "989": [0.08167, 0.58167, 0, 0], + "1008": [0, 0.43056, 0.04028, 0], + "8245": [0, 0.54986, 0, 0], + "8463": [0, 0.68889, 0, 0], + "8487": [0, 0.68889, 0, 0], + "8498": [0, 0.68889, 0, 0], + "8502": [0, 0.68889, 0, 0], + "8503": [0, 0.68889, 0, 0], + "8504": [0, 0.68889, 0, 0], + "8513": [0, 0.68889, 0, 0], + "8592": [-0.03598, 0.46402, 0, 0], + "8594": [-0.03598, 0.46402, 0, 0], + "8602": [-0.13313, 0.36687, 0, 0], + "8603": [-0.13313, 0.36687, 0, 0], + "8606": [0.01354, 0.52239, 0, 0], + "8608": [0.01354, 0.52239, 0, 0], + "8610": [0.01354, 0.52239, 0, 0], + "8611": [0.01354, 0.52239, 0, 0], + "8619": [0, 0.54986, 0, 0], + "8620": [0, 0.54986, 0, 0], + "8621": [-0.13313, 0.37788, 0, 0], + "8622": [-0.13313, 0.36687, 0, 0], + "8624": [0, 0.69224, 0, 0], + "8625": [0, 0.69224, 0, 0], + "8630": [0, 0.43056, 0, 0], + "8631": [0, 0.43056, 0, 0], + "8634": [0.08198, 0.58198, 0, 0], + "8635": [0.08198, 0.58198, 0, 0], + "8638": [0.19444, 0.69224, 0, 0], + "8639": [0.19444, 0.69224, 0, 0], + "8642": [0.19444, 0.69224, 0, 0], + "8643": [0.19444, 0.69224, 0, 0], + "8644": [0.1808, 0.675, 0, 0], + "8646": [0.1808, 0.675, 0, 0], + "8647": [0.1808, 0.675, 0, 0], + "8648": [0.19444, 0.69224, 0, 0], + "8649": [0.1808, 0.675, 0, 0], + "8650": [0.19444, 0.69224, 0, 0], + "8651": [0.01354, 0.52239, 0, 0], + "8652": [0.01354, 0.52239, 0, 0], + "8653": [-0.13313, 0.36687, 0, 0], + "8654": [-0.13313, 0.36687, 0, 0], + "8655": [-0.13313, 0.36687, 0, 0], + "8666": [0.13667, 0.63667, 0, 0], + "8667": [0.13667, 0.63667, 0, 0], + "8669": [-0.13313, 0.37788, 0, 0], + "8672": [-0.064, 0.437, 0, 0], + "8674": [-0.064, 0.437, 0, 0], + "8705": [0, 0.825, 0, 0], + "8708": [0, 0.68889, 0, 0], + "8709": [0.08167, 0.58167, 0, 0], + "8717": [0, 0.43056, 0, 0], + "8722": [-0.03598, 0.46402, 0, 0], + "8724": [0.08198, 0.69224, 0, 0], + "8726": [0.08167, 0.58167, 0, 0], + "8733": [0, 0.69224, 0, 0], + "8736": [0, 0.69224, 0, 0], + "8737": [0, 0.69224, 0, 0], + "8738": [0.03517, 0.52239, 0, 0], + "8739": [0.08167, 0.58167, 0, 0], + "8740": [0.25142, 0.74111, 0, 0], + "8741": [0.08167, 0.58167, 0, 0], + "8742": [0.25142, 0.74111, 0, 0], + "8756": [0, 0.69224, 0, 0], + "8757": [0, 0.69224, 0, 0], + "8764": [-0.13313, 0.36687, 0, 0], + "8765": [-0.13313, 0.37788, 0, 0], + "8769": [-0.13313, 0.36687, 0, 0], + "8770": [-0.03625, 0.46375, 0, 0], + "8774": [0.30274, 0.79383, 0, 0], + "8776": [-0.01688, 0.48312, 0, 0], + "8778": [0.08167, 0.58167, 0, 0], + "8782": [0.06062, 0.54986, 0, 0], + "8783": [0.06062, 0.54986, 0, 0], + "8785": [0.08198, 0.58198, 0, 0], + "8786": [0.08198, 0.58198, 0, 0], + "8787": [0.08198, 0.58198, 0, 0], + "8790": [0, 0.69224, 0, 0], + "8791": [0.22958, 0.72958, 0, 0], + "8796": [0.08198, 0.91667, 0, 0], + "8806": [0.25583, 0.75583, 0, 0], + "8807": [0.25583, 0.75583, 0, 0], + "8808": [0.25142, 0.75726, 0, 0], + "8809": [0.25142, 0.75726, 0, 0], + "8812": [0.25583, 0.75583, 0, 0], + "8814": [0.20576, 0.70576, 0, 0], + "8815": [0.20576, 0.70576, 0, 0], + "8816": [0.30274, 0.79383, 0, 0], + "8817": [0.30274, 0.79383, 0, 0], + "8818": [0.22958, 0.72958, 0, 0], + "8819": [0.22958, 0.72958, 0, 0], + "8822": [0.1808, 0.675, 0, 0], + "8823": [0.1808, 0.675, 0, 0], + "8828": [0.13667, 0.63667, 0, 0], + "8829": [0.13667, 0.63667, 0, 0], + "8830": [0.22958, 0.72958, 0, 0], + "8831": [0.22958, 0.72958, 0, 0], + "8832": [0.20576, 0.70576, 0, 0], + "8833": [0.20576, 0.70576, 0, 0], + "8840": [0.30274, 0.79383, 0, 0], + "8841": [0.30274, 0.79383, 0, 0], + "8842": [0.13597, 0.63597, 0, 0], + "8843": [0.13597, 0.63597, 0, 0], + "8847": [0.03517, 0.54986, 0, 0], + "8848": [0.03517, 0.54986, 0, 0], + "8858": [0.08198, 0.58198, 0, 0], + "8859": [0.08198, 0.58198, 0, 0], + "8861": [0.08198, 0.58198, 0, 0], + "8862": [0, 0.675, 0, 0], + "8863": [0, 0.675, 0, 0], + "8864": [0, 0.675, 0, 0], + "8865": [0, 0.675, 0, 0], + "8872": [0, 0.69224, 0, 0], + "8873": [0, 0.69224, 0, 0], + "8874": [0, 0.69224, 0, 0], + "8876": [0, 0.68889, 0, 0], + "8877": [0, 0.68889, 0, 0], + "8878": [0, 0.68889, 0, 0], + "8879": [0, 0.68889, 0, 0], + "8882": [0.03517, 0.54986, 0, 0], + "8883": [0.03517, 0.54986, 0, 0], + "8884": [0.13667, 0.63667, 0, 0], + "8885": [0.13667, 0.63667, 0, 0], + "8888": [0, 0.54986, 0, 0], + "8890": [0.19444, 0.43056, 0, 0], + "8891": [0.19444, 0.69224, 0, 0], + "8892": [0.19444, 0.69224, 0, 0], + "8901": [0, 0.54986, 0, 0], + "8903": [0.08167, 0.58167, 0, 0], + "8905": [0.08167, 0.58167, 0, 0], + "8906": [0.08167, 0.58167, 0, 0], + "8907": [0, 0.69224, 0, 0], + "8908": [0, 0.69224, 0, 0], + "8909": [-0.03598, 0.46402, 0, 0], + "8910": [0, 0.54986, 0, 0], + "8911": [0, 0.54986, 0, 0], + "8912": [0.03517, 0.54986, 0, 0], + "8913": [0.03517, 0.54986, 0, 0], + "8914": [0, 0.54986, 0, 0], + "8915": [0, 0.54986, 0, 0], + "8916": [0, 0.69224, 0, 0], + "8918": [0.0391, 0.5391, 0, 0], + "8919": [0.0391, 0.5391, 0, 0], + "8920": [0.03517, 0.54986, 0, 0], + "8921": [0.03517, 0.54986, 0, 0], + "8922": [0.38569, 0.88569, 0, 0], + "8923": [0.38569, 0.88569, 0, 0], + "8926": [0.13667, 0.63667, 0, 0], + "8927": [0.13667, 0.63667, 0, 0], + "8928": [0.30274, 0.79383, 0, 0], + "8929": [0.30274, 0.79383, 0, 0], + "8934": [0.23222, 0.74111, 0, 0], + "8935": [0.23222, 0.74111, 0, 0], + "8936": [0.23222, 0.74111, 0, 0], + "8937": [0.23222, 0.74111, 0, 0], + "8938": [0.20576, 0.70576, 0, 0], + "8939": [0.20576, 0.70576, 0, 0], + "8940": [0.30274, 0.79383, 0, 0], + "8941": [0.30274, 0.79383, 0, 0], + "8994": [0.19444, 0.69224, 0, 0], + "8995": [0.19444, 0.69224, 0, 0], + "9416": [0.15559, 0.69224, 0, 0], + "9484": [0, 0.69224, 0, 0], + "9488": [0, 0.69224, 0, 0], + "9492": [0, 0.37788, 0, 0], + "9496": [0, 0.37788, 0, 0], + "9585": [0.19444, 0.68889, 0, 0], + "9586": [0.19444, 0.74111, 0, 0], + "9632": [0, 0.675, 0, 0], + "9633": [0, 0.675, 0, 0], + "9650": [0, 0.54986, 0, 0], + "9651": [0, 0.54986, 0, 0], + "9654": [0.03517, 0.54986, 0, 0], + "9660": [0, 0.54986, 0, 0], + "9661": [0, 0.54986, 0, 0], + "9664": [0.03517, 0.54986, 0, 0], + "9674": [0.11111, 0.69224, 0, 0], + "9733": [0.19444, 0.69224, 0, 0], + "10003": [0, 0.69224, 0, 0], + "10016": [0, 0.69224, 0, 0], + "10731": [0.11111, 0.69224, 0, 0], + "10846": [0.19444, 0.75583, 0, 0], + "10877": [0.13667, 0.63667, 0, 0], + "10878": [0.13667, 0.63667, 0, 0], + "10885": [0.25583, 0.75583, 0, 0], + "10886": [0.25583, 0.75583, 0, 0], + "10887": [0.13597, 0.63597, 0, 0], + "10888": [0.13597, 0.63597, 0, 0], + "10889": [0.26167, 0.75726, 0, 0], + "10890": [0.26167, 0.75726, 0, 0], + "10891": [0.48256, 0.98256, 0, 0], + "10892": [0.48256, 0.98256, 0, 0], + "10901": [0.13667, 0.63667, 0, 0], + "10902": [0.13667, 0.63667, 0, 0], + "10933": [0.25142, 0.75726, 0, 0], + "10934": [0.25142, 0.75726, 0, 0], + "10935": [0.26167, 0.75726, 0, 0], + "10936": [0.26167, 0.75726, 0, 0], + "10937": [0.26167, 0.75726, 0, 0], + "10938": [0.26167, 0.75726, 0, 0], + "10949": [0.25583, 0.75583, 0, 0], + "10950": [0.25583, 0.75583, 0, 0], + "10955": [0.28481, 0.79383, 0, 0], + "10956": [0.28481, 0.79383, 0, 0], + "57350": [0.08167, 0.58167, 0, 0], + "57351": [0.08167, 0.58167, 0, 0], + "57352": [0.08167, 0.58167, 0, 0], + "57353": [0, 0.43056, 0.04028, 0], + "57356": [0.25142, 0.75726, 0, 0], + "57357": [0.25142, 0.75726, 0, 0], + "57358": [0.41951, 0.91951, 0, 0], + "57359": [0.30274, 0.79383, 0, 0], + "57360": [0.30274, 0.79383, 0, 0], + "57361": [0.41951, 0.91951, 0, 0], + "57366": [0.25142, 0.75726, 0, 0], + "57367": [0.25142, 0.75726, 0, 0], + "57368": [0.25142, 0.75726, 0, 0], + "57369": [0.25142, 0.75726, 0, 0], + "57370": [0.13597, 0.63597, 0, 0], + "57371": [0.13597, 0.63597, 0, 0] +}, +"Caligraphic-Regular": { + "48": [0, 0.43056, 0, 0], + "49": [0, 0.43056, 0, 0], + "50": [0, 0.43056, 0, 0], + "51": [0.19444, 0.43056, 0, 0], + "52": [0.19444, 0.43056, 0, 0], + "53": [0.19444, 0.43056, 0, 0], + "54": [0, 0.64444, 0, 0], + "55": [0.19444, 0.43056, 0, 0], + "56": [0, 0.64444, 0, 0], + "57": [0.19444, 0.43056, 0, 0], + "65": [0, 0.68333, 0, 0.19445], + "66": [0, 0.68333, 0.03041, 0.13889], + "67": [0, 0.68333, 0.05834, 0.13889], + "68": [0, 0.68333, 0.02778, 0.08334], + "69": [0, 0.68333, 0.08944, 0.11111], + "70": [0, 0.68333, 0.09931, 0.11111], + "71": [0.09722, 0.68333, 0.0593, 0.11111], + "72": [0, 0.68333, 0.00965, 0.11111], + "73": [0, 0.68333, 0.07382, 0], + "74": [0.09722, 0.68333, 0.18472, 0.16667], + "75": [0, 0.68333, 0.01445, 0.05556], + "76": [0, 0.68333, 0, 0.13889], + "77": [0, 0.68333, 0, 0.13889], + "78": [0, 0.68333, 0.14736, 0.08334], + "79": [0, 0.68333, 0.02778, 0.11111], + "80": [0, 0.68333, 0.08222, 0.08334], + "81": [0.09722, 0.68333, 0, 0.11111], + "82": [0, 0.68333, 0, 0.08334], + "83": [0, 0.68333, 0.075, 0.13889], + "84": [0, 0.68333, 0.25417, 0], + "85": [0, 0.68333, 0.09931, 0.08334], + "86": [0, 0.68333, 0.08222, 0], + "87": [0, 0.68333, 0.08222, 0.08334], + "88": [0, 0.68333, 0.14643, 0.13889], + "89": [0.09722, 0.68333, 0.08222, 0.08334], + "90": [0, 0.68333, 0.07944, 0.13889] +}, +"Fraktur-Regular": { + "33": [0, 0.69141, 0, 0], + "34": [0, 0.69141, 0, 0], + "38": [0, 0.69141, 0, 0], + "39": [0, 0.69141, 0, 0], + "40": [0.24982, 0.74947, 0, 0], + "41": [0.24982, 0.74947, 0, 0], + "42": [0, 0.62119, 0, 0], + "43": [0.08319, 0.58283, 0, 0], + "44": [0, 0.10803, 0, 0], + "45": [0.08319, 0.58283, 0, 0], + "46": [0, 0.10803, 0, 0], + "47": [0.24982, 0.74947, 0, 0], + "48": [0, 0.47534, 0, 0], + "49": [0, 0.47534, 0, 0], + "50": [0, 0.47534, 0, 0], + "51": [0.18906, 0.47534, 0, 0], + "52": [0.18906, 0.47534, 0, 0], + "53": [0.18906, 0.47534, 0, 0], + "54": [0, 0.69141, 0, 0], + "55": [0.18906, 0.47534, 0, 0], + "56": [0, 0.69141, 0, 0], + "57": [0.18906, 0.47534, 0, 0], + "58": [0, 0.47534, 0, 0], + "59": [0.12604, 0.47534, 0, 0], + "61": [-0.13099, 0.36866, 0, 0], + "63": [0, 0.69141, 0, 0], + "65": [0, 0.69141, 0, 0], + "66": [0, 0.69141, 0, 0], + "67": [0, 0.69141, 0, 0], + "68": [0, 0.69141, 0, 0], + "69": [0, 0.69141, 0, 0], + "70": [0.12604, 0.69141, 0, 0], + "71": [0, 0.69141, 0, 0], + "72": [0.06302, 0.69141, 0, 0], + "73": [0, 0.69141, 0, 0], + "74": [0.12604, 0.69141, 0, 0], + "75": [0, 0.69141, 0, 0], + "76": [0, 0.69141, 0, 0], + "77": [0, 0.69141, 0, 0], + "78": [0, 0.69141, 0, 0], + "79": [0, 0.69141, 0, 0], + "80": [0.18906, 0.69141, 0, 0], + "81": [0.03781, 0.69141, 0, 0], + "82": [0, 0.69141, 0, 0], + "83": [0, 0.69141, 0, 0], + "84": [0, 0.69141, 0, 0], + "85": [0, 0.69141, 0, 0], + "86": [0, 0.69141, 0, 0], + "87": [0, 0.69141, 0, 0], + "88": [0, 0.69141, 0, 0], + "89": [0.18906, 0.69141, 0, 0], + "90": [0.12604, 0.69141, 0, 0], + "91": [0.24982, 0.74947, 0, 0], + "93": [0.24982, 0.74947, 0, 0], + "94": [0, 0.69141, 0, 0], + "97": [0, 0.47534, 0, 0], + "98": [0, 0.69141, 0, 0], + "99": [0, 0.47534, 0, 0], + "100": [0, 0.62119, 0, 0], + "101": [0, 0.47534, 0, 0], + "102": [0.18906, 0.69141, 0, 0], + "103": [0.18906, 0.47534, 0, 0], + "104": [0.18906, 0.69141, 0, 0], + "105": [0, 0.69141, 0, 0], + "106": [0, 0.69141, 0, 0], + "107": [0, 0.69141, 0, 0], + "108": [0, 0.69141, 0, 0], + "109": [0, 0.47534, 0, 0], + "110": [0, 0.47534, 0, 0], + "111": [0, 0.47534, 0, 0], + "112": [0.18906, 0.52396, 0, 0], + "113": [0.18906, 0.47534, 0, 0], + "114": [0, 0.47534, 0, 0], + "115": [0, 0.47534, 0, 0], + "116": [0, 0.62119, 0, 0], + "117": [0, 0.47534, 0, 0], + "118": [0, 0.52396, 0, 0], + "119": [0, 0.52396, 0, 0], + "120": [0.18906, 0.47534, 0, 0], + "121": [0.18906, 0.47534, 0, 0], + "122": [0.18906, 0.47534, 0, 0], + "8216": [0, 0.69141, 0, 0], + "8217": [0, 0.69141, 0, 0], + "58112": [0, 0.62119, 0, 0], + "58113": [0, 0.62119, 0, 0], + "58114": [0.18906, 0.69141, 0, 0], + "58115": [0.18906, 0.69141, 0, 0], + "58116": [0.18906, 0.47534, 0, 0], + "58117": [0, 0.69141, 0, 0], + "58118": [0, 0.62119, 0, 0], + "58119": [0, 0.47534, 0, 0] +}, +"Main-Bold": { + "33": [0, 0.69444, 0, 0], + "34": [0, 0.69444, 0, 0], + "35": [0.19444, 0.69444, 0, 0], + "36": [0.05556, 0.75, 0, 0], + "37": [0.05556, 0.75, 0, 0], + "38": [0, 0.69444, 0, 0], + "39": [0, 0.69444, 0, 0], + "40": [0.25, 0.75, 0, 0], + "41": [0.25, 0.75, 0, 0], + "42": [0, 0.75, 0, 0], + "43": [0.13333, 0.63333, 0, 0], + "44": [0.19444, 0.15556, 0, 0], + "45": [0, 0.44444, 0, 0], + "46": [0, 0.15556, 0, 0], + "47": [0.25, 0.75, 0, 0], + "48": [0, 0.64444, 0, 0], + "49": [0, 0.64444, 0, 0], + "50": [0, 0.64444, 0, 0], + "51": [0, 0.64444, 0, 0], + "52": [0, 0.64444, 0, 0], + "53": [0, 0.64444, 0, 0], + "54": [0, 0.64444, 0, 0], + "55": [0, 0.64444, 0, 0], + "56": [0, 0.64444, 0, 0], + "57": [0, 0.64444, 0, 0], + "58": [0, 0.44444, 0, 0], + "59": [0.19444, 0.44444, 0, 0], + "60": [0.08556, 0.58556, 0, 0], + "61": [-0.10889, 0.39111, 0, 0], + "62": [0.08556, 0.58556, 0, 0], + "63": [0, 0.69444, 0, 0], + "64": [0, 0.69444, 0, 0], + "65": [0, 0.68611, 0, 0], + "66": [0, 0.68611, 0, 0], + "67": [0, 0.68611, 0, 0], + "68": [0, 0.68611, 0, 0], + "69": [0, 0.68611, 0, 0], + "70": [0, 0.68611, 0, 0], + "71": [0, 0.68611, 0, 0], + "72": [0, 0.68611, 0, 0], + "73": [0, 0.68611, 0, 0], + "74": [0, 0.68611, 0, 0], + "75": [0, 0.68611, 0, 0], + "76": [0, 0.68611, 0, 0], + "77": [0, 0.68611, 0, 0], + "78": [0, 0.68611, 0, 0], + "79": [0, 0.68611, 0, 0], + "80": [0, 0.68611, 0, 0], + "81": [0.19444, 0.68611, 0, 0], + "82": [0, 0.68611, 0, 0], + "83": [0, 0.68611, 0, 0], + "84": [0, 0.68611, 0, 0], + "85": [0, 0.68611, 0, 0], + "86": [0, 0.68611, 0.01597, 0], + "87": [0, 0.68611, 0.01597, 0], + "88": [0, 0.68611, 0, 0], + "89": [0, 0.68611, 0.02875, 0], + "90": [0, 0.68611, 0, 0], + "91": [0.25, 0.75, 0, 0], + "92": [0.25, 0.75, 0, 0], + "93": [0.25, 0.75, 0, 0], + "94": [0, 0.69444, 0, 0], + "95": [0.31, 0.13444, 0.03194, 0], + "96": [0, 0.69444, 0, 0], + "97": [0, 0.44444, 0, 0], + "98": [0, 0.69444, 0, 0], + "99": [0, 0.44444, 0, 0], + "100": [0, 0.69444, 0, 0], + "101": [0, 0.44444, 0, 0], + "102": [0, 0.69444, 0.10903, 0], + "103": [0.19444, 0.44444, 0.01597, 0], + "104": [0, 0.69444, 0, 0], + "105": [0, 0.69444, 0, 0], + "106": [0.19444, 0.69444, 0, 0], + "107": [0, 0.69444, 0, 0], + "108": [0, 0.69444, 0, 0], + "109": [0, 0.44444, 0, 0], + "110": [0, 0.44444, 0, 0], + "111": [0, 0.44444, 0, 0], + "112": [0.19444, 0.44444, 0, 0], + "113": [0.19444, 0.44444, 0, 0], + "114": [0, 0.44444, 0, 0], + "115": [0, 0.44444, 0, 0], + "116": [0, 0.63492, 0, 0], + "117": [0, 0.44444, 0, 0], + "118": [0, 0.44444, 0.01597, 0], + "119": [0, 0.44444, 0.01597, 0], + "120": [0, 0.44444, 0, 0], + "121": [0.19444, 0.44444, 0.01597, 0], + "122": [0, 0.44444, 0, 0], + "123": [0.25, 0.75, 0, 0], + "124": [0.25, 0.75, 0, 0], + "125": [0.25, 0.75, 0, 0], + "126": [0.35, 0.34444, 0, 0], + "168": [0, 0.69444, 0, 0], + "172": [0, 0.44444, 0, 0], + "175": [0, 0.59611, 0, 0], + "176": [0, 0.69444, 0, 0], + "177": [0.13333, 0.63333, 0, 0], + "180": [0, 0.69444, 0, 0], + "215": [0.13333, 0.63333, 0, 0], + "247": [0.13333, 0.63333, 0, 0], + "305": [0, 0.44444, 0, 0], + "567": [0.19444, 0.44444, 0, 0], + "710": [0, 0.69444, 0, 0], + "711": [0, 0.63194, 0, 0], + "713": [0, 0.59611, 0, 0], + "714": [0, 0.69444, 0, 0], + "715": [0, 0.69444, 0, 0], + "728": [0, 0.69444, 0, 0], + "729": [0, 0.69444, 0, 0], + "730": [0, 0.69444, 0, 0], + "732": [0, 0.69444, 0, 0], + "768": [0, 0.69444, 0, 0], + "769": [0, 0.69444, 0, 0], + "770": [0, 0.69444, 0, 0], + "771": [0, 0.69444, 0, 0], + "772": [0, 0.59611, 0, 0], + "774": [0, 0.69444, 0, 0], + "775": [0, 0.69444, 0, 0], + "776": [0, 0.69444, 0, 0], + "778": [0, 0.69444, 0, 0], + "779": [0, 0.69444, 0, 0], + "780": [0, 0.63194, 0, 0], + "824": [0.19444, 0.69444, 0, 0], + "915": [0, 0.68611, 0, 0], + "916": [0, 0.68611, 0, 0], + "920": [0, 0.68611, 0, 0], + "923": [0, 0.68611, 0, 0], + "926": [0, 0.68611, 0, 0], + "928": [0, 0.68611, 0, 0], + "931": [0, 0.68611, 0, 0], + "933": [0, 0.68611, 0, 0], + "934": [0, 0.68611, 0, 0], + "936": [0, 0.68611, 0, 0], + "937": [0, 0.68611, 0, 0], + "8211": [0, 0.44444, 0.03194, 0], + "8212": [0, 0.44444, 0.03194, 0], + "8216": [0, 0.69444, 0, 0], + "8217": [0, 0.69444, 0, 0], + "8220": [0, 0.69444, 0, 0], + "8221": [0, 0.69444, 0, 0], + "8224": [0.19444, 0.69444, 0, 0], + "8225": [0.19444, 0.69444, 0, 0], + "8242": [0, 0.55556, 0, 0], + "8407": [0, 0.72444, 0.15486, 0], + "8463": [0, 0.69444, 0, 0], + "8465": [0, 0.69444, 0, 0], + "8467": [0, 0.69444, 0, 0], + "8472": [0.19444, 0.44444, 0, 0], + "8476": [0, 0.69444, 0, 0], + "8501": [0, 0.69444, 0, 0], + "8592": [-0.10889, 0.39111, 0, 0], + "8593": [0.19444, 0.69444, 0, 0], + "8594": [-0.10889, 0.39111, 0, 0], + "8595": [0.19444, 0.69444, 0, 0], + "8596": [-0.10889, 0.39111, 0, 0], + "8597": [0.25, 0.75, 0, 0], + "8598": [0.19444, 0.69444, 0, 0], + "8599": [0.19444, 0.69444, 0, 0], + "8600": [0.19444, 0.69444, 0, 0], + "8601": [0.19444, 0.69444, 0, 0], + "8636": [-0.10889, 0.39111, 0, 0], + "8637": [-0.10889, 0.39111, 0, 0], + "8640": [-0.10889, 0.39111, 0, 0], + "8641": [-0.10889, 0.39111, 0, 0], + "8656": [-0.10889, 0.39111, 0, 0], + "8657": [0.19444, 0.69444, 0, 0], + "8658": [-0.10889, 0.39111, 0, 0], + "8659": [0.19444, 0.69444, 0, 0], + "8660": [-0.10889, 0.39111, 0, 0], + "8661": [0.25, 0.75, 0, 0], + "8704": [0, 0.69444, 0, 0], + "8706": [0, 0.69444, 0.06389, 0], + "8707": [0, 0.69444, 0, 0], + "8709": [0.05556, 0.75, 0, 0], + "8711": [0, 0.68611, 0, 0], + "8712": [0.08556, 0.58556, 0, 0], + "8715": [0.08556, 0.58556, 0, 0], + "8722": [0.13333, 0.63333, 0, 0], + "8723": [0.13333, 0.63333, 0, 0], + "8725": [0.25, 0.75, 0, 0], + "8726": [0.25, 0.75, 0, 0], + "8727": [-0.02778, 0.47222, 0, 0], + "8728": [-0.02639, 0.47361, 0, 0], + "8729": [-0.02639, 0.47361, 0, 0], + "8730": [0.18, 0.82, 0, 0], + "8733": [0, 0.44444, 0, 0], + "8734": [0, 0.44444, 0, 0], + "8736": [0, 0.69224, 0, 0], + "8739": [0.25, 0.75, 0, 0], + "8741": [0.25, 0.75, 0, 0], + "8743": [0, 0.55556, 0, 0], + "8744": [0, 0.55556, 0, 0], + "8745": [0, 0.55556, 0, 0], + "8746": [0, 0.55556, 0, 0], + "8747": [0.19444, 0.69444, 0.12778, 0], + "8764": [-0.10889, 0.39111, 0, 0], + "8768": [0.19444, 0.69444, 0, 0], + "8771": [0.00222, 0.50222, 0, 0], + "8776": [0.02444, 0.52444, 0, 0], + "8781": [0.00222, 0.50222, 0, 0], + "8801": [0.00222, 0.50222, 0, 0], + "8804": [0.19667, 0.69667, 0, 0], + "8805": [0.19667, 0.69667, 0, 0], + "8810": [0.08556, 0.58556, 0, 0], + "8811": [0.08556, 0.58556, 0, 0], + "8826": [0.08556, 0.58556, 0, 0], + "8827": [0.08556, 0.58556, 0, 0], + "8834": [0.08556, 0.58556, 0, 0], + "8835": [0.08556, 0.58556, 0, 0], + "8838": [0.19667, 0.69667, 0, 0], + "8839": [0.19667, 0.69667, 0, 0], + "8846": [0, 0.55556, 0, 0], + "8849": [0.19667, 0.69667, 0, 0], + "8850": [0.19667, 0.69667, 0, 0], + "8851": [0, 0.55556, 0, 0], + "8852": [0, 0.55556, 0, 0], + "8853": [0.13333, 0.63333, 0, 0], + "8854": [0.13333, 0.63333, 0, 0], + "8855": [0.13333, 0.63333, 0, 0], + "8856": [0.13333, 0.63333, 0, 0], + "8857": [0.13333, 0.63333, 0, 0], + "8866": [0, 0.69444, 0, 0], + "8867": [0, 0.69444, 0, 0], + "8868": [0, 0.69444, 0, 0], + "8869": [0, 0.69444, 0, 0], + "8900": [-0.02639, 0.47361, 0, 0], + "8901": [-0.02639, 0.47361, 0, 0], + "8902": [-0.02778, 0.47222, 0, 0], + "8968": [0.25, 0.75, 0, 0], + "8969": [0.25, 0.75, 0, 0], + "8970": [0.25, 0.75, 0, 0], + "8971": [0.25, 0.75, 0, 0], + "8994": [-0.13889, 0.36111, 0, 0], + "8995": [-0.13889, 0.36111, 0, 0], + "9651": [0.19444, 0.69444, 0, 0], + "9657": [-0.02778, 0.47222, 0, 0], + "9661": [0.19444, 0.69444, 0, 0], + "9667": [-0.02778, 0.47222, 0, 0], + "9711": [0.19444, 0.69444, 0, 0], + "9824": [0.12963, 0.69444, 0, 0], + "9825": [0.12963, 0.69444, 0, 0], + "9826": [0.12963, 0.69444, 0, 0], + "9827": [0.12963, 0.69444, 0, 0], + "9837": [0, 0.75, 0, 0], + "9838": [0.19444, 0.69444, 0, 0], + "9839": [0.19444, 0.69444, 0, 0], + "10216": [0.25, 0.75, 0, 0], + "10217": [0.25, 0.75, 0, 0], + "10815": [0, 0.68611, 0, 0], + "10927": [0.19667, 0.69667, 0, 0], + "10928": [0.19667, 0.69667, 0, 0] +}, +"Main-Italic": { + "33": [0, 0.69444, 0.12417, 0], + "34": [0, 0.69444, 0.06961, 0], + "35": [0.19444, 0.69444, 0.06616, 0], + "37": [0.05556, 0.75, 0.13639, 0], + "38": [0, 0.69444, 0.09694, 0], + "39": [0, 0.69444, 0.12417, 0], + "40": [0.25, 0.75, 0.16194, 0], + "41": [0.25, 0.75, 0.03694, 0], + "42": [0, 0.75, 0.14917, 0], + "43": [0.05667, 0.56167, 0.03694, 0], + "44": [0.19444, 0.10556, 0, 0], + "45": [0, 0.43056, 0.02826, 0], + "46": [0, 0.10556, 0, 0], + "47": [0.25, 0.75, 0.16194, 0], + "48": [0, 0.64444, 0.13556, 0], + "49": [0, 0.64444, 0.13556, 0], + "50": [0, 0.64444, 0.13556, 0], + "51": [0, 0.64444, 0.13556, 0], + "52": [0.19444, 0.64444, 0.13556, 0], + "53": [0, 0.64444, 0.13556, 0], + "54": [0, 0.64444, 0.13556, 0], + "55": [0.19444, 0.64444, 0.13556, 0], + "56": [0, 0.64444, 0.13556, 0], + "57": [0, 0.64444, 0.13556, 0], + "58": [0, 0.43056, 0.0582, 0], + "59": [0.19444, 0.43056, 0.0582, 0], + "61": [-0.13313, 0.36687, 0.06616, 0], + "63": [0, 0.69444, 0.1225, 0], + "64": [0, 0.69444, 0.09597, 0], + "65": [0, 0.68333, 0, 0], + "66": [0, 0.68333, 0.10257, 0], + "67": [0, 0.68333, 0.14528, 0], + "68": [0, 0.68333, 0.09403, 0], + "69": [0, 0.68333, 0.12028, 0], + "70": [0, 0.68333, 0.13305, 0], + "71": [0, 0.68333, 0.08722, 0], + "72": [0, 0.68333, 0.16389, 0], + "73": [0, 0.68333, 0.15806, 0], + "74": [0, 0.68333, 0.14028, 0], + "75": [0, 0.68333, 0.14528, 0], + "76": [0, 0.68333, 0, 0], + "77": [0, 0.68333, 0.16389, 0], + "78": [0, 0.68333, 0.16389, 0], + "79": [0, 0.68333, 0.09403, 0], + "80": [0, 0.68333, 0.10257, 0], + "81": [0.19444, 0.68333, 0.09403, 0], + "82": [0, 0.68333, 0.03868, 0], + "83": [0, 0.68333, 0.11972, 0], + "84": [0, 0.68333, 0.13305, 0], + "85": [0, 0.68333, 0.16389, 0], + "86": [0, 0.68333, 0.18361, 0], + "87": [0, 0.68333, 0.18361, 0], + "88": [0, 0.68333, 0.15806, 0], + "89": [0, 0.68333, 0.19383, 0], + "90": [0, 0.68333, 0.14528, 0], + "91": [0.25, 0.75, 0.1875, 0], + "93": [0.25, 0.75, 0.10528, 0], + "94": [0, 0.69444, 0.06646, 0], + "95": [0.31, 0.12056, 0.09208, 0], + "97": [0, 0.43056, 0.07671, 0], + "98": [0, 0.69444, 0.06312, 0], + "99": [0, 0.43056, 0.05653, 0], + "100": [0, 0.69444, 0.10333, 0], + "101": [0, 0.43056, 0.07514, 0], + "102": [0.19444, 0.69444, 0.21194, 0], + "103": [0.19444, 0.43056, 0.08847, 0], + "104": [0, 0.69444, 0.07671, 0], + "105": [0, 0.65536, 0.1019, 0], + "106": [0.19444, 0.65536, 0.14467, 0], + "107": [0, 0.69444, 0.10764, 0], + "108": [0, 0.69444, 0.10333, 0], + "109": [0, 0.43056, 0.07671, 0], + "110": [0, 0.43056, 0.07671, 0], + "111": [0, 0.43056, 0.06312, 0], + "112": [0.19444, 0.43056, 0.06312, 0], + "113": [0.19444, 0.43056, 0.08847, 0], + "114": [0, 0.43056, 0.10764, 0], + "115": [0, 0.43056, 0.08208, 0], + "116": [0, 0.61508, 0.09486, 0], + "117": [0, 0.43056, 0.07671, 0], + "118": [0, 0.43056, 0.10764, 0], + "119": [0, 0.43056, 0.10764, 0], + "120": [0, 0.43056, 0.12042, 0], + "121": [0.19444, 0.43056, 0.08847, 0], + "122": [0, 0.43056, 0.12292, 0], + "126": [0.35, 0.31786, 0.11585, 0], + "163": [0, 0.69444, 0, 0], + "305": [0, 0.43056, 0, 0.02778], + "567": [0.19444, 0.43056, 0, 0.08334], + "768": [0, 0.69444, 0, 0], + "769": [0, 0.69444, 0.09694, 0], + "770": [0, 0.69444, 0.06646, 0], + "771": [0, 0.66786, 0.11585, 0], + "772": [0, 0.56167, 0.10333, 0], + "774": [0, 0.69444, 0.10806, 0], + "775": [0, 0.66786, 0.11752, 0], + "776": [0, 0.66786, 0.10474, 0], + "778": [0, 0.69444, 0, 0], + "779": [0, 0.69444, 0.1225, 0], + "780": [0, 0.62847, 0.08295, 0], + "915": [0, 0.68333, 0.13305, 0], + "916": [0, 0.68333, 0, 0], + "920": [0, 0.68333, 0.09403, 0], + "923": [0, 0.68333, 0, 0], + "926": [0, 0.68333, 0.15294, 0], + "928": [0, 0.68333, 0.16389, 0], + "931": [0, 0.68333, 0.12028, 0], + "933": [0, 0.68333, 0.11111, 0], + "934": [0, 0.68333, 0.05986, 0], + "936": [0, 0.68333, 0.11111, 0], + "937": [0, 0.68333, 0.10257, 0], + "8211": [0, 0.43056, 0.09208, 0], + "8212": [0, 0.43056, 0.09208, 0], + "8216": [0, 0.69444, 0.12417, 0], + "8217": [0, 0.69444, 0.12417, 0], + "8220": [0, 0.69444, 0.1685, 0], + "8221": [0, 0.69444, 0.06961, 0], + "8463": [0, 0.68889, 0, 0] +}, +"Main-Regular": { + "32": [0, 0, 0, 0], + "33": [0, 0.69444, 0, 0], + "34": [0, 0.69444, 0, 0], + "35": [0.19444, 0.69444, 0, 0], + "36": [0.05556, 0.75, 0, 0], + "37": [0.05556, 0.75, 0, 0], + "38": [0, 0.69444, 0, 0], + "39": [0, 0.69444, 0, 0], + "40": [0.25, 0.75, 0, 0], + "41": [0.25, 0.75, 0, 0], + "42": [0, 0.75, 0, 0], + "43": [0.08333, 0.58333, 0, 0], + "44": [0.19444, 0.10556, 0, 0], + "45": [0, 0.43056, 0, 0], + "46": [0, 0.10556, 0, 0], + "47": [0.25, 0.75, 0, 0], + "48": [0, 0.64444, 0, 0], + "49": [0, 0.64444, 0, 0], + "50": [0, 0.64444, 0, 0], + "51": [0, 0.64444, 0, 0], + "52": [0, 0.64444, 0, 0], + "53": [0, 0.64444, 0, 0], + "54": [0, 0.64444, 0, 0], + "55": [0, 0.64444, 0, 0], + "56": [0, 0.64444, 0, 0], + "57": [0, 0.64444, 0, 0], + "58": [0, 0.43056, 0, 0], + "59": [0.19444, 0.43056, 0, 0], + "60": [0.0391, 0.5391, 0, 0], + "61": [-0.13313, 0.36687, 0, 0], + "62": [0.0391, 0.5391, 0, 0], + "63": [0, 0.69444, 0, 0], + "64": [0, 0.69444, 0, 0], + "65": [0, 0.68333, 0, 0], + "66": [0, 0.68333, 0, 0], + "67": [0, 0.68333, 0, 0], + "68": [0, 0.68333, 0, 0], + "69": [0, 0.68333, 0, 0], + "70": [0, 0.68333, 0, 0], + "71": [0, 0.68333, 0, 0], + "72": [0, 0.68333, 0, 0], + "73": [0, 0.68333, 0, 0], + "74": [0, 0.68333, 0, 0], + "75": [0, 0.68333, 0, 0], + "76": [0, 0.68333, 0, 0], + "77": [0, 0.68333, 0, 0], + "78": [0, 0.68333, 0, 0], + "79": [0, 0.68333, 0, 0], + "80": [0, 0.68333, 0, 0], + "81": [0.19444, 0.68333, 0, 0], + "82": [0, 0.68333, 0, 0], + "83": [0, 0.68333, 0, 0], + "84": [0, 0.68333, 0, 0], + "85": [0, 0.68333, 0, 0], + "86": [0, 0.68333, 0.01389, 0], + "87": [0, 0.68333, 0.01389, 0], + "88": [0, 0.68333, 0, 0], + "89": [0, 0.68333, 0.025, 0], + "90": [0, 0.68333, 0, 0], + "91": [0.25, 0.75, 0, 0], + "92": [0.25, 0.75, 0, 0], + "93": [0.25, 0.75, 0, 0], + "94": [0, 0.69444, 0, 0], + "95": [0.31, 0.12056, 0.02778, 0], + "96": [0, 0.69444, 0, 0], + "97": [0, 0.43056, 0, 0], + "98": [0, 0.69444, 0, 0], + "99": [0, 0.43056, 0, 0], + "100": [0, 0.69444, 0, 0], + "101": [0, 0.43056, 0, 0], + "102": [0, 0.69444, 0.07778, 0], + "103": [0.19444, 0.43056, 0.01389, 0], + "104": [0, 0.69444, 0, 0], + "105": [0, 0.66786, 0, 0], + "106": [0.19444, 0.66786, 0, 0], + "107": [0, 0.69444, 0, 0], + "108": [0, 0.69444, 0, 0], + "109": [0, 0.43056, 0, 0], + "110": [0, 0.43056, 0, 0], + "111": [0, 0.43056, 0, 0], + "112": [0.19444, 0.43056, 0, 0], + "113": [0.19444, 0.43056, 0, 0], + "114": [0, 0.43056, 0, 0], + "115": [0, 0.43056, 0, 0], + "116": [0, 0.61508, 0, 0], + "117": [0, 0.43056, 0, 0], + "118": [0, 0.43056, 0.01389, 0], + "119": [0, 0.43056, 0.01389, 0], + "120": [0, 0.43056, 0, 0], + "121": [0.19444, 0.43056, 0.01389, 0], + "122": [0, 0.43056, 0, 0], + "123": [0.25, 0.75, 0, 0], + "124": [0.25, 0.75, 0, 0], + "125": [0.25, 0.75, 0, 0], + "126": [0.35, 0.31786, 0, 0], + "160": [0, 0, 0, 0], + "168": [0, 0.66786, 0, 0], + "172": [0, 0.43056, 0, 0], + "175": [0, 0.56778, 0, 0], + "176": [0, 0.69444, 0, 0], + "177": [0.08333, 0.58333, 0, 0], + "180": [0, 0.69444, 0, 0], + "215": [0.08333, 0.58333, 0, 0], + "247": [0.08333, 0.58333, 0, 0], + "305": [0, 0.43056, 0, 0], + "567": [0.19444, 0.43056, 0, 0], + "710": [0, 0.69444, 0, 0], + "711": [0, 0.62847, 0, 0], + "713": [0, 0.56778, 0, 0], + "714": [0, 0.69444, 0, 0], + "715": [0, 0.69444, 0, 0], + "728": [0, 0.69444, 0, 0], + "729": [0, 0.66786, 0, 0], + "730": [0, 0.69444, 0, 0], + "732": [0, 0.66786, 0, 0], + "768": [0, 0.69444, 0, 0], + "769": [0, 0.69444, 0, 0], + "770": [0, 0.69444, 0, 0], + "771": [0, 0.66786, 0, 0], + "772": [0, 0.56778, 0, 0], + "774": [0, 0.69444, 0, 0], + "775": [0, 0.66786, 0, 0], + "776": [0, 0.66786, 0, 0], + "778": [0, 0.69444, 0, 0], + "779": [0, 0.69444, 0, 0], + "780": [0, 0.62847, 0, 0], + "824": [0.19444, 0.69444, 0, 0], + "915": [0, 0.68333, 0, 0], + "916": [0, 0.68333, 0, 0], + "920": [0, 0.68333, 0, 0], + "923": [0, 0.68333, 0, 0], + "926": [0, 0.68333, 0, 0], + "928": [0, 0.68333, 0, 0], + "931": [0, 0.68333, 0, 0], + "933": [0, 0.68333, 0, 0], + "934": [0, 0.68333, 0, 0], + "936": [0, 0.68333, 0, 0], + "937": [0, 0.68333, 0, 0], + "8211": [0, 0.43056, 0.02778, 0], + "8212": [0, 0.43056, 0.02778, 0], + "8216": [0, 0.69444, 0, 0], + "8217": [0, 0.69444, 0, 0], + "8220": [0, 0.69444, 0, 0], + "8221": [0, 0.69444, 0, 0], + "8224": [0.19444, 0.69444, 0, 0], + "8225": [0.19444, 0.69444, 0, 0], + "8230": [0, 0.12, 0, 0], + "8242": [0, 0.55556, 0, 0], + "8407": [0, 0.71444, 0.15382, 0], + "8463": [0, 0.68889, 0, 0], + "8465": [0, 0.69444, 0, 0], + "8467": [0, 0.69444, 0, 0.11111], + "8472": [0.19444, 0.43056, 0, 0.11111], + "8476": [0, 0.69444, 0, 0], + "8501": [0, 0.69444, 0, 0], + "8592": [-0.13313, 0.36687, 0, 0], + "8593": [0.19444, 0.69444, 0, 0], + "8594": [-0.13313, 0.36687, 0, 0], + "8595": [0.19444, 0.69444, 0, 0], + "8596": [-0.13313, 0.36687, 0, 0], + "8597": [0.25, 0.75, 0, 0], + "8598": [0.19444, 0.69444, 0, 0], + "8599": [0.19444, 0.69444, 0, 0], + "8600": [0.19444, 0.69444, 0, 0], + "8601": [0.19444, 0.69444, 0, 0], + "8614": [0.011, 0.511, 0, 0], + "8617": [0.011, 0.511, 0, 0], + "8618": [0.011, 0.511, 0, 0], + "8636": [-0.13313, 0.36687, 0, 0], + "8637": [-0.13313, 0.36687, 0, 0], + "8640": [-0.13313, 0.36687, 0, 0], + "8641": [-0.13313, 0.36687, 0, 0], + "8652": [0.011, 0.671, 0, 0], + "8656": [-0.13313, 0.36687, 0, 0], + "8657": [0.19444, 0.69444, 0, 0], + "8658": [-0.13313, 0.36687, 0, 0], + "8659": [0.19444, 0.69444, 0, 0], + "8660": [-0.13313, 0.36687, 0, 0], + "8661": [0.25, 0.75, 0, 0], + "8704": [0, 0.69444, 0, 0], + "8706": [0, 0.69444, 0.05556, 0.08334], + "8707": [0, 0.69444, 0, 0], + "8709": [0.05556, 0.75, 0, 0], + "8711": [0, 0.68333, 0, 0], + "8712": [0.0391, 0.5391, 0, 0], + "8715": [0.0391, 0.5391, 0, 0], + "8722": [0.08333, 0.58333, 0, 0], + "8723": [0.08333, 0.58333, 0, 0], + "8725": [0.25, 0.75, 0, 0], + "8726": [0.25, 0.75, 0, 0], + "8727": [-0.03472, 0.46528, 0, 0], + "8728": [-0.05555, 0.44445, 0, 0], + "8729": [-0.05555, 0.44445, 0, 0], + "8730": [0.2, 0.8, 0, 0], + "8733": [0, 0.43056, 0, 0], + "8734": [0, 0.43056, 0, 0], + "8736": [0, 0.69224, 0, 0], + "8739": [0.25, 0.75, 0, 0], + "8741": [0.25, 0.75, 0, 0], + "8743": [0, 0.55556, 0, 0], + "8744": [0, 0.55556, 0, 0], + "8745": [0, 0.55556, 0, 0], + "8746": [0, 0.55556, 0, 0], + "8747": [0.19444, 0.69444, 0.11111, 0], + "8764": [-0.13313, 0.36687, 0, 0], + "8768": [0.19444, 0.69444, 0, 0], + "8771": [-0.03625, 0.46375, 0, 0], + "8773": [-0.022, 0.589, 0, 0], + "8776": [-0.01688, 0.48312, 0, 0], + "8781": [-0.03625, 0.46375, 0, 0], + "8784": [-0.133, 0.67, 0, 0], + "8800": [0.215, 0.716, 0, 0], + "8801": [-0.03625, 0.46375, 0, 0], + "8804": [0.13597, 0.63597, 0, 0], + "8805": [0.13597, 0.63597, 0, 0], + "8810": [0.0391, 0.5391, 0, 0], + "8811": [0.0391, 0.5391, 0, 0], + "8826": [0.0391, 0.5391, 0, 0], + "8827": [0.0391, 0.5391, 0, 0], + "8834": [0.0391, 0.5391, 0, 0], + "8835": [0.0391, 0.5391, 0, 0], + "8838": [0.13597, 0.63597, 0, 0], + "8839": [0.13597, 0.63597, 0, 0], + "8846": [0, 0.55556, 0, 0], + "8849": [0.13597, 0.63597, 0, 0], + "8850": [0.13597, 0.63597, 0, 0], + "8851": [0, 0.55556, 0, 0], + "8852": [0, 0.55556, 0, 0], + "8853": [0.08333, 0.58333, 0, 0], + "8854": [0.08333, 0.58333, 0, 0], + "8855": [0.08333, 0.58333, 0, 0], + "8856": [0.08333, 0.58333, 0, 0], + "8857": [0.08333, 0.58333, 0, 0], + "8866": [0, 0.69444, 0, 0], + "8867": [0, 0.69444, 0, 0], + "8868": [0, 0.69444, 0, 0], + "8869": [0, 0.69444, 0, 0], + "8872": [0.249, 0.75, 0, 0], + "8900": [-0.05555, 0.44445, 0, 0], + "8901": [-0.05555, 0.44445, 0, 0], + "8902": [-0.03472, 0.46528, 0, 0], + "8904": [0.005, 0.505, 0, 0], + "8942": [0.03, 0.9, 0, 0], + "8943": [-0.19, 0.31, 0, 0], + "8945": [-0.1, 0.82, 0, 0], + "8968": [0.25, 0.75, 0, 0], + "8969": [0.25, 0.75, 0, 0], + "8970": [0.25, 0.75, 0, 0], + "8971": [0.25, 0.75, 0, 0], + "8994": [-0.14236, 0.35764, 0, 0], + "8995": [-0.14236, 0.35764, 0, 0], + "9136": [0.244, 0.744, 0, 0], + "9137": [0.244, 0.744, 0, 0], + "9651": [0.19444, 0.69444, 0, 0], + "9657": [-0.03472, 0.46528, 0, 0], + "9661": [0.19444, 0.69444, 0, 0], + "9667": [-0.03472, 0.46528, 0, 0], + "9711": [0.19444, 0.69444, 0, 0], + "9824": [0.12963, 0.69444, 0, 0], + "9825": [0.12963, 0.69444, 0, 0], + "9826": [0.12963, 0.69444, 0, 0], + "9827": [0.12963, 0.69444, 0, 0], + "9837": [0, 0.75, 0, 0], + "9838": [0.19444, 0.69444, 0, 0], + "9839": [0.19444, 0.69444, 0, 0], + "10216": [0.25, 0.75, 0, 0], + "10217": [0.25, 0.75, 0, 0], + "10222": [0.244, 0.744, 0, 0], + "10223": [0.244, 0.744, 0, 0], + "10229": [0.011, 0.511, 0, 0], + "10230": [0.011, 0.511, 0, 0], + "10231": [0.011, 0.511, 0, 0], + "10232": [0.024, 0.525, 0, 0], + "10233": [0.024, 0.525, 0, 0], + "10234": [0.024, 0.525, 0, 0], + "10236": [0.011, 0.511, 0, 0], + "10815": [0, 0.68333, 0, 0], + "10927": [0.13597, 0.63597, 0, 0], + "10928": [0.13597, 0.63597, 0, 0] +}, +"Math-BoldItalic": { + "47": [0.19444, 0.69444, 0, 0], + "65": [0, 0.68611, 0, 0], + "66": [0, 0.68611, 0.04835, 0], + "67": [0, 0.68611, 0.06979, 0], + "68": [0, 0.68611, 0.03194, 0], + "69": [0, 0.68611, 0.05451, 0], + "70": [0, 0.68611, 0.15972, 0], + "71": [0, 0.68611, 0, 0], + "72": [0, 0.68611, 0.08229, 0], + "73": [0, 0.68611, 0.07778, 0], + "74": [0, 0.68611, 0.10069, 0], + "75": [0, 0.68611, 0.06979, 0], + "76": [0, 0.68611, 0, 0], + "77": [0, 0.68611, 0.11424, 0], + "78": [0, 0.68611, 0.11424, 0], + "79": [0, 0.68611, 0.03194, 0], + "80": [0, 0.68611, 0.15972, 0], + "81": [0.19444, 0.68611, 0, 0], + "82": [0, 0.68611, 0.00421, 0], + "83": [0, 0.68611, 0.05382, 0], + "84": [0, 0.68611, 0.15972, 0], + "85": [0, 0.68611, 0.11424, 0], + "86": [0, 0.68611, 0.25555, 0], + "87": [0, 0.68611, 0.15972, 0], + "88": [0, 0.68611, 0.07778, 0], + "89": [0, 0.68611, 0.25555, 0], + "90": [0, 0.68611, 0.06979, 0], + "97": [0, 0.44444, 0, 0], + "98": [0, 0.69444, 0, 0], + "99": [0, 0.44444, 0, 0], + "100": [0, 0.69444, 0, 0], + "101": [0, 0.44444, 0, 0], + "102": [0.19444, 0.69444, 0.11042, 0], + "103": [0.19444, 0.44444, 0.03704, 0], + "104": [0, 0.69444, 0, 0], + "105": [0, 0.69326, 0, 0], + "106": [0.19444, 0.69326, 0.0622, 0], + "107": [0, 0.69444, 0.01852, 0], + "108": [0, 0.69444, 0.0088, 0], + "109": [0, 0.44444, 0, 0], + "110": [0, 0.44444, 0, 0], + "111": [0, 0.44444, 0, 0], + "112": [0.19444, 0.44444, 0, 0], + "113": [0.19444, 0.44444, 0.03704, 0], + "114": [0, 0.44444, 0.03194, 0], + "115": [0, 0.44444, 0, 0], + "116": [0, 0.63492, 0, 0], + "117": [0, 0.44444, 0, 0], + "118": [0, 0.44444, 0.03704, 0], + "119": [0, 0.44444, 0.02778, 0], + "120": [0, 0.44444, 0, 0], + "121": [0.19444, 0.44444, 0.03704, 0], + "122": [0, 0.44444, 0.04213, 0], + "915": [0, 0.68611, 0.15972, 0], + "916": [0, 0.68611, 0, 0], + "920": [0, 0.68611, 0.03194, 0], + "923": [0, 0.68611, 0, 0], + "926": [0, 0.68611, 0.07458, 0], + "928": [0, 0.68611, 0.08229, 0], + "931": [0, 0.68611, 0.05451, 0], + "933": [0, 0.68611, 0.15972, 0], + "934": [0, 0.68611, 0, 0], + "936": [0, 0.68611, 0.11653, 0], + "937": [0, 0.68611, 0.04835, 0], + "945": [0, 0.44444, 0, 0], + "946": [0.19444, 0.69444, 0.03403, 0], + "947": [0.19444, 0.44444, 0.06389, 0], + "948": [0, 0.69444, 0.03819, 0], + "949": [0, 0.44444, 0, 0], + "950": [0.19444, 0.69444, 0.06215, 0], + "951": [0.19444, 0.44444, 0.03704, 0], + "952": [0, 0.69444, 0.03194, 0], + "953": [0, 0.44444, 0, 0], + "954": [0, 0.44444, 0, 0], + "955": [0, 0.69444, 0, 0], + "956": [0.19444, 0.44444, 0, 0], + "957": [0, 0.44444, 0.06898, 0], + "958": [0.19444, 0.69444, 0.03021, 0], + "959": [0, 0.44444, 0, 0], + "960": [0, 0.44444, 0.03704, 0], + "961": [0.19444, 0.44444, 0, 0], + "962": [0.09722, 0.44444, 0.07917, 0], + "963": [0, 0.44444, 0.03704, 0], + "964": [0, 0.44444, 0.13472, 0], + "965": [0, 0.44444, 0.03704, 0], + "966": [0.19444, 0.44444, 0, 0], + "967": [0.19444, 0.44444, 0, 0], + "968": [0.19444, 0.69444, 0.03704, 0], + "969": [0, 0.44444, 0.03704, 0], + "977": [0, 0.69444, 0, 0], + "981": [0.19444, 0.69444, 0, 0], + "982": [0, 0.44444, 0.03194, 0], + "1009": [0.19444, 0.44444, 0, 0], + "1013": [0, 0.44444, 0, 0] +}, +"Math-Italic": { + "47": [0.19444, 0.69444, 0, 0], + "65": [0, 0.68333, 0, 0.13889], + "66": [0, 0.68333, 0.05017, 0.08334], + "67": [0, 0.68333, 0.07153, 0.08334], + "68": [0, 0.68333, 0.02778, 0.05556], + "69": [0, 0.68333, 0.05764, 0.08334], + "70": [0, 0.68333, 0.13889, 0.08334], + "71": [0, 0.68333, 0, 0.08334], + "72": [0, 0.68333, 0.08125, 0.05556], + "73": [0, 0.68333, 0.07847, 0.11111], + "74": [0, 0.68333, 0.09618, 0.16667], + "75": [0, 0.68333, 0.07153, 0.05556], + "76": [0, 0.68333, 0, 0.02778], + "77": [0, 0.68333, 0.10903, 0.08334], + "78": [0, 0.68333, 0.10903, 0.08334], + "79": [0, 0.68333, 0.02778, 0.08334], + "80": [0, 0.68333, 0.13889, 0.08334], + "81": [0.19444, 0.68333, 0, 0.08334], + "82": [0, 0.68333, 0.00773, 0.08334], + "83": [0, 0.68333, 0.05764, 0.08334], + "84": [0, 0.68333, 0.13889, 0.08334], + "85": [0, 0.68333, 0.10903, 0.02778], + "86": [0, 0.68333, 0.22222, 0], + "87": [0, 0.68333, 0.13889, 0], + "88": [0, 0.68333, 0.07847, 0.08334], + "89": [0, 0.68333, 0.22222, 0], + "90": [0, 0.68333, 0.07153, 0.08334], + "97": [0, 0.43056, 0, 0], + "98": [0, 0.69444, 0, 0], + "99": [0, 0.43056, 0, 0.05556], + "100": [0, 0.69444, 0, 0.16667], + "101": [0, 0.43056, 0, 0.05556], + "102": [0.19444, 0.69444, 0.10764, 0.16667], + "103": [0.19444, 0.43056, 0.03588, 0.02778], + "104": [0, 0.69444, 0, 0], + "105": [0, 0.65952, 0, 0], + "106": [0.19444, 0.65952, 0.05724, 0], + "107": [0, 0.69444, 0.03148, 0], + "108": [0, 0.69444, 0.01968, 0.08334], + "109": [0, 0.43056, 0, 0], + "110": [0, 0.43056, 0, 0], + "111": [0, 0.43056, 0, 0.05556], + "112": [0.19444, 0.43056, 0, 0.08334], + "113": [0.19444, 0.43056, 0.03588, 0.08334], + "114": [0, 0.43056, 0.02778, 0.05556], + "115": [0, 0.43056, 0, 0.05556], + "116": [0, 0.61508, 0, 0.08334], + "117": [0, 0.43056, 0, 0.02778], + "118": [0, 0.43056, 0.03588, 0.02778], + "119": [0, 0.43056, 0.02691, 0.08334], + "120": [0, 0.43056, 0, 0.02778], + "121": [0.19444, 0.43056, 0.03588, 0.05556], + "122": [0, 0.43056, 0.04398, 0.05556], + "915": [0, 0.68333, 0.13889, 0.08334], + "916": [0, 0.68333, 0, 0.16667], + "920": [0, 0.68333, 0.02778, 0.08334], + "923": [0, 0.68333, 0, 0.16667], + "926": [0, 0.68333, 0.07569, 0.08334], + "928": [0, 0.68333, 0.08125, 0.05556], + "931": [0, 0.68333, 0.05764, 0.08334], + "933": [0, 0.68333, 0.13889, 0.05556], + "934": [0, 0.68333, 0, 0.08334], + "936": [0, 0.68333, 0.11, 0.05556], + "937": [0, 0.68333, 0.05017, 0.08334], + "945": [0, 0.43056, 0.0037, 0.02778], + "946": [0.19444, 0.69444, 0.05278, 0.08334], + "947": [0.19444, 0.43056, 0.05556, 0], + "948": [0, 0.69444, 0.03785, 0.05556], + "949": [0, 0.43056, 0, 0.08334], + "950": [0.19444, 0.69444, 0.07378, 0.08334], + "951": [0.19444, 0.43056, 0.03588, 0.05556], + "952": [0, 0.69444, 0.02778, 0.08334], + "953": [0, 0.43056, 0, 0.05556], + "954": [0, 0.43056, 0, 0], + "955": [0, 0.69444, 0, 0], + "956": [0.19444, 0.43056, 0, 0.02778], + "957": [0, 0.43056, 0.06366, 0.02778], + "958": [0.19444, 0.69444, 0.04601, 0.11111], + "959": [0, 0.43056, 0, 0.05556], + "960": [0, 0.43056, 0.03588, 0], + "961": [0.19444, 0.43056, 0, 0.08334], + "962": [0.09722, 0.43056, 0.07986, 0.08334], + "963": [0, 0.43056, 0.03588, 0], + "964": [0, 0.43056, 0.1132, 0.02778], + "965": [0, 0.43056, 0.03588, 0.02778], + "966": [0.19444, 0.43056, 0, 0.08334], + "967": [0.19444, 0.43056, 0, 0.05556], + "968": [0.19444, 0.69444, 0.03588, 0.11111], + "969": [0, 0.43056, 0.03588, 0], + "977": [0, 0.69444, 0, 0.08334], + "981": [0.19444, 0.69444, 0, 0.08334], + "982": [0, 0.43056, 0.02778, 0], + "1009": [0.19444, 0.43056, 0, 0.08334], + "1013": [0, 0.43056, 0, 0.05556] +}, +"Math-Regular": { + "65": [0, 0.68333, 0, 0.13889], + "66": [0, 0.68333, 0.05017, 0.08334], + "67": [0, 0.68333, 0.07153, 0.08334], + "68": [0, 0.68333, 0.02778, 0.05556], + "69": [0, 0.68333, 0.05764, 0.08334], + "70": [0, 0.68333, 0.13889, 0.08334], + "71": [0, 0.68333, 0, 0.08334], + "72": [0, 0.68333, 0.08125, 0.05556], + "73": [0, 0.68333, 0.07847, 0.11111], + "74": [0, 0.68333, 0.09618, 0.16667], + "75": [0, 0.68333, 0.07153, 0.05556], + "76": [0, 0.68333, 0, 0.02778], + "77": [0, 0.68333, 0.10903, 0.08334], + "78": [0, 0.68333, 0.10903, 0.08334], + "79": [0, 0.68333, 0.02778, 0.08334], + "80": [0, 0.68333, 0.13889, 0.08334], + "81": [0.19444, 0.68333, 0, 0.08334], + "82": [0, 0.68333, 0.00773, 0.08334], + "83": [0, 0.68333, 0.05764, 0.08334], + "84": [0, 0.68333, 0.13889, 0.08334], + "85": [0, 0.68333, 0.10903, 0.02778], + "86": [0, 0.68333, 0.22222, 0], + "87": [0, 0.68333, 0.13889, 0], + "88": [0, 0.68333, 0.07847, 0.08334], + "89": [0, 0.68333, 0.22222, 0], + "90": [0, 0.68333, 0.07153, 0.08334], + "97": [0, 0.43056, 0, 0], + "98": [0, 0.69444, 0, 0], + "99": [0, 0.43056, 0, 0.05556], + "100": [0, 0.69444, 0, 0.16667], + "101": [0, 0.43056, 0, 0.05556], + "102": [0.19444, 0.69444, 0.10764, 0.16667], + "103": [0.19444, 0.43056, 0.03588, 0.02778], + "104": [0, 0.69444, 0, 0], + "105": [0, 0.65952, 0, 0], + "106": [0.19444, 0.65952, 0.05724, 0], + "107": [0, 0.69444, 0.03148, 0], + "108": [0, 0.69444, 0.01968, 0.08334], + "109": [0, 0.43056, 0, 0], + "110": [0, 0.43056, 0, 0], + "111": [0, 0.43056, 0, 0.05556], + "112": [0.19444, 0.43056, 0, 0.08334], + "113": [0.19444, 0.43056, 0.03588, 0.08334], + "114": [0, 0.43056, 0.02778, 0.05556], + "115": [0, 0.43056, 0, 0.05556], + "116": [0, 0.61508, 0, 0.08334], + "117": [0, 0.43056, 0, 0.02778], + "118": [0, 0.43056, 0.03588, 0.02778], + "119": [0, 0.43056, 0.02691, 0.08334], + "120": [0, 0.43056, 0, 0.02778], + "121": [0.19444, 0.43056, 0.03588, 0.05556], + "122": [0, 0.43056, 0.04398, 0.05556], + "915": [0, 0.68333, 0.13889, 0.08334], + "916": [0, 0.68333, 0, 0.16667], + "920": [0, 0.68333, 0.02778, 0.08334], + "923": [0, 0.68333, 0, 0.16667], + "926": [0, 0.68333, 0.07569, 0.08334], + "928": [0, 0.68333, 0.08125, 0.05556], + "931": [0, 0.68333, 0.05764, 0.08334], + "933": [0, 0.68333, 0.13889, 0.05556], + "934": [0, 0.68333, 0, 0.08334], + "936": [0, 0.68333, 0.11, 0.05556], + "937": [0, 0.68333, 0.05017, 0.08334], + "945": [0, 0.43056, 0.0037, 0.02778], + "946": [0.19444, 0.69444, 0.05278, 0.08334], + "947": [0.19444, 0.43056, 0.05556, 0], + "948": [0, 0.69444, 0.03785, 0.05556], + "949": [0, 0.43056, 0, 0.08334], + "950": [0.19444, 0.69444, 0.07378, 0.08334], + "951": [0.19444, 0.43056, 0.03588, 0.05556], + "952": [0, 0.69444, 0.02778, 0.08334], + "953": [0, 0.43056, 0, 0.05556], + "954": [0, 0.43056, 0, 0], + "955": [0, 0.69444, 0, 0], + "956": [0.19444, 0.43056, 0, 0.02778], + "957": [0, 0.43056, 0.06366, 0.02778], + "958": [0.19444, 0.69444, 0.04601, 0.11111], + "959": [0, 0.43056, 0, 0.05556], + "960": [0, 0.43056, 0.03588, 0], + "961": [0.19444, 0.43056, 0, 0.08334], + "962": [0.09722, 0.43056, 0.07986, 0.08334], + "963": [0, 0.43056, 0.03588, 0], + "964": [0, 0.43056, 0.1132, 0.02778], + "965": [0, 0.43056, 0.03588, 0.02778], + "966": [0.19444, 0.43056, 0, 0.08334], + "967": [0.19444, 0.43056, 0, 0.05556], + "968": [0.19444, 0.69444, 0.03588, 0.11111], + "969": [0, 0.43056, 0.03588, 0], + "977": [0, 0.69444, 0, 0.08334], + "981": [0.19444, 0.69444, 0, 0.08334], + "982": [0, 0.43056, 0.02778, 0], + "1009": [0.19444, 0.43056, 0, 0.08334], + "1013": [0, 0.43056, 0, 0.05556] +}, +"SansSerif-Regular": { + "33": [0, 0.69444, 0, 0], + "34": [0, 0.69444, 0, 0], + "35": [0.19444, 0.69444, 0, 0], + "36": [0.05556, 0.75, 0, 0], + "37": [0.05556, 0.75, 0, 0], + "38": [0, 0.69444, 0, 0], + "39": [0, 0.69444, 0, 0], + "40": [0.25, 0.75, 0, 0], + "41": [0.25, 0.75, 0, 0], + "42": [0, 0.75, 0, 0], + "43": [0.08333, 0.58333, 0, 0], + "44": [0.125, 0.08333, 0, 0], + "45": [0, 0.44444, 0, 0], + "46": [0, 0.08333, 0, 0], + "47": [0.25, 0.75, 0, 0], + "48": [0, 0.65556, 0, 0], + "49": [0, 0.65556, 0, 0], + "50": [0, 0.65556, 0, 0], + "51": [0, 0.65556, 0, 0], + "52": [0, 0.65556, 0, 0], + "53": [0, 0.65556, 0, 0], + "54": [0, 0.65556, 0, 0], + "55": [0, 0.65556, 0, 0], + "56": [0, 0.65556, 0, 0], + "57": [0, 0.65556, 0, 0], + "58": [0, 0.44444, 0, 0], + "59": [0.125, 0.44444, 0, 0], + "61": [-0.13, 0.37, 0, 0], + "63": [0, 0.69444, 0, 0], + "64": [0, 0.69444, 0, 0], + "65": [0, 0.69444, 0, 0], + "66": [0, 0.69444, 0, 0], + "67": [0, 0.69444, 0, 0], + "68": [0, 0.69444, 0, 0], + "69": [0, 0.69444, 0, 0], + "70": [0, 0.69444, 0, 0], + "71": [0, 0.69444, 0, 0], + "72": [0, 0.69444, 0, 0], + "73": [0, 0.69444, 0, 0], + "74": [0, 0.69444, 0, 0], + "75": [0, 0.69444, 0, 0], + "76": [0, 0.69444, 0, 0], + "77": [0, 0.69444, 0, 0], + "78": [0, 0.69444, 0, 0], + "79": [0, 0.69444, 0, 0], + "80": [0, 0.69444, 0, 0], + "81": [0.125, 0.69444, 0, 0], + "82": [0, 0.69444, 0, 0], + "83": [0, 0.69444, 0, 0], + "84": [0, 0.69444, 0, 0], + "85": [0, 0.69444, 0, 0], + "86": [0, 0.69444, 0.01389, 0], + "87": [0, 0.69444, 0.01389, 0], + "88": [0, 0.69444, 0, 0], + "89": [0, 0.69444, 0.025, 0], + "90": [0, 0.69444, 0, 0], + "91": [0.25, 0.75, 0, 0], + "93": [0.25, 0.75, 0, 0], + "94": [0, 0.69444, 0, 0], + "95": [0.35, 0.09444, 0.02778, 0], + "97": [0, 0.44444, 0, 0], + "98": [0, 0.69444, 0, 0], + "99": [0, 0.44444, 0, 0], + "100": [0, 0.69444, 0, 0], + "101": [0, 0.44444, 0, 0], + "102": [0, 0.69444, 0.06944, 0], + "103": [0.19444, 0.44444, 0.01389, 0], + "104": [0, 0.69444, 0, 0], + "105": [0, 0.67937, 0, 0], + "106": [0.19444, 0.67937, 0, 0], + "107": [0, 0.69444, 0, 0], + "108": [0, 0.69444, 0, 0], + "109": [0, 0.44444, 0, 0], + "110": [0, 0.44444, 0, 0], + "111": [0, 0.44444, 0, 0], + "112": [0.19444, 0.44444, 0, 0], + "113": [0.19444, 0.44444, 0, 0], + "114": [0, 0.44444, 0.01389, 0], + "115": [0, 0.44444, 0, 0], + "116": [0, 0.57143, 0, 0], + "117": [0, 0.44444, 0, 0], + "118": [0, 0.44444, 0.01389, 0], + "119": [0, 0.44444, 0.01389, 0], + "120": [0, 0.44444, 0, 0], + "121": [0.19444, 0.44444, 0.01389, 0], + "122": [0, 0.44444, 0, 0], + "126": [0.35, 0.32659, 0, 0], + "305": [0, 0.44444, 0, 0], + "567": [0.19444, 0.44444, 0, 0], + "768": [0, 0.69444, 0, 0], + "769": [0, 0.69444, 0, 0], + "770": [0, 0.69444, 0, 0], + "771": [0, 0.67659, 0, 0], + "772": [0, 0.60889, 0, 0], + "774": [0, 0.69444, 0, 0], + "775": [0, 0.67937, 0, 0], + "776": [0, 0.67937, 0, 0], + "778": [0, 0.69444, 0, 0], + "779": [0, 0.69444, 0, 0], + "780": [0, 0.63194, 0, 0], + "915": [0, 0.69444, 0, 0], + "916": [0, 0.69444, 0, 0], + "920": [0, 0.69444, 0, 0], + "923": [0, 0.69444, 0, 0], + "926": [0, 0.69444, 0, 0], + "928": [0, 0.69444, 0, 0], + "931": [0, 0.69444, 0, 0], + "933": [0, 0.69444, 0, 0], + "934": [0, 0.69444, 0, 0], + "936": [0, 0.69444, 0, 0], + "937": [0, 0.69444, 0, 0], + "8211": [0, 0.44444, 0.02778, 0], + "8212": [0, 0.44444, 0.02778, 0], + "8216": [0, 0.69444, 0, 0], + "8217": [0, 0.69444, 0, 0], + "8220": [0, 0.69444, 0, 0], + "8221": [0, 0.69444, 0, 0] +}, +"Script-Regular": { + "65": [0, 0.7, 0.22925, 0], + "66": [0, 0.7, 0.04087, 0], + "67": [0, 0.7, 0.1689, 0], + "68": [0, 0.7, 0.09371, 0], + "69": [0, 0.7, 0.18583, 0], + "70": [0, 0.7, 0.13634, 0], + "71": [0, 0.7, 0.17322, 0], + "72": [0, 0.7, 0.29694, 0], + "73": [0, 0.7, 0.19189, 0], + "74": [0.27778, 0.7, 0.19189, 0], + "75": [0, 0.7, 0.31259, 0], + "76": [0, 0.7, 0.19189, 0], + "77": [0, 0.7, 0.15981, 0], + "78": [0, 0.7, 0.3525, 0], + "79": [0, 0.7, 0.08078, 0], + "80": [0, 0.7, 0.08078, 0], + "81": [0, 0.7, 0.03305, 0], + "82": [0, 0.7, 0.06259, 0], + "83": [0, 0.7, 0.19189, 0], + "84": [0, 0.7, 0.29087, 0], + "85": [0, 0.7, 0.25815, 0], + "86": [0, 0.7, 0.27523, 0], + "87": [0, 0.7, 0.27523, 0], + "88": [0, 0.7, 0.26006, 0], + "89": [0, 0.7, 0.2939, 0], + "90": [0, 0.7, 0.24037, 0] +}, +"Size1-Regular": { + "40": [0.35001, 0.85, 0, 0], + "41": [0.35001, 0.85, 0, 0], + "47": [0.35001, 0.85, 0, 0], + "91": [0.35001, 0.85, 0, 0], + "92": [0.35001, 0.85, 0, 0], + "93": [0.35001, 0.85, 0, 0], + "123": [0.35001, 0.85, 0, 0], + "125": [0.35001, 0.85, 0, 0], + "710": [0, 0.72222, 0, 0], + "732": [0, 0.72222, 0, 0], + "770": [0, 0.72222, 0, 0], + "771": [0, 0.72222, 0, 0], + "8214": [-0.00099, 0.601, 0, 0], + "8593": [1e-05, 0.6, 0, 0], + "8595": [1e-05, 0.6, 0, 0], + "8657": [1e-05, 0.6, 0, 0], + "8659": [1e-05, 0.6, 0, 0], + "8719": [0.25001, 0.75, 0, 0], + "8720": [0.25001, 0.75, 0, 0], + "8721": [0.25001, 0.75, 0, 0], + "8730": [0.35001, 0.85, 0, 0], + "8739": [-0.00599, 0.606, 0, 0], + "8741": [-0.00599, 0.606, 0, 0], + "8747": [0.30612, 0.805, 0.19445, 0], + "8748": [0.306, 0.805, 0.19445, 0], + "8749": [0.306, 0.805, 0.19445, 0], + "8750": [0.30612, 0.805, 0.19445, 0], + "8896": [0.25001, 0.75, 0, 0], + "8897": [0.25001, 0.75, 0, 0], + "8898": [0.25001, 0.75, 0, 0], + "8899": [0.25001, 0.75, 0, 0], + "8968": [0.35001, 0.85, 0, 0], + "8969": [0.35001, 0.85, 0, 0], + "8970": [0.35001, 0.85, 0, 0], + "8971": [0.35001, 0.85, 0, 0], + "9168": [-0.00099, 0.601, 0, 0], + "10216": [0.35001, 0.85, 0, 0], + "10217": [0.35001, 0.85, 0, 0], + "10752": [0.25001, 0.75, 0, 0], + "10753": [0.25001, 0.75, 0, 0], + "10754": [0.25001, 0.75, 0, 0], + "10756": [0.25001, 0.75, 0, 0], + "10758": [0.25001, 0.75, 0, 0] +}, +"Size2-Regular": { + "40": [0.65002, 1.15, 0, 0], + "41": [0.65002, 1.15, 0, 0], + "47": [0.65002, 1.15, 0, 0], + "91": [0.65002, 1.15, 0, 0], + "92": [0.65002, 1.15, 0, 0], + "93": [0.65002, 1.15, 0, 0], + "123": [0.65002, 1.15, 0, 0], + "125": [0.65002, 1.15, 0, 0], + "710": [0, 0.75, 0, 0], + "732": [0, 0.75, 0, 0], + "770": [0, 0.75, 0, 0], + "771": [0, 0.75, 0, 0], + "8719": [0.55001, 1.05, 0, 0], + "8720": [0.55001, 1.05, 0, 0], + "8721": [0.55001, 1.05, 0, 0], + "8730": [0.65002, 1.15, 0, 0], + "8747": [0.86225, 1.36, 0.44445, 0], + "8748": [0.862, 1.36, 0.44445, 0], + "8749": [0.862, 1.36, 0.44445, 0], + "8750": [0.86225, 1.36, 0.44445, 0], + "8896": [0.55001, 1.05, 0, 0], + "8897": [0.55001, 1.05, 0, 0], + "8898": [0.55001, 1.05, 0, 0], + "8899": [0.55001, 1.05, 0, 0], + "8968": [0.65002, 1.15, 0, 0], + "8969": [0.65002, 1.15, 0, 0], + "8970": [0.65002, 1.15, 0, 0], + "8971": [0.65002, 1.15, 0, 0], + "10216": [0.65002, 1.15, 0, 0], + "10217": [0.65002, 1.15, 0, 0], + "10752": [0.55001, 1.05, 0, 0], + "10753": [0.55001, 1.05, 0, 0], + "10754": [0.55001, 1.05, 0, 0], + "10756": [0.55001, 1.05, 0, 0], + "10758": [0.55001, 1.05, 0, 0] +}, +"Size3-Regular": { + "40": [0.95003, 1.45, 0, 0], + "41": [0.95003, 1.45, 0, 0], + "47": [0.95003, 1.45, 0, 0], + "91": [0.95003, 1.45, 0, 0], + "92": [0.95003, 1.45, 0, 0], + "93": [0.95003, 1.45, 0, 0], + "123": [0.95003, 1.45, 0, 0], + "125": [0.95003, 1.45, 0, 0], + "710": [0, 0.75, 0, 0], + "732": [0, 0.75, 0, 0], + "770": [0, 0.75, 0, 0], + "771": [0, 0.75, 0, 0], + "8730": [0.95003, 1.45, 0, 0], + "8968": [0.95003, 1.45, 0, 0], + "8969": [0.95003, 1.45, 0, 0], + "8970": [0.95003, 1.45, 0, 0], + "8971": [0.95003, 1.45, 0, 0], + "10216": [0.95003, 1.45, 0, 0], + "10217": [0.95003, 1.45, 0, 0] +}, +"Size4-Regular": { + "40": [1.25003, 1.75, 0, 0], + "41": [1.25003, 1.75, 0, 0], + "47": [1.25003, 1.75, 0, 0], + "91": [1.25003, 1.75, 0, 0], + "92": [1.25003, 1.75, 0, 0], + "93": [1.25003, 1.75, 0, 0], + "123": [1.25003, 1.75, 0, 0], + "125": [1.25003, 1.75, 0, 0], + "710": [0, 0.825, 0, 0], + "732": [0, 0.825, 0, 0], + "770": [0, 0.825, 0, 0], + "771": [0, 0.825, 0, 0], + "8730": [1.25003, 1.75, 0, 0], + "8968": [1.25003, 1.75, 0, 0], + "8969": [1.25003, 1.75, 0, 0], + "8970": [1.25003, 1.75, 0, 0], + "8971": [1.25003, 1.75, 0, 0], + "9115": [0.64502, 1.155, 0, 0], + "9116": [1e-05, 0.6, 0, 0], + "9117": [0.64502, 1.155, 0, 0], + "9118": [0.64502, 1.155, 0, 0], + "9119": [1e-05, 0.6, 0, 0], + "9120": [0.64502, 1.155, 0, 0], + "9121": [0.64502, 1.155, 0, 0], + "9122": [-0.00099, 0.601, 0, 0], + "9123": [0.64502, 1.155, 0, 0], + "9124": [0.64502, 1.155, 0, 0], + "9125": [-0.00099, 0.601, 0, 0], + "9126": [0.64502, 1.155, 0, 0], + "9127": [1e-05, 0.9, 0, 0], + "9128": [0.65002, 1.15, 0, 0], + "9129": [0.90001, 0, 0, 0], + "9130": [0, 0.3, 0, 0], + "9131": [1e-05, 0.9, 0, 0], + "9132": [0.65002, 1.15, 0, 0], + "9133": [0.90001, 0, 0, 0], + "9143": [0.88502, 0.915, 0, 0], + "10216": [1.25003, 1.75, 0, 0], + "10217": [1.25003, 1.75, 0, 0], + "57344": [-0.00499, 0.605, 0, 0], + "57345": [-0.00499, 0.605, 0, 0], + "57680": [0, 0.12, 0, 0], + "57681": [0, 0.12, 0, 0], + "57682": [0, 0.12, 0, 0], + "57683": [0, 0.12, 0, 0] +}, +"Typewriter-Regular": { + "33": [0, 0.61111, 0, 0], + "34": [0, 0.61111, 0, 0], + "35": [0, 0.61111, 0, 0], + "36": [0.08333, 0.69444, 0, 0], + "37": [0.08333, 0.69444, 0, 0], + "38": [0, 0.61111, 0, 0], + "39": [0, 0.61111, 0, 0], + "40": [0.08333, 0.69444, 0, 0], + "41": [0.08333, 0.69444, 0, 0], + "42": [0, 0.52083, 0, 0], + "43": [-0.08056, 0.53055, 0, 0], + "44": [0.13889, 0.125, 0, 0], + "45": [-0.08056, 0.53055, 0, 0], + "46": [0, 0.125, 0, 0], + "47": [0.08333, 0.69444, 0, 0], + "48": [0, 0.61111, 0, 0], + "49": [0, 0.61111, 0, 0], + "50": [0, 0.61111, 0, 0], + "51": [0, 0.61111, 0, 0], + "52": [0, 0.61111, 0, 0], + "53": [0, 0.61111, 0, 0], + "54": [0, 0.61111, 0, 0], + "55": [0, 0.61111, 0, 0], + "56": [0, 0.61111, 0, 0], + "57": [0, 0.61111, 0, 0], + "58": [0, 0.43056, 0, 0], + "59": [0.13889, 0.43056, 0, 0], + "60": [-0.05556, 0.55556, 0, 0], + "61": [-0.19549, 0.41562, 0, 0], + "62": [-0.05556, 0.55556, 0, 0], + "63": [0, 0.61111, 0, 0], + "64": [0, 0.61111, 0, 0], + "65": [0, 0.61111, 0, 0], + "66": [0, 0.61111, 0, 0], + "67": [0, 0.61111, 0, 0], + "68": [0, 0.61111, 0, 0], + "69": [0, 0.61111, 0, 0], + "70": [0, 0.61111, 0, 0], + "71": [0, 0.61111, 0, 0], + "72": [0, 0.61111, 0, 0], + "73": [0, 0.61111, 0, 0], + "74": [0, 0.61111, 0, 0], + "75": [0, 0.61111, 0, 0], + "76": [0, 0.61111, 0, 0], + "77": [0, 0.61111, 0, 0], + "78": [0, 0.61111, 0, 0], + "79": [0, 0.61111, 0, 0], + "80": [0, 0.61111, 0, 0], + "81": [0.13889, 0.61111, 0, 0], + "82": [0, 0.61111, 0, 0], + "83": [0, 0.61111, 0, 0], + "84": [0, 0.61111, 0, 0], + "85": [0, 0.61111, 0, 0], + "86": [0, 0.61111, 0, 0], + "87": [0, 0.61111, 0, 0], + "88": [0, 0.61111, 0, 0], + "89": [0, 0.61111, 0, 0], + "90": [0, 0.61111, 0, 0], + "91": [0.08333, 0.69444, 0, 0], + "92": [0.08333, 0.69444, 0, 0], + "93": [0.08333, 0.69444, 0, 0], + "94": [0, 0.61111, 0, 0], + "95": [0.09514, 0, 0, 0], + "96": [0, 0.61111, 0, 0], + "97": [0, 0.43056, 0, 0], + "98": [0, 0.61111, 0, 0], + "99": [0, 0.43056, 0, 0], + "100": [0, 0.61111, 0, 0], + "101": [0, 0.43056, 0, 0], + "102": [0, 0.61111, 0, 0], + "103": [0.22222, 0.43056, 0, 0], + "104": [0, 0.61111, 0, 0], + "105": [0, 0.61111, 0, 0], + "106": [0.22222, 0.61111, 0, 0], + "107": [0, 0.61111, 0, 0], + "108": [0, 0.61111, 0, 0], + "109": [0, 0.43056, 0, 0], + "110": [0, 0.43056, 0, 0], + "111": [0, 0.43056, 0, 0], + "112": [0.22222, 0.43056, 0, 0], + "113": [0.22222, 0.43056, 0, 0], + "114": [0, 0.43056, 0, 0], + "115": [0, 0.43056, 0, 0], + "116": [0, 0.55358, 0, 0], + "117": [0, 0.43056, 0, 0], + "118": [0, 0.43056, 0, 0], + "119": [0, 0.43056, 0, 0], + "120": [0, 0.43056, 0, 0], + "121": [0.22222, 0.43056, 0, 0], + "122": [0, 0.43056, 0, 0], + "123": [0.08333, 0.69444, 0, 0], + "124": [0.08333, 0.69444, 0, 0], + "125": [0.08333, 0.69444, 0, 0], + "126": [0, 0.61111, 0, 0], + "127": [0, 0.61111, 0, 0], + "305": [0, 0.43056, 0, 0], + "567": [0.22222, 0.43056, 0, 0], + "768": [0, 0.61111, 0, 0], + "769": [0, 0.61111, 0, 0], + "770": [0, 0.61111, 0, 0], + "771": [0, 0.61111, 0, 0], + "772": [0, 0.56555, 0, 0], + "774": [0, 0.61111, 0, 0], + "776": [0, 0.61111, 0, 0], + "778": [0, 0.61111, 0, 0], + "780": [0, 0.56597, 0, 0], + "915": [0, 0.61111, 0, 0], + "916": [0, 0.61111, 0, 0], + "920": [0, 0.61111, 0, 0], + "923": [0, 0.61111, 0, 0], + "926": [0, 0.61111, 0, 0], + "928": [0, 0.61111, 0, 0], + "931": [0, 0.61111, 0, 0], + "933": [0, 0.61111, 0, 0], + "934": [0, 0.61111, 0, 0], + "936": [0, 0.61111, 0, 0], + "937": [0, 0.61111, 0, 0], + "2018": [0, 0.61111, 0, 0], + "2019": [0, 0.61111, 0, 0], + "8242": [0, 0.61111, 0, 0] +}}; diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/functions.js b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/functions.js new file mode 100644 index 0000000..5d4ed0d --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/functions.js @@ -0,0 +1,569 @@ +var utils = require("./utils"); +var ParseError = require("./ParseError"); + +/* This file contains a list of functions that we parse, identified by + * the calls to defineFunction. + * + * The first argument to defineFunction is a single name or a list of names. + * All functions named in such a list will share a single implementation. + * + * Each declared function can have associated properties, which + * include the following: + * + * - numArgs: The number of arguments the function takes. + * If this is the only property, it can be passed as a number + * instead of an element of a properties object. + * - argTypes: (optional) An array corresponding to each argument of the + * function, giving the type of argument that should be parsed. Its + * length should be equal to `numArgs + numOptionalArgs`. Valid + * types: + * - "size": A size-like thing, such as "1em" or "5ex" + * - "color": An html color, like "#abc" or "blue" + * - "original": The same type as the environment that the + * function being parsed is in (e.g. used for the + * bodies of functions like \color where the first + * argument is special and the second argument is + * parsed normally) + * Other possible types (probably shouldn't be used) + * - "text": Text-like (e.g. \text) + * - "math": Normal math + * If undefined, this will be treated as an appropriate length + * array of "original" strings + * - greediness: (optional) The greediness of the function to use ungrouped + * arguments. + * + * E.g. if you have an expression + * \sqrt \frac 1 2 + * since \frac has greediness=2 vs \sqrt's greediness=1, \frac + * will use the two arguments '1' and '2' as its two arguments, + * then that whole function will be used as the argument to + * \sqrt. On the other hand, the expressions + * \frac \frac 1 2 3 + * and + * \frac \sqrt 1 2 + * will fail because \frac and \frac have equal greediness + * and \sqrt has a lower greediness than \frac respectively. To + * make these parse, we would have to change them to: + * \frac {\frac 1 2} 3 + * and + * \frac {\sqrt 1} 2 + * + * The default value is `1` + * - allowedInText: (optional) Whether or not the function is allowed inside + * text mode (default false) + * - numOptionalArgs: (optional) The number of optional arguments the function + * should parse. If the optional arguments aren't found, + * `null` will be passed to the handler in their place. + * (default 0) + * + * The last argument is that implementation, the handler for the function(s). + * It is called to handle these functions and their arguments. + * It receives two arguments: + * - context contains information and references provided by the parser + * - args is an array of arguments obtained from TeX input + * The context contains the following properties: + * - funcName: the text (i.e. name) of the function, including \ + * - parser: the parser object + * - lexer: the lexer object + * - positions: the positions in the overall string of the function + * and the arguments. + * The latter three should only be used to produce error messages. + * + * The function should return an object with the following keys: + * - type: The type of element that this is. This is then used in + * buildHTML/buildMathML to determine which function + * should be called to build this node into a DOM node + * Any other data can be added to the object, which will be passed + * in to the function in buildHTML/buildMathML as `group.value`. + */ + +function defineFunction(names, props, handler) { + if (typeof names === "string") { + names = [names]; + } + if (typeof props === "number") { + props = { numArgs: props }; + } + // Set default values of functions + var data = { + numArgs: props.numArgs, + argTypes: props.argTypes, + greediness: (props.greediness === undefined) ? 1 : props.greediness, + allowedInText: !!props.allowedInText, + numOptionalArgs: props.numOptionalArgs || 0, + handler: handler + }; + for (var i = 0; i < names.length; ++i) { + module.exports[names[i]] = data; + } +} + +// A normal square root +defineFunction("\\sqrt", { + numArgs: 1, + numOptionalArgs: 1 +}, function(context, args) { + var index = args[0]; + var body = args[1]; + return { + type: "sqrt", + body: body, + index: index + }; +}); + +// Some non-mathy text +defineFunction("\\text", { + numArgs: 1, + argTypes: ["text"], + greediness: 2 +}, function(context, args) { + var body = args[0]; + // Since the corresponding buildHTML/buildMathML function expects a + // list of elements, we normalize for different kinds of arguments + // TODO(emily): maybe this should be done somewhere else + var inner; + if (body.type === "ordgroup") { + inner = body.value; + } else { + inner = [body]; + } + + return { + type: "text", + body: inner + }; +}); + +// A two-argument custom color +defineFunction("\\color", { + numArgs: 2, + allowedInText: true, + greediness: 3, + argTypes: ["color", "original"] +}, function(context, args) { + var color = args[0]; + var body = args[1]; + // Normalize the different kinds of bodies (see \text above) + var inner; + if (body.type === "ordgroup") { + inner = body.value; + } else { + inner = [body]; + } + + return { + type: "color", + color: color.value, + value: inner + }; +}); + +// An overline +defineFunction("\\overline", { + numArgs: 1 +}, function(context, args) { + var body = args[0]; + return { + type: "overline", + body: body + }; +}); + +// A box of the width and height +defineFunction("\\rule", { + numArgs: 2, + numOptionalArgs: 1, + argTypes: ["size", "size", "size"] +}, function(context, args) { + var shift = args[0]; + var width = args[1]; + var height = args[2]; + return { + type: "rule", + shift: shift && shift.value, + width: width.value, + height: height.value + }; +}); + +// A KaTeX logo +defineFunction("\\KaTeX", { + numArgs: 0 +}, function(context) { + return { + type: "katex" + }; +}); + +defineFunction("\\phantom", { + numArgs: 1 +}, function(context, args) { + var body = args[0]; + var inner; + if (body.type === "ordgroup") { + inner = body.value; + } else { + inner = [body]; + } + + return { + type: "phantom", + value: inner + }; +}); + +// Extra data needed for the delimiter handler down below +var delimiterSizes = { + "\\bigl" : {type: "open", size: 1}, + "\\Bigl" : {type: "open", size: 2}, + "\\biggl": {type: "open", size: 3}, + "\\Biggl": {type: "open", size: 4}, + "\\bigr" : {type: "close", size: 1}, + "\\Bigr" : {type: "close", size: 2}, + "\\biggr": {type: "close", size: 3}, + "\\Biggr": {type: "close", size: 4}, + "\\bigm" : {type: "rel", size: 1}, + "\\Bigm" : {type: "rel", size: 2}, + "\\biggm": {type: "rel", size: 3}, + "\\Biggm": {type: "rel", size: 4}, + "\\big" : {type: "textord", size: 1}, + "\\Big" : {type: "textord", size: 2}, + "\\bigg" : {type: "textord", size: 3}, + "\\Bigg" : {type: "textord", size: 4} +}; + +var delimiters = [ + "(", ")", "[", "\\lbrack", "]", "\\rbrack", + "\\{", "\\lbrace", "\\}", "\\rbrace", + "\\lfloor", "\\rfloor", "\\lceil", "\\rceil", + "<", ">", "\\langle", "\\rangle", "\\lt", "\\gt", + "\\lvert", "\\rvert", "\\lVert", "\\rVert", + "\\lgroup", "\\rgroup", "\\lmoustache", "\\rmoustache", + "/", "\\backslash", + "|", "\\vert", "\\|", "\\Vert", + "\\uparrow", "\\Uparrow", + "\\downarrow", "\\Downarrow", + "\\updownarrow", "\\Updownarrow", + "." +]; + +var fontAliases = { + "\\Bbb": "\\mathbb", + "\\bold": "\\mathbf", + "\\frak": "\\mathfrak" +}; + +// Single-argument color functions +defineFunction([ + "\\blue", "\\orange", "\\pink", "\\red", + "\\green", "\\gray", "\\purple", + "\\blueA", "\\blueB", "\\blueC", "\\blueD", "\\blueE", + "\\tealA", "\\tealB", "\\tealC", "\\tealD", "\\tealE", + "\\greenA", "\\greenB", "\\greenC", "\\greenD", "\\greenE", + "\\goldA", "\\goldB", "\\goldC", "\\goldD", "\\goldE", + "\\redA", "\\redB", "\\redC", "\\redD", "\\redE", + "\\maroonA", "\\maroonB", "\\maroonC", "\\maroonD", "\\maroonE", + "\\purpleA", "\\purpleB", "\\purpleC", "\\purpleD", "\\purpleE", + "\\mintA", "\\mintB", "\\mintC", + "\\grayA", "\\grayB", "\\grayC", "\\grayD", "\\grayE", + "\\grayF", "\\grayG", "\\grayH", "\\grayI", + "\\kaBlue", "\\kaGreen" +], { + numArgs: 1, + allowedInText: true, + greediness: 3 +}, function(context, args) { + var body = args[0]; + var atoms; + if (body.type === "ordgroup") { + atoms = body.value; + } else { + atoms = [body]; + } + + return { + type: "color", + color: "katex-" + context.funcName.slice(1), + value: atoms + }; +}); + +// There are 2 flags for operators; whether they produce limits in +// displaystyle, and whether they are symbols and should grow in +// displaystyle. These four groups cover the four possible choices. + +// No limits, not symbols +defineFunction([ + "\\arcsin", "\\arccos", "\\arctan", "\\arg", "\\cos", "\\cosh", + "\\cot", "\\coth", "\\csc", "\\deg", "\\dim", "\\exp", "\\hom", + "\\ker", "\\lg", "\\ln", "\\log", "\\sec", "\\sin", "\\sinh", + "\\tan","\\tanh" +], { + numArgs: 0 +}, function(context) { + return { + type: "op", + limits: false, + symbol: false, + body: context.funcName + }; +}); + +// Limits, not symbols +defineFunction([ + "\\det", "\\gcd", "\\inf", "\\lim", "\\liminf", "\\limsup", "\\max", + "\\min", "\\Pr", "\\sup" +], { + numArgs: 0 +}, function(context) { + return { + type: "op", + limits: true, + symbol: false, + body: context.funcName + }; +}); + +// No limits, symbols +defineFunction([ + "\\int", "\\iint", "\\iiint", "\\oint" +], { + numArgs: 0 +}, function(context) { + return { + type: "op", + limits: false, + symbol: true, + body: context.funcName + }; +}); + +// Limits, symbols +defineFunction([ + "\\coprod", "\\bigvee", "\\bigwedge", "\\biguplus", "\\bigcap", + "\\bigcup", "\\intop", "\\prod", "\\sum", "\\bigotimes", + "\\bigoplus", "\\bigodot", "\\bigsqcup", "\\smallint" +], { + numArgs: 0 +}, function(context) { + return { + type: "op", + limits: true, + symbol: true, + body: context.funcName + }; +}); + +// Fractions +defineFunction([ + "\\dfrac", "\\frac", "\\tfrac", + "\\dbinom", "\\binom", "\\tbinom" +], { + numArgs: 2, + greediness: 2 +}, function(context, args) { + var numer = args[0]; + var denom = args[1]; + var hasBarLine; + var leftDelim = null; + var rightDelim = null; + var size = "auto"; + + switch (context.funcName) { + case "\\dfrac": + case "\\frac": + case "\\tfrac": + hasBarLine = true; + break; + case "\\dbinom": + case "\\binom": + case "\\tbinom": + hasBarLine = false; + leftDelim = "("; + rightDelim = ")"; + break; + default: + throw new Error("Unrecognized genfrac command"); + } + + switch (context.funcName) { + case "\\dfrac": + case "\\dbinom": + size = "display"; + break; + case "\\tfrac": + case "\\tbinom": + size = "text"; + break; + } + + return { + type: "genfrac", + numer: numer, + denom: denom, + hasBarLine: hasBarLine, + leftDelim: leftDelim, + rightDelim: rightDelim, + size: size + }; +}); + +// Left and right overlap functions +defineFunction(["\\llap", "\\rlap"], { + numArgs: 1, + allowedInText: true +}, function(context, args) { + var body = args[0]; + return { + type: context.funcName.slice(1), + body: body + }; +}); + +// Delimiter functions +defineFunction([ + "\\bigl", "\\Bigl", "\\biggl", "\\Biggl", + "\\bigr", "\\Bigr", "\\biggr", "\\Biggr", + "\\bigm", "\\Bigm", "\\biggm", "\\Biggm", + "\\big", "\\Big", "\\bigg", "\\Bigg", + "\\left", "\\right" +], { + numArgs: 1 +}, function(context, args) { + var delim = args[0]; + if (!utils.contains(delimiters, delim.value)) { + throw new ParseError( + "Invalid delimiter: '" + delim.value + "' after '" + + context.funcName + "'", + context.lexer, context.positions[1]); + } + + // \left and \right are caught somewhere in Parser.js, which is + // why this data doesn't match what is in buildHTML. + if (context.funcName === "\\left" || context.funcName === "\\right") { + return { + type: "leftright", + value: delim.value + }; + } else { + return { + type: "delimsizing", + size: delimiterSizes[context.funcName].size, + delimType: delimiterSizes[context.funcName].type, + value: delim.value + }; + } +}); + +// Sizing functions (handled in Parser.js explicitly, hence no handler) +defineFunction([ + "\\tiny", "\\scriptsize", "\\footnotesize", "\\small", + "\\normalsize", "\\large", "\\Large", "\\LARGE", "\\huge", "\\Huge" +], 0, null); + +// Style changing functions (handled in Parser.js explicitly, hence no +// handler) +defineFunction([ + "\\displaystyle", "\\textstyle", "\\scriptstyle", + "\\scriptscriptstyle" +], 0, null); + +defineFunction([ + // styles + "\\mathrm", "\\mathit", "\\mathbf", + + // families + "\\mathbb", "\\mathcal", "\\mathfrak", "\\mathscr", "\\mathsf", + "\\mathtt", + + // aliases + "\\Bbb", "\\bold", "\\frak" +], { + numArgs: 1, + greediness: 2 +}, function (context, args) { + var body = args[0]; + var func = context.funcName; + if (func in fontAliases) { + func = fontAliases[func]; + } + return { + type: "font", + font: func.slice(1), + body: body + }; +}); + +// Accents +defineFunction([ + "\\acute", "\\grave", "\\ddot", "\\tilde", "\\bar", "\\breve", + "\\check", "\\hat", "\\vec", "\\dot" + // We don't support expanding accents yet + // "\\widetilde", "\\widehat" +], { + numArgs: 1 +}, function(context, args) { + var base = args[0]; + return { + type: "accent", + accent: context.funcName, + base: base + }; +}); + +// Infix generalized fractions +defineFunction(["\\over", "\\choose"], { + numArgs: 0 +}, function (context) { + var replaceWith; + switch (context.funcName) { + case "\\over": + replaceWith = "\\frac"; + break; + case "\\choose": + replaceWith = "\\binom"; + break; + default: + throw new Error("Unrecognized infix genfrac command"); + } + return { + type: "infix", + replaceWith: replaceWith + }; +}); + +// Row breaks for aligned data +defineFunction(["\\\\", "\\cr"], { + numArgs: 0, + numOptionalArgs: 1, + argTypes: ["size"] +}, function(context, args) { + var size = args[0]; + return { + type: "cr", + size: size + }; +}); + +// Environment delimiters +defineFunction(["\\begin", "\\end"], { + numArgs: 1, + argTypes: ["text"] +}, function(context, args) { + var nameGroup = args[0]; + if (nameGroup.type !== "ordgroup") { + throw new ParseError( + "Invalid environment name", + context.lexer, context.positions[1]); + } + var name = ""; + for (var i = 0; i < nameGroup.value.length; ++i) { + name += nameGroup.value[i].value; + } + return { + type: "environment", + name: name, + namepos: context.positions[1] + }; +}); diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/mathMLTree.js b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/mathMLTree.js new file mode 100644 index 0000000..0c7d441 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/mathMLTree.js @@ -0,0 +1,102 @@ +/** + * These objects store data about MathML nodes. This is the MathML equivalent + * of the types in domTree.js. Since MathML handles its own rendering, and + * since we're mainly using MathML to improve accessibility, we don't manage + * any of the styling state that the plain DOM nodes do. + * + * The `toNode` and `toMarkup` functions work simlarly to how they do in + * domTree.js, creating namespaced DOM nodes and HTML text markup respectively. + */ + +var utils = require("./utils"); + +/** + * This node represents a general purpose MathML node of any type. The + * constructor requires the type of node to create (for example, `"mo"` or + * `"mspace"`, corresponding to `<mo>` and `<mspace>` tags). + */ +function MathNode(type, children) { + this.type = type; + this.attributes = {}; + this.children = children || []; +} + +/** + * Sets an attribute on a MathML node. MathML depends on attributes to convey a + * semantic content, so this is used heavily. + */ +MathNode.prototype.setAttribute = function(name, value) { + this.attributes[name] = value; +}; + +/** + * Converts the math node into a MathML-namespaced DOM element. + */ +MathNode.prototype.toNode = function() { + var node = document.createElementNS( + "http://www.w3.org/1998/Math/MathML", this.type); + + for (var attr in this.attributes) { + if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) { + node.setAttribute(attr, this.attributes[attr]); + } + } + + for (var i = 0; i < this.children.length; i++) { + node.appendChild(this.children[i].toNode()); + } + + return node; +}; + +/** + * Converts the math node into an HTML markup string. + */ +MathNode.prototype.toMarkup = function() { + var markup = "<" + this.type; + + // Add the attributes + for (var attr in this.attributes) { + if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) { + markup += " " + attr + "=\""; + markup += utils.escape(this.attributes[attr]); + markup += "\""; + } + } + + markup += ">"; + + for (var i = 0; i < this.children.length; i++) { + markup += this.children[i].toMarkup(); + } + + markup += "</" + this.type + ">"; + + return markup; +}; + +/** + * This node represents a piece of text. + */ +function TextNode(text) { + this.text = text; +} + +/** + * Converts the text node into a DOM text node. + */ +TextNode.prototype.toNode = function() { + return document.createTextNode(this.text); +}; + +/** + * Converts the text node into HTML markup (which is just the text itself). + */ +TextNode.prototype.toMarkup = function() { + return utils.escape(this.text); +}; + +module.exports = { + MathNode: MathNode, + TextNode: TextNode +}; diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/parseData.js b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/parseData.js new file mode 100644 index 0000000..abaad81 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/parseData.js @@ -0,0 +1,23 @@ +/** + * The resulting parse tree nodes of the parse tree. + */ +function ParseNode(type, value, mode) { + this.type = type; + this.value = value; + this.mode = mode; +} + +/** + * A result and final position returned by the `.parse...` functions. + * + */ +function ParseResult(result, newPosition, peek) { + this.result = result; + this.position = newPosition; +} + +module.exports = { + ParseNode: ParseNode, + ParseResult: ParseResult +}; + diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/parseTree.js b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/parseTree.js new file mode 100644 index 0000000..3adba82 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/parseTree.js @@ -0,0 +1,17 @@ +/** + * Provides a single function for parsing an expression using a Parser + * TODO(emily): Remove this + */ + +var Parser = require("./Parser"); + +/** + * Parses an expression using a Parser, then returns the parsed result. + */ +var parseTree = function(toParse, settings) { + var parser = new Parser(toParse, settings); + + return parser.parse(); +}; + +module.exports = parseTree; diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/symbols.js b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/symbols.js new file mode 100644 index 0000000..99a483a --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/symbols.js @@ -0,0 +1,621 @@ +/** + * This file holds a list of all no-argument functions and single-character + * symbols (like 'a' or ';'). + * + * For each of the symbols, there are three properties they can have: + * - font (required): the font to be used for this symbol. Either "main" (the + normal font), or "ams" (the ams fonts). + * - group (required): the ParseNode group type the symbol should have (i.e. + "textord", "mathord", etc). + See https://github.com/Khan/KaTeX/wiki/Examining-TeX#group-types + * - replace: the character that this symbol or function should be + * replaced with (i.e. "\phi" has a replace value of "\u03d5", the phi + * character in the main font). + * + * The outermost map in the table indicates what mode the symbols should be + * accepted in (e.g. "math" or "text"). + */ + +module.exports = { + math: {}, + text: {} +}; + +function defineSymbol(mode, font, group, replace, name) { + module.exports[mode][name] = { + font: font, + group: group, + replace: replace + }; +} + +// (For some reason jshint believes open and close to be global symbols.) +/* globals -open, -close */ + +// Some abbreviations for commonly used strings. +// This helps minify the code, and also spotting typos using jshint. + +// modes: +var math = "math"; +var text = "text"; + +// fonts: +var main = "main"; +var ams = "ams"; + +// groups: +var accent = "accent"; +var bin = "bin"; +var close = "close"; +var inner = "inner"; +var mathord = "mathord"; +var op = "op"; +var open = "open"; +var punct = "punct"; +var rel = "rel"; +var spacing = "spacing"; +var textord = "textord"; + +// Now comes the symbol table + +// Relation Symbols +defineSymbol(math, main, rel, "\u2261", "\\equiv"); +defineSymbol(math, main, rel, "\u227a", "\\prec"); +defineSymbol(math, main, rel, "\u227b", "\\succ"); +defineSymbol(math, main, rel, "\u223c", "\\sim"); +defineSymbol(math, main, rel, "\u22a5", "\\perp"); +defineSymbol(math, main, rel, "\u2aaf", "\\preceq"); +defineSymbol(math, main, rel, "\u2ab0", "\\succeq"); +defineSymbol(math, main, rel, "\u2243", "\\simeq"); +defineSymbol(math, main, rel, "\u2223", "\\mid"); +defineSymbol(math, main, rel, "\u226a", "\\ll"); +defineSymbol(math, main, rel, "\u226b", "\\gg"); +defineSymbol(math, main, rel, "\u224d", "\\asymp"); +defineSymbol(math, main, rel, "\u2225", "\\parallel"); +defineSymbol(math, main, rel, "\u22c8", "\\bowtie"); +defineSymbol(math, main, rel, "\u2323", "\\smile"); +defineSymbol(math, main, rel, "\u2291", "\\sqsubseteq"); +defineSymbol(math, main, rel, "\u2292", "\\sqsupseteq"); +defineSymbol(math, main, rel, "\u2250", "\\doteq"); +defineSymbol(math, main, rel, "\u2322", "\\frown"); +defineSymbol(math, main, rel, "\u220b", "\\ni"); +defineSymbol(math, main, rel, "\u221d", "\\propto"); +defineSymbol(math, main, rel, "\u22a2", "\\vdash"); +defineSymbol(math, main, rel, "\u22a3", "\\dashv"); +defineSymbol(math, main, rel, "\u220b", "\\owns"); + +// Punctuation +defineSymbol(math, main, punct, "\u002e", "\\ldotp"); +defineSymbol(math, main, punct, "\u22c5", "\\cdotp"); + +// Misc Symbols +defineSymbol(math, main, textord, "\u0023", "\\#"); +defineSymbol(math, main, textord, "\u0026", "\\&"); +defineSymbol(math, main, textord, "\u2135", "\\aleph"); +defineSymbol(math, main, textord, "\u2200", "\\forall"); +defineSymbol(math, main, textord, "\u210f", "\\hbar"); +defineSymbol(math, main, textord, "\u2203", "\\exists"); +defineSymbol(math, main, textord, "\u2207", "\\nabla"); +defineSymbol(math, main, textord, "\u266d", "\\flat"); +defineSymbol(math, main, textord, "\u2113", "\\ell"); +defineSymbol(math, main, textord, "\u266e", "\\natural"); +defineSymbol(math, main, textord, "\u2663", "\\clubsuit"); +defineSymbol(math, main, textord, "\u2118", "\\wp"); +defineSymbol(math, main, textord, "\u266f", "\\sharp"); +defineSymbol(math, main, textord, "\u2662", "\\diamondsuit"); +defineSymbol(math, main, textord, "\u211c", "\\Re"); +defineSymbol(math, main, textord, "\u2661", "\\heartsuit"); +defineSymbol(math, main, textord, "\u2111", "\\Im"); +defineSymbol(math, main, textord, "\u2660", "\\spadesuit"); + +// Math and Text +defineSymbol(math, main, textord, "\u2020", "\\dag"); +defineSymbol(math, main, textord, "\u2021", "\\ddag"); + +// Large Delimiters +defineSymbol(math, main, close, "\u23b1", "\\rmoustache"); +defineSymbol(math, main, open, "\u23b0", "\\lmoustache"); +defineSymbol(math, main, close, "\u27ef", "\\rgroup"); +defineSymbol(math, main, open, "\u27ee", "\\lgroup"); + +// Binary Operators +defineSymbol(math, main, bin, "\u2213", "\\mp"); +defineSymbol(math, main, bin, "\u2296", "\\ominus"); +defineSymbol(math, main, bin, "\u228e", "\\uplus"); +defineSymbol(math, main, bin, "\u2293", "\\sqcap"); +defineSymbol(math, main, bin, "\u2217", "\\ast"); +defineSymbol(math, main, bin, "\u2294", "\\sqcup"); +defineSymbol(math, main, bin, "\u25ef", "\\bigcirc"); +defineSymbol(math, main, bin, "\u2219", "\\bullet"); +defineSymbol(math, main, bin, "\u2021", "\\ddagger"); +defineSymbol(math, main, bin, "\u2240", "\\wr"); +defineSymbol(math, main, bin, "\u2a3f", "\\amalg"); + +// Arrow Symbols +defineSymbol(math, main, rel, "\u27f5", "\\longleftarrow"); +defineSymbol(math, main, rel, "\u21d0", "\\Leftarrow"); +defineSymbol(math, main, rel, "\u27f8", "\\Longleftarrow"); +defineSymbol(math, main, rel, "\u27f6", "\\longrightarrow"); +defineSymbol(math, main, rel, "\u21d2", "\\Rightarrow"); +defineSymbol(math, main, rel, "\u27f9", "\\Longrightarrow"); +defineSymbol(math, main, rel, "\u2194", "\\leftrightarrow"); +defineSymbol(math, main, rel, "\u27f7", "\\longleftrightarrow"); +defineSymbol(math, main, rel, "\u21d4", "\\Leftrightarrow"); +defineSymbol(math, main, rel, "\u27fa", "\\Longleftrightarrow"); +defineSymbol(math, main, rel, "\u21a6", "\\mapsto"); +defineSymbol(math, main, rel, "\u27fc", "\\longmapsto"); +defineSymbol(math, main, rel, "\u2197", "\\nearrow"); +defineSymbol(math, main, rel, "\u21a9", "\\hookleftarrow"); +defineSymbol(math, main, rel, "\u21aa", "\\hookrightarrow"); +defineSymbol(math, main, rel, "\u2198", "\\searrow"); +defineSymbol(math, main, rel, "\u21bc", "\\leftharpoonup"); +defineSymbol(math, main, rel, "\u21c0", "\\rightharpoonup"); +defineSymbol(math, main, rel, "\u2199", "\\swarrow"); +defineSymbol(math, main, rel, "\u21bd", "\\leftharpoondown"); +defineSymbol(math, main, rel, "\u21c1", "\\rightharpoondown"); +defineSymbol(math, main, rel, "\u2196", "\\nwarrow"); +defineSymbol(math, main, rel, "\u21cc", "\\rightleftharpoons"); + +// AMS Negated Binary Relations +defineSymbol(math, ams, rel, "\u226e", "\\nless"); +defineSymbol(math, ams, rel, "\ue010", "\\nleqslant"); +defineSymbol(math, ams, rel, "\ue011", "\\nleqq"); +defineSymbol(math, ams, rel, "\u2a87", "\\lneq"); +defineSymbol(math, ams, rel, "\u2268", "\\lneqq"); +defineSymbol(math, ams, rel, "\ue00c", "\\lvertneqq"); +defineSymbol(math, ams, rel, "\u22e6", "\\lnsim"); +defineSymbol(math, ams, rel, "\u2a89", "\\lnapprox"); +defineSymbol(math, ams, rel, "\u2280", "\\nprec"); +defineSymbol(math, ams, rel, "\u22e0", "\\npreceq"); +defineSymbol(math, ams, rel, "\u22e8", "\\precnsim"); +defineSymbol(math, ams, rel, "\u2ab9", "\\precnapprox"); +defineSymbol(math, ams, rel, "\u2241", "\\nsim"); +defineSymbol(math, ams, rel, "\ue006", "\\nshortmid"); +defineSymbol(math, ams, rel, "\u2224", "\\nmid"); +defineSymbol(math, ams, rel, "\u22ac", "\\nvdash"); +defineSymbol(math, ams, rel, "\u22ad", "\\nvDash"); +defineSymbol(math, ams, rel, "\u22ea", "\\ntriangleleft"); +defineSymbol(math, ams, rel, "\u22ec", "\\ntrianglelefteq"); +defineSymbol(math, ams, rel, "\u228a", "\\subsetneq"); +defineSymbol(math, ams, rel, "\ue01a", "\\varsubsetneq"); +defineSymbol(math, ams, rel, "\u2acb", "\\subsetneqq"); +defineSymbol(math, ams, rel, "\ue017", "\\varsubsetneqq"); +defineSymbol(math, ams, rel, "\u226f", "\\ngtr"); +defineSymbol(math, ams, rel, "\ue00f", "\\ngeqslant"); +defineSymbol(math, ams, rel, "\ue00e", "\\ngeqq"); +defineSymbol(math, ams, rel, "\u2a88", "\\gneq"); +defineSymbol(math, ams, rel, "\u2269", "\\gneqq"); +defineSymbol(math, ams, rel, "\ue00d", "\\gvertneqq"); +defineSymbol(math, ams, rel, "\u22e7", "\\gnsim"); +defineSymbol(math, ams, rel, "\u2a8a", "\\gnapprox"); +defineSymbol(math, ams, rel, "\u2281", "\\nsucc"); +defineSymbol(math, ams, rel, "\u22e1", "\\nsucceq"); +defineSymbol(math, ams, rel, "\u22e9", "\\succnsim"); +defineSymbol(math, ams, rel, "\u2aba", "\\succnapprox"); +defineSymbol(math, ams, rel, "\u2246", "\\ncong"); +defineSymbol(math, ams, rel, "\ue007", "\\nshortparallel"); +defineSymbol(math, ams, rel, "\u2226", "\\nparallel"); +defineSymbol(math, ams, rel, "\u22af", "\\nVDash"); +defineSymbol(math, ams, rel, "\u22eb", "\\ntriangleright"); +defineSymbol(math, ams, rel, "\u22ed", "\\ntrianglerighteq"); +defineSymbol(math, ams, rel, "\ue018", "\\nsupseteqq"); +defineSymbol(math, ams, rel, "\u228b", "\\supsetneq"); +defineSymbol(math, ams, rel, "\ue01b", "\\varsupsetneq"); +defineSymbol(math, ams, rel, "\u2acc", "\\supsetneqq"); +defineSymbol(math, ams, rel, "\ue019", "\\varsupsetneqq"); +defineSymbol(math, ams, rel, "\u22ae", "\\nVdash"); +defineSymbol(math, ams, rel, "\u2ab5", "\\precneqq"); +defineSymbol(math, ams, rel, "\u2ab6", "\\succneqq"); +defineSymbol(math, ams, rel, "\ue016", "\\nsubseteqq"); +defineSymbol(math, ams, bin, "\u22b4", "\\unlhd"); +defineSymbol(math, ams, bin, "\u22b5", "\\unrhd"); + +// AMS Negated Arrows +defineSymbol(math, ams, rel, "\u219a", "\\nleftarrow"); +defineSymbol(math, ams, rel, "\u219b", "\\nrightarrow"); +defineSymbol(math, ams, rel, "\u21cd", "\\nLeftarrow"); +defineSymbol(math, ams, rel, "\u21cf", "\\nRightarrow"); +defineSymbol(math, ams, rel, "\u21ae", "\\nleftrightarrow"); +defineSymbol(math, ams, rel, "\u21ce", "\\nLeftrightarrow"); + +// AMS Misc +defineSymbol(math, ams, rel, "\u25b3", "\\vartriangle"); +defineSymbol(math, ams, textord, "\u210f", "\\hslash"); +defineSymbol(math, ams, textord, "\u25bd", "\\triangledown"); +defineSymbol(math, ams, textord, "\u25ca", "\\lozenge"); +defineSymbol(math, ams, textord, "\u24c8", "\\circledS"); +defineSymbol(math, ams, textord, "\u00ae", "\\circledR"); +defineSymbol(math, ams, textord, "\u2221", "\\measuredangle"); +defineSymbol(math, ams, textord, "\u2204", "\\nexists"); +defineSymbol(math, ams, textord, "\u2127", "\\mho"); +defineSymbol(math, ams, textord, "\u2132", "\\Finv"); +defineSymbol(math, ams, textord, "\u2141", "\\Game"); +defineSymbol(math, ams, textord, "\u006b", "\\Bbbk"); +defineSymbol(math, ams, textord, "\u2035", "\\backprime"); +defineSymbol(math, ams, textord, "\u25b2", "\\blacktriangle"); +defineSymbol(math, ams, textord, "\u25bc", "\\blacktriangledown"); +defineSymbol(math, ams, textord, "\u25a0", "\\blacksquare"); +defineSymbol(math, ams, textord, "\u29eb", "\\blacklozenge"); +defineSymbol(math, ams, textord, "\u2605", "\\bigstar"); +defineSymbol(math, ams, textord, "\u2222", "\\sphericalangle"); +defineSymbol(math, ams, textord, "\u2201", "\\complement"); +defineSymbol(math, ams, textord, "\u00f0", "\\eth"); +defineSymbol(math, ams, textord, "\u2571", "\\diagup"); +defineSymbol(math, ams, textord, "\u2572", "\\diagdown"); +defineSymbol(math, ams, textord, "\u25a1", "\\square"); +defineSymbol(math, ams, textord, "\u25a1", "\\Box"); +defineSymbol(math, ams, textord, "\u25ca", "\\Diamond"); +defineSymbol(math, ams, textord, "\u00a5", "\\yen"); +defineSymbol(math, ams, textord, "\u2713", "\\checkmark"); + +// AMS Hebrew +defineSymbol(math, ams, textord, "\u2136", "\\beth"); +defineSymbol(math, ams, textord, "\u2138", "\\daleth"); +defineSymbol(math, ams, textord, "\u2137", "\\gimel"); + +// AMS Greek +defineSymbol(math, ams, textord, "\u03dd", "\\digamma"); +defineSymbol(math, ams, textord, "\u03f0", "\\varkappa"); + +// AMS Delimiters +defineSymbol(math, ams, open, "\u250c", "\\ulcorner"); +defineSymbol(math, ams, close, "\u2510", "\\urcorner"); +defineSymbol(math, ams, open, "\u2514", "\\llcorner"); +defineSymbol(math, ams, close, "\u2518", "\\lrcorner"); + +// AMS Binary Relations +defineSymbol(math, ams, rel, "\u2266", "\\leqq"); +defineSymbol(math, ams, rel, "\u2a7d", "\\leqslant"); +defineSymbol(math, ams, rel, "\u2a95", "\\eqslantless"); +defineSymbol(math, ams, rel, "\u2272", "\\lesssim"); +defineSymbol(math, ams, rel, "\u2a85", "\\lessapprox"); +defineSymbol(math, ams, rel, "\u224a", "\\approxeq"); +defineSymbol(math, ams, bin, "\u22d6", "\\lessdot"); +defineSymbol(math, ams, rel, "\u22d8", "\\lll"); +defineSymbol(math, ams, rel, "\u2276", "\\lessgtr"); +defineSymbol(math, ams, rel, "\u22da", "\\lesseqgtr"); +defineSymbol(math, ams, rel, "\u2a8b", "\\lesseqqgtr"); +defineSymbol(math, ams, rel, "\u2251", "\\doteqdot"); +defineSymbol(math, ams, rel, "\u2253", "\\risingdotseq"); +defineSymbol(math, ams, rel, "\u2252", "\\fallingdotseq"); +defineSymbol(math, ams, rel, "\u223d", "\\backsim"); +defineSymbol(math, ams, rel, "\u22cd", "\\backsimeq"); +defineSymbol(math, ams, rel, "\u2ac5", "\\subseteqq"); +defineSymbol(math, ams, rel, "\u22d0", "\\Subset"); +defineSymbol(math, ams, rel, "\u228f", "\\sqsubset"); +defineSymbol(math, ams, rel, "\u227c", "\\preccurlyeq"); +defineSymbol(math, ams, rel, "\u22de", "\\curlyeqprec"); +defineSymbol(math, ams, rel, "\u227e", "\\precsim"); +defineSymbol(math, ams, rel, "\u2ab7", "\\precapprox"); +defineSymbol(math, ams, rel, "\u22b2", "\\vartriangleleft"); +defineSymbol(math, ams, rel, "\u22b4", "\\trianglelefteq"); +defineSymbol(math, ams, rel, "\u22a8", "\\vDash"); +defineSymbol(math, ams, rel, "\u22aa", "\\Vvdash"); +defineSymbol(math, ams, rel, "\u2323", "\\smallsmile"); +defineSymbol(math, ams, rel, "\u2322", "\\smallfrown"); +defineSymbol(math, ams, rel, "\u224f", "\\bumpeq"); +defineSymbol(math, ams, rel, "\u224e", "\\Bumpeq"); +defineSymbol(math, ams, rel, "\u2267", "\\geqq"); +defineSymbol(math, ams, rel, "\u2a7e", "\\geqslant"); +defineSymbol(math, ams, rel, "\u2a96", "\\eqslantgtr"); +defineSymbol(math, ams, rel, "\u2273", "\\gtrsim"); +defineSymbol(math, ams, rel, "\u2a86", "\\gtrapprox"); +defineSymbol(math, ams, bin, "\u22d7", "\\gtrdot"); +defineSymbol(math, ams, rel, "\u22d9", "\\ggg"); +defineSymbol(math, ams, rel, "\u2277", "\\gtrless"); +defineSymbol(math, ams, rel, "\u22db", "\\gtreqless"); +defineSymbol(math, ams, rel, "\u2a8c", "\\gtreqqless"); +defineSymbol(math, ams, rel, "\u2256", "\\eqcirc"); +defineSymbol(math, ams, rel, "\u2257", "\\circeq"); +defineSymbol(math, ams, rel, "\u225c", "\\triangleq"); +defineSymbol(math, ams, rel, "\u223c", "\\thicksim"); +defineSymbol(math, ams, rel, "\u2248", "\\thickapprox"); +defineSymbol(math, ams, rel, "\u2ac6", "\\supseteqq"); +defineSymbol(math, ams, rel, "\u22d1", "\\Supset"); +defineSymbol(math, ams, rel, "\u2290", "\\sqsupset"); +defineSymbol(math, ams, rel, "\u227d", "\\succcurlyeq"); +defineSymbol(math, ams, rel, "\u22df", "\\curlyeqsucc"); +defineSymbol(math, ams, rel, "\u227f", "\\succsim"); +defineSymbol(math, ams, rel, "\u2ab8", "\\succapprox"); +defineSymbol(math, ams, rel, "\u22b3", "\\vartriangleright"); +defineSymbol(math, ams, rel, "\u22b5", "\\trianglerighteq"); +defineSymbol(math, ams, rel, "\u22a9", "\\Vdash"); +defineSymbol(math, ams, rel, "\u2223", "\\shortmid"); +defineSymbol(math, ams, rel, "\u2225", "\\shortparallel"); +defineSymbol(math, ams, rel, "\u226c", "\\between"); +defineSymbol(math, ams, rel, "\u22d4", "\\pitchfork"); +defineSymbol(math, ams, rel, "\u221d", "\\varpropto"); +defineSymbol(math, ams, rel, "\u25c0", "\\blacktriangleleft"); +defineSymbol(math, ams, rel, "\u2234", "\\therefore"); +defineSymbol(math, ams, rel, "\u220d", "\\backepsilon"); +defineSymbol(math, ams, rel, "\u25b6", "\\blacktriangleright"); +defineSymbol(math, ams, rel, "\u2235", "\\because"); +defineSymbol(math, ams, rel, "\u22d8", "\\llless"); +defineSymbol(math, ams, rel, "\u22d9", "\\gggtr"); +defineSymbol(math, ams, bin, "\u22b2", "\\lhd"); +defineSymbol(math, ams, bin, "\u22b3", "\\rhd"); +defineSymbol(math, ams, rel, "\u2242", "\\eqsim"); +defineSymbol(math, main, rel, "\u22c8", "\\Join"); +defineSymbol(math, ams, rel, "\u2251", "\\Doteq"); + +// AMS Binary Operators +defineSymbol(math, ams, bin, "\u2214", "\\dotplus"); +defineSymbol(math, ams, bin, "\u2216", "\\smallsetminus"); +defineSymbol(math, ams, bin, "\u22d2", "\\Cap"); +defineSymbol(math, ams, bin, "\u22d3", "\\Cup"); +defineSymbol(math, ams, bin, "\u2a5e", "\\doublebarwedge"); +defineSymbol(math, ams, bin, "\u229f", "\\boxminus"); +defineSymbol(math, ams, bin, "\u229e", "\\boxplus"); +defineSymbol(math, ams, bin, "\u22c7", "\\divideontimes"); +defineSymbol(math, ams, bin, "\u22c9", "\\ltimes"); +defineSymbol(math, ams, bin, "\u22ca", "\\rtimes"); +defineSymbol(math, ams, bin, "\u22cb", "\\leftthreetimes"); +defineSymbol(math, ams, bin, "\u22cc", "\\rightthreetimes"); +defineSymbol(math, ams, bin, "\u22cf", "\\curlywedge"); +defineSymbol(math, ams, bin, "\u22ce", "\\curlyvee"); +defineSymbol(math, ams, bin, "\u229d", "\\circleddash"); +defineSymbol(math, ams, bin, "\u229b", "\\circledast"); +defineSymbol(math, ams, bin, "\u22c5", "\\centerdot"); +defineSymbol(math, ams, bin, "\u22ba", "\\intercal"); +defineSymbol(math, ams, bin, "\u22d2", "\\doublecap"); +defineSymbol(math, ams, bin, "\u22d3", "\\doublecup"); +defineSymbol(math, ams, bin, "\u22a0", "\\boxtimes"); + +// AMS Arrows +defineSymbol(math, ams, rel, "\u21e2", "\\dashrightarrow"); +defineSymbol(math, ams, rel, "\u21e0", "\\dashleftarrow"); +defineSymbol(math, ams, rel, "\u21c7", "\\leftleftarrows"); +defineSymbol(math, ams, rel, "\u21c6", "\\leftrightarrows"); +defineSymbol(math, ams, rel, "\u21da", "\\Lleftarrow"); +defineSymbol(math, ams, rel, "\u219e", "\\twoheadleftarrow"); +defineSymbol(math, ams, rel, "\u21a2", "\\leftarrowtail"); +defineSymbol(math, ams, rel, "\u21ab", "\\looparrowleft"); +defineSymbol(math, ams, rel, "\u21cb", "\\leftrightharpoons"); +defineSymbol(math, ams, rel, "\u21b6", "\\curvearrowleft"); +defineSymbol(math, ams, rel, "\u21ba", "\\circlearrowleft"); +defineSymbol(math, ams, rel, "\u21b0", "\\Lsh"); +defineSymbol(math, ams, rel, "\u21c8", "\\upuparrows"); +defineSymbol(math, ams, rel, "\u21bf", "\\upharpoonleft"); +defineSymbol(math, ams, rel, "\u21c3", "\\downharpoonleft"); +defineSymbol(math, ams, rel, "\u22b8", "\\multimap"); +defineSymbol(math, ams, rel, "\u21ad", "\\leftrightsquigarrow"); +defineSymbol(math, ams, rel, "\u21c9", "\\rightrightarrows"); +defineSymbol(math, ams, rel, "\u21c4", "\\rightleftarrows"); +defineSymbol(math, ams, rel, "\u21a0", "\\twoheadrightarrow"); +defineSymbol(math, ams, rel, "\u21a3", "\\rightarrowtail"); +defineSymbol(math, ams, rel, "\u21ac", "\\looparrowright"); +defineSymbol(math, ams, rel, "\u21b7", "\\curvearrowright"); +defineSymbol(math, ams, rel, "\u21bb", "\\circlearrowright"); +defineSymbol(math, ams, rel, "\u21b1", "\\Rsh"); +defineSymbol(math, ams, rel, "\u21ca", "\\downdownarrows"); +defineSymbol(math, ams, rel, "\u21be", "\\upharpoonright"); +defineSymbol(math, ams, rel, "\u21c2", "\\downharpoonright"); +defineSymbol(math, ams, rel, "\u21dd", "\\rightsquigarrow"); +defineSymbol(math, ams, rel, "\u21dd", "\\leadsto"); +defineSymbol(math, ams, rel, "\u21db", "\\Rrightarrow"); +defineSymbol(math, ams, rel, "\u21be", "\\restriction"); + +defineSymbol(math, main, textord, "\u2018", "`"); +defineSymbol(math, main, textord, "$", "\\$"); +defineSymbol(math, main, textord, "%", "\\%"); +defineSymbol(math, main, textord, "_", "\\_"); +defineSymbol(math, main, textord, "\u2220", "\\angle"); +defineSymbol(math, main, textord, "\u221e", "\\infty"); +defineSymbol(math, main, textord, "\u2032", "\\prime"); +defineSymbol(math, main, textord, "\u25b3", "\\triangle"); +defineSymbol(math, main, textord, "\u0393", "\\Gamma"); +defineSymbol(math, main, textord, "\u0394", "\\Delta"); +defineSymbol(math, main, textord, "\u0398", "\\Theta"); +defineSymbol(math, main, textord, "\u039b", "\\Lambda"); +defineSymbol(math, main, textord, "\u039e", "\\Xi"); +defineSymbol(math, main, textord, "\u03a0", "\\Pi"); +defineSymbol(math, main, textord, "\u03a3", "\\Sigma"); +defineSymbol(math, main, textord, "\u03a5", "\\Upsilon"); +defineSymbol(math, main, textord, "\u03a6", "\\Phi"); +defineSymbol(math, main, textord, "\u03a8", "\\Psi"); +defineSymbol(math, main, textord, "\u03a9", "\\Omega"); +defineSymbol(math, main, textord, "\u00ac", "\\neg"); +defineSymbol(math, main, textord, "\u00ac", "\\lnot"); +defineSymbol(math, main, textord, "\u22a4", "\\top"); +defineSymbol(math, main, textord, "\u22a5", "\\bot"); +defineSymbol(math, main, textord, "\u2205", "\\emptyset"); +defineSymbol(math, ams, textord, "\u2205", "\\varnothing"); +defineSymbol(math, main, mathord, "\u03b1", "\\alpha"); +defineSymbol(math, main, mathord, "\u03b2", "\\beta"); +defineSymbol(math, main, mathord, "\u03b3", "\\gamma"); +defineSymbol(math, main, mathord, "\u03b4", "\\delta"); +defineSymbol(math, main, mathord, "\u03f5", "\\epsilon"); +defineSymbol(math, main, mathord, "\u03b6", "\\zeta"); +defineSymbol(math, main, mathord, "\u03b7", "\\eta"); +defineSymbol(math, main, mathord, "\u03b8", "\\theta"); +defineSymbol(math, main, mathord, "\u03b9", "\\iota"); +defineSymbol(math, main, mathord, "\u03ba", "\\kappa"); +defineSymbol(math, main, mathord, "\u03bb", "\\lambda"); +defineSymbol(math, main, mathord, "\u03bc", "\\mu"); +defineSymbol(math, main, mathord, "\u03bd", "\\nu"); +defineSymbol(math, main, mathord, "\u03be", "\\xi"); +defineSymbol(math, main, mathord, "o", "\\omicron"); +defineSymbol(math, main, mathord, "\u03c0", "\\pi"); +defineSymbol(math, main, mathord, "\u03c1", "\\rho"); +defineSymbol(math, main, mathord, "\u03c3", "\\sigma"); +defineSymbol(math, main, mathord, "\u03c4", "\\tau"); +defineSymbol(math, main, mathord, "\u03c5", "\\upsilon"); +defineSymbol(math, main, mathord, "\u03d5", "\\phi"); +defineSymbol(math, main, mathord, "\u03c7", "\\chi"); +defineSymbol(math, main, mathord, "\u03c8", "\\psi"); +defineSymbol(math, main, mathord, "\u03c9", "\\omega"); +defineSymbol(math, main, mathord, "\u03b5", "\\varepsilon"); +defineSymbol(math, main, mathord, "\u03d1", "\\vartheta"); +defineSymbol(math, main, mathord, "\u03d6", "\\varpi"); +defineSymbol(math, main, mathord, "\u03f1", "\\varrho"); +defineSymbol(math, main, mathord, "\u03c2", "\\varsigma"); +defineSymbol(math, main, mathord, "\u03c6", "\\varphi"); +defineSymbol(math, main, bin, "\u2217", "*"); +defineSymbol(math, main, bin, "+", "+"); +defineSymbol(math, main, bin, "\u2212", "-"); +defineSymbol(math, main, bin, "\u22c5", "\\cdot"); +defineSymbol(math, main, bin, "\u2218", "\\circ"); +defineSymbol(math, main, bin, "\u00f7", "\\div"); +defineSymbol(math, main, bin, "\u00b1", "\\pm"); +defineSymbol(math, main, bin, "\u00d7", "\\times"); +defineSymbol(math, main, bin, "\u2229", "\\cap"); +defineSymbol(math, main, bin, "\u222a", "\\cup"); +defineSymbol(math, main, bin, "\u2216", "\\setminus"); +defineSymbol(math, main, bin, "\u2227", "\\land"); +defineSymbol(math, main, bin, "\u2228", "\\lor"); +defineSymbol(math, main, bin, "\u2227", "\\wedge"); +defineSymbol(math, main, bin, "\u2228", "\\vee"); +defineSymbol(math, main, textord, "\u221a", "\\surd"); +defineSymbol(math, main, open, "(", "("); +defineSymbol(math, main, open, "[", "["); +defineSymbol(math, main, open, "\u27e8", "\\langle"); +defineSymbol(math, main, open, "\u2223", "\\lvert"); +defineSymbol(math, main, open, "\u2225", "\\lVert"); +defineSymbol(math, main, close, ")", ")"); +defineSymbol(math, main, close, "]", "]"); +defineSymbol(math, main, close, "?", "?"); +defineSymbol(math, main, close, "!", "!"); +defineSymbol(math, main, close, "\u27e9", "\\rangle"); +defineSymbol(math, main, close, "\u2223", "\\rvert"); +defineSymbol(math, main, close, "\u2225", "\\rVert"); +defineSymbol(math, main, rel, "=", "="); +defineSymbol(math, main, rel, "<", "<"); +defineSymbol(math, main, rel, ">", ">"); +defineSymbol(math, main, rel, ":", ":"); +defineSymbol(math, main, rel, "\u2248", "\\approx"); +defineSymbol(math, main, rel, "\u2245", "\\cong"); +defineSymbol(math, main, rel, "\u2265", "\\ge"); +defineSymbol(math, main, rel, "\u2265", "\\geq"); +defineSymbol(math, main, rel, "\u2190", "\\gets"); +defineSymbol(math, main, rel, ">", "\\gt"); +defineSymbol(math, main, rel, "\u2208", "\\in"); +defineSymbol(math, main, rel, "\u2209", "\\notin"); +defineSymbol(math, main, rel, "\u2282", "\\subset"); +defineSymbol(math, main, rel, "\u2283", "\\supset"); +defineSymbol(math, main, rel, "\u2286", "\\subseteq"); +defineSymbol(math, main, rel, "\u2287", "\\supseteq"); +defineSymbol(math, ams, rel, "\u2288", "\\nsubseteq"); +defineSymbol(math, ams, rel, "\u2289", "\\nsupseteq"); +defineSymbol(math, main, rel, "\u22a8", "\\models"); +defineSymbol(math, main, rel, "\u2190", "\\leftarrow"); +defineSymbol(math, main, rel, "\u2264", "\\le"); +defineSymbol(math, main, rel, "\u2264", "\\leq"); +defineSymbol(math, main, rel, "<", "\\lt"); +defineSymbol(math, main, rel, "\u2260", "\\ne"); +defineSymbol(math, main, rel, "\u2260", "\\neq"); +defineSymbol(math, main, rel, "\u2192", "\\rightarrow"); +defineSymbol(math, main, rel, "\u2192", "\\to"); +defineSymbol(math, ams, rel, "\u2271", "\\ngeq"); +defineSymbol(math, ams, rel, "\u2270", "\\nleq"); +defineSymbol(math, main, spacing, null, "\\!"); +defineSymbol(math, main, spacing, "\u00a0", "\\ "); +defineSymbol(math, main, spacing, "\u00a0", "~"); +defineSymbol(math, main, spacing, null, "\\,"); +defineSymbol(math, main, spacing, null, "\\:"); +defineSymbol(math, main, spacing, null, "\\;"); +defineSymbol(math, main, spacing, null, "\\enspace"); +defineSymbol(math, main, spacing, null, "\\qquad"); +defineSymbol(math, main, spacing, null, "\\quad"); +defineSymbol(math, main, spacing, "\u00a0", "\\space"); +defineSymbol(math, main, punct, ",", ","); +defineSymbol(math, main, punct, ";", ";"); +defineSymbol(math, main, punct, ":", "\\colon"); +defineSymbol(math, ams, bin, "\u22bc", "\\barwedge"); +defineSymbol(math, ams, bin, "\u22bb", "\\veebar"); +defineSymbol(math, main, bin, "\u2299", "\\odot"); +defineSymbol(math, main, bin, "\u2295", "\\oplus"); +defineSymbol(math, main, bin, "\u2297", "\\otimes"); +defineSymbol(math, main, textord, "\u2202", "\\partial"); +defineSymbol(math, main, bin, "\u2298", "\\oslash"); +defineSymbol(math, ams, bin, "\u229a", "\\circledcirc"); +defineSymbol(math, ams, bin, "\u22a1", "\\boxdot"); +defineSymbol(math, main, bin, "\u25b3", "\\bigtriangleup"); +defineSymbol(math, main, bin, "\u25bd", "\\bigtriangledown"); +defineSymbol(math, main, bin, "\u2020", "\\dagger"); +defineSymbol(math, main, bin, "\u22c4", "\\diamond"); +defineSymbol(math, main, bin, "\u22c6", "\\star"); +defineSymbol(math, main, bin, "\u25c3", "\\triangleleft"); +defineSymbol(math, main, bin, "\u25b9", "\\triangleright"); +defineSymbol(math, main, open, "{", "\\{"); +defineSymbol(math, main, close, "}", "\\}"); +defineSymbol(math, main, open, "{", "\\lbrace"); +defineSymbol(math, main, close, "}", "\\rbrace"); +defineSymbol(math, main, open, "[", "\\lbrack"); +defineSymbol(math, main, close, "]", "\\rbrack"); +defineSymbol(math, main, open, "\u230a", "\\lfloor"); +defineSymbol(math, main, close, "\u230b", "\\rfloor"); +defineSymbol(math, main, open, "\u2308", "\\lceil"); +defineSymbol(math, main, close, "\u2309", "\\rceil"); +defineSymbol(math, main, textord, "\\", "\\backslash"); +defineSymbol(math, main, textord, "\u2223", "|"); +defineSymbol(math, main, textord, "\u2223", "\\vert"); +defineSymbol(math, main, textord, "\u2225", "\\|"); +defineSymbol(math, main, textord, "\u2225", "\\Vert"); +defineSymbol(math, main, rel, "\u2191", "\\uparrow"); +defineSymbol(math, main, rel, "\u21d1", "\\Uparrow"); +defineSymbol(math, main, rel, "\u2193", "\\downarrow"); +defineSymbol(math, main, rel, "\u21d3", "\\Downarrow"); +defineSymbol(math, main, rel, "\u2195", "\\updownarrow"); +defineSymbol(math, main, rel, "\u21d5", "\\Updownarrow"); +defineSymbol(math, math, op, "\u2210", "\\coprod"); +defineSymbol(math, math, op, "\u22c1", "\\bigvee"); +defineSymbol(math, math, op, "\u22c0", "\\bigwedge"); +defineSymbol(math, math, op, "\u2a04", "\\biguplus"); +defineSymbol(math, math, op, "\u22c2", "\\bigcap"); +defineSymbol(math, math, op, "\u22c3", "\\bigcup"); +defineSymbol(math, math, op, "\u222b", "\\int"); +defineSymbol(math, math, op, "\u222b", "\\intop"); +defineSymbol(math, math, op, "\u222c", "\\iint"); +defineSymbol(math, math, op, "\u222d", "\\iiint"); +defineSymbol(math, math, op, "\u220f", "\\prod"); +defineSymbol(math, math, op, "\u2211", "\\sum"); +defineSymbol(math, math, op, "\u2a02", "\\bigotimes"); +defineSymbol(math, math, op, "\u2a01", "\\bigoplus"); +defineSymbol(math, math, op, "\u2a00", "\\bigodot"); +defineSymbol(math, math, op, "\u222e", "\\oint"); +defineSymbol(math, math, op, "\u2a06", "\\bigsqcup"); +defineSymbol(math, math, op, "\u222b", "\\smallint"); +defineSymbol(math, main, inner, "\u2026", "\\ldots"); +defineSymbol(math, main, inner, "\u22ef", "\\cdots"); +defineSymbol(math, main, inner, "\u22f1", "\\ddots"); +defineSymbol(math, main, textord, "\u22ee", "\\vdots"); +defineSymbol(math, main, accent, "\u00b4", "\\acute"); +defineSymbol(math, main, accent, "\u0060", "\\grave"); +defineSymbol(math, main, accent, "\u00a8", "\\ddot"); +defineSymbol(math, main, accent, "\u007e", "\\tilde"); +defineSymbol(math, main, accent, "\u00af", "\\bar"); +defineSymbol(math, main, accent, "\u02d8", "\\breve"); +defineSymbol(math, main, accent, "\u02c7", "\\check"); +defineSymbol(math, main, accent, "\u005e", "\\hat"); +defineSymbol(math, main, accent, "\u20d7", "\\vec"); +defineSymbol(math, main, accent, "\u02d9", "\\dot"); +defineSymbol(math, main, mathord, "\u0131", "\\imath"); +defineSymbol(math, main, mathord, "\u0237", "\\jmath"); + +defineSymbol(text, main, spacing, "\u00a0", "\\ "); +defineSymbol(text, main, spacing, "\u00a0", " "); +defineSymbol(text, main, spacing, "\u00a0", "~"); + +// There are lots of symbols which are the same, so we add them in afterwards. + +// All of these are textords in math mode +var mathTextSymbols = "0123456789/@.\""; +for (var i = 0; i < mathTextSymbols.length; i++) { + var ch = mathTextSymbols.charAt(i); + defineSymbol(math, main, textord, ch, ch); +} + +// All of these are textords in text mode +var textSymbols = "0123456789`!@*()-=+[]'\";:?/.,"; +for (var i = 0; i < textSymbols.length; i++) { + var ch = textSymbols.charAt(i); + defineSymbol(text, main, textord, ch, ch); +} + +// All of these are textords in text mode, and mathords in math mode +var letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; +for (var i = 0; i < letters.length; i++) { + var ch = letters.charAt(i); + defineSymbol(math, main, mathord, ch, ch); + defineSymbol(text, main, textord, ch, ch); +} diff --git a/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/utils.js b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/utils.js new file mode 100644 index 0000000..078bef1 --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/lib/katex/src/src/utils.js @@ -0,0 +1,105 @@ +/** + * This file contains a list of utility functions which are useful in other + * files. + */ + +/** + * Provide an `indexOf` function which works in IE8, but defers to native if + * possible. + */ +var nativeIndexOf = Array.prototype.indexOf; +var indexOf = function(list, elem) { + if (list == null) { + return -1; + } + if (nativeIndexOf && list.indexOf === nativeIndexOf) { + return list.indexOf(elem); + } + var i = 0, l = list.length; + for (; i < l; i++) { + if (list[i] === elem) { + return i; + } + } + return -1; +}; + +/** + * Return whether an element is contained in a list + */ +var contains = function(list, elem) { + return indexOf(list, elem) !== -1; +}; + +/** + * Provide a default value if a setting is undefined + */ +var deflt = function(setting, defaultIfUndefined) { + return setting === undefined ? defaultIfUndefined : setting; +}; + +// hyphenate and escape adapted from Facebook's React under Apache 2 license + +var uppercase = /([A-Z])/g; +var hyphenate = function(str) { + return str.replace(uppercase, "-$1").toLowerCase(); +}; + +var ESCAPE_LOOKUP = { + "&": "&", + ">": ">", + "<": "<", + "\"": """, + "'": "'" +}; + +var ESCAPE_REGEX = /[&><"']/g; + +function escaper(match) { + return ESCAPE_LOOKUP[match]; +} + +/** + * Escapes text to prevent scripting attacks. + * + * @param {*} text Text value to escape. + * @return {string} An escaped string. + */ +function escape(text) { + return ("" + text).replace(ESCAPE_REGEX, escaper); +} + +/** + * A function to set the text content of a DOM element in all supported + * browsers. Note that we don't define this if there is no document. + */ +var setTextContent; +if (typeof document !== "undefined") { + var testNode = document.createElement("span"); + if ("textContent" in testNode) { + setTextContent = function(node, text) { + node.textContent = text; + }; + } else { + setTextContent = function(node, text) { + node.innerText = text; + }; + } +} + +/** + * A function to clear a node. + */ +function clearNode(node) { + setTextContent(node, ""); +} + +module.exports = { + contains: contains, + deflt: deflt, + escape: escape, + hyphenate: hyphenate, + indexOf: indexOf, + setTextContent: setTextContent, + clearNode: clearNode +}; diff --git a/debian/missing-sources/books/xdoc/fancy/render.js b/debian/missing-sources/books/xdoc/fancy/render.js new file mode 100644 index 0000000..5d1a5eb --- /dev/null +++ b/debian/missing-sources/books/xdoc/fancy/render.js @@ -0,0 +1 @@ +This is a base64 encoded version of books/xdoc/fancy/render.xsl. diff --git a/debian/missing-sources/doc/manual/render.js b/debian/missing-sources/doc/manual/render.js new file mode 100644 index 0000000..5d1a5eb --- /dev/null +++ b/debian/missing-sources/doc/manual/render.js @@ -0,0 +1 @@ +This is a base64 encoded version of books/xdoc/fancy/render.xsl. diff --git a/debian/missing-sources/doc/manual/xdata.js b/debian/missing-sources/doc/manual/xdata.js new file mode 100644 index 0000000..f4bd6ec --- /dev/null +++ b/debian/missing-sources/doc/manual/xdata.js @@ -0,0 +1 @@ +This is a compiled database of "defxdoc" commands scattered throughout the lisp files found under books/. diff --git a/debian/old/acl2-doc.doc-base b/debian/old/acl2-doc.doc-base new file mode 100644 index 0000000..f402a2f --- /dev/null +++ b/debian/old/acl2-doc.doc-base @@ -0,0 +1,10 @@ +Document: acl2 +Title: Debian ACL2 Manual +Author: Matt Kaufmann,kaufmann@cs.utexas.edu and J Strother Moore,moore@cs.utexas.edu +Abstract: This manual documents the ACL2 computational logic system. +Section: Science/Mathematics + +Format: HTML +Index: /usr/share/doc/acl2-doc/HTML/acl2-doc.html +Files: /usr/share/doc/acl2-doc/HTML/*.html + diff --git a/debian/old/patches.in b/debian/old/patches.in new file mode 100644 index 0000000..9fdd9f1 --- /dev/null +++ b/debian/old/patches.in @@ -0,0 +1,25 @@ +--- v2-8-alpha-03-17/books/interface/emacs/acl2-interface.el 2004-03-17 05:43:50.000000000 +0000 ++++ acl2-2.8/books/interface/emacs/acl2-interface.el 2004-03-23 20:11:08.000000000 +0000 +@@ -28,13 +28,18 @@ + ;; ---------------------------------------------------------------------- + ;; Load all of the various acl2-interface files, if necessary. + +-(load "inf-acl2.el") ;(require 'inf-acl2) +-(load "mfm-acl2.el") ;(require 'mfm-acl2) +-(load "interface-macros.el") ;(require 'interface-macros) ++;(load "inf-acl2.el") ;(require 'inf-acl2) ++;(load "mfm-acl2.el") ;(require 'mfm-acl2) ++;(load "interface-macros.el") ;(require 'interface-macros) ++ ++(require 'inf-acl2) ++(require 'mfm-acl2) ++(require 'interface-macros) + + (update-mode-menu-alist *acl2-user-map-interface*) + +-(load "acl2-interface-functions.el") ++;(load "acl2-interface-functions.el") ++(load "acl2-interface-functions") + + ;; ---------------------------------------------------------------------- + ;; Specials used by functions in interface-macros.el. diff --git a/debian/patches/(setq-si::*optimize-maximum-pages*-nil)-in-elementary-bounders.acl2 b/debian/patches/(setq-si::*optimize-maximum-pages*-nil)-in-elementary-bounders.acl2 new file mode 100644 index 0000000..364c304 --- /dev/null +++ b/debian/patches/(setq-si::*optimize-maximum-pages*-nil)-in-elementary-bounders.acl2 @@ -0,0 +1,36 @@ +Description: <short summary of the patch> + TODO: Put a short summary on the line above and replace this paragraph + with a longer explanation of this change. Complete the meta-information + with other relevant fields (see below for details). To make it easier, the + information below has been extracted from the changelog. Adjust it or drop + it. + . + acl2 (6.2-5) unstable; urgency=low + . + * (setq si::*optimize-maximum-pages* nil) in elementary-bounders.acl2 + * build-dep against latest gcl +Author: Camm Maguire <camm@debian.org> + +--- +The information above should follow the Patch Tagging Guidelines, please +checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here +are templates for supplementary fields that you might want to add: + +Origin: <vendor|upstream|other>, <url of original patch> +Bug: <url in upstream bugtracker> +Bug-Debian: http://bugs.debian.org/<bugnumber> +Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber> +Forwarded: <no|not-needed|url proving that it has been forwarded> +Reviewed-By: <name and email of someone who approved the patch> +Last-Update: <YYYY-MM-DD> + +--- acl2-6.2.orig/books/tau/bounders/elementary-bounders.acl2 ++++ acl2-6.2/books/tau/bounders/elementary-bounders.acl2 +@@ -1,4 +1,7 @@ + #+acl2-par + (set-waterfall-parallelism t) + ++#+gcl ++(setq si::*optimize-maximum-pages* nil) ++ + (certify-book "elementary-bounders") diff --git a/debian/patches/4.3 b/debian/patches/4.3 new file mode 100644 index 0000000..6e9d453 --- /dev/null +++ b/debian/patches/4.3 @@ -0,0 +1,38 @@ +Description: <short summary of the patch> + TODO: Put a short summary on the line above and replace this paragraph + with a longer explanation of this change. Complete the meta-information + with other relevant fields (see below for details). To make it easier, the + information below has been extracted from the changelog. Adjust it or drop + it. + . + acl2 (4.3-1) unstable; urgency=low + . + * New upstream release +Author: Camm Maguire <camm@debian.org> + +--- +The information above should follow the Patch Tagging Guidelines, please +checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here +are templates for supplementary fields that you might want to add: + +Origin: <vendor|upstream|other>, <url of original patch> +Bug: <url in upstream bugtracker> +Bug-Debian: http://bugs.debian.org/<bugnumber> +Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber> +Forwarded: <no|not-needed|url proving that it has been forwarded> +Reviewed-By: <name and email of someone who approved the patch> +Last-Update: <YYYY-MM-DD> + +Index: acl2-5.0/acl2-fns.lisp +=================================================================== +--- acl2-5.0.orig/acl2-fns.lisp 2012-08-20 01:06:11.000000000 +0000 ++++ acl2-5.0/acl2-fns.lisp 2012-08-24 18:45:49.000000000 +0000 +@@ -1354,7 +1354,7 @@ + + #+gcl + (cond +- ((gcl-version->= 2 7 0) ++ (t;(gcl-version->= 2 7 0) + + ; It seems that GCL 2.7.0 has had problems with user-homedir-pathname in static + ; versions because of how some system functions are relocated. So we define diff --git a/debian/patches/4.3a b/debian/patches/4.3a new file mode 100644 index 0000000..ab3249b --- /dev/null +++ b/debian/patches/4.3a @@ -0,0 +1,36 @@ +Description: <short summary of the patch> + TODO: Put a short summary on the line above and replace this paragraph + with a longer explanation of this change. Complete the meta-information + with other relevant fields (see below for details). To make it easier, the + information below has been extracted from the changelog. Adjust it or drop + it. + . + acl2 (4.3-1) unstable; urgency=low + . + * New upstream release +Author: Camm Maguire <camm@debian.org> + +--- +The information above should follow the Patch Tagging Guidelines, please +checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here +are templates for supplementary fields that you might want to add: + +Origin: <vendor|upstream|other>, <url of original patch> +Bug: <url in upstream bugtracker> +Bug-Debian: http://bugs.debian.org/<bugnumber> +Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber> +Forwarded: <no|not-needed|url proving that it has been forwarded> +Reviewed-By: <name and email of someone who approved the patch> +Last-Update: <YYYY-MM-DD> + +--- acl2-4.3.orig/GNUmakefile ++++ acl2-4.3/GNUmakefile +@@ -966,7 +966,7 @@ arch: full init move-large regression-fr + mini-proveall: + @rm -rf mini-proveall.out + @echo '(value :q) (lp) (mini-proveall)' | ./${PREFIXsaved_acl2} > mini-proveall.out +- @(grep '^ ORDERED-SYMBOL-ALISTP-REMOVE-FIRST-PAIR-TEST' mini-proveall.out > /dev/null) || \ ++ @(grep '^ ORDERED-SYMBOL-ALISTP-DELETE-ASSOC-EQ-TEST' mini-proveall.out > /dev/null) || \ + (echo 'Mini-proveall failed!' ; ls -l ./${PREFIXsaved_acl2}; cat mini-proveall.out ; exit 1) + @echo 'Mini-proveall passed.' + diff --git a/debian/patches/abort-centaurvltop-if-insufficient-memory b/debian/patches/abort-centaurvltop-if-insufficient-memory new file mode 100644 index 0000000..8646a49 --- /dev/null +++ b/debian/patches/abort-centaurvltop-if-insufficient-memory @@ -0,0 +1,36 @@ +Description: <short summary of the patch> + TODO: Put a short summary on the line above and replace this paragraph + with a longer explanation of this change. Complete the meta-information + with other relevant fields (see below for details). To make it easier, the + information below has been extracted from the changelog. Adjust it or drop + it. + . + acl2 (6.5-3) unstable; urgency=medium + . + * build-dep latest gcl + * abort centaur/vl/top cert if insufficient memory (mips autobuild) +Author: Camm Maguire <camm@debian.org> + +--- +The information above should follow the Patch Tagging Guidelines, please +checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here +are templates for supplementary fields that you might want to add: + +Origin: <vendor|upstream|other>, <url of original patch> +Bug: <url in upstream bugtracker> +Bug-Debian: https://bugs.debian.org/<bugnumber> +Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber> +Forwarded: <no|not-needed|url proving that it has been forwarded> +Reviewed-By: <name and email of someone who approved the patch> +Last-Update: <YYYY-MM-DD> + +--- acl2-6.5.orig/books/centaur/vl/top.acl2 ++++ acl2-6.5/books/centaur/vl/top.acl2 +@@ -1,6 +1,7 @@ + (in-package "ACL2") + #+gcl (acl2::value :q) + #+gcl (setq si::*optimize-maximum-pages* nil) ++#+gcl (let ((w (multiple-value-bind (a b c d) (si::heap-report) (/ (- d c) (/ a 8))))) (when #+native-reloc t #-native-reloc (< w 500000000) (bye -1))) + #+gcl (acl2::lp) + (include-book "portcullis") + ; cert-flags: ? t :ttags :all diff --git a/debian/patches/add-ttag-comment-to-parsetree.acl2 b/debian/patches/add-ttag-comment-to-parsetree.acl2 new file mode 100644 index 0000000..d385c99 --- /dev/null +++ b/debian/patches/add-ttag-comment-to-parsetree.acl2 @@ -0,0 +1,37 @@ +Description: <short summary of the patch> + TODO: Put a short summary on the line above and replace this paragraph + with a longer explanation of this change. Complete the meta-information + with other relevant fields (see below for details). To make it easier, the + information below has been extracted from the changelog. Adjust it or drop + it. + . + acl2 (7.4dfsg-2) unstable; urgency=medium + . + * Set GCL_MULTIPROCESS_MEMORY_POOL for certifications + * build-dep latest gcl for mips64el fix + * Bug fix: "build fails on mips (mips-aql-05)", thanks to Héctor Orón + Martínez (Closes: #863224). + * mxgot .acl2 files patch +Author: Camm Maguire <camm@debian.org> +Bug-Debian: https://bugs.debian.org/863224 + +--- +The information above should follow the Patch Tagging Guidelines, please +checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here +are templates for supplementary fields that you might want to add: + +Origin: <vendor|upstream|other>, <url of original patch> +Bug: <url in upstream bugtracker> +Bug-Debian: https://bugs.debian.org/<bugnumber> +Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber> +Forwarded: <no|not-needed|url proving that it has been forwarded> +Reviewed-By: <name and email of someone who approved the patch> +Last-Update: 2017-05-30 + +--- acl2-7.4dfsg.orig/books/centaur/vl2014/parsetree.acl2 ++++ acl2-7.4dfsg/books/centaur/vl2014/parsetree.acl2 +@@ -1,3 +1,4 @@ + :q + #+(and gcl mips64el)(setq compiler::*cc* (concatenate 'string compiler::*cc* " -mxgot ")) + (lp) ++; cert-flags: ? t :ttags :all diff --git a/debian/patches/add-upstream-certificate-relocation-patch-to-other-events.lisp b/debian/patches/add-upstream-certificate-relocation-patch-to-other-events.lisp new file mode 100644 index 0000000..f26deb3 --- /dev/null +++ b/debian/patches/add-upstream-certificate-relocation-patch-to-other-events.lisp @@ -0,0 +1,43 @@ +Description: <short summary of the patch> + TODO: Put a short summary on the line above and replace this paragraph + with a longer explanation of this change. Complete the meta-information + with other relevant fields (see below for details). To make it easier, the + information below has been extracted from the changelog. Adjust it or drop + it. + . + acl2 (6.2-8) unstable; urgency=low + . + * Allow certification failures for 1) dlopen machines, as we cannot + control the surpassed 1024 maximum dlopen limit, and 2) machines with + an insufficient hard limit on data segment size (e.g. kfreebsd-i386, or any + machine which cannot brk 1Gb). + * add build-dep on texinfo + * add upstream certificate relocation patch to other-events.lisp +Author: Camm Maguire <camm@debian.org> + +--- +The information above should follow the Patch Tagging Guidelines, please +checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here +are templates for supplementary fields that you might want to add: + +Origin: <vendor|upstream|other>, <url of original patch> +Bug: <url in upstream bugtracker> +Bug-Debian: http://bugs.debian.org/<bugnumber> +Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber> +Forwarded: <no|not-needed|url proving that it has been forwarded> +Reviewed-By: <name and email of someone who approved the patch> +Last-Update: <YYYY-MM-DD> + +--- acl2-6.2.orig/other-events.lisp ++++ acl2-6.2/other-events.lisp +@@ -12970,7 +12970,9 @@ + certification-file + (replace-string-prefix-in-tree + post-alist3 old-dir (length old-dir) new-dir) +- expansion-alist pcert-info cert-op ctx state)) ++ (replace-string-prefix-in-tree ++ expansion-alist old-dir (length old-dir) new-dir) ++ pcert-info cert-op ctx state)) + + (defun make-certificate-file (file portcullis post-alist1 post-alist2 + expansion-alist pcert-info diff --git a/debian/patches/clean-interface b/debian/patches/clean-interface new file mode 100644 index 0000000..d4865f0 --- /dev/null +++ b/debian/patches/clean-interface @@ -0,0 +1,50 @@ +Description: <short summary of the patch> + TODO: Put a short summary on the line above and replace this paragraph + with a longer explanation of this change. Complete the meta-information + with other relevant fields (see below for details). To make it easier, the + information below has been extracted from the changelog. Adjust it or drop + it. + . + acl2 (6.0-1) unstable; urgency=low + . + * New upstream release +Author: Camm Maguire <camm@debian.org> + +--- +The information above should follow the Patch Tagging Guidelines, please +checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here +are templates for supplementary fields that you might want to add: + +Origin: <vendor|upstream|other>, <url of original patch> +Bug: <url in upstream bugtracker> +Bug-Debian: http://bugs.debian.org/<bugnumber> +Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber> +Forwarded: <no|not-needed|url proving that it has been forwarded> +Reviewed-By: <name and email of someone who approved the patch> +Last-Update: <YYYY-MM-DD> + +--- acl2-6.0.orig/interface/emacs/acl2-interface.el ++++ acl2-6.0/interface/emacs/acl2-interface.el +@@ -28,18 +28,13 @@ + ;; ---------------------------------------------------------------------- + ;; Load all of the various acl2-interface files, if necessary. + +-;(load "inf-acl2.el") ;(require 'inf-acl2) +-;(load "mfm-acl2.el") ;(require 'mfm-acl2) +-;(load "interface-macros.el") ;(require 'interface-macros) +- +-(require 'inf-acl2) +-(require 'mfm-acl2) +-(require 'interface-macros) ++(load "inf-acl2.el") ;(require 'inf-acl2) ++(load "mfm-acl2.el") ;(require 'mfm-acl2) ++(load "interface-macros.el") ;(require 'interface-macros) + + (update-mode-menu-alist *acl2-user-map-interface*) + +-;(load "acl2-interface-functions.el") +-(load "acl2-interface-functions") ++(load "acl2-interface-functions.el") + + ;; ---------------------------------------------------------------------- + ;; Specials used by functions in interface-macros.el. diff --git a/debian/patches/consolidate-in-6.2 b/debian/patches/consolidate-in-6.2 new file mode 100644 index 0000000..f76e4fc --- /dev/null +++ b/debian/patches/consolidate-in-6.2 @@ -0,0 +1,50 @@ +Description: <short summary of the patch> + TODO: Put a short summary on the line above and replace this paragraph + with a longer explanation of this change. Complete the meta-information + with other relevant fields (see below for details). To make it easier, the + information below has been extracted from the changelog. Adjust it or drop + it. + . + acl2 (6.2-1) UNRELEASED; urgency=low + . + * New upstream release +Author: Camm Maguire <camm@localhost> + +--- +The information above should follow the Patch Tagging Guidelines, please +checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here +are templates for supplementary fields that you might want to add: + +Origin: <vendor|upstream|other>, <url of original patch> +Bug: <url in upstream bugtracker> +Bug-Debian: http://bugs.debian.org/<bugnumber> +Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber> +Forwarded: <no|not-needed|url proving that it has been forwarded> +Reviewed-By: <name and email of someone who approved the patch> +Last-Update: <YYYY-MM-DD> + +--- acl2-6.2.orig/books/interface/emacs/acl2-interface.el ++++ acl2-6.2/books/interface/emacs/acl2-interface.el +@@ -28,13 +28,18 @@ + ;; ---------------------------------------------------------------------- + ;; Load all of the various acl2-interface files, if necessary. + +-(load "inf-acl2.el") ;(require 'inf-acl2) +-(load "mfm-acl2.el") ;(require 'mfm-acl2) +-(load "interface-macros.el") ;(require 'interface-macros) ++;(load "inf-acl2.el") ;(require 'inf-acl2) ++;(load "mfm-acl2.el") ;(require 'mfm-acl2) ++;(load "interface-macros.el") ;(require 'interface-macros) ++ ++(require 'inf-acl2) ++(require 'mfm-acl2) ++(require 'interface-macros) + + (update-mode-menu-alist *acl2-user-map-interface*) + +-(load "acl2-interface-functions.el") ++;(load "acl2-interface-functions.el") ++(load "acl2-interface-functions") + + ;; ---------------------------------------------------------------------- + ;; Specials used by functions in interface-macros.el. diff --git a/debian/patches/debian-changes-4.1-5 b/debian/patches/debian-changes-4.1-5 new file mode 100644 index 0000000..f303a4d --- /dev/null +++ b/debian/patches/debian-changes-4.1-5 @@ -0,0 +1,35 @@ +Description: Upstream changes introduced in version 4.1-5 + This patch has been created by dpkg-source during the package build. + Here's the last changelog entry, hopefully it gives details on why + those changes were made: + . + acl2 (4.1-5) unstable; urgency=low + . + * build depend on latest gcl + * turn off si::*optimize-maximum-pages* in reverse-by-separation.acl2 + * remove unnecessary patch from serialize-tests.lisp + . + The person named in the Author field signed this changelog entry. +Author: Camm Maguire <camm@debian.org> + +--- +The information above should follow the Patch Tagging Guidelines, please +checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here +are templates for supplementary fields that you might want to add: + +Origin: <vendor|upstream|other>, <url of original patch> +Bug: <url in upstream bugtracker> +Bug-Debian: http://bugs.debian.org/<bugnumber> +Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber> +Forwarded: <no|not-needed|url proving that it has been forwarded> +Reviewed-By: <name and email of someone who approved the patch> +Last-Update: <YYYY-MM-DD> + +--- acl2-4.1.orig/books/misc/misc2/reverse-by-separation.acl2 ++++ acl2-4.1/books/misc/misc2/reverse-by-separation.acl2 +@@ -1,2 +1,5 @@ ++(acl2::value :q) ++(setq si:*optimize-maximum-pages* nil) ++(acl2::lp) + (include-book "coi/bags/top" :dir :system) + (certify-book "reverse-by-separation" 1) diff --git a/debian/patches/do-not-pre-allocate-contiguous-blocks-in-acl2.lisp b/debian/patches/do-not-pre-allocate-contiguous-blocks-in-acl2.lisp new file mode 100644 index 0000000..1ddaeb2 --- /dev/null +++ b/debian/patches/do-not-pre-allocate-contiguous-blocks-in-acl2.lisp @@ -0,0 +1,42 @@ +Description: <short summary of the patch> + TODO: Put a short summary on the line above and replace this paragraph + with a longer explanation of this change. Complete the meta-information + with other relevant fields (see below for details). To make it easier, the + information below has been extracted from the changelog. Adjust it or drop + it. + . + acl2 (7.1-3) unstable; urgency=medium + . + * don't pre-allocate contiguous blocks in acl2.lisp +Author: Camm Maguire <camm@debian.org> + +--- +The information above should follow the Patch Tagging Guidelines, please +checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here +are templates for supplementary fields that you might want to add: + +Origin: <vendor|upstream|other>, <url of original patch> +Bug: <url in upstream bugtracker> +Bug-Debian: https://bugs.debian.org/<bugnumber> +Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber> +Forwarded: <no|not-needed|url proving that it has been forwarded> +Reviewed-By: <name and email of someone who approved the patch> +Last-Update: <YYYY-MM-DD> + +--- acl2-7.1.orig/acl2.lisp ++++ acl2-7.1/acl2.lisp +@@ -506,10 +506,10 @@ + + ; Camm Maguire has suggested, on 9/22/2013, the following forms, which allowed + ; him to complete an ACL2 regresssion using 2.6.10pre. +-#+gcl +-(progn +- (si::allocate 'contiguous 15000 t) +- (si::allocate-sgc 'contiguous 15000 100000 10)) ++;; #+gcl ++;; (progn ++;; (si::allocate 'contiguous 15000 t) ++;; (si::allocate-sgc 'contiguous 15000 100000 10)) + + ; The following avoids errors from extra right parentheses, but we leave it + ; commented out since it doesn't seem important enough to merit messing around diff --git a/debian/patches/fix-elementary-bounders.acl2 b/debian/patches/fix-elementary-bounders.acl2 new file mode 100644 index 0000000..ead0e9d --- /dev/null +++ b/debian/patches/fix-elementary-bounders.acl2 @@ -0,0 +1,38 @@ +Description: <short summary of the patch> + TODO: Put a short summary on the line above and replace this paragraph + with a longer explanation of this change. Complete the meta-information + with other relevant fields (see below for details). To make it easier, the + information below has been extracted from the changelog. Adjust it or drop + it. + . + acl2 (6.2-5) unstable; urgency=low + . + * (setq si::*optimize-maximum-pages* nil) in elementary-bounders.acl2 + * build-dep against latest gcl +Author: Camm Maguire <camm@debian.org> + +--- +The information above should follow the Patch Tagging Guidelines, please +checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here +are templates for supplementary fields that you might want to add: + +Origin: <vendor|upstream|other>, <url of original patch> +Bug: <url in upstream bugtracker> +Bug-Debian: http://bugs.debian.org/<bugnumber> +Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber> +Forwarded: <no|not-needed|url proving that it has been forwarded> +Reviewed-By: <name and email of someone who approved the patch> +Last-Update: <YYYY-MM-DD> + +--- acl2-6.2.orig/books/tau/bounders/elementary-bounders.acl2 ++++ acl2-6.2/books/tau/bounders/elementary-bounders.acl2 +@@ -1,7 +1,7 @@ + #+acl2-par + (set-waterfall-parallelism t) +- ++:q + #+gcl + (setq si::*optimize-maximum-pages* nil) +- ++(lp) + (certify-book "elementary-bounders") diff --git a/debian/patches/grammar-reader-dependency-patch b/debian/patches/grammar-reader-dependency-patch new file mode 100644 index 0000000..081184e --- /dev/null +++ b/debian/patches/grammar-reader-dependency-patch @@ -0,0 +1,46 @@ +Description: <short summary of the patch> + TODO: Put a short summary on the line above and replace this paragraph + with a longer explanation of this change. Complete the meta-information + with other relevant fields (see below for details). To make it easier, the + information below has been extracted from the changelog. Adjust it or drop + it. + . + acl2 (6.5-1) unstable; urgency=low + . + * New upstream release +Author: Camm Maguire <camm@debian.org> + +--- +The information above should follow the Patch Tagging Guidelines, please +checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here +are templates for supplementary fields that you might want to add: + +Origin: <vendor|upstream|other>, <url of original patch> +Bug: <url in upstream bugtracker> +Bug-Debian: http://bugs.debian.org/<bugnumber> +Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber> +Forwarded: <no|not-needed|url proving that it has been forwarded> +Reviewed-By: <name and email of someone who approved the patch> +Last-Update: <YYYY-MM-DD> + +--- acl2-6.5.orig/books/parsers/earley/grammar-reader.lisp ++++ acl2-6.5/books/parsers/earley/grammar-reader.lisp +@@ -673,7 +673,7 @@ + + (encapsulate + () +- (local (include-book ++ (local + + ; Provides us with the following, necessary for read-lexicon-line-strong + +@@ -681,7 +681,8 @@ + ;;; n (not (equal x ""))) + ;;; (< 0 (length x))))) + +- "str/arithmetic" :dir :system)) ++ ;; [Jared]: removed newline to un-fool dependency scanner ++ (include-book "str/arithmetic" :dir :system)) + + (defthm read-lexicon-line-strong + (implies (and diff --git a/debian/patches/infix-pathname-fix b/debian/patches/infix-pathname-fix new file mode 100644 index 0000000..ad2252c --- /dev/null +++ b/debian/patches/infix-pathname-fix @@ -0,0 +1,48 @@ +Description: <short summary of the patch> + TODO: Put a short summary on the line above and replace this paragraph + with a longer explanation of this change. Complete the meta-information + with other relevant fields (see below for details). To make it easier, the + information below has been extracted from the changelog. Adjust it or drop + it. + . + acl2 (7.2dfsg-3) unstable; urgency=medium + . + * build-dep against latest gcl + * upstream pathname patch +Author: Camm Maguire <camm@debian.org> + +--- +The information above should follow the Patch Tagging Guidelines, please +checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here +are templates for supplementary fields that you might want to add: + +Origin: <vendor|upstream|other>, <url of original patch> +Bug: <url in upstream bugtracker> +Bug-Debian: https://bugs.debian.org/<bugnumber> +Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber> +Forwarded: <no|not-needed|url proving that it has been forwarded> +Reviewed-By: <name and email of someone who approved the patch> +Last-Update: 2016-10-16 + +--- acl2-7.2dfsg.orig/books/interface/infix/infix.lisp ++++ acl2-7.2dfsg/books/interface/infix/infix.lisp +@@ -5076,10 +5076,10 @@ Allow redefinition (even of system funct + (defun load-theory-or-init (dir) + (let* ((initfile (make-pathname :name (concatenate 'string *infix-mode* "-init") + :type "lisp" +- :directory (pathname-directory dir))) ++ :directory (when dir (pathname-directory dir)))) + (theoryfile (make-pathname :name (concatenate 'string *infix-mode* "-theory") + :type "lisp" +- :directory (pathname-directory dir)))) ++ :directory (when dir (pathname-directory dir))))) + ;; We assume that, if present, the -theory file loads the -init file. + (cond ((probe-file theoryfile) (load-obj-or-lisp theoryfile) t) + ((probe-file initfile) (load-obj-or-lisp initfile) t) +@@ -5914,4 +5914,4 @@ works whether of not we are currently in + is possible to nest math modes in latex after all. This feature is + documented in section 3.4.1, Defining Commands, in the Latex manual. + +-|# +\ No newline at end of file ++|# diff --git a/debian/patches/interface-from-5.0 b/debian/patches/interface-from-5.0 new file mode 100644 index 0000000..5bff4bc --- /dev/null +++ b/debian/patches/interface-from-5.0 @@ -0,0 +1,15276 @@ +Description: <short summary of the patch> + TODO: Put a short summary on the line above and replace this paragraph + with a longer explanation of this change. Complete the meta-information + with other relevant fields (see below for details). To make it easier, the + information below has been extracted from the changelog. Adjust it or drop + it. + . + acl2 (6.0-1) unstable; urgency=low + . + * New upstream release +Author: Camm Maguire <camm@debian.org> + +--- +The information above should follow the Patch Tagging Guidelines, please +checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here +are templates for supplementary fields that you might want to add: + +Origin: <vendor|upstream|other>, <url of original patch> +Bug: <url in upstream bugtracker> +Bug-Debian: http://bugs.debian.org/<bugnumber> +Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber> +Forwarded: <no|not-needed|url proving that it has been forwarded> +Reviewed-By: <name and email of someone who approved the patch> +Last-Update: <YYYY-MM-DD> + +--- /dev/null ++++ acl2-6.0/interface/infix/acl2-formatting.lisp +@@ -0,0 +1,158 @@ ++; ACL2 Version 1.9 ++ ++; Copyright (C) 1989-96 Computational Logic, Inc. (CLI). All rights reserved. ++ ++; Use of this software constitutes agreement with the terms of ACL2 ++; license agreement, found in the file LICENSE. ++ ++(in-package "ACL2") ++ ++(defparameter *infix-error-flg* nil) ++ ++(symbol-name 'acl2-output-channel::standard-error-output-0) ++(setf (get 'acl2-output-channel::standard-error-output-0 ++ *open-output-channel-type-key*) :character) ++(setf (get 'acl2-output-channel::standard-error-output-0 ++ *open-output-channel-key*) *standard-output*) ++ ++(defconst *standard-eo* 'acl2-output-channel::standard-error-output-0) ++ ++(f-put-global 'standard-eo 'acl2-output-channel::standard-error-output-0 state) ++ ++(defun infix-error-fmt (hardp ctx str alist state) ++ ++; Almost the same as ACL2 error-fmt. ++ ++ (setq *infix-error-flg* t) ++ ++ (let ((channel *standard-eo*)) ;(f-get-global 'standard-co state) ++ (mv-let (col state) ++ (fmt1 (if hardp ++ "~%~%HARD ACL2 ERROR" ++ "~%~%ACL2 Error") ++ nil 0 channel state nil) ++ (mv-let (col state) ++ (fmt-in-ctx ctx col channel state) ++ (mv-let (col state) ++ (fmt1 str alist col channel state (default-evisc-tuple state)) ++ (fmt1 "~%~%" nil col channel state nil)))))) ++ ++(defun string-output-fn (form) ++ `(let ((saved-stream (get 'acl2-output-channel::standard-character-output-0 ++ *open-output-channel-key*)) ++ *infix-error-flg* ++ (saved-fn (symbol-function 'error-fmt))) ++ (unwind-protect ++ (progn ++ (setf (symbol-function 'error-fmt) ++ (symbol-function 'infix-error-fmt)) ++ (let ((ans ++ (with-output-to-string ++ (foo) ++ (setf (get 'acl2-output-channel::standard-character-output-0 ++ *open-output-channel-key*) ++ foo) ++ ,form))) ++ (cons *infix-error-flg* ans))) ++ (setf (symbol-function 'error-fmt) ++ saved-fn) ++ (setf (get 'acl2-output-channel::standard-character-output-0 ++ *open-output-channel-key*) ++ saved-stream)))) ++ ++(defmacro string-output (form) ++ (string-output-fn form)) ++ ++(defun set-infix-markup-table (tbl state) ++ (f-put-global 'infix-markup-table tbl state)) ++ ++(defun infix-markup-table (state) ++ (or (and (f-boundp-global 'infix-markup-table state) ++ (f-get-global 'infix-markup-table state)) ++ (doc-markup-table state))) ++ ++(defun set-infix-char-subst-table (tbl state) ++ (f-put-global 'infix-char-subst-table tbl state)) ++ ++(defun infix-char-subst-table (state) ++ (or (and (f-boundp-global 'infix-char-subst-table state) ++ (f-get-global 'infix-char-subst-table state)) ++ (doc-char-subst-table state))) ++ ++;; For examples of markup-tables and char-subst-tables see ++;; scribe-init.lisp and latex-init.lisp ++ ++(defun infix-preprocess-doc (str &key ++ (markup-table (infix-markup-table *the-live-state*)) ++ (char-subst-table (infix-char-subst-table *the-live-state*)) ++ (prefix "") ++ fmt-alist ++ (name '|<some name>|) ++ par-p ++ &aux (state *the-live-state*)) ++ (string-output ++ (cond ++ ((doc-stringp str) ++ (pprogn ++ (print-doc-string-part 0 str prefix markup-table char-subst-table fmt-alist ++ *standard-co* name par-p state) ++ (print-doc-string-part 1 str prefix markup-table char-subst-table fmt-alist ++ *standard-co* name par-p state) ++ (print-doc-string-part 2 str prefix markup-table char-subst-table fmt-alist ++ *standard-co* name par-p state))) ++ ;; Otherwise, print the string, stopping at the first ~/ (if any, else to end of string). ++ ;; Note that unlike the other case, no special effort is made to ++ ;; strip off leading spaces using get-doc-string-de-indent [see below]. ++ (t (print-doc-string-part1 str ++ 0 ++ (length str) ++ 0;;(get-doc-string-de-indent str) ++ prefix ++ markup-table ++ char-subst-table ++ fmt-alist ++ *standard-co* ++ name ++ state ++ (if par-p :par 0)))))) ++ ++;;; Compute args for key. ++ ++(defun keyword-command-arg-number (key state) ++ (declare (xargs :mode :program)) ++ (let ((temp (assoc-eq key (f-get-global 'ld-keyword-aliases state)))) ++ (cond (temp (cadr temp)) ++ ((eq key :q) 0) ++ (t ++ (let ((sym (intern (symbol-name key) "ACL2")) ++ (wrld (w state))) ++ (cond ++ ((function-symbolp sym wrld) ++ (length (formals sym wrld))) ++ ((getprop sym 'macro-body nil 'current-acl2-world wrld) ++ (let ((args (getprop sym 'macro-args nil 'current-acl2-world wrld))) ++ (if (no-lambda-keywordsp args) ++ (length args) ++ nil))) ++ (t nil))))))) ++ ++;; The following two functions support the reading of ++;; keyword commands, using ACL2 mechanisms for computing ++;; number of args, if allowed. ++ ++(proclaim '(ftype (function (t t) t) ++ user::read-keyword-form)) ++ ++(defvar user::acl2-markup-table) ++(defvar user::acl2-char-subst-table) ++ ++(defun user::acl2-parse-string (doc) ++ (infix-preprocess-doc doc ++ :markup-table user::acl2-markup-table ++ :char-subst-table user::acl2-char-subst-table)) ++ ++(defun user::acl2-keywordp (key) (keywordp key)) ++ ++(defun user::read-keyword-command (key) ++ (user::read-keyword-form key ++ (keyword-command-arg-number key *the-live-state*))) +--- /dev/null ++++ acl2-6.0/interface/infix/CLI.sty +@@ -0,0 +1,18 @@ ++% CLIverbatim is like the LaTeX verbatim environment except ++% that the characters \ { } $ _ and ^ are NOT transparent. This means that ++% you can embed control sequences inside of verbatim text, and do math ++% subscripting and superscripting. ++ ++\def\CLIdospecials{\do \ \do \&\do \# \do \^^K \do \^^A \do \% \do \~} ++ ++\def\@CLIverbatim{\trivlist \item[]\if@minipage\else\vskip\parskip\fi ++\leftskip\@totalleftmargin\rightskip\z@ ++\parindent\z@\parfillskip\@flushglue\parskip\z@ ++\@tempswafalse \def\par{\if@tempswa\hbox{}\fi\@tempswatrue\@@par} ++\obeylines \small \tt \catcode``=13 \@noligs \let\do\@makeother \CLIdospecials} ++ ++\def\CLIverbatim{\@CLIverbatim \frenchspacing\@vobeyspaces} ++\let\endCLIverbatim=\endtrivlist ++ ++\def\smtt{\small\tt} ++\def\bm{\smtt} +--- /dev/null ++++ acl2-6.0/interface/infix/scribe-init.lisp +@@ -0,0 +1,565 @@ ++; ACL2 Version 1.9 ++ ++; Copyright (C) 1989-96 Computational Logic, Inc. (CLI). All rights reserved. ++ ++; Use of this software constitutes agreement with the terms of ACL2 ++; license agreement, found in the file LICENSE. ++ ++ ++;; Init file for infix.lisp in Scribe mode. ++;; Feb 20 1992, by MKSmith ++ ++;; In order to fix a bug in the AKCL interpreter's use of proclaim. ++;; we depend on this file being compiled and loaded in an environment ++;; in which infix.lisp has already been loaded. ++;; #+akcl (load-base "akcl-patch.lisp") ++ ++(in-package "user") ++ ++(format *terminal-io* "Loading the ainfix scribe-init file.") ++ ++ ++ ++;; Mode should actually be set before this file is loaded. ++ ++(infix-settings :mode "scribe" ++ :extension "mss" ++ :op-location 'front ++ :comment-format 'smith ++ :format-!-in-comments nil ++ :eliminate-top-parens t ++ :eliminate-inner-parens nil ++ :no-index-calls nil ) ++ ++ ++;; Increase this number to more accurately allow for proper output width. ++(defparameter *rightmost-char-number* 100) ++(defparameter *default-chars-wide* 100) ++(defparameter *latex-indent-number-limit* 100) ++ ++(defparameter nqread-normal-clause-enders ++ (append '(#\@) nqread-default-normal-clause-enders)) ++ ++; THE SCRIBE PRELUDE. ++ ++(defparameter *standard-prelude* ++ "@make(clinote) ++@device(postscript) ++@style(leftmargin 1.5 inch,linewidth 5.5 inch, indent 0, ++ font clitimesroman, indexcase folded) ++ ++@enable(index) ++ ++@libraryfile(clisymbols) ++@libraryfile(stable) ++ ++@comment{Kcrlf is used in @index[] to cause the form to ignore} ++@comment{newlines after the indexing command. Not what we want in the} ++@comment{forms below.} ++ ++@Form(Kcrlf={}) ++ ++@Modify(format,above 1.2lines,below 1.2 lines) ++@define(st, use t, size -2) ++ ++@Define(block,Break Off,Nofill,Spaces Kept,BlankLines kept,Justification off,afterentry {@$}) ++@define(nop) ++ ++@pageheading(immediate,center={}) ++@pagefooting(immediate,center={@value(page)}) ++ ++") ++ ++(defparameter *standard-postlude* ++ " ++") ++ ++(defparameter *example-prelude* ++ (concatenate 'string *standard-prelude* ++" ++@standardtable(name BaseTbl, Columns 2, columnwidth 2.5 inch, allcolumns=center, ++ float, boxed, flushtop, ++ above 1 line, below 1 line) ++ ++Here is a summary of the conventional syntax (~a) in terms of the official syntax ++of the Acl2 logic. ++ ++@begin{enumerate} ++ ++Variables. !tx, !ty, !tz, etc. are printed in italics. ++ ++Function application. For any function symbol for which special ++syntax is not given below, an application of the symbol is printed with ++the usual notation; e.g., the term !v(fn x y z) is ++printed as !t(fn x y z). Note that the function symbol is printed in ++Roman. In the special case that !qc is a function symbol of no ++arguments, i.e., it is a constant, the term !v(c) is printed merely as ++!t(c), in small caps, with no trailing parentheses. Because variables are printed in ++italics, there is no confusion between the printing of variables and ++constants. ++ ++Other constants. !tt, !tf, and !tnil are printed in bold. ++Quoted constants are printed in the ordinary syntax of the ACL2 logic, ++in a `typewriter font.' For example, ++@t{'(a b c)} is still printed just that way. @t{#b001} is printed ++as !t#b001, @t{#o765} is printed as !t#o765, and @t{#xa9} is printed as ++!t#xa9, representing binary, octal and hexadecimal, respectively. ++ ++")) ++ ++(defparameter *begin-example-table* " ++@newpage() ++@begin(BaseTbl) ++@tableid(BaseTbl~d) ++@tableHeading(Immediate, RowFormat BaseTblColumnHeadings, ++ Line {ACL2 Syntax@\\Conventional Syntax})~%" ++ "Needs an argument, integer, in order to give different tables different names.") ++ ++(defparameter *end-example-table* "@end(BaseTbl) ++ ++") ++ ++(defparameter *example-table-size* 32) ++ ++(defparameter *example-postlude* "") ++ ++;; BASIC BRACKETS AND THEIR QUOTED VERSION. ++ ++(defparameter *begin* "{") ++(defparameter *end* "}") ++ ++(defparameter *lbrace* "@nop<{>") ++(defparameter *rbrace* "@nop<}>") ++ ++;; NEWLINE PARAMETERS ++ ++(defparameter *newline-in-env* "") ++(defparameter *newline-in-text* "") ++ ++(defparameter *force-newline-in-env* "") ++(defparameter *force-newline-in-text* "@*") ++ ++ ++;; ENVIRONMENT BEGIN-END PAIRS ++ ++(defparameter *begin-index* "@index{") ++(defparameter *end-index* "@index{") ++ ++(defparameter *begin-text-env* "@begin{text,above 1 line,below 1 line}") ++(defparameter *end-text-env* "@end{text}") ++ ++(defparameter *begin-verbatim-env* "@begin{verbatim}") ++(defparameter *end-verbatim-env* "@end{verbatim}") ++ ++(defparameter *begin-format-env* "@begin{format}") ++(defparameter *end-format-env* "@end{format}") ++ ++(defparameter *begin-emphasis-env* "@begin{format, FaceCode i}") ++(defparameter *end-emphasis-env* "@end{format}") ++ ++(defparameter *begin-comment-env* "@begin{comment}") ++(defparameter *end-comment-env* "@end{comment}") ++ ++(defparameter *begin-section-env* "@section{") ++(defparameter *end-section-env* "}") ++ ++(defparameter *begin-subsection-env* "@subsection{") ++(defparameter *end-subsection-env* "}") ++ ++(defparameter *begin-tt-env* "@t{") ++(defparameter *end-tt-env* "}") ++ ++(defparameter *begin-string-env* "@st{") ++(defparameter *end-string-env* "}") ++ ++(defparameter *begin-bold-env* "@b{") ++(defparameter *end-bold-env* "}") ++ ++(defparameter *begin-italic-env* "@i{") ++(defparameter *end-italic-env* "}") ++ ++(defparameter *begin-sc-env* "@c{") ++(defparameter *end-sc-env* "}") ++ ++(defparameter *begin-enumerate-env* "@begin{enumerate}") ++(defparameter *end-enumerate-env* "@end{enumerate}") ++(defparameter *begin-item* " ++@begin(multiple) ++") ++(defparameter *end-item* " ++@end(multiple) ++") ++ ++(defparameter *mv-bracket-left* "@langle") ++(defparameter *mv-bracket-right* "@rangle") ++ ++(defparameter *forall* "@forall ") ++(defparameter *exists* "@exists ") ++ ++ ++;; TABBING ENVIRONMENT AND TAB OPERATIONS ++ ++(defparameter *begin-group-tabbing-env* "@begin{format,group}@tabclear{}") ++ ++(defparameter *begin-tabbing-env* "@begin{format}@tabclear{}") ++(defparameter *end-tabbing-env* "@end{format}") ++ ++(defun new-tab-row (&optional followed-by-infix-print-term) ++ (declare (ignore followed-by-infix-print-term)) ++ (pwrite-char #\Newline)) ++ ++(defparameter *tab* "@\\") ++(defparameter *flush* "@>") ++ ++(defparameter *column-separator* *tab*) ++ ++(defparameter *tab-list* nil) ++ ++(defparameter *set-margin* "@begin(block)") ++(defparameter *set-tab* "@^") ++(defparameter *pop-margin* "@end(block)") ++ ++(defparameter *default-op-tab-space* "@math{@quad}@ @ @ ") ++(defparameter *indent-string* "@math{@quad}") ++(defparameter *default-indent* 4) ++ ++(defun get-op-width-string (op) ++ (declare (ignore op)) ++ nil) ++ ++(defparameter *noindent* "") ++ ++; (defparameter *testmargin* nil) ++ ++(defun begin-tabbing () ++ ++; Tabbing environments can be nested in Scribe. ++; Use this fact with set-margin. ++ ++ (setq *tab-list* (cons '(begin-tabs) *tab-list*)) ++ ;; (if *testmargin* (format t "~%Begin tabbing : ~a~%" *tab-list*)) ++ (princ *begin-tabbing-env*) ++ (setq *infix-loc* *left-margin*)) ++ ++(defun begin-group-tabbing () ++ ++; Tabbing environments can be nested in Scribe. ++; Use this fact with set-margin. ++ ++ (setq *tab-list* nil) ++ (princ *begin-group-tabbing-env*) ++ (setq *infix-loc* *left-margin*)) ++ ++(defun end-tabbing () ++ (sloop while (and *tab-list* (not (equal (caar *tab-list*) 'begin-tabs))) ++ do (setq *tab-list* (cdr *tab-list*))) ++ (if *tab-list* (setq *tab-list* (cdr *tab-list*))) ++ ;; (if *testmargin* (format t "~%End tabbing : ~a~%" *tab-list*)) ++ (princ *end-tabbing-env*)) ++ ++(defun increase-margin () ++ (pprin1i *default-op-tab-space*) ++ (set-margin)) ++ ++(defun set-margin () ++ ++; Generate instructions to set the current indentation. ++; In latex we use tabs, which cause *tabto* to tab to this column in the future. ++; `Punt' if we hit the limit, by throwing all the way out. ++ ++ (cond (*do-not-use-tabs* nil) ++ ;; Bump Latex limit way up for Scribe. ++ (t (cond ((= *tabs-in* *latex-indent-number-limit*) ++ (throw 'taboverflow t))) ++ (setq *tabs-in* (1+ *tabs-in*)) ++ (pprinc *set-margin*) ++ (push (cons 'lm *infix-loc*) *tab-list*) ++ ;; (if *testmargin* (format t "~%Set margin : ~a~%" *tab-list*)) ++ ))) ++ ++(defun get-margin () ++ (get-margin2 *tab-list*)) ++ ++(defun get-margin2 (tl) ++ (let ((setting (car tl))) ++ (cond ((null setting) *left-margin*) ++ ((eq (car setting) 'lm) (cdr setting)) ++ (t (get-margin2 (cdr tl)))))) ++ ++(defun begin-flushright () ++ (pprinc *flush*)) ++ ++(defun end-flushright () ++ (pprinc *tab*)) ++ ++(defun begin-normal-text () ++ (pprinc *begin-text-env*)) ++ ++(defun end-normal-text () ++ (pprinc *end-text-env*)) ++ ++(defun flushright (form) ++ (begin-flushright) ++ (pprinc form) ++ (end-flushright)) ++ ++(defun do-tab () ++ ++; The *tab-list* is either NIL, ((LM loc) ...), or ((TAB loc) ...) ++; Only tab if there is something to tab to. ++ ++ (cond (*do-not-use-tabs* (pprinc " ")) ++ ((and *tab-list* (eq (caar *tab-list*) 'tab)) ++ (pprinc *tab*)) ++ (t (pprinc " ")))) ++ ++(defun set-tab (&optional op) ++ ++; Generate instructions to set a tab at the current location. ++; `Punt' if we hit the limit, by throwing all the way out. ++ ++ (cond (*do-not-use-tabs* nil) ++ (t (cond ((= *tabs-in* *latex-indent-number-limit*) ;Let Latex-Limit hold for Scribe also. ++ (throw 'taboverflow t))) ++ (setq *tabs-in* (1+ *tabs-in*)) ++ (cond ((and op (get-op-width-string op)) ++ (pprinc (get-op-width-string op))) ++ (t (pprinc *default-op-tab-space*))) ++ (push (cons 'tab *infix-loc*) *tab-list*) ++ ;; (if *testmargin* (format t "~%Setting tab : ~a~%" *tab-list*)) ++ (pprinc *set-tab*)))) ++ ++(defun pop-tab () ++ ;; We don't really remove tabs from the formatted env. ++ ;; Just track them in Lisp. ++ ;; Generate command to `tab to one tab less in'. ++ ;; Do not pop tabs beyond left margin or past the beginning of a tabbing env. ++ (cond (*do-not-use-tabs* nil) ++ ((and *tab-list* (eq (caar *tab-list*) 'tab)) ++ (setq *tabs-in* (1- *tabs-in*)) ++ (pop *tab-list*) ++ ;; (if *testmargin* (format t "~%Popped tab : ~a~%" *tab-list*)) ++ ) ++ (t nil))) ++ ++(defun pop-margin () ++ ;; Generate command to `return to one margin less in'. ++ ;; For bookkeepping reasons we pop tabs after the margin. ++ ;; (if *testmargin* (format t "~%Popping margin ...~%")) ++ (cond (*do-not-use-tabs* nil) ++ ((and *tab-list* (eq (caar *tab-list*) 'tab)) ++ (pop-tab) ++ (pop-margin)) ++ ((and *tab-list* (eq (caar *tab-list*) 'lm)) ++ (setq *tabs-in* (1- *tabs-in*)) ++ (pop *tab-list*) ++ ;; (if *testmargin* (format t "~%Popped margin : ~a~%" *tab-list*)) ++ (pprinc *pop-margin*)) ++ (t nil))) ++ ++;; (defun newline-to-current-margin () ++;; ;; Generates command for return to current indentation setting. ++;; (cond (*do-not-use-tabs* (pprinci " ")) ++;; (t (pwrite-char #\Newline) ++;; (setq *infix-loc* (get-margin))))) ++ ++(defun to-current-margin () ++ ;; Generates command for return to current indentation setting, ++ ;; unless we are already there. ++ (cond (*do-not-use-tabs* (pprinci " ")) ++ ((eql *infix-loc* (get-margin))) ++ (t (newline)))) ++ ++;; (defun force-newline () ++;; ;; Forces a newline in running text. ++;; (pprinc "@*") ++;; (pwrite-char #\Newline) ++;; (cond (*do-not-use-tabs* ++;; (setq *infix-loc* *left-margin*)) ++;; (t (setq *infix-loc* (get-margin))))) ++ ++;; (defun force-newline () ++;; ;; Forces a newline in running text OR in tabbing env. ++;; (if (null *tab-list*) ++;; (progn (pprinc "@*") ++;; (pwrite-char #\Newline) ++;; (cond (*do-not-use-tabs* ++;; (setq *infix-loc* *left-margin*)) ++;; (t (setq *infix-loc* (get-margin))))) ++;; (cond (*do-not-use-tabs* (pprinci " ")) ++;; (t (pwrite-char #\Newline) ++;; (setq *infix-loc* (get-margin)))))) ++ ++(defun set-left-margin () ++ (cond ((< *infix-loc* *left-margin*) ++ (sloop for i from *infix-loc* to (- *left-margin* 1) ++ do (pwrite-char #\Space)) ++ (pprinc "@$")))) ++ ++ ++;; FONTS ++ ++(defparameter *function-font* "@r") ; Roman. sc = small caps ++ ++(defun roman-font (term) ++ (pprinc *function-font*) ++ (pprinc "{") ++ (print-atom term) ++ (pprinc "}")) ++ ++ ++;; MATH ENV AND OPERATORS ++ ++(defparameter *neg-str* "@not") ++ ++(defparameter *math-format* "@math{~a}") ++(defparameter *math-begin* "@math{") ++(defparameter *math-end* "}") ++ ++;; These must be enclosed in a math env. Tried using a @quad, but it is too thick. ++(defparameter *math-thick-space* "@ ") ++(defparameter *math-space* "##") ; # is a thin space ++(defparameter *math-thin-space* "#") ++ ++(defparameter *subscript* "@-") ++ ++(defparameter *begin-subscript* "@-{") ++(defparameter *end-subscript* "}") ++ ++;; MISC. ++ ++(defparameter *newpage* "@newpage()") ++ ++(defparameter *comma-atsign* ",@@") ++(defparameter *caret* "^") ++ ++(defparameter *dotted-pair-separator* " . ") ++(defparameter *dotted-pair-separator-newline* ". ") ++ ++(defparameter *no-tab-event-trailer* "~%~%") ++(defparameter *print-default-event-header* "~%@c{Event}: ") ++(defparameter *print-default-lisp-header* "~%@c{Lisp}: ") ++ ++(defparameter *print-default-command-header* "~%") ++(defparameter *no-tab-command-trailer* "~%~%") ++ ++;; OTHER FUNCTIONS ++ ++;; Should both be `(#\@ @\}) but we handle them individually in the appropriate ++;; spots in the two following functions. ++(defparameter doc-special-chars nil) ++(defparameter doc-index-specials nil) ++ ++(defparameter doc-other-chars nil) ++ ++;; We didn't compile the following because the compiler declaration ++;; in Sinfix, through a bug in AKCL, caused this routine to produce ++;; spurious results. ++ ++;; The patch to akcl that is loaded in sinfix should fix this problem. ++;; Other lisps shouldn't need it. ++;; These use to be of the form (eval-when (load) (eval '<defn>)) ++ ++(eval-when (load) (eval ++'(defun handle-special-chars (char) ++ ;; USED BY PRINT-ATOM. CHAR is local to print-atom. ++ ;; We don't use the global, DOC-SPECIAL-CHARS, since there are ++ ;; only two, @ and }, and we do something different in each case. ++ (cond ((char= char #\@) (pprinc "@@") (incf *infix-loc* 1)) ++ ((char= char #\}) (pprinc *rbrace*) (incf *infix-loc* 1)) ++ ++ ;; Atoms printed in all lower case. ++ ++ (t (pwrite-char (if (eq *print-case* :downcase) ++ (char-downcase char) ++ char))))) ++)) ++ ++(eval-when (load) (eval ++'(defun handle-special-chars-in-string (char) ++ ;; USED BY PRINT-ATOM. CHAR is local to print-atom. ++ (cond ((char= char #\@) (pprinc "@@") (incf *infix-loc* 1)) ++ ((char= char #\}) (pprinc *rbrace*) (incf *infix-loc* 1)) ++ (t (pwrite-char char)))) ++)) ++ ++;; PRINTING INDEX ENTRIES ++ ++;; We don't bother to count braces in Scribe, we just quote them. ++ ++(defun index (x &optional subkind) ++ (pprinc *begin-index*) ++ (let ((str (if (stringp x) x (symbol-name x))) ++ (num-chars 0) ++ ;(inserted-excl nil) ++ ) ++ ++ (if subkind ++ (cond ((stringp subkind) (setq str (concatenate 'string str ", " subkind))) ++ ((symbolp subkind) (setq str (concatenate 'string str ", " (string subkind)))) ++ (t nil))) ++ ++ (sloop for i below (length str) ++ for char = (char (the string str) (the fixnum i)) ++ until (> num-chars *index-entry-max*) ++ ++ ;; Quote special Scribe characters as @ & }. ++ ++ do (cond ((char= char #\@) (pprinc "@@") (incf num-chars 2)) ++ ((char= char #\}) (pprinc *rbrace*) (incf num-chars 2)) ++ ++ (t (pwrite-char (if (eq *print-case* :downcase) ++ (char-downcase char) ++ char)) ++ (incf num-chars 1))) ++ finally (cond ((> num-chars *index-entry-max*) ++ (pformat *terminal-io* ++ "~% Warning: Index entry for ~a truncated to ~a characters. ~%" ++ x num-chars) ++ (pprinc "..."))) ++ )) ++ (pprinc *end*)) ++ ++(defun skip-index-entries () ++ ;; We are looking at a backslash. In Tex mode we need to skip to the end ++ ;; of the entry, because we may add !'s. In Scribe mode this is just NIL. ++ nil) ++ ++(defun adjust-tabbing-env () ++ ;; We are looking at a backslash. In Tex mode we may need to check for ++ ;; some special cases. ++ ;; In Scribe mode this is just NIL. ++ nil) ++ ++(defparameter acl2-char-subst-table ++ '((#\@ #\@ #\@))) ++ ++(defparameter acl2-markup-table ++ '(("-" . "@emdash{}") ++ ("B" . "@b{~sa}") ++ ("BF" . "~%@begin{format}") ++ ("BID" . "") ;begin implementation dependent ++ ("BQ" . "~%@begin{quotation}") ++ ("BV" . "~%@begin{verbatim}") ++ ("C" . "@t{~sa}") ;originally @code, but we don't want `' in info file ++ ("EF" . "@end{format}~%") ++ ("EID" . "") ;end implementation dependent ++ ("EM" . "@i{~sa}") ;emphasis ++ ("EQ" . "~%@end{quotation}~%") ;TexInfo needs leading line break to ++ ;avoid problems with @refill ++ ("EV" . "@end{verbatim}~%") ++ ("I" . "@i{~sa}") ++ ("ID" . "~sa") ;implementation dependent ++ ("IL" . "~sa") ++ ("ILC" . "@t{~sa}") ;originally @code, but we don't want `' in info file ++ ("L" . "See ~sA") ++ ("NL" . "@*~%") ++ ("PAR" . "") ;paragraph mark, of no significance for scribe ++ ("PL" . "see ~sA") ;used for parenthetical crossrefs ++ ("SC" . "@c{~sa}") ;small caps ++ ("ST" . "@b{~sa}") ;strong emphasis ++ ("T" . "@t{~sa}") ++ ("TERMINAL" . "") ; terminal only, ignore ++ )) ++ ++ +--- /dev/null ++++ acl2-6.0/interface/infix/sloop.lisp +@@ -0,0 +1,1098 @@ ++;;; -*- Mode:LISP; Package: (SLOOP LISP); Syntax:COMMON-LISP; Base:10 -*- ;;;;;;;; ++;;; ;;;;; ++;;; Copyright (c) 1985,86 by William Schelter, ;;;;; ++;;; All rights reserved ;;;;; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++ ++;;Report bugs to atp.schelter@r20.utexas.edu ++;;It comes with ABSOLUTELY NO WARRANTY but we hope it is useful. ++ ++ ++;;The following code is meant to run in COMMON LISP and to provide ++;;extensive iteration facilities, with very high backwards compatibility ++;;with the traditional loop macro. It is meant to be publicly available! ++;;Anyone is hereby given permission to copy it provided he does not make ++;;ANY changes to the file unless he is William Schelter. He may change ++;;the behavior after loading it by resetting the global variables such ++;;as like *Use-locatives*, *automatic-declarations*,.. listed at the ++;;beginning of this file. The original of this file is on ++;;r20.utexas.edu:<atp.schelter>sloop.lisp I am happy to accept suggestions ++;;for different defaults for various implementations, or for improvements. ++ ++;;If you want to redefine the common lisp loop you may include in your code: ++;;(defmacro loop (&body body) ++;; (parse-loop body)) ++ ++;; Principal New Features ++ ++;;Sloop is extremely user extensible so that you may easily redefine most ++;;behavior, or add additional collections, and paths. There are a number ++;;of such examples defined in this file, including such constructs as ++;;"for V in-fringe X", "sum V", "averaging V", "for SYM in-package Y", ++;;"collate V" (for collecting X into an ordered list), "for (ELT I) in-array AR", ++;;"for (KEY ELT) in-table FOO" (if foo is a hash table). And of course ++;;you can combine any collection method with any path. ++;;Also there is iteration over products so that you may write ++;;(sloop for I below K ++;; sloop (for J below I ++;; collecting (foo I J))) ++;;Declare is fully supported. The syntax would be ++;;(sloop for u in l with v = 0 ++;; declare (fixnum u v) ++;; do ....) ++ ++;;This extensibility is gained by the ability to define a "loop-macro", ++;;which plays a role analagous to an ordiary lisp macro. See eg. ++;;definitions near that of "averaging". Essentially a "loop-macro" ++;;takes some arguments (supplied from the body of the loop following its ++;;occurrence, and returns a new form to be stuffed onto the front of the ++;;loop form, in place of it and its arguments). ++ ++;;Compile notes: ++;;For dec-20 clisp load the lisp file before compiling. ++ ++ ++;;there seems to be no unanimity about what in-package etc. does on loading ++;;and compiling a file. The following is as close to the examples in ++;;the Common Lisp manual, as we could make it. ++;;The user should put (require "SLOOP") and then (use-package "SLOOP") ++;;early in his init file. Note use of the string to avoid interning 'sloop ++;;in some other package. ++ ++ ++(in-package "SLOOP" :use '(LISP)) ++(eval-when (compile eval load) ++(provide "SLOOP") ++(export '(loop-return sloop def-loop-collect def-loop-map ++ def-loop-for def-loop-macro local-finish ++ loop-finish) (find-package "SLOOP")) ++) ++ ++;;some variables that may be changed to suit different implementations: ++ ++(eval-when (compile load eval) ++ ++(defparameter *use-locatives* nil "See sloop.lisp") ;#+lispm t #-lispm nil ++;;If t should have locf, such that (setf b nil) (setq a (locf b)) then if ++;;(setf (cdr a) (cons 3 nil)) b==>(3). This is useful for building lists ++;;starting with a variable pointing to nil, since otherwise we must check ++;;each time if the list has really been started, before we do a ++;;(setf (cdr b) ..) ++ ++(defparameter *Automatic-declarations* ++ #+lispm nil ++ #-lispm ++ '(:from fixnum ++ :in #+kcl object #-kcl t ++ :collect #+kcl object #-kcl t ) "See sloop.lisp") ++;; some other reasonable ones would be :count fixnum :max fixnum ++;;Automatic declarations for variables in the stepping and collecting, ++;;so for i below n, gives i and n a :from declaration (here fixnum) ++;;for item in lis, gives (declare (t item)) ++ ++(defvar *type-check* t "If t adds a type check on bounds of from loop if there ++is and automatic declare") ++ ++(defparameter *macroexpand-hook-for-no-copy* #-(or lmi ti) 'funcall #+(or lmi ti) t) ++;;some lisps remember a macro so that (loop-return) will expand eq forms ++;;always in the same manner, even if the form is in a macrolet! To defeat this feature ++;;we copy all macro expansions unless *macro-expand-hook* = *macroexpand-hook-for-no-copy* ++) ++ ++#+kcl (eval-when (compile) (proclaim '(optimize (safety 2) (space 2)))) ++ ++;;to do ++;;Fix (declare (joe (type (array fixnum)))) type for declarations. ++ ++;;*****ONLY CONDITIONALIZATIONS BELOW HERE SHOULD BE FOR BUG FIXES****** ++;;eg. some kcls don't return nil from a prog by default! ++ ++;;all macros here in here. ++(eval-when (compile eval load) ++ ++(defparameter *sloop-translations* '((appending . append) ++ ((collecting collect) . collect) ++ ((maximizing maximize) . maximize) ++ ((minimizing minimize) . minimize) ++ (nconcing . nconc) ++ ((count counting) . count) ++ (summing . sum) ++ (if . when) ++ (as . for) ++ (in-fringe . in-fringe) ++ (collate . collate) ++ (in-table . in-table) ++ (in-carefully . in-carefully) ++ (averaging . averaging) ++ (repeat . repeat) ++ (first-use . first-use) ++ (in-array . in-array)) ++ "A list of cons's where the translation is the cdr, and the car ++is a list of names or name to be translated. Essentially allows 'globalizing' ++a symbol for the purposes of being a keyword in a sloop") ++ ++ ++(defparameter *additional-collections* nil) ++ ++(defmacro lcase (item &body body) ++ (let (bod last-case tem) ++ (do ((rest body (cdr rest)) (v)) ++ ((or last-case (null rest))) ++ (setq v (car rest)) ++ (push ++ (cond ((eql (car v) t) (setq last-case t) v) ++ ((eql (car v) :collect) ++ `((loop-collect-keyword-p .item.) ,@ (cdr v))) ++ ((eql (car v) :no-body) ++ `((parse-no-body .item.) ,@ (cdr v))) ++ ((setq tem ++ (member (car v) '(:sloop-macro :sloop-for :sloop-map))) ++ `((and (symbolp .item.)(get .item. ,(car tem))) ,@ (cdr v))) ++ (t ++ `((l-equal .item. ',(car v)) ,@ (cdr v)))) ++ bod)) ++ (or last-case (push `(t (error "lcase fell off end ~a " .item.)) bod)) ++ `(let ((.item. (translate-name ,item))) ++ (cond ,@ (nreverse bod))))) ++ ++;;some cl implementations lack define-setf-method and others have already defined this. ++;;so we will change the definition of desetq to not use setf. ++;(define-setf-method cons (a b) ++; (let ((store (gensym "store"))) ++; (values nil nil (list store) ++; `(progn ,@ (and a `((setf ,a (car ,store)))) ++; ,@ (and b `((setf ,b (cdr ,store))))) ++; `(error "You should not be setting this")))) ++ ++;(defmacro cons-for-setf (form) ++; (cond ((symbolp form) form) ++; ((consp form) ++; (cond ((cdr form) ++; `(cons (cons-for-setf ,(car form)) (cons-for-setf ,(cdr form)))) ++; (t `(cons (cons-for-setf ,(car form)) nil)))))) ++ ++;(defmacro desetq (form val) ++; "(desetq (a b) '(3 4)) would work. This is destructured setq" ++; (cond ((symbolp form) `(setq ,form ,val)) ++; (t ++; `(setf (cons-for-setf ,form) ,val)))) ++ ++(defun desetq1 (form val) ++ (cond ((symbolp form) ++ (and form `(setf ,form ,val))) ++ ((consp form) ++ `(progn ,(desetq1 (car form) `(car ,val)) ++ ,@ (if (consp (cdr form)) (list(desetq1 (cdr form) `(cdr ,val))) ++ (and (cdr form) `((setf ,(cdr form) (cdr ,val))))))) ++ (t (error "")))) ++ ++(defmacro desetq (form val) ++ (cond ((atom val) (desetq1 form val)) ++ (t (let ((value (gensym))) ++ `(let ((,value ,val)) , (desetq1 form value)))))) ++ ++(defmacro loop-return (&rest vals) ++ (cond ((<= (length vals) 1) ++ `(return ,@ vals)) ++ (t`(return (values ,@ vals))))) ++ ++(defmacro loop-finish () ++ `(go finish-loop)) ++ ++(defmacro local-finish () ++ `(go finish-loop)) ++ ++(defmacro sloop (&body body) ++ (parse-loop body)) ++ ++(defmacro def-loop-map (name args &body body) ++ (def-loop-internal name args body 'map)) ++(defmacro def-loop-for (name args &body body ) ++ (def-loop-internal name args body 'for nil 1)) ++(defmacro def-loop-macro (name args &body body) ++ (def-loop-internal name args body 'macro)) ++(defmacro def-loop-collect (name arglist &body body ) ++ "Define function of 2 args arglist= (collect-var value-to-collect)" ++ (def-loop-internal name arglist body 'collect '*additional-collections* 2 2)) ++ ++(defmacro sloop-swap () ++ `(progn (rotatef a *loop-bindings*) ++ (rotatef b *loop-prologue*) ++ (rotatef c *loop-epilogue*) ++ (rotatef e *loop-end-test*) ++ (rotatef f *loop-increment*) ++ (setf *inner-sloop* (not *inner-sloop*)) ++ )) ++ ++) ++ ++(defun l-equal (a b) ++ (and (symbolp a) ++ (cond ((symbolp b) ++ (equal (symbol-name a) (symbol-name b))) ++ ((listp b) ++ (member a b :test 'l-equal))))) ++ ++(defun loop-collect-keyword-p (command) ++ (or (member command '(collect append nconc sum count) :test 'l-equal) ++ (find command *additional-collections* :test 'l-equal))) ++ ++(defun translate-name (name) ++ (cond ((and (symbolp name) ++ (cdar (member name *sloop-translations* :test 'l-equal :key 'car)))) ++ (t name))) ++ ++(defun loop-pop () ++ (declare (special *last-val* *loop-form*)) ++ (cond (*loop-form* ++ (setq *last-val* (pop *loop-form*))) ++ (t (setq *last-val* 'empty-form) nil))) ++ ++(defun loop-un-pop () (declare (special *last-val* *loop-form*)) ++ (case *last-val* ++ (empty-form nil) ++ (already-un-popped (error "you are un-popping without popping")) ++ (t (push *last-val* *loop-form*) (setf *last-val* 'alread-un-popped)))) ++ ++(defun loop-peek () (declare (special *last-val* *loop-form*)) ++ (car *loop-form*)) ++ ++(defun loop-let-bindings(binds) ++ (do ((v (car binds) (cdr v))) ++ ((null v) (nreverse (car binds))) ++ (or (cdar v) (setf (car v) (caar v))))) ++ ++(defun parse-loop (form &aux inner-body) ++ (let ((*loop-form* form) ++ (*Automatic-declarations* *Automatic-declarations*) ++ *last-val* *loop-map* ++ *loop-body* ++ *loop-name* ++ *loop-prologue* *inner-sloop* ++ *loop-epilogue* *loop-increment* ++ *loop-collect-pointers* *loop-map-declares* ++ *loop-collect-var* *no-declare* ++ *loop-end-test* ++ *loop-bindings* ++ *product-for* local-macros ++ (finish-loop 'finish-loop) ++ ) ++ (declare (special *loop-form* *last-val* *loop-map* ++ *loop-collect-pointers* ++ *loop-name* *inner-sloop* ++ *loop-body* ++ *loop-prologue* ++ *no-declare* ++ *loop-bindings* ++ *loop-collect-var* *loop-map-declares* ++ *loop-epilogue* *loop-increment* ++ *loop-end-test* *product-for* ++ )) ++ (unless (and (symbolp (car *loop-form*)) (car *loop-form*)) ++ (push 'do *loop-form*)) ;compatible with common lisp loop.. ++ (parse-loop1) ++ (when (or *loop-map* *product-for*) ++ (or *loop-name* (setf *loop-name* (gensym "SLOOP"))) ++ (and (eql 'finish-loop finish-loop) ++ (setf finish-loop (gensym "FINISH")))) ++ ;some one might use local-finish,local-return or loop-finish they might be bound at an outer level. ++ ;we have to always include this since loop-return may be being bound outside. ++ (and ; *loop-name* ++ (push ++ `(loop-return (&rest vals) `(return-from ,',*loop-name* (values ,@ vals))) ++ local-macros)) ++ (when t ;; (or (> *loop-level* 1) (not (eql finish-loop 'finish-loop))) ++ (push `(loop-finish () `(go ,',finish-loop)) local-macros) ++ (push `(local-finish () `(go ,',finish-loop)) local-macros)) ++ (and *loop-collect-var* ++ (push `(return-from ,*loop-name* , *loop-collect-var*) ++ *loop-epilogue*)) ++ (setq inner-body (append *loop-end-test* ++ (nreverse *loop-body*) ++ (nreverse *loop-increment*))) ++ (cond (*loop-map* ++ (setq inner-body (substitute-sloop-body inner-body))) ++ (t (setf inner-body (cons 'next-loop ++ (append inner-body '((go next-loop))))))) ++ (let ((bod ++ `(macrolet ,local-macros ++ (block ,*loop-name* ++ (tagbody ++ ,@ (append ++ (nreverse *loop-prologue*) ++ inner-body ++ `(,finish-loop) ++ (nreverse *loop-epilogue*) ++ #+kcl '((loop-return nil)))))) ++ ++ )) ++ ;;temp-fix..should not be necessary but some lisps cache macro expansions. ++ ;;and ignore the macrolet!! ++ (unless (eql *macroexpand-hook* *macroexpand-hook-for-no-copy*) ++ (setf bod (copy-tree bod))) ++ (dolist (v *loop-bindings*) ++ (setf bod ++ `(let ,(loop-let-bindings v) ,@(and (cdr v) `(,(cons 'declare (cdr v)))) ++ ,bod))) ++ bod ++ ))) ++ ++(defun parse-loop1 () ++ (declare (special *loop-form* ++ *loop-body* *loop-increment* ++ *no-declare* *loop-end-test* ++ *loop-name* )) ++ (lcase (loop-peek) ++ (named (loop-pop) (setq *loop-name* (loop-pop))) ++ (t nil)) ++ (do ((v (loop-pop) (loop-pop))) ++ ((and (null v) (null *loop-form*))) ++ (lcase v ++ (:no-body) ++ (for (parse-loop-for)) ++ (while (push ++ `(or ,(loop-pop) (local-finish)) *loop-body*)) ++ (until (push ++ `(and ,(loop-pop) (local-finish)) *loop-body*)) ++ (do (setq *loop-body* (append (parse-loop-do) *loop-body*))) ++ ((when unless) (setq *loop-body* (append (parse-loop-when) *loop-body*))) ++ (:collect (setq *loop-body* (append (parse-loop-collect) *loop-body*))) ++ ))) ++ ++ ++(defun parse-no-body (com &aux (found t) (first t)) ++ "Reads successive no-body-contribution type forms, like declare, initially, etc. ++which can occur anywhere. Returns t if it finds some ++otherwise nil" ++ (declare (special *loop-form* ++ *loop-body* ++ *loop-increment* ++ *no-declare* *loop-end-test* ++ *loop-name* )) ++ (do ((v com (loop-pop))) ++ ((null (or first *loop-form*))) ++ (lcase v ++ ((initially finally)(parse-loop-initially v)) ++ (nil nil) ++ (with (parse-loop-with)) ++ (declare (parse-loop-declare (loop-pop) t)) ++ (nodeclare (setq *no-declare* (loop-pop))) ;take argument to be consistent. ++ (increment (setq *loop-increment* (append (parse-loop-do) *loop-increment*))) ++ (end-test (setq *loop-end-test* (append (parse-loop-do) *loop-end-test*))) ++ (with-unique (parse-loop-with nil t)) ++ (:sloop-macro (parse-loop-macro v :sloop-macro)) ++ (t ++ (cond (first ++ (setf found nil)) ++ (t (loop-un-pop))) ++ (return 'done))) ++ (setf first nil)) ++ found) ++ ++(defun parse-loop-with (&optional and-with only-if-not-there) ++ (let ((var (loop-pop))) ++ (lcase (loop-peek) ++ (= (loop-pop) ++ (or (symbolp var) (error "Not a variable ~a" var)) ++ (loop-add-binding var (loop-pop) (not and-with) nil nil t only-if-not-there)) ++ (t (loop-add-temps var nil nil (not and-with) only-if-not-there))) ++ (lcase (loop-peek) ++ (and (loop-pop) ++ (lcase (loop-pop) ++ (with (parse-loop-with t )) ++ (with-unique (parse-loop-with t t)) ++ (t (loop-un-pop) (parse-loop-with t)) ++ )) ++ (t nil)))) ++ ++(defun parse-loop-do (&aux result) ++ (declare (special *loop-form*)) ++ (do ((v (loop-pop) (loop-pop)) ) ++ (()) ++ (cond ++ ((listp v) ++ (push v result) ++ (or *loop-form* (return 'done))) ++ (t (loop-un-pop) (return 'done)))) ++ (or result (error "empty clause")) ++ result) ++ ++(defun parse-loop-initially (command ) ++ (declare (special *loop-prologue* *loop-epilogue* *loop-bindings*)) ++ (lcase command ++ (initially (let ((form (parse-loop-do))) ++ (dolist (v (nreverse form)) ++ (cond ((and (listp v) ++ (member (car v) '(setf setq)) ++ (eql (length v) 3) ++ (symbolp (second v)) ++ (constantp (third v)) ++ (loop-add-binding (second v) (third v) nil nil nil t t) ++ )) ++ (t (setf *loop-prologue* (cons v *loop-prologue*))))))) ++ (finally ++ (setf *loop-epilogue* (append (parse-loop-do) *loop-epilogue*))))) ++ ++(defun parse-one-when-clause ( &aux this-case (want 'body) v) ++ (declare (special *loop-form*)) ++ (prog nil ++ next-loop ++ (and (null *loop-form*) (return 'done)) ++ (setq v (loop-pop)) ++ (lcase v ++ (:no-body) ++ (:collect (or (eql 'body want) (go finish)) ++ (setq this-case (append (parse-loop-collect) this-case)) ++ (setq want 'and)) ++ (when (or (eql 'body want) (go finish)) ++ (setq this-case (append (parse-loop-when) this-case)) ++ (setq want 'and)) ++ (do (or (eql 'body want) (go finish)) ++ (setq this-case (append (parse-loop-do) this-case)) ++ (setq want 'and)) ++ (and (or (eql 'and want) (error "Premature AND")) ++ (setq want 'body)) ++ (t (loop-un-pop)(return 'done))) ++ (go next-loop) ++ finish ++ (loop-un-pop)) ++ (or this-case (error "Hanging conditional")) ++ this-case) ++ ++ ++(defun parse-loop-when (&aux initial else else-clause ) ++ (declare (special *last-val* )) ++ (let ((test (cond ((l-equal *last-val* 'unless) `(not , (loop-pop))) ++ (t (loop-pop))))) ++ (setq initial (parse-one-when-clause)) ++ (lcase (loop-peek) ++ (else ++ (loop-pop) ++ (setq else t) ++ (setq else-clause (parse-one-when-clause))) ++ (t nil)) ++ `((cond (,test ,@ (nreverse initial)) ++ ,@ (and else `((t ,@ (nreverse else-clause)))))))) ++ ++(defun pointer-for-collect (collect-var) ++ (declare (special *loop-collect-pointers*)) ++ (or (cdr (assoc collect-var *loop-collect-pointers*)) ++ (let ((sym(loop-add-binding (gensym "POIN") nil nil :collect ))) ++ (push (cons collect-var sym) ++ *loop-collect-pointers*) ++ sym))) ++ ++(defun parse-loop-collect ( &aux collect-var pointer name-val) ++ (declare (special *last-val* *loop-body* *loop-collect-var* ++ *loop-collect-pointers* *inner-sloop* ++ *loop-prologue* )) ++ (and *inner-sloop* (throw 'collect nil)) ++ (let ((command *last-val*) ++ (val (loop-pop))) ++ (lcase (loop-pop) ++ (into (loop-add-binding (setq collect-var (loop-pop)) nil nil t nil t )) ++ (t (loop-un-pop) ++ (cond (*loop-collect-var* (setf collect-var *loop-collect-var*)) ++ (t (setf collect-var ++ (setf *loop-collect-var* ++ (loop-add-binding (gensym "COLL") nil ))))))) ++ (lcase command ++ ((append nconc collect) ++ (setf pointer (pointer-for-collect collect-var)) ++ (cond (*use-locatives* ++ (pushnew `(setf ,pointer ++ (locf ,collect-var)) *loop-prologue* :test 'equal))) ++ (lcase command ++ ( append ++ (unless (and (listp val) (eql (car val) 'list)) ++ (setf val `(copy-list ,val)))) ++ (t nil))) ++ (t nil)) ++ (cond ((and (listp val) (not *use-locatives*)) ++ (setq name-val (loop-add-binding (gensym "VAL") nil nil))) ++ (t (setf name-val val))) ++ (let ++ ((result ++ (lcase command ++ ((nconc append) ++ (let ((set-pointer `(and (setf (cdr ,pointer) ,name-val) ++ (setf ,pointer (last (cdr ,pointer)))))) ++ (cond (*use-locatives* ++ (list set-pointer)) ++ (t ++ `((cond (,pointer ,set-pointer) ++ (t (setf ,pointer (last (setf ,collect-var ,name-val)))))))))) ++ (collect ++ (cond (*use-locatives* ++ `((setf (cdr ,pointer) (setf ,pointer (cons ,name-val nil))))) ++ (t `((cond (,pointer (setf (cdr ,pointer) ++ (setf ,pointer (cons ,name-val nil)))) ++ (t (setf ,collect-var ++ (setf ,pointer (cons ,name-val nil))))))))) ++ (t (setq command (translate-name command)) ++ (cond ((find command *additional-collections* :test 'l-equal) ++ (loop-parse-additional-collections command collect-var name-val)) ++ (t (error "loop fell off end ~a" command))))))) ++ (cond ((eql name-val val) ++ result) ++ (t (nconc result `((setf ,name-val ,val) ))))))) ++ ++(defun loop-parse-additional-collections (command collect-var name-val &aux eachtime) ++ (declare (special *loop-prologue* *last-val* *loop-collect-var* *loop-epilogue* )) ++ (let* ((com (find command *additional-collections* :test 'l-equal)) ++ (helper (get com :sloop-collect))) ++ (let ((form (funcall helper collect-var name-val))) ++ (let ((*loop-form* form) *last-val*) ++ (declare (special *loop-form* *last-val*)) ++ (do ((v (loop-pop) (loop-pop))) ++ ((null *loop-form*)) ++ (lcase v ++ (:no-body) ++ (do (setq eachtime (parse-loop-do))))) ++ eachtime)))) ++ ++(defun the-type (symbol type) ++ (declare (special *no-declare*)) ++ (and *no-declare* (setf type nil)) ++ (and type (setf type (or (getf *Automatic-declarations* type) ++ (and (not (keywordp type)) type)))) ++ (and (consp type) (eq (car type) 'type) (setf type (second type))) ++ (cond (type (list 'the type symbol )) ++ (t symbol))) ++ ++;; ++ ++(defun type-error () ++ (error "While checking a bound of a sloop, I found the wrong type ++for something in *automatic-declarations*. Perhaps your limit is wrong? ++If not either use nodeclare t or set *automatic-declarations* to nil. ++recompile.")) ++ ++ ++;;this puts down code to check that automatic declarations induced by ++;; :from are indeed valid! It checks both ends of the interval, and ++;;so need not check the numbers in between. ++ ++(defun make-value (value type-key &aux type ) ++ (declare (special *no-declare*)) ++ (cond ((and ++ (not *no-declare*) ++ *type-check* ++ (eq type-key :from) ++ (setq type (getf *Automatic-declarations* type-key))) ++ (setq type ++ (cond ((and (consp type) ++ (eq (car type) 'type)) ++ (second type)) ++ (t type))) ++ (cond ((constantp value) ++ (or (typep value type) ++ (error ++ "Sloop found the type of ~a was not type ~a,~ ++ Maybe you want to insert SLOOP NODECLARE T ..." ++ value ++ type)) ++ (list value)) ++ (t (let (chk) ++ ++ `((let ,(cond ((atom value) ++ nil) ++ (t `((,(setq chk(gensym)) ,value)))) ++ (or (typep ,(or chk value) ',type) (type-error)) ++ ,(or chk value))))))) ++ (t (list value)))) ++ ++ ++;;keep track of the bindings in a list *loop-bindings* ++;;each element of the list will give rise to a different let. ++;;the car will be the variable bindings, ++;;the cdr the declarations. ++ ++ ++(defun loop-add-binding ++ (variable value &optional (new-level t) type force-type (force-new-value t) ++ only-if-not-there &aux tem) ++ "Add a variable binding to the current or new level. ++ If FORCE-TYPE, ignore a *no-declare*. ++ If ONLY-IF-NOT-THERE, check all levels." ++ (declare (special *loop-bindings*)) ++ (when (or new-level (null *loop-bindings*)) (push (cons nil nil) *loop-bindings*)) ++ (cond ((setq tem (assoc variable (caar *loop-bindings*) )) ++ (and force-new-value ++ (setf (cdr tem) (and value (make-value value type))))) ++ ((and (or only-if-not-there (and (null (symbol-package variable)) ++ (constantp value))) ++ (dolist (v (cdr *loop-bindings*)) ++ (cond ((setq tem (assoc variable (car v))) ++ (and force-new-value ++ (setf (cdr tem) ++ (and value (make-value value type)))) ++ (return t)))))) ++ (t (push (cons variable (and value (make-value value type))) ++ (caar *loop-bindings*)))) ++ (and type (loop-declare-binding variable type force-type)) ++ variable) ++ ++;(defmacro nth-level (n) `(nth ,n *loop-bindings*)) ++;if x = (nth i *loop-bindings*) ++;(defmacro binding-declares (x) `(cdr ,x)) ;(cons 'declare (binding-declares x)) to get honest declare statement ++;(defmacro binding-values (x) `(car ,x)) ;(let (binding-values x) ) to get let. ++ ++(defun loop-declare-binding (var type force-type &optional odd-type ++ &aux found tem) ++ (declare (special *loop-bindings* *Automatic-declarations* ++ *no-declare* *loop-map*)) ++ odd-type ;;ignored ++ (and type (setf type (or (getf *Automatic-declarations* type) ++ (and (not (keywordp type)) type)))) ++ (when (and type(or force-type (null *no-declare*))) ++ (dolist (v *loop-bindings*) ++ (cond ((assoc var (car v)) (setf found t) ++ (do ((decs (cdr v) (cdr decs))) ++ ((null decs) (push nil (cdr v))(setf tem (cdr v))) ++ (when (or (and (eq (caar decs) 'type) ++ (eq (third (car decs)) var)) ++ (eql (second (car decs)) var)) ++ (setf tem decs) (return 'done))) ++ (setf (car tem) ++ (cond ((and (consp type) (eq (car type) 'type)) ++ (list 'type (second type) var)) ++ (t (list type var)))) ++ ++ (and found (return 'done))))) ++ (or found *loop-map* (error "Could not find variable ~a in bindings" var))) ++ var) ++ ++(defun parse-loop-declare (&optional (decl-list (loop-pop)) (force t)) ++ (let ((type (car decl-list)) odd-type) ++ (cond ((eq type 'type) ++ (setf decl-list (cdr decl-list) type (car decl-list) odd-type t))) ++ (dolist (v (cdr decl-list)) ++ (loop-declare-binding v (car decl-list) force odd-type)))) ++ ++(defun loop-add-temps (form &optional val type new-level only-if-not-there) ++ (cond ((null form)) ++ ((symbolp form) ++ (loop-add-binding form val new-level type nil t only-if-not-there)) ++ ((listp form) ++ (loop-add-temps (car form)) ++ (loop-add-temps (cdr form))))) ++ ++(defun parse-loop-for ( &aux direction inc) ++ (declare (special *loop-form* *loop-map-declares* *loop-map* ++ *loop-body* *loop-increment* *no-declare* ++ *loop-prologue* ++ *loop-epilogue* ++ *loop-end-test* ++ *loop-bindings* ++ )) ++ (let* ((var (loop-pop)) test incr) ++ (do ((v (loop-pop) (loop-pop))) ++ (()) ++ (lcase v ++ (in (let ((lis (gensym "LIS"))) ++ (loop-add-temps var nil :in t) ++ (loop-add-binding lis (loop-pop) nil) ++ (push `(desetq ,var (car ,lis)) *loop-body*) ++ (setf incr `(setf ,lis (cdr ,lis))) ++ (setq test `(null ,lis) ) ++ )) ++ (on (let ((lis ++ (cond ((symbolp var) var) ++ (t (gensym "LIS"))))) ++ (loop-add-temps var nil :in t) ++ (loop-add-binding lis (loop-pop) nil) ++ (setf incr `(setf ,lis (cdr ,lis))) ++ (unless (eql lis var) ++ (push `(desetq ,var ,lis) *loop-body*)) ++ (setf test `(null ,lis)))) ++ ((upfrom from) ++ (loop-add-binding var (loop-pop) (not(prog1 direction (setf direction 'up))) :from) ++ (setf incr `(setf ,var ,(the-type `(+ ,var 1) :from)))) ++ (downfrom ++ (loop-add-binding var (loop-pop) (not(prog1 direction (setf direction 'down))) :from) ++ (setf incr `(setf ,var ,(the-type `(- ,var 1) :from)))) ++ (by(setq inc (loop-pop)) ++ (cond ((and (listp inc)(eql (car inc) 'quote)) ++ (setf inc (second inc)) ++ )) ++ (cond (direction ++ (setf incr (subst inc 1 incr))) ++ (t (setf incr (subst inc 'cdr incr))))) ++ (below ++ (let ((lim (gensym "LIM"))) ++ (loop-add-binding var 0 (not(prog1 direction (setf direction 'up))) ++ :from nil nil) ++ (loop-add-binding lim (loop-pop) nil :from ) ++ (or incr (setf incr `(setf ,var ,(the-type `(+ ,var 1) :from)))) ++ (setq test `(>= ,var ,lim)))) ++ (above ++ (let ((lim (gensym "ABOVE"))) ++ (loop-add-binding var 0 (not(prog1 direction (setf direction 'down))) ++ :from nil nil) ++ (loop-add-binding lim (loop-pop) nil :from ) ++ (or incr (setf incr `(setf ,var ,(the-type `(- ,var 1) :from)))) ++ (setq test `(<= ,var ,lim)))) ++ (to ++ (let ((lim (gensym "LIM"))) ++ (loop-add-binding var 0 (not(prog1 direction (or direction (setf direction 'up)))) ++ :from nil nil) ++ (loop-add-binding lim (loop-pop) nil :from ) ++ (or incr (setf incr `(setf ,var ,(the-type `(+ ,var 1) :from)))) ++ (setq test `(,(if (eql direction 'down) '< '>),var ,lim)))) ++ (:sloop-for (parse-loop-macro (translate-name v) :sloop-for var ) ++ (return 'done)) ++ (:sloop-map (parse-loop-map (translate-name v) var ) (return nil)) ++ (t(or ; (null *loop-form*) ++ (loop-un-pop)) ++ (return 'done) ++ ) ++ )) ++ ++ (let (type) ++ ;;whew maybe this is a for from type loop ++ ;;with no bound so to be safe need a fixnum bound.. ++ (cond ((and direction (not *no-declare*) ++ (not test) ++ *type-check* ++ (setq type (getf *automatic-declarations* :from)) ++ (progn (if (and (consp type)(eq (car type) 'type)) ++ (setf type (second type))) ++ (subtypep type 'fixnum))) ++ (or (constantp inc) (error "increment must be constant.")) ++ (push ++ (cond ((eq direction 'up) ++ `(or (< ,var ,(- most-positive-fixnum ++ (or inc 1))) ++ (type-error))) ++ (t ++ `(or (> ,var ,(+ most-negative-fixnum ++ (or inc 1)))) ++ (type-error)) ++ ) *loop-increment* ) ++ ))) ++ ++ (and test (push (copy-tree `(and ,test (local-finish))) *loop-end-test*)) ++ (and incr (push incr *loop-increment*)) ++ )) ++ ++(defun parse-loop-macro (v type &optional initial &aux result) ++ (declare (special *loop-form*)) ++ (let ((helper (get v type)) args) ++ (setq args ++ (ecase type ++ (:sloop-for ++ (let ((tem (get v :sloop-for-args))) ++ (or (cdr tem) (error "sloop-for macro needs at least one arg")) ++ (cdr tem))) ++ (:sloop-macro(get v :sloop-macro-args)))) ++ (let ((last-helper-apply-arg ++ (cond ((member '&rest args) (prog1 *loop-form* (setf *loop-form* nil))) ++ (t (dotimes (i (length args) (nreverse result)) ++ (push (car *loop-form*) result) ++ (setf *loop-form* (cdr *loop-form*))))))) ++ (setq *loop-form* ++ (append ++ (case type ++ (:sloop-for (apply helper initial last-helper-apply-arg)) ++ (:sloop-macro(apply helper last-helper-apply-arg))) ++ *loop-form*))))) ++ ++(defun parse-loop-map (v var) ++ (declare (special *loop-map* *loop-map-declares* *loop-form*)) ++ (and *loop-map* (error "Sorry only one allowed loop-map per sloop")) ++ (let ((helper (get v :sloop-map)) ++ (args (get v :sloop-map-args))) ++ (or args (error "map needs one arg before the key word")) ++ (cond ((member '&rest args)(error "Build this in two steps if you want &rest"))) ++ (let* (result ++ (last-helper-apply-arg ++ (dotimes (i (1- (length args)) (nreverse result)) ++ (push (car *loop-form*) result) (setf *loop-form* (cdr *loop-form*))))) ++ (setq *loop-map-declares* ++ (do ((v (loop-pop)(loop-pop)) (result)) ++ ((null (l-equal v 'declare)) ++ (loop-un-pop) ++ (and result (cons 'declare result))) ++ (push (loop-pop) result))) ++ (setq *loop-map* (apply helper var last-helper-apply-arg)) ++ nil))) ++ ++(defun substitute-sloop-body (inner-body) ++ (declare (special *loop-map* *loop-map-declares*)) ++ (cond (*loop-map* ++ (setf inner-body (list (subst (cons 'progn inner-body) ++ :sloop-body *loop-map*))) ++ (and *loop-map-declares* ++ (setf inner-body(subst *loop-map-declares* ++ :sloop-map-declares inner-body))))) ++ inner-body) ++ ++;;;**User Extensible Iteration Facility** ++ ++(eval-when (compile eval load) ++(defun def-loop-internal (name args body type &optional list min-args max-args ++ &aux (*print-case* :upcase) (helper (intern (format nil "~a-SLOOP-~a" name type)))) ++ (and min-args (or (>= (length args) min-args)(error "need more args"))) ++ (and max-args (or (<= (length args) max-args)(error "need less args"))) ++ `(eval-when (load compile eval) ++ (defun ,helper ,args ++ ,@ body) ++ ,@ (and list `((pushnew ',name ,list))) ++ (setf (get ',name ,(intern (format nil "SLOOP-~a" type) (find-package 'keyword))) ',helper) ++ (setf (get ',name ,(intern (format nil "SLOOP-~a-ARGS" type)(find-package 'keyword))) ',args))) ++) ++ ++ ++;;DEF-LOOP-COLLECT ++;;lets you get a handle on the collection var. ++;;exactly two args. ++;;First arg=collection-variable ++;;Second arg=value this time thru the loop. ++(def-loop-collect sum (ans val) ++ `(initially (setq ,ans 0) ++ do (setq ,ans (+ ,ans ,val)))) ++(def-loop-collect logxor (ans val) ++ `(initially (setf ,ans 0) ++ do (setf ,ans (logxor ,ans ,val)) ++ declare (fixnum ,ans ,val))) ++(def-loop-collect maximize (ans val) ++ `(initially (setq ,ans nil) ++ do (if ,ans (setf ,ans (max ,ans ,val)) (setf ,ans ,val)))) ++ ++(def-loop-collect minimize (ans val) ++ `(initially (setq ,ans nil) ++ do (if ,ans (setf ,ans (min ,ans ,val)) (setf ,ans ,val)))) ++ ++(def-loop-collect count (ans val) ++ `(initially (setq ,ans 0) ++ do (and ,val (setf ,ans (1+ ,ans))))) ++ ++(def-loop-collect thereis (ans val)(declare(ignore ans))`(do (if ,val (loop-return ,val)))) ++(def-loop-collect always (ans val) `(initially (setq ,ans t) do (and (null ,val)(loop-return nil)))) ++(def-loop-collect never (ans val) `(initially (setq ,ans t) do (and ,val (loop-return nil)))) ++ ++ ++;;DEF-LOOP-MACRO ++;;If we have done ++;(def-loop-macro averaging (x) ++; `(sum ,x into .tot. and count t into .how-many. ++; finally (loop-return (/ .tot. (float .how-many.))))) ++ ++;(def-loop-collect average (ans val) ++; `(initially (setf ,ans 0.0) ++; with-unique .how-many. = 0 ++; do (setf ,ans (/ (+ (* .how-many. ,ans) ,val) (incf .how-many.))) ++; )) ++ ++;;provides averaging with current value the acutal average. ++(def-loop-macro averaging (x) ++ `(with-unique .average. = 0.0 ++ and with-unique .n-to-average. = 0 ++ declare (float .average. ) declare (fixnum .n-to-average.) ++ do (setf .average. (/ (+ (* .n-to-average. .average.) ,x) (incf .n-to-average.))) ++ finally (loop-return .average.))) ++ ++(def-loop-macro repeat (x) ++ (let ((ind (gensym))) ++ `(for ,ind below ,x))) ++ ++(def-loop-macro return (x) ++ `(do (loop-return ,x))) ++;;then we can write: ++;(sloop for x in l when (oddp x) averaging x) ++ ++ ++;;DEF-LOOP-FOR ++;;def-loop-for and def-loop-macro ++;;are almost identical except that the def-loop-for construct can only occur ++;;after a for: ++;(def-loop-for in-array (vars array) ++; (let ((elt (car vars)) ++; (ind (second vars))) ++; `(for ,ind below (length ,array) do (setf ,elt (aref ,array ,ind))))) ++;; (sloop for (elt ind) in-array ar when (oddp elt) collecting ind) ++;;You are just building something understandable by loop but minus the for. ++;;Since this is almost like a "macro", and users may want to customize their ++;;own, the comparsion of tokens uses eq, ie. you must import IN-ARRAY to your package ++;;if you define it in another one. Actually we make a fancier in-array ++;;below which understands from, to, below, downfrom,.. and can have ++;;either (elt ind) or elt as the argument vars. ++ ++;;DEF-LOOP-MAP ++;;A rather general iteration construct which allows you to map over things ++;;It can only occur after FOR. ++;;There can only be one loop-map for a given loop, so you want to only ++;;use them for complicated iterations. ++ ++(def-loop-map in-table (var table) ++ `(maphash #'(lambda ,var :sloop-map-declares :sloop-body) ,table)) ++;Usage (sloop for (key elt) in-table table ++; declare (fixnum elt) ++; when (oddp elt) collecting (cons key elt)) ++ ++ ++(def-loop-map in-package (var pkg) ++ `(do-symbols (,var (find-package ,pkg)) :sloop-body)) ++ ++;(defun te()(sloop for sym in-package 'sloop when (fboundp sym) count t)) ++ ++;;in-array that understands from,downfrowm,to, below, above,etc. ++;;I used a do for the macro iteration to be able include it here. ++(def-loop-for in-array (vars array &rest args) ++ (let (elt ind to) ++ (cond ((listp vars) (setf elt (car vars) ind (second vars))) ++ (t (setf elt vars ind (gensym "INDEX" )))) ++ (let ((skip (do ((v args (cddr v)) (result)) ++ (()) ++ (lcase (car v) ++ ((from downfrom) ) ++ ((to below above) (setf to t)) ++ (by) ++ (t (setq args (copy-list v)) ++ (return (nreverse result)))) ++ (push (car v) result) (push (second v) result)))) ++ (or to (setf skip (nconc `(below (length ,array)) skip))) ++ `(for ,ind ++ ,@ skip ++ with ,elt ++ do (setf ,elt (aref ,array ,ind)) ,@ args)))) ++ ++;usage: IN-ARRAY ++;(sloop for (elt i) in-array ar from 4 ++; when (oddp i) ++; collecting elt) ++ ++;(sloop for elt in-array ar below 10 by 2 ++; do (print elt)) ++ ++(def-loop-for = (var val) ++ (lcase (loop-peek) ++ (then (loop-pop) `(with ,var initially (desetq ,var ,val) increment (desetq ,var ,(loop-pop)))) ++ (t `(with ,var do (desetq ,var ,val))))) ++ ++(def-loop-macro sloop (for-loop) ++ (lcase (car for-loop) ++ (for)) ++ (let (*inner-sloop* *loop-body* *loop-map* inner-body ++ (finish-loop (gensym "FINISH")) ++ a b c e f (*loop-form* for-loop)) ++ (declare (special *inner-sloop* *loop-end-test* *loop-increment* ++ *product-for* *loop-map* ++ *loop-form* *loop-body* *loop-prologue* *loop-epilogue* *loop-end-test* ++ *loop-bindings* ++ )) ++ (setf *product-for* t) ++ (loop-pop) ++ (sloop-swap) ++ (parse-loop-for) ++ (sloop-swap) ++ (do () ++ ((null *loop-form*)) ++ (cond ((catch 'collect (parse-loop1))) ++ ((null *loop-form*)(return 'done)) ++ (t ;(fsignal "hi") ++ (print *loop-form*) ++ (sloop-swap) ++ (parse-loop-collect) ++ (sloop-swap) ++ (print *loop-form*) ++ ))) ++ (sloop-swap) ++ (setf inner-body (nreverse *loop-body*)) ++ (and *loop-map* (setf inner-body (substitute-sloop-body inner-body))) ++ (let ((bod ++ `(macrolet ((local-finish () `(go ,',finish-loop))) ++ (tagbody ++ ,@ (nreverse *loop-prologue*) ++ ,@ (and (null *loop-map*) '(next-loop)) ++ ,@ (nreverse *loop-end-test*) ++ ,@ inner-body ++ ,@ (nreverse *loop-increment*) ++ ,@ (and (null *loop-map*) '((go next-loop))) ++ ,finish-loop ++ ,@ (nreverse *loop-epilogue*))))) ++ (dolist (v *loop-bindings*) ++ (setf bod ++ `(let ,(loop-let-bindings v) ,@(and (cdr v) `(,(cons 'declare (cdr v)))) ++ ,bod))) ++ (sloop-swap) ++ `(do ,bod)))) ++ ++;Usage: SLOOP FOR ++;(defun te () ++; (sloop for i below 5 ++; sloop (for j to i collecting (list i j)))) ++ ++(def-loop-for in-carefully (var lis) ++ "Path with var in lis except lis may end with a non nil cdr" ++ (let ((point (gensym "POINT"))) ++ `(with ,point and with ,var initially (setf ,point ,lis) ++ do(desetq ,var (car ,point)) ++ end-test (and (atom ,point)(local-finish)) ++ increment (setf ,point (cdr ,point))))) ++ ++;usage: IN-CAREFULLY ++;(defun te (l) ++; (sloop for v in-carefully l collecting v)) ++ ++;Note the following is much like the mit for i first expr1 then expr2 ++;but it is not identical, in that if expr1 refers to paralell for loop ++;it will not get the correct initialization. But since we have such generality in the ++;our definition of a for construct, it is unlikely that all people who define ++;This is why we use a different name ++ ++(def-loop-for first-use (var expr1 then expr2) ++ (or (l-equal then 'then) (error "First must be followed by then")) ++ `(with ,var initially (desetq ,var ,expr1) increment (desetq ,var ,expr2))) ++ ++(defvar *collate-order* #'<) ++ ++;;of course this should be a search of the list based on the ++;;order and splitting into halves. I have one such written, ++;;but for short lists it may not be important. It takes more space. ++(defun find-in-ordered-list ++ (it list &optional (order-function *collate-order*) &aux prev) ++ (do ((v list (cdr v))) ++ ((null v) (values prev nil)) ++ (cond ((eql (car v) it) (return (values v t))) ++ ((funcall order-function it (car v)) ++ (return (values prev nil)))) ++ (setq prev v))) ++ ++(def-loop-collect collate (ans val) ++ "Collects values into a sorted list without duplicates. ++Order based order function *collate-order*" ++ `(do (multiple-value-bind ++ (after already-there ) ++ (find-in-ordered-list ,val ,ans) ++ (unless already-there ++ (cond (after (setf (cdr after) (cons ,val (cdr after)))) ++ (t (setf ,ans (cons ,val ,ans)))))))) ++ ++;usage: COLLATE ++;(defun te () ++; (let ((res ++; (sloop for i below 10 ++; sloop (for j downfrom 8 to 0 ++; collate (* i (mod j (max i 1)) (random 2)))))))) ++ ++(defun map-fringe (fun tree) ++ (do ((v tree)) ++ (()) ++ (cond ((atom v) ++ (and v (funcall fun v))(return 'done)) ++ ((atom (car v)) ++ (funcall fun (car v))) ++ (t (map-fringe fun (car v) ))) ++ (setf v (cdr v)))) ++ ++(def-loop-map in-fringe (var tree) ++ "Map over the non nil atoms in the fringe of tree" ++ `(map-fringe #'(lambda (,var) :sloop-map-declares :sloop-body) ,tree)) ++ ++;;usage: IN-FRINGE ++;(sloop for v in-fringe '(1 2 (3 (4 5) . 6) 8 1 2) ++; declare (fixnum v) ++; maximize v) +--- /dev/null ++++ acl2-6.0/interface/infix/latex-theory.lisp +@@ -0,0 +1,165 @@ ++; ACL2 Version 1.9 ++ ++; Copyright (C) 1989-96 Computational Logic, Inc. (CLI). All rights reserved. ++ ++; Use of this software constitutes agreement with the terms of ACL2 ++; license agreement, found in the file LICENSE. ++ ++(in-package "user") ++ ++(load-base "latex-init") ++ ++; INFIX-OPS ++ ++; infix-ops (infix operators) should be function symbols of two or more ++; arguments for which it is desired that one symbol come out between every ++; adjacent pair of arguments. E.g., invoking (make-infix-op plus "+") causes ++; the term (plus a b c d) to be printed as (a $+$ b $+$ c $+$ d). Invoking ++; (make-infix-op equal "=" "\\not=") causes the term (equal x y) to be printed ++; as (x $=$ y) and it also causes the term (not (equal x y)) to be printed as ++; (x $\not= y). ++ ++; Thus, for example, if one introduces a new function, say join, and wants to ++; print terms of the form (join x y) as (x \bigtriangledown y), cf. p. 44 of ++; the Latex manual, then one should invoke: ++ ++; (make-infix-op join "\\bigtriangledown") ++ ++; from Lisp. That is all that need be done to cause infix-file to subsequently ++; print `join' terms this way. ++ ++; Note that throughout the following examples, we have used two backslashes to ++; get one because, in Common Lisp, backslash is a character for quoting other ++; characters. ++ ++; Examples of make-infix-op. ++ ++(make-infix-op eq "=_{eq}" "\\not=_{eq}") ++(make-infix-op = "=_{n}" "\\not=_{n}") ++(make-infix-op equal "=" "\\not=") ++(make-infix-op lessp "<" "\\not<") ++(make-infix-op < "<" "\\not<") ++(make-infix-op e0-ord-< "\\leq_\\epsilon" "\\not\\leq_\\epsilon") ++(make-infix-op leq "\\leq" "\\not\\leq") ++(make-infix-op <= "\\leq" "\\not\\leq") ++(make-infix-op greaterp ">" "\\not>") ++(make-infix-op > ">" "\\not>") ++(make-infix-op geq "\\geq" "\\not\\geq") ++(make-infix-op >= "\\geq" "\\not\\geq") ++(make-infix-op member "\\in" "\\not\\in") ++ ++(make-infix-op append " @ ") ++ ++(make-infix-op implies "\\rightarrow") ++(make-infix-op iff "\\leftrightarrow") ++(make-infix-op / "/") ++(make-infix-op remainder "{\\rm\\bf{mod}}") ++(make-infix-op union "\\cup") ++(make-infix-op + "+") ++(make-infix-op - "-") ++(make-infix-op * "*") ++(make-infix-op and "\\wedge") ++(make-infix-op or "\\vee") ++(make-infix-op congruent "\\cong") ++ ++(defun zerop-printer (term) ++ (infix-print-term1 (list 'congruent (cadr term) 0))) ++ ++(declare-fn-printer zerop (function zerop-printer)) ++ ++(make-infix-op intersection-theories "\\cap") ++(make-infix-op set-difference-theories "{\\rm\\bf{less}}") ++(make-infix-op union-theories "\\cup") ++ ++ ++; UNARY-PREFIX-OPS, UNARY-SUFFIX-OPS, and UNARY-ABS-OPS ++ ++; Use make-unary-prefix-op and make-unary-suffix-op only for function symbols ++; of one argument. The string str (or *neg-str*) will be printed before or ++; after the argument. ++ ++; unary-suffix-ops should be unary function symbols. ++ ++; (make-unary-suffix-op foo x str) makes (foo x) print as (x $str$). ++ ++; Examples of make-unary-suffix-op. ++ ++(make-unary-suffix-op sub1 "-\\;1") ++(make-unary-suffix-op numberp "\\in {\\rm\\bf{N}}" "\\not\\in {\\rm\\bf{N}}") ++(make-unary-suffix-op zerop "\\simeq {\\tt{0}}" "\\not\\simeq {\\tt{0}}") ++;; (make-unary-suffix-op nlistp "\\simeq {\\rm{\\bf{nil}}}" "\\not\\simeq {\\rm{\\bf{nil}}}") ++ ++; unary-prefix-ops should be unary function symbols. ++ ++; (make-unary-prefix-op foo str) makes (foo x) print as ($str$ x). ++ ++; Examples of make-unary-prefix-op. ++ ++(make-unary-prefix-op 1+ "1\\;+") ++(make-unary-prefix-op minus "-") ++ ++; unary-abs-ops should be unary function symbols. ++ ++; To create syntax like that for absolute value, use (make-unary-absolute-op ++; lhs-str rhs-str), where lhs-str and rhs-str are the strings to print on the ++; left and right of the argument. (make-unary-abs-op foo str1 str2) makes (foo ++; x) print as (str1 x str2). See the example for abs below. ++ ++ ++; SOME POSSIBLE EXTENSIONS ++ ++(defun simple-extension () ++ ++; Here are a few examples of normal mathematical notation for functions not in ++; the bootstrap. Invoke this function to put these into effect. ++ ++ (make-unary-abs-op abs "\\mid" "\\mid") ++ ++ (make-unary-suffix-op fact "{\\rm{!}}") ++ ++ ++ (make-infix-op subsetp "\\subset" "\\not\\subset") ++ (make-infix-op intersect "\\cap")) ++ ++(defun dmg-syntax () ++ ++; Here are some examples once tentatively proposed by David Goldschlag for his ++; work. Invoke this function to put these into effect. ++ ++; prefix-multiple-op's should be function symbols that take as many arguments as ++; make-prefix-multiple-op is given arguments. (make-prefix-multiple-op foo str1 ++; str2) makes (foo x y) print as ($str1$ x $str2$ y). That is, the first string ++; comes first. ++ ++ (make-prefix-multiple-op invariant "\\Box" "{\\rm\\bf{in}}") ++ (make-prefix-multiple-op eventually-stable "\\Diamond\\Box" "{\\rm\\bf{in}}") ++ ++; infix-multiple-op's should be function symbols that take one more argument ++; than make-infix-multiple-op is given arguments. (make-infix-multiple-op foo ++; str1 str2) makes (foo x y z) print as (x $str1$ y $str2$ z). That is, the ++; strings are placed between adjacent arguments. ++ ++ (make-infix-multiple-op leads-to "\\mapsto" "{\\rm\\bf{in}}") ++ (make-infix-multiple-op unless "{\\rm\\bf{unless}}" "{\\rm\\bf{in}}") ++ (make-infix-multiple-op ensures "{\\rm\\bf{ensures}}" "{\\rm\\bf{in}}") ++ (make-infix-multiple-op e-ensures "\,${\\rm\\bf{e-ensures}}$\," "{\\rm\\bf{for}}" ++ "{\\rm\\bf{in}}") ++ (make-infix-multiple-op n "\\leadsto" "{\\rm\\bf{by}}") ++ (make-infix-multiple-op initial-condition "{\\rm{\\bf{initially\\;in}}}")) ++ ++; Undoing. To cause applications of a function symbol fn to be printed in the ++; default way, i.e., fn(x, y), invoke (clean-up 'fn). ++ ++(defparameter *do-not-index-calls-of* ++ (union *do-not-index-calls-of* ++ '(implies and or not if cond ++ implies iff union ++ eq = equal ++ le < > ge leq <= geq >= lessp e0-ord-< ++ greaterp ++ member append ++ + - * / remainder ++ union intersection ++ car cadr cdr cddr caddr cons consp ++ disable force integerp member-equal null ++ stringp symbolp true-listp alistp))) +--- /dev/null ++++ acl2-6.0/interface/infix/doinfix +@@ -0,0 +1,66 @@ ++#!/bin/csh ++ ++# Usage: doinfix sample.lisp scribe ++# : doinfix sample.lisp latex ++# : doinfix sample.lisp { defaults to sample or Scribe } ++# If you want the default mode to be LATEX then set DMODE ++# in this file. ++ ++# My apologies for this ugly script. Surely there's ++# a better way to do this. ++ ++if (${#argv} == 0) then ++ echo 'usage: "doinfix file [mode]"' ++ exit ++endif ++ ++set DIR = /slocal/src/acl2/v1-8/interface/infix ++set DMODE = "scribe" ++set FILE = ${argv[1]} ++set ROOT = $FILE:r ++set THEORY = $ROOT-theory.lisp ++ ++if (${#argv} == 1) then ++ if ( -f $THEORY ) then ++ set MODE=$ROOT ++ else ++ set MODE=$DMODE ++ endif ++else ++ set MODE=${argv[2]} ++endif ++ ++# Want LOG to be written in the current directory. ++set LOG = $ROOT:t.$MODE.log ++ ++rm -f workxxx ++echo ':q' > workxxx ++echo '(in-package "user")' >> workxxx ++echo -n '(load "' >> workxxx ++echo -n $DIR >> workxxx ++echo '/infix")' >> workxxx ++echo -n '(infix-file "' >> workxxx ++echo -n $FILE >> workxxx ++echo -n '" :mode "' >> workxxx ++echo -n ${MODE} >> workxxx ++echo '")' >> workxxx ++ ++acl2 < workxxx > $LOG ++ ++if (${MODE} == "scribe") then ++ scribe $ROOT.mss >> $LOG ++else ++ if (${MODE} == "latex") then ++ latex $ROOT >> $LOG ++else ++ if (-f $ROOT.mss ) then ++ scribe $ROOT.mss >> $LOG ++else ++ if (-f $ROOT.tex ) then ++ latex $ROOT >> $LOG ++endif ++endif ++endif ++endif ++ ++echo "See log file, $LOG." +--- /dev/null ++++ acl2-6.0/interface/infix/scribe-theory.lisp +@@ -0,0 +1,186 @@ ++; ACL2 Version 1.9 ++ ++; Copyright (C) 1989-96 Computational Logic, Inc. (CLI). All rights reserved. ++ ++; Use of this software constitutes agreement with the terms of ACL2 ++; license agreement, found in the file LICENSE. ++ ++(in-package "user") ++ ++;; The init file should be compiled. ++(load-base "scribe-init") ++ ++(defun nth-printer (term) ++ (let ((n (cadr term)) ++ (expr (caddr term))) ++ (infix-print-term1 expr) ++ (pprinc "@-{") ++ (infix-print-term1 n) ++ (pprinc "}"))) ++ ++(declare-fn-printer nth (function nth-printer)) ++ ++(defun list-printer (term) ++ (pprinc "[") ++ (infix-print-l (cdr term)) ++ (pprinc "]")) ++ ++(declare-fn-printer list (function list-printer)) ++ ++ ++ ++; INFIX-OPS ++ ++; infix-ops (infix operators) should be function symbols of two or more ++; arguments for which it is desired that one symbol come out between every ++; adjacent pair of arguments. E.g., invoking (make-infix-op plus "+") causes ++; the term (plus a b c d) to be printed as (a + b + c + d). Invoking ++; (make-infix-op equal "=" "@neq") causes the term (equal x y) to be printed ++; as (x = y) and it also causes the term (not (equal x y)) to be printed as ++; (x @neq y). ++ ++; Thus, for example, if one introduces a new function, say join, and wants to ++; print terms of the form (join x y) as (x @delta y): ++ ++; (make-infix-op join "@delta") ++ ++; from Lisp. That is all that need be done to cause infix-file to subsequently ++; print `join' terms this way. ++ ++; Note that throughout the following examples, we have used two backslashes to ++; get one because, in Common Lisp, backslash is a character for quoting other ++; characters. ++ ++; Examples of make-infix-op. ++ ++(make-infix-op eq "@eq@-{eq}" "@neq@-{eq}") ++(make-infix-op = "@eq@-{n}" "@neq@-{n}") ++(make-infix-op equal "@eq" "@neq") ++(make-infix-op lessp "@lt") ++(make-infix-op < "@lt") ++(make-infix-op e0-ord-< "@lt@-{@g(e)}") ++(make-infix-op leq "@lte") ++(make-infix-op <= "@lte") ++(make-infix-op greaterp "@gt" ) ++(make-infix-op > "@gt" ) ++(make-infix-op geq "@gte") ++(make-infix-op >= "@gte") ++(make-infix-op member "@in" "@notin") ++ ++(make-infix-op append "@@") ++ ++(make-infix-op implies "@rightarrow") ++(make-infix-op iff "@iff") ++(make-infix-op / "@div") ++ ++;; Use sinfix def ++(make-infix-op remainder "@b{mod}") ++(make-infix-op union "@union") ++(make-infix-op + "@add") ++(make-infix-op - "@sub") ++(make-infix-op * "@mult") ++(make-infix-op and "@and") ++(make-infix-op or "@or") ++(make-infix-op congruent "@congruent") ++ ++(defun zerop-printer (term) ++ (infix-print-term1 (list 'congruent (cadr term) 0))) ++ ++(declare-fn-printer zerop (function zerop-printer)) ++ ++(make-infix-op intersection-theories "@inter") ++(make-infix-op set-difference-theories "@i{less}") ++(make-infix-op union-theories "@union") ++ ++ ++; UNARY-PREFIX-OPS, UNARY-SUFFIX-OPS, and UNARY-ABS-OPS ++ ++; Use make-unary-prefix-op and make-unary-suffix-op only for function symbols ++; of one argument. The string str (or *neg-str*) will be printed before or ++; after the argument. ++ ++; unary-suffix-ops should be unary function symbols. ++ ++; (make-unary-suffix-op foo x str) makes (foo x) print as (x @math{str}). ++ ++; Examples of make-unary-suffix-op. ++ ++(make-unary-suffix-op 1- " @sub 1") ++(make-unary-suffix-op numberp "@in @b{N}" "@notin @b{N}") ++(make-unary-suffix-op zerop "@congruent @ @t{0}") ++;; (make-unary-suffix-op nlistp "@approx @b{nil}" "@not @approx @b{nil}") ++ ++; unary-prefix-ops should be unary function symbols. ++ ++; (make-unary-prefix-op foo str) makes (foo x) print as ($str$ x). ++ ++; Examples of make-unary-prefix-op. ++ ++(make-unary-prefix-op 1+ "1 @add ") ++(make-unary-prefix-op minus "@sub ") ++ ++; unary-abs-ops should be unary function symbols. ++ ++; To create syntax like that for absolute value, use (make-unary-absolute-op ++; lhs-str rhs-str), where lhs-str and rhs-str are the strings to print on the ++; left and right of the argument. (make-unary-abs-op foo str1 str2) makes (foo ++; x) print as (str1 x str2). See the example for abs below. ++ ++ ++; SOME POSSIBLE EXTENSIONS ++ ++ ++(defun simple-extension () ++ ++; Here are a few examples of normal mathematical notation for functions not in ++; the bootstrap. Invoke this function to put these into effect. ++ ++ (make-unary-abs-op abs "@abs<" ">") ++ (make-unary-suffix-op fact "@r{!}") ++ (make-infix-op subsetp "@subset") ++ (make-infix-op intersect "@inter")) ++ ++ ++(defun dmg-syntax () ++ ++; Here are some examples once tentatively proposed by David Goldschlag for his ++; work. Invoke this function to put these into effect. ++ ++; prefix-multiple-op's should be function symbols that take as many arguments as ++; make-prefix-multiple-op is given arguments. (make-prefix-multiple-op foo str1 ++; str2) makes (foo x y) print as ($str1$ x $str2$ y). That is, the first string ++; comes first. ++ ++ (make-prefix-multiple-op invariant "@box(@ )" "@b{in}") ++ (make-prefix-multiple-op eventually-stable "@lozenge@box(@ )" "@b{in}") ++ ++; infix-multiple-op's should be function symbols that take one more argument ++; than make-infix-multiple-op is given arguments. (make-infix-multiple-op foo ++; str1 str2) makes (foo x y z) print as (x $str1$ y $str2$ z). That is, the ++; strings are placed between adjacent arguments. ++ ++ (make-infix-multiple-op leads-to "@pari" "@b{in}") ++ (make-infix-multiple-op unless "@b{unless}" "@b{in}") ++ (make-infix-multiple-op ensures "@b{ensures}" "@b{in}") ++ (make-infix-multiple-op e-ensures "@ @b{e-ensures}@ " "@b{for}" "@b{in}") ++ ; (make-infix-multiple-op n "\\leadsto" "{\\rm\\bf{by}}") ++ (make-infix-multiple-op initial-condition "@b{initially@quad in}")) ++ ++; Undoing. To cause applications of a function symbol fn to be printed in the ++; default way, i.e., fn(x, y), invoke (clean-up 'fn). ++ ++(defparameter *do-not-index-calls-of* ++ (union *do-not-index-calls-of* ++ '(implies and or not if cond ++ implies iff union ++ eq = equal ++ le < > ge leq <= geq >= lessp e0-ord-< ++ greaterp ++ member append ++ + - * / remainder ++ union intersection ++ car cadr cdr cddr caddr cons consp ++ disable force integerp member-equal null ++ strinp symbolp true-listp alistp))) ++ ++ +--- /dev/null ++++ acl2-6.0/interface/infix/infix.lisp +@@ -0,0 +1,5935 @@ ++; ACL2 Version 1.9 ++ ++; Copyright (C) 1989-96 Computational Logic, Inc. (CLI). All rights reserved. ++ ++; Use of this software constitutes agreement with the terms of ACL2 ++; license agreement, found in the file LICENSE. ++ ++; NOTE: we depend on the following externally defined package: ++ ++(in-package "USER") ++ ++;; MAJOR MODS ++ ++;; 1. Added ACL2 ~ formatting conventions in doc strings and comments. ++;; BUT THEY ONLY APPLY IF THIS FILE IS LOADED INTO ACL2. ++;; And the following may be used to disable it. ++;; *acl2-format-comments* => nil, *acl2-format-doc-strings* => nil. ++;; Ignored in lisp. ++;; We handle doc strings by calling an ACL2 function ++;; that takes a doc string and 2 tables and returns ++;; a doc string, with the ACL2 formatting done. ++;; In order to handle arbitrary formatting within doc strings `~id[x]` ++;; will eventually map to `x`. Thus, in scribe mode, ~id[@section](Testing) ++;; will come out as @section(Testing). ++;; Whereas @section(Testing) would come out as @@section(Testing) ++ ++;; BUGS ++ ++;; 1. In comments !p(implies a b) produces different results from !p(IMPLIES a b) ++;; Case is honored when reading comments. !p may need to adjust case. ++;; We could just store things redundantly under `IMPLIES' and `implies', ++;; but then we would fail on `Implies' ++;; ++;; 2. "~ID[{\\it foo}]" does not map to "{\\it foo}". The braces get quoted. ++;; Matt Kaufmann may fix. Until then, the user can either not use ++;; any special formatting other that that provided by ! and ~, or can ++;; turn off ACL2 formatting, by setting *acl2-format-doc-strings* and ++;; *acl2-format-comments* to nil. (See keyword args to INFIX-FILE and ++;; INFIX-SETTINGS.) With this turned off you can still use ! and whatever ++;; native text formatting conventions you wish. ++;; ++;; 3. "!cfoo" when processed by nqftm2fmt will result in an attempt to ++;; eval foo. This may break, if the user is not taking advantage of ++;; this !c `feature'. ++ ++;; Note the difference between the backslash in comments and the backslash ++;; in doc strings. In doc strings, because they are read as strings, they ++;; need to be quoted (e.g. doubled). ++ ++ ++;; INTERACTIONS ++ ++;; We treat comments and doc strings similarly. The only difference is that ++;; the initial comment characters of a comment line determine the format that ++;; the comment text is imbedded in (e.g. running text, verbatim, format, etc. ++;; See COMMENT-FORMAT documentation). ++ ++;; There are 3 (at least) kinds of imbedded formatting commands ++;; that can occur in comments and doc strings. They are handled ++;; in distinct phases of processing. ++;; ++;; 1. ~ ACL2 doc string formatting commands. ++;; 2. ! Infix commands. ++;; 3. Text formatter commands (Scribe or LaTeX) ++;; ++;; The first two effect the output of this infix processor. ++ ++;; To ensure that your text formatter (type 3) commands ++;; are preserved during processing steps 1 and 2, the simplest ++;; approach is to enclose the commands that you wish ++;; to preserve in the ~id[...] form or between ~bid[] .. ~eid[] pairs. ++;; SEE BUG 2 ABOVE. ++ ++;; Comments and doc strings are preprocessed to translate their ACL2 ++;; formatting commands to our target formatter. ++;; Note that the ACL2 doc formatter goes to great lengths to make sure ++;; weird characters in the target dialect are quoted. So if you want ++;; such things preserved, you need to use the ~id forms above. Because ++;; we now pass comment text through the ACL2 doc formatter, you ++;; will need to treat comments as you treat doc strings. ++;; You also need ;; to be careful of occurences of "~". If a "~" is ++;; not followed by an ACL2 formatting command, we will complain. ++ ++;; Load packages and macros we depend on. ++;; [The following comment is modified from previous versions, which said ++;; "Require must be here.".] ++;; Require probably must be here if using other than GCL. ++ ++#-gcl ++(progn ++ (require "sloop" "/acl2/interface/infix/sloop") ++ (use-package "SLOOP")) ++ ++;; Add space for CFUNs (compiled funs without environment) in GCL. ++ ++#+gcl(eval-when (load eval compile) ++ (defun pages-allocated (type) ++ (declare (ignore type)) ++ (multiple-value-bind ++ (nfree npages maxpage nppage gcs used) (system:allocated 'cfun) ++ (declare (ignore nfree maxpage nppage gcs used)) ++ npages))) ++ ++#+gcl(eval-when (load) ++ (cond ++ ((boundp 'si::*gcl-major-version*) ;GCL 2.0 or greater ++ (if (< (pages-allocated 'cfun) 200) (sys:allocate 'cfun 200))) ++ ((< (sys::allocated-pages 'cfun) 200) (sys:allocate 'cfun 200)))) ++ ++;; ACL2 doc string interaction. First is for ~ directives, second ++;; for special characters. ++ ++(defvar acl2-markup-table nil) ++(defvar acl2-char-subst-table nil) ++ ++;; Read-keyword command uses the acl2 read to suck in keyword ++;; commands. ++ ++(proclaim '(ftype (function (t) t) ++ acl2-parse-string ++ read-keyword-command)) ++ ++(defvar a-very-rare-cons nil) ++ ++(defun read-keyword-form (key n) ++ "This function reads the N args for keyword command, KEY, ++where we have used ACL2 mechanisms to compute N. It returns a form. ++If KEY cannot be presented in keyword form, N will be NIL." ++ (cond ((null n) key) ++ ((integerp n) ++ (let (args) ++ (sloop for i from 1 to n ++ do (setq args ++ (append ++ args ++ (list (readx *standard-input* nil a-very-rare-cons nil))))) ++ (cons (intern (symbol-name key)) args))) ++ (t key))) ++ ++(eval-when (load eval compile) ++ ++;; Set this to be the directory in which we compile this file. ++(defparameter *infix-directory* #.(namestring (truename "./"))) ++ ++) ++ ++(defun load-base (s) ++ (load (concatenate 'string *infix-directory* s))) ++ ++(eval-when (load eval) ++ ++(if (find-package "acl2") ++ (progn (load-base "acl2-formatting.lisp")) ++ ++ (progn (defun acl2-parse-string (doc) (cons nil doc)) ++ (defun acl2-keywordp (key) nil) ++ (defun read-keyword-command (key) key))) ++ ++) ++ ++ ++#| ++ ++ A Conventional Syntax Pretty-Printer for ACL2 ++ ++ Originially written by Rober Boyer ++ Modified for Scribe by Michael K. Smith (2/92,8/93) ++ Modified for ACL2 by Michael K. Smith (10/93) ++ ++ ++ INTRODUCTION ++ ++The functions in this file implement a pretty-printer for Acl2 events. The ++syntax produced is conventional mathematical notation. ++ ++This file is not automatically compiled or loaded when building Acl2. ++To use this printer, after compiling and loading Acl2, compile this file and ++load it, i.e., (compile-file "infix.lisp") and (load "infix"). For ++more information on installation see the README file in the directory ++containing this file. ++ ++The following text is, currently, the only documentation for this facility. ++Criticism of all sorts solicited. ++ ++ ++ BASIC USE ++ ++The intent is to take an ACL2 events file and produce a nicely formatted ++document. Knowing what text formatter you are targeting, you can insert text ++formatting commands into comments. You can also request an infix ++transformation of prefix forms in comments (see documentation of function ++NQFMT2FMT. ++ ++ONE NOTE OF CAUTION: It is important that you know what text formatter you ++are targetting, since the bulk of your comments will be copied literally into ++the text input file. It is up to you to ensure that the interaction of ++your comments with the formatting convention of choice for the various ++comment types results in legal text formatting commands. That is, if you ++are in Scribe mode and a comment contains an email message with net addresss ++you should quote occurences of "@" as "@@". More importantly, if you decide ++that ";\" introduces a line to be formatted as raw LaTex (the default in ++"latex" mode), you need to ensure that any occurrence of "_" or other LaTeX ++special characters on such a line results in a meaningful formatting ++command. For simple transformations of .event files to LaTeX I suggest you ++use the default :COMMENT-FORMAT (= 'BOYER). This causes most comments to be ++formatted within verbatim environments, which are not so picky about special ++characters. Scribe is more forgiving of these problems because it only has ++the single special character, "@" that needs to be watched out for. (See ++`SETTINGS THAT MAY BE MODIFIED IN MODE-THEORY.LISP'.) ++ ++There are two basic modes, "latex" and "scribe". You can then build on top of ++these to customize the printing of functions in your theory. All mode ++sensitivity should be contained in the file <mode>-theory.lisp. Normally this ++file also loads a basic file called <mode>-init.lisp. The idea is that the ++`-init' files contain the minimal required information for INFIX to do its job ++with respect to a particular text formatter. The `-theory' file contains the ++details of how you want the functions in your theory to be printed. ++`Scribe-theory.lisp' and `latex-theory.lisp' load `scribe-init.lisp' and ++`latex-init.lisp', respectively. ++ ++In order to customize printing for a particular file of events, say ++"clock.events", we suggest the following approach. Each column shows the ++procedure for the corresponding text formatter, Latex or Scribe. ++ ++First, assume we have a file "clock.events", in proper syntactic form for ++acceptance by LD. That is to say, suppose that the file ++"clock.events" contains only legal event commands such as defun's and ++defthm's, Lisp style comments, and the few other sorts of miscellaneous ++instructions documented as legal instructions to LD. ++ ++ ++1. Create clock-theory.lisp. It should have the following form: ++ ++- Tex Scribe ++- ---------------------------------------------------------------- ++- (load-base "latex-theory.lisp") (load-base "scribe-theory.lisp") ++- ... ++- Your extensions and/or redefinitions. ++- See in particular the documentation on make-infix et.al. ++- under `SIX GENERAL OPERATOR SCHEMAS', and the examples at the ++- end of this file and in scribe-theory.lisp and latex-theory.lisp. ++- ... ++- INFIX-SETTINGS provides some simple control over an assortment of ++- formatting options. See `SETTINGS THAT MAY BE MODIFIED IN MODE-THEORY.LISP'. ++- ... ++- (infix-settings :mode "clock" (infix-settings :mode "clock" ++- :extension "tex" ...) :extension "mss" ...) ++ ++2. Save clock-theory.lisp, preferably in the same directory with clock.events. ++ ++3. Call infix-file. The simplest call on infix-file would be just ++ ++- (infix-file "clock"). ++ ++ which will result in the file "clock.tex" or "clock.mss" ++ ++4. Run the appropriate formatter. ++ ++5. Special considerations for latex vs. scribe. ++ ++- To get an index in LaTeX. To avoid an index in Scribe ++- ---------------------------------------------------------------- ++- %latex clock Insert @disable(Index) in clock.mss. ++- %makeindex clock ++- %latex clock ++ ++ ++A full blown call to infix-file includes a file root and keyword arguments. ++Below is such a call with keywords supplied with their defaults. ++ ++- (infix-file fl :print-case :downcase :mode nil :chars-wide 77 :comment t) ++- ++- :print-case - must be one of :downcase, :upcase, or :capitalize. ++- DEFAULT: :downcase. ++- ++- :mode - if not provided (thus defaulting to nil) we look for ++- "fl-theory.lisp" and load it if present. If not, we use ++- the mode of the last successfull call to infix-file or ++- query whether you want to use Scribe or Latex mode. ++- In this last case you will need to know where the basic ++- theory files are located. Simplest is to create a trivial ++- -theory file in the same directory as the event files that ++- just loads appropriate scribe or latex -theory file. ++- DEFAULT: fl root name. If not found, queries the user. ++- ++- :chars-wide - approximate width in characters of the formatted output. ++- Controls where infix inserts line breaks within expressions. ++- DEFAULT: 77. ++- ++- :comment - If t, then certain specially marked Acl2 expressions in ++- comments are replaced with their conventional notation. ++- See the documentation of the function `nqfmt2fmt' below for ++- a description of the special syntax for this replacement ++- process. We assume you use this feature. If not, ++- set *nq-default* to NIL in your mode file. ++- DEFAULT: T. ++ ++ ++ COMMENT HANDLING ++ ++- Jul 28 93 MKS - Extended comment handling. ++- Aug 3 93 MKS - Still haven't done anything with internal comments. ++ ++Modified Treatment of comments: `infix-file' preserves comments ++between events, but skips over comments within events. We completely ++skip comments within events because we have not figured out how to ++place them appropriately mechanically. Documentations strings in ++events are handled, normally by pulling them out of the event and ++inserting them before the event itself. ++ ++Comments are formatted in several ways, depending on the character immediately ++following the semi-colon or OPEN-BAR-COMMENT. A comment may be turned into: ++ ++- 1. Running TEXT. The comment chars (see definition following) are ++- eliminated and the text is copied to the output file. ++- ++- 2. A FORMATted environment. The comment chars (see definition ++- following) are eliminated, line breaks and spaces are preserved, and ++- the font is the default document font. ++- ++- 3. A VERBATIM environment. The comment chars may or may not be preserved, ++- line breaks and spaces are PRESERVED and the font is a fixed width font. ++- ++- 4. An EMPHASIS environment. Like format, but the font is italic. ++ ++This set, which is used by the named formats in *comment-format-alist*, can ++be extended by modifying the value of *comment-environment-mapping* in your ++theory file. ++ ++To replace the comment format conventions, use (define-comment-format name ++format). ++ ++The format argument has two parts, one for semi-colon comments ++and the other for #| ... |# comments. The assignment below corresponds to ++Boyer's initial setting. ++ ++- (define-comment-format 'boyer ++- '((#\; (("\\" nil text)) nil verbatim #\;) ++- (#\# (("\\" nil text)) t verbatim ))) ++ ++The structure of each of these lists is ++- type ::= (label (substring*) spaces-p format [char]) ++- substring ::= (string spaces-p format [char]) ++ ++LABEL indicates which of the two types of comments we are looking at, either ++those that start with a SEMI-COLON or those that start with LB VERTICAL-BAR. ++We determine what to do in the various cases (which amounts to choosing ++SPACES-P, FORMAT, and CHAR) based on whether the comment type indicated by ++LABEL is followed by any of the strings that begin SUBSTRINGS or not. If it ++matches, we use the components of the matching substring, otherwise we use ++the default for the comment type, i.e. the elements of the type list. ++ ++- If SPACES-P, consume one space if there is one. ++- Begin formatting according to FORMAT. ++- Insert CHAR. ++ ++So, for the example above, the first sublist, whose car is the semi-colon ++character, describes how to format comments that begin with a semi-colon followed ++by specific strings. There are two possibilites. If the semi-colon is not ++followed by a back-slash (\), we don't look for a space, we ensure we are in a ++verbatim environment, and print a semi-colon. If semi-colon is followed by a ++back-slash, we don't look for a space and ensure that we are in a text environment. ++ ++Thus, if we encounter a comment beginning ";\", the comment should be ++inserted as top level text with no special formatting. The ";\" will not show ++up in the output. ++ ++ ++- COMMENT TRANSFORMATIONS: ++ ++There are three versions. One reflects MKSmith's preferences, one Boyer's, ++and one the Common Lisp defaults. MKSmiths is the default. To get Boyer's, ++do (setup-comment-format 'boyer). To get Common Lisp's, do ++(setup-comment-format 'cl). You can insert this form in your theory file. ++To create your own conventions, see DEFINE-COMMENT-FORMAT. ++ ++- Description: ++ ++- BT begins running text, with no environment modifiers. ++- BF ... EF corresponds to <begin-format> ... <end-format> ++- BV ... EV corresponds to <begin-verbatim> ... <end-verbatim> ++- BE ... EE corresponds to <begin-emphasis> ... <end-emphasis> ++- BS ... ES corresponds to <begin-section-name> ... <end-section-name> ++- BC ... EC corresponds to <begin-comment> ... <end-comment> ++- ++- MKS Boyer CL ++- ++- #| ... |# BT... BV ... EV BT... ++- #|\ ... |# BT... BT ... BT... ++- #|- ... |# BF... EF BV- ... EV BF... EF ++- #|; ... |# BV... EV BV; ... EV BV... BV ++- ++- ; ... BT... BV; ... EV BE... EE ++- ;; ... BT... BV;; ... EV BF... EF ++- ;;; ... BV... EV BV;;; ... EV BT... ++- ;;;; ... BV;... EV BV;;;; ... EV BS... ES ++ ++- ;# ... BC... EC ++- ;\ ... BT... BT ... BT... ++- ;- ... BF... EF BV;- ... EV BF... EF ++- ;+ ... BV... EV BV;+ ... EV BV... EV ++- ;! ... BE... EE BV;! ... EV BE... EE ++ ++- ;;- ... BF; ... EF BV;;- ... EV BF; ... EF ++- ;;+ ... BV; ... EV BV;;+ ... EV BV; ... EV ++- ;;! ... BE; ... EE BV;;! ... EV BE; ... EE ++ ++ ++ ++ COVERAGE ++ ++The `infix-file' function should handle the entirety of the Acl2 term syntax ++checked by ld. We DO print out the `hint' parts of events. ++ ++ ++ ++ MOTIVATION ++ ++We hope this notation will facilitate the communication of work with Acl2 to ++those who do not happily read Lisp notation. But we have no expectation that ++this notation will make it easier for the Acl2 user to formulate or to prove ++theorems. ++ ++ ++ NO ERROR CHECKING ++ ++Warning about the absence of error checking: In general, user-callable ++subroutines of Acl2 do extensive syntactic checking on their input and ++explicitly report syntactic errors. But this pretty printer does not do such ++syntactic checking. Rather, we assume the given input is known to be ++syntactically correct, namely as though checked by `LD'. Failure to ++provide input in correct syntactic form can result in nasty, brutish, and ++short Lisp errors. ++ ++ ++ OTHER USER-LEVEL FUNCTIONS ++ ++Besides `infix-file', here are the other user-level functions supported by ++this file. ++ ++(a) (print-examples) creates a stand-alone, file named ++"infix-examples.tex" or "infix-examples.mss", which is a summary of ++the syntax we print in terms of the official Acl2 syntax. This file ++will also correctly report any user modifications made to the syntax ++by invocation of the make... functions described later. We hope that ++users will want to include this file in reports about Acl2 use to ++make clear what syntactic conventions they are using. ++ ++(b) (NQFMT2FMT "foo") copies the file "foo.lisp" to the file ++"foo.tex" or "foo.mss", but along the way, Acl2 terms preceded by an ++exclamation mark and certain alphabetic characters are replaced with ++the formatting commands for the conventional notation this printer ++generates. For example, when in latex mode, if nqfmt2fmt encounters ++!t(gcd x (difference y x)) in a file, it will replace it with ++{\rm{gcd}}\,({\it{x\/}}, {\it{y\/}} $-$ {\it{x\/}}). We find the ++former much easier to read in a file. nqfmt2fmt thus permits one to ++keep Acl2 forms in files to be read and edited by humans, e.g., in ++comments in Acl2 event files. Ordinary uses of !, e.g., uses of it ++followed by white space or punctuation characters, are, of course, ++unaltered. ++ ++Let ev be an Acl2 event form, e.g., (defun foo (x) 3) ++ fm be an Acl2 term, e.g., (plus x y) ++ foo be a symbol ++ ++Summary: ++ ++!Pfm - Pretty print. ++!Tfm - Pretty print but without any line breaks. ++!Eev - Format event. ++!Ifoo - Identity, handling special chars of formatter. ++!Qfn - `fn'. ++!Vfoo - Verbatim. ++ ++Begin HACK ALERT ++ ++!Cform - [C]ommand evaluate. This should really be E for EVAL. ++ The form is evaled in Lisp. This allows you to do things ++ like dynamically change the margin (*rightmost-char-number*) ++ turn indexing on (SETQ *DO-NOT-INDEX* NIL) and off ++ (SETQ *DO-NOT-INDEX* T), or even redefine a printer. ++ ++End HACK ALERT ++ ++!section(text) - Format text as a section header. ++!subsection(text) - Format test as a subsection header. ++ ++!B(text) - bold ++!S(text) - italic ++ ++Detail: ++ ++!Eev - Event. Results in conventional notation for ev. ++ ++!Ifoo - Identity. Results in foo, but with with formatting sensitive ++ characters quoted. ++ ++!Pfm - Pretty print. Results in conventional mathematical notation. ++ ++!Qfn - where fn is a symbol, results in fn surrounded by single gritches, ++ after formatting sensitive characters have been quoted, e.g., !qfoo results ++ in `foo' in TeX. Useful for distinguishing function symbols from other ++ words in a sentence, since function symbols appear in Roman. ++ Mnemonic: Q -- think Quoted. ++ ++!Tfm - where fm is an Acl2 term, results in conventional mathematical ++ notation for fm, but without any line breaks. ++ Mnemonic: T -- think Term. ++ ++!Vfoo - foo is printed as is, but in typewriter font, and with special characters quoted. ++ Mnemonic: V -- think Verbatim. ++ ++! followed by anything else is left alone, along with the exclamation mark. ++ ++See the comment at the beginning of the definition of nqfmt2fmt, below, for ++details on the syntax and replacements. There is also an option to nqfmt2fmt ++for simply stripping out the !commands. ++ ++(c) (infix-form fm) prints (to *standard-output*) the formatting input for the ++conventional notation for the Acl2 term fm. `infix-form' and `infix-event' ++can be used to generate Latex or Scribe to be inserted manually into ++papers, but we recommend the use of nqfmt2fmt, described above, for this ++purpose. ++ ++(d) (infix-event ev) prints (to *standard-output*) the Latex or Scribe for the ++conventional notation for the Acl2 event ev. ++ ++ ++ USER EXTENSION OF SYNTAX ++ ++`infix-file' is table-driven, and it is very easy to extend in certain ways, ++e.g., to introduce a new infix operator. See the very end of this file, at ++`USER MODIFIABLE TABLE SETUP', for examples of how to establish new syntax. ++ ++Also see `SETTINGS THAT MAY BE MODIFIED IN MODE-THEORY.LISP' to see how to ++control additional features of the printing process, e.g. indexing, details of ++comment handling, parentheses around expressions, etc. ++ ++ ++ PARENTHESES and PRECEDENCE ++ ++This pretty-printer does not provide a facility for the suppression of ++parentheses via the declaration of precedence for operators. An objective in ++printing a formula is clarity. We know of very, very few cases (e.g., + and ++*) where precedence is something on which people agree. As a small ++contribution towards the suppression of parentheses , we do drop the outermost ++parentheses of a formula when the formula is an argument of a function that is ++being printed in the usual f(x,y) notation, with subterms separated by ++parentheses and commas. ++ ++In addition, the user has two alternatives to fully parenthesized notation. ++ ++1. Eliminate them at the top level by setting *TOP-PARENS-ELIMINABLE* ++ to T. ++ ++2. Eliminate them except where absolutely required (e.g. around ++ normal, prefix function arguments) by setting ++ *TOP-PARENS-ELIMINABLE-DEFAULT* to T. ++ ++See the section `SETTINGS THAT MAY BE MODIFIED IN MODE-THEORY.LISP'. ++ ++ ++ OTHER FORMATTERS ++ ++There are some functions in this file that take advantage of similarities ++between LaTeX and Scribe. They are marked with `WARNING: Latex/Scribe ++dependency'. If you want to generate input to some other formatter you may ++want to take a look at these. Not guaranteed to be complete. In order to ++built a -init.lisp file for some other formatter make sure you look at ++`SPECIAL VARIABLES THAT MUST BE DEFINED IN MODE-INIT.LISP'. ++ ++ ++ END OF COMMENTS ON USE ++ ++|# ++ ++#| --------------------------------------------------------------------------------- ++ ++ COMPILATION DEPENDENCIES ++|# ++ ++;; Check that we are in a compatible Acl2. ++ ++;(eval-when (load eval compile) ++; (or (boundp 'infix-input-file-type) ++; (error "~%~%infix.lisp is to be compiled and used with acl2 versions 1992 or later,~%~ ++; not stand-alone or with older versions of acl2.~%"))) ++ ++;; Not used. ++ ++; (defun untranslate-event (form) (acl2::untranslate form nil)) ++ ++;; Included from Nqthm. ++ ++(defun our-flatc (x) ++ (cond ((stringp x) (+ 2 (length x))) ++ ((symbolp x) (length (symbol-name x))) ++ ((integerp x) (our-flatc-number x)) ++ (t (let ((*print-base* 10) ++ (*print-pretty* nil) ++ (*print-radix* nil) ++ (*print-level* nil) ++ (*print-length* nil) ++ (*print-case* :upcase)) ++ (length (format nil "~a" x)))))) ++ ++(defun our-flatc-number (n) ++ (cond ((< n 0) (1+ (our-flatc-number (- n)))) ++ ((< n 10) 1) ++ (t (1+ (our-flatc-number (floor (/ n 10))))))) ++ ++(defvar a-very-rare-cons (cons nil nil)) ++ ++ ++#| --------------------------------------------------------------------------------- ++ ++ SETTINGS THAT MAY BE MODIFIED IN MODE-THEORY.LISP. ++ ++Use INFIX-SETTINGS to set this first set of properties. ++See files latex-mode.lisp and scribe-mode.lisp for examples. ++ ++The things you can control with INFIX-SETTINGS are listed below. The first ++choice is the default, so if you are happy with the default you don't need to ++fool with the setting. See examples after the enumeration. These are ++all keyword arguments to INFIX-SETTINGS. ++ ++1. MODE: a string naming the theory we are in. The default is constructed ++ the the name of the events file. If no corresponding -theory file is found, ++ query the user. ++ ++2. EXTENSION: type of output file ("mss", "tex", ...) ++ ++3. OP-LOCATION: ['FRONT, 'BACK] ++ Controls where operator is printed when printing on multiple lines ++ 'FRONT - put operator at beginning of line (Smith's way) ++ 'BACK - put operator at end of line (Boyer's way) ++ ++4. COMMENT-FORMAT: ['SMITH, 'BOYER, 'CL] ++ Chooses from one of the predefined conventions for determining from the character ++ following the comment character how to format the comment. This interacts ++ with your use of native-mode formatting commands in comments in the .events file. ++ ++ For your own control over this, use (DEFINE-COMMENT-FORMAT name format). ++ See the description of comment handling for more information. ++ ++5a. FORMAT-!-IN-COMMENTS: [T, nil] ++ If true, run nqfmt2fmt over comments. ++ ++5b. ACL2-FORMAT-COMMENTS: [T, nil] ++ If true, run the acl2 doc string formatting process over comments. ++ ++5c. ACL2-FORMAT-DOC-STRINGS: [T, nil] ++ If true, run the acl2 doc string formatting process over doc strings. ++ ++6. ELIMINATE-TOP-PARENS: boolean [T, nil] ++ Indicates whether you wish the outermost parentheses of function bodies suppressed. ++ ++7. ELIMINATE-INNER-PARENS: boolean [T, nil] ++ Suppresses all precedence related parentheses. Much cleaner output, though an ++ expression printed with this flag=true may reconstruct oddly, depending on the ++ reader's precedence model. The indentation of large expressions helps somewhat. ++ ++ Example: Consider the defun, ++ (defun foo (l) ++ (and (plistp l) (and (bar l) (baz (cdr l))))) ++ ++ Below is a table showing how the body (the AND) would be printed. ++ ++ TOP INNER Printed output of body of foo ++ t t plistp(l) & bar(l) & baz(cdr(l)) ++ t nil plistp(l) & (bar(l) & baz(cdr(l))) ++ nil t (plistp(l) & bar(l) & baz(cdr(l))) ++ nil nil (plistp(l) & (bar(l) & baz(cdr(l)))) ++ ++8. NO-INDEX: boolean [NIL, t]. If T, then no index is generated. ++ ++9. NO-INDEX-CALLS: boolean [NIL, T] or list ++ If you want all function calls indexed, NIL. you do not want any function use indexed, T. ++ If you want to exclude certain function calls, provide a list of function ++ names to be ignored. ++ ++If you do not provide a keyword value pair, the settings remains unchanged. ++Thus, you really don't have to call this function. Though typically you want ++to change the :mode if you have created a special theory extension on top of ++Scribe or Latex. ++ ++The minimal call on INFIX-SETTINGS requires a mode and extension. ++ ++(INFIX-SETTINGS :MODE "scribe" ++ :EXTENSION "mss" ) ++ ++The maximal call, setting everything explicitly. ++The following shows infix-settings with all of the default settings as ++arguments. The comments indicate required types of values. `...' indicates ++settings that the user may extend with more work. ++ ++(INFIX-SETTINGS :MODE "scribe" ; string ["scribe","latex",...] ++ :EXTENSION "mss" ; string ["mss","tex"] ++ :OP-LOCATION 'FRONT ; ['FRONT,'BACK] ++ :COMMENT-FORMAT 'SMITH ; ['SMITH,'BOYER,'CL,...] ++ :FORMAT-!-IN-COMMENTS NIL ; [t,nil] ++ :ACL2-FORMAT-COMMENTS T ; [t,nil] ++ :ACL2-FORMAT-DOC-STRINGS T ; [t,nil] ++ :ELIMINATE-TOP-PARENS T ; [t,nil] ++ :ELIMINATE-INNER-PARENS T ; [t,nil] ++ :NO-INDEX NIL ; [t,nil] ++ :NO-INDEX-CALLS NIL ; [t,nil,l] ++ ) ++ ++|# ++ ++ ++; Variable controlling handling of special formatting within comments. See `NQFMT2FMT'. ++ ++(defparameter *nq-default* t) ++ ++; If *INFIX-OP-LOCATION* (:OP-LOCATION arg to INFIX-SETTINGS) is 'BACK ++; then you get Boyer's style of printing a list of infix operators and ++; arguments. If 'FRONT, you get Smiths. Smiths is the default. ++; You can tell who last editted this file. ++ ++;- BACK form is e.g ++;- arg1 op foo(a,b,c) & ++;- arg2 op bar(a,1) & ++;- argn some-long-function-name(a,b,1) ++ ++;- FRONT form is e.g ++;- arg1 foo(a,b,c) ++;- op arg2 & bar(a,1) ++;- op argn & some-long-function-name(a,b,1) ++ ++ ++; Either FRONT or BACK. ++(defparameter *infix-op-location* 'front) ++ ++; Extension of input file. ++(defparameter infix-input-file-type "lisp") ++ ++ ++#| ++ SETTINGS THAT MAY BE RESET IN MODE-THEORY.LISP. (2) ++ ++The following variables do not NEED to be reset in your mode file, but they may be. ++ ++|# ++ ++(defparameter *top-parens-eliminable* nil) ++ ++; *TOP-PARENS-ELIMINABLE-DEFAULT* is a global. If t, then it is ALWAYS ++; assumed to be ok to omit the outermost parentheses of the expressions ++; we are about to print. This may procudes output that cannot ++; unambiguously be parsed back into its original sexpr format. ++ ++(defparameter *top-parens-eliminable-default* nil) ++ ++#|\ ++ ++INDEXING ++ ++If you do not any index (SETQ *DO-NOT-INDEX* T). ++If you do not want occurences of functions indexed (SETQ *DO-NOT-INDEX-CALLS* T). ++If you want to exclude certain functions, add them to the list *DO-NOT-INDEX-CALLS-OF*. ++If you want no index, see comments at beginning of file. ++ ++ ++DEBUGGING ++ ++Setting *INFIX-TRACE* to T will provide some debugging help when testing new mode files. ++ ++ ++ END OF SETTINGS FOR MODE-INIT.LISP. ++ ++--------------------------------------------------------------------------------- ++|# ++ ++ ++; --------------------------------------------------------------------------------- ++; ++; SPECIAL VARIABLES THAT MUST BE DEFINED IN MODE-INIT.LISP. ++; ++; Use INFIX-SETTINGS to set this variable. See Introduction. ++ ++; One of NIL, "latex", "scribe", or another string. ++(defparameter *infix-mode* nil) ++ ++ ++;; STRINGS BASED ON THE TARGET FORMATTER (LaTeX, Scribe, ...) ++ ++;; Default extension of created files. ++(defvar *mode-extension* nil) ++ ++(defparameter *standard-prelude* nil) ++(defparameter *standard-postlude* nil) ++ ++(defparameter *example-prelude* nil) ++(defparameter *begin-example-table* nil) ++(defparameter *end-example-table* nil) ++(defparameter *example-table-size* nil) ++(defparameter *example-postlude* nil) ++ ++;; BASIC BRACKETS AND THEIR QUOTED VERSION. ++ ++(defparameter *begin* "") ++(defparameter *end* "") ++(defparameter *lbrace* "") ++(defparameter *rbrace* "") ++ ++;; ENVIRONMENT BEGIN-END PAIRS ++ ++(defparameter *begin-index* "") ++(defparameter *end-index* "") ++ ++(defparameter *begin-text-env* "") ++(defparameter *end-text-env* "") ++ ++(defparameter *begin-verbatim-env* "") ++(defparameter *end-verbatim-env* "") ++ ++(defparameter *begin-format-env* "") ++(defparameter *end-format-env* "") ++ ++(defparameter *begin-emphasis-env* "") ++(defparameter *end-emphasis-env* "") ++ ++(defparameter *begin-comment-env* "") ++(defparameter *end-comment-env* "") ++ ++(defparameter *begin-section-env* "") ++(defparameter *end-section-env* "") ++ ++(defparameter *begin-subsection-env* "") ++(defparameter *end-subsection-env* "") ++ ++(defparameter *begin-tt-env* "") ++(defparameter *end-tt-env* "") ++ ++(defparameter *begin-string-env* "") ++(defparameter *end-string-env* "") ++ ++(defparameter *begin-bold-env* "") ++(defparameter *end-bold-env* "") ++ ++(defparameter *begin-italic-env* "") ++(defparameter *end-italic-env* "") ++ ++(defparameter *begin-sc-env* "") ++(defparameter *end-sc-env* "") ++ ++(defparameter *begin-enumerate-env* "") ++(defparameter *end-enumerate-env* "") ++(defparameter *begin-item* "") ++(defparameter *end-item* "") ++ ++(defparameter *forall* "") ++(defparameter *exists* "") ++ ++;; TABBING AND INDENTING ENVIRONMENT AND TAB OPERATIONS ++ ++(defparameter *begin-tabbing-env* nil) ++(defparameter *end-tabbing-env* nil) ++(defparameter *new-tab-row* nil) ++ ++;; Needs to be redefined in <mode>-init.lisp ++;; No longer used. A LIE! ++(defmacro new-tab-row (&optional followed-by-infix-print-term) ++ (declare (ignore followed-by-infix-print-term)) ++ '(pprinc *new-tab-row*)) ++ ++(defparameter *tab* nil) ++ ++(defparameter *column-separator* nil) ++ ++; *tabs-list* is a text-formatter specific variable. Typically of the form of a ++; list of pairs, either (tab . n) or (lm . n), where n is the value of ++; *infix-loc* when we set tabs and margins. ++ ++(defparameter *tab-list* nil) ++(defparameter *tab-stack* nil) ++ ++(defparameter *set-margin* nil) ++(defparameter *pop-margin* nil) ++(defparameter *set-tab* nil) ++ ++(defparameter *default-op-tab-space* "") ++ ++(defparameter *adjust-tab-before-margin* nil) ++ ++;; FONTS ++ ++(defparameter *function-font* nil) ++(defparameter *neg-str* nil) ++ ++;; MATH ENV AND OPERATORS ++ ++(defparameter *math-format* nil) ++(defparameter *math-begin* nil) ++(defparameter *math-end* nil) ++ ++(defparameter *math-thick-space* nil) ++(defparameter *math-thin-space* nil) ++ ++(defparameter *subscript* nil) ++ ++(defparameter *begin-subscript* nil) ++(defparameter *end-subscript* nil) ++ ++;; MISC. ++ ++(defparameter *newpage* nil) ++ ++(defparameter *comma-atsign* nil) ++(defparameter *caret* nil) ++ ++(defparameter *dotted-pair-separator* " . ") ++(defparameter *dotted-pair-separator-newline* ". ") ++ ++(defparameter *no-tab-event-trailer* nil) ++(defparameter *print-default-event-header* nil) ++(defparameter *print-default-lisp-header* nil) ++ ++(defparameter *print-default-command-header* nil) ++(defparameter *no-tab-command-trailer* nil) ++ ++ ++;; ACL2 RELATED. ++ ++;; We conditionally apply the ACL2 formatting conventions. ++ ++(defvar *acl2-format-comments* t) ++(defvar *acl2-format-doc-strings* t) ++ ++ ++#|\--------------------------------------------------------------------------------- ++ ++ FUNCTIONS THAT MUST BE DEFINED IN MODE-INIT.LISP. ++ ++Signatures as passed to (proclaim '(ftype ...) ..) ++ ++() -> t : function of no args, returning arbitrary type ++ ++ begin-tabbing end-tabbing ++ begin-normal-text end-normal-text ++ increase-margin ++ set-margin pop-margin ++ get-margin pop-tab ++ do-tab ++ begin-flushright end-flushright ++ ++ ;; to-current-margin ;; newline-to-current-margin ++ ;; force-newline ++ ++(t) -> t : function of one arbitray arg, returning arbitrary type ++ ++ flushright ++ ++ ++(t) -> t : function of one optional arg, returning arbitrary type ++ ++ set-tab ++ ++(character) -> t : function of one character arg, returning arbitrary type ++ ++ handle-special-chars ++ handle-special-chars-in-string ++ char { Why is this in this list? } ++ ++ ++--------------------------------------------------------------------------------- ++ ++ IMPLEMENTATION COMMENTS ++ ++The three `tables' that govern the printing are the variables: ++ ++1. *atom-alist*, which governs printing of variables, numbers, T, F, and NIL. ++ ++2. *fn-alist*, which governs the printing of any term that starts with a ++function symbol, including LET, COND, CASE, LIST, LIST*, and FOR. ++ ++3. *event-printer-alist*, which governs the printing of events. ++ ++4. *special-quoted-forms-alist*, which governs the special printing of selected ++quoted symbols. ++ ++Each table is an alist. Each member of any of these alists is a list (symbol ++fn), where symbol is the car of a form (or in the case of a non-consp form, ++the form itself) which is about to be printed. fn is a Common Lisp function ++of one argument which is called on the form in question to do the printing. ++For each alist, there is a default function that is returned if a symbol is ++not explicitly represented. One such default is the function ++default-fn-printer, which is a good function to study before contemplating ++serious modifications to this file. ++ ++Although adding new members to these alists, and defining corresponding ++special purpose functions, is certainly sensible and easy, there are several ++points to be made. ++ ++1. It is unlikely that there will be any call to edit `*atom-alist*' until ++and unless TRANSLATE is changed. ++ ++2. *fn-alist* can be most easily modified by the use of the macros ++make-infix-op, make-unary-prefix-op, make-unary-suffix-op, ++make-infix-multiple-op, and make-prefix-multiple-op. See the very end of the ++file for many examples of how syntax operators can be easily established. ++ ++We really do assume throughout this code that the input file has passed ++through LD, e.g., we assume that the last test in a `cond' is on T, ++the last test in a case is an `otherwise', and that the third argument to ++`defthm' is something that translate can accept. ++ ++ ++STANDARD OUTPUT USED ++ ++Printing. We do *all* of our printing of formulas to *standard-output*, so we ++call princ and write-char on just one argument, the thing to be printed. ++ ++|# ++ ++; PRINTING ++ ++; The setting of the *left-margin* causes only the stuff within tabbing ++; environments to be moved over. Acl2 event forms that do not use that ++; tabbing environment should be adjusted by other means by the user if desired. ++; *left-margin* may be set before invoking infix-form or infix-event. ++ ++(defparameter *left-margin* 0) ++ ++; *rightmost-char-number* is bound sometimes to alter subsidiary printing ++; operations that more text needs to be printed on the same line after they ++; finish. ++ ++(defparameter *rightmost-char-number* 77) ++ ++; *infix-loc* is a good estimate of how far in from the left margin we ++; currently are, counting as 1 any character, or any symbol not wired in. ++ ++(defparameter *infix-loc* 0) ++ ++; If *testing* is t, then we are not really printing but only counting the ++; characters we would print, trying to see if a line break is necessary. ++ ++(defparameter *testing* nil) ++ ++(defparameter *latex-indent-number-limit* 13) ++ ++; In *tabs-in* we keep track of how deep into tabs we are so that we can punt ++; if necessary. ++ ++(defparameter *tabs-in* 0) ++ ++(defparameter *do-not-use-tabs* nil) ++ ++; We cannot place defparameters for the following three special symbols at this ++; place in the file because their initial values contain `functions' of ++; functions to be defined later. ++ ++(proclaim '(special *atom-alist* *fn-alist*)) ++ ++(defparameter *event-printer-alist* nil) ++ ++(defparameter *index-entry-max* 100) ++ ++(defparameter *negative-constant-table* nil) ++ ++(defparameter *negative-infix-table* nil) ++ ++(defparameter *constant-ops* nil) ++ ++(defparameter *infix-ops* nil) ++ ++(defparameter *infix-multiple-ops* nil) ++ ++(defparameter *prefix-multiple-ops* nil) ++ ++(defparameter *suffix-multiple-ops* nil) ++ ++(defparameter *unary-prefix-ops* nil) ++ ++(defparameter *negative-unary-prefix-table* nil) ++ ++(defparameter *unary-suffix-ops* nil) ++ ++(defparameter *negative-unary-suffix-table* nil) ++ ++(defparameter *unary-abs-ops* nil) ++ ++(defparameter *tracing-advise-break* nil) ++ ++(defparameter *white-space* '(#\Space #\Newline #\Tab #\Page)) ++ ++(defparameter *started-a-verbatim* nil) ++ ++(defparameter *started-a-format* nil) ++ ++(defparameter *reported-tabs* nil) ++ ++; This `secret' function symbol is used to print out integers generated by ++; readins #b, #o, or #x syntax. ++ ++(defparameter *infix-radix* (make-symbol "*infix-radix*")) ++ ++; One should add to this list if any other special forms are hard wired into ++; this printer. ++ ++(defparameter *wired-in-infix-examples* ++ '((if x y z) ++ (cond (test1 value1) (test2 value2) (t value3)) ++ (case x (key1 answer1) (key2 answer2) (otherwise default)) ++; (for x in l when (test x) collect (fn x)) ++ (let ((var1 val1) (var2 val2)) form) ++ (let* ((var1 val1) (var2 val2)) form) ++ (forall (x y) (p x)) ++ (exists (x y) (p x)) ++ (not x))) ++ ++; Severe warning on printing. It is illegal for any function in this ++; file to do any printing except via these four printing macros: ++; pprinc, pprin1, pformat, and pwrite-char. This may be true ++; transitively, e.g., pprinci calls pprinc. ++ ++; This rule is imposed so that the `hack' of printing invisibly (see ++; *testing*) will work. The point is that any printing operation may ++; be called many times! But we do not want to print unless the ++; special *testing* is bound to nil! Key fact: if *testing* is t, we ++; DO NOT print. ++ ++; A very sloppy fudge factor to account for the fact that in \tt mode, ++; characters are fatter. ++ ++(defparameter *tt-size* 1.3) ++ ++(defparameter *do-not-index* nil) ++ ++(defparameter *do-not-index-calls* nil) ++ ++(defparameter *infix-comma* (make-symbol "comma")) ++ ++(defparameter *infix-comma-atsign* (make-symbol "comma-atsign")) ++ ++(defparameter *infix-backquote* (make-symbol "backquote")) ++ ++(defparameter *do-not-index-calls-of* ++ (list *infix-radix* *infix-comma* *infix-comma-atsign* *infix-backquote*)) ++ ++(defvar *user-package* (find-package "user")) ++ ++(eval-when (load compile eval) ++ ++(defmacro pprinc (x) ++ `(or *testing* (let ((*package* *user-package*)) ++ (princ ,x)))) ++ ++(defmacro pprin1 (x) ++ `(or *testing* (let ((*package* *user-package*)) ++ (prin1 ,x)))) ++ ++(defmacro pformat (&rest x) ++ `(or *testing* (let ((*package* *user-package*)) ++ (format ,@x)))) ++ ++(defmacro ppformat (&rest x) ++ `(or *testing* (let ((*package* *user-package*)) ++ (format *standard-output* ,@x)))) ++ ++(defmacro pwrite-char (x) ++ `(or *testing* (write-char ,x))) ++ ++) ++ ++; It is absolutely desireable that any printing done by any function inside this ++; file, within the scope of a tabbing environment, be done with with pprinci, ++; pprin1, or print-atom IF the printing is to contribute `real', i.e., ++; non-formatting, characters to the final output. The optional second argument ++; specifies how many characters are being contributed, with default 1. If ++; *testing* is t, not only do we not want to print, but we want to throw out to ++; advise-break if we have exceeded the *rightmost-char-number*. ++ ++(defvar *newline-in-text* "") ++(defvar *newline-in-env* "") ++ ++(defvar *force-newline-in-text* "") ++(defvar *force-newline-in-env* "") ++ ++(defvar *prev-line-loc* nil) ++ ++(defun line-return () ++ (setq *prev-line-loc* *infix-loc*) ++ (pwrite-char #\Newline) ++ (setq *infix-loc* (get-margin))) ++ ++(defun newline-in-env (&optional force) ++ (if force (pprinc *force-newline-in-env*) (pprinc *newline-in-env*)) ++ (line-return)) ++ ++(defun newline-in-text (&optional force) ++ (if force (pprinc *force-newline-in-text*) (pprinc *newline-in-text*)) ++ (line-return)) ++ ++(eval-when (load compile eval) ++ ++(defmacro begin-text () `(begin-normal-text)) ++ ++(defmacro end-text () '(end-normal-text)) ++ ++(defun last-line-feed-position (x) ++ (if (stringp x) (position #\linefeed x :from-end t))) ++ ++(defmacro pprinci (x &optional (i 1)) ++ `(let ((x ,x) ++ (i ,i) ++ n) ++ (pprinc x) ++ (setq *prev-line-loc* *infix-loc*) ++ (cond ((setq n (last-line-feed-position x)) ++ (if (> (- (length x) 1) n) ++ (setq *infix-loc* (- (length x) 1 n)) ++ (setq *infix-loc* (get-margin)))) ++ (t (incf *infix-loc* i))) ++ (cond ((and *testing* ++ (> *infix-loc* *rightmost-char-number*)) ++ (throw 'advise-break t))))) ++ ++(defmacro pprin1i (x) ++ `(progn (let ((x ,x)) ++ (pprin1 x) ++ (incf *infix-loc* (our-flatc x))) ++ (cond ((and *testing* ++ (> *infix-loc* *rightmost-char-number*)) ++ (throw 'advise-break t))))) ++ ++) ++ ++(defun newline (&optional force) ++ (cond (*do-not-use-tabs* (pprinci " ")) ++ ((null *tab-stack*) (newline-in-text force)) ++ (t (newline-in-env force)))) ++ ++(defun to-current-margin () ++ (cond ((eql *infix-loc* (get-margin)) nil) ++ (t (newline)))) ++ ++(defun blankline (&optional force) ++ (cond ((and (eql *infix-loc* (get-margin)) ++ (eql *prev-line-loc* *infix-loc*))) ++ ((eql *infix-loc* (get-margin)) (newline force)) ++ (t (newline force) (newline force)))) ++ ++(defvar *default-indent-spaces* 4) ++ ++ ++; SIX GENERAL OPERATOR SCHEMAS ++ ++; The following make-... macros are used to generate functions and entries for ++; the *fn-alist*. See the end of this file for many examples of usage which can ++; be easily extended. ++ ++(defun clean-up (fn) ++ ++; This function is supposed to remove completely all trace of any prior establishment ++; of any syntax for the function symbol fn. ++ ++ (or (symbolp fn) ++ (error (format nil "Illegal function symbol name: ~a." fn))) ++ ;; DELTA !!!! ++ (setf (get fn 'literalform) nil) ++ (sloop for lst in '(*constant-ops* *infix-ops* *unary-prefix-ops* *unary-suffix-ops* *unary-abs-ops*) ++ do (set lst (remove fn (eval lst)))) ++ (sloop for alist in '(*fn-alist* *negative-constant-table* *negative-infix-table* *negative-unary-prefix-table* ++ *negative-unary-suffix-table* *prefix-multiple-ops* ++ *suffix-multiple-ops* ++ *infix-multiple-ops*) ++ do (set alist (sloop for pair in (eval alist) ++ unless (eq fn (car pair)) ++ collect pair)))) ++ ++;; Used to reinitialize during clean-up-everything ++(defparameter *save-fn-alist* nil) ++ ++(defun clean-up-everything () ++ (sloop for alist in '(*fn-alist* *negative-constant-table* ++ *negative-infix-table* ++ *negative-unary-prefix-table* ++ *negative-unary-suffix-table* ++ *prefix-multiple-ops* ++ *suffix-multiple-ops* ++ *infix-multiple-ops*) ++ do (progn ++ (sloop for pair in (eval alist) ++ do (clean-up (car pair))) ++ (set alist nil))) ++ ;; Reinitialize ++ (setq *fn-alist* *save-fn-alist*)) ++ ++(defmacro make-constant-op (name str &optional neg-str) ++ (let ((fn-name (intern (format nil "~s-constant-op-printer" name)))) ++ `(progn ++ (clean-up ',name) ++ (setf (get ',name 'literalform) ,(format nil *math-format* str)) ++ (defun ,fn-name ++ (term) ++ (declare (ignore term)) ++ (pprinci ,(format nil *math-format* str))) ++ (push (list ',name (function ,fn-name)) ++ *fn-alist*) ++ (push ',name *constant-ops*) ++ ,(cond (neg-str `(push (list ',name ',(format nil *math-format* neg-str)) ++ *negative-constant-table*))) ++ ',name))) ++ ++(defmacro make-infix-op (name str &optional neg-str) ++ (let ((fn-name (intern (format nil "~s-infix-op-printer" name)))) ++ `(progn ++ (clean-up ',name) ++ (setf (get ',name 'literalform) ,(format nil *math-format* str)) ++ (defun ,fn-name ++ (term) ++ (default-infix-printer ++ term ++ ,(format nil *math-format* str))) ++ (push (list ',name (function ,fn-name)) ++ *fn-alist*) ++ (push ',name *infix-ops*) ++ ,(cond (neg-str `(push (list ',name ',(format nil *math-format* neg-str)) ++ *negative-infix-table*))) ++ ',name))) ++ ++(defmacro make-infix-multiple-op (name &rest strs) ++ (let ((fn-name (intern (format nil "~s-infix-multiple-op-printer" name)))) ++ `(progn ++ (clean-up ',name) ++ (defun ,fn-name ++ (term) ++ (default-infix-multiple-printer ++ term ++ ',(sloop for str in strs collect ++ (format nil *math-format* str)))) ++ (push (list ',name (function ,fn-name)) ++ *fn-alist*) ++ (push (cons ',name ,(length strs)) *infix-multiple-ops*) ++ ',name))) ++ ++(defmacro make-prefix-multiple-op (name &rest strs) ++ (let ((fn-name (intern (format nil "~s-prefix-multiple-op-printer" name)))) ++ `(progn ++ (clean-up ',name) ++ (defun ,fn-name ++ (term) ++ (default-prefix-multiple-printer ++ term ++ ',(sloop for str in strs collect ++ (format nil *math-format* str)))) ++ (push (list ',name (function ,fn-name)) ++ *fn-alist*) ++ (push (cons ',name ,(length strs)) *prefix-multiple-ops*) ++ ',name))) ++ ++(defmacro make-suffix-multiple-op (name &rest strs) ++ (let ((fn-name (intern (format nil "~s-prefix-multiple-op-printer" name)))) ++ `(progn ++ (clean-up ',name) ++ (defun ,fn-name ++ (term) ++ (default-suffix-multiple-printer ++ term ++ ',(sloop for str in strs collect ++ (format nil *math-format* str)))) ++ (push (list ',name (function ,fn-name)) ++ *fn-alist*) ++ (push (cons ',name ,(length strs)) *suffix-multiple-ops*) ++ ',name))) ++ ++(defmacro make-unary-prefix-op (name str &optional neg-str) ++ (let ((fn-name (intern (format nil "~s-unary-prefix-op-printer" name)))) ++ `(progn ++ (clean-up ',name) ++ (defun ,fn-name ++ (term) ++ (default-unary-prefix-printer ++ term ++ ,(format nil *math-format* str))) ++ (push (list ',name (function ,fn-name)) ++ *fn-alist*) ++ (push ',name *unary-prefix-ops*) ++ ,(cond (neg-str `(push (list ',name ',(format nil *math-format* neg-str)) ++ *negative-unary-prefix-table*))) ++ ',name))) ++ ++(defmacro make-unary-suffix-op (name str &optional neg-str) ++ (let ((fn-name (intern (format nil "~s-unary-suffix-op-printer" name)))) ++ `(progn ++ (clean-up ',name) ++ (defun ,fn-name ++ (term) ++ (default-unary-suffix-printer ++ term ++ ,(format nil *math-format* str))) ++ (push (list ',name (function ,fn-name)) ++ *fn-alist*) ++ (push ',name *unary-suffix-ops*) ++ ,(cond (neg-str `(push (list ',name ',(format nil *math-format* neg-str)) ++ *negative-unary-suffix-table*))) ++ ',name))) ++ ++(defmacro make-unary-abs-op (name lhs-str rhs-str) ++ (let ((fn-name (intern (format nil "~s-unary-abs-op-printer" name)))) ++ `(progn ++ (clean-up ',name) ++ (defun ,fn-name ++ (term) ++ (default-unary-abs-printer ++ term ++ ,(concatenate 'string *math-begin* lhs-str) ++ ,(concatenate 'string rhs-str *math-end*))) ++ (push (list ',name (function ,fn-name)) ++ *fn-alist*) ++ (push ',name *unary-abs-ops*) ++ ',name))) ++ ++(defmacro declare-atom-printer (x v) ++ `(let ((temp (assoc ',x *atom-alist*))) ++ (if (null temp) ++ (setq *atom-alist* (cons (list ',x ,v) *atom-alist*)) ++ (rplacd temp (list ,v))))) ++ ++(defmacro declare-fn-printer (x v) ++ `(let ((temp (assoc ',x *fn-alist*))) ++ (if (null temp) ++ (setq *fn-alist* (cons (list ',x ,v) *fn-alist*)) ++ (rplacd temp (list ,v))))) ++ ++(defmacro declare-event-printer (x v) ++ `(let ((temp (assoc ',x *event-printer-alist*))) ++ (if (null temp) ++ (setq *event-printer-alist* (cons (list ',x ,v) *event-printer-alist*)) ++ (rplacd temp (list ,v))))) ++ ++(defmacro declare-command-printer (x v) ++ `(let ((temp (assoc ',x *event-printer-alist*))) ++ (if (null temp) ++ (setq *event-printer-alist* (cons (list ',x ,v) *event-printer-alist*)) ++ (rplacd temp (list ,v))))) ++ ++(defmacro def-atom-printer (x args body) ++ (let ((printer (intern (concatenate 'string (symbol-pname x) "-atom-printer")))) ++ `(let ((temp (assoc ',x *atom-alist*))) ++ (defun ,printer ,args ,body) ++ (if (null temp) ++ (setq *atom-alist* (cons (list ',x (function ,printer)) *atom-alist*)) ++ (rplacd temp (list (function ,printer))))))) ++ ++(defmacro def-fn-printer (x args body) ++ (let ((printer (intern (concatenate 'string (symbol-pname x) "-fn-printer")))) ++ `(let ((temp (assoc ',x *fn-alist*))) ++ (defun ,printer ,args ,body) ++ (if (null temp) ++ (setq *fn-alist* (cons (list ',x (function ,printer)) *fn-alist*)) ++ (rplacd temp (list (function ,printer))))))) ++ ++(defmacro def-event-printer (x args body) ++ (let ((printer (intern (concatenate 'string (symbol-pname x) "-event-printer")))) ++ `(let ((temp (assoc ',x *event-printer-alist*))) ++ (defun ,printer ,args ,body) ++ (if (null temp) ++ (setq *event-printer-alist* ++ (cons (list ',x (function ,printer)) *event-printer-alist*)) ++ (rplacd temp (list (function ,printer))))))) ++ ++ ++; TABBING ++ ++; Infix-File generates text that uses the Latex `tabbing' or Scribe `format' environment, ++; setting a tab for each new level of indentation. We find this a convenient ++; sublanguage to target. ++ ++; It appears based upon various experiment that perhaps Latex cannot handle tabs ++; more than about 14 deep, or so. ++ ++; The parameter, *latex-indent-number-limit*, could perhaps be increased if one ++; had a Latex wherein this limit has been raised. However, it is a relatively rare ++; function that needs terms that are more than 13 function calls deep. When ++; infix-file hits this limit in Latex mode, it falls back upon the standard Acl2 ++; pretty-printer, and puts the result in a verbatim environment. ++ ++;; All of the following should be defined in the text-formatting init file, ++;; e.g., latex-init.lisp or scribe-init.lisp. ++ ++(proclaim '(ftype (function nil t) ++ begin-tabbing ;enter a tabbing environment ++ begin-group-tabbing ;enter a tabbing environment, no page breaks ++ end-tabbing ;exit tabbing env ++ begin-normal-text ; ++ end-normal-text ++ increase-margin ;increment left margin by a fixed amount ++ set-margin ;set margin to current line location ++ pop-margin ;pop to previous margin ++ get-margin ;value ++ set-tab ;set at tab at current line location ++ pop-tab ;remove a tab ++ do-tab ;tab to next tab ++ begin-flushright ++ end-flushright ++ ;; to-current-margin ++ ;; newline-to-current-margin ; ++ ;; force-newline ++ )) ++ ++(proclaim '(ftype (function (t) t) ++ flushright)) ++ ++(proclaim '(ftype (function (&optional t) t) ++ set-tab)) ++ ++(proclaim '(ftype (function (character) t) ++ handle-special-chars ++ handle-special-chars-in-string char)) ++ ++ ++; PRINT-ATOM ++ ++; We want to slashify special characters in the following three lists in ++; case they appear in an Acl2 symbol. Used only by print-atom and index. ++ ++(defparameter doc-special-chars nil) ++(defparameter doc-other-chars nil) ++(defparameter doc-index-specials nil) ++ ++; We also to handle the characters in doc-other-chars specially, by going into ++; math mode, since slashification with backslash does not work. ++ ++(defun print-string (str &optional i) ++ ++; Our own printer, which slashifies (or otherwise quotes) the doc-special-chars and ++; doc-other-chars in strings. We print all Acl2 symbols with this ++; function and print-atom because we want to avoid generating stuff that will make ++; the text formatter barf, e.g., in Latex, a symbol with an unslashified $, <, or { in it. ++ ++ (cond ((stringp str) ++ (sloop for j below (length (the string str)) ++ for char = (char (the string str) (the fixnum j)) ++ do (handle-special-chars-in-string char) ++ finally (incf *infix-loc* (or i (length str))))) ++ ((symbolp str) ++ (print-atom str i)) ++ ((characterp str) (print-character str i)) ++ (t (pprin1i str))) ++ (cond ((and *testing* ++ (> *infix-loc* *rightmost-char-number*)) ++ (throw 'advise-break t)))) ++ ++(defun print-atom (atm &optional i) ++ ++; Our own atom printer, which slashifies (or otherwise quotes) the doc-special-chars and ++; doc-other-chars in symbols and strings. We print all Acl2 symbols with this ++; function because we want to avoid generating stuff that will make the text formatter barf, ++; e.g., in Latex, a symbol with an unslashified $, <, or { in it. ++; If i is present is is meant to be the actual printed width of the formatted output, e.g. ++; stripped of formatting commands. ++ ++ (cond ((symbolp atm) ++ (if (keywordp atm) ++ (pprinc ":")) ++ (sloop with str = (symbol-name atm) ++ for j below (length (symbol-name (the symbol atm))) ++ for char = (char (the string str) (the fixnum j)) ++ do (handle-special-chars char) ++ finally (incf *infix-loc* (or i (length str))))) ++ ((stringp atm) ++ (incf *infix-loc* (or i (+ 4 (* 2 (length atm))))) ++ (pprinc *begin-string-env*) ;was *begin-tt-env* ++ (pprinc "\"") ++ (sloop for i below (length atm) ++ for char = (char (the string atm) (the fixnum i)) ++ do (handle-special-chars-in-string char)) ++ (pprinc "\"") ++ (pprinc *end-string-env*)) ++ (t (pprin1i atm))) ++ (cond ((and *testing* ++ (> *infix-loc* *rightmost-char-number*)) ++ (throw 'advise-break t)))) ++ ++(defun print-character (c &optional i) ++ ++; Our own character printer, quotes the doc-special-chars and ++; doc-other-chars used to print characters. We print all Acl2 characters with this ++; function because we want to avoid generating stuff that will make the text formatter barf, ++; e.g., in Latex, a symbol with an unslashified $, <, or { in it. ++; If i is present is is meant to be the actual printed width of the formatted output, e.g. ++; stripped of formatting commands. ++ ++ (handle-special-chars #\#) ++ (handle-special-chars #\\) ++ (handle-special-chars c) ++ (incf *infix-loc* (or i 3)) ++ (cond ((and *testing* ++ (> *infix-loc* *rightmost-char-number*)) ++ (throw 'advise-break t)))) ++ ++(defun print-atoms (l) ++ (cond ((cdr l) ++ (sloop for x on l ++ do (cond ((cddr x) ++ (print-atom (car x)) ++ (pprinc ", ")) ++ ((cdr x) ++ (print-atom (car x)) ++ (pprinc " and ")) ++ (t (print-atom (car x)))))) ++ (t (print-atom (car l))))) ++ ++(defun print-bare-function-name (term) ++ (pprinc "`") ++ (print-atom term) ++ (pprinc "'")) ++ ++(defun print-bare-function-names (l) ++ (cond ((cdr l) ++ (sloop for x on l ++ do (cond ((cddr x) ++ (print-bare-function-name (car x)) ++ (pprinc ", ")) ++ ((cdr x) ++ (print-bare-function-name (car x)) ++ (pprinc " and ")) ++ (t (print-bare-function-name (car x)))))) ++ (t (print-bare-function-name (car l))))) ++ ++ ++; FONT SYMBOL PRINTERS ++ ++(defun bold-sym-printer (x &optional i) ; Print in bold face. ++ (pprinc *begin-bold-env*) ++ (cond ((symbolp x) (print-atom x i)) ++ ((characterp x) (print-character x i)) ++ (t (print-string x i))) ++ (pprinc *end-bold-env*)) ++ ++(defun italic-sym-printer (x &optional i) ; Print in italic face. ++ (pprinc *begin-italic-env*) ++ (cond ((symbolp x) (print-atom x i)) ++ ((characterp x) (print-character x i)) ++ (t (print-string x i))) ++ (pprinc *end-italic-env*)) ++ ++(defun tt-sym-printer (x &optional i) ; Print in typewriter font. ++ (pprinc *begin-tt-env*) ++ (cond ((symbolp x) (print-atom x i)) ++ ((characterp x) (print-character x i)) ++ (t (print-string x i))) ++ ;; We charge more for tt characters. ++ (incf *infix-loc* (* (- *tt-size* 1) (our-flatc x))) ++ (pprinc *end-tt-env*)) ++ ++(defun small-caps-sym-printer (x &optional i) ; Print in small caps. ++ (pprinc *begin-sc-env*) ++ (cond ((symbolp x) (print-atom x i)) ++ ((characterp x) (print-character x i)) ++ (t (print-string x i))) ++ (pprinc *end-sc-env*)) ++ ++(defun font-sym-printer (symbol font) ++ (case font ++ (bold (bold-sym-printer symbol)) ++ (italic (italic-sym-printer symbol)) ++ (tt (tt-sym-printer symbol)) ++ (sc (small-caps-sym-printer symbol)) ++ (otherwise (format *terminal-io* "Bad font descriptor (~a) passed to subscript printer.~%" font) ++ (tt-sym-printer symbol)))) ++ ++(defun subscript (x) ++ (pprinc *begin-subscript*) ++ (print-atom x) ++ (pprinc *end-subscript*)) ++ ++; *ATOM-ALIST* ++ ++; *atom-alist* is one of the three tables off of which this printer is driven. ++; It determines how a variable symbol is printed. It is unlikely that anyone ++; would want to change this unless translate changes because t, f, and nil are ++; the only symbols that translate treats specially as constants instead of as ++; variable symbols. ++ ++; We would like to put this at the beginning of the file but cannot, so we put ++; a special declaration up there. ++ ++(defparameter *atom-alist* ++ (list (list 't (function bold-sym-printer)) ++ (list 'f (function bold-sym-printer)) ++ (list 'nil (function bold-sym-printer)))) ++ ++(defun default-atom-printer (var) ++ ++; We put variables in italics, strings in typewriter. ++ ++ (cond ((keywordp var) (print-atom var)) ++ ((symbolp var) (italic-sym-printer var)) ++ ((stringp var) (print-atom var)) ++ ((numberp var) (tt-sym-printer var)) ++ ((characterp var) (print-character var)) ++ (t (pprin1 var)))) ++ ++(defun get-atom-printer (sym) ++ (let ((a (assoc sym *atom-alist*))) ++ (cond (a (cadr a)) ++ (t (function default-atom-printer))))) ++ ++ ++; QUOTE ++ ++; The printing of quote terms is intrinsically intertwined with the printing of ++; backquoted terms. The backquoted terms have been read with our ++; special-to-infix-file backquote reader. ++ ++(defun quote-printer1 (term) ++ ++; How we output a quoted term. ++ ++ (cond ((stringp term) (print-atom term)) ++ ((atom term) ++ (tt-sym-printer term)) ++ ((eq (car term) 'quote) ++ (quote-printer term)) ++ ((eq (car term) *infix-comma*) ++ (comma-printer term)) ++ ((eq (car term) *infix-comma-atsign*) ++ (comma-atsign-printer term)) ++ ((eq (car term) *infix-backquote*) ++ (backquote-printer term)) ++ ((eq (car term) *infix-radix*) ++ (funcall (function *infix-radix*-printer) term)) ++ ((advise-break (list 'quote term)) ++ (quote-printer1-advise-break term)) ++ (t (quote-printer1-tt-form term)))) ++ ++(defun tt-pprinci (term &optional (size 1)) ++ (pprinci *begin-tt-env* size) ++ (pprinci term size) ++ (pprinci *end-tt-env*)) ++ ++(defun quote-printer1-tt-form (term) ++ (tt-pprinci "(" *tt-size*) ++ (sloop for tail on term do ++ (progn (quote-printer1 (car tail)) ++ (cond ((null (cdr tail)) (tt-pprinci ")" *tt-size*)) ++ ((or (atom (cdr tail)) ++ (eq (car (cdr tail)) *infix-comma*) ++ (eq (car (cdr tail)) *infix-comma-atsign*) ++ (eq (car (cdr tail)) *infix-backquote*)) ++ (tt-pprinci *dotted-pair-separator* 4) ++ (quote-printer1 (cdr tail)) ++ (tt-pprinci ")" *tt-size*) ++ (line-return)) ++ (t (tt-pprinci " " *tt-size*)))) ++ until (atom (cdr tail)))) ++ ++(defun quote-printer1-advise-break (term) ++ (tt-pprinci "(" *tt-size*) ++ (set-margin) ++ ;; (let ((*left-margin-tab-context* nil)) ) ++ (sloop for tail on term ++ do (progn (quote-printer1 (car tail)) ++ (cond ((null (cdr tail)) ++ (tt-pprinci ")" *tt-size*)) ++ ((or (atom (cdr tail)) ++ (eq (car (cdr tail)) *infix-comma*) ++ (eq (car (cdr tail)) *infix-comma-atsign*) ++ (eq (car (cdr tail)) *infix-backquote*)) ++ (to-current-margin) ;newline ++ (tt-pprinci *dotted-pair-separator-newline* 4) ++ (quote-printer1 (cdr tail)) ++ (tt-pprinci ")" *tt-size*) ++ (return nil)) ++ ((and (or (atom (car tail)) (eq *infix-radix* (car (car tail)))) ++ (cdr tail) ++ (or (atom (cadr tail)) (eq *infix-radix* (car (cadr tail)))) ++ (not (advise-break (list 'quote (cadr tail))))) ++ (tt-pprinci " " *tt-size*)) ++ (t (to-current-margin)))) ;newline ++ until (atom (cdr tail))) ++ (pop-margin)) ++ ++(defun pending-printer (term) ++ (declare (ignore term)) ++ (italic-sym-printer "pending")) ++ ++(defvar *special-quoted-forms-alist* ++ (list (cons 'pending (function pending-printer)))) ++ ++(defun quote-printer (term) ++ (let ((fun (cdr (assoc (cadr term) *special-quoted-forms-alist*)))) ++ (if fun ++ (funcall fun (list (cadr term))) ++ (progn (tt-pprinci "'" *tt-size*) ++ (quote-printer1 (cadr term)))))) ++ ++(defun backquote-printer (term) ++ (tt-pprinci "`" *tt-size*) ++ (quote-printer1 (cadr term))) ++ ++(defun comma-printer (term) ++ (tt-pprinci "," *tt-size*) ++ (quote-printer1 (cadr term))) ++ ++(defun comma-atsign-printer (term) ++ (tt-pprinci *comma-atsign* 4) ++ (quote-printer1 (cadr term))) ++ ++ ++;; NEED to have read, read in the user package, where all of our ++;; variables are compiled!. So use readx. ++ ++(defun readx (str a b c) ++ (let ((*package* *user-package*)) ++ (let ((val (read str a b c))) ++ (if (acl2-keywordp val) ++ (read-keyword-command val) ++ val)))) ++ ++(defun read-from-stringx (str) ++ (let ((*package* *user-package*)) ++ (read-from-string str))) ++ ++ ++; We arrange to read #b, #o, and #x syntax preserving what was read and to ++; print it in the conventional notation whereby #o10 comes out as ++ ++; 10 ++; 8 ++ ++; We do this by having READ fake numbers into the parse tree looking like ++; function calls of the function whose name is the uninterned symbol that is ++; the value of *infix-radix*, and by supplying a printer for this symbol. ++ ++; The 6 read macros for this syntax: ++ ++(defun smash-infix-readtable () ++ (sloop for c in '(#\B #\b #\O #\o #\X #\x) ++ as n in '(2 2 8 8 16 16) ++ for l = (case n ++ (2 '(#\0 #\1)) ++ (8 '(#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7)) ++ (16 '(#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9 ++ #\A #\B #\C #\D #\E #\F ++ #\a #\b #\c #\d #\e #\f))) ++ do ++ (set-dispatch-macro-character ++ #\# ++ c ++ (let ((l l) ++ (nn n) ++ (arithmetic-signs '(#\+ #\- #\/))) ++ (function (lambda (stream char n) ++ (declare (ignore char n)) ++ (list* *infix-radix* nn ++ (sloop for ch = (read-char stream) ++ with ll = nil ++ do ++ (cond ((or (member ch l) ++ (member ch arithmetic-signs)) ++ (push ch ll)) ++ (t (unread-char ch stream) ++ (return (nreverse ll))))))))))) ++ ++; Also setup the backquote reader. ++ ++ (set-macro-character #\` ++ #'(lambda (stream char) ++ (declare (ignore char)) ++ (list *infix-backquote* (readx stream t nil t)))) ++ (set-macro-character #\, ++ #'(lambda (stream char) ++ (declare (ignore char)) ++ (case (peek-char nil stream t nil t) ++ ((#\@ #\.) ++ (read-char stream) ++ (list *infix-comma-atsign* (readx stream t nil t))) ++ (t (list *infix-comma* (readx stream t nil t))))))) ++ ++(defun *infix-radix*-printer (term) ++ (pprinc *math-begin*) ++ (pprinc *begin-tt-env*) ++ (sloop for ch in (cddr term) do (pprinc ch)) ++ (pprinc *end*) ++ (pprinc *subscript*) ; "}_{" ++ (pprinc *begin*) ++ (pprin1i (cadr term)) ++ (pprinc *end-tt-env*) ++ (pprinc *math-end*)) ++ ++(defun subscript-printer (symbol subscript &optional (font 'tt)) ++ ;; Font must be one of bold, italic, tt, sc (small caps) ++ (pprinc *math-begin*) ++ (font-sym-printer symbol font) ++ (pprinc *subscript*) ; "_" in latex ++ (pprinc *begin*) ++ (font-sym-printer subscript font) ++ (pprinc *end*) ++ (pprinc *math-end*)) ++ ++;; FROM NQTHM ++ ++(eval-when (load compile eval) ++ ++(defmacro match (term pattern) (match-macro term pattern)) ++ ++(defun match-macro (term pat) ++ (cond ((atom term) ++ (match1-macro term pat)) ++ (t (let ((sym (gensym "match"))) ++ `(let ((,sym ,term)) ++ ,(match1-macro sym pat)))))) ++ ++(defvar setq-lst nil) ++(defvar test-lst nil) ++ ++(defun match1-macro (term pat) ++ (let (test-lst setq-lst) ++ (match2-macro term pat) ++ (list (quote cond) ++ (cons ++ (cond ((null test-lst) t) ++ ((null (cdr test-lst)) (car test-lst)) ++ (t (cons (quote and) test-lst))) ++ (nconc setq-lst (list t)))))) ++ ++(defun match2-macro (term pat) ++ (cond ((atom pat) ++ (cond ((eq pat (quote &)) nil) ++ ((or (eq pat t) (eq pat nil)) ++ (error "attempt to smash t or nil.")) ++ ((symbolp pat) ++ (setq setq-lst (nconc setq-lst (list (list (quote setq) pat term))))) ++ (t (setq test-lst ++ (nconc test-lst (list (list (quote equal) pat term))))))) ++ ((eq (quote cons) (car pat)) ++ (setq test-lst (nconc test-lst (list (list (quote consp) term)))) ++ (match2-macro (list (quote car) term) (cadr pat)) ++ (match2-macro (list (quote cdr) term) (caddr pat))) ++ ((eq (quote quote) (car pat)) ++ (cond ((symbolp (cadr pat)) ++ (setq test-lst ++ (nconc test-lst ++ (list (list (quote eq) ++ (list (quote quote) (cadr pat)) term))))) ++ (t (setq test-lst (nconc test-lst ++ (list (list (quote equal) ++ (list (quote quote) (cadr pat)) ++ term))))))) ++ (t (cond ((not (eq (quote list) (car pat))) ++ (setq pat (cons (quote list) ++ (cons (list (quote quote) (car pat)) ++ (cdr pat)))))) ++ (sloop for subpat in (cdr pat) do ++ (progn (setq test-lst ++ (nconc test-lst (list (list (quote consp) term)))) ++ (match2-macro (list (quote car) term) subpat) ++ (setq term (list (quote cdr) term)))) ++ (setq test-lst (nconc test-lst (list (list (quote eq) term nil))))))) ++ ++) ++ ++;; END NQTHM importation ++ ++ ++; A FEW HAND-CODED FORM PRINTERS: IF, COND, CASE, LET, FOR, FORALL and EXISTS. ++ ++(defun math-space (&optional (n 1)) ++ (cond (*do-not-use-tabs* (setq n 1))) ++ (pprinc *math-begin*) ++ (sloop for i from 1 to n do ++ (pprinci *math-thick-space*)) ++ (pprinc *math-end*)) ++ ++(defun math-thin-space (&optional (n 1)) ++ (cond (*do-not-use-tabs* (setq n 1))) ++ (pprinc *math-begin*) ++ (sloop for i from 1 to n do ++ (pprinci *math-thin-space*)) ++ (pprinc *math-end*)) ++ ++(defun condify (term) ++ (let (x u v) ++ (sloop with pairs ++ while (match term (if x u v)) ++ do (progn (push (list x u) pairs) ; ??? I put the push and setq into a PROGN ??? ++ (setq term v)) ++ finally ++ (progn (push (list t term) pairs) ++ (return (cons 'cond (reverse pairs))))))) ++ ++(defun if-printer (term) ++ (cond ((null (cddr term)) ++ (format *terminal-io* "~%Ill formed if-expression - ~a~%" term) ++ (cond-printer (condify (append term '(nil nil))))) ++ ((null (cdddr term)) ++ (format *terminal-io* "~%Ill formed if-expression - ~a~%" term) ++ (cond-printer (condify (append term '(nil))))) ++ (t (cond-printer (condify term))))) ++ ++; We take the attitude that we can print an untranslated term t as we would ++; print an untranslated term t' provided that t and t' translate to the same ++; term. This point of view is to be found expressed in our treatment of nested ++; if's as though they were conds. ++ ++(defun cond-printer (term) ++ (let (some-line-broken) ++ (advise-break-if-testing) ++ (let ((*top-parens-eliminable* t)) ++ (cond ((null (cddr term)) ++ (infix-print-term1 (cadr (cadr term)))) ++ (t (let ((cases (cdr term)) ++ (first-case (car (cdr term)))) ++ (set-margin) ++ ;; (let ((*left-margin-tab-context* nil)) ) ++ (bold-sym-printer "if " 3) ++ (infix-print-term1 (car first-case)) ++ ;; then ++ (cond ((let ((*rightmost-char-number* (- *rightmost-char-number* 7))) ++ (advise-break (cadr first-case))) ++ (setq some-line-broken t) ++ (to-current-margin)) ;newline- ++ (t (math-space 1))) ++ (bold-sym-printer " then " 5) ++ (infix-print-term1 (cadr first-case)) ++ ;; else ++ (cond ((let ((*rightmost-char-number* (- *rightmost-char-number* 7))) ++ (advise-break (cons 'cond (cdr cases)))) ++ (setq some-line-broken t) ++ (to-current-margin)) ;newline- ++ (t (math-space 1))) ++ ;; ++ (sloop for tail on (cdr cases) do ++ (cond ((null (cdr tail)) ++ (bold-sym-printer " else " 5) ++ (let ((*rightmost-char-number* (- *rightmost-char-number* 6))) ++ (infix-print-term1 (cadr (car tail)))) ++ ;; TESTING. Inserted (math-space 1) and deleted the following ++ ;; Swithced back, using to-current-margin. ++ (if some-line-broken ++ (to-current-margin) ++ (math-space 1)) ++ (bold-sym-printer "fi" 3) ++ (pop-margin)) ++ (t (bold-sym-printer " elseif " 7) ++ (infix-print-term1 (caar tail)) ++ (cond ((let ((*rightmost-char-number* ++ (- *rightmost-char-number* 7))) ++ (advise-break (cadar tail))) ++ (setq some-line-broken t) ++ (to-current-margin)) ;newline ++ (t (math-space 1))) ++ (bold-sym-printer " then " 5) ++ (infix-print-term1 (cadar tail)) ++ (to-current-margin)))))))))) ;newline ++ ++(defun print-one-case (case term) ++ (let ((break (advise-break term))) ++ (bold-sym-printer " case = " 7) ++ ;; Was (infix-print-term1 case) ++ (quote-printer1 case) ++ (bold-sym-printer " then " 5) ++ (if break ++ (progn (to-current-margin) (math-space 5) (set-margin)) ;newline ++ (math-space 1)) ++ (infix-print-term1 term) ++ (if break (pop-margin)) ++ (to-current-margin))) ;newline ++ ++(defun case-printer (term) ++ (advise-break-if-testing) ++ (let ((*top-parens-eliminable* t)) ++ (cond ((null (cdddr term)) ++ (infix-print-term1 (cadr (caddr term)))) ++ (t (let ((cases (cddr term)) ++ (first-case (car (cddr term)))) ++ (set-margin) ++ ;; (let ((*left-margin-tab-context* nil)) ... ) ++ (bold-sym-printer "case on " 9) ++ (infix-print-term1 (cadr term)) ++ (pprinci ":") ++ (to-current-margin) ;newline ++ (pprinci " " 2) ++ (set-margin) ++ (print-one-case (car first-case) (cadr first-case)) ++ (sloop for tail on (cdr cases) do ++ (cond ((null (cdr tail)) ++ (bold-sym-printer " otherwise " 10) ++ (infix-print-term1 (cadr (car tail))) ++ (to-current-margin) ++ ;; (math-space 1) ++ ;; Was imbedded in ++ ;; (let((*rightmost-char-number* (- *rightmost-char-number* 8))) ++ ;; <form>) ++ (bold-sym-printer "endcase" 8) ++ (pop-margin)) ++ (t (print-one-case (caar tail) (cadar tail))))) ++ (pop-margin)))))) ++ ++(defun let-printer (term) ++ (advise-break-if-testing) ++ (let ((*top-parens-eliminable* t)) ++ (cond ((null (cadr term)) ++ (infix-print-term1 (caddr term))) ++ (t (let ((lets (cadr term))) ++ (set-margin) ++ ;; (let ((*left-margin-tab-context* nil)) .. ) ++ (bold-sym-printer "let " 5) ++ (set-margin) ++ ;; Symbolp lets => lets = NIL. Deleted (infix-print-term1 lets)) ++ (if (consp lets) ++ (sloop for tail on lets ++ for let = (car tail) ++ do (progn (infix-print-term1 (car let)) ++ (bold-sym-printer " be " 3) ++ (infix-print-term1 (cadr let)) ++ (cond ((cdr tail) ++ (pprinci ", " 1) ++ (to-current-margin)) ++ (t (to-current-margin) ++ (bold-sym-printer " in " 3)))))) ++ ;; Deleted (to-current-margin) after printing " in " ++ (pop-margin) ++ (to-current-margin) ++ (let ((*rightmost-char-number* (- *rightmost-char-number* 7))) ++ (infix-print-term1 (caddr term))) ++ (pop-margin)))))) ++ ++(defun let*-printer (term) ++ (advise-break-if-testing) ++ (let ((*top-parens-eliminable* t)) ++ (cond ((null (cadr term)) ++ (infix-print-term1 (caddr term))) ++ (t (let ((lets (cadr term))) ++ (set-margin) ++ ;; (let ((*left-margin-tab-context* nil)) .. ) ++ (bold-sym-printer "let* " 5) ++ (set-margin) ++ (if (consp lets) ++ (sloop for tail on lets ++ for let = (car tail) ++ do (progn (infix-print-term1 (car let)) ++ (bold-sym-printer " be " 3) ++ (infix-print-term1 (cadr let)) ++ (cond ((cdr tail) ++ (pprinci ", " 1) ++ (to-current-margin)) ;newline ++ (t (to-current-margin) ++ (bold-sym-printer " in " 3))) ++ ))) ++ (pop-margin) ++ (to-current-margin) ++ (let ((*rightmost-char-number* (- *rightmost-char-number* 7))) ++ (infix-print-term1 (caddr term))) ++ (pop-margin)))))) ++ ++(defun mv-printer (term) ++ (mv-printer1 (cdr term))) ++ ++(defparameter *mv-bracket-left* "") ++(defparameter *mv-bracket-right* "") ++ ++(defun mv-printer1 (vars) ++ (pprinc *mv-bracket-left*) ++ (sloop for tail on vars do ++ (progn ++ (if (symbolp (car tail)) ++ (funcall (get-atom-printer (car tail)) (car tail)) ++ (infix-print-term1 (car tail))) ++ (if (cdr tail) (pprinci ", " *tt-size*)))) ++ (pprinc *mv-bracket-right*)) ++ ++(defun assign-printer (vars term) ++ (cond ((atom vars) ++ (funcall (get-atom-printer vars) vars)) ++ (t (mv-printer1 vars))) ++ (math-space 1) ++ (pprinc ":=") ++ (math-space 1) ++ (infix-print-term1 term) ++ (pprinc ";")) ++ ++(defun mv-let-printer (term) ++ ;; (mv-let (arg1 ... argn) form form) ++ (advise-break-if-testing) ++ (let ((*top-parens-eliminable* t) ++ (vars (cadr term)) ++ (value (caddr term)) ++ (form (cadddr term))) ++ (set-margin) ++ (assign-printer vars value) ++ ;; newline(to-current-margin) ++ (to-current-margin) ++ (infix-print-term form) ++ (pop-margin))) ++ ++(defun make-alist-pairlist (l) ++ (if (not (consp l)) ++ l ++ (cons (list (caar l) (cdar l)) ++ (make-alist-pairlist (cdr l))))) ++ ++ ++; *FN-ALIST* ++ ++; *fn-alist* is considerably extended via calls to make-... at the end of this ++; file. This initial value given here picks up the very few entries for which ++; we have totally ad hoc handling. Although LIST and LIST* are essentially ++; macros, we handle them by the default-fn-printer, since they evaluate all ++; their arguments. We could have handled IF this default way, too. It was ++; essential that we handle QUOTE, COND, CASE, LET, and FOR specially because ++; they do not evaluate all their arguments but `parse' them to some extent. ++ ++; We would like to put this at the top but have to put it after the functions ++; are defined. ++ ++(defparameter *fn-alist* ++ (list (list 'quote (function quote-printer)) ++ (list *infix-backquote* (function backquote-printer)) ++ (list *infix-radix* (function *infix-radix*-printer)) ++ (list 'if (function if-printer)) ++ (list 'let (function let-printer)) ++ (list 'let* (function let*-printer)) ++ (list 'mv (function mv-printer)) ++ (list 'mv-let (function mv-let-printer)) ++ (list 'cond (function cond-printer)) ++ (list 'case (function case-printer)))) ++ ++(defun default-fn-printer (term) ++ ++; This function is a good function to study if one finds it necessary to define ++; by hand a special handler for a function symbol. We annotate rather ++; verbosely as a pedagogical device. ++ ++; In general, we know that term is a lisp object on which TRANSLATE does not ++; cause an error. ++ ++; Binding *top-parens-eliminable* is a sign to the infix, prefix, and suffix ++; operators immediately below that we are putting out syntactic noise (e.g., ++; commas) that is so strong that they need not emit an initial outer layer of ++; parentheses. ++ ++ (let ((*top-parens-eliminable* t) ++ (advice (advise-break term))) ++ ++ (cond ((atom (car term)) ++ ++; First put out the function symbol, in roman. ++; Functions of no arguments are printed as constants, without parentheses, ++; rather than with, e.g., foo(). ++ ++ (cond ((null (cdr term)) ++ (roman-font (car term)) ++ (return-from default-fn-printer nil))) ++ ++; We want a very tiny space in front of the open parenthesis because otherwise, ++; it looks like some function symbols touch the open parenthesis. In some ++; cases, this results in a touch more space than we like, and perhaps there ++; exists a more delicate kerning command. ++ ++ (roman-font (car term)) ++ (math-thin-space) ++ (pprinci "(")) ++ (t (pprinci "(") ++ (setq term (cons 'foo term)))) ++ (cond ((null (cdr term)) ++ (pprinci ")")) ++ ((null (cddr term)) ++ (infix-print-term1 (cadr term)) ++ (pprinci ")")) ++ ++; The coder of the printer for each function should consider whether to print ++; flat or not, by calling advise-break. This is a somewhat aesthetic and ++; heuristic decision. ++ ++ (advice ++ ++; If it is decided not to print flat, one needs somewhere early to set a tab ++; stop to which to return. ++ ++ (set-margin) ++ ;; (let ((*left-margin-tab-context* nil)) .. ) ++ (sloop for tail on (cdr term) ++ do (progn (infix-print-term1 (car tail)) ++ (cond ((cdr tail) ++ (pprinci ",") ++ ;; Each call of newline-to-current-magin will ++ ;; return to the indent we set. ++ (to-current-margin)) ;newline ++ (t ++ (pprinci ")") ++ ;; Now we get rid of the indent. ++ (pop-margin)))))) ++ (t (sloop for tail on (cdr term) ++ do (progn ++ (cond ((keywordp (car tail)) ++ (infix-print-keyword-value-pair (car tail) (cadr tail)) ++ (setq tail (cdr tail))) ++ (t (infix-print-term1 (car tail)))) ++ (cond ((cdr tail) ++ (pprinci ", ")) ++ (t (pprinci ")"))))))))) ++ ++(defun infix-print-keyword-value-pair (key value) ++ (infix-print-term1 (list 'assign (symbol-name key) value))) ++ ++(defun get-fn-printer (sym) ++ (or (symbolp sym) ++ (error (format nil "Illegal object where function symbol expected : ~a." sym))) ++ (let ((a (assoc sym *fn-alist*))) ++ (cond (a (cadr a)) ++ (t (function default-fn-printer))))) ++ ++(defun defun-call-part-printer (term) ++ (let ((*top-parens-eliminable* t) ++ (advice (advise-break term))) ++ (cond ((atom (car term)) ++ ++; First put out the function symbol, in roman. ++; Functions of no arguments are printed as constants, without parentheses, ++; rather than with, e.g., foo(). ++ ++ (cond ((null (cdr term)) ++ (roman-font (car term)) ++ (return-from defun-call-part-printer nil))) ++ ++; We want a very tiny space in front of the open parenthesis because otherwise, ++; it looks like some function symbols touch the open parenthesis. In some ++; cases, this results in a touch more space than we like, and perhaps there ++; exists a more delicate kerning command. ++ ++ (roman-font (car term)) ++ (math-thin-space) ++ (pprinci "(")) ++ (t (pprinci "(") ++ (setq term (cons 'foo term)))) ++ (cond ((null (cdr term)) ++ (pprinci ")")) ++ ((null (cddr term)) ++ ;; infix-print-arg takes a list of args and prints the first. ++ ;; This allows it to handle &optional. ++ (infix-print-args (cdr term)) ++ (pprinci ")")) ++ ++; The coder of the printer for each function should consider whether to print ++; flat or not, by calling advise-break. This is a somewhat aesthetic and ++; heuristic decision. ++ ++ (advice ++ ++; If it is decided not to print flat, one needs somewhere early to set a tab ++; stop to which to return. ++ ++ (set-margin) ++ (infix-print-args (cdr term) t) ++ (pprinci ")") ++ (pop-margin)) ++ (t (infix-print-args (cdr term)) ++ (pprinci ")"))))) ++ ++ ++; BREAKS ++ ++(defun advise-break (term) ++ ++; advise-break is the only place that *testing* is bound, and here it is bound ++; to t, meaning that we want no printing, just want to know if we can print ++; term flat. We also bind, just to restore, the current *infix-loc* and ++; *tab-list*. ++ ++; This first cond is only for debugging purposes. Same for the second value ++; of the prog1. ++ ++ (cond (*tracing-advise-break* ++ (format *terminal-io* "~%Entering *infix-loc* = ~a, *testing* = ~a~%" *infix-loc* *testing*))) ++ (prog1 ++ (let ((*infix-loc* *infix-loc*) ++ (*tab-list* *tab-list*)) ++ (cond (*testing* nil) ++ (t (catch 'advise-break ++ (let ((*testing* t)) ++ (infix-print-term1 term) ++ nil))))) ++ (cond (*tracing-advise-break* ++ (format *terminal-io* "~%Exiting *infix-loc* = ~a~%" *infix-loc*))))) ++ ++;; Next 3 from Nqthm. ++(defparameter *extra-propertyless-symbols-alist* nil) ++ ++(defun propertyless-symbolp (x) ++ (or (car-cdrp x) ++ (member x (quote (nil quote list let case cond t f ++ list*))) ++ (assoc x *extra-propertyless-symbols-alist*))) ++ ++(defun car-cdrp (x) ++ (let ((str (symbol-name x))) ++ (cond ((and (> (length str) 2) ++ (eql (aref str 0) #\c) ++ (eql (aref str (1- (length str))) #\r) ++ (sloop for i from 1 to (- (length str) 2) ++ always (or (eql (aref str i) #\a) ++ (eql (aref str i) #\d)))) ++ (sloop for i downfrom (- (length str) 2) to 1 collect ++ (aref str i))) ++ (t nil)))) ++ ++(defun advise-break-if-testing () ++ ++; A printer function that is sure that it will break should short circuit the ++; expense of calculating whether printing flat is ok. ++ ++ (cond (*testing* ++ (throw 'advise-break t)))) ++ ++(defun do-not-index-call-of (fn) ++ (or *do-not-index* ++ *do-not-index-calls* ++ (propertyless-symbolp fn) ++ ;; (eq 'ground-zero (get fn 'main-event)) ++ (get fn '*predefined*) ;seems appropriate for Acl2. ++ (member fn *do-not-index-calls-of*))) ++ ++(defun index-call (fn) ++ (cond (*testing* nil) ++ ((do-not-index-call-of fn) nil) ++ (t (index fn)))) ++ ++(defun index-event (fn) ++ (cond (*testing* nil) ++ (*do-not-index* nil) ++ ((do-not-index-event-of fn) nil) ++ (t (index fn)))) ++ ++(defun infix-print-term1 (term) ++ (cond ((atom term) ++ (funcall (get-atom-printer term) term)) ++ ((consp (car term)) ++ (sloop for x in term do (infix-print-term1 x))) ++ ((not (symbolp (car term))) ++ (sloop for x in term do (infix-print-term1 x))) ++ (t (funcall (get-fn-printer (car term)) ++ term) ++ (index-call (car term))))) ++ ++(defun infix-print-term (term) ++ (newline) ++ (infix-print-term1 term) ++ (newline) ++ nil) ++ ++(defun infix-print-list-element-newline (term &optional trailer) ++ ;; TRAILER, if present, must be a string. ++ (infix-print-term1 term) ++ (if trailer (pprinc trailer)) ++ (newline) ++ nil) ++ ++(defun infix-print-list-element (term &optional trailer) ++ ;; TRAILER, if present, must be a string. ++ (infix-print-term1 term) ++ (if trailer (pprinc trailer)) ++ nil) ++ ++(defun infix-print-list1 (l) ++ (set-margin) ++ (sloop for tail on l ++ do (cond ((consp tail) ++ (infix-print-term1 (car tail)) ++ (if (cdr tail) (pprinci ", "))) ++ (t (pprinci " . " (infix-print-term1 tail))))) ++ ;; Now we get rid of the indent. ++ (pop-margin)) ++ ++(defun infix-print-list-a (l &optional printer) ++ (set-margin) ++ (sloop for tail on l ++ do (cond ((consp tail) ++ (if printer ++ (funcall printer (car tail)) ++ (infix-print-term1 (car tail))) ++ (if (cdr tail) (pprinci ", "))) ++ (t (pprinci " . ") ++ (if printer ++ (funcall printer tail) ++ (infix-print-term1 tail))))) ++ ;; Now we get rid of the indent. ++ (pop-margin)) ++ ++(defun infix-print-list (l) ++ (set-margin) ++ (newline) ++ (sloop for tail on l ++ do (cond ((consp tail) ++ ;; Issues newline at end of call. ++ (infix-print-list-element-newline (car tail) (if (cdr tail) ", ")) ++ (cond ((and (cdr tail) (not (consp tail))) ++ (pprinci " . ") ++ (infix-print-list-element-newline (cdr tail)) ++ (loop-return nil)))) ++ ;; Should never get to this. Sloop doesn't deal with ++ ;; non-consp cdrs. ++ (t (pprinci " . ") (infix-print-list-element-newline tail)))) ++ ;; Now we get rid of the indent. ++ (pop-margin)) ++ ++(defun infix-print-l (l &optional printer) ++ (let ((advice (advise-break l))) ++ (if (null printer) ++ (if advice ++ (setq printer (function infix-print-list-element-newline)) ++ (setq printer (function infix-print-list-element)))) ++ (set-margin) ++ (newline) ++ ;; NEED L TO BE A PROPER LIST. ++ (sloop for tail on l ++ do (cond ((consp tail) ++ ;; Issues newline at end of call. ++ (funcall printer (car tail) ++ (if (and (cdr tail) (consp (cdr tail))) ++ ", " ++ nil)) ++ (if (and (cdr tail) (not (consp (cdr tail)))) ++ (progn (pprinci " . ") ++ (funcall printer (cdr tail)) ++ (loop-return nil)))) ++ (t nil))) ++ ;; Now we get rid of the indent. ++ (pop-margin))) ++ ++;; &optional var || &optional (var [literal [varp]]) ++;; &rest v ++;; &key foo bar ++;; &whole l ++;; &body l ++;; &allow-other-keys ++ ++(defvar infix-lambda-list-keywords '(&optional &rest &key &whole &body &allow-other-keys)) ++ ++(defun infix-print-args (l &optional terpri-flag) ++ ;; Whether the args will fit was decided by the caller. ++ ;; If not, terpri-flag is T and we emit a newline between args. ++ ;; Margin is set at current position. ++ (sloop for tail on l ++ do (let ((arg (car tail))) ++ (cond ((not (member arg infix-lambda-list-keywords)) ++ (cond ((symbolp arg) (italic-sym-printer arg)) ++ ((and (consp arg) (equal (length arg) 2)) ++ (italic-sym-printer (car arg)) ++ (math-space 1) ++ (pprinc ":=") ++ (math-space 1) ++ (infix-print-term1 (cadr arg))) ++ ((and (consp arg) (equal (length arg) 3)) ++ (italic-sym-printer (car arg)) ++ (math-space 1) ++ (pprinc ":=") ++ (math-space 1) ++ (infix-print-term1 (cadr arg)) ++ (math-space 1) ++ (pprinc " flag ") ++ (math-space 1) ++ (infix-print-term1 (caddr arg))) ++ (t (format t "Unrecognized argument type ~s" arg))) ++ (if (cdr tail) (pprinci ", "))) ++ (t (small-caps-sym-printer arg) (pprinci " "))) ++ (if terpri-flag (newline)))) ;newline ++ ) ++ ++;; Let set-margin and set-tab know if they are in a context where ++;; we are using a left margin followed by a tab. ++(defparameter *left-margin-tab-context* nil) ++ ++(defun default-infix-printer (term op) ++ (let* ((top-parens-were-eliminable *top-parens-eliminable*) ++ (*top-parens-eliminable* *top-parens-eliminable-default*) ++ (advice (advise-break term))) ++ (cond ((null top-parens-were-eliminable) ++ (pprinci "("))) ++ ++; We hate to see (member x (foo ...)) broken right after the x, where ++; x is an atom. ++ ++ (cond ((and advice ++ (not (and (<= (length term) 3) ++ (atom (cadr term))))) ++ ;; Note that this INFIX printer expects at least two arguments. ++ (cond ((consp op) ++ (if (eq *infix-op-location* 'FRONT) ++ (smith-infix-print-tail "" term top-parens-were-eliminable) ++ (boyer-infix-print-tail "" term top-parens-were-eliminable))) ++ ((eq *infix-op-location* 'FRONT) ++ (smith-infix-print-tail op (cdr term) top-parens-were-eliminable)) ++ (t (boyer-infix-print-tail op (cdr term) top-parens-were-eliminable)))) ++ ++ ((consp op) ++ (if (eq *infix-op-location* 'FRONT) ++ (smith-infix-print-tail "" term top-parens-were-eliminable) ++ (boyer-infix-print-tail "" term top-parens-were-eliminable))) ++ ((= (length term) 2) ++ ;; We have accidentally captured a unary op. Since ++ ;; We assume these will behave like +/-, e.g. if ++ ;; (op x y) prints as "x O y" then (op x) prints as "O x". ++ (pprinci op 3) ++ (pprinci " ") ++ (infix-print-term1 (cadr term)) ++ (if (null top-parens-were-eliminable) (pprinci ")"))) ++ (t ++ (sloop for tail on (cdr term) ++ do ++ (progn (infix-print-term1 (car tail)) ++ (cond ((cdr tail) ++ (pprinci " ") ++ (pprinci op 3) ++ (pprinci " ")) ++ (t (cond ((null top-parens-were-eliminable) ++ (pprinci ")"))))))))))) ++ ++; See `SETTINGS THAT MAY BE MODIFIED IN MODE-THEORY.LISP' for a description ++; of the difference between these two modes of printing. ++ ++(defun boyer-infix-print-tail (op args top-parens-were-eliminable) ++ (set-tab) ++ (sloop for tail on args ++ do ++ (progn (infix-print-term1 (car tail)) ++ (cond ((cdr tail) ++ (newline) (do-tab) ;force-newline ++ (math-space 5) ++ (pprinci op 3) ++ (newline) (do-tab)) ;force-newline ++ (t (cond ((null top-parens-were-eliminable) ++ (pprinci ")"))) ++ (pop-tab)))))) ++ ++(defun smith-infix-print-tail (op args top-parens-were-eliminable) ++ ;; Does this assume we are in a tabbing env? ++ (set-margin) ++ (set-tab op) ++ ;; (let ((*left-margin-tab-context* t)) ... ) ++ (infix-print-term1 (car args)) ++ (sloop for tail on (cdr args) ++ do ++ (progn (to-current-margin) ++ (pprinci op 3) ++ (do-tab) ++ (infix-print-term1 (car tail)) ++ (cond ((cdr tail) ++ (to-current-margin)) ++ (t (cond ((null top-parens-were-eliminable) ++ (pprinci ")"))) ++ (pop-margin) ++ ;; MOD Nov 30 94 MKS ++ ;; (to-current-margin) ;newline ++ ))))) ++ ++ ++(defun default-unary-prefix-printer (term op) ++ (let* ((top-parens-were-eliminable *top-parens-eliminable*) ++ (*top-parens-eliminable* *top-parens-eliminable-default*)) ++ (cond ((null top-parens-were-eliminable) ++ (pprinci "("))) ++ (pprinci op 3) ++ (pprinci " ") ++ (infix-print-term1 (cadr term)) ++ (cond ((null top-parens-were-eliminable) ++ (pprinci ")"))))) ++ ++(defun default-infix-multiple-printer (term strs) ++ (let* ((top-parens-were-eliminable *top-parens-eliminable*) ++ (*top-parens-eliminable* *top-parens-eliminable-default*) ++ (advice (advise-break term))) ++ (cond ((null top-parens-were-eliminable) ++ (pprinci "("))) ++ (if (eq *infix-op-location* 'FRONT) ++ (smith-infix-multiple-printer term strs advice) ++ (boyer-infix-multiple-printer term strs advice)) ++ (cond ((null top-parens-were-eliminable) ++ (pprinci ")"))))) ++ ++(defun boyer-infix-multiple-printer (term strs advice) ++ (set-tab) ++ (infix-print-term1 (cadr term)) ++ (sloop for arg in (cddr term) ++ as str in strs do ++ (cond (advice (newline) (do-tab)) ;force-newline ++ (t (pprinci " "))) ++ (pprinci str) ++ (cond (advice (newline) (do-tab)) ;force-newline ++ (t (pprinci " "))) ++ (infix-print-term1 arg)) ++ (pop-tab)) ++ ++(defun smith-infix-multiple-printer (term strs advice) ++ (set-margin) ++ ;; (let ((*left-margin-tab-context* nil)) .. ) ++ (infix-print-term1 (cadr term)) ++ (sloop for arg in (cddr term) ++ as str in strs ++ do (progn (cond (advice (to-current-margin)) ;newline ++ (t (pprinci " "))) ++ (pprinci str) ++ ;;(cond (advice (newline-to-current-margin)) ++ ;; (t (pprinci " "))) ++ (pprinci " ") ++ (infix-print-term1 arg))) ++ (pop-margin)) ++ ++(defun default-prefix-multiple-printer (term strs) ++ (let* ((top-parens-were-eliminable *top-parens-eliminable*) ++ (*top-parens-eliminable* *top-parens-eliminable-default*) ++ (advice (advise-break term))) ++ (cond ((null top-parens-were-eliminable) ++ (pprinci "("))) ++ (set-margin) ++ ;; (let ((*left-margin-tab-context* nil)) .. ) ++ (sloop for tail on (cdr term) ++ as str in strs ++ do (progn (pprinci str) ++ ;;(cond (advice (newline-to-current-margin)) ++ ;; (t (pprinci " "))) ++ (pprinci " ") ++ (infix-print-term1 (car tail)) ++ (cond ((null tail) nil) ++ (advice (to-current-margin)) ;newline ++ (t (pprinci " "))))) ++ (pop-margin) ++ (cond ((null top-parens-were-eliminable) ++ (pprinci ")"))))) ++ ++(defun default-suffix-multiple-printer (term strs) ++ (let* ((top-parens-were-eliminable *top-parens-eliminable*) ++ (*top-parens-eliminable* *top-parens-eliminable-default*) ++ (advice (advise-break term))) ++ (cond ((null top-parens-were-eliminable) ++ (pprinci "("))) ++ (set-margin) ++ (sloop for tail on (cdr term) ++ as str in strs ++ do (progn (infix-print-term1 (car tail)) ++ ;;(cond (advice (newline-to-current-margin)) ++ ;; (t (pprinci " "))) ++ (pprinci str) ++ (cond ((null (cdr tail))) ++ (advice (to-current-margin)) ;newline ++ (t nil)))) ++ (pop-margin) ++ (cond ((null top-parens-were-eliminable) ++ (pprinci ")"))))) ++ ++(defun default-unary-suffix-printer (term op) ++ (let* ((top-parens-were-eliminable *top-parens-eliminable*) ++ (*top-parens-eliminable* *top-parens-eliminable-default*)) ++ (cond ((null top-parens-were-eliminable) ++ (pprinci "("))) ++ (set-margin) ++ (infix-print-term1 (cadr term)) ++ (pprinci " ") ++ (pprinci op 3) ++ (pop-margin) ++ (cond ((null top-parens-were-eliminable) ++ (pprinci ")"))))) ++ ++(defun default-unary-abs-printer (term lhs-str rhs-str) ++ (let* ((top-parens-were-eliminable *top-parens-eliminable*) ++ (*top-parens-eliminable* *top-parens-eliminable-default*)) ++ (cond ((null top-parens-were-eliminable) ++ (pprinci "("))) ++ (set-margin) ++ (pprinci lhs-str) ++ (infix-print-term1 (cadr term)) ++ (pprinci rhs-str) ++ (pop-margin) ++ (cond ((null top-parens-were-eliminable) ++ (pprinci ")"))))) ++ ++ ++; PRINTING INDEX ENTRIES ++ ++; Who could ever have guessed that it would take this much code to print out a ++; simple \index{foo} command for an arbitrary Acl2 function symbol foo. There ++; are so many special cases one can hardly believe one's eyes. ++ ++; Should be re-defined in mode-init.lisp, e.g. latex-init.lisp. ++ ++(defparameter index-subitem-length 30) ++ ++(defun index (x &optional subkind) ++ ;; Subkind must be string or atom. ++ (pprinc *begin-index*) ++ (cond ((stringp x) (print-string x 0)) ++ (t (print-atom x 0))) ++ ;; WARNING: Latex/Scribe dependency. ++ (if subkind ++ (cond ((stringp subkind) (pprinc ", ") (print-string subkind 0)) ++ ((symbolp subkind) (pprinc ", ") (print-atom subkind 0)) ++ (t nil))) ++ (pprinc *end-index*)) ++ ++ ++; EVENT PRINTERS ++ ++(defvar *local-context* nil ++ "Indicates when we are in a `local' context, e.g. in encapsulate.") ++ ++(defvar *local-handlers* nil ++ "List of events that are sensitive to *local-context*") ++;; Every -printer that calls event-label printer is so sensitive. ++ ++(defmacro local-print (x) ++ `(or (member ',x *local-handlers*) ++ (setq *local-handlers* (cons ',x *local-handlers*)))) ++ ++(defun event-doc-string (doc) ++ (cond ((or (null doc) (not (stringp doc)) (string= doc ""))) ++ (t (begin-text) ++ (if *acl2-format-doc-strings* ++ (let ((pair (acl2-parse-string doc))) ++ (if (car pair) ;failed ++ nil ++ (setq doc (cdr pair))))) ++ ;; IS PPRINC THE RIGHT THING? WHAT ABOUT SPECIAL CHARS? ++ ;; I think so. ++ (pprinci doc) ++ (to-current-margin) ++ (end-text) ++ (blankline)))) ++ ++(defun print-default-event-header () ++ (ppformat *print-default-event-header*) ++ (setq *infix-loc* 0)) ++ ++(defun no-tab-event-trailer () ++ (ppformat *no-tab-event-trailer*)) ++ ++(defun print-default-command-header () ++ (ppformat *print-default-command-header*) ++ (setq *infix-loc* 0)) ++ ++(defun no-tab-command-trailer () ++ "May occur in a tabbing env. due to an encapsulate. ++In which case we don't want to print *no-tab-command-trailer*." ++ (if *tab-stack* (blankline) (ppformat *no-tab-command-trailer*))) ++ ++(defun event-label-printer (label &optional lowercase) ++ (if *local-context* (small-caps-sym-printer "LOCAL ")) ++ (small-caps-sym-printer label) ++ (if lowercase (pprinc lowercase))) ++ ++(eval-when (load compile eval) ++ ++(defun begin-event (&optional doc) ++ (blankline) ++ (event-doc-string doc) ++ (begin-tabbing) ++ (line-return)) ++ ++(defmacro end-event () ++ '(progn (end-tabbing) ++ (blankline))) ++ ++(defmacro begin-paragraph () ++ `(progn (blankline) (begin-text))) ++ ++(defmacro end-paragraph () ++ `(progn (end-text) (blankline))) ++ ++) ++ ++;; acl2 == segment* ++;; segment == text blankline || event blankline ++;; event == [ doc blankline ] begin-event body [ keys ] end-event ++;; body == type header = form || type header acl2 ++ ++(defun default-event-printer (event) ++ (begin-event) ++ (if *local-context* ++ (event-label-printer "Local Event" " (of unknown type): ") ++ (event-label-printer "Event" " (of unknown type): ")) ++ (newline) ++ (quote-printer1 event) ++ (end-event)) ++ ++(defun extract-keywords (l keys) ++ (cond ((not (consp keys)) nil) ++ ((member (car keys) l) ++ (cons (cadr (member (car keys) l)) ++ (extract-keywords l (cdr keys)))) ++ (t (cons nil (extract-keywords l (cdr keys)))))) ++ ++ ++(defun defcor-printer (event) ++ (let* ((name (nth 1 event)) ++ (old-event (nth 2 event)) ++ (keys (extract-keywords event '(:rule-classes :doc))) ++ (rule-classes (car keys)) ++ (doc (cadr keys))) ++ (begin-event doc) ++ (event-label-printer "Corollary: ") ++ (print-atom name) ++ (pprinci " is a corollary to ") ++ (print-atom old-event) ++ (pprinci ".") ++ (index name) ++ (to-current-margin) ++ (cond ((and (consp rule-classes) ++ (consp (car rule-classes)) ++ (equal (car (car rule-classes)) :rewrite) ++ (consp (cdr (car rule-classes))) ++ (equal (car (cdr (car rule-classes))) :corollary)) ++ (infix-print-term (cadr (cdr (car rule-classes))))) ++ (t (pprinc "Rule Classes: ") ++ (infix-print-term rule-classes))) ++ (end-event))) ++ ++(local-print defcor) ++ ++ ++(defun defequiv-printer (event) ++ (let* ((fn (nth 1 event)) ++ (keys (extract-keywords event '(:rule-classes :doc))) ++ (rule-classes (car keys)) ++ (doc (cadr keys))) ++ (begin-event doc) ++ (event-label-printer "Equivalence relation: ") ++ (print-atom fn) ++ (index fn) ++ (flushright-rule-classes rule-classes) ++ (end-tabbing))) ++ ++(local-print defequiv) ++ ++(defun defdoc-printer (term) ++ (ppformat "~%New documentation for: ~s.~%" (cadr term)) ++ (pprinci (caddr term))) ++ ++(defun flushright-rule-classes (rules) ++ (if rules ++ (progn (begin-flushright) ++ (rule-class-printer rules) ++ (end-flushright)))) ++ ++ ++(defun defaxiom-printer (term) ++ ;; name term :rule-clases clases :doc string ++ (let* ((name (nth 1 term)) ++ (subterm (nth 2 term)) ++ (keys (extract-keywords term '(:rule-classes :doc))) ++ (rule-classes (car keys)) ++ (doc (cadr keys))) ++ (begin-event doc) ++ (event-label-printer "Axiom: ") ++ (print-atom name) ++ (index name) ++ (flushright-rule-classes rule-classes) ++ (infix-print-term subterm) ++ (end-event))) ++ ++(local-print defaxiom) ++ ++ ++(defun defcong-printer (term) ++ ;; equiv1 k equiv2 fn :rule-classes :instructions :hints :otf-flg :cheat :doc ++ (let* ((equiv1 (nth 1 term)) ++ (equiv2 (nth 2 term)) ++ (fn (nth 3 term)) ++ (arity (nth 4 term)) ++ (keys (extract-keywords term '(:rule-classes :instructions :hints :otf-flg :doc))) ++ (rule-classes (nth 0 keys)) ++ (doc (nth 4 keys))) ++ (begin-event doc) ++ (event-label-printer "Equivalence relation: ") ++ (print-atom equiv1) ++ (small-caps-sym-printer " preserves ") ++ (print-atom equiv2) ++ (to-current-margin) ++ (small-caps-sym-printer " for argument position ") ++ (print-atom arity) ++ (small-caps-sym-printer " of ") ++ (infix-print-term1 fn) ++ (index equiv1 "equivalence") ++ (index equiv2 "equivalence") ++ (if (consp fn) (index (car fn))) ++ (flushright-rule-classes rule-classes) ++ (newline) ++ (end-event))) ++ ++(local-print defcong) ++ ++ ++(defun defconst-printer (event) ++ (let ((name (nth 1 event)) ++ (term (nth 2 event)) ++ (doc (nth 3 event))) ++ (begin-event doc) ++ (event-label-printer "Constant: ") ++ (infix-print-term (list 'equal name term)) ++ (end-event))) ++ ++(local-print defconst) ++ ++(defun defevaluator-printer (term) ++ ;; ev ev-list signatures ++ (let ((ev (nth 1 term)) ++ (ev-list (nth 2 term)) ++ (signatures (cadddr term))) ++ (begin-event "Define an evaluator.") ++ (ppformat "Let `~s' be an evaluator function, with mutually-recursive counterpart ++`~s', for the functions" ev ev-list) ++ (print-bare-function-names (mapcar (function car) signatures)) ++ (index ev) ++ (index ev-list) ++ (end-event))) ++ ++(local-print defevaluator) ++ ++ ++(defun deflabel-printer (event) ++ (let* ((name (nth 1 event)) ++ (keys (extract-keywords event '(:doc))) ++ (doc (nth 0 keys))) ++ (begin-event doc) ++ (event-label-printer "Label: ") ++ (print-atom name) ++ (index name) ++ (end-event))) ++ ++(local-print deflabel) ++ ++ ++(defun defrefinement-printer (term) ++ ;; equiv1 equiv2 :rule-classes :instructions :hints :otf-flg :doc ++ (let* ((eq1 (nth 1 term)) ++ (eq2 (nth 2 term)) ++ (keys (extract-keywords term '(:rule-classes :instructions :hints :otf-flg :doc))) ++ ;(rule-classes (nth 0 keys)) ++ (doc (nth 4 keys))) ++ (begin-event doc) ++ (event-label-printer "Refinement: ") ++ (print-atom eq1) ++ (small-caps-sym-printer " refines ") ++ (print-atom eq2) ++ (index eq1) ++ (index eq2) ++ (end-event))) ++ ++(local-print defrefinement) ++ ++ ++(defun defpkg-printer (event) ++ (let ((name (nth 1 event)) ++ ; (contents (nth 2 event)) ++ (doc (if (> (length event) 3) (nth 3 event)))) ++ ;; ++ ;; We do the following so that we can print and ++ ;; read symbols in this package. ++ ;; ++ (if (not (find-package name)) (make-package name)) ++ ;; ++ (begin-event doc) ++ (event-label-printer "Package ") ++ (bold-sym-printer name) ++ (index name " defined") ++ ;; (infix-print-term contents) ++ (to-current-margin) ++ (end-event))) ++ ++ ++(defun in-package-printer (event) ++ (let ((name (nth 1 event))) ++ ;; ++ ;; We do the following so that we can print and ++ ;; read symbols in this package. ++ ;; ++ (if (not (find-package name)) (make-package name)) ++ ;; ++ (begin-event) ++ (event-label-printer "Set current package" " to be ") ++ (bold-sym-printer name) ++ (pprinc ".") (index name "package used") ++ (end-event))) ++ ++(local-print in-package) ++ ++(defun rebuild-printer (event) ++ (let ((name (nth 1 event)) ++ (key (if (cddr event) (caddr event)))) ++ (begin-event) ++ (event-label-printer "Rebuild ") ++ (italic-sym-printer name) ++ (cond ((or (null key) ++ (equal key t) ++ (equal key :all) ++ (equal key :query)) ++ (pprinc ".")) ++ ((symbolp key) (ppformat " through ~s." (symbol-name key))) ++ ((and (consp key) ++ (eq (car key) 'quote) ++ (symbolp (cadr key))) ++ (ppformat " through ~s." (symbol-name (cadr key)))) ++ (t (ppformat "."))) ++ (end-event))) ++ ++(local-print rebuild) ++ ++(defun filename-sym-printer (x) ++ (italic-sym-printer (acl2-smash-file-name x))) ++ ++;; A file (to acl2) may be a string or ++;; (:ABSOLUTE . string* ) ++;; (:RELATIVE . string* ) ++ ++(defun acl2-file-name-root (file) ++ (cond ((not (consp file)) file) ++ (t (car (last file))))) ++ ++(defun acl2-smash-file-name (file) ++ (cond ((not (consp file)) ++ (cond ((stringp file) file) ++ ((symbolp file) (symbol-name file)) ++ (t ""))) ++ ((equal (car file) :absolute) ++ (concatenate 'string "/" (acl2-smash-file-name (cdr file)))) ++ ((equal (car file) :relative) ++ (acl2-smash-file-name (cdr file))) ++ ((equal (car file) :back) ++ (concatenate 'string "../" (acl2-smash-file-name (cdr file)))) ++ ((cdr file) (concatenate 'string (car file) "/" (acl2-smash-file-name (cdr file)))) ++ (t (car file)))) ++ ++ ++(defun include-book-printer (event) ++ (let* ((file (nth 1 event)) ++ (root (acl2-file-name-root file)) ++ (keys (extract-keywords event '(:doc))) ++ (doc (nth 0 keys))) ++ (begin-event doc) ++ (event-label-printer "Including" " the book: ") ++ (filename-sym-printer file) ++ (pprinc ".") (index root "included") ++ (end-event))) ++ ++(local-print include-book) ;??? ++ ++ ++(defun certify-book-printer (event) ++ (let* ((file (nth 1 event)) ++ (root (acl2-file-name-root file))) ++ (begin-event) ++ (event-label-printer "Certifying" " the book: ") ++ (filename-sym-printer file) ++ (pprinc ".") (index root "certified") ++ (end-event))) ++ ++(local-print certify-book) ;??? ++ ++(defun infix-print-macro-body (body) ++ (cond ((not (consp body)) (infix-print-term1 body)) ++ ((equal (car body) 'quote) ++ (pprinc "'") (infix-print-term1 (cadr body))) ++ ((equal (car body) '*infix-backquote*) ++ (pprinc "`") (infix-print-term1 (cadr body))) ++ (t (infix-print-term1 body)))) ++ ++ ++(defun defmacro-printer (event) ++ (let* ((name (nth 1 event)) ++ ;; Note that macro args may include &optional or &rest. ++ (args (nth 2 event)) ++ (doc (nth 3 event)) ++ (body (car (last event))) ++ (form (cons name args))) ++ (begin-event doc) ++ (event-label-printer "Macro: ") ++ (index name "defined") ++ (to-current-margin) ++ ;; Can we fit the defun on one line? ++ (cond ((let ((*rightmost-char-number* (- *rightmost-char-number* 12))) ++ (advise-break (list 'equal form body))) ++ ;; No. ++ (defun-call-part-printer form) ++ (to-current-margin) ;newline ++ (pprinci (format nil " ~a " (get 'equal 'literalform))) ++ (to-current-margin) ;(new-tab-row t) ++ (infix-print-macro-body body)) ++ (t (defun-call-part-printer form) ++ (pprinci (format nil " ~a " (get 'equal 'literalform))) ++ (infix-print-macro-body body))) ++ (to-current-margin) ++ (end-event))) ++ ++(local-print defmacro) ++ ++ ++(defun defstub-printer (event) ++ (let ((name (nth 1 event)) ++ (args (nth 2 event)) ++ (result (nth 3 event))) ++ (begin-event) ++ (event-label-printer "Function: ") ++ (infix-print-term1 (cons name args)) ++ ;; (if (equal 1 (length args)) ++ ;; (pprinc " of one argument.") ++ ;; (ppformat " of ~a arguments." (length args)))) ++ (cond ((symbolp result)) ++ (t (ppformat ". Returns ~a results." (length (cdr result))))) ++ (end-event))) ++ ++(local-print defstub) ++ ++(defun rule-class-printer (classes) ++ ;; classes is either keyword or a list of keywords or ++ ;; lists whose car is a keyword. ++ (cond ((consp classes) ++ (rule-class-print (car classes)) ++ (mapc (function (lambda (x) (print-string ", ") (rule-class-print x))) (cdr classes))) ++ (t (rule-class-print classes)))) ++ ++(defun rule-class-print (class) ++ (cond ((keywordp class) (italic-sym-printer class)) ++ ((keywordp (car class)) (italic-sym-printer (car class))) ++ (t nil))) ++ ++ ++(defun defthm-printer (term) ++ ;; name term :rule-classes :instructions :hints :otf-flg :doc ++ (let* ((name (nth 1 term)) ++ (subterm (nth 2 term)) ++ (keys (extract-keywords term '(:rule-classes :instructions :hints :otf-flg :doc))) ++ (rule-classes (nth 0 keys)) ++ (doc (nth 4 keys))) ++ (begin-event doc) ++ (event-label-printer "Theorem: ") ++ (print-atom name) ++ (index name) ++ (flushright-rule-classes rule-classes) ++ (infix-print-term subterm) ++ (end-event))) ++ ++(local-print defthm) ++ ++(defparameter *noindent* nil) ++(defvar *indent-string* " ") ++(defvar *default-indent* 2) ++ ++(defun begin-indent (&optional newline (indent *default-indent*)) ++ (if newline (newline)) ++ (sloop for i from 1 to indent do (pprinc *indent-string*)) ++ (set-margin)) ++ ++(defun end-indent () ++ (pop-margin) ++ (line-return)) ++ ++ ++ ++ ++(defun encapsulate-printer (term) ++ (let ((signatures (nth 1 term)) ++ (events (cddr term))) ++ (begin-event) ++ (event-label-printer "Begin Encapsulation") ++ (if signatures ++ (progn (blankline) ++ (event-label-printer "Constrain" " the functions: ") ++ ;; SCRIBE SPECIFIC BRANCH. ++ (if (or (string= *infix-mode* "scribe") ++ (string= *infix-mode* "SCRIBE")) ++ (blankline)) ++ (begin-indent) ++ (mapc (function (lambda (x) ++ (defstub-printer (cons 'defstub x)))) ++ signatures) ++ (end-indent) ++ ;(blankline) ++ (small-caps-sym-printer "according to the following events: "))) ++ (blankline) ++ (begin-indent) ++ (mapc (function (lambda (x) (infix-event x))) events) ++ (end-indent) ++ (blankline) ++ (small-caps-sym-printer "End encapsulatation.") ++ (end-event))) ++ ++(defun skip-proofs-printer (term) ++ (let ((event (nth 1 term))) ++ (ppformat "~%The proofs normally generated by the following event are being skipped.~%~%") ++ (funcall (get-event-printer (car event)) event))) ++ ++ ++ ++ ++(defun local-printer (term) ++ (let ((event (cadr term)) ++ (*local-context* t)) ++ (if (and (consp event) (member (car event) *local-handlers*)) ++ (infix-event event) ++ (progn (event-label-printer "Local event: ") ++ (infix-event event))))) ++ ++ ++(defun mutual-recursion-printer (term) ++ (let ((events (cdr term))) ++ (mapc (function (lambda (x) (infix-event x))) events))) ++ ++ ++(defun defuns-printer (term) ++ (let ((events (cdr term))) ++ (mapc (function (lambda (x) (infix-event (cons 'defun x)))) events))) ++ ++ ++(defun ld-printer (term) ++ (let ((keys (extract-keywords term '(:standard-co :proofs-co :current-package ++ :ld-skip-proofsp :ld-redefinition-action ++ :ld-prompt :ld-keyword-aliases :ld-pre-eval-filter ++ :ld-pre-eval-print :ld-post-eval-print :ld-evisc-tuple ++ :ld-error-triples :ld-error-action ++ :ld-query-control-alist :ld-verbose)))) ++ (begin-event) ++ (event-label-printer "Load" " the file: ") ++ (filename-sym-printer (cadr term)) ++ (end-event) ++ (if keys ++ (let ((pairs (pairlis '(:standard-co :proofs-co :current-package ++ :ld-skip-proofsp :ld-redefinition-action ++ :ld-prompt :ld-keyword-aliases :ld-pre-eval-filter ++ :ld-pre-eval-print :ld-post-eval-print :ld-evisc-tuple ++ :ld-error-triples :ld-error-action ++ :ld-query-control-alist :ld-verbose) ++ keys))) ++ (pprinc "Loaded with the following settings: ") ++ (print-settings-list pairs))) ++ (blankline))) ++ ++(defun infix-print-setting (a) ++ ;; X is pair of form keyword . setting. ++ (let ((f (get-keyword-printer (car a)))) ++ (funcall f a))) ++ ++(defun print-settings-list (pairs) ++ (sloop for tail on pairs ++ do (cond ((not (consp tail))) ++ ((cddr tail) ++ (infix-print-setting (car tail)) ++ (pprinci ", ")) ++ ((cdr tail) ++ (infix-print-setting (car tail))) ++ (t ++ (pprinci " and ") ++ (infix-print-setting (car tail)) (pprinci "."))))) ++ ++(defun extract-declare-xarg (dcls) ++ ;; dcls = ((DECLARE arg*)) ++ ;; arg = xarg || other ++ ;; xarg = (XARGS key value ...) ++ ;; key = :guard || :measure || :mode ++ (cond ((null dcls) nil) ++ ((consp (car dcls)) ++ (let ((dcl (car dcls))) ++ (cond ((and (equal (car dcl) 'declare) ++ (equal (car (cadr dcl)) 'xargs)) ++ (append (cdr (cadr dcl)) ++ (extract-declare-xarg (cdr dcls)))) ++ (t (extract-declare-xarg (cdr dcls)))))) ++ (t (extract-declare-xarg (cdr dcls))))) ++ ++(defun print-decls (dcls) ++ (print-decls2 (extract-declare-xarg dcls))) ++ ++(defun print-decls2 (dcls) ++ (if (null dcls) ++ nil ++ (let* ((keys (extract-keywords dcls '(:measure :guard :mode))) ++ ;; Left out :well-founded-relation, :hints, :guard-hints, verify-guards, :otf-flag ++ (measure (nth 0 keys)) ++ (guard (nth 1 keys)) ++ (mode (nth 2 keys))) ++ (when measure ++ (bold-sym-printer "Measure: ") ++ (set-margin) ++ (infix-print-term1 measure) ++ (pop-margin)) ++ (when mode ++ (bold-sym-printer "Mode: ") ++ (print-atom mode) ++ (to-current-margin)) ;newline ++ (when guard ++ (bold-sym-printer "Guard: ") ++ (set-margin) ++ (infix-print-term1 guard) ++ (pop-margin) ++ (to-current-margin))))) ;newline ++ ++ ++ ++(defun defun-printer1 (term equiv) ++ ;; (defun name args doc-string dcl ... dcl body) ++ (let* ((name (nth 1 term)) ++ (args (nth 2 term)) ++ (doc (if (stringp (nth 3 term)) (nth 3 term))) ++ (form (cons name args)) ++ (body (car (last term))) ++ (eq (list equiv form body)) ++ dcls) ++ (sloop for x in (cdddr term) ++ do (if (or (stringp x) ++ (equal x body)) ++ nil ++ (setq dcls (append dcls (list x))))) ++ (begin-event doc) ++ (event-label-printer "Definition: ") ++ (index name "defined") ++ (to-current-margin) ++ ;; Can we fit the defun on one line? ++ (cond ((let ((*rightmost-char-number* (- *rightmost-char-number* 12))) ++ (advise-break eq)) ++ ;; No. ++ (infix-print-term1 form) ++ (to-current-margin) ;newline ++ (pprinci (format nil " ~a " (get equiv 'literalform)) 3) ++ ;; (new-tab-row t) ++ (infix-print-term body)) ++ (t (infix-print-term1 form) ++ (pprinci (format nil " ~a " (get equiv 'literalform)) 3) ++ (infix-print-term1 body))) ++ (to-current-margin) ++ (print-decls dcls) ++ (end-event))) ++ ++ ++(defun defun-printer (term) ++ (defun-printer1 term 'equal)) ++ ++(local-print defun) ++(local-print define) ++ ++(defun forall-printer (term) ++ (let ((vars (nth 1 term)) ++ (body (nth 2 term))) ++ (pprinci *forall* *tt-size*) ++ (cond ((atom vars) ++ (funcall (get-atom-printer vars) vars)) ++ (t (sloop for tail on vars do ++ (funcall (get-atom-printer (car tail)) (car tail)) ++ (cond ((cdr tail) ++ (pprinci ", " *tt-size*)))))) ++ (pprinc ":") ++ (math-space 1) ++ (infix-print-term1 body))) ++ ++(defun exists-printer (term) ++ (let ((vars (nth 1 term)) ++ (body (nth 2 term))) ++ (pprinci *exists* *tt-size*) ++ (cond ((atom vars) ++ (funcall (get-atom-printer vars) vars)) ++ (t (sloop for tail on vars do ++ (funcall (get-atom-printer (car tail)) (car tail)) ++ (cond ((cdr tail) ++ (pprinci ", " *tt-size*)))))) ++ (pprinc ":") ++ (math-space 1) ++ (infix-print-term1 body))) ++ ++(declare-fn-printer exists (function exists-printer)) ++(declare-fn-printer forall (function forall-printer)) ++ ++ ++;; Rune Runic Desig ++;; def = symbolp :functionp == (:DEFINITION symb). ++;; ex = (symbolp) :functionp == (:EXECUTABLE-COUNTERPART symb) ++;; thm = symbolp :defthm == {...} set introduced ++;; ax = symbolp :defaxiom == {...} set introduced ++;; th = symbolp :deftheory == {...} set introduced ++ ++;; runic-desig = def | ex | thm | ax | theory | ?? string ++;; runic-des == sym | (sym) ++;; rune == (:DEFINITION sym) | (:EXECUTABLE-COUNTERPART sym) ++;; | (:REWRITE sym) | (:REWRITE sym) ++;; | (:ELIM sym) | runic-des ++ ++ ++ ++(defun print-rune-string (rune) ++ (cond ((eq rune :here) (pprinc "the current theory")) ++ ((not (consp rune)) (print-bare-function-name rune)) ++ ((null (cdr rune)) ++ (pprinc "the executable counterpart of ") ++ (print-bare-function-name (car rune))) ++ ((eq (car rune) :executable-counterpart) ++ (pprinc "the executable counterpart of ") ++ (print-bare-function-name (cadr rune))) ++ ((eq (car rune) :definition) ++ (pprinc "the definition of ") ++ (print-bare-function-name (cadr rune))) ++ ((eq (car rune) :rewrite) ++ (pprinc "the rewrite rule, ") ++ (print-bare-function-name (cadr rune))) ++ ((eq (car rune) :elim) ++ (pprinc "the elimination rule, ") ++ (print-bare-function-name (cadr rune))) ++ (t (pprinc "the ") (print-atom (car rune)) ++ (pprinc " rule, ") ++ (print-bare-function-name (cadr rune))))) ++ ++(defun runes-print (runes) ++ (cond ((cdr runes) ++ (sloop for x on runes ++ do (cond ((cddr x) ++ (print-rune-string (car x)) ++ (pprinc ", ")) ++ ((cdr x) ++ (print-rune-string (car x)) ++ (pprinc " and ")) ++ (t (print-rune-string (car x)))))) ++ (t (print-rune-string (car runes))))) ++ ++;; name == sym | string | :here -- event name ++;; theory == (rune*) -- sets of runes to enable/disable in concert ++;; theory-des == ++;; (DISABLE runic-desig*) => theory ++;; | (ENABLE runic-desig*) => theory ++;; ++;; | (CURRENT-THEORY name) => theory -- name is atom, string, or :here ++;; | (UNIVERSAL-THEORY name) => theory -- as of logical name ++;; | (THEORY name) => theory ++;; | (FUNCTION-THEORY name) => theory -- function symbol rules ++;; ++;; | (INTERSECTION-THEORIES th1 th2) => theory ++;; | (SET-DIFFERENCE-THEORIES th1 th2) => theory ++;; | (UNION-THEORIES th1 th2) => theory ++ ++ ++(defun theory-print (form &optional (tail "")) ++ (cond ((not (consp form)) ++ (pprinci (format nil "the theory ")) ++ (bold-sym-printer form) ++ (pprinci tail)) ++ ((eq (car form) 'quote) (runes-print (cadr form)) (pprinci tail)) ++ (t (or *do-not-use-tabs* (begin-tabbing)) ++ (infix-print-term1 form)(pprinci tail) ++ (or *do-not-use-tabs* (end-tabbing))))) ++ ++(defun deftheory-printer (event) ++ (let* ((name (nth 1 event)) ++ (theory (nth 2 event)) ++ (keys (extract-keywords event '(:doc))) ++ (doc (nth 0 keys))) ++ (event-doc-string doc) ++ (newline) ++ (begin-text) ++ (line-return) ++ (event-label-printer "Define" " the theory ") ++ (bold-sym-printer name) ++ (index name "theory") ++ (pprinc " to be ") ++ (theory-print theory ".") ++ (end-text) ++ (blankline))) ++ ++(local-print deftheory) ++ ++ ++(defun in-theory-printer (event) ++ (let* ((theory (nth 1 event)) ++ (keys (extract-keywords event '(:doc))) ++ (doc (nth 0 keys)) ++ *do-not-use-tabs*) ++ (event-doc-string doc) ++ (newline) ++ (begin-text) ++ (line-return) ++ (event-label-printer "Modify" " the current theory: ") ++ (theory-print theory ".") ++ (end-text) ++ (blankline))) ++ ++(local-print in-theory) ++ ++ ++(defun boot-strap-printer (term) ++ (declare (ignore term)) ++ (begin-event) ++ (event-label-printer "Start" " with the initial Acl2 theory.") ++ (end-event)) ++ ++ ++(defun verify-guards-printer (event) ++ (let* ((name (nth 1 event)) ++ (keys (extract-keywords event '(:doc))) ++ (doc (nth 0 keys))) ++ (begin-event doc) ++ (event-label-printer "Verify guards" " for ") ++ (print-bare-function-name name) ++ (index name "guard verification") ++ (end-event))) ++ ++(local-print verify-guards) ++ ++ ++;; (verify-termination fn dcl ... dcl) ++;; or (verify-termination (fn1 dcl ... dcl) (fn2 dcl ... dcl) ...) ++ ++(defun verify-termination-printer (event) ++ (begin-event) ++ (event-label-printer "Verify termination" " for ") ++ (set-margin) ++ (let ((events (if (symbolp (cadr event)) ++ (list (cdr event)) ++ (cdr event)))) ++ (mapl (function (lambda (x) ++ (progn (print-verify-termination (car x)) ++ (to-current-margin)))) ++ events)) ++ (pop-margin) ++ (end-event)) ++ ++(local-print verify-termination) ++ ++(defun print-verify-termination (x) ++ (cond ((consp x) ++ (pprinc " ") ++ (print-bare-function-name (car x)) ++ (pprinc " with ") ++ (print-decls (cdr x))) ++ (t (pprinc " ") (print-bare-function-name x)))) ++ ++(defun disable-printer (form) ++ (pprinc "Disable ") ++ (runes-print (cdr form))) ++ ++(declare-fn-printer disable (function disable-printer)) ++ ++(defun enable-printer (form) ++ (pprinc "Enable ") ++ (runes-print (cdr form))) ++ ++(declare-fn-printer enable (function enable-printer)) ++ ++(defun current-theory-printer (form) ++ (cond ((eq (cadr form) :here) ++ (pprinci "the current theory ")) ++ ((and (consp (cadr form)) (eq (car (cadr form)) 'quote)) ++ (pprinci (format nil "the theory as of ~a" (cadr (cadr form))))) ++ (t (pprinci (format nil "the theory as of ~a" (cadr form)))))) ++ ++(declare-fn-printer current-theory (function current-theory-printer)) ++ ++(defun universal-theory-printer (form) ++ (cond ((eq (cadr form) :here) ++ (pprinci "the current universal theory ")) ++ ((and (consp (cadr form)) (eq (car (cadr form)) 'quote)) ++ (pprinci (format nil "the theory as of ~a" (cadr (cadr form))))) ++ (t (pprinci (format nil "the universal theory as of ~a" (cadr form)))))) ++ ++(declare-fn-printer universal-theory (function universal-theory-printer)) ++ ++(defun theory-printer (form) ++ (cond ((eq (cadr form) :here) ++ (pprinci "the current theory ")) ++ ((and (cadr form) (consp (cadr form)) (eq (car (cadr form)) 'quote)) ++ (pprinci "the theory ") (bold-sym-printer (cadr (cadr form)))) ++ (t (pprinci (format nil "the theory ~a" (cadr form)))))) ++ ++(declare-fn-printer theory (function theory-printer)) ++ ++(defun function-theory-printer (form) ++ (cond ((eq (cadr form) :here) ++ (pprinci "the current function theory ")) ++ ((and (cadr form) (consp (cadr form)) (eq (car (cadr form)) 'quote)) ++ (pprinci "the function theory ") (bold-sym-printer (cadr (cadr form)))) ++ (t (pprinci (format nil "the function theory ~a" (cadr form)))))) ++ ++(declare-fn-printer function-theory (function function-theory-printer)) ++ ++;; See scribe or latex init to see how the following are handled. ++;; intersection-theories ++;; set-difference-theories ++;; union-theories ++ ++(defun theory-invariant-printer (form) ++ (let ((term (cadr form)) ++ (key (if (cddr form) (caddr form) nil))) ++ (cond ((eq (car term) 'incompatible) ++ (print-rune-string (cadr term)) ++ (pprinc " is incompatible with ") ++ (print-rune-string (caddr term)) ++ (pprinc " in this theory") ++ (if key (pprinc "Call this invariant ") (print-atom key))) ++ (t (cond (key (pprinc (format nil "Invariant [~a]: " key)) ++ (infix-print-term1 (term))) ++ (t (pprinc "Invariant : ") ++ (infix-print-term1 (term)))))))) ++ ++(declare-fn-printer theory-invariant (function theory-invariant-printer)) ++ ++(defun defun-sk-printer (event) ++ ;; (defun-sk name args body &key doc quant-ok skolem-name thm-name) ++ (let* ((name (nth 1 event)) ++ (args (nth 2 event)) ++ (body (nth 3 event)) ++ (keys (extract-keywords event '(:doc :quant-ok :skolem-name :thm-name))) ++ (doc (nth 0 keys)) ++ (form (cons name args)) ++ (eq (list 'equal form body))) ++ (begin-event doc) ++ (event-label-printer "Definition w/quantifier: ") ++ (index name "defined with quantifier") ++ (to-current-margin) ++ ;; Can we fit the defun on one line? ++ (cond ((let ((*rightmost-char-number* (- *rightmost-char-number* 12))) ++ (advise-break eq)) ++ ;; No. ++ (infix-print-term1 form) ++ (to-current-margin) ;newline ++ (pprinci (format nil " ~a " (get 'equal 'literalform)) 3) ++ ;; (new-tab-row t) ++ (infix-print-term body)) ++ (t (infix-print-term1 form) ++ (pprinci (format nil " ~a " (get 'equal 'literalform)) 3) ++ (infix-print-term1 body))) ++ (to-current-margin) ++ (end-event))) ++ ++;; ( LEFT IN ---------- ++ ++(defun do-file-printer (term) ++ (print-default-event-header) ++ (pprinc "Do all forms in the file: ++") ++ (italic-sym-printer (cadr term)) ++ (no-tab-event-trailer)) ++ ++(defun setq-printer (term) ++ (print-default-event-header) ++ (let (name value) ++ (match term (setq name value)) ++ (ppformat "Give the Acl2 control variable ") ++ (tt-sym-printer name) ++ (ppformat " the value ") ++ (tt-sym-printer value) ++ (ppformat ".")) ++ (no-tab-event-trailer)) ++ ++(defun comp-printer (term) ++ ":comp t - compile all uncompiled ACL2 functions ++:comp foo - compile the defined function foo ++:comp (foo bar) - compile the defined functions foo and bar" ++ (print-default-command-header) ++ (cond ((null (cdr term)) ++ (pprinc "Unknown compile command.")) ++ ((equal (cadr term) t) ++ (pprinc "Compile all uncompiled ACL2 functions.")) ++ ((symbolp (cadr term)) ++ (pprinc "Compile ") ++ (print-bare-function-name (cadr term)) ++ (pprinc ".")) ++ (t (pprinc "Compile ") ++ (print-bare-function-names (cadr term)) ++ (pprinc "."))) ++ (no-tab-command-trailer)) ++ ++(defmacro define-command-printer (name string) ++ (let ((fn-name (intern (format nil "~s-COMMAND-PRINTER" name)))) ++ `(progn ++ (clean-up ',name) ++ (defun ,fn-name ++ (term) ++ (declare (ignore term)) ++ (print-default-command-header) ++ (pprinc ,string) ++ (no-tab-command-trailer)) ++ (declare-command-printer ,name (function ,fn-name))))) ++ ++(defun checkpoint-forced-goals-printer (term) ++ (print-default-command-header) ++ (if (cadr term) ++ (pprinc "Checkpoint forced goals.") ++ (pprinc "Do not checkpoint forced goals.")) ++ (no-tab-command-trailer)) ++ ++(define-command-printer disable-forcing "Disable forcing.") ++(define-command-printer enable-forcing "Enable forcing.") ++(define-command-printer good-bye "Exiting both ACL2 & lisp.") ++(define-command-printer oops-printer "Redo last undo.") ++ ++(defun puff-printer (term) ++ (print-default-command-header) ++ (pprinc "Expand command ") ++ (print-atom (cadr term)) ++ (pprinc ".") ++ (no-tab-command-trailer)) ++ ++(defun puff*-printer (term) ++ (print-default-command-header) ++ (pprinc "Expand command ") ++ (print-atom (cadr term)) ++ (pprinc " recursively.") ++ (no-tab-command-trailer)) ++ ++(define-command-printer q "Quiting ACL2.") ++(define-command-printer redef "Allow redefinition without undoing.") ++(define-command-printer redef! ++ "!!! ACL2 system hacker's redefinition command: ++Allow redefinition (even of system functions) without undoing.") ++ ++(defun reset-ld-specials-printer (term) ++ (print-default-command-header) ++ (pprinc "Reset LD specials to their initial value") ++ (if (cadr term) ++ (pprinc ", including I/O channels.") ++ (pprinc ".")) ++ (no-tab-command-trailer)) ++ ++(defun set-cbd-printer (term) ++ (print-default-command-header) ++ (pprinc "Set connected book directory to ") ++ (filename-sym-printer (cadr term)) ++ (pprinc ".") ++ (no-tab-command-trailer)) ++ ++(defun set-guard-checking-printer (term) ++ (print-default-command-header) ++ (if (cadr term) ++ (pprinc "Set guard checking on.") ++ (pprinc "Set guard checking off.")) ++ (no-tab-command-trailer)) ++ ++(define-command-printer start-proof-tree "Start prooftree logging.") ++(define-command-printer stop-proof-tree "Stop prooftree logging.") ++(define-command-printer u "Undo last event.") ++ ++(defun ubt-printer (term) ++ (print-default-command-header) ++ (cond ((null (cdr term)) ++ (pprinc "Undo the last event.")) ++ (t (pprinc "Undo back through the event named `") ++ (print-atom (cadr term)) ++ (pprinc "'."))) ++ (no-tab-command-trailer)) ++ ++(defun retrieve-printer (term) ++ (print-default-command-header) ++ (pprinc "Re-enter proof-checker state") ++ (if (cadr term) ++ (ppformat " named ~s." (cadr term)) ++ (pprinc ".")) ++ (no-tab-command-trailer)) ++ ++(define-command-printer unsave "") ++(define-command-printer save "") ++ ++(defun verify-printer (event) ++ (begin-event "Enter the interactive proof check with:") ++ (infix-print (cadr event)) ++ (end-event)) ++ ++(defun accumulated-persistence-printer (term) ++ (print-default-command-header) ++ (if (cadr term) ++ (pprinc "Activate statistics gathering.") ++ (pprinc "De-activate statistics gathering.")) ++ (no-tab-command-trailer)) ++ ++(defun show-accumulated-persistence-printer (term) ++ (print-default-command-header) ++ (cond ((equal (cadr term) :frames) ++ (pprinc "Display statistics ordered by frames built.")) ++ ((equal (cadr term) :tries) ++ (pprinc "Display statistics ordered by times tried.")) ++ ((equal (cadr term) :ratio) ++ (pprinc "Display statistics ordered by the ratio of frames built to times tried.")) ++ (t nil)) ++ (no-tab-command-trailer)) ++ ++(defun brr-printer (term) ++ (print-default-command-header) ++ (if (cadr term) ++ (pprinc "Enable the breaking of rewrite rules.") ++ (pprinc "Disable the breaking of rewrite rules.")) ++ (no-tab-command-trailer)) ++ ++(defun monitor-printer (term) ++ (let ((form (cadr term)) ++ (flag (caddr term))) ++ (if (and (consp form) (equal (car form) 'quote)) ++ (setq form (cadr form))) ++ (if (and (consp flag) (equal (car flag) 'quote)) ++ (setq flag (cadr flag))) ++ (print-default-command-header) ++ (pprinc "Monitor: ") ++ (print-rune-string form) ++ (cond ((equal flag t)) ++ (t (pprinc " when ") ++ (infix-print-term flag))) ++ (no-tab-command-trailer))) ++ ++(define-command-printer monitored-runes "Print monitored runes.") ++ ++(defun unmonitor-printer (term) ++ (let ((form (cadr term))) ++ (if (and (consp form) (equal (car form) 'quote)) ++ (setq form (cadr form))) ++ (print-default-command-header) ++ (pprinc "Un-monitor: ") ++ (cond ((equal form :all) (pprinc "all monitored runes.")) ++ (t (print-rune-string form) ++ (pprinc "."))) ++ (no-tab-command-trailer))) ++ ++(defun add-macro-alias-printer (term) ++ (print-default-command-header) ++ (pprinc "Let the macro name ") ++ (print-bare-function-name (cadr term)) ++ (pprinc " be an alias for the function ") ++ (print-bare-function-name (caddr term)) ++ (pprinc ".") ++ (no-tab-command-trailer)) ++ ++(defun remove-macro-alias-printer (term) ++ (print-default-command-header) ++ (pprinc "Remove the alias from the macro ") ++ (print-bare-function-name (cadr term)) ++ (pprinc ".") ++ (no-tab-command-trailer)) ++ ++(define-command-printer logic "Enter logic mode.") ++(define-command-printer program "Enter program mode.") ++ ++(defun set-compile-fns-printer (term) ++ (print-default-command-header) ++ (if (cadr term) ++ (pprinc "New functions will be compiled after their defun.") ++ (pprinc "New functions will not be compiled after their defun.")) ++ (no-tab-command-trailer)) ++ ++(defun set-ignore-ok-printer (term) ++ (print-default-command-header) ++ (cond ((null (cadr term)) ++ (pprinc "Disallow unused formals and locals.")) ++ ((eq (cadr term) t) ++ (pprinc "Allow unused formals and locals.")) ++ ((eq (cadr term) :warn) ++ (pprinc "Allow unused formals and locals, but print warning."))) ++ (no-tab-command-trailer)) ++ ++(define-command-printer set-invisible-fns-alist "Setting the invisible fns alist.") ++ ++(defun set-irrelevant-formals-ok-printer (term) ++ (print-default-command-header) ++ (cond ((null (cadr term)) ++ (pprinc "Disallow irrelevant formals in definitions.")) ++ ((eq (cadr term) t) ++ (pprinc "Allow irrelevant formals in definitions.")) ++ ((eq (cadr term) :warn) ++ (pprinc "Allow irrelevant formals in definitions, but print warning."))) ++ (no-tab-command-trailer)) ++ ++(defun set-measure-function-printer (term) ++ (print-default-command-header) ++ (pprinc "Set the default measure function to be ") ++ (print-bare-function-name (cadr term)) ++ (pprinc ".") ++ (no-tab-command-trailer)) ++ ++(defun set-verify-guards-eagerness-printer (term) ++ (print-default-command-header) ++ (cond ((equal (cadr term) 0) ++ (pprinc "No guard verification unless :verify-guards is t.")) ++ ((equal (cadr term) 1) ++ (pprinc "Verify guards, if supplied.")) ++ ((equal (cadr term) 2) ++ (pprinc "Verify guards, unless :verify-guards is NIL."))) ++ (no-tab-command-trailer)) ++ ++(defun set-well-founded-ordering-printer (term) ++ (print-default-command-header) ++ (pprinc "Set the default well-founded relation to be ") ++ (print-bare-function-name (cadr term)) ++ (pprinc ".") ++ (no-tab-command-trailer)) ++ ++;; TABLE ++ ++(defun table-printer (term) ++ ;; (table tests 1 '(...)) ; set contents of tests[1] to '(...) ++ ;; (table tests 25) ; get contents of tests[25] ++ ;; (table tests) ; return table tests as an alist ++ ;; (table tests nil nil :clear) ; clear table tests ++ ;; (table tests nil (foo 7) :clear) ; set table tests to (foo 7) ++ ;; (table tests nil nil :guard) ; fetch the table guard ++ ;; (table tests nil nil :guard term) ; set the table guard ++ (print-default-command-header) ++ (let ((table (nth 1 term)) ++ (i (nth 2 term)) ++ (value (nth 3 term)) ++ (op (nth 4 term)) ++ (guard (nth 5 term))) ++ (cond ((null (cddr term)) ++ (ppformat "Return table, ") ++ (infix-print-term1 table) ++ (ppformat ", as an alist.")) ++ ((null (cdddr term)) ++ (infix-print-term1 table) ++ (pprinc "[") ++ (infix-print-term1 i) ++ (pprinc "]")) ++ ((null (cdddr (cdr term))) ++ (infix-print-term1 table) ++ (pprinc "[") ++ (infix-print-term1 i) ++ (pprinc "]") ++ (math-space 1) ++ (pprinc ":=") ++ (math-space 1) ++ (infix-print-term1 value) ++ (pprinc ";")) ++ ((null op) ++ (message (format nil "Unknown table operation ~s" term))) ++ ((equal op :clear) ++ (cond ((null value) ++ (ppformat "Clear table, ") ++ (infix-print-term1 table) ++ (ppformat ".")) ++ (t (ppformat "Set elements of table, ") ++ (infix-print-term1 table) ++ (ppformat " to ") ++ (infix-print-term1 value) ++ (pprinc ".")))) ++ ((equal op :guard) ++ (cond ((null guard) ++ (ppformat "Fetch guard of table, ") ++ (infix-print-term1 table) ++ (ppformat ".")) ++ (t ++ (ppformat "Set guard of table, ") ++ (infix-print-term1 table) ++ (ppformat ", to ") ++ (infix-print-term1 guard) ++ (pprinc ".")))) ++ (t (message (format nil "Unknown table operation ~s" term))))) ++ (no-tab-command-trailer)) ++ ++;; We would like to put this at the top, but the functions need to be defined first. ++ ++(setq *event-printer-alist* ++ (append ++ *event-printer-alist* ++ (list ++ (list 'defaxiom (function defaxiom-printer)) ++ (list 'defcong (function defcong-printer)) ++ (list 'defconst (function defconst-printer)) ++ (list 'defcor (function defcor-printer)) ;gone ++ (list 'defequiv (function defequiv-printer)) ++ (list 'deflabel (function deflabel-printer)) ++ (list 'defdoc (function defdoc-printer)) ++ (list 'defevaluator (function defevaluator-printer)) ++ (list 'defmacro (function defmacro-printer)) ++ (list 'defpkg (function defpkg-printer)) ++ (list 'defrefinement (function defrefinement-printer)) ++ (list 'defstub (function defstub-printer)) ++ (list 'deftheory (function deftheory-printer)) ++ (list 'defthm (function defthm-printer)) ++ (list 'defun (function defun-printer)) ++ (list 'defun-sk (function defun-sk-printer)) ++ (list 'define (function defun-printer)) ;mks&mk specific ++ (list 'in-package (function in-package-printer)) ++ (list 'rebuild (function rebuild-printer)) ++ (list 'encapsulate (function encapsulate-printer)) ++ (list 'verify-guards (function verify-guards-printer)) ++ (list 'verify-termination (function verify-termination-printer)) ++ ++ ;; Books ++ ++ (list 'include-book (function include-book-printer)) ++ (list 'certify-book (function certify-book-printer)) ++ (list 'certify-book! (function certify-book-printer)) ++ ++ ;; History. ++ ++ ;; (list 'ubt (function ubt-printer)) ++ ;; (list 'pbt (function ignore-printer)) ++ ;; (list 'pc (function pc-printer)) ++ ;; (list 'pcb (function pcb-printer)) ++ ;; (list 'pe (function pe-printer)) ++ ++ ;; OTHER ++ ++ (list 'in-theory (function in-theory-printer)) ++ (list 'local (function local-printer)) ++ (list 'mutual-recursion (function mutual-recursion-printer)) ++ (list 'defuns (function defuns-printer)) ++ (list 'ld (function ld-printer)) ++ ++ (list 'comp (function comp-printer)) ++ (list 'checkpoint-forced-goals (function checkpoint-forced-goals-printer)) ++ (list 'puff (function puff-printer)) ++ (list 'puff* (function puff*-printer)) ++ (list 'reset-ld-specials (function reset-ld-specials-printer)) ++ (list 'set-cbd (function set-cbd-printer)) ++ ++ (list 'set-guard-checking (function set-guard-checking-printer)) ++ (list 'ubt (function ubt-printer)) ++ (list 'ubt! (function ubt-printer)) ++ (list 'retrieve (function retrieve-printer)) ++ (list 'skip-proofs (function skip-proofs-printer)) ++ (list 'accumulated-persistence (function accumulated-persistence-printer)) ++ (list 'show-accumulated-persistence (function show-accumulated-persistence-printer)) ++ (list 'brr (function brr-printer)) ++ (list 'monitor (function monitor-printer)) ++ (list 'unmonitor (function unmonitor-printer)) ++ (list 'add-macro-alias (function add-macro-alias-printer)) ++ (list 'remove-macro-alias (function remove-macro-alias-printer)) ++ (list 'set-compile-fns (function set-compile-fns-printer)) ++ (list 'set-ignore-ok (function set-ignore-ok-printer)) ++ (list 'set-irrelevant-formals-ok (function set-irrelevant-formals-ok-printer)) ++ (list 'set-measure-function (function set-measure-function-printer)) ++ (list 'set-verify-guards-eagerness (function set-verify-guards-eagerness-printer)) ++ (list 'set-well-founded-ordering (function set-well-founded-ordering-printer)) ++ ++ (list 'table (function table-printer)) ++ ++ ))) ++ ++(defparameter *save-event-printer-alist* *event-printer-alist*) ++ ++(defun get-event-printer (sym) ++ (let ((a (assoc sym *event-printer-alist*))) ++ (cond (a (cadr a)) ++ (t (function default-event-printer))))) ++ ++;; KEYWORD PRINTERS ++ ++(defvar *keyword-printer-alist* nil) ++ ++;; Argument to keyword printers is a pair (key . value) ++ ++(defun get-keyword-printer (sym) ++ (let ((a (assoc sym *keyword-printer-alist*))) ++ (cond (a (cadr a)) ++ (t (function default-keyword-printer))))) ++ ++(defun default-keyword-printer (pair) ++ (ppformat " ~a is ~a" (car pair) (cdr pair))) ++ ++(defun standard-co-keyword-printer (pair) ++ ;; "foo.out" ++ (ppformat " standard output to ~a" (cdr pair))) ++ ++(defun proofs-co-keyword-printer (pair) ++ ;; "proofs.out" ++ (ppformat " proof output to ~a" (cdr pair))) ++ ++(defun current-package-keyword-printer (pair) ++ ;; 'acl2 ++ (let ((name (if (equal (car (cdr pair)) 'quote) ++ (cadr (cdr pair)) ++ (cdr pair)))) ++ (ppformat " in the package ~a" name))) ++ ++(defun ld-skip-proofsp-keyword-printer (pair) ++ ;; 'include-book ++ (cond ((null (cdr pair)) ++ (ppformat " doing proofs")) ++ ((equal (cdr pair) t) ++ (ppformat " skipping termination proofs")) ++ ((equal (cdr pair) '(quote include-book)) ++ (ppformat " assuming proofs in included books")) ++ ((equal (cdr pair) '(quote include-book-with-locals)) ++ (ppformat " assuming proofs in included books and executing local events")) ++ ((equal (cdr pair) '(quote initialize-acl2)) ++ (ppformat " skipping local proofs")) ++ (t nil))) ++ ++(defun ld-redefinition-action-keyword-printer (pair) ++ ;; nil ++ (cond ((null (cdr pair)) ++ (ppformat " redefinition prohibited")) ++ (t (let ((a (car (cdr pair))) ++ (b (cdr (cdr pair)))) ++ (cond ((eq a ':query) ++ (ppformat " query on redefinition ")) ++ ((eq a ':warn) ++ (ppformat " warn on redefinition")) ++ ((eq a ':doit) ++ (ppformat " redefinition ok")) ++ (t ; :warn! :query! ++ (ppformat " redefinition ~a" a))) ++ (cond ((eq b ':erase) ++ (ppformat " erase properties on redefinition ")) ++ ((eq a ':overwrite) ++ (ppformat " overwrite properties on redefinition")) ++ (t ++ (ppformat " redefinition properties ~a" a))))))) ++ ++(defun ld-prompt-keyword-printer (pair) ++ ;; t ++ (cond ((null (cdr pair)) ++ (ppformat " no prompt")) ++ ((eq (cdr pair) t) ++ (ppformat " default prompt")) ++ (t ++ (ppformat " prompt function = ~a" (cdr pair))))) ++ ++(defun ld-keyword-aliases-keyword-printer (pair) ++ ;; pair = (:ld-keyword-aliases '((:q 0 q-fn) (:e 0 exit-acl2-macro))) ++ (let ((x (cdr pair))) ++ (if (equal (car x) 'quote) ++ (setq x (cadr x))) ++ (ppformat " define keyword aliases (") ++ (sloop for tail on x do ++ (cond ((cddr tail) ++ (ppformat "~s = ~a of arity ~d, " ++ (car (car tail)) (caddr (car tail)) (cadr (car tail)))) ++ ((cdr tail) ++ (ppformat "~s = ~a of arity ~d and " ++ (car (car tail)) (caddr (car tail)) (cadr (car tail)))) ++ (t (ppformat "~s = ~a of arity ~d" ++ (car (car tail)) (caddr (car tail)) (cadr (car tail)))))) ++ (ppformat ")"))) ++ ++(defun ld-pre-eval-filter-keyword-printer (pair) ++ ;; :all ++ (cond ((null (cdr pair))) ++ ((equal (cdr pair) ':all) ++ (ppformat " every form read is evaled")) ++ ((equal (cdr pair) ':query) ++ (ppformat " user queried whether form read is evaled")) ++ (t nil))) ++ ++(defun ld-pre-eval-print-keyword-printer (pair) ++ ;; nil ++ (if (cdr pair) ++ (ppformat " forms read are printed") ++ (ppformat " forms read are not printed"))) ++ ++(defun ld-post-eval-print-keyword-printer (pair) ++ ;; :all ++ (cond ((null (cdr pair)) ++ (ppformat " results are not printed")) ++ ((equal (cdr pair) t) ++ (ppformat " results are printed")) ++ ((equal (cdr pair) ':command-conventions) ++ (ppformat " conditionally print error triples")) ++ (t nil))) ++ ++(defun ld-evisc-tuple-keyword-printer (pair) ++ ;; '(alist nil nil level length) ++ (let (value) ++ (cond ((null (cdr pair)) (setq value nil)) ++ ((not (consp (cdr pair))) (setq value (cdr pair))) ++ ((equal (car (cdr pair)) 'quote) (setq value (cadr (cdr pair)))) ++ (t (setq value (cdr pair)))) ++ (cond ((null value) ++ (ppformat " print results fully")) ++ (t (let ((alist (cadr value)) ++ (level (car (cdddr value))) ++ (length (car (cdr (cdddr value))))) ++ (ppformat " eviscerate results (level = ~d, length = ~d)" level length) ++ (if alist ++ (progn (ppformat "whose cars are in (" ) ++ (sloop for tail on alist do ++ (cond ((cddr tail) ++ (ppformat"~a, " (car (car tail)))) ++ ((cdr tail) ++ (ppformat " ~a, and" (car (car tail)))) ++ (t (ppformat " ~a)" (car (car tail))))))))))))) ++ ++(defun ld-error-triples-keyword-printer (pair) ++ ;; t ++ (cond ((null (cdr pair)) ++ (ppformat " errors printed as triples")) ++ ((equal (cdr pair) t) ++ (ppformat " errors roll back to state before call")) ++ (t nil))) ++ ++(defun ld-error-action-keyword-printer (pair) ++ ;; :return ++ (cond ((null (cdr pair))) ++ ((equal (cdr pair) ':continue) ++ (ppformat " continue after errors")) ++ ((equal (cdr pair) ':return) ++ (ppformat " return after errors")) ++ ((equal (cdr pair) ':error) ++ (ppformat " signal errors")) ++ (t nil))) ++ ++(defun ld-query-control-alist-keyword-printer (pair) ++ ;; nil ++ (cond ((null (cdr pair)) ++ (ppformat " handle queries interactively")) ++ ((equal (cdr pair) 't) ++ (ppformat " queries default to first accepted response")) ++ (t ++ (ppformat "queries default according to ~s" (cdr pair))))) ++ ++(defun ld-verbose-keyword-printer (pair) ++ ;; nil ++ (cond ((null (cdr pair)) ++ (ppformat"verbose mode off ")) ++ (t ++ (ppformat " verbose mode on")))) ++ ++(defparameter *keyword-printer-alist* ++ (list (list ':standard-co (function standard-co-keyword-printer)) ++ (list ':proofs-co (function proofs-co-keyword-printer)) ++ (list ':current-package (function current-package-keyword-printer)) ++ (list ':ld-skip-proofsp (function ld-skip-proofsp-keyword-printer)) ++ (list ':ld-redefinition-action (function ld-redefinition-action-keyword-printer)) ++ (list ':ld-prompt (function ld-prompt-keyword-printer)) ++ (list ':ld-keyword-aliases (function ld-keyword-aliases-keyword-printer)) ++ (list ':ld-pre-eval-filter (function ld-pre-eval-filter-keyword-printer)) ++ (list ':ld-pre-eval-print (function ld-pre-eval-print-keyword-printer)) ++ (list ':ld-post-eval-print (function ld-post-eval-print-keyword-printer)) ++ (list ':ld-evisc-tuple (function ld-evisc-tuple-keyword-printer)) ++ (list ':ld-error-triples (function ld-error-triples-keyword-printer)) ++ (list ':ld-error-action (function ld-error-action-keyword-printer)) ++ (list ':ld-query-control-alist (function ld-query-control-alist-keyword-printer)) ++ (list ':ld-verbose (function ld-verbose-keyword-printer)))) ++ ++ ++; COPY COMMENTS ++ ++;; MKS Tue Jul 13 1993 ++;; Make ;- comments and BAR-COMMENTs followed by a dash appear in ++;; a formatted (in Latex, verbatim) environment. ++ ++(defparameter *comment-environment* nil) ++ ++(defparameter *comment-format* 'smith) ++ ++(defparameter *comment-semi-net* nil) ++(defparameter *comment-lb-net* nil) ++ ++;; We use this two stage template/eval kludge so that if the template can ++;; be used to reset the variable after the user has defined these variables. ++ ++;; Note a problem with this flexibility. In some contexts we need to format ++;; special characters and in others we don't. Thus in LaTeX, in a Verbatim ++;; we don't need to quote `_', but in running text we do need to quote it. ++ ++(defparameter *comment-environment-mapping-template* ++ (quote `((text "" "") ++ (format ,*begin-format-env* ,*end-format-env*) ++ (verbatim ,*begin-verbatim-env* ,*end-verbatim-env*) ++ (emphasis ,*begin-emphasis-env* ,*end-emphasis-env*) ++ (comment ,*begin-comment-env* ,*end-comment-env*) ++ (section ,*begin-section-env* ,*end-section-env*)))) ++ ++(defparameter *comment-environment-mapping* ++ (eval *comment-environment-mapping-template*)) ++ ++(defparameter *saved-whitespace* nil) ++ ++(defun print-saved-whitespace () ++ (sloop for c in *saved-whitespace* ++ do (if (stringp c) (pprinc c) (pwrite-char c))) ++ (setq *saved-whitespace* nil)) ++ ++(defun wrap-up-copy-comments () ++ ;; MOD - X ++ (end-environment) ++ (print-saved-whitespace) ++ (throw 'copy-comments nil)) ++ ++(defun begin-environment (env) ++ (setq *comment-environment* env) ++ (ppformat ++ (or (cadr (assoc env *comment-environment-mapping*)) ""))) ++ ++(defun end-environment () ++ (if *comment-environment* ++ (ppformat (or (caddr (assoc *comment-environment* ++ *comment-environment-mapping*)) ++ ""))) ++ (setq *comment-environment* nil)) ++ ++(defun end-environment-and-write (c) ++ (end-environment) ++ (pwrite-char c)) ++ ++(defun pop-environment-write-and-push (string) ++ (let ((saved-env *comment-environment*)) ++ (if (not saved-env) ++ (pprinc string) ++ (progn (end-environment) ++ (pprinc string) ++ (begin-environment saved-env))))) ++ ++(defun end-environment-if-not (env) ++ (if (not (equal *comment-environment* env)) ++ (end-environment))) ++ ++(defun white-space-string-p (s) ++ (let ((x t)) ++ (sloop for i from 0 to (- (length s) 1) ++ do (setq x (and x (member (char s i) *white-space*)))) ++ x)) ++ ++(defun insert-newpage () ++ (pop-environment-write-and-push (pformat nil "~%~a~%" *newpage*))) ++ ++;; (defparameter *format-tag-char* #\~) ++ ++(defun check-environment-and-write (env ch) ++ ++ ;; Note: Latex causes an error on an empty VERBATIM environment, so we watch out ++ ;; for that as a special case. Also, Latex forbids control-l in a verbatim ++ ;; environment, so we watch out for that, too. ++ ++ ;; Thus, we forbid any empty environments, and we always pull a page break ++ ;; out of the current environment. ++ ++ ;; First, end an existing environment if it is not ENV. ++ ++ (end-environment-if-not env) ++ ++ (cond ((not *comment-environment*) ; We are in no environment. Enter one. ++ (cond ((and ch (not (member ch *white-space*))) ++ ;; Assuming *saved-whitespace* can't intersect ++ ;; characters handled by (handle-special-chars-in-string ch) ++ (print-saved-whitespace) ++ (begin-environment env)) ++ ++;; Does this work? Printing of saved whitespace complicated by the ++;; verbatim restrictions of latex. I.e., can't have an empty verbatim. ++ ++ ++ ((and ch (eql ch #\Page)) ;; MOD 1/96 (equal env 'verbatim) ++ ;;(setq *saved-whitespace* ++ ;; (append *saved-whitespace* ++ ;; (list (format nil "~%~a~%" *newpage*)))) ++ (ppformat t "~%~a~%" *newpage*)) ++ (ch (setq *saved-whitespace* ++ (append *saved-whitespace* (list ch))))))) ++ ;; Tabs ++ (cond ((and (equal env 'verbatim) ++ (eql ch #\Tab) ++ (not *reported-tabs*)) ++ (setq *reported-tabs* t) ++ (pformat *terminal-io* ++ "WARNING: about tabs!~%We note the presence of a tab ~ ++ in a comment that we are copying~%into a verbatim ~ ++ environment. Tabs will be treated just like ~%single spaces ~ ++ by Latex. Consider removing all tabs, e.g., ~%with the ~ ++ Emacs command M-x untabify.~%"))) ++ ++ ;; Print it or not, checking #\Page. ++ (cond (*saved-whitespace*) ++ ((and (eql ch #\Page) (equal env 'verbatim)) ++ (end-environment) ++ (ppformat "~%~a~%" *newpage*) ++ (begin-environment env)) ++ ++ (ch ++ ;; Switched (pwrite-char ch) ++ (handle-special-chars-in-string ch)))) ++ ++(defun unread-chars (l stream) ++ (sloop for c in l do (unread-char c stream))) ++ ++(defun read-char-in-comment () ++ (let ((c (read-char *standard-input* nil a-very-rare-cons))) ++ (cond ((eq c a-very-rare-cons) ++ ;; EOF. We are no longer in a comment. ++ ;; Exit whatever environment we are in, which will be either ++ ;; verbatim, format, or none. ++ (wrap-up-copy-comments)) ++ (t c)))) ++ ++(defun copy-comments-read-net (net) ++ ;; Returns (env char), where env is the environment to ++ ;; enter and char is nil or a char to unread. ++ ;; Net is cdr of a net whose car = #\; ++ ;; Have already read a #\; ++ ;; ++ ;; Test (progn (read-char)(COPY-COMMENTS-READ-NET *comment-semi-net*)) ++ ;; ++ (let* ((subnet (car net)) ++ (action (cadr net)) ++ ;; on EOF does a throw out once it cleans up. ++ (c (read-char-in-comment)) ++ (branch (assoc c subnet))) ++ (cond ((null branch) ++ (unread-char c *standard-input*) ++ (list (car action) (cadr action))) ++ (t (copy-comments-read-net (cdr branch)))))) ++ ++(defvar number-deep nil "Measure of depth of imbedding in \#\| \|\# comments") ++ ++(defun normalize-lb-comment-line (str action) ++ (let ((beg (search "#|" str)) ++ (end (search "|#" str))) ++ (cond ((and beg end) ++ (cond ((< beg end) ++ (normalize-lb-comment-line ++ (concatenate 'string ++ (subseq str 0 beg) ++ (subseq str (+ beg 2) end) ++ (subseq str (+ end 2))) ++ action)) ++ (t (format-comment-string (subseq str 0 end) action) ++ (decf number-deep 1) ++ (cond ((= number-deep 0) ++ (end-environment) ++ (unread-chars (coerce (subseq str (+ end 2)) 'list) ++ str)) ++ (t (normalize-lb-comment-line (read-line *standard-input*) action)))))) ++ (beg (incf number-deep 1) ++ (format-comment-string (subseq str 0 beg) action) ++ (normalize-lb-comment-line (subseq str (+ beg 2)) action)) ++ (end (format-comment-string (subseq str 0 end) action) ++ (decf number-deep 1) ++ (cond ((= number-deep 0) ++ (end-environment) ++ (subseq str (+ end 2))) ++ (t (normalize-lb-comment-line (subseq str (+ end 2)) action)))) ++ (t (format-comment-string str action) ++ (normalize-lb-comment-line (read-line *standard-input*) action))))) ++ ++(defun format-comment-string (line mode) ++ (if (and *acl2-format-comments* (search "~" line)) ++ (let ((pair (acl2-parse-string line))) ++ (if (car pair) ;failed ++ nil ++ (setq line (cdr pair))))) ++ (let ((max (- (length line) 1))) ++ (sloop for i from 0 to max ++ do (let ((ch (aref line i))) ++ (cond ((eql ch #\Page) (insert-newpage)) ++ ;; switched (pwrite-char ch) ++ (*comment-environment* (handle-special-chars-in-string ch)) ++ (t (check-environment-and-write mode ch))))) ++ (if (> max 0) ++ (if (not (char-equal (aref line max) #\Newline)) ++ (pwrite-char #\Newline) ++ nil) ++ (pwrite-char #\Newline)) ++ nil)) ++ ++(defun copy-comments () ++ ++; This function tries to sneak up to the next top-level open parenthesis, ++; parsing all of the Lisp comments up till there. ++; NOTE: Jul 13 93 MKS ++; Random atoms, numbers, strings and characters are treated as if they were in ++; comments. And are printed in a FORMAT environment. ++; NOTE: Nov 30 94 MKS ++; This sneaking up doesn't work quite the way we would like. If we have ++; a comment line, followed by a blank line, followed by (foo ..) then we ++; put out the formatted comment line, followed by a blank line, followed ++; by a close-environment, followed by the formatted (foo ..). ++ ++ (let (*comment-environment*) ++ (catch 'copy-comments ++ (sloop ++ for ch = (read-char-in-comment) ++ ++; The top level loop for simulating the skimming of whitespace and comments ++; that READ would perform to get to the next open parenthesis. ++ ++ (case ch ++ ++; Semicolon starts a comment. ++; We use *COMMENT-SEMI-NET* to determine how to format the comment based on the ++; immediately following characters. This is user-setable to produce ++; running text, a format environment (honors spaces and newlines, but probably ++; does not produce a fixed width font), a verbatim environment (like format, but ++; fixed width font), an emphasis environment (typically italics), or a title ++; environment (like a section name). ++ ++ (#\; ++ ;; Do one line. ++ (let ((action (copy-comments-read-net *comment-semi-net*))) ++ (check-environment-and-write (car action) (cadr action)) ++ (format-comment-string (read-line *standard-input*) (car action)))) ++ ++; #\| starts a comment. ++; As above, we use the *comment-lb-net* to determine what formatting action to take. ++; \|# ends one. ++ ++ (#\# ++ (setq ch (read-char-in-comment)) ++ (cond ((not (eql ch #\|)) ++ (error"Do not know how to handle #~s while copying at the top level." ch))) ++ (let ((action (copy-comments-read-net *comment-lb-net*))) ++ ++ ;; The following may not put us into an env if (cadr ++ ;; action) is whitespace. ++ ++ (check-environment-and-write (car action) (cadr action)) ++ ++ ;; We ignore formatting changes within imbedded #| |# comments. ++ ;; They are stuck with whatever the outermost comment ++ ;; decreed. ++ ++ (setq number-deep 1) ++ (let* ((line (read-line *standard-input*)) ++ (rest (normalize-lb-comment-line line (car action)))) ++ (cond ((and rest (not (string-equal rest ""))) ++ ;; Sep 22 95 MKS reversed order of the 2 forms below. ++ ;; Wrap-up throws out of copy-comments. ++ (unread-chars (nreverse (coerce rest 'list)) ++ *standard-input*) ++ (wrap-up-copy-comments)))))) ++ ++ ;; A raw ^L at the top level, not in a comment. ++ (#\Page (end-environment) ++ (ppformat "~%~a~%" *newpage*)) ++ ++ (#\Newline ++ (end-environment) ++ (print-saved-whitespace) ++ (pwrite-char ch)) ++ (#\( ++ (unread-char #\( *standard-input*) ++ (wrap-up-copy-comments)) ++ ;; Handle keywords like parenthesized forms, because they may ++ ;; need to read their arguments. ++ (#\: ++ (unread-char #\: *standard-input*) ++ (wrap-up-copy-comments)) ++ (otherwise ;; switched (pwrite-char ch) ++ ;; MOD - Sep 21 95 MKS ++ ;; Added the following: ++ (print-saved-whitespace) ++ (handle-special-chars-in-string ch) ++ )))))) ++ ++ ++;;-------------------------------------------------------------------------------- ++; ++; COMMENT FORMATS ++; ++ ++(defparameter *comment-format-alist* nil) ++(defparameter *comment-format* nil) ++ ++(defun update-alist (al key value) ++ (cond ((not (consp al)) (list (cons key key value))) ++ ((eq key (caar al)) (cons (cons key value) (cdr al))) ++ (t (cons (car al) (update-alist (cdr al) key value))))) ++ ++(defun define-comment-format (n format) ++ ;; Last call to this sets *comment-format*. ++ ;; Can be overruled by ++ ;; 1. assigning directly to *comment-format*, ++ ;; 2. calling (setup-comment-format format-name), or ++ ;; 3. calling infix-setup with the appropriate arguments. ++ (if (not (check-comment-character-net format)) ++ (format *terminal-io* "~%Ill formed definition for comment format ~a" n) ++ (progn ++ (setq *comment-format* n) ++ (cond ((assoc n *comment-format-alist*) ++ (setq *comment-format-alist* (update-alist *comment-format-alist* n format))) ++ (t (setq *comment-format-alist* ++ (cons (cons n format) *comment-format-alist*))))))) ++ ++(defun setup-comment-format (&optional n) ++ (cond ((and n (assoc n *comment-format-alist*)) ++ ;; A named format. ++ (setq *comment-format* n)) ++ ((and n *comment-format*) ++ ;; Not defined. Use existing setting. ++ (format *terminal-io* ++ "~%No comment format named ~a. Left as ~a." n *comment-format*)) ++ (n (setq *comment-format* 'smith) ++ (format *terminal-io* ++ "~%No comment format named ~a. Defaluting to ~a." n *comment-format*)) ++ ((null *comment-format*) ++ (cond ((eq *infix-op-location* 'FRONT) ++ (setq *comment-format* 'smith)) ++ ((eq *infix-op-location* 'BACK) ++ (setq *comment-format* 'boyer)) ++ (t (setq *comment-format* 'smith)))) ++ ((assoc *comment-format* *comment-format-alist*)) ++ (*comment-format-alist* ++ (setq *comment-format* (caar *comment-format-alist*)) ++ (format *terminal-io* "~%Defaluting to first format in alist, ~a." *comment-format*)) ++ (t ;; Should never get here. ++ (format *terminal-io* "~%*** No comment formats defined!!! ***"))) ++ (compute-comment-character-net *comment-format*) ++ ;; We have side-effected *comment-semi-net* and *comment-lb-net* ++ ;; Update mapping info AFTER users theory file loaded. ++ (setq *comment-environment-mapping* (eval *comment-environment-mapping-template*))) ++ ++(defun check-comment-character-net (l) ++ (if (null l) ++ (format *terminal-io* "*COMMENT-FORMAT* is not present in *COMMENT-FORMAT-ALIST*.")) ++ (if (not (assoc #\; l)) ++ (format *terminal-io* "Selected comment format should include a list labelled \"\;\".")) ++ (if (not (assoc #\# l)) ++ (format *terminal-io* "Selected comment format should include a list labelled \"\#\".")) ++ ;; Each branch is of the form (string flag environment [echo-character]) ++ (check-comment-character-net2 l)) ++ ++(defun check-comment-character-net2 (l) ++ (cond ((null l) t) ++ ((and (listp l) ++ (listp (car l)) ++ (characterp (caar l)) ++ (every ++ (function ++ (lambda (branch) ++ (if (check-comment-character-branch branch) ++ t ++ (format *terminal-io* "Ill-formed branch in *COMMENT-FORMAT-ALIST*.~ ++ ~%~a" branch)))) ++ (cadr (car l))) ++ (let ((top (cddr (car l)))) ++ (and (or (equal (car top) 't) (null (car top))) ++ ;; Must be known environment. ++ (assoc (cadr top) *comment-environment-mapping*) ++ (or (null (cddr top)) (characterp (caddr top)))))) ++ ;; Do the other one, if there. ++ (check-comment-character-net2 (cdr l))) ++ (t nil))) ++ ++(defun check-comment-character-branch (b) ++ (and (listp b) ++ (> (length b) 2) ++ (stringp (car b)) ++ (or (equal (cadr b) 't) (null (cadr b))) ++ ;; Must be known environment. ++ (assoc (caddr b) *comment-environment-mapping*) ++ (or (null (cdddr b)) ++ (characterp (cadddr b))))) ++ ++(defun compute-comment-character-net (name) ++ (let ((l (cdr (assoc name *comment-format-alist*)))) ++ (let ((net (assoc #\; l))) ++ (setq *comment-semi-net* ++ (if net ++ (cdr (compute-net -1 (car net) (cadr net) (caddr net) (cdddr net))) ++ nil))) ++ (let ((net (assoc #\# l))) ++ (setq *comment-lb-net* ++ (if net ++ (cdr (compute-net -1 (car net) (cadr net) (caddr net) (cdddr net))) ++ nil))))) ++ ++(defun compute-net (n char net skip-one-blank-p default) ++ (list char ++ (append (if skip-one-blank-p ++ `((#\ nil ,default)) ++ nil) ++ (compute-branches (+ n 1) net)) ++ default)) ++ ++(defun compute-branches (n net) ++ (cond ((null net) nil) ++ (t (merge-net (compute-branch n (car net)) ++ (compute-branches n (cdr net)))))) ++ ++(defun compute-branch (n branch) ++ ;; branch is of the form (string flag . default) ++ (let ((string (car branch)) ++ (flag (cadr branch)) ++ (default (cddr branch))) ++ (cond ((> n (length string)) nil) ++ ((= n (length string)) ++ (if flag ++ `(#\ nil ,default) ++ nil)) ++ (t (append (list (char string n) ++ (list (compute-branch (+ n 1) branch))) ++ (if (= (+ n 1) (length string)) (list default) nil)))))) ++ ++(defun merge-net (branch net) ++ ;; All branches of net begin with a unique character. ++ ;; As does the result. ++ (cond ((null net) (list branch)) ++ ((char= (car branch) (caar net)) ++ (let ((def1 (caddr branch)) ++ (def2 (caddr (car net)))) ++ (cons ++ (list (car branch) ++ (merge-net (caadr branch) (cadr (car net))) ++ (cond ((equal def1 def2) def1) ++ ((and def1 def2) ++ (format *terminal-io* ++ "Your comment network is in conflict ~a ~a." branch (car net)) ++ def1) ++ (def1 def1) ++ (t def2))) ++ (cdr net)))) ++ (t (cons (car net) (merge-net branch (cdr net)))))) ++ ++(define-comment-format 'boyer ++ '((#\; (("\\" t text)) ++ nil verbatim #\;) ++ (#\# (("\\" t text)) ++ nil verbatim))) ++ ++(define-comment-format 'smith ++ '((#\; (("\;" t text ) ++ ("\#" t comment ) ++ ("\;\;" t verbatim ) ++ ("\\" t text ) ++ ("-" t format ) ++ ("+" t verbatim ) ++ ("!" t emphasis ) ++ ("\;\\" nil text #\;) ++ ("\;-" nil format #\;) ++ ("\;+" nil verbatim #\;) ++ ("\;!" nil emphasis #\;)) ++ t text) ++ (#\# (("\\" t text ) ++ ("\#" t comment ) ++ ("-" t format ) ++ ("\;" t verbatim )) ++ t text ))) ++ ++ ++(define-comment-format 'CL ++ '((#\; (("\;" t format ) ++ ("\;\;" t text ) ++ ("\;\;\;" t section) ++ ++ ("\\" t text ) ++ ("-" t format ) ++ ("+" t verbatim ) ++ ("!" t emphasis ) ++ ("\;\\" nil text #\;) ++ ("\;-" nil format #\;) ++ ("\;+" nil verbatim #\;) ++ ("\;!" nil emphasis #\;)) ++ t emphasis) ++ (#\# (("\\" t text ) ++ ("-" t format ) ++ ("\;" t verbatim )) ++ t text ))) ++ ++(setup-comment-format 'cl) ++ ++;; End of comment stuff. ++ ++(defun infix-form (form &key ((:print-case *print-case*) :downcase)) ++ ;; We cannot recover well from this case since we don't ++ ;; know where we are. All of the I/O that provides that info ++ ;; is in the top level loop. So these inner forms are just out of luck. ++ (let ((*top-parens-eliminable* t) ++ (*print-pretty* nil) ++ ;; (*saved-tab-stack* *tab-stack*) ++ ) ++ ;; (cond ((catch 'taboverflow ++ ;; (let ((*tabs-in* 1)) ++ ;; (or *do-not-use-tabs* (begin-tabbing)) ++ ;; (infix-print-term1 form) ++ ;; (or *do-not-use-tabs* (end-tabbing)) ++ ;; nil)) ++ ;; (pformat *terminal-io* ++ ;; "~%Sorry. Exceeded tabbing limit (1). ~a needs hand massaging.~%" ++ ;; (car form)) ++ ;; (setq *tab-stack* *saved-tab-stack*) ++ ;; (newline))) ++ (let ((*tabs-in* 1)) ++ (or *do-not-use-tabs* (begin-tabbing)) ++ (infix-print-term1 form) ++ (or *do-not-use-tabs* (end-tabbing)) ++ nil))) ++ ++(defun infix-event (form &key ((:print-case *print-case*) :downcase)) ++ ;; We cannot recover well from this case since we don't ++ ;; know where we are. All of the I/O that provides that info ++ ;; is in the top level loop. So these inner forms are just out of luck. ++ (let ((*top-parens-eliminable* t) ++ (*print-pretty* nil)) ++ ;; (cond ((catch 'taboverflow ++ ;; (let ((*tabs-in* 1)) ++ ;; (funcall (get-event-printer (car form)) form) ++ ;; nil)) ++ ;; (pformat *terminal-io* ++ ;; "~%Sorry. Exceeded tabbing limit (2). ~a needs hand massaging.~%" ++ ;; (car form)) ++ ;; (newline))) ++ (let ((*tabs-in* 1)) ++ (funcall (get-event-printer (car form)) form) ++ nil))) ++ ++(defparameter *last-mode* nil) ++ ++(defparameter *infix-trace* nil) ++ ++(defun current-directory () ++ ;; This is somewhat redundant. ++ ;; That is (probe-file file) should equal ++ ;; (probe-file (concatenate 'string (current-directory) file)) ++ ;; But we let *current-directory* also be set by the input file. ++ (truename "./")) ++ ++;; This may be set by the function above or based on the directory of the input file. ++(defparameter *current-directory* nil) ++ ++(defun probe-theory (fl) ++ (let ((name (concatenate 'string (pathname-name fl) "-theory"))) ++ (or (probe-file (make-pathname :name name ++ :type "lisp" :defaults fl)) ++ (probe-file (make-pathname :name name ++ :type "lisp" ++ :directory (pathname-directory *current-directory*) ++ :defaults fl)) ++ (probe-file (make-pathname :name name ++ :type "lisp" ++ :directory (pathname-directory *infix-directory*) ++ :defaults fl))))) ++ ++;; Check that *infix-directory* we can find at least a latex and scribe theory. ++(eval-when (load eval) ++ (if (not (and (probe-theory "scribe") (probe-theory "latex"))) ++ (format *terminal-io* "~%Seem to be missing theory of scribe or latex or both.~%"))) ++ ++(defun type-file-name (file type &optional force) ++ ;;if extension = nil, return file. ++ ;;if file already has type and force = nil, return file. ++ (cond ((null type) file) ++ ((and (not force) (pathname-type file)) file) ++ (t (make-pathname :type type :defaults file)))) ++ ++(defvar *default-chars-wide* 77) ++ ++(defun directory-or-current (fl) ++ (let ((dir (directory-namestring fl))) ++ (cond ((null dir) (current-directory)) ++ ((not (equal dir "")) dir) ++ (t (current-directory))))) ++ ++(defun probe-cert-for-packages (fl) ++ (let ((cert (probe-file (make-pathname :type "cert" :defaults fl))) ++ doit) ++ (if cert ++ (progn ++ (format t "Checking ~s for defpackage forms.~%" cert) ++ (with-open-file ++ (*standard-input* cert :direction :input) ++ (sloop for form = (read *standard-input* nil a-very-rare-cons nil) ++ until (or (eq form a-very-rare-cons) ++ (eq form :end-portcullis-cmds)) ++ do ++ (cond ((eq form :begin-portcullis-cmds) ++ (setq doit t)) ++ ((and doit (consp form) (eq (car form) 'defpkg)) ++ (if (not (find-package (cadr form))) ++ (make-package (cadr form)))) ++ (t nil)))))))) ++ ++(defun infix-file (fl &key ((:print-case *print-case*) :downcase) ++ (mode nil) ++ (chars-wide *default-chars-wide*) ++ (comment *nq-default*)) ++ ++ (let ((*current-directory* (directory-or-current fl)) ++ (fl-root (pathname-name fl)) ++ *tab-stack*) ++ (cond ((and mode (string= mode *infix-mode*)) ++ (format t "~%Processing in ~a mode.~%" mode)) ++ ((stringp mode) ++ (setq *infix-mode* mode) ++ (format t "~%Entering ~a mode.~%" *infix-mode*) ++ (load-infix-init-file)) ++ (mode ++ (setq *infix-mode* (string mode)) ++ (format t "~%Entering ~a mode.~%" *infix-mode*) ++ (load-infix-init-file)) ++ ((probe-theory fl-root) ++ (setq *infix-mode* (pathname-name fl-root)) ++ (format t "~%Entering ~a mode.~%" *infix-mode*) ++ (load-infix-init-file)) ++ ((null *infix-mode*) ++ (cond ((y-or-n-p "Enter Latex mode? ") ++ (setq *infix-mode* "latex")) ++ ((y-or-n-p "Enter Scribe mode? ") ++ (setq *infix-mode* "scribe")) ++ (t (setq *infix-mode* nil))) ++ (if *infix-mode* ++ (progn (format t "~%Entering ~a mode.~%" *infix-mode*) ++ (load-infix-init-file)))) ++ (t (format t "~%Remaining in ~a mode.~%" *infix-mode*))) ++ ++; infix-file takes a root file name, e.g., foo, reads the file foo.lisp, ++; which we suppose has been previously checked by LD, and creates the ++; file foo.tex, which the user can then run through Latex, etc. By default, we ++; lowercase all variable and function symbols, but the user can override this ++; with the keyword parameter. ++ ++; If the keyword comment is given as true, then we first generate fl.nqxxx and then ++; invoke nqfmt2fmt, generating fl.xxx (.tex or .mss). ++ ++ ;; Update comment information AFTER users theory file loaded. ++ (setup-comment-format) ++ ++ (if *infix-mode* ++ (let ((infl (type-file-name fl infix-input-file-type)) ; ".lisp" ++ ;; .mss, .tex, .nqmss, .nqtex ++ (outfl (type-file-name fl (fmtfile-extension *infix-mode* comment) t)) ++ (a-very-rare-cons (cons nil nil)) ++ (*print-pretty* nil) ++ (*top-parens-eliminable* t) ++ (*readtable* (copy-readtable nil)) ++ (*reported-tabs* nil) ++ (*infix-loc* 0) ++ (*left-margin* 0) ++ (*rightmost-char-number* chars-wide) ++ (count 1) ++ inpos) ++ (probe-cert-for-packages fl) ++ (smash-infix-readtable) ++ ++ (with-open-file ++ (*standard-input* infl :direction :input) ++ (with-open-file ++ ++; We do *all* of our printing of terms to *standard-output*, giving princ only ++; one argument. ++ ++ (*standard-output* outfl :direction :output :if-exists :rename-and-delete) ++ ++; The formatting system opening. ++ ++ (ppformat *standard-prelude*) ++ (sloop for form = (progn (copy-comments) ++ ;; Set this here so we don't rewrite preceding comment, ++ ;; if tabs overflow. ++ (setq inpos (file-position *standard-input*)) ++ (readx *standard-input* nil a-very-rare-cons nil)) ++ ++; We remember where we are in the output file as part of our mechanism for ++; recovering from the very small finiteness of the Latex tabbing mechanism. We ++; will rewrite to the current position and start printing in verbatim mode with ++; PPR if we exceed the Latex tabbing mechanism. ++ ++ for outpos = (file-position *standard-output*) ++ until (eq form a-very-rare-cons) ++ do ++ ; (ppformat "\\filbreak %\\item~%") ++ (cond ((or (eq (car form) 'comment) ++ (cond ((catch 'taboverflow ++ (let ((*tabs-in* 1)) ++ (if *infix-trace* ++ (format *terminal-io* "~% ~a " (car form))) ++ ;; Let the user know we are making some ++ ;; kind of progress, every 10 events. ++ (if (= count 10) ++ (progn (format *terminal-io* ".") ++ (setq count 1)) ++ (incf count)) ++ (funcall (get-event-printer (car form)) form)) ++ nil) ++ (pformat *terminal-io* ++ "~%Warning: Tab limit reached in event ~a~ ++ ~%Hand massaging required.~%" ++ (or (and (consp form) (cdr form) (cadr form)) ++ (car form))) ++ t))) ++ ;; If taboverflow, go back to where we started printing and ++ ;; print over the previous stuff. In the 'commment case our ++ ;; position is unchanged. ++ (file-position *standard-output* outpos) ++ (setq *tab-stack* nil) ++ (begin-environment 'verbatim) ++ (let ((stop (file-position *standard-input*))) ++ (file-position *standard-input* inpos) ++ (sloop while (< (file-position *standard-input*) stop) ++ do (check-environment-and-write 'verbatim ++ (read-char *standard-input*)))) ++ (end-environment)) ++ (t nil))) ++ (ppformat *standard-postlude*))) ++ (if comment ++ (nqfmt2fmt fl) ++ outfl)) ++ (format t "~%No mode specified (e.g. Latex or Scribe), aborting.~%")))) ++ ++(defun load-obj-or-lisp (file) ++ (let ((object (make-pathname :type "o" :defaults file))) ++ (cond ((and (probe-file object) ++ (> (file-write-date object) (file-write-date file))) ++ (load object)) ++ ((probe-file file) (load file)) ++ (t (error (format nil "~%No theory or init file mathcing ~f~%" file)))))) ++ ++;; (defun load-obj-or-lisp (file) ++;; (let* ((name2 (if (member 'sparc *features*) ++;; (concatenate 'string (pathname-name file) "-sparc") ++;; (concatenate 'string (pathname-name file) "-sun"))) ++;; (file2 (probe-file (make-pathname :name name2 :defaults file))) ++;; (object (probe-file (make-pathname :type "o" :defaults file))) ++;; (object2 (if file2 (probe-file (make-pathname :type "o" :defaults file2))))) ++;; (cond ((and object2 (> (file-write-date object2) (file-write-date file2))) ++;; (load object2)) ++;; (file2 (load file2)) ++;; ((and object (> (file-write-date object) (file-write-date file))) ++;; (load object)) ++;; ((probe-file file) (load file)) ++;; (t (error (format nil "~%No theory or init file mathcing ~f~%" file)))))) ++ ++(defun load-theory-or-init (dir) ++ (let* ((initfile (make-pathname :name (concatenate 'string *infix-mode* "-init") ++ :type "lisp" ++ :directory (pathname-directory dir))) ++ (theoryfile (make-pathname :name (concatenate 'string *infix-mode* "-theory") ++ :type "lisp" ++ :directory (pathname-directory dir)))) ++ ;; We assume that, if present, the -theory file loads the -init file. ++ (cond ((probe-file theoryfile) (load-obj-or-lisp theoryfile) t) ++ ((probe-file initfile) (load-obj-or-lisp initfile) t) ++ (t nil)))) ++ ++(defun load-infix-init-file () ++ (clean-up-everything) ++ (cond ((null *infix-mode*) ++ (format t "~%Failed to initialize. *infix-mode* is NIL.~%")) ++ ((not (stringp *infix-mode*)) ++ (format t "~%Failed to initialize.~ ++ ~%*infix-mode* (~a) is not a string.~%" *infix-mode*)) ++ ((load-theory-or-init *current-directory*)) ++ ((load-theory-or-init *infix-directory*)) ++ (t (format t "~%Failed to initialize. No init or theory file in ~a nor ~a.~%" ++ *current-directory* *infix-directory*) ++ (setq *infix-mode* nil)))) ++ ++(defun fmtfile-extension (mode comment) ++ (cond ((and *mode-extension* (stringp *mode-extension*)) ++ (if comment (concatenate 'string "nq" *mode-extension*) *mode-extension*)) ++ ((string= mode "latex") ++ (if comment "nqtex" "tex")) ++ ((string= mode "scribe") ++ (if comment "nqmss" "mss")) ++ (t (if comment "nqnq" "nq")))) ++ ++(defun fmt2fmt-extension (remove! mode) ++ (cond (remove! "stripped") ++ ((and *mode-extension* (stringp *mode-extension*)) ++ (concatenate 'string "nq" *mode-extension*)) ++ ((string= mode "latex") "nqtex") ++ ((string= mode "scribe") "nqmss") ++ (t "nqnq"))) ++ ++(defvar nqread-default-white-space '(#\Space #\Newline #\Tab #\Page #\Return)) ++(defvar nqread-default-normal-clause-enders '(#\. #\! #\? #\, #\; #\:)) ++(defvar nqread-default-break-chars '(#\( #\) #\` #\' #\" #\; #\,)) ++ ++(defparameter nqread-white-space nqread-default-white-space) ++(defparameter nqread-normal-clause-enders nqread-default-normal-clause-enders) ++(defparameter nqread-break-chars nqread-default-break-chars) ++ ++(defun acl2-read-preserving-whitespace-error () ++ (error "A character or an integer or an Acl2 symbol was expected at location ~a of input." ++ (file-position *standard-input*))) ++ ++(defun acl2-read-preserving-whitespace () ++ ++; This function does the READing right after a ! command. This ++; function is almost the same as read-preserving-whitespace. It is ++; different only because of the peculiar problem of trailing ++; punctuation marks. We sometimes stop the reading before Common Lisp ++; would. ++ ++; In processing ! commands, we call READ on the following text. If ++; the text starts with an open parenthesis or string-quote, it is ++; clear where the READing should stop. However, if a mere symbol or ++; number follows a ! command, then when READing the symbol we treat ++; an exclamation mark, colon, question mark, or period that is ++; followed by whitespace as a punctuation mark, not as part of the ++; symbol that is to be READ. The other ordinary English clause ending ++; punctuation characters (comma and semicolon) already naturally ++; terminate a READ, as do parentheses, quotation marks, and ++; whitespace. ++ ++; Example. When we do a READ while processing a ! command under ++; nqtex2tex, we have to decide what to do about text such as ++ ++; !tnil. ++ ++; The question is, does the period belong to the token to be read, or ++; is it just some user punctuation? We take the attitude that the ++; answer is punctuation. Now, this attitude is a bit arbitrary. nil. ++; is a legal Common Lisp symbol. Unfortunately it is ALSO a legal Acl2 symbol. ++; But we are just going to assume that it is atypical. And likewise for ++; `foo.bar'. We also run into problems reading things like ++; xxx.@end{text}@begin{format}@tabclear{}. This is a fine atom as far as ++; ACL2 is concerned. Likewise ++; xxx.\begin{verbatim}\hfill ++; So the text-formatting -init file will need to extend nqread-normal-clause-enders ++; to account for this. ++ ++; One might ask, who cares? The reason we care is that nil, and other ++; symbols on *atom-alist*, get printed specially. For example, nil is ++; printed in bold, not italics. If we read nil. as one symbol, it would ++; come out in intalics because nil. is not on *atom-alist*. ++ ++; The idea of fiddling with READ so that it is `smart' about not ++; reading a trailing punctuation character is weird. But then, ++; calling READ in the middle of Tex file is weird, too. We have found from ++; experience that it is very hard to write sentences that have ++; whitespace after every symbol. We want to be able to write things ++; like !tnil, and !tnil. So here is the general procedure for how far ++; we READ after a ! command. When we say READ below, we really mean ++; read-preserving-whitespace. ++ ++; We peek at the first nonwhitespace character after the ! command, ++; and we consider the cases on this character. ++ ++; If it is ( or " we simply call READ, knowing that upon encountering ++; the closing " or ) READ will not look at any trailing punctuation. ++ ++; If it is ' or ` we recursively read further with this function and ++; then quote or backquote the result. This is so that `foo. will come ++; out right. ++ ++; Otherwise, we call READ on the string consisting of all of the ++; characters up to but not including the first (a) whitespace, (b) ++; terminating readmacro Common Lisp character, i.e., ()`'"";,, or (c) ++; normal English clause ending character, i.e., .!?:, that is followed ++; by a whitespace. ++ ++; Known ambiguity. Although periods are permitted at the ends of ++; numbers in Acl2 syntax, we treat them as ends of sentences, if they ++; are followed by white space. Thus in reading !t5. , the read ++; would not pick up the period. So the period would appear in the ++; final text. It is hard to see whether this is a bug, a feature, or ++; a problem that simply never arises. ++ ++; Known ambiguity. Because the quotation mark is a legal character ++; in Acl2 symbols, a minor question arises about the handling of ++; a terminal question mark in an Acl2 symbol; we treat it as punctuation. ++; Thus !qfoo? will come out as `foo'? rather than `foo?'. ++ ++; All this peeking stuff doesn't work really correctly if there are ++; comments in the way, so we adopt this rule: don't put comments in ++; expressions after ! commands. Typically, this function is called ++; inside of a comment. If the text to be read extends over a line and ++; the next line begins with a ; character, you may not get at all what ++; you want because the text on the line after the ; will be skipped. ++ ++ (case (peek-char t *standard-input*) ++ ((#\( #\") (read-preserving-whitespace *standard-input*)) ++ (#\' ++ (read-char *standard-input*) ++ (list 'quote (acl2-read-preserving-whitespace))) ++ (#\` ++ (read-char *standard-input*) ++ (list *infix-backquote* (acl2-read-preserving-whitespace))) ++ (otherwise ++ (let ((*package* *user-package*)) ++ (read-from-string ++ (coerce ++ (nconc ++ (prog (c ans c2) ++ loop ++ (setq c (peek-char nil *standard-input* nil a-very-rare-cons)) ++ (cond ((or (eq c a-very-rare-cons) ++ (member c nqread-white-space) ++ (member c nqread-break-chars)) ++ (cond ((null ans) ++ (acl2-read-preserving-whitespace-error))) ++ (return (nreverse ans))) ++ ((member c nqread-normal-clause-enders) ++ (read-char *standard-input*) ++ (setq c2 (peek-char nil *standard-input* nil a-very-rare-cons)) ++ (cond ((or (member c2 nqread-white-space) ++ (eq c2 a-very-rare-cons)) ++ (unread-char c *standard-input*) ++ (cond ((null ans) ++ (acl2-read-preserving-whitespace-error))) ++ (return (nreverse ans))) ++ (t (push c ans)))) ++ ((member c '(#\| #\; #\\)) ++ (acl2-read-preserving-whitespace-error)) ++ (t (read-char *standard-input*) ++ (push c ans))) ++ (go loop)) ++ ++; Sticking on this extra space is not strictly necessary. We do it to ++; work around a bug in AKCL 1-605. ++ ++ (list #\Space)) ++ 'string)))))) ++ ++(defparameter nqtex2tex-chars ++ (coerce "eipqtv" 'list)) ++ ++; NQFMT2FMT ++ ++(defun nqfmt2fmt (fl &key ++ ((:print-case *print-case*) :downcase) ++ ((:left-margin *left-margin*) 5) ++ (just-remove-! nil)) ++ ++; Copies the file fl.nqxxx file to the file fl.xxx file, replacing Acl2 forms ++; preceded by a two character sequence starting with an exclamation mark with ++; the results described below. If an exclamation mark is not followed by one ++; of these special characters, then the following form is preserved unchanged, ++; and the exclamation mark and the character following it are preserved, too. ++ ++; Although we may extend this set of replacement commands, we *promise* to give ++; special meanings only to alphabetic characters after !. Thus we promise ++; never to give !! a replacement effect. ++ ++; In every case, for one of the replacement characters, upper or lower case has ++; the same effect. ++ ++; !Bform, prints form in bold. ++ ++; !Eev, where ev is an Acl2 event form, e.g., (defun foo (x) 3), results in ++; conventional notation for ev. We may introduce line breaks via tabbing commands. ++; Mnemonic: E -- think Event. ++ ++; !Ifoo, where foo is a symbol, results in foo, but with with formatting sensitive ++; characters quoted. For example, in TeX, !Ia$b would result in a\$b. ++; Mnemonic: I -- think Identity. ++ ++; !Pfm, where fm is an Acl2 term, e.g., (plus x y), results in conventional ++; mathematical notation for fm. May introduce line breaks via tabbing. ++; Mnemonic: P -- think Pretty print. ++ ++; !Qfn, where fn is a symbol, results in fn surrounded by single gritches, ++; after formatting sensitive characters have been quoted, e.g., !qfoo results in ++; `foo' in TeX. Useful for distinguishing function symbols from other words in a ++; sentence, since function symbols appear in Roman. ++; Mnemonic: Q -- think Quoted. ++ ++; !Tfm, where fm is an Acl2 term, results in conventional mathematical ++; notation for fm, but without any line breaks. ++; Mnemonic: T -- think Term. ++ ++; !Vfoo means that foo is printed as is, but in typewriter font, and with ++; special characters quoted. ++; Mnemonic: V -- think Verbatim. ++ ++; ! followed by anything else is left alone, along with the exclamation mark. ++ ++; One can certainly use nqfmt2fmt on the result of running infix-file, but one ++; must do so deliberately by first running infix-file, then renaming the ++; resulting file, say foo.tex, to be foo.nqtex, and then running nqfmt2fmt. ++; More convenient is to run infix-file with the :comment keyword parameter set to t, ++; which causes infix-file first to generate a .nqtex file and second to run ++; nqfmt2fmt on that file. ++ ++; If the :just-remove-! keyword is t, then a file named root.stripped is ++; created, with all of our special ! commands options removed. ++ ++; Implementation note. In all the cases we treat explicitly, the characters ++; after !? are read with the Lisp function READ-PRESERVING-WHITESPACE, which ++; is just the same as READ except that it doesn't gratuitously consume whitespace ++; at the end of a READ. ++ ++; Warning: Because we use a relative of READ to obtain the forms immediately ++; after the two character exclamation commands, the user must beware that if a ++; form to be read extends for more than a line, and if a semicolon (comment ++; character) is encountered on the next line, say at the beginning, READ will ++; skip that line from the semicolon on, which may not be what the user intends. ++; Thus it can be safer to use the #\| ... \|# construct for comments containing ++; !, especially if one is in the habit of using the Emacs command M-x fill ++; paragraph to rearrange paragraphs that begin with the comment delimiter ++; semicolon. ++ ++ (let ((infl (type-file-name fl (fmt2fmt-extension just-remove-! *infix-mode*) t)) ++ (*print-pretty* nil) ++ (orig-readtable (copy-readtable nil)) ++ (outfl (type-file-name fl (fmtfile-extension *infix-mode* nil) t)) ++ (a-very-rare-cons (cons nil nil)) ++ (count 1) ++ (*readtable* (copy-readtable nil))) ++ (smash-infix-readtable) ++ (with-open-file ++ (*standard-input* infl :direction :input) ++ (with-open-file ++ (*standard-output* outfl :direction :output :if-exists :rename-and-delete) ++ (sloop for c = (read-char *standard-input* nil a-very-rare-cons) ++ (let (form) ++ (cond ((catch 'taboverflow ++ (cond ((eq c a-very-rare-cons) (return-from nqfmt2fmt outfl)) ++ ;; The Latex indexing routines may insert new exclamation points!!! ++ ((eql c #\\) ++ (cond ((skip-index-entries) nil) ++ ;; I am inserting a gigantic hack here because ++ ;; I can't figure out a more principled, simple ++ ;; way to get the effect I want in LaTeX. ++ ;; The problem is that at the end of a tabbing ++ ;; environment we often have two lines of the form: ++ ;; .... \\ ++ ;; \end{tabbing} ++ ;; which causes the event formatted in the tabbing ++ ;; env to appear to be followed by two blank lines ++ ;; rather than one. ++ ((adjust-tabbing-env) nil) ++ (t (pwrite-char c)))) ++ ((eql c #\!) ++ (let ((c (read-char *standard-input* nil a-very-rare-cons))) ++ (cond ((eq c a-very-rare-cons) ++ (pwrite-char #\!) ++ (return-from nqfmt2fmt outfl))) ++ (case c ++ ((#\B #\b) ++ (or just-remove-! ++ (let ((term (acl2-read-preserving-whitespace))) ++ (setq form term) ++ (bold-sym-printer term)))) ++ ((#\C #\c) ++ (or just-remove-! ++ (let ((term (acl2-read-preserving-whitespace))) ++ ;(handler-case ++ (eval term) ++ ;(error () (pwrite-char #\!) ++ ; (pwrite-char c) ++ ; (prin1 term))) ++ ))) ++ ((#\E #\e) ++ (or just-remove-! ++ (let ((term (acl2-read-preserving-whitespace))) ++ (setq form term) ++ (infix-event term)))) ++ ((#\I #\i) ++ (or just-remove-! ++ (let ((term (acl2-read-preserving-whitespace))) ++ (print-atom term)))) ++ ((#\P #\p) ++ (or just-remove-! ++ (let ((term (acl2-read-preserving-whitespace))) ++ (setq form term) ++ (infix-form term)))) ++ ((#\Q #\q) ++ (or just-remove-! ++ (let ((term (acl2-read-preserving-whitespace))) ++ (print-bare-function-name term)))) ++ ((#\S #\s) ++ (or just-remove-! ++ (let ((rest (acl2-read-preserving-whitespace))) ++ (sectionize rest just-remove-!)))) ++ ((#\T #\t) ++ (or just-remove-! ++ (let ((term (acl2-read-preserving-whitespace)) ++ (*do-not-use-tabs* t)) ++ (infix-form term)))) ++ ((#\V #\v) ++ (or just-remove-! ++ (let* ((*readtable* orig-readtable) ++ (term (acl2-read-preserving-whitespace)) ++ (*do-not-use-tabs* t)) ++ (quote-printer1 term)))) ++ ((#\Space #\Tab #\Newline) ++ (pwrite-char #\!) ++ (pwrite-char c)) ++ (otherwise ++ (or just-remove-! ++ (pformat *terminal-io* ++ "Surprising character after ! ~a.~%" c)) ++ (pwrite-char #\!) ++ (pwrite-char c))))) ++ ;; Let the user know we are making some kind ++ ;; of progress, every 60 lines ++ ((eql c #\Newline) ++ (if (= count 60) ++ (progn (format *terminal-io* "-") (setq count 1)) ++ (incf count)) ++ (pwrite-char c)) ++ (t (pwrite-char c))) ++ nil) ++ (pformat *terminal-io* ++ "~%Sorry. Exceeded tabbing limit (2). ++We can't handle this large a form in running text. ~a needs hand massaging.~%" ++ (car form)) ++ (newline)))) ++ ))))) ++ ++(defvar balanced-parens '((#\( . #\)) ++ (#\[ . #\]) ++ (#\{ . #\}))) ++ ++(defun sectionize (rest just-remove-!) ++ ;; sleazy hack to make sections independent of mode (scribe or tex). ++ (let (left right) ++ (setq rest (intern (string-upcase rest))) ++ (cond ((equal rest 'ection) ++ (setq left (read-char *standard-input* nil a-very-rare-cons)) ++ (setq right (cdr (assoc left balanced-parens))) ++ (cond ((null right) (pprinc "section") (pwrite-char left)) ++ (t (pprinc *begin-section-env*) ++ (sloop for c = (read-char *standard-input* nil a-very-rare-cons) ++ until (equal c right) ++ do (pwrite-char c)) ++ (pprinc *end-section-env*)))) ++ ((equal rest 'ubsection) ++ (setq left (read-char *standard-input* nil a-very-rare-cons)) ++ (setq right (cdr (assoc left balanced-parens))) ++ (cond ((null right) (pprinc "subsection") (pwrite-char left)) ++ (t (pprinc *begin-subsection-env*) ++ (sloop for c = (read-char *standard-input* nil a-very-rare-cons) ++ until (equal c right) ++ do (pwrite-char c)) ++ (pprinc *end-subsection-env*)))) ++ (t (or just-remove-! ++ (pformat *terminal-io* "Surprising string after !s ~s.~%" rest)) ++ (pwrite-char #\!) ++ (pwrite-char #\s) ++ (pprinc rest))))) ++ ++(defun skip-index-entries () ++ ;; We are looking at a backslash. In Tex mode we need to skip to the end ++ ;; of the entry, because we may add !'s. In Scribe mode this is just NIL. ++ nil) ++ ++(defun adjust-tabbing-env () ++ ;; We are looking at a backslash. In Tex mode we may need to replace ++ ;; .... \\ ++ ;; \end{tabbing} ++ ;; with ++ ;; .... ++ ;; \end{tabbing} ++ ;; NOTE: this will only work if NQFMT2FMT is run. ++ ;; In Scribe mode this is just NIL. ++ nil) ++ ++ ++; INFIX SETTINGS ++ ++; This function should be called by the <mode>-init file, or may be called by ++; the <mode>-theory file to override the <mode>-init settings. ++ ++(defun infix-settings ++ (&key (mode nil p-mode) ; string ["SCRIBE","latex",...] ++ (extension nil p-extension) ; string ["MSS","tex"] ++ (op-location nil p-op-location) ; ['FRONT,'BACK] ++ (comment-format nil p-comment-format) ; ['SMITH,'boyer] ++ (format-!-in-comments nil p-format-!-in-comments) ; [T,nil] ++ (acl2-format-comments nil p-acl2-format-comments) ; [T,nil] ++ (acl2-format-doc-strings nil p-acl2-format-doc-strings) ; [T,nil] ++ (eliminate-top-parens nil p-eliminate-top-parens) ; [T,nil] ++ (eliminate-inner-parens nil p-eliminate-inner-parens) ; [T,nil] ++ (no-index nil p-no-index) ; [t,NIL] ++ (no-index-calls nil p-no-index-calls)) ; [t,NIL,l] ++ ++ (if p-mode (setq *infix-mode* mode)) ++ (if p-extension (setq *mode-extension* extension)) ++ (if p-op-location (setq *infix-op-location* op-location)) ++ (if p-comment-format (setup-comment-format comment-format)) ++ (if p-format-!-in-comments (setq *nq-default* format-!-in-comments)) ++ (if p-acl2-format-comments (setq *acl2-format-comments* acl2-format-comments)) ++ (if p-acl2-format-doc-strings (setq *acl2-format-doc-strings* acl2-format-doc-strings)) ++ (if p-eliminate-top-parens (setq *top-parens-eliminable* eliminate-top-parens)) ++ (if p-eliminate-inner-parens (setq *top-parens-eliminable-default* eliminate-inner-parens)) ++ (if p-no-index ++ (setq *do-not-index* no-index)) ++ (if p-no-index-calls ++ (cond ((consp no-index-calls) ++ (setq *do-not-index-calls-of* (append no-index-calls *do-not-index-calls-of*)) ++ (setq *do-not-index-calls* nil)) ++ (t (setq *do-not-index-calls* no-index-calls))))) ++ ++(defun will-will-not (x) ++ (if x "will" "will not")) ++ ++(defun show-infix-settings () ++ (format *terminal-io* "~%Expecting a .~a file to be mapped to .~a file to be formatted by ~a." ++ infix-input-file-type *mode-extension* *infix-mode*) ++ (format *terminal-io* "~%Multiline infix ops will be printed at the ~a of the line." *infix-op-location*) ++ (format *terminal-io* "~%Comment format is ~a." *comment-format*) ++ (format *terminal-io* "~%!formatting ~a be in effect." (will-will-not *nq-default*)) ++ (format *terminal-io* "~%Topmost parens ~a be suppressed." (will-will-not *top-parens-eliminable*)) ++ (format *terminal-io* "~%Inner parens ~a be suppressed." (will-will-not *top-parens-eliminable-default*)) ++ (format *terminal-io* "~%Index ~a be created." (will-will-not (not *do-not-index*))) ++ (format *terminal-io* "~%Calls ~a be indexed." (will-will-not (not *do-not-index-calls*)))) ++ ++(defun help-infix-settings () ++ (format *terminal-io* "~%To see current settings use (SHOW-INFIX-SETTINGS). ++To change settings use INFIX-SETTINGS and supply the keyword arguments ++for settings you wish to modify. Defaults in caps.~%") ++ (format *terminal-io* "~%:mode : string - formatting style [\"SCRIBE\",\"latex\",...]") ++ (format *terminal-io* "~%:extension : string - output file extension [\"MSS\",\"tex\"]") ++ (format *terminal-io* "~%:op-location : ['FRONT, 'back] ++ - Multiline infix operators will be printed at the front ++ - or back of the line according to this setting.") ++ (format *terminal-io* "~%:comment-format : ['SMITH, 'boyer, 'cl] - Comment format") ++ (format *terminal-io* "~%:no-index: [t,NIL] - Index will/will not be created") ++ (format *terminal-io* "~%:no-index-calls : [t,NIL,1ist] ++ - Calls will/will not be indexed. If a list, ++ - these functions will not be indexed.") ++ (format *terminal-io* "~%:format-!-in-comments : [T, nil] - !formatting in effect.") ++ (format *terminal-io* "~%:acl2-format-comments : [T, nil] - acl2 comment formatting.") ++ (format *terminal-io* "~%:acl2-format-doc-strings : [T, nil] - acl2 formatting doc strings.") ++ (format *terminal-io* "~%:eliminate-top-parens : [T, nil] - Topmost parens suppressed.") ++ (format *terminal-io* "~%:eliminate-inner-parens : [T, nil] - Inner parens suppressed.")) ++ ++ ++; DEFINITION BY EXAMPLES ++ ++; Anyone extending the syntax by hand rather than by use of one of the make... ++; functions ought also to add something to this list of examples to illustrate ++; the new syntax. ++ ++(defun functify (l) ++ ;; Removes redundant elements from an alist. ++ (sloop for tail on l with ans ++ do (cond ((null (assoc (car (car tail)) ans)) ++ (push (car tail) ans))) ++ finally (return (nreverse ans)))) ++ ++(defvar *infix-test-directory* ++ (concatenate 'string *infix-directory* "test/")) ++ ++(defun scrunch (l) ++ (sloop for tail on l unless (member (car tail) (cdr tail)) ++ collect (car tail))) ++ ++(defun print-examples (&optional mode) ++ ++; Illustrates the current syntax via a brief sample document. ++ ++ (cond (mode ++ (cond ((and (stringp mode) ++ (or (equal mode "latex") ++ (equal mode "scribe"))) ++ (setq *infix-mode* mode) ++ (format t "~%Entering ~a mode.~%" *infix-mode*) ++ (load-infix-init-file)) ++ (t (error (format nil "Unknown mode ~s" mode))))) ++ ((stringp *infix-mode*) ++ (format t "~%Entering ~a mode.~%" *infix-mode*) ++ (load-infix-init-file)) ++ ((null *infix-mode*) ++ (cond ((y-or-n-p "Enter Latex mode? ") ++ (setq *infix-mode* "latex")) ++ ((y-or-n-p "Enter Scribe mode? ") ++ (setq *infix-mode* "scribe")) ++ (t (setq *infix-mode* nil))) ++ (if *infix-mode* ++ (progn (format t "~%Entering ~a mode.~%" *infix-mode*) ++ (load-infix-init-file)))) ++ (t (format t "Remaining in ~a mode." *infix-mode*))) ++ ++ ++ ++ (let ((*print-pretty* nil) ++ (*print-case* :downcase)) ++ (with-open-file ++ (*standard-output* (type-file-name "infix-examples" ++ (fmt2fmt-extension nil *infix-mode*) t) ++ :direction :output ++ :if-exists :rename-and-delete) ++ (ppformat *example-prelude* *infix-mode*) ++ (sloop for form in (functify *wired-in-infix-examples*) ++ do (let ((*do-not-use-tabs* t)) ++ (pprinc *begin-item*) ++ (quote-printer1 form) ++ (ppformat " is printed as ~%~%") ++ (infix-form form) ++ (ppformat ".~%") ++ (pprinc *end-item*)) ++ (ppformat "~%")) ++ (pprinc *begin-item*) ++ (ppformat "The remaining symbols that are printed specially are ++described in the following table.") ++ (pprinc *end-item*) ++ (pprinc *end-enumerate-env*) ++ (ppformat "~%~%") ++ (let ((*tab-stack* t) ++ (table-number 1) ++ (example-number 1)) ++ ;; need to set *tab-list* non-nil to ensure (newline) works properly. ++ (ppformat *begin-example-table* table-number) ++ (sloop for form in ++ (append (sloop for pair in (functify *atom-alist*) ++ collect (car pair)) ++ (sloop for name in (scrunch *constant-ops*) ++ collect (list name)) ++ (sloop for name in (scrunch *infix-ops*) ++ collect (list name 'x 'y)) ++ (sloop for pair in (functify *negative-constant-table*) ++ collect (list 'not (list (car pair)))) ++ (sloop for pair in (functify *negative-infix-table*) ++ collect (list 'not (list (car pair) 'x 'y))) ++ (sloop for name in (scrunch *unary-prefix-ops*) ++ collect (list name 'x)) ++ (sloop for pair in (functify *negative-unary-prefix-table*) ++ collect (list 'not (list (car pair) 'x))) ++ (sloop for name in (scrunch *unary-suffix-ops*) ++ collect (list name 'x)) ++ (sloop for pair in (functify *negative-unary-suffix-table*) ++ collect (list 'not (list (car pair) 'x))) ++ (sloop for name in (scrunch *unary-abs-ops*) ++ collect (list name 'x)) ++ (sloop for pair in (functify *prefix-multiple-ops*) ++ collect (cons (car pair) ++ (sloop for i from 1 to (cdr pair) collect ++ (intern (format nil "X~a" i))))) ++ (sloop for pair in (functify *suffix-multiple-ops*) ++ collect (cons (car pair) ++ (sloop for i from 1 to (cdr pair) collect ++ (intern (format nil "X~a" i))))) ++ (sloop for pair in (functify *infix-multiple-ops*) ++ collect (cons (car pair) ++ (sloop for i from 1 to (1+ (cdr pair)) collect ++ (intern (format nil "X~a" i)))))) ++ do (let ((*do-not-use-tabs* t)) ++ (cond ((> example-number *example-table-size*) ++ (ppformat *end-example-table*) ++ (ppformat *begin-example-table* table-number) ++ (setq example-number 1))) ++ (quote-printer1 form) ++ (pprinc *column-separator*) ++ (infix-form form) ++ (new-tab-row nil) ++ (line-return) ++ (setq table-number (+ 1 table-number)) ++ (setq example-number (+ 1 example-number)) ++ (setq *infix-loc* *left-margin*))) ++ (ppformat *end-example-table*)) ++ (pprinc *example-postlude*)) ++ (nqfmt2fmt "infix-examples"))) ++ ++ ++; The following should be modified to interact with the vaiables that set ++; parens printing. In particular, this seems to be the piece of precedence that ++; is most easily screwed up. ++ ++; NOT ++ ++; The following code is for the special handling of NOT, which involves diving ++; into the term negated to turn a predicate into one that has a slash through ++; it. We advise that the casual user not touch this. ++ ++(defun not-printer (term) ++ (let (x) ++ (cond ((atom (cadr term)) ++ (default-unary-prefix-printer term *neg-str*)) ++ ((setq x (assoc (car (cadr term)) *negative-constant-table*)) ++ (pprinc (cadr x))) ++ ((setq x (assoc (car (cadr term)) *negative-infix-table*)) ++ (default-infix-printer (cadr term) (cadr x))) ++ ((setq x (assoc (car (cadr term)) *negative-unary-prefix-table*)) ++ (default-unary-prefix-printer (cadr term) (cadr x))) ++ ((setq x (assoc (car (cadr term)) *negative-unary-suffix-table*)) ++ (default-unary-suffix-printer (cadr term) (cadr x))) ++ (t (default-unary-prefix-printer term *neg-str*))))) ++ ++(declare-fn-printer not (function not-printer)) ++ ++;; REAL INITIALIZATION. Used to reinitialize during clean-up-everything ++(setq *save-fn-alist* *fn-alist*) ++ ++ ++; USER MODIFIABLE TABLE SETUP ++ ++; It is easy to augment, or even to modify, the syntax by calling one of the ++; make-... functions illustrated below. The non-initial arguments to these ++; make-... functions are strings to be printed by Latex to generate operators ++; and other noise words when printing a term whose function symbol is the ++; intial argument of the call to make-... ++ ++; make-infix-op, make-unary-prefix-op, and make-unary-suffix-op take an ++; optional second argument, *neg-str*, which indicates how to print an the ++; negation of an application of the function symbol in question. ++ ++; In TeX or Latex, one can do astonishingly clever things. But the strings ++; that we have in mind should do nothing clever involving motion, they should ++; only result in characters being placed at the current location. While being ++; printed, the strings will be passed no arguments or information about the ++; context in which printing is to take place. Typically, these strings should ++; be nothing more than instructions to print a single symbol. The strings are ++; processed in `math mode', and in fact, they are auomatically embedded in ++; $...$. ++ ++; None of the operators below are built into this printer anywhere else except ++; by the code below. The meaning of `not', defined above, is wired in because ++; it gives the meaning to the optional *neg-str* arguments. ++ ++ ++; CONSTANT-OPS ++ ++; Sometimes you want to print a function as a constant, particularly if it is one. ++; (make-constant-op op str) causes (op ..) to print as str. ++ ++; INFIX-OPS ++ ++; infix-ops (infix operators) should be function symbols of two or more ++; arguments for which it is desired that one symbol come out between every ++; adjacent pair of arguments. E.g., invoking (make-infix-op plus "+") causes ++; the term (plus a b c d) to be printed as (a $+$ b $+$ c $+$ d). Invoking ++; (make-infix-op equal "=" "\\not=") causes the term (equal x y) to be printed ++; as (x $=$ y) and it also causes the term (not (equal x y)) to be printed as ++; (x $\not= y). ++ ++; Thus, for example, if one introduces a new function, say join, and wants to ++; print terms of the form (join x y) as (x \bigtriangledown y), cf. p. 44 of ++; the Latex manual, then one should invoke: ++ ++; (make-infix-op join "\\bigtriangledown") ++ ++; from Lisp. That is all that need be done to cause infix-file to subsequently ++; print `join' terms this way. ++ ++; Note that throughout the following examples, we have used two backslashes to ++; get one because, in Common Lisp, backslash is a character for quoting other ++; characters. ++ ++; Examples of make-infix-op are contained in latex-theory.lisp. Look for INFIX OPERATORS. ++ ++ ++; UNARY-PREFIX-OPS, UNARY-SUFFIX-OPS, and UNARY-ABS-OPS ++ ++; Use make-unary-prefix-op and make-unary-suffix-op only for function symbols ++; of one argument. The string str (or *neg-str*) will be printed before or ++; after the argument. ++ ++; For more examples, see latex-theory.lisp. ++ ++; unary-suffix-ops should be unary function symbols. ++ ++; (make-unary-suffix-op foo x str) makes (foo x) print as (x $str$). ++ ++; Examples of make-unary-suffix-op. ++ ++; unary-prefix-ops should be unary function symbols. ++ ++; (make-unary-prefix-op foo str) makes (foo x) print as ($str$ x). ++ ++; unary-abs-ops should be unary function symbols. ++ ++; To create syntax like that for absolute value, use (make-unary-absolute-op ++; lhs-str rhs-str), where lhs-str and rhs-str are the strings to print on the ++; left and right of the argument. (make-unary-abs-op foo str1 str2) makes (foo ++; x) print as (str1 x str2). See the example for abs below. ++ ++ ++; SOME POSSIBLE EXTENSIONS ++ ++ ++;; (simple-extension) ; see latex-theory.lisp ++;; (dmg-syntax) ; see latex-theory.lisp ++ ++; Undoing. To cause applications of a function symbol fn to be printed in the ++; default way, i.e., fn(x, y), invoke (clean-up 'fn). ++ ++ ++;; TESTING ++ ++;; Lines in the test file are the following form: ++ ++;; filename ++;; or (filename mode) ++;; or (filename mode comment) ++ ++;; Comment defaults to T. ++ ++(defvar *mode-list* '("latex" "scribe")) ++ ++(defvar *test-file* "testfile") ++ ++;; Better to use test-directory ++;; (defun test-infix () ++;; (let ((files (read-file-list *test-file*))) ++;; (sloop for test in files ++;; do (cond ((or (stringp test) ++;; (and (consp test) (null (cdr test)))) ++;; ;; "file" or (file) ++;; (if (consp test) (setq test (car test))) ++;; (sloop for mode in *mode-list* ++;; do (progn ++;; (format *terminal-io* ++;; "~%Translating ~a in ~a mode.~%" test mode) ++;; (infix-file test :mode mode :comment t)))) ++;; ((and (consp test) (eql (length test) 2)) ++;; ;; (file mode) ++;; (format *terminal-io* ++;; "~%Translating ~a in ~a mode.~%" (car test) (cadr test)) ++;; (infix-file (car test) :mode (cadr test) :comment t)) ++;; ((and (consp test) (eql (length test) 3)) ++;; ;; (file mode comment) ++;; (format *terminal-io* ++;; "~%Translating ~a in ~a mode, with comment = ~a.~%" ++;; (car test) (cadr test) (caddr test)) ++;; (infix-file (car test) :mode (cadr test) :comment (caddr test))) ++;; (t (format *terminal-io* "~%BAD TEST FILE SPEC: ~ad.~%" test)))))) ++ ++;; (defun read-file-list (file) ++;; (cond ((null (probe-file file)) ++;; (format t "~%Failed to find file: ~a~%" file)) ++;; (t (with-open-file ++;; (*standard-input* file :direction :input) ++;; (sloop for form = (readx *standard-input* nil a-very-rare-cons nil) ++;; until (eq form a-very-rare-cons) ++;; collect form))))) ++ ++ ++;; Testing functions ++ ++;; MODIFY and USE: ++;; mks: script test.log ++;; mks: ++;; >(load "infix") ++;; >(test-directory "scribe") ++;; >(bye) ++;; mks: foreach f (*.mss) ++;; ? scribe $f ++;; ? end ++;; mks: ^D ++;; mks: sed -e s/^V^M// test.log > test-scribe.log ++ ++(defun test-directory (mode &optional directory (comment nil comment-p)) ++ ;; ONLY EXPECTING mode = "latex" or "scribe" ++ (let ((type (if (string= mode "latex") "tex" "mss")) ++ (dir (or directory *infix-test-directory*)) ++ ;; Default testing excludes nqfmt2fmt translations ++ ;; for latex, since it is so much more sensitive ++ ;; to character weirdness. ++ (com (if (string= mode "latex") nil t))) ++ (if comment-p (setq com comment)) ++ (setq dir (concatenate 'string dir "*.lisp")) ++ (mapc (function (lambda (f) ++ (format *terminal-io* "~%Infixing ~a.lisp." (pathname-name f)) ++ (if (probe-file (make-pathname :type type :defaults f)) ++ (format *terminal-io* "~%~a.~a already exists. Skipping.~%" ++ (pathname-name f) type) ++ (infix-file f :mode mode)))) ++ (directory dir)))) ++ ++(format *terminal-io* "~%~%--- Do (help-infix-settings) for help. ---~%~%") ++ ++ ++#| Note on math printing from LSmith. ++ ++Bill and I had troubles printing with infix because nesting math modes ++is not allowed in latex. Our latex output from infix is filled with ++ ++ {\ifmmode <form>\else$<form>$\fi} ++ ++with the two <form>s identical and often containing more ifmmodes. ++ ++I happened across a solution to this problem in the Latex manual. ++ ++ \mbox{$<form>$} ++ ++works whether of not we are currently in mathmode. In other words, it ++is possible to nest math modes in latex after all. This feature is ++documented in section 3.4.1, Defining Commands, in the Latex manual. ++ ++|# +\ No newline at end of file +--- /dev/null ++++ acl2-6.0/interface/infix/makefile +@@ -0,0 +1,84 @@ ++ ++# ACL2 Version 1.9 ++ ++# Copyright (C) 1989-96 Computational Logic, Inc. (CLI). All rights reserved. ++ ++# Use of this software constitutes agreement with the terms of ACL2 ++# license agreement, found in the file LICENSE. ++ ++# Example invocations (see README): ++ ++# make ; Recompile what's needed. ++# make example ; Create and print example forms in MODE. ++# make events ; Create and print example events in MODE. ++# make clean ; Cleanup everything but .o files and TAG table. ++# make tags ; Create TAG table. ++# make full ; Clean, compile, create TAGS, and print example in MODE. ++ ++LISP = acl2 ++DIR = /acl2/interface/infix ++SAVED = ${DIR}/Save ++# TEST = ${DIR}/test ++TEST = ${DIR}/books ++# MODE = "scribe" ++MODE = "latex" ++LPR = lpr ++DVI = dvips ++ ++sources = infix.lisp scribe-init.lisp latex-init.lisp ++ ++# 'make' without a target uses the first one, e.g. ++ ++compile: ${sources} ++ rm -f workxxx ++ echo ':q' > workxxx ++ echo '(in-package "user")' >> workxxx ++ echo '(when (find-package "sloop") (use-package "sloop"))' >> workxxx ++ echo '(compile-file "infix.lisp")' >> workxxx ++ echo '(load "infix")' >> workxxx ++ echo '(compile-file "scribe-init.lisp")' >> workxxx ++ echo '(compile-file "latex-init.lisp")' >> workxxx ++ ${LISP} < workxxx ++ rm -f workxxx ++ ++full: clean tags example events ++ ++tags: ${sources} ++ etags *.lisp ++ ++example: ++ rm -f workxxx ++ echo ':q' > workxxx ++ echo '(in-package "user")' >> workxxx ++ echo '(when (find-package "sloop") (use-package "sloop"))' >> workxxx ++ echo '(load "infix")' >> workxxx ++ echo '(print-examples ${MODE})' >> workxxx ++ ${LISP} < workxxx ++ if [ ${MODE} = "scribe" ] ; then \ ++ scribe infix-examples.mss ; scribe infix-examples.mss ; ${LPR} infix-examples.ps;\ ++ else \ ++ rm -f infix-examples.aux ; latex infix-examples ; ${DVI} -o infix-examples.ps infix-examples ; \ ++ fi ++ ++events: #clean-doc ++ rm -f workxxx ++ echo ':q' > workxxx ++ echo '(in-package "user")' >> workxxx ++ echo '(when (find-package "sloop") (use-package "sloop"))' >> workxxx ++ echo '(load "infix")' >> workxxx ++ echo '(infix-file "sample.lisp" :mode "${MODE}")' >> workxxx ++ ${LISP} < workxxx ++ if [ ${MODE} = "scribe" ] ; then \ ++ scribe sample.mss ; else \ ++ latex sample && latex sample && ${DVI} -o sample.ps sample ; \ ++ fi ++ ++clean-all: clean ++ rm -f *.o TAGS ++ ++clean: clean-doc ++ rm -f *~* *#* workxxx *.o *.tex *.nqtex TAGS *.dvi *.ps *.err *.aux *.log *.idx ++ ++clean-doc: ++ rm -f ${DIR}/*.otl ${DIR}/*.err ${DIR}/*.ps ${DIR}/*.aux ++ rm -f ${DIR}/*.dvi ${DIR}/*.aux ${DIR}/*.log ${DIR}/*.idx ${DIR}/.log +--- /dev/null ++++ acl2-6.0/interface/infix/latex-init.lisp +@@ -0,0 +1,739 @@ ++; ACL2 Version 1.9 ++ ++; Copyright (C) 1989-96 Computational Logic, Inc. (CLI). All rights reserved. ++ ++; Use of this software constitutes agreement with the terms of ACL2 ++; license agreement, found in the file LICENSE. ++ ++;; Init file for infix.lisp in Latex mode. ++;; Feb 20 1992, by MKSmith ++;; This file depends on the LaTeX .sty file, "CLI.sty". ++;; CLI.sty should be stored in *infix-directory*. ++ ++(in-package "user") ++ ++(format *terminal-io* "Loading the ainfix latex-init file.") ++ ++;; Mode should actually be set before this file is loaded. ++ ++(infix-settings :mode "latex" ++ :extension "tex" ++ :op-location 'front ++ :comment-format 'smith ++ :format-!-in-comments nil ++ :eliminate-top-parens t ++ :eliminate-inner-parens nil ++ :no-index-calls nil ) ++ ++(defparameter *rightmost-char-number* 100) ++(defparameter *default-chars-wide* 100) ++(defparameter *latex-indent-number-limit* 14) ++ ++(defparameter nqread-normal-clause-enders ++ (append '(#\\ #\{) nqread-default-normal-clause-enders)) ++ ++ ++;; THE LATEX PRELUDE. ++ ++(defparameter *standard-prelude* ++ (format nil "\\documentstyle[makeidx,~aCLI]{article}~%~ ++ \\makeindex~%~ ++ %\\setlength{\\oddsidemargin}{.5in}~%~ ++ %\\setlength{\\evensidemargin}{.5in}~%~ ++ %\\setlength{\\textwidth}{5.8in}~%~ ++ \\begin{document}~%~ ++ %\\setlength{\\parindent}{0pt}~%~ ++ %\\newcounter{bean}~%~ ++ %\\begin{list}{\\arabic{bean}.}~ ++ {\\usecounter{bean}~ ++ \\setlength{\\leftmargin}{0pt}~ ++ \\setlength{\\rightmargin}{0pt}~ ++ \\setlength{\\listparindent}{20pt}~ ++ \\setlength{\\parsep}{5pt}}~ ++ ~%%\\item[]~%~%" *infix-directory*)) ++ ++(defparameter *standard-postlude* ++ "%\\end{list} ++\\printindex ++\\end{document} ++") ++ ++(defparameter *example-prelude* ++ "\\documentstyle{article} \\begin{document} ++ ++Here is a summary of the conventional syntax (~a) in terms of the official syntax ++of the Nqthm logic. ++ ++\\begin{enumerate} ++\\item Variables are printed in italics, unless specified otherwise in the table below. ++ ++\\item Function application. For any function symbol for which special ++syntax is not given below, an application of the symbol is printed with ++the usual notation; e.g., the term !v(fn x y z) is ++printed as !t(fn x y z). Note that the function symbol is printed in ++Roman. In the special case that !qc is a function symbol of no ++arguments, i.e., it is a constant, the term !v(c) is printed merely as ++!t(c), in small caps, with no trailing parentheses. Because variables are printed in ++italics, there is no confusion between the printing of variables and ++constants. ++ ++\\item Other constants. ++Quoted constants are printed in the ordinary syntax of the Nqthm logic, ++in a `typewriter font.' For example, ++{\\tt '(a b c)} is still printed just that way. \\verb+#b001+ is printed ++as !t#b001, \\verb+#o765+ is printed as !t#o765, and \\verb+#xa9+ is printed as ++!t#xa9, representing binary, octal and hexadecimal, respectively.") ++ ++(defparameter *example-table-size* 40) ++ ++(defparameter *begin-example-table* "~%~%\\begin{tabular}{|c|c|}\\hline~%~ ++ Nqthm Syntax & Conventional Syntax \\\\ \\hline \\hline") ++ ++(defparameter *end-example-table* " \\hline \\end{tabular} ++") ++ ++(defparameter *example-postlude* "\\end{document}") ++ ++;; BASIC BRACKETS AND THEIR QUOTED VERSION. ++ ++(defparameter *begin* "{") ++(defparameter *end* "}") ++ ++(defparameter *lbrace* "\{") ++(defparameter *rbrace* "\}") ++ ++;; NEWLINE PARAMETERS ++ ++(defparameter *newline-in-env* "\\\\") ++(defparameter *newline-in-text* "") ++ ++(defparameter *force-newline-in-env* "\\\\") ++(defparameter *force-newline-in-text* "\\hfill \\break ") ++ ++;; ENVIRONMENT BEGIN-END PAIRS ++ ++(defparameter *begin-index* "\\index{") ++(defparameter *end-index* "}") ++ ++(defparameter *begin-text-env* "") ++(defparameter *end-text-env* "") ++ ++(defparameter *begin-verbatim-env* "\\begin{verbatim}") ++(defparameter *end-verbatim-env* "\\end{verbatim}") ++ ++(defparameter *begin-format-env* "\\begin{CLIverbatim}\\begin{rm}") ++(defparameter *end-format-env* "\\end{rm}\\end{CLIverbatim}") ++ ++;; Depends on CLI.sty ++(defparameter *begin-emphasis-env* "\\begin{CLIverbatim}\\begin{it}") ++(defparameter *end-emphasis-env* "\\end{it}\\end{CLIverbatim}") ++ ++(defparameter *begin-section-env* "\\section{") ++(defparameter *end-section-env* "}") ++ ++(defparameter *begin-subsection-env* "\\subsection{") ++(defparameter *end-subsection-env* "}") ++ ++(defparameter *begin-tt-env* "{\\tt{") ++(defparameter *end-tt-env* "}}") ++ ++(defparameter *begin-string-env* "{\\tt{") ++(defparameter *end-string-env* "}}") ++ ++(defparameter *begin-bold-env* "{\\bf{") ++(defparameter *end-bold-env* "}}") ++ ++(defparameter *begin-italic-env* "{\\it{") ++(defparameter *end-italic-env* "\\/}}") ++ ++(defparameter *begin-sc-env* "{\\sc{") ++(defparameter *end-sc-env* "}}") ++ ++;; This won't work. ++ ++(defparameter *begin-comment-env* "%") ++(defparameter *end-comment-env* " ++") ++ ++(defparameter *begin-enumerate-env* "\\begin{enumerate}") ++(defparameter *end-enumerate-env* "\\end{enumerate}") ++(defparameter *begin-item* "\\item ") ++(defparameter *end-item* "") ++ ++(defparameter *mv-bracket-left* "$\\langle$") ++(defparameter *mv-bracket-right* "$\\rangle$") ++ ++(defparameter *forall* "$\\forall\\;$") ++(defparameter *exists* "$\\exists\\;$") ++ ++ ++;; TABBING AND INDENTING ENVIRONMENT AND TAB OPERATIONS ++ ++;; I don't know how to do this in Latex. ++(defparameter *begin-group-tabbing-env* "\\begin{tabbing} ++") ++(defparameter *begin-tabbing-env* "\\begin{tabbing} ++") ++(defparameter *end-tabbing-env* "\\end{tabbing} ++") ++(defparameter *new-tab-row* " \\\\") ++ ++;; Just in case some other mode defined it otherwise. ++(defun new-tab-row (&optional followed-by-infix-print-term) ++ (declare (ignore followed-by-infix-print-term)) ++ (pprinc *new-tab-row*)) ++ ++(defparameter *tab* "\\>") ++(defparameter *flush* "\\`") ++ ++(defparameter *column-separator* "&") ++ ++(defparameter *tab-list* nil) ++ ++(defparameter *set-margin* "\\=\\+") ++(defparameter *pop-margin* "\\-") ++(defparameter *set-tab* "\\=") ++ ++(defparameter *default-op-tab-space* "$\\quad$ ") ++(defparameter *indent-string* "$\\quad$ ") ++(defparameter *default-indent* 2) ++ ++(defun get-op-width-string (op) ++ (declare (ignore op)) ++ nil) ++ ++(defparameter *noindent* "\\noindent ") ++ ++;; Not properly defined yet. ++(defun begin-normal-text () (line-return)) ++(defun end-normal-text () (line-return)) ++ ++(defvar *tab-stack* nil) ++ ++(defun begin-tabbing () ++ ++; Tabbing environments cannot be nested in Latex. ++ ++ (if (null *tab-stack*) ++ (princ *begin-tabbing-env*)) ++ (setq *tab-stack* (cons *tab-list* *tab-stack*)) ++ (setq *tab-list* nil) ++ ++ (if (> *left-margin* 0) ++ (progn (sloop for i from 1 to *left-margin* do (pprinc "M")) ++ (pprinc "\\=\\+\\kill") ++ (pwrite-char #\Newline))) ++ (setq *infix-loc* *left-margin*)) ++ ++(defun begin-group-tabbing () ++ ++ (if (null *tab-stack*) ++ (princ *begin-group-tabbing-env*)) ++ (setq *tab-stack* (cons *tab-list* *tab-stack*)) ++ (setq *tab-list* nil) ++ ++ (if (> *left-margin* 0) ++ (progn (sloop for i from 1 to *left-margin* do (pprinc "M")) ++ (pprinc "\\=\\+\\kill") ++ (pwrite-char #\Newline))) ++ (setq *infix-loc* *left-margin*)) ++ ++(defun end-tabbing () ++ (cond ((null *tab-stack*)) ++ ((null (cdr *tab-stack*)) ++ (setq *tab-list* (car *tab-stack*)) ++ (setq *tab-stack* nil) ++ (princ *end-tabbing-env*)) ++ (t (setq *tab-list* (car *tab-stack*)) ++ (setq *tab-stack* (cdr *tab-stack*))))) ++ ++;; (defun begin-tabbing () ++;; ++;; ; Tabbing environments cannot be nested in Latex. ++;; ++;; (setq *tab-list* nil) ++;; (princ *begin-tabbing-env*) ++;; (if (> *left-margin* 0) ++;; (progn (sloop for i from 1 to *left-margin* do (pprinc "M")) ++;; (pprinc "\\=\\+\\kill") ++;; (pwrite-char #\Newline))) ++;; (setq *infix-loc* *left-margin*)) ++;; ++;; (defun begin-group-tabbing () ++;; (setq *tab-list* nil) ++;; (princ *begin-group-tabbing-env*) ++;; (if (> *left-margin* 0) ++;; (progn (sloop for i from 1 to *left-margin* do (pprinc "M")) ++;; (pprinc "\\=\\+\\kill") ++;; (pwrite-char #\Newline))) ++;; (setq *infix-loc* *left-margin*)) ++;; ++;; (defun end-tabbing () ++;; (princ *end-tabbing-env*)) ++ ++(defun increase-margin () ++ (pprin1i *default-op-tab-space*) ++ (set-margin)) ++ ++(defun set-margin () ++ ++; Generate instructions to set the current indentation. ++; In latex we use tabs, which cause *tabto* to tab to this column in the future. ++; `Punt' if we hit the limit, by throwing all the way out. ++ ++ (cond (*do-not-use-tabs* nil) ++ (t (cond ((= *tabs-in* *latex-indent-number-limit*) ++ (throw 'taboverflow t))) ++ (setq *tabs-in* (1+ *tabs-in*)) ++ (adjust-margin-to-last-tab-first *tab-list*) ++ (pprinc *set-margin*) ++ (push (cons 'lm *infix-loc*) *tab-list*)))) ++ ++(defun adjust-margin-to-last-tab-first (tl) ++ (cond ((null tl)) ++ ((eq (caar tl) 'tab) ++ (pprinc "\\+") ++ (adjust-margin-to-last-tab-first (cdr tl))) ++ (t nil))) ++ ++(defun get-margin () ++ (get-margin2 *tab-list*)) ++ ++(defun get-margin2 (tl) ++ (let ((setting (car tl))) ++ (cond ((null setting) *left-margin*) ++ ((eq (car setting) 'lm) (cdr setting)) ++ (t (get-margin2 (cdr tl)))))) ++ ++(defun begin-flushright () ++ (pprinc *flush*)) ++ ++(defun end-flushright () nil) ++ ++(defun flushright (form) ++ (begin-flushright) ++ (pprinc form) ++ (end-flushright)) ++ ++(defun do-tab () ++ (cond (*do-not-use-tabs* (pprinc " ")) ++ ((and *tab-list* (eq (caar *tab-list*) 'tab)) ++ (pprinc *tab*)) ++ (t (pprinc " ")))) ++ ++(defun set-tab (&optional op) ++ ++; Generate instructions to set a tab at the current location. ++; `Punt' if we hit the limit, by throwing all the way out. ++ ++ (cond (*do-not-use-tabs* nil) ++ (t (cond ((= *tabs-in* *latex-indent-number-limit*) ++ (throw 'taboverflow t))) ++ (setq *tabs-in* (1+ *tabs-in*)) ++ (cond ((and op (get-op-width-string op)) ++ (pprinc (get-op-width-string op))) ++ (t (pprinc *default-op-tab-space*))) ++ (push (cons 'tab *infix-loc*) *tab-list*) ++ (pprinc *set-tab*)))) ++ ++(defun pop-tab () ++ ;; We don't really remove tabs from the formatted env. ++ ;; Just track them in Lisp. ++ ;; Generate command to `tab to one tab less in'. ++ ;; Do not pop tabs beyond left margin. ++ (cond (*do-not-use-tabs* nil) ++ ((and *tab-list* (eq (caar *tab-list*) 'tab)) ++ (setq *tabs-in* (1- *tabs-in*)) ++ ;; We don't tell TeX to remove the tab. This works because ++ ;; before we try to use tabi again, we will reset its value. ++ (pop *tab-list*)) ++ (t nil))) ++ ++(defun pop-margin () ++ ;; Generate command to `return to one margin less in'. ++ ;; If there are tabs after the margin, they are popped as well. ++ ;; NOTE: The way this must work in Latex is that if there ++ ;; are tabs they are just ignored. If there is an LM ++ ;; we pop it as well as any \+ that were done to move over tabs ++ ;; to it. ++ (cond (*do-not-use-tabs* nil) ++ ((null *tab-list*) nil) ++ ((and (eq (caar *tab-list*) 'tab) ++ (eq (caadr *tab-list*) 'lm)) ++ (pop-tab) ++ (pop *tab-list*) ++ (setq *tabs-in* (1- *tabs-in*)) ++ (pprinc *pop-margin*) ++ (adjust-margin-to-first-tab-last *tab-list*)) ++ ((and *tab-list* (eq (caar *tab-list*) 'lm)) ++ (setq *tabs-in* (1- *tabs-in*)) ++ (pop *tab-list*) ++ (pprinc *pop-margin*) ++ (adjust-margin-to-first-tab-last *tab-list*)) ++ (t nil))) ++ ++(defun adjust-margin-to-first-tab-last (tl) ++ (cond ((null tl)) ++ ((eq (caar tl) 'tab) ++ (pprinc "\\-") ++ (adjust-margin-to-first-tab-last (cdr tl))) ++ (t nil))) ++ ++;; (defun to-current-margin () ++;; ;; Generates command for return to current indentation setting, ++;; ;; unless we are already there. ++;; (cond (*do-not-use-tabs* (pprinci " ")) ++;; ((eql *infix-loc* (get-margin))) ++;; (t (pprinc *new-tab-row*) ++;; (setq *infix-loc* (get-margin))))) ++ ++;; (defun newline-to-current-margin () ++;; ;; Generates command for return to current indentation setting.' ++;; (cond (*do-not-use-tabs* (pprinci " ")) ++;; (t (pprinc *new-tab-row*) ++;; (setq *infix-loc* (get-margin))))) ++ ++;; (defun force-newline () ++;; ;; Forces a newline in running text OR in a tabbing env. ++;; (if (null *tab-list*) ++;; (progn (pprinci "\\hfill \\break ") ++;; (pwrite-char #\Newline) ++;; (cond (*do-not-use-tabs*) ++;; (t (setq *infix-loc* (get-margin))))) ++;; (progn (cond (*do-not-use-tabs* (pprinci " ")) ++;; (t (pprinc *new-tab-row*) ++;; (setq *infix-loc* (get-margin))))))) ++ ++;; FONTS ++ ++(defparameter *function-font* "\\rm") ++ ++(defun roman-font (term) ++ (pprinc "{") ++ (pprinc *function-font*) ++ (pprinc "{") ++ (print-atom term) ++ (pprinc "}}")) ++ ++ ++;; MATH ENV AND OPERATORS ++ ++(defparameter *neg-str* (format nil "$~a$" "\\neg")) ++ ++(defparameter *math-format* "$~a$") ++(defparameter *math-begin* "$") ++(defparameter *math-end* "$") ++ ++(defparameter *math-thick-space* "\\;") ++(defparameter *math-thin-space* "\\,") ++ ++(defparameter *subscript* "_") ++ ++(defparameter *begin-subscript* "\\(_{") ++(defparameter *end-subscript* "}\\)") ++ ++;; MISC ++ ++(defparameter *newpage* "\\newpage") ++ ++(defparameter *comma-atsign* ",@") ++(defparameter *caret* "\\char'136") ;; It is a tad subtle getting a caret printed. ++(defparameter *tilde* "\\char'176") ;; It is a tad subtle getting a tilde printed. ++ ++(defparameter *dotted-pair-separator* " .\\ ") ; I don't understand the \\ ++(defparameter *dotted-pair-separator-newline* ".\\ ") ; ditto ++ ++(defparameter *no-tab-event-trailer* "~%~%\\addvspace{10pt}") ++(defparameter *print-default-event-header* "~%\\noindent{\\sc Event}: ") ++(defparameter *print-default-lisp-header* "~%\\noindent{\\sc Lisp}: ") ++ ++(defparameter *print-default-command-header* "~%\\noindent~%") ++(defparameter *no-tab-command-trailer* "~%~%\\addvspace{10pt}") ++ ++ ++ ++ ++;; OTHER FUNCTIONS ++ ++(defparameter doc-special-chars (coerce "#$%&~_^\\{}" 'list)) ++(defparameter doc-other-chars (coerce "<>|" 'list)) ++(defparameter doc-index-specials (coerce "@|!\"" 'list)) ++ ++;; We didn't compile the following because the compiler declaration ++;; in Sinfix, through a bug in AKCL, caused this routine to produce ++;; spurious results. ++ ++;; The patch to akcl that is loaded in sinfix should fix this problem. ++;; Other lisps shouldn't need it. ++;; These use to be of the form (eval-when (load) (eval '<defn>)) ++ ++(defun handle-special-chars (char) ++ ;; USED BY PRINT-ATOM. CHAR is local to print-atom. ++ (cond ((eql char #\^) ++ (pprinc "\\verb|^|")) ++ ((eql char #\~) ++ (pprinc *tilde*) ++ (incf *infix-loc* 1)) ++ ((member char doc-special-chars) ++ (pwrite-char #\\) ++ (pwrite-char (cond ((eq *print-case* :downcase) ++ (char-downcase char)) ++ (t char)))) ++ ((member char doc-other-chars) ++ (pwrite-char #\$) ++ (pwrite-char (cond ((eq *print-case* :downcase) ++ (char-downcase char)) ++ (t char))) ++ (pwrite-char #\$)) ++ (t (pwrite-char (cond ((eq *print-case* :downcase) ++ (char-downcase char)) ++ (t char)))))) ++ ++(defun handle-special-chars-in-string (char) ++ ;; USED BY PRINT-ATOM. CHAR is local to print-atom. ++ (cond ((eql char #\~) ++ (pprinc *tilde*) ++ (incf *infix-loc* 1)) ++ ((member char doc-special-chars) ++ (incf *infix-loc* 1) ++ (pwrite-char #\\) ++ (pwrite-char char)) ++ ((member char doc-other-chars) ++ (incf *infix-loc* 2) ++ (pwrite-char #\$) ++ (pwrite-char char) ++ (pwrite-char #\$)) ++ (t (pwrite-char char)))) ++ ++ ++;; PRINTING INDEX ENTRIES ++ ++; Who could ever have guessed that it would take this much code to print out a ++; simple \index{foo} command for an arbitrary Nqthm function symbol foo. There ++; are so many special cases one can hardly believe one's eyes. ++ ++(defparameter index-subitem-length 30) ++ ++(defun index (x &optional subkind) ++ ++#| ++Yuk city on quotations of weird characters. ++ ++See the latex guide to indexes, ++tex3.0/TeX3.0/LaTeX/LaTeXmakeindex/doc/makeindex.tex. The characters vertical ++bar, @, and ! are used within index strings, and need to be quoted with a ++single double quote mark. ++ ++Also, it looks like makeindex chokes on index entries of more than 64 ++characters, in the sense that after 64, things suddenly become subitems, which ++is a good way to get screwed if there are weird characters in the first 64 that ++need quoting or balancing. ++ ++|# ++ ++ (pprinc *begin-index*) ++ (let ((str (if (stringp x) x (symbol-name x))) ++ (num-chars 0) ++ (inserted-excl nil)) ++ ++ (if subkind ++ (cond ((stringp subkind) (setq str (concatenate 'string str ", " subkind))) ++ ((symbolp subkind) (setq str (concatenate 'string str ", " (string subkind)))) ++ (t nil))) ++ ++ (sloop with brace-count = 0 ++ for i below (length str) ++ for char = (char (the string str) (the fixnum i)) ++ until (> num-chars *index-entry-max*) ++ do ++ (progn ++ (cond ((and (> num-chars index-subitem-length) ++ (not inserted-excl) ++ (= brace-count 0)) ++ ++; There is some sort of a bug in the Latex indexing machinery whereby if an ++; entry has more than 64 characters, a `subitem' is automatically started. But ++; this may happen in a bad place, in terms of character quotation, so we force ++; a subitem earlier, at our convenience. ++ ++ (pwrite-char #\!) ++ (setq inserted-excl t))) ++ ++; It is a tad subtle getting a caret or tilde printed. ++ ++ (cond ((eql char #\^) ++ (pprinc *caret*) ++ (incf num-chars 8)) ++ ++ ((eql char #\~) ++ (pprinc *tilde*) ++ (incf num-chars 8)) ++ ++; If braces are not balanced, the index machinery will barf, so we keep track ++; and try to help out later, if we can. ++ ++ ((eql char #\{) ++ (incf brace-count 1) ++ (pwrite-char #\\) ;!!! This won't work in Scribe. ++ (pwrite-char char) ++ (incf num-chars 2)) ++ ((eql char #\}) ++ (decf brace-count 1) ++ (pwrite-char #\\) ++ (pwrite-char char) ++ (incf num-chars 2)) ++ ++; There are the special characters like @ which have a special meaning just in ++; Latex indexing, and they have to be quoted their own special way. ++ ++ ((member char doc-index-specials) ++ (pwrite-char #\") ++ (pwrite-char char) ++ (incf num-chars 2)) ++ ++; And of course, one has to watch our for such standard special TeX characters ++; as $. ++ ++ ((member char doc-special-chars) ++ (pwrite-char #\\) ++ (pwrite-char char) ++ (incf num-chars 2)) ++ ++; If one tries to set an ordinary < or >, it won't work, and just quoting with ++; backslash doesn't work either, so we sneak into math mode. ++ ++ ((member char doc-other-chars) ++ (pwrite-char #\$) ++ (pwrite-char char) ++ (pwrite-char #\$) ++ (incf num-chars 3)) ++ (t (pwrite-char (cond ((eq *print-case* :downcase) ++ (char-downcase char)) ++ (t char))) ++ (incf num-chars 1))) ++ (cond ((< brace-count 0) ++ (pformat *terminal-io* ++ "~% Error: The index entry for ~a will ~ ++ fail because of the imbalance of set ~ ++ braces.~%" ++ x)))) ++ finally ++ (progn ++ (cond ((> num-chars *index-entry-max*) ++ (pformat *terminal-io* ++ "~% Warning: Index entry for ~a truncated to ~a characters. ~%" ++ x num-chars) ++ (pprinc "..."))) ++ (cond ((not (equal brace-count 0)) ++ (cond ((> brace-count 0) ++ (sloop for i from 1 to brace-count do ++ (pprinc "\\}")))) ++ (pformat *terminal-io* ++ "~%Warning: Balancing set braces on ~ ++ ~a so Latex indexing will work.~%" ++ x)))))) ++ (pprinc *end*)) ++ ++(defun skip-index-entries () ++ ;; We are looking at a backslash. If this begins an index entry, in Tex ++ ;; mode we need to skip to the end of the entry, because we may have added !'s. ++ ;; In Scribe mode this function returns NIL. ++ (let ((pos (file-position *standard-input*)) ++ (index '(#\i #\n #\d #\e #\x #\{)) ++ success ++ c) ++ (sloop for x on index ++ while (and x (char= (setq c (read-char *standard-input* nil a-very-rare-cons)) (car x))) ++ finally (cond ((null x) ++ (pprinc "\\index{") ++ (skip-to-brace) ++ (setq success t)))) ++ (cond ((not success) ++ ;; Back to read the char immediately following the #\. ++ (file-position *standard-input* pos) ++ nil) ++ (t t)))) ++ ++(defun adjust-tabbing-env () ++ ;; We are looking at a backslash. In Tex mode we want to replace ++ ;; .... \\ ++ ;; \end{tabbing} ++ ;; with ++ ;; .... ++ ;; \end{tabbing} ++ ;; Worse and worse. There is more than one such pattern. ++ (let ((pos (file-position *standard-input*)) ++ (patterns '((#\\ #\newline #\\ #\- #\\ #\e #\n #\d #\{ #\t #\a #\b #\b #\i #\n #\g #\}) ++ (#\\ #\newline #\\ #\e #\n #\d #\{ #\t #\a #\b #\b #\i #\n #\g #\}))) ++ success ++ c) ++ (sloop for pattern in patterns ++ while (not success) ++ do (progn ++ (sloop for x on pattern ++ while (char= (setq c (read-char *standard-input* nil a-very-rare-cons)) (car x)) ++ finally (cond ((null x) ++ (line-return) ++ (pprinc "\\end{tabbing}") ++ (setq success t)))) ++ (if (not success) ++ ;; Back to read the char immediately following the #\. ++ (file-position *standard-input* pos)))) ++ success)) ++ ++(defun skip-to-brace () ++ ;; Skip to next non-quoted #\}. ++ ;; We assume one exists. ++ (sloop for c = (read-char *standard-input* nil a-very-rare-cons) ++ until (char= c #\}) ++ do (cond ((char= c #\\) ++ ;; Handle imbedded, quoted right braces. ++ (pwrite-char c) ++ (pwrite-char (read-char *standard-input* nil a-very-rare-cons))) ++ (t (pwrite-char c)))) ++ (pwrite-char #\})) ++ ++(defparameter acl2-char-subst-table ++ '((#\~ #\\ #\c #\h #\a #\r #\' #\1 #\7 #\6 #\ ) ++ (#\^ #\\ #\c #\h #\a #\r #\' #\1 #\3 #\6 #\ ) ++ (#\# #\\ #\#) ++ (#\& #\\ #\&) ++ (#\$ #\\ #\$) ++ (#\% #\\ #\%) ++ (#\_ #\\ #\_) ++ (#\\ #\\ #\\) ++ (#\{ #\\ #\{) ++ (#\} #\\ #\}) ++ (#\< #\$ #\< #\$) ++ (#\> #\$ #\> #\$) ++ (#\| #\$ #\| #\$))) ++ ++ ++(defparameter acl2-markup-table ++ '(("-" . "---") ++ ("B" . "{\\bf ~sa}") ++ ("BF" . "~%\\begin{CLIverbatim}\\begin{rm}") ++ ("BID" . "") ;begin implementation dependent ++ ("BQ" . "~%\\begin{quotation}") ++ ("BV" . "~%\\begin{verbatim}") ++ ("C" . "{\\tt ~sa}") ;originally @code, but we don't want `' in info file ++ ("EF" . "\\end{rm}\\end{CLIverbatim}~%") ++ ("EID" . "") ;end implementation dependent ++ ("EM" . "{\\it ~sa}") ;emphasis ++ ("EQ" . "~%\\end{quotation}~%") ;TexInfo needs leading line break to ++ ;avoid problems with @refill ++ ("EV" . "\\end{verbatim}~%") ++ ("I" . "{\\it ~sa}") ++ ("ID" . "~sa") ;implementation dependent ++ ("IL" . "~sa") ++ ("ILC" . "{\\tt ~sa}") ;originally @code, but problem with info file ++ ("L" . "See ~sA") ++ ("NL" . "\\hfill \\break ") ++ ("PAR" . "") ;paragraph mark, of no significance for latex ++ ("PL" . "see ~sA") ;used for parenthetical crossrefs ++ ("SC" . "{\\sc ~sa}") ;small caps ++ ("ST" . "{\\bf ~sa}") ;strong emphasis ++ ("T" . "{\\tt ~sa}") ++ ("TERMINAL" . "") ; terminal only, ignore ++ )) ++ +--- /dev/null ++++ acl2-6.0/interface/infix/README +@@ -0,0 +1,168 @@ ++Copyright (C) 1994,1995,1996 Computational Logic, Inc. (CLI). ++All Rights Reserved. ++ ++Infix printing for ++ ++ ACL2 Version 1.9 ++ ++Use of this software constitutes agreement with the terms of ACL2 ++license agreement, found in the file LICENSE in the top level ACL2 ++distribution directory. ++ ++Comments, bugs, suggestions to: ++ ++ Michael K. Smith ++ Computational Logic Inc. ++ 1717 W 6th, Suite 290 ++ Austin, TX 78703-4776 ++ ++ Fax : (512) 322-0656 ++ Email: mksmith@cli.com ++ ++ Date : Mar 27 59 ++ ++-------------------------------------------------------------------------- ++PROBLEMS ++ ++The only known problem (as of the above date) is with `!' formatting ++directives in comments. If you depend on this capability (by using ++INFIX-FILE with `:comment t') then you need to make sure that all uses ++of ! in your file are acceptable. In general, ! as punctuation will ++be fine, but things like `{!foo}*' will cause problems, i.e. you may ++experience unpredictable formatting results, or worse, a break into ++lisp. In this case, you will need to either correct the problem or run ++INFIX-FILE with `!' processing suppressed (which is the default). ++You can guarantee it by: ++ ++ (infix-file "foo" :comment nil) ++ ++There is also a problem with deeply indented forms in LaTeX. The ++depth of indentation permitted depends on your LaTeX installation. On ++ours, it is 13, which is wired into the file latex-init.lisp, in the ++variable *latex-indent-number-limit*. If this limit is exceeded the ++form is printed as lisp, rather than in infix, and we issue a message: ++ ++ Warning: Tab limit reached in event local ++ Hand massaging required. ++ ++-------------------------------------------------------------------------- ++INSTALLATION ++ ++For decent speed the system should be compiled. ++ ++The best way to build the system is as follows: ++ ++1. First build ACL2 ++ ++2. Connect to the infix installation directory. ++ ++3. Set the following macros properly in the file "makefile": ++ ++ LISP = acl2 ++ DIR = /slocal/src/acl2/v1-8/interface/infix ++ LPR = lpr ++ DVI = dvips ++ ++DIR should point to the installation directory. When I use {$DIR} in ++the rest of this file, I mean for it to be replaced by whatever you ++have set DIR to. LPR should be the command on your system to print ++a .ps file. DVI should print LaTeX output, without requiring an extension. ++ ++4. UNFORTUNATE NOTE: Near the top of the file "infix.lisp" is the form ++ ++ (require "sloop" "/slocal/src/acl2/v1-8/interface/infix/sloop") ++ ++You need to change that directory name to reflect the actual location ++of the infix sources. E.g. ++ ++ (require "sloop" "{$DIR}/sloop") ++ ++5. Do: ++ ++ make compile ++ ++It is important to do this in the directory in which infix resides. ++For one thing, that's where the makefile is and for another it causes ++the variable, *infix-directory*, to get set properly. ++ ++It is possible to build the system in a bare lisp by setting ++`LISP=lucid' or some other lisp. But I do not recommend this as the ++system has not been extensively tested in that mode. ++ ++6. To perform a simple test of the system and get some idea of what ++the results look like do: ++ ++ make example ++ ++Depending on what MODE is set to in your makefile, this will either produce ++infix-examples.ps (from Scribe) or infix-examples.dvi file (from LaTeX) and ++send them to a poscript printer. ++ ++7. You might want to make the script doinfix executable (by `chmod +x doinfix'). ++You can then infix your files at the shell prompt by ++ ++ doinfix file.lisp scribe & ++ ++In order for this to work you will first need to modify the following ++line in doinfix: ++ ++ set DIR = /slocal/src/acl2/v1-8/interface/infix ++ ++to point to ${DIR}. ++-------------------------------------------------------------------------- ++USE ++ ++The simplest way to run the program is to use step 7, above. Failing ++that, the next simplest approach is as follows: ++ ++Connect to the directory containing the ACL2 .lisp files that you want ++to convert to infix. ++ ++If `LISP' was set to ACL2 in the compilation phase then start up ACL2 ++and do: ++ ++ :q ;; to exit the ACL2 loop ++ (in-package "user") ++ (load "{$DIR}/infix") ++ ++Where `{$DIR}' is whatever directory path is needed to get to ++"infix.o". ++ ++If 'LISP' was set to something else, start that lisp and do: ++ ++ (load "{$DIR}/infix") ++ ++In either case, the basic call is then ++ ++ (infix-file <file> :mode <mode>) ++ ++where <file> is the name of a .lisp file and, in the ++simplest case, <mode> is one of "scribe" or "latex". For example: ++ ++ (infix-file "clock" :mode "scribe") ++ (infix-file "clock.lisp" :mode "scribe") works too. ++ ++See the documentation in infix.lisp for information on user ++parameterization and extension of modes. In particular, see the ++section `SETTINGS THAT MAY BE MODIFIED IN MODE-THEORY.LISP'. ++ ++Just as a note, if you have an events file, say clock.lisp, and ++create a corresponding theory file, clock-theory.lisp, then you can ++use the even simpler invocation: ++ ++ (infix-file "clock") ++ ++The simplest such a clock-theory file might just consist of: ++ ++ (in-package "user") ++ (load-base "latex-theory") ++ ++By default, infix expects the scribe-theory and latex-theory files to ++be in *infix-directory*. And they in turn expect their corresponding ++-init files to be there also. ++ ++Other -theory files may reside in *infix-directory* or in the `current ++directory' (defined to be the directory returned by (probe-file "./") ++at execution time). The current directory is checked first. ++ ++ +--- /dev/null ++++ acl2-6.0/interface/emacs/top-start-shell-acl2.el +@@ -0,0 +1,8 @@ ++(defvar *acl2-interface-dir* ++ "/projects/acl2/v2-x/interface/emacs/") ++ ++(setq *acl2-user-map-interface* ++ '((global keys))) ++ ++(let ((load-path (cons *acl2-interface-dir* load-path))) ++ (load "load-shell-acl2")) +--- /dev/null ++++ acl2-6.0/interface/emacs/README-mouse.ps +@@ -0,0 +1,1421 @@ ++%!PS-Adobe-2.0 ++%%Title: README.mss ++%%DocumentFonts: (atend) ++%%Creator: J Strother Moore and Scribe 7(1750) ++%%CreationDate: 18 September 1995 15:44 ++%%Pages: (atend) ++%%EndComments ++% PostScript Prelude for Scribe. ++/BS {/SV save def ++ /PH exch 100 div def ++ /PW exch 100 div def ++ 0.0 PH translate ++ .01 -.01 scale} bind def ++/ES {SV restore showpage} bind def ++/SC {setrgbcolor} bind def ++/FMTX matrix def ++/RDF {WFT SLT 0.0 eq ++ {SSZ 0.0 0.0 SSZ neg 0.0 0.0 FMTX astore} ++ {SSZ 0.0 SLT neg sin SLT cos div SSZ mul SSZ neg 0.0 0.0 FMTX astore} ++ ifelse makefont setfont} bind def ++/SLT 0.0 def ++/SI { /SLT exch cvr def RDF} bind def ++/WFT /Courier findfont def ++/SF { /WFT exch findfont def RDF} bind def ++/SSZ 1000.0 def ++/SS { /SSZ exch 100.0 mul def RDF} bind def ++/AF { /WFT exch findfont def /SSZ exch 100.0 mul def RDF} bind def ++/MT /moveto load def ++/PF{transform .25 sub round .25 add exch ++ .25 sub round .25 add exch itransform} bind def ++/RPF{currentpoint exch 4 1 roll ++ add 3 1 roll add exch PF} bind def ++/XM {currentpoint exch pop moveto} bind def ++/UL {gsave newpath moveto dup 2.0 div 0.0 exch RPF moveto ++ setlinewidth 0.0 rlineto stroke grestore} bind def ++/LH {gsave newpath PF moveto setlinewidth ++ 0.0 rlineto ++ gsave stroke grestore} bind def ++/LV {gsave newpath PF moveto setlinewidth ++ 0.0 exch rlineto ++ gsave stroke grestore} bind def ++/BX {gsave newpath PF moveto setlinewidth ++ exch ++ dup 0.0 RPF lineto ++ exch 0.0 exch neg RPF lineto ++ neg 0.0 RPF lineto ++ closepath ++ gsave stroke grestore} bind def ++/BX1 {grestore} bind def ++/BX2 {setlinewidth 1 setgray stroke grestore} bind def ++/PB {/PV save def newpath translate ++ 100.0 -100.0 scale pop /showpage {} def} bind def ++/PE {PV restore} bind def ++/GB {/PV save def newpath translate rotate ++ div dup scale 100.0 -100.0 scale /showpage {} def} bind def ++/GE {PV restore} bind def ++/FB {dict dup /FontMapDict exch def begin} bind def ++/FM {cvn exch cvn exch def} bind def ++/FE {end /original-findfont /findfont load def /findfont ++ {dup FontMapDict exch known{FontMapDict exch get} if ++ original-findfont} def} bind def ++/BC {gsave moveto dup 0 exch rlineto exch 0 rlineto neg 0 exch rlineto closepath clip} bind def ++/EC /grestore load def ++/SH /show load def ++/MX {exch show 0.0 rmoveto} bind def ++/W {0 32 4 -1 roll widthshow} bind def ++/WX {0 32 5 -1 roll widthshow 0.0 rmoveto} bind def ++/RC {100.0 -100.0 scale ++PW 0.0 translate ++-90.0 rotate ++.01 -.01 scale} bind def ++/URC {100.0 -100.0 scale ++90.0 rotate ++PW neg 0.0 translate ++.01 -.01 scale} bind def ++/RCC {100.0 -100.0 scale ++0.0 PH neg translate 90.0 rotate ++.01 -.01 scale} bind def ++/URCC {100.0 -100.0 scale ++-90.0 rotate 0.0 PH translate ++.01 -.01 scale} bind def ++/CL {gsave newpath moveto setrgbcolor ++ exch ++ dup 0.0 rlineto ++ exch 0.0 exch neg rlineto ++ neg 0.0 rlineto ++ fill grestore} bind def ++%%EndProlog ++%%Page: 1 1 ++ ++93600 79200 BS ++0 SI ++13 /Times-Roman AF ++19716 9892 MT ++(The ACL2 Prooftree and Mouse Interface)SH ++10 SS ++24655 13132 MT ++(M. Kaufmann & M. K. Smith)SH ++12 /Times-Bold AF ++7200 17536 MT ++(1. Introduction)300 W ++10 /Times-Roman AF ++7200 19478 MT ++(NOTE: This) ++425 W( interface should be considered preliminary, although it has been used successfully at Computational)87 W ++7200 20583 MT ++(Logic, Inc. It is not part of the ACL2 software in the strictest sense \050which is co-authored by Matt) ++29 W( Kaufmann and J)30 W ++7200 21688 MT ++(Moore\051, but we feel that it will be useful to ACL2 users.)SH ++7200 23898 MT ++(This note describes how to get the ACL2/Emacs prooftree and mouse support. You just need to add) ++177 W( a single)176 W ++7200 25003 MT ++(autoload form to your .emacs file. And then issue the correspoding M-x command.)SH ++7200 27213 MT ++(The prooftree support has been tested in the following Emacs:)SH ++7450 28823 MT ++(Emacs 18)SH ++7450 29928 MT ++(Emacs 19) ++SH( -) ++1750 W( with comint and WFS's shell, sshell.el.)SH ++7450 31033 MT ++(Lemacs 19)SH ++7200 33243 MT ++(The menu and mouse support currently works with Emacs 19.)SH ++/Times-Bold SF ++7200 35453 MT ++(If you don't want) ++245 W( to deal with any of this:)246 W ++/Times-Roman SF ++28098 XM ++(You probably want to put the following form in your acl2-)246 W ++7200 36558 MT ++(customization.lisp file.)SH ++/Courier-Bold SF ++7800 38820 MT ++(:STOP-PROOF-TREE)SH ++/Times-Roman SF ++7200 41768 MT ++(This will turn off the proof tree printing from ACL2. For documentation in ACL2 do)SH ++/Courier-Bold SF ++7800 43573 MT ++(:doc proof-tree)SH ++/Times-Roman SF ++7200 45390 MT ++(To turn proof trees back on use `:START-PROOF-TREE'.)SH ++7200 46495 MT ++(NOTE: If you do `:STOP-PROOF-TREE' in ACL2, then M-x start-proof-tree will not) ++2 W( accomplish anything useful in)1 W ++7200 47600 MT ++(Emacs.)SH ++12 /Times-Bold AF ++7200 51284 MT ++(2. LOADING) ++300 W( EMACS INTERFACE CODE)SH ++11 SS ++7200 54181 MT ++(2.1 Simplest) ++275 W( .emacs Additions)SH ++10 /Times-Roman AF ++7200 56035 MT ++(If you want the full interface, put the following in your .emacs file after) ++23 W( replacing /slocal/src/acl2/v1-8/ with the full)24 W ++7200 57140 MT ++(pathname of your acl2-sources/ directory.)SH ++/Courier-Bold SF ++7800 59402 MT ++(\050setq *acl2-interface-dir*)SH ++9000 60533 MT ++("/slocal/src/acl2/v1-8/interface/emacs/"\051)SH ++7800 62795 MT ++(\050autoload 'run-acl2 ;;)SH ++/Times-Italic SF ++(emacs 19.27 only at this time)SH ++/Courier-Bold SF ++9000 63926 MT ++(\050concat *acl2-interface-dir* "top-start-inferior-acl2"\051)SH ++9000 65057 MT ++("Begin ACL2 in an inferior ACL2 mode buffer.")SH ++9000 66188 MT ++(t\051)SH ++/Times-Roman SF ++7200 69136 MT ++(Then, to get things started in Emacs do `M-x run-acl2'. Use `M-x acl2-mode' to get `<acl2-file>.lisp' into) ++30 W( the right)29 W ++7200 70241 MT ++(mode. The) ++278 W( commands in the various modes are listed in a later) ++14 W( section. But you can see most of them by observing)15 W ++7200 71346 MT ++(the new) ++62 W( pull-down menus and pop-up menu in inferior ACL2 mode and ACL2 mode. The pop-up menu is tied to)61 W ++ES ++%%Page: 2 2 ++ ++93600 79200 BS ++0 SI ++10 /Times-Roman AF ++7200 4286 MT ++(The ACL2 Prooftree and Mouse Interface)SH ++53500 XM ++(2)SH ++7200 5391 MT ++(Internal Note)SH ++7200 9686 MT ++(mouse-3.)SH ++7200 11896 MT ++(If you just want proof trees, use the following after replacing /slocal/src/acl2/v1-8/ with the full) ++80 W( pathname of your)81 W ++7200 13001 MT ++(acl2-sources/ directory.)SH ++/Courier-Bold SF ++7800 15263 MT ++(\050setq *acl2-interface-dir*)SH ++9000 16394 MT ++("/slocal/src/acl2/v1-8/interface/emacs/"\051)SH ++7200 18656 MT ++(\050autoload 'start-proof-tree)SH ++8400 19787 MT ++(\050concat *acl2-interface-dir* "top-start-shell-acl2"\051)SH ++8400 20918 MT ++("Enable proof tree logging in a prooftree buffer.")SH ++8400 22049 MT ++(t\051)SH ++11 /Times-Bold AF ++7200 26077 MT ++(2.2 More) ++275 W( Control from .emacs: Setting preferences)SH ++10 /Times-Roman AF ++7200 27931 MT ++(The alist, *acl2-user-map-interface*, determines what menus you) ++86 W( get. If a feature is included after a mode name,)85 W ++7200 29036 MT ++(then you get it.)SH ++/Courier-Bold SF ++7200 31298 MT ++(\050defvar *acl2-user-map-interface*)SH ++8400 32429 MT ++('\050\050inferior-acl2-mode menu-bar popup-menu keys\051)SH ++9600 33560 MT ++(\050acl2-mode menu-bar) ++5400 W( popup-menu keys\051)SH ++9600 34691 MT ++(\050prooftree-mode menu-bar) ++2400 W( popup-menu keys\051\051\051)SH ++/Times-Roman SF ++7200 38032 MT ++(If you set the following to T, you will switch to the inferior ACL2 buffer) ++46 W( when you send forms, regions, or buffers)47 W ++7200 39137 MT ++(to it.)SH ++/Courier-Bold SF ++7800 41399 MT ++(\050setq *acl2-eval-and-go* nil\051)SH ++/Times-Roman SF ++7200 44347 MT ++(If you set the following) ++78 W( to NIL you will be queried for their values when you start up a prooftree buffer \050via M-x)77 W ++7200 45452 MT ++(start-proof-tree\051. These) ++250 W( are the defaults you get based on the autoload above.)SH ++/Courier-Bold SF ++7800 47714 MT ++(\050setq *acl2-proof-tree-height* 17\051)SH ++7800 48845 MT ++(\050setq *checkpoint-recenter-line* 3\051)SH ++12 /Times-Bold AF ++7200 53660 MT ++(3. Commands)300 W ++10 /Times-Roman AF ++7200 55602 MT ++(Commands are enabled based on the value of the alist, *acl2-user-map-interface*, as described above.) ++101 W( There) ++454 W( are)102 W ++7200 56707 MT ++(some conventions that you need to know regarding arguments to mouse commands.)SH ++7200 58917 MT ++(If a menu bar entry is of the form)SH ++7950 60527 MT ++(Print event ...)SH ++7200 62137 MT ++(the "..." indicates that you will be prompted in the minibuffer for an argument.)SH ++7200 64347 MT ++(If a menu bar entry is of the form)SH ++7950 65957 MT ++(Mode >)SH ++7200 67567 MT ++(the ">" indicates a suborninate menu that will pop up if you release on this menu item.)SH ++7200 69777 MT ++(Pop-up menu items indicate whether) ++59 W( they take an argument based on a preceding ".". The argument is determined)58 W ++7200 70882 MT ++(by what you clicked on to bring up the) ++105 W( menu. Arguments derived from things that appear in the chronology are)106 W ++7200 71987 MT ++(somewhat robust. So that if you had a list of events on the screen like:)SH ++ES ++%%Page: 3 3 ++ ++93600 79200 BS ++0 SI ++10 /Times-Roman AF ++7200 4286 MT ++(The ACL2 Prooftree and Mouse Interface)SH ++53500 XM ++(3)SH ++7200 5391 MT ++(Internal Note)SH ++/Courier-Bold SF ++12600 9674 MT ++(13 \050DEFMACRO) ++600 W( TEXT \050X\051 ...\051)SH ++7800 10805 MT ++(L 14) ++3600 W( \050DEFUN) ++600 W( MSG-P \050X\051 ...\051)SH ++7800 11936 MT ++(L 15) ++3600 W( \050DEFUN) ++600 W( MAKE-PACKET \050X Y Z\051 ...\051)SH ++7800 13067 MT ++(L 16) ++3600 W( \050DEFUN) ++600 W( HISTORY-P \050L\051 ...\051)SH ++12600 14198 MT ++(17 \050DEFMACRO) ++600 W( INFROM \050X\051 ...\051)SH ++/Times-Roman SF ++7200 16015 MT ++(to see event 14 you could click right anywhere on that line and select either ". Print Event" or ". Print Command".)SH ++11 /Times-Bold AF ++7200 18912 MT ++(3.1 Prooftree) ++275 W( Related)SH ++10 /Times-Roman AF ++9000 20766 MT ++(M-x start-proof-tree)SH ++9000 21871 MT ++(M-x stop-proof-tree)SH ++11 /Times-Bold AF ++7200 24768 MT ++(3.2 Prooftree) ++275 W( Mode)SH ++7200 27665 MT ++(3.2-A POPUP) ++275 W( MENU)SH ++10 /Times-Roman AF ++9000 29519 MT ++(Abort)SH ++23400 XM ++(Abort *inferior-acl2*.)SH ++9000 30624 MT ++(Goto subgoal)SH ++23400 XM ++(Go to clicked on subgoal in *inferior-acl2*.)SH ++9000 31729 MT ++(Resume proof tree)SH ++23400 XM ++(Resume printing proof tree.)SH ++9000 32834 MT ++(Suspend proof tree)SH ++23400 XM ++(Suspend printing proof tree.)SH ++9000 33939 MT ++(Checkpoint/Suspend)SH ++23400 XM ++(Suspend prooftree and go to clicked on checkpoint.)SH ++9000 35044 MT ++(Checkpoint)SH ++23400 XM ++(Go to clicked on checkpoint.)SH ++9000 36149 MT ++(Help)SH ++11 /Times-Bold AF ++7200 39046 MT ++(3.2-B MENU) ++275 W( BAR)SH ++10 /Times-Roman AF ++9000 40900 MT ++(Prooftree)SH ++11050 42510 MT ++(Checkpoint)SH ++23400 XM ++(Go to next checkpoint)SH ++11050 43615 MT ++(Goto subgoal)SH ++23400 XM ++(That cursor is on.)SH ++11050 44720 MT ++(Checkpoint / Suspend)SH ++23400 XM ++(Go to next checkpoint and suspend proof tree.)SH ++11050 45825 MT ++(Resume proof tree)SH ++11050 46930 MT ++(Suspend proof tree)SH ++11050 48035 MT ++(Abort)SH ++23400 XM ++(Abort prooftree. \050ACL2 will continue to send prooftrees, it just)SH ++23400 49140 MT ++(won't go the the prooftree buffer.\051)SH ++11050 50245 MT ++(Help)SH ++11 /Times-Bold AF ++7200 53142 MT ++(3.2-C KEYS)275 W ++10 /Times-Roman AF ++9000 54996 MT ++(C-z z)SH ++23400 XM ++(Previous C-z key binding)SH ++9000 56101 MT ++(C-z c)SH ++23400 XM ++(Go to checkpoint)SH ++9000 57206 MT ++(C-z s)SH ++23400 XM ++(Suspend proof tree)SH ++9000 58311 MT ++(C-z r)SH ++23400 XM ++(Resume proof tree)SH ++9000 59416 MT ++(C-z a)SH ++23400 XM ++(Mfm abort secondary buffer)SH ++9000 60521 MT ++(C-z g)SH ++23400 XM ++(Goto subgoal)SH ++9000 61626 MT ++(C-z h)SH ++23400 XM ++(help)SH ++9000 62731 MT ++(C-z ?)SH ++23400 XM ++(help)SH ++ES ++%%Page: 4 4 ++ ++93600 79200 BS ++0 SI ++10 /Times-Roman AF ++7200 4286 MT ++(The ACL2 Prooftree and Mouse Interface)SH ++53500 XM ++(4)SH ++7200 5391 MT ++(Internal Note)SH ++11 /Times-Bold AF ++7200 9737 MT ++(3.3 ACL2) ++275 W( Mode)SH ++10 /Times-Roman AF ++7200 11591 MT ++(ACL2 Mode is like Lisp) ++147 W( mode except that the functions that send sexprs to the inferior Lisp process expect an)146 W ++7200 12696 MT ++(inferior ACL2 process in the *inferior-acl2* buffer.)SH ++11 /Times-Bold AF ++7200 15593 MT ++(3.3-A POPUP) ++275 W( MENU)SH ++10 /Times-Roman AF ++9000 17447 MT ++(Send to ACL2)SH ++23400 XM ++(Send top level form clicked on to ACL2.)SH ++9000 18552 MT ++(Add hint)SH ++23400 XM ++(Add the hint form to the clicked on defun.)SH ++10800 20162 MT ++(Do not induct.)SH ++10800 21267 MT ++(Do not generalize.)SH ++10800 22372 MT ++(Do not fertilize.)SH ++10800 23477 MT ++(Expand)SH ++23400 XM ++(expand form. Requests you mouse it.)SH ++10800 24582 MT ++(Hands off.)SH ++10800 25687 MT ++(Disable)SH ++23400 XM ++(Disable symbol. Requests you mouse it.)SH ++10800 26792 MT ++(Enable)SH ++23400 XM ++(Enable symbol. Requests you mouse it.)SH ++10800 27897 MT ++(Induct)SH ++23400 XM ++(Induct based on form. Requests you mouse it.)SH ++10800 29002 MT ++(Cases)SH ++23400 XM ++(Perform case split on form.Requests you mouse it.)SH ++9000 30612 MT ++(Go to inferior ACL2)SH ++9000 31717 MT ++(Verify)SH ++23400 XM ++(Take clicked on form into interactive prover.)SH ++11 /Times-Bold AF ++7200 34614 MT ++(3.3-B KEYS)275 W ++10 /Times-Roman AF ++9000 36468 MT ++(C-x C-e)SH ++23400 XM ++(eval last sexp)SH ++9000 37573 MT ++(C-c C-r)SH ++23400 XM ++(eval region)SH ++9000 38678 MT ++(C-M-x)SH ++23400 XM ++(eval defun)SH ++9000 39783 MT ++(C-c C-e)SH ++23400 XM ++(eval defun)SH ++9000 40888 MT ++(C-c C-z)SH ++23400 XM ++(switch to ACL2)SH ++9000 41993 MT ++(C-c C-l)SH ++23400 XM ++(load file)SH ++9000 43098 MT ++(C-c C-a)SH ++23400 XM ++(show arglist)SH ++9000 44203 MT ++(C-c C-d)SH ++23400 XM ++(describe symbol)SH ++9000 45308 MT ++(C-c C-f)SH ++23400 XM ++(show function documentation)SH ++9000 46413 MT ++(C-c C-v)SH ++23400 XM ++(show variable documentation)SH ++9000 47518 MT ++(C-ce)SH ++23400 XM ++(eval defun and go to ACL2)SH ++9000 48623 MT ++(C-cr)SH ++23400 XM ++(eval region and go to ACL2)SH ++11 /Times-Bold AF ++7200 51520 MT ++(3.4 Inferior) ++275 W( ACL2 Mode)SH ++7200 54417 MT ++(3.4-A MENU) ++275 W( BAR)SH ++10 /Times-Roman AF ++9000 56271 MT ++(Events)SH ++11050 57881 MT ++(Recent events)SH ++23400 XM ++(\050pbt '\050:here -10\051\051)SH ++11050 58986 MT ++(Print back through ...)SH ++23400 XM ++(\050pbt <event>\051)SH ++11050 60091 MT ++(Undo)SH ++23400 XM ++(\050ubt ':here\051)SH ++11050 61196 MT ++(Oops)SH ++23400 XM ++(\050oops\051)SH ++11050 62301 MT ++(Undo through ...)SH ++23400 XM ++(\050ubt '<event>\051)SH ++11050 63406 MT ++(Undo through ...)SH ++23400 XM ++(\050ubt! '<cd>\051)SH ++11050 65616 MT ++(Load file ...)SH ++23400 XM ++(\050cl2-load-file\051)SH ++11050 67826 MT ++(Disable ...)SH ++23400 XM ++(\050in-theory \050disable <symbol>\051\051)SH ++11050 68931 MT ++(Enable ...)SH ++23400 XM ++(\050in-theory \050enable <symbol>\051\051)SH ++11050 71141 MT ++(Verify guards ...)SH ++23400 XM ++(\050verify-guards '<symbol>\051)SH ++ES ++%%Page: 5 5 ++ ++93600 79200 BS ++0 SI ++10 /Times-Roman AF ++7200 4286 MT ++(The ACL2 Prooftree and Mouse Interface)SH ++53500 XM ++(5)SH ++7200 5391 MT ++(Internal Note)SH ++11050 9686 MT ++(Verify termination ...)SH ++23400 XM ++(\050verify-guards '<symbol>\051)SH ++11050 11896 MT ++(Certify-book ...)SH ++23400 XM ++(\050certify-book <filename>\051)SH ++11050 13001 MT ++(Include-book ...)SH ++23400 XM ++(\050include-book <filename> \051)SH ++10800 15211 MT ++(Compound commands)SH ++12850 16821 MT ++(Expand compound command ...)SH ++27000 XM ++(\050puff '<cd>\051)SH ++12850 17926 MT ++(Expand compound command! ...)SH ++27000 XM ++(\050puff* '<cd>\051)SH ++10800 20136 MT ++(Table)SH ++12850 21746 MT ++(Print value ...)SH ++23400 XM ++(\050table symbol\051)SH ++12850 22851 MT ++(Clear ...)SH ++23400 XM ++(\050table <symbol> nil nil :clear)SH ++12850 23956 MT ++(Print guard ...)SH ++23400 XM ++(\050table <symbol> nil nil :guard\051)SH ++9000 26166 MT ++(Print)SH ++11050 28376 MT ++(Event ...)SH ++23400 XM ++(\050pe 'event\051)SH ++11050 29481 MT ++(Event! ...)SH ++23400 XM ++(\050pe! 'event\051)SH ++11050 30586 MT ++(Back through ...)SH ++23400 XM ++(\050pbt 'event\051)SH ++11050 32796 MT ++(Command ...)SH ++23400 XM ++(\050pc '<cd>\051)SH ++11050 33901 MT ++(Command block ...)SH ++23400 XM ++(\050pcb '<cd>\051)SH ++11050 35006 MT ++(Full Command block ...)SH ++23400 XM ++(\050pcb! '<cd>\051)SH ++11050 37216 MT ++(Signature ...)SH ++23400 XM ++(\050args 'event\051)SH ++11050 38321 MT ++(Formula ...)SH ++23400 XM ++(\050pf 'event\051)SH ++11050 39426 MT ++(Properties ...)SH ++23400 XM ++(\050props 'event\051)SH ++11050 41636 MT ++(Print connected book directory)SH ++25200 XM ++(\050cbd\051)SH ++11050 43846 MT ++(Rules whose top function symbol is ...)SH ++27000 XM ++(\050pl 'event\051)SH ++11050 44951 MT ++(Rules stored by event ...)SH ++23400 XM ++(\050pr 'event\051)SH ++11050 46056 MT ++(Rules stored by command ...)SH ++23400 XM ++(\050pr! '<cd>\051)SH ++11050 48266 MT ++(Monitored-runes)SH ++23400 XM ++(\050monitored-runes\051)SH ++9000 50476 MT ++(Control)SH ++11050 52686 MT ++(Load ...)SH ++23400 XM ++(\050ld filename\051)SH ++11050 53791 MT ++(Accumulated Persistence)SH ++13100 55401 MT ++(Activate)SH ++23400 XM ++(\050accumulated-persistence t\051)SH ++13100 56506 MT ++(Deactivate)SH ++23400 XM ++(\050accumulated-persistence nil\051)SH ++13100 57611 MT ++(Display statistics ordered by)SH ++15150 59221 MT ++(frames)SH ++23400 XM ++(\050show-accumulated-persistence :frames\051)SH ++15150 60326 MT ++(times tried)SH ++23400 XM ++(\050show-accumulated-persistence :tries\051)SH ++15150 61431 MT ++(ratio)SH ++23400 XM ++(\050show-accumulated-persistence :ratio\051)SH ++12600 63041 MT ++(Break rewrite)SH ++14650 64651 MT ++(Start general rule monitoring)SH ++27000 XM ++(\050brr t\051)SH ++14650 65756 MT ++(Stop general rule monitoring)SH ++27000 XM ++(\050brr nil\051)SH ++14650 66861 MT ++(Print monitored runes)SH ++25200 XM ++(\050monitored-runes\051)SH ++14650 67966 MT ++(Monitor rune: ...)SH ++23400 XM ++(\050monitor '\050:definition <event>\051 't\051)SH ++14650 69071 MT ++(Unmonitor rune: ...)SH ++23400 XM ++(\050unmonitor '\050:definition <event>\051\051)SH ++12600 71281 MT ++(Commands)SH ++ES ++%%Page: 6 6 ++ ++93600 79200 BS ++0 SI ++10 /Times-Roman AF ++7200 4286 MT ++(The ACL2 Prooftree and Mouse Interface)SH ++53500 XM ++(6)SH ++7200 5391 MT ++(Internal Note)SH ++14650 9686 MT ++(Abort to ACL2 top-level)SH ++25200 XM ++(#.)SH ++14650 10791 MT ++(Term being rewritten)SH ++23400 XM ++(:target)SH ++14650 11896 MT ++(Substitution making :lhs equal :target)SH ++30600 XM ++(:unify-subst)SH ++14650 13001 MT ++(Hypotheses)SH ++23400 XM ++(:hyps)SH ++14650 14106 MT ++(Ith hypothesis ...)SH ++23400 XM ++(:hyp <integer>)SH ++14650 15211 MT ++(Left-hand side of conclusion)SH ++27000 XM ++(:lhs)SH ++14650 16316 MT ++(Right-hand side of conclusion)SH ++27000 XM ++(:rhs)SH ++14650 17421 MT ++(Type assumptions governing :target)SH ++30600 XM ++(:type-alist)SH ++14650 18526 MT ++(Ttree before :eval)SH ++23400 XM ++(:initial-ttree)SH ++14650 19631 MT ++(Negations of backchaining hyps pursued)SH ++32400 XM ++(:ancestors)SH ++14650 21841 MT ++(Rewrite's path from top clause to :target)SH ++32400 XM ++(:path)SH ++14650 22946 MT ++(Top-most frame in :path)SH ++25200 XM ++(:top)SH ++14650 24051 MT ++(Ith frame in :path ...)SH ++23400 XM ++(:frame <integer>)SH ++12600 26261 MT ++(AFTER :EVAL)SH ++14650 27871 MT ++(Did application succeed?)SH ++25200 XM ++(:wonp)SH ++14650 28976 MT ++(Rewritten :rhs)SH ++23400 XM ++(:rewritten-rhs)SH ++14650 30081 MT ++(Ttree)SH ++23400 XM ++(:final-ttree)SH ++14650 31186 MT ++(Reason rule failed)SH ++23400 XM ++(:failure-reason)SH ++12600 33396 MT ++(CONTROL)SH ++14650 35006 MT ++(Exit break)SH ++23400 XM ++(:ok)SH ++14650 36111 MT ++(Exit break, printing result)SH ++25200 XM ++(:go)SH ++14650 37216 MT ++(Try rule and re-enter break afterwards)SH ++30600 XM ++(:eval)SH ++12600 39426 MT ++(WITH NO RECURSIVE BREAKS)SH ++14650 41036 MT ++(:ok!)SH ++23400 XM ++(\050:ok!\051)SH ++14650 42141 MT ++(:go!)SH ++23400 XM ++(\050:go!\051)SH ++14650 43246 MT ++(:eval!)SH ++23400 XM ++(\050:eval!\051)SH ++12600 45456 MT ++(WITH RUNES MONITORED DURING RECURSION)SH ++14650 47066 MT ++(:ok ...)250 W ++23400 XM ++(\050:ok$ sexpr\051)SH ++14650 48171 MT ++(:go ...)SH ++23400 XM ++(\050:go$ sexpr\051)250 W ++14650 49276 MT ++(:eval ...)SH ++23400 XM ++(\050:eval$ sexpr\051)SH ++12850 50886 MT ++(Help)SH ++23400 XM ++(\050:help\051)SH ++11050 52496 MT ++(Enter ACL2 Loop)SH ++23400 XM ++(\050lp\051)SH ++11050 53601 MT ++(Quit to Common Lisp)SH ++23400 XM ++(:Q)SH ++11050 54706 MT ++(ABORT)SH ++23400 XM ++(\050:good-bye\051)SH ++9000 56916 MT ++(Settings)SH ++10800 59126 MT ++(Mode)SH ++12850 60736 MT ++(Logic)SH ++23650 XM ++(\050logic\051)SH ++12850 61841 MT ++(Program)SH ++23650 XM ++(\050program\051)SH ++12850 62946 MT ++(Guard checking on)SH ++23400 XM ++(\050set-guard-checking t\051)SH ++12850 64051 MT ++(Guard checking off)SH ++23400 XM ++(\050set-guard-checking nil\051)SH ++10800 66261 MT ++(Forcing)SH ++12850 67871 MT ++(On)SH ++23400 XM ++(\050enable-forcing\051)SH ++12850 68976 MT ++(Off)SH ++23400 XM ++(\050disable-forcing\051)SH ++10800 71186 MT ++(Compile functions)SH ++ES ++%%Page: 7 7 ++ ++93600 79200 BS ++0 SI ++10 /Times-Roman AF ++7200 4286 MT ++(The ACL2 Prooftree and Mouse Interface)SH ++53500 XM ++(7)SH ++7200 5391 MT ++(Internal Note)SH ++12850 9686 MT ++(On)SH ++23400 XM ++(\050set-compile-fns t\051)SH ++12850 10791 MT ++(Off)SH ++23400 XM ++(\050set-compile-fns nil\051)SH ++10800 13001 MT ++(Proof tree)SH ++12850 14611 MT ++(Start prooftree)SH ++23400 XM ++(\050start-proof-tree\051pre \050start-proof-tree nil\051\051)SH ++12850 15716 MT ++(Stop prooftree)SH ++23400 XM ++(\050stop-proof-tree\051post \050stop-proof-tree\051\051)SH ++12850 16821 MT ++(Checkpoint forced goals on)SH ++25200 XM ++(\050checkpoint-forced-goals\051)SH ++10800 19031 MT ++(Inhibit Display of)SH ++12850 20641 MT ++(Error messages)SH ++23400 XM ++(\050assign inhibit-output-lst '\050error\051\051)SH ++12850 21746 MT ++(Warnings)SH ++23400 XM ++(\050assign inhibit-output-lst '\050warning\051\051)SH ++12850 22851 MT ++(Observations)SH ++23400 XM ++(\050assign inhibit-output-lst '\050observation\051\051)SH ++12850 23956 MT ++(Proof commentary)SH ++23400 XM ++(\050assign inhibit-output-lst '\050prove\051\051)SH ++12850 25061 MT ++(Proof tree)SH ++23400 XM ++(\050assign inhibit-output-lst '\050prove\051\051)SH ++12850 26166 MT ++(Non-proof commentary)SH ++23400 XM ++(\050assign inhibit-output-lst '\050event\051\051)SH ++12850 27271 MT ++(Summary)SH ++23400 XM ++(\050assign inhibit-output-lst '\050summary\051\051)SH ++10800 29481 MT ++(Unused Variables)SH ++12850 31091 MT ++(Ignore)SH ++23400 XM ++(\050set-ignore-ok t\051)SH ++12850 32196 MT ++(Fail)SH ++23400 XM ++(\050set-ignore-ok nil\051)SH ++12850 33301 MT ++(Warn)SH ++23400 XM ++(\050set-ignore-ok :warn\051)SH ++10800 35511 MT ++(Irrelevant formulas)SH ++12850 37121 MT ++(Ok)SH ++23400 XM ++(\050set-irrelevant-formals-ok t\051)SH ++12850 38226 MT ++(Fail)SH ++23400 XM ++(\050set-irrelevant-formals-ok nil\051)SH ++12850 39331 MT ++(Warn)SH ++23400 XM ++(\050set-irrelevant-formals-ok :warn\051)SH ++10800 41541 MT ++(Load)SH ++12600 43151 MT ++(Error action)SH ++14650 44761 MT ++(Continue)SH ++23400 XM ++(\050set-ld-error-actions :continue\051)SH ++14650 45866 MT ++(Return)SH ++23400 XM ++(\050set-ld-error-actions :return\051)SH ++14650 46971 MT ++(Error)SH ++23400 XM ++(\050set-ld-error-actions :error\051)SH ++12600 49181 MT ++(Error triples)SH ++14650 50791 MT ++(On)SH ++23400 XM ++(\050set-ld-error-triples t\051)SH ++14650 51896 MT ++(Off)SH ++23400 XM ++(\050set-ld-error-triples nil\051)SH ++12600 54106 MT ++(Post eval print)SH ++14650 55716 MT ++(On)SH ++23400 XM ++(\050set-ld-post-eval-print t\051)SH ++14650 56821 MT ++(Off)SH ++23400 XM ++(\050set-ld-post-eval-print nil\051)SH ++14650 57926 MT ++(Command conventions)SH ++25200 XM ++(\050set-ld-post-eval-print :command-conventions\051)SH ++12600 60136 MT ++(Pre eval filter)SH ++14650 61746 MT ++(All)SH ++23400 XM ++(\050set-ld-pre-eval-filter :all\051)SH ++14650 62851 MT ++(Query)SH ++23400 XM ++(\050set-ld-pre-eval-filter :query\051)SH ++12600 65061 MT ++(Prompt)SH ++14650 66671 MT ++(On)SH ++23400 XM ++(\050set-ld-prompt t\051)SH ++14650 67776 MT ++(Off)SH ++23400 XM ++(\050set-ld-prompt nil\051)SH ++12600 69986 MT ++(Skip proofs)SH ++14650 71596 MT ++(On)SH ++23400 XM ++(\050set-ld-skip-proofs t\051)SH ++ES ++%%Page: 8 8 ++ ++93600 79200 BS ++0 SI ++10 /Times-Roman AF ++7200 4286 MT ++(The ACL2 Prooftree and Mouse Interface)SH ++53500 XM ++(8)SH ++7200 5391 MT ++(Internal Note)SH ++14650 9686 MT ++(Off)SH ++23400 XM ++(\050set-ld-skip-proofs nil\051)SH ++12600 11896 MT ++(Verbose: on)SH ++14650 13506 MT ++(On)SH ++23400 XM ++(\050set-ld-verbose t\051)SH ++14650 14611 MT ++(Off)SH ++23400 XM ++(\050set-ld-verbose nil\051)SH ++12850 16821 MT ++(Redefinition permitted)SH ++23400 XM ++(\050redef\051)SH ++12850 17926 MT ++(Reset specials)SH ++23400 XM ++(\050reset-ld-specials t\051)SH ++12600 19031 MT ++(HACKERS. DANGER!)SH ++14650 20641 MT ++(RED redefinition!)SH ++23400 XM ++(\050redef!\051)SH ++10800 23956 MT ++(Books)SH ++12850 25566 MT ++(Print connected book directory)SH ++27000 XM ++(\050cbd\051)SH ++12850 26671 MT ++(Set connected book directory ...)SH ++27000 XM ++(\050set-cbd filename\051)SH ++12850 27776 MT ++(Certify-book ...)SH ++23400 XM ++(\050certify-book filename\051)SH ++12850 28881 MT ++(Include-book ...)SH ++23400 XM ++(\050include-book filename\051)SH ++10800 31091 MT ++(ACL2 Help)SH ++12850 32701 MT ++(Documentation)SH ++23400 XM ++(\050doc '<symbol>\051)SH ++12850 33806 MT ++(Arguments)SH ++23400 XM ++(\050args '<symbol>\051)SH ++12850 34911 MT ++(More)SH ++23400 XM ++(\050more\051)SH ++12850 36016 MT ++(Apropos ...)SH ++23400 XM ++(\050docs '<symbol>\051)SH ++12850 37121 MT ++(Info)SH ++23400 XM ++(\050cl2-info\051)SH ++12850 38226 MT ++(Tutorial)SH ++23400 XM ++(\050acl2-info-tutorial\051)SH ++12850 39331 MT ++(Release Notes)SH ++23400 XM ++(\050cl2-info-release-notes\051)SH ++11 /Times-Bold AF ++7200 43333 MT ++(3.4-B INFERIOR) ++275 W( ACL2 POPUP MENU)SH ++10 /Times-Roman AF ++9250 45187 MT ++(Recent events)SH ++23400 XM ++(\050pbt '\050:here -10\051\051)SH ++9250 46292 MT ++(Print Event)SH ++23400 XM ++(\050pe '<symbol>\051)SH ++9250 47397 MT ++(Print back to)SH ++23400 XM ++(\050pbt '<cd>\051)SH ++9250 48502 MT ++(Disable)SH ++23400 XM ++(\050in-theory \050disable <symbol>\051\051)SH ++9250 49607 MT ++(Enable)SH ++23400 XM ++(\050in-theory \050enable <symbol>\051\051)SH ++9250 50712 MT ++(Undo)SH ++23400 XM ++(\050ubt ':here\051)SH ++9250 51817 MT ++(Undo thru)SH ++23400 XM ++(\050ubt '<cd>\051)SH ++9250 52922 MT ++(Documentation)SH ++23400 XM ++(\050doc '<symbol>\051)SH ++9250 54027 MT ++(Arguments, etc)SH ++23400 XM ++(\050args '<symbol>\051)SH ++9250 55132 MT ++(Verify)SH ++23400 XM ++(Take clicked on form into interactive prover.)SH ++11 /Times-Bold AF ++7200 58029 MT ++(3.4-C KEYS)275 W ++10 /Times-Roman AF ++9000 59883 MT ++(C-x C-e)SH ++23400 XM ++(Eval last sexp)SH ++9000 60988 MT ++(C-c C-l)SH ++23400 XM ++(Load file)SH ++9000 62093 MT ++(C-c C-a)SH ++23400 XM ++(Show arglist)SH ++9000 63198 MT ++(C-c C-d)SH ++23400 XM ++(Describe symbol)SH ++9000 64303 MT ++(C-c C-f)SH ++23400 XM ++(Show function documentation)SH ++9000 65408 MT ++(C-c C-v)SH ++23400 XM ++(Show variable documentation)SH ++9000 66513 MT ++(C-cl)SH ++23400 XM ++(Load file)SH ++9000 67618 MT ++(C-ck)SH ++23400 XM ++(Compile file)SH ++9000 68723 MT ++(C-ca)SH ++23400 XM ++(Show arglist)SH ++9000 69828 MT ++(C-cd)SH ++23400 XM ++(Describe symbol)SH ++9000 70933 MT ++(C-cf)SH ++23400 XM ++(Show function documentation)SH ++ES ++%%Page: 9 9 ++ ++93600 79200 BS ++0 SI ++10 /Times-Roman AF ++7200 4286 MT ++(The ACL2 Prooftree and Mouse Interface)SH ++53500 XM ++(9)SH ++7200 5391 MT ++(Internal Note)SH ++9000 9686 MT ++(C-cv)SH ++23400 XM ++(Show variable documentation)SH ++ES ++%%Page: i 10 ++ ++93600 79200 BS ++0 SI ++10 /Times-Roman AF ++30461 75600 MT ++(i)SH ++13 /Times-Bold AF ++18956 9871 MT ++(The ACL2 Prooftree and Mouse Interface)SH ++25977 14548 MT ++(Table of Contents)SH ++11 /Times-Roman AF ++9400 18903 MT ++(1. Introduction) ++SH( .) ++62 W( . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .)SH ++53450 XM ++(1)SH ++9400 20099 MT ++(2. LOADING EMACS INTERFACE CODE) ++SH( .) ++33 W( . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .)SH ++53450 XM ++(1)SH ++10 SS ++10200 21204 MT ++(2.1. Simplest .emacs Additions) ++SH( .) ++55 W( . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .)SH ++53500 XM ++(1)SH ++10200 22309 MT ++(2.2. More Control from .emacs: Setting preferences) ++SH( .) ++365 W( . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .)SH ++53500 XM ++(2)SH ++11 SS ++9400 23505 MT ++(3. Commands) ++SH( .) ++488 W( . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .)SH ++53450 XM ++(2)SH ++10 SS ++10200 24610 MT ++(3.1. Prooftree Related) ++SH( .) ++224 W( . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .)SH ++53500 XM ++(3)SH ++10200 25715 MT ++(3.2. Prooftree Mode) ++SH( .) ++446 W( . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .)SH ++53500 XM ++(3)SH ++11200 26820 MT ++(3.2-A. POPUP MENU) ++SH( .) ++389 W( . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .)SH ++53500 XM ++(3)SH ++11200 27925 MT ++(3.2-B. MENU BAR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .)SH ++53500 XM ++(3)SH ++11200 29030 MT ++(3.2-C. KEYS) ++SH( .) ++139 W( . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .)SH ++53500 XM ++(3)SH ++10200 30135 MT ++(3.3. ACL2 Mode) ++SH( .) ++667 W( . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .)SH ++53500 XM ++(4)SH ++11200 31240 MT ++(3.3-A. POPUP MENU) ++SH( .) ++389 W( . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .)SH ++53500 XM ++(4)SH ++11200 32345 MT ++(3.3-B. KEYS) ++SH( .) ++139 W( . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .)SH ++53500 XM ++(4)SH ++10200 33450 MT ++(3.4. Inferior ACL2 Mode) ++SH( .) ++363 W( . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .)SH ++53500 XM ++(4)SH ++11200 34555 MT ++(3.4-A. MENU BAR) ++SH( .) ++445 W( . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .)SH ++53500 XM ++(4)SH ++11200 35660 MT ++(3.4-B. INFERIOR ACL2 POPUP MENU) ++SH( .) ++333 W( . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .)SH ++53500 XM ++(8)SH ++11200 36765 MT ++(3.4-C. KEYS) ++SH( .) ++139 W( . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .)SH ++53500 XM ++(8)SH ++ES ++%%Trailer ++%%Pages: 10 ++%%DocumentFonts: Times-Roman Times-Bold Courier-Bold Times-Italic +--- /dev/null ++++ acl2-6.0/interface/emacs/acl2-interface.el +@@ -0,0 +1,454 @@ ++ ++;; Add interface for various acl2 buffers. ++;; Sep 20 94 MKS ++ ++;; ---------------------------------------------------------------------- ++;; USER SETTINGS ++ ++;; The following controls what features of the interfaces get used. ++;; These settings mirror those in start-inferior-acl2.el. ++;; You can override these setting by setting them in your .emacs file. ++ ++;; The variable, *acl2-user-map-interface*, is an alist of modes . (list of features). ++;; The features currently supported are: menu-bar, pop-up-menu, and keys. ++;; The default below says add them all. ++ ++;; Before the menu-bar, popup-menu or keys are defined we check ++;; the following alist to see what the user wants. ++ ++(defvar *acl2-user-map-interface* ++ '((inferior-acl2-mode-map menu-bar popup-menu keys) ++ (shell-mode-map menu-bar popup-menu keys) ++ (acl2-mode-map menu-bar popup-menu keys) ++ (prooftree-mode-map menu-bar popup-menu keys))) ++ ++;; (defvar *acl2-proof-tree-height* 17) ++;; (defvar *checkpoint-recenter-line* 3) ++ ++;; ---------------------------------------------------------------------- ++;; Load all of the various acl2-interface files, if necessary. ++ ++;(load "inf-acl2.el") ;(require 'inf-acl2) ++;(load "mfm-acl2.el") ;(require 'mfm-acl2) ++;(load "interface-macros.el") ;(require 'interface-macros) ++ ++(require 'inf-acl2) ++(require 'mfm-acl2) ++(require 'interface-macros) ++ ++(update-mode-menu-alist *acl2-user-map-interface*) ++ ++;(load "acl2-interface-functions.el") ++(load "acl2-interface-functions") ++ ++;; ---------------------------------------------------------------------- ++;; Specials used by functions in interface-macros.el. ++ ++;; MENU-BAR-FINAL-ITEMS is a global, honored by all menu-bar presentations. ++;; If the menu-bar contains any element whose car (a SYMBOL) ++;; is in it, that element will appear after any not mentioned. ++;; The ordering of MENU-BAR-FINAL-ITEMS is honored in the presentation. ++(setq menu-bar-final-items '(events help-acl2 help)) ++ ++(defconst general-wrapper "(acl2-wrap (acl2::%s))\n") ++(defconst verify-wrapper "(lisp %s)\n") ++(defconst acl2-wrapper "(%s)\n") ++(defconst interface-wrapper acl2-wrapper) ++ ++(setq interface-to-top '(inf-acl2-last-line-to-top)) ++(setq menu-bar-prefix "acl2-menu-bar-%s") ++ ++(setq interface-menu-function '(inf-acl2-send-string <command> <arg>)) ++(setq interface-popup-function '(inf-acl2-send-string <command> <arg>)) ++ ++;; These alists allow us to handle some arguments to menu and popup function ++;; differently from the defaults above. ++ ++(setq menu-arg-functions ++ (append (cons 'cd ++ '(cond ((not cd) (beep t)) ++ (t (inf-acl2-send-string <command> cd)))) ++ menu-arg-functions)) ++ ++(setq popup-arg-functions ++ (append (cons 'cd ++ '(let ((thing (thing-at-click click 'symbol)) ++ (number (thing-at-click click 'number))) ++ (cond (thing (inf-acl2-send-string <command> thing)) ++ ((and (stringp number) ++ (numberp (setq number (int-to-string number)))) ++ (inf-acl2-send-string <command> number)) ++ (t (beep t))))) ++ popup-arg-functions)) ++ ++;; ====================================================================== ++;; Inferior acl2 ++ ++;; ---------------------------------------------------------------------- ++;; Inferior acl2 menu bar. The buffer containing the Acl2 process. ++ ++(defconst inf-acl2-menu-bar ++ '((:menu "History" ++ (:entry "Recent events" "pbt '(:here -10)" :to-top) ++ (:entry "Print back through ..." "pbt '%s" :arg event :to-top) ++ ++ (:entry "Undo" "u") ++ (:entry "Oops" "oops" ) ++ (:entry "Undo through ..." "ubt '%s" :arg event) ++ (:entry "Undo! through ..." "ubt! '%s" :arg cd) ++ (:label "") ++ (:entry "Load file ..." acl2-load-file) ++ (:label "") ++ (:entry "Disable ..." "in-theory (disable %s)" :arg symbol) ++ (:entry "Enable ..." "in-theory (enable %s)" :arg symbol) ++ (:label "") ++ (:entry "Verify guards ..." "verify-guards '%s" :arg symbol) ++ (:entry "Verify termination ..." "verify-termination '%s" :arg symbol) ++ (:label "") ++ (:entry "Certify-book ..." "certify-book \"%s\"" :arg filename) ; world of 0 commands ++ (:entry "Include-book ..." "include-book \"%s\"" :arg filename) ++ (:label "") ++ (:menu "Compound commands" ++ (:entry "Expand ..." "puff '%s" :arg cd :to-top) ++ (:entry "Expand! ..." "puff* '%s" :arg cd :to-top)) ++ (:menu "Table" ++ (:entry "Print value ..." "table %s" :arg symbol) ++ (:entry "Clear ..." "table %s nil nil :clear" :arg symbol) ++ (:entry "Print guard ..." "table %s nil nil :guard" :arg symbol) ++ ;; ("Print element ..." "(table <arg1> <arg2>)") ++ ;; ("Set element ..." "(table <arg1> <arg2> <arg3>)") ++ ;; ("Set value ..." "(table <arg1> nil <arg2> :clear)") ++ ;; ("Set Guard ..." "(table <arg1> nil nil :guard <arg2>)") ++ )) ++ (:menu "Print" ++ (:entry "Event ..." "pe '%s" :arg event :to-top) ++ (:entry "Event! ..." "pe! '%s" :arg event :to-top) ++ (:entry "Back through ..." "pbt '%s" :arg event :to-top) ++ ++ (:entry "Command ..." "pc '%s" :arg cd :to-top) ++ (:entry "Command block ..." "pcb '%s" :arg cd :to-top) ++ (:entry "Full Command block ..." "pcb! '%s" :arg cd :to-top) ++ ++ (:entry "Signature ..." "args '%s" :arg event :to-top) ++ (:entry "Formula ..." "pf '%s" :arg event :to-top) ++ (:entry "Properties ..." "props '%s" :arg event :to-top) ++ ++ (:entry "Print connected book directory" "cbd") ++ ++ (:entry "Rules whose top function symbol is ..." "pl '%s" :arg event :to-top) ++ (:entry "Rules stored by event ..." "pr '%s" :arg event :to-top) ++ (:entry "Rules stored by command ..." "pr! '%s" :arg cd :to-top) ++ ++ (:entry "Monitored-runes" "monitored-runes")) ++ ++ (:menu "Control" ++ (:entry "Load ..." "ld \"%s\"" :arg filename) ++ (:entry "Compile all" "comp t") ++ (:entry "Compile ..." "comp '%s" :arg symbol) ++ ++ (:menu "Accumulated Persistence" ++ (:entry "Activate" "accumulated-persistence t") ++ (:entry "Deactivate" "accumulated-persistence nil") ++ (:menu "Display statistics ordered by" ++ (:entry "frames" "show-accumulated-persistence :frames") ++ (:entry "times tried" "show-accumulated-persistence :tries") ++ (:entry "ratio" "show-accumulated-persistence :ratio"))) ++ ++ (:menu "Break rewrite" ++ (:entry "Start general rule monitoring" "brr t") ++ (:entry "Stop general rule monitoring" "brr nil") ++ (:entry "Print monitored runes" "monitored-runes") ++ (:entry "Monitor rune: ..." "monitor '(:definition %s) 't" :arg event) ++ (:entry "Unmonitor rune: ..." "unmonitor '(:definition %s)" :arg event) ++ ;; (:entry "Conditionally exit break-rewrite" "ok-if") ++ ;; Above needs an argument. ++ (:label "") ++ (:menu "Commands" ++ (:entry "Abort to ACL2 top-level" "#." :unwrapped) ++ (:entry "Term being rewritten" ":target" :unwrapped) ++ (:entry "Substitution making :lhs equal :target" ":unify-subst" :unwrapped) ++ (:entry "Hypotheses" ":hyps" :unwrapped) ++ (:entry "Ith hypothesis ..." ":hyp %d" :arg integer :unwrapped) ++ (:entry "Left-hand side of conclusion" ":lhs" :unwrapped) ++ (:entry "Right-hand side of conclusion" ":rhs" :unwrapped) ++ (:entry "Type assumptions governing :target" ":type-alist" :unwrapped) ++ (:entry "Ttree before :eval" ":initial-ttree" :unwrapped) ++ (:entry "Negations of backchaining hyps pursued" ":ancestors" :unwrapped) ++ ++ (:label "") ++ (:entry "Rewrite's path from top clause to :target" ":path" :unwrapped) ++ (:entry "Top-most frame in :path" ":top" :unwrapped) ++ (:entry "Ith frame in :path ..." ":frame %d" :arg integer :unwrapped) ++ ++ (:label "") ++ (:menu "AFTER :EVAL" ++ (:entry "Did application succeed?" ":wonp" :unwrapped) ++ (:entry "Rewritten :rhs" ":rewritten-rhs" :unwrapped) ++ (:entry "Ttree" ":final-ttree" :unwrapped) ++ (:entry "Reason rule failed" ":failure-reason" :unwrapped)) ++ ++ (:menu "CONTROL" ++ (:entry "Exit break" ":ok" :unwrapped) ++ (:entry "Exit break, printing result" ":go" :unwrapped) ++ (:entry "Try rule and re-enter break afterwards" ":eval" :unwrapped)) ++ ++ (:menu "WITH NO RECURSIVE BREAKS" ++ (:entry ":ok!" ":ok!") ++ (:entry ":go!" ":go!") ++ (:entry ":eval!" ":eval!")) ++ ++ (:menu "WITH RUNES MONITORED DURING RECURSION" ++ (:entry ":ok ..." ":ok$ %s" :arg sexpr) ++ (:entry ":go ..." ":go$ %s" :arg sexpr) ++ (:entry ":eval ..." ":eval$ %s" :arg sexpr)) ++ (:label "") ++ (:entry "Help" ":help"))) ++ (:entry "Enter Acl2 Loop" "(lp)" :unwrapped) ++ (:entry "Quit to Common Lisp" ":Q" :unwrapped) ++ (:entry "ABORT" ":good-bye")) ++ ++ (:menu "Settings" ++ (:menu "Mode" ++ (:entry "Logic" "logic") ++ (:entry "Program" "program") ++ (:entry "Guard checking on" "set-guard-checking t") ++ (:entry "Guard checking off" "set-guard-checking nil")) ++ (:menu "Forcing" ++ (:entry "On" "enable-forcing") ++ (:entry "Off" "disable-forcing")) ++ (:menu "Compile functions" ++ (:entry "On" "set-compile-fns t") ++ (:entry "Off" "set-compile-fns nil")) ++ (:menu "Proof tree" ++ (:entry "Start prooftree" "start-proof-tree" :pre (start-proof-tree nil)) ++ (:entry "Stop prooftree" "stop-proof-tree" :post (stop-proof-tree)) ++ (:entry "Checkpoint forced goals on" "checkpoint-forced-goals t") ++ (:entry "Checkpoint forced goals on" "checkpoint-forced-goals nil")) ++ (:menu "Inhibit Display of " ++ (:entry "Error messages" "assign inhibit-output-lst '(error)") ++ (:entry "Warnings" "assign inhibit-output-lst '(warning)") ++ (:entry "Observations" "assign inhibit-output-lst '(observation)") ++ (:entry "Proof commentary" "assign inhibit-output-lst '(prove)") ++ (:entry "Proof tree" "assign inhibit-output-lst '(proof-tree)") ++ (:entry "Non-proof commentary" "assign inhibit-output-lst '(event)") ++ (:entry "Summary" "assign inhibit-output-lst '(summary)")) ++ (:menu "Unused Variables" ++ (:entry "Ignore" "set-ignore-ok t") ++ (:entry "Fail" "set-ignore-ok nil") ++ (:entry "Warn" "set-ignore-ok :warn")) ++ (:menu "Irrelevant formulas" ++ (:entry "Ok" "set-irrelevant-formals-ok t") ++ (:entry "Fail" "set-irrelevant-formals-ok nil") ++ (:entry "Warn" "set-irrelevant-formals-ok :warn")) ++ (:menu "Load" ++ (:menu "Error action" ++ (:entry "Continue" "set-ld-error-actions :continue") ++ (:entry "Return" "set-ld-error-actions :return") ++ (:entry "Error" "set-ld-error-actions :error")) ++ (:menu "Error triples" ++ (:entry "On" "set-ld-error-triples t") ++ (:entry "Off" "set-ld-error-triples nil")) ++ (:menu "Post eval print" ++ (:entry "On" "set-ld-post-eval-print t") ++ (:entry "Off" "set-ld-post-eval-print nil") ++ (:entry "Command conventions" "set-ld-post-eval-print :command-conventions")) ++ (:menu "Pre eval filter" ++ (:entry "All" "set-ld-pre-eval-filter :all") ++ (:entry "Query" "set-ld-pre-eval-filter :query")) ++ (:menu "Prompt" ++ (:entry "On" "set-ld-prompt t") ++ (:entry "Off" "set-ld-prompt nil")) ++ (:menu "Skip proofs" ++ (:entry "On" "set-ld-skip-proofs t") ++ (:entry "Off" "set-ld-skip-proofs nil")) ++ (:menu "Verbose: on" ++ (:entry "On" "set-ld-verbose t") ++ (:entry "Off" "set-ld-verbose nil")) ++ (:entry "Redefinition permitted" "redef") ++ (:entry "Reset specials" "reset-ld-specials nil") ++ (:entry "Reset specials (+ I/O)" "reset-ld-specials t") ++ (:menu "HACKERS. DANGER!" ;advanced ++ (:entry "Redefinition permitted!" "redef!")))) ++ ++ (:menu "Books" ++ (:entry "Print connected book directory" "cbd") ++ (:entry "Set connected book directory ..." "set-cbd %s" :arg filename) ++ (:entry "Certify-book ..." "certify-book \"%s\"" :arg filename) ++ (:entry "Include-book ..." "include-book \"%s\"" :arg filename)) ++ ++ (:menu "Acl2 Help" ++ (:entry "Documentation" "doc '%s" :arg symbol :to-top) ++ (:entry "Arguments" "args '%s" :arg symbol :to-top) ++ (:entry "More" "more") ++ (:entry "Apropos ..." "docs '%s" :arg symbol :to-top) ++ (:entry "Menu help" acl2-menu-help)))) ++ ++ ++;; ---------------------------------------------------------------------- ++;; Inferior acl2 popup menu. The buffer containing the Acl2 process. ++ ++(defconst inferior-acl2-popup ++ '((:entry "Recent events" "pbt '(:here -10)") ++ (:entry ". Print Event" "pe '%s" :arg event) ++ (:entry ". Print Command" "pc '%s" :arg cd) ++ (:entry ". Print back to" "pbt '%s" :arg cd) ++ (:entry ". Disable" "in-theory (disable %s)" :arg event) ++ (:entry ". Enable" "in-theory (enable %s)" :arg event) ++ (:entry "Undo" "ubt ':here") ++ (:entry ". Undo thru" "ubt '%s" :arg cd) ++ (:entry ". Documentation" "doc '%s" :arg symbol) ++ (:entry ". Arguments, etc" "args '%s" :arg symbol) ++ (:label "") ++ (:entry ". Verify" acl2-mouse-verify click))) ++ ++ ++;; ---------------------------------------------------------------------- ++;; inferior acl2 keys ++ ++(defconst inferior-acl2-keys ++ '(("\C-x\C-e" acl2-eval-last-sexp) ++ ("\C-c\C-l" acl2-load-file) ++ ("\C-c\C-a" acl2-show-arglist) ++ ("\C-c\C-d" acl2-describe-sym) ++ ("\C-c\C-f" acl2-show-function-documentation) ++ ("\C-c\C-v" acl2-show-variable-documentation) ++ ("\C-cl" acl2-load-file) ++ ("\C-ck" acl2-compile-file) ++ ("\C-ca" acl2-show-arglist) ++ ("\C-cd" acl2-describe-sym) ++ ("\C-cf" acl2-show-function-documentation) ++ ("\C-cv" acl2-show-variable-documentation))) ++ ++(define-interface inferior-acl2-mode inferior-acl2-mode-map ++ inf-acl2-menu-bar ++ '(inout completion signals) ++ inferior-acl2-popup ++ inferior-acl2-keys) ++ ++;; ====================================================================== ++;; Acl2 mode ++ ++;; ---------------------------------------------------------------------- ++;; Acl2 mode popup menu. For buffers containing Acl2 code. ++ ++;; For acl2-mode-map ++;; What happened to default-menu ??? We just overwrite it. ++ ++(defconst acl2-menu-bar-value nil) ++ ++(defconst acl2-popup-menu-value ++ '((:entry ". Send to Acl2" acl2-eval-event-at-click :arg click) ++ ++ (:entry "Send region to Acl2" acl2-mouse-eval-region) ++ (:entry "Send buffer to Acl2" acl2-mouse-eval-buffer) ++ ++ (:entry ". Add hint" add-hint-to-defun-at-click :arg click) ++ (:entry "Go to inferior Acl2" switch-to-acl2-eof) ++ (:entry ". Verify" acl2-mouse-verify :arg click))) ++ ++(defconst acl2-keys ; due to inferior acl2 ++ '(("\C-x\C-e" acl2-eval-last-sexp) ++ ("\C-c\C-r" acl2-eval-region) ++ ("\M-\C-x" acl2-eval-event) ++ ("\C-c\C-e" acl2-eval-event) ++ ("\C-c\C-z" switch-to-acl2-eof) ++ ("\C-c\C-l" acl2-load-file) ++ ("\C-c\C-a" acl2-show-arglist) ++ ("\C-c\C-d" acl2-describe-sym) ++ ("\C-c\C-f" acl2-show-function-documentation) ++ ("\C-c\C-v" acl2-show-variable-documentation) ++ ("\C-ce" acl2-eval-event-and-go) ++ ("\C-cr" acl2-eval-region-and-go))) ++ ++(define-interface acl2-mode acl2-mode-map ++ acl2-menu-bar-value ++ nil ++ acl2-popup-menu-value ++ acl2-keys) ++ ++ ++;; ====================================================================== ++;; Prooftree mode ++ ++;; ---------------------------------------------------------------------- ++;; Prooftree mode menu-bar menu. ++ ++(defconst prooftree-menu-bar ++ '((:menu "Prooftree" ++ (:entry "Checkpoint" acl2-menu-checkpoint) ++ (:entry "Checkpoint / Suspend" acl2-menu-checkpoint-suspend) ++ (:entry "Suspend proof tree" suspend-proof-tree) ++ (:entry "Resume proof tree" resume-proof-tree) ++ (:entry ". Goto subgoal" goto-subgoal) ++ (:entry "Help" checkpoint-help) ++ ))) ++ ++ ++;; ---------------------------------------------------------------------- ++;; Prooftree pop-up menu ++ ++;; Unconditionally expects prooftree-mode-map to be set. ++;; Prooftree mode should have already been established by mfm-acl2. ++ ++(defconst prooftree-popup-menu-value ++ '((:entry ". Checkpoint" acl2-mouse-checkpoint :arg click) ++ (:entry ". Goto subgoal" goto-subgoal-menu :arg click) ++ (:entry ". Checkpoint/Suspend" acl2-mouse-checkpoint-suspend :arg click) ++ (:entry "Suspend proof tree" suspend-proof-tree) ++ (:entry "Resume proof tree" resume-proof-tree) ++ (:entry "Help" checkpoint-help) ++ )) ++ ++;; Defined in mfm-acl2 so that checkpoint-help can use it. ++(defvar prooftree-subkey) ++(setq prooftree-subkey "\C-z") ++ ++;; prooftree-subkeymap was set by prooftree-mode.el. Now do it here. ++(defvar prooftree-subkeymap (make-sparse-keymap)) ++ ++(defvar old-prooftree-subkey (key-binding prooftree-subkey)) ++ ++(define-key prooftree-mode-map prooftree-subkey prooftree-subkeymap) ++ ++(defconst prooftree-keys ++; WARNING: Keep this in sync with the corresponding definition in ++; key-interface.el. ++ (list ++ (list 'prooftree-subkeymap "z" old-prooftree-subkey) ++ (list 'prooftree-subkeymap "c" 'checkpoint) ++ (list 'prooftree-subkeymap "s" 'suspend-proof-tree) ++ (list 'prooftree-subkeymap "r" 'resume-proof-tree) ++ (list 'prooftree-subkeymap "g" 'goto-subgoal) ++ (list 'prooftree-subkeymap "h" 'checkpoint-help) ++ (list 'prooftree-subkeymap "?" 'checkpoint-help) ++ (list 'prooftree-subkeymap "o" 'prooftree-select-other-frame) ++ (list 'prooftree-subkeymap "b" 'visit-proof-tree) ++ (list 'prooftree-subkeymap "B" 'visit-proof-tree-other-frame))) ++ ++(define-interface prooftree-mode ;mode ++ prooftree-mode-map ;mode-map ++ prooftree-menu-bar ++ nil ;menu-bar-remove ++ prooftree-popup-menu-value ++ prooftree-keys) ++ ++;; Just in case this file gets loaded after checkpointing has started. ++;; (if (and (fboundp 'checkpoint) ++;; (bufferp (get-buffer "prooftree"))) ++;; (save-excursion ++;; (set-buffer "prooftree") ++;; (if (not (equal major-mode 'prooftree-mode)) ++;; (prooftree-mode) ++;; (run-hooks prooftree-mode-hook)))) ++ ++(provide 'acl2-interface) ++ ++;; ====================================================================== ++;; TODO: ++;; ++;; ====================================================================== ++;; LOG: ++;; ++ ++ ++ +--- /dev/null ++++ acl2-6.0/interface/emacs/acl2-interface-functions.el +@@ -0,0 +1,467 @@ ++ ++;; ---------------------------------------------------------------------- ++;; Define the functions. ++ ++(defvar *acl2-eval-and-go* nil) ++ ++(defun acl2-eval-event-at-click (click) ++ "Go to click and execute acl2-eval-event" ++ (interactive "e") ++ (let ((posn (event-start click)) ++ (end (event-end click))) ++ (select-window (posn-window posn)) ++ (if (numberp (posn-point posn)) ++ (goto-char (posn-point posn))) ++ ;; If mark is highlighted, no need to bounce the cursor. ++ (acl2-eval-event *acl2-eval-and-go*))) ++ ++(defun acl2-mouse-eval-region () ++ (interactive) ++ (save-excursion ++ (let ((start (point)) ++ (end (mark))) ++ (if (<= start end) ++ (acl2-eval-region start end *acl2-eval-and-go*) ++ (acl2-eval-region end start *acl2-eval-and-go*))))) ++ ++(defun acl2-mouse-eval-buffer () ++ (interactive) ++ (save-excursion (acl2-eval-region (point-min) (point-max) *acl2-eval-and-go*))) ++ ++(defun this-line-to-top () (interactive) (recenter 0)) ++ ++(defun inf-acl2-last-line-to-top () ++ (save-excursion ++ (set-buffer inferior-acl2-buffer) ++ (goto-char (point-max)) ++ (this-line-to-top))) ++ ++(defun acl2-menu-help () ++ (interactive) ++ "Provides information about ACL2 menus, esp. where they get ++their arguments." ++ (with-output-to-temp-buffer "*Help*" ++ (princ "ACL2 Menu Use. ++----------------------------------------------------------------- ++If a menu bar entry is of the form ++ ++ Print event ... ++ ++the \"...\" indicates that you will be prompted in the minibuffer ++for an argument. The system normally tries to find a default based ++on where the cursor is in the buffer. ++ ++If a menu bar entry is of the form ++ ++ Mode > ++ ++the \">\" indicates that a suborninate menu will pop up if you ++release on this menu item. ++ ++Pop-up menu items indicate that they take an argument by a ++preceding \".\". The argument is determined by what you clicked on to ++bring up the menu. Arguments derived from things that appear in the ++chronology are somewhat robust. So that if you had a list of events ++on the screen like: ++ ++ 13 (DEFMACRO TEXT (X) ...) ++ L 14 (DEFUN MSG-P (X) ...) ++ L 15 (DEFUN MAKE-PACKET (X Y Z) ...) ++ L 16 (DEFUN HISTORY-P (L) ...) ++ 17 (DEFMACRO INFROM (X) ...) ++ ++to see event 14 you could mouse-right anywhere on that line and select ++either \". Print Event\" or \". Print Command\". ++"))) ++ ++(defun acl2-mouse-verify (click) ++ (interactive "e") ++ (send-verify-sexp-to-acl2-process click)) ++ ++;; Sep 16 94 MKSmith - new version ++(defun send-verify-sexp-to-acl2-process (click) ++ "Writes a form consisting of `(verify ' and the region of the current buffer ++delimited by point and the click to a temporary file. Closes with ')\n'. ++If other-window-p is not nil the buffer is selected ++in the other window, otherwise it is selected in the current window (unless ++it is currently exposed in another window)." ++ (let* ((process (inferior-acl2-proc)) ++ (cmd-string inferior-acl2-load-command) ++ (filename (temporary-filename (process-id process)))) ++ ++ (save-excursion ++ (let ((posn (event-start click))) ++ (select-window (posn-window posn)) ++ (if (numberp (posn-point posn)) ++ (goto-char (posn-point posn))) ++ (let ((b (point))) ++ ;; WRITE-REGION has the `feature' that if start is a string ++ ;; it gets written, rather than the region. ++ (write-region "(acl2::verify " nil filename nil 'nomessage) ++ (forward-sexp 1) ++ (write-region b (point) filename t 'nomessage) ++ (write-region ")\n" nil filename t 'nomessage)) ++ (process-send-string process (format cmd-string filename)))) ++ (switch-to-acl2 t))) ++ ++(defvar inf-acl2-saved-menu-bar-items nil) ++ ++;; These are used by the prooftree menus. ++ ++(defun acl2-menu-checkpoint () (interactive) (checkpoint nil)) ++ ++(defun acl2-menu-checkpoint-suspend () (interactive) (checkpoint t)) ++ ++(defun goto-subgoal-menu (click) ++ (interactive "e") ++ (let ((posn (event-start click)) ++ (end (event-end click))) ++ (select-window (posn-window posn)) ++ (if (numberp (posn-point posn)) ++ (goto-char (posn-point posn))) ++ (goto-subgoal (checkpoint-on-line)))) ++ ++(defun acl2-mouse-checkpoint (click) ++ "Go to checkpoint clicked on in the \"prooftree\" buffer with ++the character \"c\" in the first column. " ++ (interactive "e") ++ (let ((posn (event-start click)) ++ (end (event-end click))) ++ (select-window (posn-window posn)) ++ (if (numberp (posn-point posn)) ++ (goto-char (posn-point posn))) ++ (checkpoint nil))) ++ ++(defun acl2-mouse-checkpoint-suspend (click) ++ "Go to checkpoint clicked on in the \"prooftree\" buffer with ++the character \"c\" in the first column. " ++ (interactive "e") ++ (let ((posn (event-start click)) ++ (end (event-end click))) ++ (select-window (posn-window posn)) ++ (if (numberp (posn-point posn)) ++ (goto-char (posn-point posn))) ++ (checkpoint t))) ++ ++;; ---------------------------------------------------------------------- ++ ++(defun read-event-name-with-default () ++ (let* (this-event ++ (x (read-string (format "Event name (default: %s)" ++ (setq this-event (event-at-cursor)))))) ++ (if (string-equal x "") ++ this-event ++ x))) ++ ++(defun read-cd-with-default () ++ (let* (this-event ++ (x (read-string (format "Command id (default: %s)" ++ (setq this-event (cd-at-cursor)))))) ++ (if (string-equal x "") ++ this-event ++ x))) ++ ++(setq menu-interactive-arg ++ (append menu-interactive-arg ++ '((event (interactive (list (read-event-name-with-default)))) ++ (cd (interactive (list (read-cd-with-default)))) ++ (command (interactive (list (read-cd-with-default))))))) ++ ++(setq popup-menu-interactive-arg ++ (append menu-interactive-arg ++ '((event (interactive "e")) ++ (cd (interactive "X")) ++ (command (interactive "X"))))) ++ ++(setq menu-arg-name ++ (append menu-arg-name ++ '((cd cd) (command cd) (event event)))) ++ ++;; Syntax for event in history ++;; L d 52 (DEFUN FOO (X) X) ++;; P d 52 (DEFUN FOO (X) X) ++;; PLd 52 (DEFUN FOO (X) X) ++;; > (DEFTHM TRUE-LISTP-APP ++;; /LVd 52 (DEFUN FOO (X) X) ++;; LV 53 (DEFUN BAR (X) (CONS X X)) ++;; \ 54 (DEFUN FOO (X) X) ++ ++;; In each of the following patterns the command descriptor # is in ++;; (string-to-number (buffer-substring (match-beginning 1) (match-end 1))) ++;; And the event begins at (match-end 0), though it may not be an event. ++ ++(defconst *acl2-history-cd-line-format1* ++ "^[/\\ \t][PLV ][PLV ][d ][ \t]+\\([-0-9]+\\)[:x ]+") ++ ++(defconst *acl2-history-cd-line-format2* "^>[ \t]+") ++ ++(defconst *acl2-history-cd-line-format3* "^[ \trgbp]+\\([-0-9]+\\)[:x ]+" ++ "From older version of Acl2.") ++ ++(defconst *acl2-def-beginning* "([Dd][Ed][Ff][a-zA-z]+[ \t]+") ++ ++(defun event-at-cursor () ++ ;; Wants to return a string = event name. ++ (save-excursion ++ (beginning-of-line) ++ (if (save-excursion ++ (beginning-of-line) ++ (or (looking-at *acl2-history-cd-line-format1*) ++ (looking-at *acl2-history-cd-line-format2*) ++ (looking-at *acl2-history-cd-line-format3*))) ++ (goto-char (match-end 0))) ++ (if (looking-at *acl2-def-beginning*) ++ (goto-char (match-end 0))) ++ (symbol-at-cursor))) ++ ++(defun cd-at-cursor () ++ ;; Wants to return a command descriptor, preferably a number. ++ (save-excursion ++ (cond ((save-excursion ++ (beginning-of-line) ++ (or (looking-at *acl2-history-cd-line-format1*) ++ (looking-at *acl2-history-cd-line-format3*))) ++ (string-to-number (buffer-substring (match-beginning 1) (match-end 1)))) ++ ((looking-at *acl2-history-cd-line-format2*) ++ (goto-char (match-end 0)) ++ (if (looking-at *acl2-def-beginning*) ++ (progn (goto-char (match-end 0)))) ++ (symbol-at-cursor)) ++ (t (symbol-at-cursor))))) ++ ++ ++;; ---------------------------------------------------------------------- ++;; More utilities ++ ++(defun inferior-acl2-proc () ++ "Returns the current inferior Acl2 process. ++See variable `inferior-acl2-buffer'." ++ (let ((proc (get-buffer-process (if (eq major-mode 'inferior-acl2-mode) ++ (current-buffer) ++ inferior-acl2-buffer)))) ++ (or proc ++ (error "No Acl2 subprocess; see variable `inferior-acl2-buffer'")))) ++ ++;; Try to unwedge Acl2. ++ ++(defun acl2-abort-mystery-wedge () ++ (interactive) ++ ;; (let ((inferior-acl2-load-command ":q\n")) ++ ;; (acl2-send-sexp-and-go)) ++ (comint-send-string (inferior-acl2-proc) ":q\n")) ++ ++;;; Ancillary functions ++;;; =================== ++ ++;;; Reads a string from the user. ++(defun acl2-symprompt (prompt default) ++ (list (let* ((prompt (if default ++ (format "%s (default %s): " prompt default) ++ (concat prompt ": "))) ++ (ans (read-string prompt))) ++ (if (zerop (length ans)) default ans)))) ++ ++ ++(defvar acl2-prev-l/c-dir/file nil ++ "Record last directory and file used in loading or compiling. ++This holds a cons cell of the form `(DIRECTORY . FILE)' ++describing the last `acl2-load-file' or `acl2-compile-file' command.") ++ ++(defvar acl2-source-modes '(acl2-mode) ++ "Used to determine if a buffer contains Acl2 source code. ++If it's loaded into a buffer that is in one of these major modes, it's ++considered an Acl2 source file by `acl2-load-file' and `acl2-compile-file'. ++Used by these commands to determine defaults.") ++ ++(defun acl2-load-file (file-name) ++ "Load an Acl2 file into the inferior Acl2 process." ++ ;; 4th param below is NIL because LOAD doesn't need an exact name. ++ ;; But what about LD? ++ (interactive (comint-get-source "Load Acl2 file: " acl2-prev-l/c-dir/file ++ acl2-source-modes nil)) ++ (comint-check-source file-name) ; Check to see if buffer needs saved. ++ (setq acl2-prev-l/c-dir/file (cons (file-name-directory file-name) ++ (file-name-nondirectory file-name))) ++ (comint-send-string (inferior-acl2-proc) ++ (format inferior-acl2-load-command file-name)) ++ (switch-to-acl2 t)) ++ ++ ++;; ---------------------------------------------------------------------- ++;; NOT currently used ++ ++;; Adapted from function-called-at-point in help.el. ++(defun acl2-fn-called-at-pt () ++ "Returns the name of the function called in the current call. ++The value is nil if it can't find one." ++ (condition-case nil ++ (save-excursion ++ (save-restriction ++ (narrow-to-region (max (point-min) (- (point) 1000)) (point-max)) ++ (backward-up-list 1) ++ (forward-char 1) ++ (let ((obj (acl2-var-at-pt))) ++ (and (symbolp obj) obj)))) ++ (error nil))) ++ ++;;; Adapted from variable-at-point in help.el. ++(defun acl2-var-at-pt () ++ (condition-case () ++ (save-excursion ++ (forward-sexp 1) ++ (forward-sexp -1) ++ (skip-chars-forward "'") ++ (let* ((begin (point)) ++ (max (save-excursion (end-of-line) (point))) ++ (end (- (re-search-forward "[ ,()\\.!?#|`';']" max t) 1)) ++ (obj (car (read-from-string (buffer-substring begin end))))) ++ (and (symbolp obj) obj))) ++ (error nil))) ++ ++ ++;; NEEDED FOR KEY COMMANDS ++ ++(defvar acl2-function-doc-command ++ "(acl2::doc '%s)\n" ++ "Command to query inferior Acl2 for a function's documentation.") ++ ++(defvar acl2-var-doc-command ++ "(acl2::doc '%s)\n" ++ "Command to query inferior Acl2 for a variable's documentation.") ++ ++(defvar acl2-arglist-command ++ "(acl2::args '%s)\n" ++ "Command to query inferior Acl2 for a function's arglist.") ++ ++(defvar acl2-describe-sym-command ++ "(acl2::doc '%s)\n" ++ "Command to query inferior Acl2 for a variable's documentation.") ++ ++(defun acl2-show-function-documentation (fn) ++ "Send a command to the inferior Acl2 to give documentation for function FN. ++See variable `acl2-function-doc-command'." ++ (interactive (acl2-symprompt "Function doc" (acl2-fn-called-at-pt))) ++ (inf-acl2-last-line-to-top) ++ (comint-proc-query (inferior-acl2-proc) ++ (format acl2-function-doc-command fn))) ++ ++(defun acl2-describe-sym (sym) ++ "Send a command to the inferior Acl2 to describe symbol SYM. ++See variable `acl2-describe-sym-command'." ++ (interactive (acl2-symprompt "Describe" (acl2-var-at-pt))) ++ (inf-acl2-last-line-to-top) ++ (comint-proc-query (inferior-acl2-proc) ++ (format acl2-describe-sym-command sym))) ++ ++(defun acl2-show-arglist (fn) ++ "Send a query to the inferior Acl2 for the arglist for function FN. ++See variable `acl2-arglist-command'." ++ (interactive (acl2-symprompt "Arglist" (acl2-fn-called-at-pt))) ++ (inf-acl2-last-line-to-top) ++ (comint-proc-query (inferior-acl2-proc) (format acl2-arglist-command fn))) ++ ++(defun acl2-show-variable-documentation (var) ++ "Send a command to the inferior Acl2 to give documentation for function FN. ++See variable `acl2-var-doc-command'." ++ (interactive (acl2-symprompt "Variable doc" (acl2-var-at-pt))) ++ (inf-acl2-last-line-to-top) ++ (comint-proc-query (inferior-acl2-proc) (format acl2-var-doc-command var))) ++ ++ ++;; HINTS: ++;; Click in defun or defthm to add a hint. ++ ++(defconst hint-x-popup-menu ++ '("Hints" ++ ("Do not induct" ":do-not-induct t ") ++ ("Do not generalize" ":do-not 'generalize ") ++ ("Do not fertilize" ":do-not 'fertilize ") ++ ("Expand" ":expand (%s) " sexp) ++ ("Hands off" ":hands-off (%s) " symbol) ++ ("Disable" ":in-theory (disable %s) " symbol) ++ ("Enable" ":in-theory (enable %s) " symbol) ++ ("Induct" ":induct %s " sexp) ++ ("Cases" ":cases (%s) " sexp))) ++ ++;; (defun foo () "bar" ++;; (declare (xargs ... :guard-hints (("Goal" . <hints>))))) ++;; ++;; (defthm foo "bar" body ++;; :rule-classes (a .b) ++;; :hints (("Goal" <hints>))) ++ ++;; Need to be able to do rule classes, multiple enable, disable ++ ++(defun find-hint-insertion-point () ++ "Returns a list of the form (POINT STRING), where STRING ++is the format string in which to insert the hint, and POINT is ++where to put it" ++ (interactive) ++ (save-excursion ++ (end-of-defun) ++ (skip-chars-backward " \t\n\r\f") ; Makes allegro happy ++ (let ((end (point))) ++ (beginning-of-defun) ++ (cond ((looking-at "(defun ") ++ (cond ((re-search-forward ":guard-hints[ \t]*(" end t) ++ (cond ((re-search-forward "\"Goal\"" end t) ++ (if (looking-at "[ \t]") ++ (progn (forward-char 1) (list (point) "%s")) ++ (list (point) " %s"))) ++ (t (list (point) "(\"Goal\" %s)")))) ++ ((re-search-forward "(declare[ \t]+(xargs[ \t]+" end t) ++ (list (point) " :guard-hints ((\"Goal\" %s)) ")) ++ (t (forward-char 1) ++ (forward-sexp 3) ++ (if (looking-at "[ \t]*\n") ++ (skip-chars-forward " \t\n")) ++ (list (point) "(declare (xargs :guard-hints ((\"Goal\" %s))))\n")))) ++ ((looking-at "(defthm ") ++ (cond ((re-search-forward ":hints[ \t]*(" end t) ++ (cond ((re-search-forward "\"Goal\"" end t) ++ (if (looking-at "[ \t]") ++ (progn (forward-char 1) (list (point) "%s")) ++ (list (point) " %s"))) ++ (t (list (point) "(\"Goal\" %s)")))) ++ (t (goto-char (- end 1)) ++ (list (point) "\n :hints ((\"Goal\" %s))")))) ++ (t (error "Not a function or theorem")))))) ++ ++(defun add-hint-to-defun-at-click (click) ++ "Go to click, figure out where to insert, and add selected hint." ++ (interactive "e") ++ (let ((pos1 (event-start click)) ++ (end (event-end click)) ++ (hint (x-popup-dialog click hint-x-popup-menu))) ++ (select-window (posn-window pos1)) ++ (if (numberp (posn-point pos1)) ++ (goto-char (posn-point pos1))) ++ (save-excursion ++ (let* ((pair (find-hint-insertion-point)) ++ (pos (car pair)) ++ (schema (car (cdr pair))) ++ arg) ++ (cond ((not (cdr hint)) (goto-char pos) (insert (format schema (car hint)))) ++ ((setq arg (get-hint-arg (car (cdr hint)))) ++ (goto-char pos) ++ (insert (format schema (format (car hint) arg)))))) ++ (beginning-of-defun) ++ (indent-sexp)))) ++ ++(defun get-hint-arg (kind) ++ (message (format "Click on %s." kind)) ++ (let ((click (read-event)) ++ x) ++ (setq x (thing-at-click click kind)) ++ (cond ((null x) nil) ++ ((memq kind '(event symbol)) (if (symbolp x) x)) ++ ((memq kind '(number integer)) (if (numberp x) x)) ++ ((equal kind 'filename) (if (stringp x) x)) ++ ((memq kind '(cd command)) (if (or (numberp x) (symbolp x)) x)) ++ ((memq kind '(sexp sexpr)) ++ (if (or (numberp x) (symbolp x) (stringp x) (consp x)) x)) ++ (t nil)))) ++ ++(define-key acl2-mode-map [C-mouse-3] 'add-hint-to-defun-at-click) ++ ++ +--- /dev/null ++++ acl2-6.0/interface/emacs/acl2-mode.el +@@ -0,0 +1,143 @@ ++;; Copyright (C) 1985 Free Software Foundation, Inc. ++;; Copyright (C) 1994 Free Software Foundation, Inc. ++ ++;; Author : MKSmith (mksmith@cli.com) ++;; Begun : Feb 27 94 ++;; Origin : lisp-mode.el ++;; Keywords: acl2, languages ++ ++;; This file is part of GNU Emacs. ++ ++;; GNU Emacs 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, or (at your option) ++;; any later version. ++ ++;; GNU Emacs 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. ++ ++;;; Commentary: ++ ++;; The base major mode for editing Acl2 code. ++;; This mode extends very slightly lisp-mode.el (documented in the Emacs manual). ++;; See also inf-acl2.el inf-acl2-mouse.el and inf-acl2-menu.el ++ ++;;; Code: ++ ++(require 'lisp-mode) ++ ++(defvar acl2-mode-syntax-table nil "") ++(defvar acl2-mode-abbrev-table nil "") ++ ++(if (not acl2-mode-syntax-table) ++ (setq acl2-mode-syntax-table ++ (copy-syntax-table lisp-mode-syntax-table))) ++ ++(define-abbrev-table 'acl2-mode-abbrev-table ()) ++ ++(defun acl2-mode-variables (acl2-syntax) ++ (lisp-mode-variables nil) ++ (cond (acl2-syntax ++ (set-syntax-table acl2-mode-syntax-table))) ++ (setq local-abbrev-table acl2-mode-abbrev-table) ++ (make-local-variable 'lisp-indent-function) ++ (setq lisp-indent-function 'acl2-indent-function)) ++ ++(defun acl2-shared-lisp-mode-map () ++ "Return the shared lisp-mode-map, independent of Emacs version." ++ (if (boundp 'shared-lisp-mode-map) ++ shared-lisp-mode-map ++ lisp-mode-shared-map)) ++ ++(defvar acl2-mode-map nil ++ "Keymap for ordinary Acl2 mode. All commands in ++`acl2-shared-lisp-mode-map' are inherited by this map.") ++ ++(if (not acl2-mode-map) ++ (progn ++ (setq acl2-mode-map (make-sparse-keymap)) ++ (set-keymap-parent acl2-mode-map (acl2-shared-lisp-mode-map)))) ++ ++(defvar acl2-mode-hook nil) ++ ++(defun acl2-mode () ++ "Major mode for editing Acl2 code. ++Commands: ++Delete converts tabs to spaces as it moves back. ++Blank lines separate paragraphs. Semicolons start comments. ++\\{acl2-mode-map} ++Note that `run-acl2' may be used either to start an inferior Acl2 job ++or to switch back to an existing one. ++ ++Entry to this mode calls the value of `acl2-mode-hook' ++if that value is non-nil." ++ (interactive) ++ (kill-all-local-variables) ++ (use-local-map acl2-mode-map) ++ (setq major-mode 'acl2-mode) ++ (setq mode-name "Acl2") ++ (acl2-mode-variables t) ++ (set-syntax-table acl2-mode-syntax-table) ++ (run-hooks 'acl2-mode-hook)) ++ ++;; Trying this as a local variable ++;; See last entry in ACL2-MODE-VARIABLES function. ++;; (defconst lisp-indent-function 'acl2-indent-function "") ++ ++(defvar last-sexp nil) ++ ++;; Identical to LISP-INDENT-FUNCTION except checks acl2-indent-hook ++;; first for indentation. Allows user to format Acl2 differently from ++;; lisp. ++(defun acl2-indent-function (indent-point state) ++ (let ((normal-indent (current-column)) ++ (last-sexp (point))) ++ (goto-char (1+ (elt state 1))) ++ (parse-partial-sexp (point) last-sexp 0 t) ++ (if (and (elt state 2) ++ (not (looking-at "\\sw\\|\\s_"))) ++ ;; car of form doesn't seem to be a a symbol ++ (progn ++ (if (not (> (save-excursion (forward-line 1) (point)) ++ last-sexp)) ++ (progn (goto-char last-sexp) ++ (beginning-of-line) ++ (parse-partial-sexp (point) last-sexp 0 t))) ++ ;; Indent under the list or under the first sexp on the ++ ;; same line as last-sexp. Note that first thing on that ++ ;; line has to be complete sexp since we are inside the ++ ;; innermost containing sexp. ++ (backward-prefix-chars) ++ (current-column)) ++ (let ((function (buffer-substring (point) ++ (progn (forward-sexp 1) (point)))) ++ method) ++ (setq method (or (get (intern-soft function) 'acl2-indent-hook) ++ (get (intern-soft function) 'lisp-indent-function) ++ ;; Why does -hook follow -function? ++ (get (intern-soft function) 'lisp-indent-hook))) ++ (cond ((or (eq method 'defun) ++ (and (null method) ++ (> (length function) 3) ++ (string-match "\\`def" function))) ++ (lisp-indent-defform state indent-point)) ++ ((integerp method) ++ (lisp-indent-specform method state ++ indent-point normal-indent)) ++ (method ++ (funcall method state indent-point))))))) ++ ++;; (put 'progn 'lisp-indent-function 0), say, causes progn to be indented ++;; like defun if the first form is placed on the next line, otherwise ++;; it is indented like any other form (i.e. forms line up under first). ++ ++(put 'if 'acl2-indent-hook nil) ;changed from 2 in lisp. ++(put 'mv-let 'acl2-indent-hook 2) ++ ++(provide 'acl2-mode) ++ ++;;; acl2-mode.el ends here ++ ++ +--- /dev/null ++++ acl2-6.0/interface/emacs/mfm.el +@@ -0,0 +1,344 @@ ++;; May, 1994 [modified Oct., 1997] ++;; Matt Kaufmann and Mike Smith ++ ++;; This file lets one attach a filter and a collection of buffers to a ++;; process in emacs. See mfm-acl2.el for an example of how to use the ++;; utilities in this file. It should work in emacs version 18, emacs version ++;; 19 with comint, and version 19 with an old-style shell (Bill Schelter's ++;; sshell.el). ++ ++;; If using this with buffers that use comint for processes, it's a good idea ++;; to (setq mfm-comint-p t) in one's .emacs file. Otherwise, this file uses ++;; comint (i.e., mfm-comint-p is t) if and only if the emacs version is 19 or ++;; later and Schelter's sshell is not present as a feature. ++ ++;; Possible future extensions: ++ ++; Consider saving the buffer's process filter before installing our ++; own, and restoring it when executing stop-proof-tree. This is also ++; important to do when we change the *mfm-buffer*. ++ ++; Think about the effect of renaming a shell buffer. ++ ++; Create a way for #<\<e ... #>\> to cause the form to be read into ++; emacs and evaluated. ++ ++(defvar mfm-emacs-version ++ (if (and (boundp 'emacs-version) ++ (stringp emacs-version) ++ (< 1 (length emacs-version)) ++ (string-match "[0-9][0-9]" (substring emacs-version 0 2))) ++ (string-to-int (substring emacs-version 0 2)) ++ (error "The file mfm.el works for emacs versions 18 and 19, but not yours."))) ++ ++(defvar mfm-comint-p ++ (and (<= 19 mfm-emacs-version) ++ (not (featurep 'sshell)))) ++ ++; For the byte compiler: ++ ++(defvar last-input-end) ++(defvar comint-last-input-end) ++(defvar comint-output-filter-functions) ++(defvar comint-last-output-start) ++ ++(defun mfm-update-last-input-end (nchars) ++ (let ((end (if mfm-comint-p ++ comint-last-input-end ++ last-input-end))) ++ (if (and end ++ (marker-buffer end) ++ (= (point) end)) ++ (set-marker end (- end nchars))))) ++ ++(defun mfm-update-last-output-start (ostart) ++ (if mfm-comint-p ++ (set-marker comint-last-output-start ostart) ++ nil)) ++ ++(defun mfm-force-mode-line-update () ++ (if mfm-comint-p ++ (force-mode-line-update) ++ nil)) ++ ++; e.g., "*shell*" ++(defvar *mfm-buffer* nil) ++ ++; The following is adapted from a contribution from Noah Friedman, from his ++; ftelet mode. ++(defun ftelnet-carriage-filter (string) ++ (let* ((point-marker (point-marker)) ++ (proc (get-buffer-process (current-buffer))) ++ (end (if proc (process-mark proc) (point-max))) ++ (beg (or (and proc ++ (boundp 'comint-last-output-start) ++ comint-last-output-start) ++ (- end (length string))))) ++ (goto-char beg) ++ (while (search-forward "\C-m" end t) ++ (delete-char -1)) ++ (goto-char point-marker))) ++ ++(defvar *mfm-secondary-filter-functions* '(ftelnet-carriage-filter)) ++ ++(defvar *mfm-secondary-buffer* nil ++ "This variable is NIL if we are not currently accumulating output ++to the secondary buffer. If we are its value is that buffer.") ++ ++(defvar *mfm-secondary-buffer-name-alist* nil) ++ ++; We were relying on the rarity of the breaking up of a string #<\<0 or ++; #>\> So far so good, said the guy falling past the 82nd floor.... ++; Broke. So we are fixing it. ++ ++(defvar *mfm-protocol-start* "#" ++ "Character used to start and stop redirection.") ++ ++(defun mfm-initial-secondary-start () ++ (format "#<[\\]<[%s]" ++ (apply 'concat ++ (mapcar 'char-to-string ++ (mapcar 'car ++ (mapcar 'cdr ++ *mfm-secondary-buffer-name-alist*)))))) ++ ++(defvar *mfm-secondary-start* ++ (mfm-initial-secondary-start)) ++ ++(defvar *mfm-secondary-stop* "#>[\\]>") ++ ++; The value of *mfm-secondary-stop-len* should be the length of any string that ++; matches *mfm-secondary-stop*. ++(defvar *mfm-secondary-stop-len* 4) ++ ++(defvar *mfm-paused-buffers* nil) ++ ++(defvar *mfm-secondary-buffer-alist* nil) ++ ++(defun mfm-output-filter-functions () ++ (if mfm-comint-p ++ (delete t comint-output-filter-functions) ++ nil)) ++ ++(defun mfm-paused-buffers (alist) ++ (if (null alist) ++ nil ++ (if (memq 'pause (cdr (cdr (car alist)))) ++ (cons (car (car alist)) ++ (mfm-paused-buffers (cdr alist))) ++ (mfm-paused-buffers (cdr alist))))) ++ ++(defun mfm-create-buffers-from-secondary-buffer-name-alist () ++ ;; This is OK even if some or all of the buffers already exist. ++ (setq *mfm-secondary-buffer-alist* ++ (mapcar (function (lambda (pair) ++ (cons (car (cdr pair)) ++ (get-buffer-create (car pair))))) ++ *mfm-secondary-buffer-name-alist*))) ++ ++(defun mfm-initialize-secondary-buffer-alist () ++ (mfm-create-buffers-from-secondary-buffer-name-alist) ++ (setq *mfm-paused-buffers* ++ (mfm-paused-buffers *mfm-secondary-buffer-name-alist*)) ++ (setq *mfm-secondary-start* ++ (mfm-initial-secondary-start))) ++ ++(defvar *mfm-saved-tail* "") ++(defvar *mfm-secondary-text* "") ++ ++(defun mfm-string-start (string) ++ ;; Return nil or pair. ++ ;; If pair = (n NIL), then we have a match for *mfm-secondary-start* at n. ++ ;; If pair = (n T), then we have a match for *mfm-protocol-start* at n, and ++ ;; n indexs one of the last four characters of string. ++ (let ((start (string-match *mfm-secondary-start* string))) ++ (cond (start (list start nil)) ++ ((string-match *mfm-protocol-start* string (max (- (length string) 4) 0)) ++ (list (match-beginning 0) t)) ++ (t nil)))) ++ ++(defun mfm-string-stop (string) ++ ;; Return nil or pair. ++ ;; If pair = (n NIL), then we have a match for *mfm-secondary-stop* at n; ++ ;; elseif pair = (n T), then we have a match for *mfm-protocol-start* at n, ++ ;; and n indexes one of the last four characters of string. ++ (let ((stop (string-match *mfm-secondary-stop* string))) ++ (cond (stop (list stop nil)) ++ ((string-match *mfm-protocol-start* ++ string ++ (max (- (length string) 3) 0)) ++ (list (match-beginning 0) t)) ++ (t nil)))) ++ ++(defun mfm-output-filter (process string) ++ ;; At this point we need to check if secondary start or stop ++ ;; is contained in string. ++ ;; Previously error prone in case of xxx START xx START xx STOP xx STOP xx... ++ ;; Modified to handle start and stop broken across successive strings. ++ ;; E.g., xxxSTA RTxxxx xxxxST OPxxx ++ (setq string (concat *mfm-saved-tail* string)) ++ (setq *mfm-saved-tail* "") ++ (if *mfm-secondary-buffer* ++ ;; We are currently writing to one of the secondary buffers. ++ (let ((stop (mfm-string-stop string))) ++ (cond ((null stop) ++ (setq *mfm-secondary-text* ++ (concat *mfm-secondary-text* string))) ++ ((null (car (cdr stop))) ++ (setq stop (car stop)) ++ ;; Write the accumulated text, including the appropriate part of ++ ;; STRING. First write the current point as the first line. ++ (mfm-output-to-secondary ++ *mfm-secondary-buffer* ++ (concat *mfm-secondary-text* ++ (substring string 0 stop))) ++ (setq *mfm-secondary-buffer* nil) ++ (setq *mfm-secondary-text* "") ++ (mfm-output-filter ++ process ++ (substring string (+ stop *mfm-secondary-stop-len*)))) ++ ((car (cdr stop)) ++ (setq stop (car stop)) ++ ;; May or may not be done. ++ ;; Add the accumulated text to *mfm-secondary-text*. ++ (setq *mfm-secondary-text* ++ (concat *mfm-secondary-text* (substring string 0 stop))) ++ (setq *mfm-saved-tail* (substring string stop))))) ++ ++ (let* ((start (mfm-string-start string)) ++ (end (and start (match-end 0)))) ++ (cond ((null start) (mfm-output-to-primary process string)) ++ ((null (car (cdr start))) ++ (setq start (car start)) ++ ;; Write the appropriate part of STRING to primary output ++ ;; Then enter secondary buffer mode. ++ (mfm-output-to-primary process ++ (substring string 0 start)) ++ (setq *mfm-secondary-buffer* ++ (cdr (assq (aref string (1- end)) ++ *mfm-secondary-buffer-alist*))) ++ (if (null (buffer-name *mfm-secondary-buffer*)) ++ (progn (mfm-create-buffers-from-secondary-buffer-name-alist) ++ (setq *mfm-secondary-buffer* ++ (cdr (assq (aref string (1- end)) ++ *mfm-secondary-buffer-alist*))))) ++ (mfm-output-filter process (substring string end))) ++ ((car (cdr start)) ++ (setq start (car start)) ++ (mfm-output-to-primary process (substring string 0 start)) ++ (setq *mfm-saved-tail* (substring string start))))))) ++ ++(defun mfm-output-to-primary (process string) ++ ;; First check for killed buffer ++ (let ((oprocbuf (process-buffer process))) ++ (if (and oprocbuf (buffer-name oprocbuf)) ++ (let ((obuf (current-buffer)) ++ (opoint nil) (obeg nil) (oend nil)) ++ (set-buffer oprocbuf) ++ (setq opoint (point)) ++ (setq obeg (point-min)) ++ (setq oend (point-max)) ++ (let ((buffer-read-only nil) ++ (nchars (length string)) ++ (ostart nil)) ++ (widen) ++ (goto-char (process-mark process)) ++ (setq ostart (point)) ++ (if (<= (point) opoint) ++ (setq opoint (+ opoint nchars))) ++ ;; Insert after old_begv, but before old_zv. ++ (if (< (point) obeg) ++ (setq obeg (+ obeg nchars))) ++ (if (<= (point) oend) ++ (setq oend (+ oend nchars))) ++ (insert-before-markers string) ++ ;; Don't insert initial prompt outside the top of the window. ++ (if (= (window-start (selected-window)) (point)) ++ (set-window-start (selected-window) (- (point) (length string)))) ++ (mfm-update-last-input-end nchars) ++ (mfm-update-last-output-start ostart) ++ (set-marker (process-mark process) (point)) ++ (mfm-force-mode-line-update)) ++ ++ (narrow-to-region obeg oend) ++ (goto-char opoint) ++ (ftelnet-carriage-filter string) ++ (let ((functions (mfm-output-filter-functions))) ++ (while functions ++ (funcall (car functions) string) ++ (setq functions (cdr functions)))) ++ (set-buffer obuf))))) ++ ++(defun member-equal (a lst) ++ ;; because member is not defined in version 18 ++ (if (null lst) ++ nil ++ (if (equal a (car lst)) ++ lst ++ (member-equal a (cdr lst))))) ++ ++(defun mfm-paused-p (buffer-name) ++ (member-equal buffer-name *mfm-paused-buffers*)) ++ ++(defun mfm-output-to-secondary (oprocbuf string) ++ ;; First check that buffer exists. ++ (if (and oprocbuf (buffer-name oprocbuf)) ++ (let ((obuf (current-buffer))) ++ (if ; Stop output to "pause" buffers. ++ (mfm-paused-p (buffer-name oprocbuf)) ++ nil ++ (set-buffer oprocbuf) ++ ;; Clear buffer before displaying string. ++ (delete-region (point-min) (point-max)) ++ (let ((buffer-read-only nil)) ++ (insert string)) ++ (mfm-force-mode-line-update) ++ (let ((functions *mfm-secondary-filter-functions*)) ++ (while functions ++ (funcall (car functions) string) ++ (setq functions (cdr functions)))) ++ (set-buffer obuf))))) ++ ++(defun mfm-abort-secondary-buffer () ++ ++ "Flush the text currently being sent to the secondary buffer and ++resume sending text to primary buffer. This does not stop or pause ++the sending of output to secondary buffers; it merely flushes the ++current stream being sent to a secondary buffer (if any)." ++ ++ (interactive) ++ (setq *mfm-secondary-buffer* nil) ++ (setq *mfm-saved-tail* "") ++ (setq *mfm-secondary-text* "")) ++ ++(defun mfm-interrupt-subjob () ++ (interactive) ++ (progn ++ (mfm-abort-secondary-buffer) ++ ;; use funcall here to avoid confusing the compiler ++ (if mfm-comint-p ++ (if (eq major-mode 'telnet-mode) ++ (funcall 'telnet-interrupt-subjob) ++ (funcall 'comint-interrupt-subjob)) ++ (funcall 'interrupt-shell-subjob)))) ++ ++(defun mfm-set-keymap-interrupt () ++ (save-excursion ++ (if *mfm-buffer* ++ (progn (set-buffer *mfm-buffer*) ++ (define-key (current-local-map) ++ "\C-C\C-C" ++ 'mfm-interrupt-subjob))))) ++ ++(defun mfm-select-buffer-window (buffer) ++ ++ "Select a window containing the given buffer if there is one; otherwise, make ++the current window fill the frame, and select the indicated buffer." ++ (let ((w (get-buffer-window buffer))) ++ (if w ++ (select-window w) ++ (progn (delete-other-windows) ++ (switch-to-buffer buffer))))) ++ ++(provide 'mfm) ++ +--- /dev/null ++++ acl2-6.0/interface/emacs/interface-macros.el +@@ -0,0 +1,644 @@ ++;; Macros to uniformly define emacs interface commands. ++;; Specifically: ++ ++;; 1. Set the menu-bar. ++;; 2. Set up a pop-up menu on mouse-3. ++;; 3. Set other random key definitions. ++;; ++;; Originally designed for Acl2. ++;; For versions of Emacs post 19 running under X. ++ ++(require 'thingatpt) ; (load "thingatpt") ++(require 'mouse) ; (load "mouse") ++ ++(provide 'interface-macros) ++ ++(defvar mode-menu-alist nil) ++(defvar menu-bar-prefix "menu-bar-%s") ++ ++(defvar interface-wrapper "%s") ++(defvar interface-to-top '(this-line-to-top)) ++ ++;; Default form for evaluating a generated command. ++;; <command> is replaced by the command string in the menu, and ++;; <arg> by the value of the computed argument (or nil) depending on ++;; the arg description in the menu. ++;; Example: '(inf-acl2-send-string <command> <arg>) ++ ++(defvar menu-arg-functions nil) ++(defvar interface-menu-function nil) ++ ++;; The following two alists allow you to override the defaults ++;; above in the case of particular argument types. ++;; Should be list of form ((argtype . expr)), where expr ++;; may contain <command> and <arg> which get replaced as for the ++;; above. ++(defvar popup-arg-functions nil) ++(defvar interface-popup-function nil) ++ ++;; The mouse gesture that popup menus are hung off. I think ++;; it is important that this be a DOWN command. ++ ++(defvar down-mouse [down-mouse-3]) ++ ++ ++;; Interface definition form: ++ ++;; (define-interface mode mode-map menu-bar menu-bar-remove popup-menu keys) ++ ++;; Before the menu-bar, popup-menu or keys are defined we check ++;; MODE-MENU-ALIST to see if the map named mode-map requests that functionality. ++ ++;; WARNING: Be sure that if should-i-install, update-mode-menu-alist, ++;; remove-mode-menu-alist, define-mode-keys, or extend-hook is changed, then it ++;; is also changed in key-interface.el. ++ ++(defun should-i-install (mode feature) ++ ;; mode is mode-name ++ (memq feature (cdr (assoc mode mode-menu-alist)))) ++ ++(defun update-mode-menu-alist (l) ++ (if (not (consp (car l))) ++ (setq l (cons l nil))) ++ (setq mode-menu-alist ++ (append l (remove-mode-menu-alist mode-menu-alist l)))) ++ ++(defun remove-mode-menu-alist (alist l) ++ (cond ((null alist) l) ++ ((assoc (car (car alist)) l) ++ (remove-mode-menu-alist (cdr alist) l)) ++ (t (cons (car alist) (remove-mode-menu-alist (cdr alist) l))))) ++ ++;; ---------------------------------------------------------------------- ++;; MENU ++;; ++;; menu ::= (command*) ++;; command ::= (:entry label string . keywords) ++;; || (:entry label symbol . keywords) ; (fboundp symbol) ++;; || (:keymap label symbol) ; (keymapp (eval symbol)) ++;; || (:menu label . menu) ++;; || (:label string) ++;; keywords ::= ([:arg arg] [:to-top] [:unwrapped] :pre :post) ++;; arg ::= symbol || integer || string || sexp || click ++ ++;; arg may be extended. For example acl2-interface-functions adds event, ++;; cd, and command. The last two stand for command-descriptors. ++ ++;; Commands: generate entries in the menu. ++;; :entry label string : Causes string (wrapped) to be sent to process. ++;; :entry label symbol : Invokes function named symbol. ++;; :menu label . menu : Recurs on menu defined by menu. ++;; :label string : Just puts string in menu, for example as documentation ++;; or to provide a blank line (:label ""). ++;; Keywords: ++;; a. :TO-TOP instructs the interface to put the current point at the top of ++;; the buffer before executing the command. Default is to do nothing. ++;; b. Normally the strings in entries are inserted into a "wrapper", the value ++;; of INTERFACE-WRAPPER. :UNWRAPPED instructs the interface to skip this step. ++;; c. :arg indicates that an argument of the indicated type must ++;; be supplied. ++;; d. :pre indicates an emacs form to be evaled before anything else. ++;; e. :post indicates an emacs form to be evaled after everything else. ++ ++(defmacro when (test &rest body) (cons 'if (cons test (list (cons 'progn body))))) ++ ++(defun extend-menu-bar (map-name key menu &optional function-prefix) ++ "MAP-NAME is keymap name. KEY is a key vector, typically ++\[menu-bar\]. TREE is menu-tree." ++ (if (null function-prefix) (setq function-prefix menu-bar-prefix)) ++ (cond ((not (keymapp (eval map-name))) (error (format "%s is not a keymap name." map-name))) ++ ((should-i-install map-name 'menu-bar) ++ (let ((map (eval map-name))) ++ (or (lookup-key map key) ++ (define-key map key (make-sparse-keymap))) ++ (define-menus map key menu function-prefix))))) ++ ++(defun define-menus (map key menu prefix) ++ ;; key is a vector, e.g. [menu-bar]. ++ ;; It is the key in map that menu is supposed to hang off. ++ ;; So that menus will come out looking like the user typed them in ++ ;; we reverse the menu list first. ++ (setq menu (reverse menu)) ++ (while menu ++ (let ((entry (car menu))) ++ (cond ((not (consp entry)) (error "Ill formed menu-tree")) ++ ((equal (car entry) ':menu) ++ (let ((label (car (cdr entry))) ++ (menu (cdr (cdr entry)))) ++ (define-key map (extend-key-vector key label) ++ (cons label (make-sparse-keymap label))) ++ (define-menus map (extend-key-vector key label) menu (concat prefix "-" label)))) ++ ((equal (car entry) ':label) ++ (define-key map (extend-key-vector key (nth 1 entry)) (cons (nth 1 entry) nil))) ++ ((equal (car entry) ':entry) ++ (define-menu-function map key entry prefix)) ++ (t (error (format "Bad menu %s" entry))))) ++ (setq menu (cdr menu)))) ++ ++(defun define-menu-function (map key entry prefix) ++ (let ((label (nth 1 entry)) ++ (function (nth 2 entry)) ++ (function-name (make-function-name prefix (nth 1 entry))) ++ (arg (menu-get-arg entry)) ++ ;; TODO. Special purpose. Need to generalize. ++ (pre (get-keyword-value ':pre entry)) ++ (post (get-keyword-value ':post entry)) ++ (to-top (memq ':to-top entry)) ++ (wrapped-p (not (memq ':unwrapped entry)))) ++ (cond ((stringp function) ++ (eval (menu-function function-name arg function to-top wrapped-p nil pre post)) ++ (define-key map (extend-key-vector key label) (cons label function-name))) ++ ((not (symbolp function)) (error (format "Bad menu entry %s" entry))) ++ ((fboundp function) ++ (if (or pre post) (error (format "Pre or post not allowed with function: %s" entry))) ++ (define-key map (extend-key-vector key label) (cons label function))) ++ ((keymapp (eval function)) ++ (define-key map (extend-key-vector key label) (cons label function))) ++ (t (error (format "Bad menu entry %s" entry)))))) ++ ++;; ---------------------------------------------------------------------- ++;; Popup Menus ++ ++(defun interface-noop () nil) ++ ++;; My simple hack for inserting labels doesn't work if any two labels ++;; are the same. Only the last one shows up. ++ ++(defun define-popup-menu (map-name menu-name entries) ++ "MAP-NAME is a keymap name. MENU-NAME must be bound to a menu-tree." ++ (let ((map (eval map-name)) ++ function-name) ++ (cond ((not (keymapp map)) (error (format "%s is not a keymap name." map-name))) ++ ((should-i-install map-name 'popup-menu) ++ ;; Initialize-popup-menu defines the function that is called when ++ ;; the mouse button is pressed. Creates menu named menu-name. ++ (setq function-name (initialize-popup-menu menu-name)) ++ (define-key map down-mouse (cons "Doesnt print" function-name)) ++ ;; So that menus will come out looking like the user typed them in ++ ;; we reverse the menu list first. ++ (setq entries (reverse entries)) ++ (while entries ++ (define-popup-menu-item menu-name (car entries)) ++ (setq entries (cdr entries))))))) ++ ++(defun define-popup-menu-item (menu-name entry) ++ ;; entry ::= (:entry "label" [function or string] . keys) ++ (let* ((label (nth 1 entry)) ++ (operation (nth 2 entry)) ++ (function-name (make-function-name menu-name label)) ++ (arg (menu-get-arg entry)) ++ ;; TODO. Special purpose. Need to generalize. ++ (pre (get-keyword-value ':pre entry)) ++ (post (get-keyword-value ':post entry)) ++ (to-top (memq ':to-top entry)) ++ (wrapped-p (not (memq ':unwrapped entry)))) ++ ;; ++ (cond ((equal (car entry) ':label) ++ (define-key (eval menu-name) (make-key-vector 'interface-noop) ++ (cons label nil))) ++ ((not (equal (car entry) ':entry)) ++ (error (format "%s not allowable entry for popup meunu %s" ++ entry menu-name))) ++ ((stringp operation) ++ ;; Create the function. ++ (eval (menu-function function-name arg operation to-top wrapped-p 'popup pre post)) ++ (put function-name menu-name arg) ++ (define-key (eval menu-name) (make-key-vector function-name) (cons label t))) ++ ((not (symbolp operation)) ++ (error (format "Bad popup function in %s" entry))) ++ ((fboundp operation) (setq function-name operation) ++ (if (or pre post) (error (format "Pre or post not allowed with function: %s" entry))) ++ (put function-name menu-name arg) ++ (define-key (eval menu-name) (make-key-vector function-name) (cons label t))) ++ (t (error (format "Undefined popup function in %" entry)))))) ++ ++(defun initialize-popup-menu (menu-name) ++ ;; Defines a menu named (car menu) as a subpart of map. ++ ;; Defines the menu select function, MENU-NAME-SELECT, to ++ ;; be hung off of a mouse key. ++ (let ((function-name (intern (concat (symbol-name menu-name) "-select")))) ++ (set menu-name (make-sparse-keymap)) ++ (define-selection-function function-name menu-name) ++ function-name)) ++ ++(defun define-selection-function (function-name menu-name) ++ (eval ++ (acl2-substitute ++ (list (cons '*menu-select* function-name) ++ (cons '*menu* menu-name)) ++ '(defun *menu-select* (click) ++ "This function is invoked in foo mode by mouse-3" ++ (interactive "e") ++ ;; replace (new-mouse-position) with click ++ (let ((action (x-popup-menu click *menu*)) ++ args) ++ (if (consp action) (setq action (car action))) ++ (if (not (symbolp action)) ++ (error "MENU ACTION MUST BE A SYMBOLP")) ++ (setq args (get action '*menu*)) ++ ;; First case indicates we abandoned the menu without selecting anything. ++ (cond ((null action) nil) ++ ((null args) (apply action nil)) ++ ((numberp args) (apply action (list args))) ++ ((equal args t) (apply action (list t))) ++ ((eq args 'click) (apply action (list click))) ++ ((memq args '(buffer filename line word sentence sexp symbol number list event cd)) ++ (apply action (list (thing-at-click click args)))) ++ ;; Default assumes that the args you have supplied are ++ ;; to be evaled. ++ (t (apply action (mapcar (function eval) args))))))))) ++ ++(defun menu-function (name arg command &optional to-top wrapped-p popup pre post) ++ (let ((arg-name (defmenu-arg-name arg popup)) ++ (interactive (defmenu-interactive-arg arg popup)) ++ body) ++ ;; COMMAND must be string. ++ (if wrapped-p (setq command (format interface-wrapper command))) ++ (setq body (menu-function-body command arg-name popup)) ++ (append (list 'defun ++ name ++ (if arg-name (list arg-name) ()) ++ interactive) ++ (if pre (list pre)) ++ (if to-top ++ (list interface-to-top ++ body) ++ (list body)) ++ (if post (list post))))) ++ ++(defvar menu-keyword-list '(:arg :to-top :unwrapped :pre :post)) ++ ++(defun menu-keywordp (x) (memq x menu-keyword-list)) ++ ++(defun menu-get-arg (l) ++ ;; l is an entry. ++ ;; form is (:entry label symbol . keys) ++ ;; also allow, because it is a mistake made repeatedly, ++ ;; (:entry label symbol arg . keys) ++ (let ((x (memq ':arg l))) ++ (cond (x (nth 1 x)) ++ ((and (equal (car l) ':entry) ++ (> (length l) 3) ++ (not (menu-keywordp (nth 3 l)))) ++ (nth 3 l)) ++ (t nil)))) ++ ++(defun get-keyword-value (key l) ++ ;; l is an entry. ++ ;; form is (:entry label symbol . keys) ++ (let ((x (member-equal key (cdr l)))) ++ (cond (x (nth 1 x)) ++ (t nil)))) ++ ++;; Mouse event naming: ++ ++;; [ modifiers ][ number ][ kind ] MOUSE button ++;; button := -1 -2 -3 ++;; modifiers := C- M- H- s- A- S- ++;; number := double- triple- ++;; kind := drag- down- up- ++ ++;; Dummy prefix keys and their meanings: ++ ++;; mode-line The mouse was in the mode line of a window. ++;; vertical-line The mouse was in the vertical line separating side-by-side windows. ++;; vertical-scroll-bar The mouse was in a vertical scroll bar. ++;; horizontal-scroll-bar The mouse was in a horizontal scroll bar. Rare. ++ ++;; Click accessors ++;; (down-mouse-3 (#<window 43 on *scratch*> 236 (53 . 8) 1222667)) ++;; | ++;; event-start ++;; (#<window 43 on *scratch*> 236 (53 . 8) 1222667) ++;; | | | ++;; posn-window | posn-col-row ++;; posn-point ++ ++ ++;; ---------------------------------------------------------------------- ++;; Menu-bar utilities ++ ++(defun remove-from-menu-bar (remove map) ++ ;; Delete menu-bar items whose labels match the strings in REMOVE. ++ (when map ++ (mapcar ++ (function (lambda (x) (define-key map (extend-key-vector [menu-bar] x) nil))) ++ remove))) ++ ++;; MENU-BAR-FINAL-ITEMS is a global, honored by all menu-bar ++;; presentations. If the menu-bar contains any element whose car (a ++;; SYMBOL) is in it, that element will appear after any not mentioned. ++;; The ordering provided by MENU-BAR-FINAL-ITEMS is honored. ++;; (setq menu-bar-final-items final) ++ ++ ++;; ---------------------------------------------------------------------- ++;; Menu function definition and argument extraction/translation ++ ++(defconst menu-arg-name ++ '((click click) ++ (number number) (integer number) ++ (sexp sexp) (sexpr sexp) ++ (file file) (filename file) ++ (symbol symbol))) ++ ++(defun defmenu-arg-name (x &optional popup) ++ (if (assoc x menu-arg-name) ++ (car (cdr (assoc x menu-arg-name))) ++ x)) ++ ++(defconst menu-interactive-arg ++ '((click (interactive "e")) ++ (symbol (interactive (list (read-symbol-with-default)))) ++ (integer (interactive (list (read-number-with-default)))) ++ (number (interactive (list (read-number-with-default)))) ++ (file (interactive "f")) ++ (filename (interactive "f")) ++ (sexpr (interactive "X")) ++ (sexp (interactive "X")))) ++ ++(defconst popup-menu-interactive-arg ++ '((symbol (interactive "S")) ++ (integer (interactive "n")) ++ (number (interactive "n")) ++ (file (interactive "f")) ++ (filename (interactive "f")) ++ (sexpr (interactive "X")) ++ (sexp (interactive "X")))) ++ ++(defun defmenu-interactive-arg (kind &optional popup) ++ (if (not popup) ++ (cond ((null kind) '(interactive)) ++ ((assoc kind menu-interactive-arg) ++ (car (cdr (assoc kind menu-interactive-arg)))) ++ (t (cond ((stringp kind) (list 'interactive kind)) ++ (t (error (format "Don't recognize %s for menu-bar" kind popup)))))) ++ ;; The way these functions are called precludes any real use ++ ;; of the interactive call to obtain the argument. ++ ;; BUT, the argument types should match. ++ (cond ((null kind) '(interactive)) ++ ((assoc kind popup-menu-interactive-arg) ++ (car (cdr (assoc kind popup-menu-interactive-arg)))) ++ (t (cond ((stringp kind) (list 'interactive kind)) ++ (t (error (format "Don't recognize %s for popups" kind)))))))) ++ ++ ++;; The basic EMACS wrapper to send a command to the process buffer. ++;; Some arg types may require special handling, in which case they ++;; are in one or both of the `-arg-functions' alists. ++ ++(defun menu-function-body (command arg &optional popup) ++ (let ((body (cdr (assoc arg (if popup popup-arg-functions menu-arg-functions))))) ++ (if (not body) ++ (if popup ++ (setq body interface-popup-function) ++ (setq body interface-menu-function))) ++ (subst arg '<arg> (subst command '<command> body)))) ++ ++ ++;; ---------------------------------------------------------------------- ++;; Popup Utiliites ++ ++(defun new-mouse-position () ++ (let ((x (mouse-position))) ++ (list (list (car (cdr x)) (cdr (cdr x))) (car x)))) ++ ++(defun acl2-substitute (alist form) ++ (cond ((not (consp form)) ++ (let ((pair (assoc form alist))) ++ (if pair (cdr pair) form))) ++ (t (cons (acl2-substitute alist (car form)) ++ (acl2-substitute alist (cdr form)))))) ++ ++(defun subst (new old form) ++ (cond ((equal form old) new) ++ ((not (consp form)) form) ++ (t (cons (subst new old (car form)) ++ (subst new old (cdr form)))))) ++ ++(defun this-line-to-top () (interactive) (recenter 0)) ++ ++;; ---------------------------------------------------------------------- ++;; Parsing objects out of the emacs buffer. ++ ++(defun thing-at-click (click type) ++ (save-excursion ++ (select-window (posn-window (event-start click))) ++ (goto-char (posn-point (event-start click))) ++ (cond ((eq type 'symbol) (symbol-at-point)) ++ ((eq type 'number) (number-at-point)) ++ ((eq type 'list) (list-at-point)) ++ ((eq type 'sexp) (find-sexp)(sexp-at-point)) ++ ;; Shouldn't be in this file ++ ((eq type 'cd) (cd-at-cursor)) ++ ((eq type 'event) (event-at-cursor)) ++ (t (thing-at-point type))))) ++ ++(defun find-sexp () ++ (interactive) ++ (cond ((looking-at "[ \t\n]+") ++ (re-search-forward "[^ \t\n]" nil nil)(backward-char 1)) ++ ((looking-at ")") (forward-sexp -1)) ++ ((re-search-backward "[ \t\n(\"]" nil nil) (forward-char 1)) ++ (t nil))) ++ ++ ++;; ---------------------------------------------------------------------- ++;; Making new names and key vectors ++ ++(defun extract-menu-name (string) ++ (let ((x (string-match "[ -\.]" string))) ++ (cond ((null x) string) ++ ((zerop x) ++ (if (> (length string) 0) ++ (extract-menu-name (substring string 1)) ++ (makeup-menu-name))) ++ (t (substring string 0 x))))) ++ ++(defvar makeup-index 1) ++ ++(defun makeup-menu-name () ++ (let ((s (format nil "BOGUS-~S" makeup-index))) ++ (setq makeup-index (+ makeup-index 1)) ++ s)) ++ ++(defun make-key-vector (name) ++ (if (stringp name) ++ (setq name (intern (remove-blanks name)))) ++ (make-vector 1 name)) ++ ++(defun extend-key-vector (vector name) ++ (if (stringp name) ++ (setq name (intern (remove-blanks name)))) ++ (vconcat vector (make-vector 1 name))) ++ ++(defun remove-blanks (name) ++ (setq name (copy-sequence name)) ++ (let ((n (length name)) ++ (i 0)) ++ (while (< i n) ++ (if (char-equal (aref name i) ?\ ) ++ (aset name i ?-)) ++ (setq i (+ i 1))) ++ name)) ++ ++(defun mk-symbol (a b) ++ (cond ((string-match "%" a) (intern (format a b))) ++ (t (intern (concat a b))))) ++ ++(defun make-function-name (prefix insert) ++ (if (vectorp prefix) (setq prefix (aref prefix 0))) ++ (if (symbolp prefix) (setq prefix (remove-blanks (symbol-name prefix)))) ++ (if (symbolp insert) (setq insert (remove-blanks (symbol-name insert)))) ++ (let ((name (mk-symbol prefix insert))) ++ (if (fboundp name) ++ (make-function-name "%s-1" name) ++ name))) ++ ++;; ---------------------------------------------------------------------- ++;; `Interactive' Read Functions ++ ++(defun read-number-with-default () ++ (let* (this-event ++ (x (read-string (format "Event name (default: %d)" ++ (setq this-event (number-at-cursor)))))) ++ (if (string-equal x "") ++ (if (numberp this-event) this-event (error "Not a number")) ++ (number-to-string x)))) ++ ++(defun read-symbol-with-default () ++ (let* (this-event ++ (x (read-string (format "Event name (default: %s)" ++ (setq this-event (symbol-at-cursor)))))) ++ (if (string-equal x "") ++ this-event ++ x))) ++ ++(defun number-at-cursor () ++ (save-excursion ++ (if (looking-at "[ \t\.(]+") ++ (goto-char (match-end 0)) ++ (progn (re-search-backward "[^0-9]" nil t) (forward-char 1))) ++ (let ((start (point)) ++ max ++ end) ++ (setq max (save-excursion (end-of-line) (point))) ++ (if (looking-at "[-0-9]+") ++ (if (re-search-forward "[ ()\.\n\t]" max t) ++ (string-to-number (buffer-substring start (- (point) 1))) ++ (string-to-number (buffer-substring start max))))))) ++ ++(defun symbol-at-cursor () ++ (save-excursion ++ (if (looking-at "[ \t\.(]+") ++ (goto-char (match-end 0)) ++ (progn (re-search-backward "[ \t\.()\n]+" nil t) (forward-char 1))) ++ (let ((start (point)) ++ max ++ end) ++ (setq max (save-excursion (end-of-line) (point))) ++ (if (re-search-forward "[ ()\.\n\t]" max t) ++ (buffer-substring start (- (point) 1)) ++ (buffer-substring start max))))) ++ ++(defun define-mode-keys (mode-map-name mode-map keys) ++ ;; An entry in keys may have two forms: ++ ;; (key function) ++ ;; (keymap key function) ++ ;; The second allows you to create subkeymaps, e.g. Control-Z ++ (if (should-i-install mode-map-name 'keys) ++ (mapcar ++ (function (lambda (x) ++ (if (equal (length x) 2) ++ (define-key mode-map (car x) (car (cdr x))) ++ (if (keymapp (eval (car x))) ++ (define-key (eval (car x)) (car (cdr x)) (car (cdr (cdr x)))) ++ (error ++ (format "Keymap %s not defined in mode %s" (car x) (car mode-map))))))) ++ keys))) ++ ++;; HOOKS ++ ++;; All of the necessary hooks are set up by doing ++;; (mode-interface-hook "mode"). E.g. (mode-interface-hook "acl2") ++ ++(defun extend-hook (hook entry) ++ ;; Add an entry onto a mode-hook, being sensitive to the ++ ;; stupid Emacs permission for it to be a function or list ++ ;; of functions. ++ (cond ((null hook) (list entry)) ++ ((symbolp hook) (if (not (equal entry hook)) (list hook entry) hook)) ++ ((not (consp hook)) ++ (message (format "Strange hook, %s, replaced by %s." hook entry)) ++ (list entry)) ++ ((equal (car hook) 'lambda) ++ (list hook entry)) ++ ((member-equal entry hook) hook) ++ (t (append hook (list entry))))) ++ ++(defmacro define-interface (xxx mode-map-name menu-bar menu-bar-remove popup-menu keys) ++ ;; xxx = mode-name, because emacs has some inhibitions about setting mode-name. ++ (let ((<mode>-map-set (make-function-name xxx "-map-set")) ++ (<mode>-mode-revert-fn (make-function-name xxx "-revert-fn")) ++ (<mode>-saved-mode-map (make-function-name xxx "-saved-map")) ++ (<mode>-menu-bar-name (make-function-name xxx "-menu-bar")) ++ (<mode>-menu-bar-remove-name (make-function-name xxx "-menu-bar-remove")) ++ (<mode>-popup-menu-name (make-function-name xxx "-popup-menu")) ++ (<mode>-keys-name (make-function-name xxx "-keys")) ++ (<mode>-mode-hook (make-function-name xxx "-hook")) ++ (<mode>-interface-hook-fn (make-function-name xxx "-interface-hook-fn")) ++ (<mode>-prefix-menu (concat (symbol-name xxx) "-menu-")) ++ (<mode>-prefix-popup (concat (symbol-name xxx) "-popup-")) ++ (<mode>-prefix-keys (concat (symbol-name xxx) "-keys-"))) ++ (if (equal <mode>-popup-menu-name popup-menu) ++ (setq <mode>-popup-menu-name (make-function-name <mode>-popup-menu-name "-2"))) ++ (acl2-substitute (list (cons '<mode>-map-name mode-map-name) ++ (cons '<mode>-menu-bar menu-bar) ++ (cons '<mode>-menu-bar-remove menu-bar-remove) ++ (cons '<mode>-popup-menu popup-menu) ++ (cons '<mode>-keys keys) ++ (cons '<mode>-menu-bar-name <mode>-menu-bar-name) ++ (cons '<mode>-popup-menu-name <mode>-popup-menu-name) ++ (cons '<mode>-menu-bar-remove-name <mode>-menu-bar-remove-name) ++ (cons '<mode>-keys-name <mode>-keys-name) ++ (cons '<mode>-map-set <mode>-map-set) ++ (cons '<mode>-mode-revert-fn <mode>-mode-revert-fn) ++ (cons '<mode>-saved-mode-map <mode>-saved-mode-map) ++ (cons '<mode>-mode-hook <mode>-mode-hook) ++ (cons '<mode>-interface-hook-fn <mode>-interface-hook-fn) ++ (cons '<mode>-prefix-menu <mode>-prefix-menu) ++ (cons '<mode>-prefix-popup <mode>-prefix-popup) ++ (cons '<mode>-prefix-keys <mode>-prefix-keys)) ++ '(progn ++ ++ (defconst <mode>-map-set nil) ++ ++ (defconst <mode>-menu-bar-name <mode>-menu-bar) ++ (defconst <mode>-menu-bar-remove-name <mode>-menu-bar-remove) ++ ++ (defun <mode>-mode-revert-fn () ++ (setq <mode>-map-name <mode>-saved-mode-map) ++ (setq <mode>-map-set nil)) ++ ++ (defun <mode>-interface-hook-fn () ++ (cond ((and (boundp '<mode>-map-name) (not <mode>-map-set)) ++ (setq <mode>-saved-mode-map (copy-keymap <mode>-map-name)) ++ (remove-from-menu-bar <mode>-menu-bar-remove <mode>-map-name) ++ (extend-menu-bar '<mode>-map-name [menu-bar] <mode>-menu-bar-name ++ <mode>-prefix-menu) ++ (define-popup-menu '<mode>-map-name '<mode>-popup-menu-name ++ <mode>-popup-menu) ++ (define-mode-keys '<mode>-map-name <mode>-map-name <mode>-keys) ++ (setq <mode>-map-set t)))) ++ ++ (defconst <mode>-mode-hook ++ (if (boundp '<mode>-mode-hook) ++ (extend-hook <mode>-mode-hook '<mode>-interface-hook-fn) ++ '(<mode>-interface-hook-fn))) ++ ++ (<mode>-interface-hook-fn))))) ++ ++;; Debugging ++;; (defun set-last-click (click) (setq last-click click)) ++;; (define-menu-item mks-menu "Set last click" 'set-last-click 'click) ++;; (x-popup-menu last-click inferior-acl2-mode-popup-menu) +--- /dev/null ++++ acl2-6.0/interface/emacs/mfm-acl2.el +@@ -0,0 +1,675 @@ ++;; May, 1994 ++;; Matt Kaufmann and Mike Smith ++ ++(require 'mfm) ++ ++;; Possible future extensions: ++ ++; Arrange that stop-proof-tree sends an appropriate string to the ACL2 ++; process, with both #+acl2-loop-only and #-acl2-loop-only in it, so ++; that the proof-tree output is inhibited in ACL2 whether we're in a ++; break or not. Similarly for start-proof-tree. If that sort of thing ++; works, consider options for suspend-proof-tree and resume-proof-tree ++; that interrupt and resume an ACL2 proof. ++ ++; We need to be able to distinguish GNU emacs 19 and its descendents from ++; 18 and lemacs and ... ++; Fortunately, mfm.el already provides this test by setting ++; mfm-emacs-version to the version number if it can figure it out. ++ ++; From mfm.el, we need to re-assign this value: ++(defconst *mfm-secondary-buffer-name-alist* '(("prooftree" ?0))) ++ ++(defconst *acl2-proof-tree-height-default* 17) ++(defconst *checkpoint-recenter-line-default* 3) ++; The following are set by start-proof-tree. ++(defvar *acl2-proof-tree-height* *acl2-proof-tree-height-default*) ++(defvar *checkpoint-recenter-line* *checkpoint-recenter-line-default*) ++ ++(defvar *proof-tree-start-string* "\n<< Starting proof tree logging >>" ++ "Must match the corresponding ACL2 string; do not change this!") ++ ++(defvar *last-acl2-point-max* nil) ++ ++; The last process saved when mfm-output-filter was installed: ++(defvar *saved-acl2-process-filter*) ++ ++; *prooftree-marker* is a marker into the prooftree buffer, or nil. It need ++; not have any meaningful position; such position would be stored in ++; overlay-arrow-position. The only reason we have *prooftree-marker* is to ++; avoid the need to keep creating new markers. ++(defvar *prooftree-marker* nil) ++ ++; *** MOVED TO acl2-interface. ++;(defvar ctl-z-keymap (make-sparse-keymap)) ++;(defvar old-ctl-z-key (key-binding "\C-Z")) ++ ++; The following is an emacs variable that we appropriate. ++(setq overlay-arrow-string ">") ++ ++(defun save-last-acl2-point-max (string) ++ (if (and *mfm-secondary-buffer* ++ (equal (buffer-name *mfm-secondary-buffer*) "prooftree")) ++ (setq *last-acl2-point-max* ++ (save-excursion ++ (set-buffer *mfm-buffer*) ++ (point-max))))) ++ ++(defun clear-overlay-from-prooftree-buffer (string) ++ (if (not (mfm-paused-p "prooftree")) ++ (setq overlay-arrow-position nil))) ++ ++(defmacro message-beep (&rest args) ++ (list 'progn ++ '(beep) ++ (cons 'message args))) ++ ++(defun initialize-proof-tree-windows (do-init) ++ (or (and (not do-init) ++ *acl2-proof-tree-height*) ++ (setq *acl2-proof-tree-height* ++ (if (numberp *acl2-proof-tree-height*) ++ (read-from-minibuffer ++ (format "Height of proof tree window (currently %d): " ++ *acl2-proof-tree-height*) ++ (format "%d" *acl2-proof-tree-height*) ++ nil t) ++ (read-from-minibuffer ++ (format "Height of proof tree window (default %d):" ++ *acl2-proof-tree-height-default*) ++ (format "%d" *acl2-proof-tree-height-default*) ++ nil t))))) ++ ++(defun initialize-acl2-buffer-process (do-init) ++ ;; returns non-nil upon success, nil upon failure ++ (let* ((proc-try (and (not do-init) ++ *mfm-buffer* ++ (get-buffer-process *mfm-buffer*))) ++ (proc ++ (or proc-try ++ (and ++ (setq *mfm-buffer* ++ (if (stringp *mfm-buffer*) ++ ++; Keep the following in sync with stop-proof-tree ++ ++ (let ((proc (get-buffer-process *mfm-buffer*))) ++ (if (and proc ++ (boundp '*saved-acl2-process-filter*)) ++ ;;so, we've done at least one save ++ (set-process-filter proc *saved-acl2-process-filter*)) ++ (read-from-minibuffer ++ (format "ACL2 buffer (currently %s): " ++ *mfm-buffer*) ++ *mfm-buffer* nil)) ++ (read-from-minibuffer "ACL2 buffer: " "*shell*" nil))) ++ (get-buffer-process *mfm-buffer*))))) ++ (and proc ++ (let ((fltr (process-filter proc))) ++ (if (not (eq fltr 'mfm-output-filter)) ++ (progn (setq *saved-acl2-process-filter* fltr) ++ (set-process-filter proc 'mfm-output-filter))) ++ (if (not (memq 'save-last-acl2-point-max ++ *mfm-secondary-filter-functions*)) ++ (setq *mfm-secondary-filter-functions* ++ (cons 'save-last-acl2-point-max ++ *mfm-secondary-filter-functions*))) ++ (if (not (memq 'clear-overlay-from-prooftree-buffer ++ *mfm-secondary-filter-functions*)) ++ (setq *mfm-secondary-filter-functions* ++ (cons 'clear-overlay-from-prooftree-buffer ++ *mfm-secondary-filter-functions*))) ++ (mfm-set-keymap-interrupt) ++ t)))) ++ ++(defun initialize-checkpoint-recenter-line (do-init) ++ (or (and (not do-init) ++ *checkpoint-recenter-line*) ++ (setq *checkpoint-recenter-line* ++ (if (numberp *checkpoint-recenter-line*) ++ (read-from-minibuffer ++ (format "Line for top of checkpoint display (currently %d): " ++ *checkpoint-recenter-line*) ++ (format "%d" *checkpoint-recenter-line*) ++ nil t) ++ (read-from-minibuffer ++ (format "Line for top of checkpoint display (default %d): " ++ *checkpoint-recenter-line-default*) ++ (format "%d" *checkpoint-recenter-line-default*) ++ nil t))))) ++ ++;; CHECKPOINT-HELP assumes these keys have been bound. ++;; So we defvar it here. ++(defvar prooftree-subkey "\C-Z") ++ ++(defun checkpoint-help () ++ "Provides information about proof-tree/checkpoint tool. ++Use `C-h d' to get more detailed information for specific functions." ++ (interactive) ++ ;; Here is how to do it in emacs 19: ++ ;; (describe-bindings "\C-Z") ++ ;; But in emacs 18, describe-bindings doesn't take an arg, so: ++ (with-output-to-temp-buffer "*Help*" ++ (princ "Checkpoint help. ++Use `C-h d' to get information on specific functions. ++ ++default key(s) binding ++-------------- ------- ++ ++C-z ?, C-z h checkpoint-help ++C-z g goto-subgoal ++C-z r resume-proof-tree ++C-z s suspend-proof-tree ++C-z c checkpoint ++C-z o select-other-frame-with-focus ++C-z b visit-proof-tree ++C-z B visit-proof-tree-other-frame ++C-z z [old C-z; suspends emacs or iconifies frame] ++"))) ++ ++;; *** INITIALIZE-PROOF-TREE-KEYS handled by acl2-interface.el ++;; Actually, the DEFINE-INTERFACE macro sets up the mode hook for ++;; prooftree mode. ++ ++;;; The following code sets up the prooftree in prooftree mode, which is just ++;;; Fundamental mode. But this allows us to use the prooftree-mode-map and ++;;; prooftree-mode-hook to set up menu and moused based interactions in a ++;;; principled fashion. ++ ++(defvar prooftree-mode-map (make-keymap)) ++ ++(defvar prooftree-mode-hook '() ++ "*Hook for customizing inferior prooftree mode.") ++ ++;;; Example: (define-key prooftree-mode-map "\C-Q" 'foo) ++ ++(defun prooftree-mode () ++ "Major mode for interacting with prooftree buffers. ++ ++\\{prooftree-mode-map} ++ ++Customization: Entry to this mode runs the hooks on `prooftree-mode-hook'. ++" ++ (interactive) ++ (setq major-mode 'prooftree-mode) ++ (setq mode-name "Prooftree") ++ (use-local-map prooftree-mode-map) ++ (run-hooks 'prooftree-mode-hook)) ++ ++;;; end of prooftree-mode. ++ ++(defun start-proof-tree-setup () ++ (delete-other-windows) ++ (switch-to-buffer *mfm-buffer*) ++ (split-window-vertically *acl2-proof-tree-height*) ++ (switch-to-buffer "prooftree") ++ (prooftree-mode) ++ (other-window 1)) ++ ++(defun start-proof-tree (do-init) ++ ++ "Start the ACL2 proof tree display. With an argument, queries for values of ++user-settable parameters. This also queries for the ACL2 buffer the first time ++it is called." ++ ++ (interactive "P") ++ (initialize-proof-tree-windows do-init) ++ (initialize-checkpoint-recenter-line do-init) ++ (if (initialize-acl2-buffer-process do-init) ++ (progn (setq *mfm-secondary-buffer* nil) ++ (mfm-initialize-secondary-buffer-alist) ++ (start-proof-tree-setup)) ++ (error "No process; start shell or inferior-acl2 and start-proof-tree again.")) ++ ++; Handled by acl2-interface.el: ++; (if (not (equal ctl-z-keymap (key-binding "\C-Z"))) ++; (initialize-proof-tree-keys do-init)) ++ ) ++ ++(defun start-proof-tree-noninteractive (mfm-buffer) ++ ++ "A typical call of this function is: ++ ++ (start-proof-tree-noninteractive \"*shell*\") ++ ++You may find it useful to put the above form followed by some version of the ++following forms in your .emacs file, assuming that you have loaded ACL2 file ++emacs/emacs-acl2.el. The result should be the start of a new frame (perhaps ++after you click in the initial emacs window) to the side of the first frame, ++with the \"prooftree\" buffer displayed in the new frame. ++ ++ (cond ((and (eq window-system 'x) ++ (fboundp 'x-display-pixel-width) ++ (= (x-display-pixel-width) 2048) ; for a wide monitor ++ ) ++ (delete-other-windows) ++ (if (boundp 'emacs-startup-hook) ; false in xemacs ++ (push 'new-prooftree-frame emacs-startup-hook))))" ++ ++; Typical call: ++; ++ (setq *mfm-buffer* mfm-buffer) ++ (start-proof-tree nil)) ++ ++(defun stop-proof-tree () ++ ++ "Stop the ACL2 proof tree display, and delete all windows except for one, ++which will contain the ACL2 buffer, emacs variable *mfm-buffer*. See also ++suspend-proof-tree." ++ ++ (interactive) ++ (let ((proc (get-buffer-process *mfm-buffer*))) ++ (if (not proc) ++ (message-beep "No process for ACL2 buffer (emacs variable *mfm-buffer*), %s." ++ *mfm-buffer*) ++ (if (boundp '*saved-acl2-process-filter*) ;so, we've done at least one save ++ (set-process-filter proc *saved-acl2-process-filter*)) ++ (delete-other-windows) ++ (switch-to-buffer *mfm-buffer*)))) ++ ++(defun suspend-proof-tree (&optional suppress-message) ++ ;; Returns non-nil if and only if anything happens. ++ ++ "Freeze the contents of the \"prooftree\" buffer, until ++resume-proof-tree is invoked. Unlike stop-proof-tree, the only effect ++of suspend-proof-tree is to stop putting characters into the ++\"prooftree\" buffer; in particular, strings destined for that buffer ++continue NOT to be put into the primary buffer, which is the value of ++the emacs variable *mfm-buffer*." ++ ++ (interactive) ++ (if (not (mfm-paused-p "prooftree")) ++ (progn (setq *mfm-paused-buffers* ++ (cons "prooftree" *mfm-paused-buffers*)) ++ (or suppress-message ++ (message "suspending prooftree")) ++ t) ++ (or suppress-message ++ (message-beep "prooftree is already suspended")) ++ nil)) ++ ++(defun remove1-equal-rec (elt lst) ++ (if (null lst) ++ lst ++ (if (equal elt (car lst)) ++ (cdr lst) ++ (cons (car lst) (remove1-equal-rec elt (cdr lst)))))) ++ ++(defun remove1-equal (elt lst) ++ (if (member-equal elt lst) ++ (remove1-equal-rec elt lst) ++ lst)) ++ ++(defun visit-proof-tree () ++ "Switch to the proof tree buffer in another window unless there is only one ++window, in which case swtich in the current window." ++ (interactive) ++ (if (< 1 (count-windows)) ++ (other-window 1)) ++ (switch-to-buffer "prooftree")) ++ ++(defun resume-proof-tree (&optional not-eob-p suppress-message) ++; Returns non-nil if and only if anything happens. ++ ++ "Resume original proof tree display, re-creating buffer ++\"prooftree\" if necessary. See also suspend-proof-tree. With prefix ++argument: push the mark, do not modify the windows, and move point to ++end of *mfm-buffer*." ++ ++ (interactive "P") ++ (if (not (get-buffer "prooftree")) ++ (mfm-create-buffers-from-secondary-buffer-name-alist)) ++ (if (not not-eob-p) ++ (progn (push-mark (point) nil) ++ (goto-char (point-max)) ++ (start-proof-tree-setup))) ++ (if (mfm-paused-p "prooftree") ++ (progn ++ (setq *mfm-paused-buffers* ++ (remove1-equal "prooftree" *mfm-paused-buffers*)) ++ (or suppress-message ++ (if not-eob-p ++ (message "resuming prooftree") ++ (message "mark set; resuming prooftree"))) ++ t) ++ (or suppress-message ++ (if not-eob-p ++ (message "prooftree not currently suspended") ++ (message "mark set; prooftree not currently suspended"))) ++ nil)) ++ ++(defun search-backward-point (string &optional bound no-error repeat-count) ++ ;; Same as search-backward in emacs 19, but not in emacs 18 -- except, ++ ;; saves excursion. ++ (save-excursion ++ (search-backward string bound no-error repeat-count) ++ (point))) ++ ++(defun position-of-checkpoint (checkpoint-string) ++ (save-excursion ++ (let* ((case-fold-search nil) ++ (bound (search-backward-point *proof-tree-start-string* nil t))) ++ (if bound ++ ;; We treat "*3.4" much differently from "Subgoal 4" or "Goal''". ++ ;; The assumption is that the first occurrence of such a string, ++ ;; without the trailing slash, is when the goal is pushed; the second ++ ;; occurrence is therefor what we want. ++ (if (equal (aref checkpoint-string 0) ?*) ++ (progn ++ (goto-char bound) ++ (if (re-search-forward ++ (format "%s[.]?[^./0-9]" checkpoint-string) ++ nil t 2) ++ (let ((saved-point (match-beginning 0))) ++ ;; make sure we're still in the same proof! ++ (and (equal (search-backward-point ++ *proof-tree-start-string* nil t) ++ bound) ++ (progn (goto-char saved-point) ++ (beginning-of-line) ++ (point)))))) ++ (if (search-backward (format "\n%s\n" checkpoint-string) bound t) ++ (progn (forward-line 1) ++ (point)) ++ (and (equal checkpoint-string "Goal") ++ bound))))))) ++ ++(defun checkpoint-on-line () ++ (let ((bound (save-excursion ++ (end-of-line) ++ (point))) ++ (case-fold-search nil)) ++ (save-excursion ++ (beginning-of-line) ++ ;; Pretty fancy stuff -- we take special care to let double-quote (") ++ ;; terminate the goal name, since goal names sometimes appear in ++ ;; double-quotes (as in hints). Note that we are happy to have regular ++ ;; expressions that match too much, as long as we find it rare that they ++ ;; do so. ++ (if (or (re-search-forward ++ "\\(\\[[^\n]+\\]\\)?Goal[^ \n\",]*\\(,\\| \\|$\\|\"\\)" ++ bound t) ++ (re-search-forward ++ "\\(\\[[^\n]+\\]\\)?Subgoal [^ \n\",]*\\(,\\| \\|$\\|\"\\)" ++ bound t) ++ (re-search-forward ++ "[*][1-9][0-9]*\\([.][0-9]+\\)*" ++ bound t)) ++ (let* ((beg (match-beginning 0)) ++ (end (match-end 0)) ++ (last-char (char-after (1- end)))) ++ (buffer-substring beg ++ (if (memq last-char '(?\n ?\ ?\" ?\,)) ++ (1- end) ++ end))))))) ++ ++(defun checkpoint-from-prooftree-buffer-1 (arg) ++ ;; assumes that we're in the exposed prooftree buffer if there is one ++ (if (equal arg 0) ++ (progn (set-buffer "prooftree") ++ (beginning-of-buffer))) ++ (prog1 (or (progn (beginning-of-line) ++ (and (looking-at "c") ++ (checkpoint-on-line))) ++ (if (search-forward "\nc" nil t) ++ (checkpoint-on-line) ++ (goto-char (point-min)) ++ (and (search-forward "\nc" nil t) ++ (checkpoint-on-line)))) ++ (forward-line))) ++ ++(defun checkpoint-from-prooftree-buffer (buff arg) ++ ;; As a side effect, advances one line past the checkpoint found (or, stays ++ ;; at the bottom). ++ (let ((obuff (current-buffer))) ++ (if buff ++ (if (equal (buffer-name obuff) "prooftree") ++ (checkpoint-from-prooftree-buffer-1 arg) ++ (let ((w (get-buffer-window buff))) ++ (if w ++ (let ((old-w (get-buffer-window obuff))) ++ (select-window w) ++ (prog1 ++ (checkpoint-from-prooftree-buffer-1 arg) ++ (select-window old-w))) ++ (progn ++ ;; This is the only way I've found to move the point. ++ (switch-to-buffer buff) ++ (prog1 ++ (checkpoint-from-prooftree-buffer-1 arg) ++ (switch-to-buffer obuff)))))) ++ (message-beep "Buffer prooftree not found.") ++ nil))) ++ ++(defun goto-subgoal-message (new-point saved-point-max) ++ (if (or (= new-point saved-point-max) ++ (not (save-excursion ++ (forward-line 2) ;in case we're looking at "Goal" ++ (search-forward *proof-tree-start-string* nil t)))) ++ (message "Point pushed; Moved to goal in final proof in ACL2 buffer.") ++ (message "Point pushed; Moved to goal in already completed proof."))) ++ ++(defun ping-buffer () ++ (insert " ") ++ (backward-delete-char 1)) ++ ++(defun update-prooftree-overlay () ++ ;; Be sure to redisplay after calling this function, or else the overlay may ++ ;; not appear. ++ (save-excursion ++ (if (not (and (markerp *prooftree-marker*) ++ (marker-buffer *prooftree-marker*))) ++ (setq *prooftree-marker* (make-marker))) ++ (set-buffer "prooftree") ++ (save-excursion ++ (forward-line -1) ++ (setq overlay-arrow-position ++ (let ((overlay-point ++ (let ((point (point))) ++ (if (equal point (point-min)) ++ nil ++ point)))) ++ (if overlay-point ++ (set-marker *prooftree-marker* ++ overlay-point ++ (get-buffer "prooftree")) ++ nil))) ++ (ping-buffer)))) ++ ++(defun switch-to-mfm-buffer () ++ (let ((w (get-buffer-window *mfm-buffer* t))) ++ (cond ((window-live-p w) ++ (select-window w) ++ (let ((focus-follows-mouse nil)) ++ (select-frame-set-input-focus (window-frame w)))) ++ (t ++ (if (let ((current-frame ++ (window-frame (get-buffer-window (current-buffer))))) ++ (and current-frame ++ (equal (frame-parameter current-frame 'name) ++ "prooftree-frame"))) ++ (select-other-frame-with-focus)) ++ (switch-to-buffer *mfm-buffer*))))) ++ ++(defun goto-subgoal (checkpoint-string &optional bound) ++ ++ "Go to the specified subgoal in the ACL2 buffer (emacs variable *mfm-buffer*) ++that lies closest to the end of that buffer -- except if the current buffer is ++\"prooftree\" when this command is invoked, the subgoal is the one from the ++proof whose tree is displayed in that buffer. A default is obtained, when ++possible, from the current line of the current buffer. ++ ++If there is more than one frame and *mfm-buffer* is displayed in some frame, ++then that frame is made the frame with the cursor, where the the specified goal ++is shown. Otherwise, if the current frame is named \"prooftree-frame\" then we ++move to another frame to display the goal in *mfm-buffer*." ++ ++ (interactive ++ (list (read-from-minibuffer "Goal name: " (checkpoint-on-line)))) ++ (let ((bound-supplied-p bound) ++ (bound (or bound ++ (and (equal (buffer-name (current-buffer)) "prooftree") ++ *last-acl2-point-max*))) ++ saved-point-max) ++ (let ((new-point ++ (save-excursion ++ (set-buffer *mfm-buffer*) ++ (setq saved-point-max (point-max)) ++ (goto-char (if bound (min (+ 100 bound) saved-point-max) saved-point-max)) ++ (and checkpoint-string ++ (position-of-checkpoint checkpoint-string))))) ++ (if new-point ++ (progn ++ (switch-to-mfm-buffer) ++ (push-mark (point)) ++ (goto-char new-point) ++ (recenter *checkpoint-recenter-line*) ++ (if bound-supplied-p ++ (update-prooftree-overlay) ++ (setq overlay-arrow-position nil)) ++ (goto-subgoal-message new-point saved-point-max)) ++ (message-beep ++ (format "Cannot find goal named \"%s\"." checkpoint-string)))))) ++ ++(defun checkpoint (keep-suspended-p) ++ ++ "Go to a checkpoint, as displayed in the \"prooftree\" buffer with ++the character \"c\" in the first column. With non-zero prefix ++argument: move the point in the ACL2 buffer (emacs variable ++*mfm-buffer*) to the first checkpoint displayed in the \"prooftree\" ++buffer, suspend the proof tree (see suspend-proof-tree), and move the ++cursor below that checkpoint in the \"prooftree\" buffer. Without a ++prefix argument, go to the first checkpoint named below the point in ++the \"prooftree\" buffer (or if there is none, to the first ++checkpoint). Note however that unless the proof tree is suspended or ++the ACL2 proof is complete or interrupted, the cursor will be ++generally be at the bottom of the \"prooftree\" buffer each time it is ++modified, which causes the first checkpoint to be the one that is ++found. ++ ++If the prefix argument is 0, move to the first checkpoint but do not ++keep suspended." ++ ++ (interactive "P") ++ (let ((suspended-p (suspend-proof-tree t)) ++ (buff (get-buffer "prooftree"))) ++ (if *mfm-buffer* ++ (let ((checkpoint-name (and buff ++ (checkpoint-from-prooftree-buffer ++ buff keep-suspended-p)))) ++ (if checkpoint-name ++ (goto-subgoal checkpoint-name *last-acl2-point-max*) ++ (message-beep "Cannot find a checkpointed goal.")) ++ (if (and (not keep-suspended-p) ++ suspended-p) ++ (resume-proof-tree t t))) ++ (if (and (not keep-suspended-p) ++ suspended-p) ++ (resume-proof-tree t t)) ++ (message-beep "There is no active ACL2 buffer")))) ++ ++(if (not (fboundp 'select-frame-set-input-focus)) ; xemacs ++ (defun select-frame-set-input-focus (frame) ++ (focus-frame frame))) ++ ++(defun select-other-frame-with-focus () ++ "Switch to another frame (which is created if necessary), and make it the one ++that contains the cursor." ++ (interactive) ++ (let ((other-frame (get-other-frame)) ++ ;; So that select-frame-set-input-focus calls x-focus-frame: ++ (focus-follows-mouse nil)) ++ (select-frame-set-input-focus other-frame))) ++ ++(if (not (fboundp 'frame-parameter)) ; xemacs ++ (defun frame-parameter (frame sym) ++ (frame-property frame sym))) ++ ++(defun my-select-frame-by-name (frame-name) ++ ++;;; Like select-frame-by-name but without causing an error. ++ ++ (let ((x (frame-list)) ++ ans) ++ (while x ++ (cond ((equal (frame-parameter (car x) 'name) ++ frame-name) ++ (setq ans (car x)) ++ (setq x nil))) ++ (setq x (cdr x))) ++ ans)) ++ ++(defun prooftree-remaining-frame-width () ++ (let* ((frame-pixel-width (frame-pixel-width)) ++ (full-pixel-width ++ (if (fboundp 'display-pixel-width) ; not xemacs ++ (display-pixel-width) ++ (x-display-pixel-width))) ++ (pixel-width-of-new-frame ++ (and full-pixel-width ++ (- full-pixel-width ++ (+ (frame-parameter nil 'left) frame-pixel-width))))) ++ (and full-pixel-width ++ (/ (* (frame-width) pixel-width-of-new-frame) ++ frame-pixel-width)))) ++ ++(defun new-prooftree-frame (&optional doit) ++ (interactive "P") ++ (cond ++ ((and (not doit) ++ (my-select-frame-by-name "prooftree-frame")) ++ (beep) ++ (message "There is already a frame named prooftree-frame. ++Give an argument if you want to create a new frame nonetheless.") ++ nil) ++ (t ++ (let ((new-width (prooftree-remaining-frame-width)) ++ (min-width 40) ++ (focus-follows-mouse nil) ++ (old-frame (window-frame (get-buffer-window (current-buffer))))) ++ (cond ++ ((null new-width) ++ (error "Unable to compute available width for new frame.")) ++ ((or doit (<= min-width new-width)) ; else don't bother ++ (let ((new-frame ++ (new-frame (list (cons 'name "prooftree-frame") ++ (cons 'width ++ (max min-width new-width)) ++ (cons 'height (frame-height)) ++ (cons 'top (frame-parameter nil 'top)) ++ (cons 'left (+ (frame-parameter nil 'left) ++ (frame-pixel-width) ++ (or (get 'border-width ++ 'x-frame-parameter) ++ ;; nil in xemacs ++ 5))))))) ++ ++; We have seen an "X protocol error" that crashes Emacs while running VNC on a ++; Mac. The following ad hoc 20-millisecond sleep seems to solve the problem, ++; but we welcome suggestions from Emacs gurus for a better approach. ++ ++ (sleep-for 0 20) ++ (select-frame-set-input-focus new-frame) ++ (switch-to-buffer "prooftree") ++ (message "Columns in new frame: %d" (frame-width new-frame)) ++ new-frame)) ++ (t ++ (error "Not enough columns available (have %d, need %d); can solve with prefix arg" ++ new-width ++ min-width))))))) ++ ++(defun visit-proof-tree-other-frame (&optional doit) ++ "Switch to prooftree buffer in \"prooftree-frame\" frame (which is created if ++necessary). Use meta-x select-other-frame-with-focus to switch back to ++original frame." ++ (interactive "P") ++ (let ((old-frame (my-select-frame-by-name "prooftree-frame"))) ++ (cond ++ (old-frame ++ (let ((focus-follows-mouse nil)) ++ (select-frame-set-input-focus old-frame)) ++ (switch-to-buffer "prooftree")) ++ (t (let ((frame (new-prooftree-frame doit))) ++ (select-frame-set-input-focus frame)))))) ++ ++(provide 'mfm-acl2) +--- /dev/null ++++ acl2-6.0/interface/emacs/README-mouse.mss +@@ -0,0 +1,506 @@ ++@make(clinote) ++ @device(postscript) ++ @style(indent 0, font clitimesroman, spacing 1, spread 1 line) ++@begin(comment) ++ @device(file) ++ @style(indent 0, justification no, leftmargin 0, rightmargin 0 in, spacing 1, spread 1 line) ++@end(comment) ++ ++@define(menu=format,leftmargin +.25in, afterentry {@tabset(2inch,2.5inch,3inch,3.5inch,4inch,4.5inch)}) ++ ++@comment{ STILL DEPENDS ON DIRECTORY. FIX WHEN INSTALLED. ++ ++ "/slocal/src/acl2/v1-8/interface/emacs/" ++ ++} ++ ++@title(The ACL2 Prooftree and Mouse Interface) ++@author(M. Kaufmann & M. K. Smith) ++ ++@section(Introduction) ++ ++NOTE: This interface should be considered preliminary, although it has been ++used successfully at Computational Logic, Inc. It is not part of the ACL2 ++software in the strictest sense (which is co-authored by Matt Kaufmann and J ++Moore), but we feel that it will be useful to ACL2 users. ++ ++This note describes how to get the ACL2/Emacs prooftree and mouse ++support. You just need to add a single autoload form to your .emacs ++file. And then issue the correspoding M-x command. ++ ++The prooftree support has been tested in the following Emacs: ++@begin(format) ++ Emacs 18 ++ Emacs 19 - with comint and WFS's shell, sshell.el. ++ Lemacs 19 ++@end(format) ++ ++The menu and mouse support currently works with Emacs 19. ++ ++@b[If you don't want to deal with any of this:] You probably want to ++put the following form in your acl2-customization.lisp file. ++@begin(verbatim) ++ ++ :STOP-PROOF-TREE ++ ++@end(verbatim) ++This will turn off the proof tree printing from ACL2. For documentation in ACL2 do ++@begin(verbatim) ++ :doc proof-tree ++@end(verbatim) ++To turn proof trees back on use `:START-PROOF-TREE'.@* ++NOTE: If you do `:STOP-PROOF-TREE' in ACL2, then M-x start-proof-tree ++will not accomplish anything useful in Emacs. ++ ++ ++@section(LOADING EMACS INTERFACE CODE) ++ ++@subsection(Simplest .emacs Additions) ++ ++If you want the full interface, put the following in your .emacs ++file after replacing /slocal/src/acl2/v1-8/ with the full pathname ++of your acl2-sources/ directory. ++@begin(verbatim) ++ ++ (setq *acl2-interface-dir* ++ "/slocal/src/acl2/v1-8/interface/emacs/") ++ ++ (autoload 'run-acl2 ;;@i[emacs 19.27 only at this time] ++ (concat *acl2-interface-dir* "top-start-inferior-acl2") ++ "Begin ACL2 in an inferior ACL2 mode buffer." ++ t) ++ ++@end(verbatim) ++Then, to get things started in Emacs do `M-x run-acl2'. Use `M-x ++acl2-mode' to get `<acl2-file>.lisp' into the right mode. The ++commands in the various modes are listed in a later section. But you ++can see most of them by observing the new pull-down menus and pop-up ++menu in inferior ACL2 mode and ACL2 mode. The pop-up menu is tied to ++mouse-3. ++ ++If you just want proof trees, use the following after replacing ++/slocal/src/acl2/v1-8/ with the full pathname of your acl2-sources/ ++directory. ++ ++@begin(verbatim) ++ ++ (setq *acl2-interface-dir* ++ "/slocal/src/acl2/v1-8/interface/emacs/") ++ ++(autoload 'start-proof-tree ++ (concat *acl2-interface-dir* "top-start-shell-acl2") ++ "Enable proof tree logging in a prooftree buffer." ++ t) ++ ++@end(verbatim) ++ ++@subsection(More Control from .emacs: Setting preferences) ++ ++The alist, *acl2-user-map-interface*, determines what menus you get. ++If a feature is included after a mode name, then you get it. ++@begin(verbatim) ++ ++(defvar *acl2-user-map-interface* ++ '((inferior-acl2-mode menu-bar popup-menu keys) ++ (acl2-mode menu-bar popup-menu keys) ++ (prooftree-mode menu-bar popup-menu keys))) ++ ++@end(verbatim) ++ ++If you set the following to T, you will switch to the inferior ACL2 ++buffer when you send forms, regions, or buffers to it. ++@begin(verbatim) ++ ++ (setq *acl2-eval-and-go* nil) ++ ++@end(verbatim) ++If you set the following to NIL you will be queried for their values ++when you start up a prooftree buffer (via M-x start-proof-tree). ++These are the defaults you get based on the autoload above. ++@begin(verbatim) ++ ++ (setq *acl2-proof-tree-height* 17) ++ (setq *checkpoint-recenter-line* 3) ++ ++@end(verbatim) ++ ++ ++@section(Commands) ++ ++Commands are enabled based on the value of the alist, ++*acl2-user-map-interface*, as described above. There are some conventions that ++you need to know regarding arguments to mouse commands. ++ ++If a menu bar entry is of the form ++@begin(format) ++ Print event ... ++@end(format) ++the "..." indicates that you will be prompted in the minibuffer for an argument. ++ ++If a menu bar entry is of the form ++@begin(format) ++ Mode > ++@end(format) ++the ">" indicates a suborninate menu that will pop up if you release ++on this menu item. ++ ++Pop-up menu items indicate whether they take an argument based on a ++preceding ".". The argument is determined by what you clicked on to ++bring up the menu. Arguments derived from things that appear in the ++chronology are somewhat robust. So that if you had a list of events ++on the screen like: ++@begin(verbatim) ++ 13 (DEFMACRO TEXT (X) ...) ++ L 14 (DEFUN MSG-P (X) ...) ++ L 15 (DEFUN MAKE-PACKET (X Y Z) ...) ++ L 16 (DEFUN HISTORY-P (L) ...) ++ 17 (DEFMACRO INFROM (X) ...) ++@end(verbatim) ++to see event 14 you could click right anywhere on that line and select ++either ". Print Event" or ". Print Command". ++ ++ ++@subsection(Prooftree Related) ++ ++@begin(menu) ++M-x start-proof-tree ++M-x stop-proof-tree ++@end(menu) ++ ++ ++@subsection(Prooftree Mode) ++ ++@subsubsection<POPUP MENU> ++ ++@begin(menu) ++Abort @\Abort *inferior-acl2*. ++Goto subgoal @\Go to clicked on subgoal in *inferior-acl2*. ++Resume proof tree @\Resume printing proof tree. ++Suspend proof tree @\Suspend printing proof tree. ++Checkpoint/Suspend @\Suspend prooftree and go to clicked on checkpoint. ++Checkpoint @\Go to clicked on checkpoint. ++Help @\ ++@end(menu) ++ ++@subsubsection<MENU BAR> ++ ++@begin(menu) ++Prooftree@begin(menu) ++ Checkpoint @\Go to next checkpoint ++ Goto subgoal @\That cursor is on. ++ Checkpoint / Suspend @\Go to next checkpoint and suspend proof tree. ++ Resume proof tree ++ Suspend proof tree ++ Abort @\Abort prooftree. (ACL2 will continue to send prooftrees, it just ++ @\won't go the the prooftree buffer.) ++ Help ++@end(menu) ++@end(menu) ++ ++@subsubsection<KEYS> ++ ++@begin(menu) ++C-z z @\Previous C-z key binding ++C-z c @\Go to checkpoint ++C-z s @\Suspend proof tree ++C-z r @\Resume proof tree ++C-z a @\Mfm abort secondary buffer ++C-z g @\Goto subgoal ++C-z h @\help ++C-z ? @\help ++@end(menu) ++ ++ ++@subsection(ACL2 Mode ) ++ ++ACL2 Mode is like Lisp mode except that the functions that send sexprs ++to the inferior Lisp process expect an inferior ACL2 process in the *inferior-acl2* buffer. ++ ++@subsubsection<POPUP MENU> ++ ++@begin(menu) ++Send to ACL2 @\Send top level form clicked on to ACL2. ++Add hint @\Add the hint form to the clicked on defun. ++@begin(menu) ++Do not induct. ++Do not generalize. ++Do not fertilize. ++Expand @\expand form. Requests you mouse it. ++Hands off. ++Disable@\Disable symbol. Requests you mouse it. ++Enable@\Enable symbol. Requests you mouse it. ++Induct@\Induct based on form. Requests you mouse it. ++Cases@\Perform case split on form.Requests you mouse it. ++@end(menu) ++Go to inferior ACL2 ++Verify@\Take clicked on form into interactive prover. ++@end(menu) ++ ++ ++@subsubsection<KEYS> ++ ++@begin(menu) ++C-x C-e @\eval last sexp ++C-c C-r @\eval region ++C-M-x @\eval defun ++C-c C-e @\eval defun ++C-c C-z @\switch to ACL2 ++C-c C-l @\load file ++C-c C-a @\show arglist ++C-c C-d @\describe symbol ++C-c C-f @\show function documentation ++C-c C-v @\show variable documentation ++C-ce @\eval defun and go to ACL2 ++C-cr @\eval region and go to ACL2 ++@end(menu) ++ ++ ++@subsection(Inferior ACL2 Mode) ++ ++@subsubsection<MENU BAR> ++ ++@begin(menu) ++Events@begin(menu) ++ Recent events @\(pbt '(:here -10)) ++ Print back through ...@\(pbt <event>) ++ Undo @\(ubt ':here) ++ Oops @\(oops) ++ Undo through ... @\(ubt '<event>) ++ Undo through ... @\(ubt! '<cd>) ++ ++ Load file ... @\(cl2-load-file) ++ ++ Disable ...@\(in-theory (disable <symbol>)) ++ Enable ... @\(in-theory (enable <symbol>)) ++ ++ Verify guards ... @\(verify-guards '<symbol>) ++ Verify termination ... @\(verify-guards '<symbol>) ++ ++ Certify-book ... @\(certify-book <filename>) ++ Include-book ... @\(include-book <filename> ) ++ ++Compound commands @begin(menu) ++ Expand compound command ... @\(puff '<cd>) ++ Expand compound command! ... @\(puff* '<cd>) ++@end(menu) ++ ++Table@begin(menu) ++ Print value ... @\(table symbol) ++ Clear ... @\(table <symbol> nil nil :clear ++ Print guard ... @\(table <symbol> nil nil :guard) ++@end(menu) ++@end(menu) ++ ++Print@begin(menu) ++ ++ Event ... @\(pe 'event) ++ Event! ... @\(pe! 'event) ++ Back through ... @\(pbt 'event) ++ ++ Command ... @\(pc '<cd>) ++ Command block ... @\(pcb '<cd>) ++ Full Command block ... @\(pcb! '<cd>) ++ ++ Signature ... @\(args 'event) ++ Formula ... @\(pf 'event) ++ Properties ... @\(props 'event) ++ ++ Print connected book directory @\(cbd) ++ ++ Rules whose top function symbol is ... @\(pl 'event) ++ Rules stored by event ... @\(pr 'event) ++ Rules stored by command ... @\(pr! '<cd>) ++ ++ Monitored-runes @\(monitored-runes) ++@end(menu) ++ ++Control@begin(menu) ++ ++ Load ... @\(ld filename) ++ Accumulated Persistence@begin(menu) ++ Activate @\(accumulated-persistence t) ++ Deactivate @\(accumulated-persistence nil) ++ Display statistics ordered by@begin(menu) ++ frames @\(show-accumulated-persistence :frames) ++ times tried @\(show-accumulated-persistence :tries) ++ ratio @\(show-accumulated-persistence :ratio) ++ @end(menu) ++Break rewrite@begin(menu) ++ Start general rule monitoring @\(brr t) ++ Stop general rule monitoring @\(brr nil) ++ Print monitored runes @\(monitored-runes) ++ Monitor rune: ... @\(monitor '(:definition <event>) 't) ++ Unmonitor rune: ... @\(unmonitor '(:definition <event>))@end(menu) ++ ++Commands@begin(menu) ++ Abort to ACL2 top-level @\#. ++ Term being rewritten @\:target ++ Substitution making :lhs equal :target @\:unify-subst ++ Hypotheses @\:hyps ++ Ith hypothesis ... @\:hyp <integer> ++ Left-hand side of conclusion @\:lhs ++ Right-hand side of conclusion @\:rhs ++ Type assumptions governing :target @\:type-alist ++ Ttree before :eval @\:initial-ttree ++ Negations of backchaining hyps pursued @\:ancestors ++ ++ Rewrite's path from top clause to :target @\:path ++ Top-most frame in :path @\:top ++ Ith frame in :path ... @\:frame <integer>@end(menu) ++ ++AFTER :EVAL@begin(menu) ++ Did application succeed? @\:wonp ++ Rewritten :rhs @\:rewritten-rhs ++ Ttree @\:final-ttree ++ Reason rule failed @\:failure-reason@end(menu) ++ ++CONTROL@begin(menu) ++ Exit break @\:ok ++ Exit break, printing result @\:go ++ Try rule and re-enter break afterwards @\:eval@end(menu) ++ ++WITH NO RECURSIVE BREAKS@begin(menu) ++ :ok! @\(:ok!) ++ :go! @\(:go!) ++ :eval! @\(:eval!)@end(menu) ++ ++WITH RUNES MONITORED DURING RECURSION@begin(menu) ++ :ok ... @\(:ok$ sexpr) ++ :go ... @\(:go$ sexpr) ++ :eval ... @\(:eval$ sexpr)@end(menu) ++ Help @\(:help)@end(menu) ++ Enter ACL2 Loop @\(lp) ++ Quit to Common Lisp @\:Q ++ ABORT @\(:good-bye) ++@end(menu) ++ ++Settings@begin(menu) ++ ++Mode @begin(menu) ++ Logic @\ (logic) ++ Program @\ (program) ++ Guard checking on @\(set-guard-checking t) ++ Guard checking off @\(set-guard-checking nil)@end(menu) ++ ++Forcing@begin(menu) ++ On @\(enable-forcing) ++ Off @\(disable-forcing)@end(menu) ++ ++Compile functions@begin(menu) ++ On @\(set-compile-fns t) ++ Off @\(set-compile-fns nil)@end(menu) ++ ++Proof tree@begin(menu) ++ Start prooftree @\(start-proof-tree)pre (start-proof-tree nil)) ++ Stop prooftree @\(stop-proof-tree)post (stop-proof-tree)) ++ Checkpoint forced goals on @\(checkpoint-forced-goals)@end(menu) ++ ++Inhibit Display of @begin(menu) ++ Error messages @\(assign inhibit-output-lst '(error)) ++ Warnings @\(assign inhibit-output-lst '(warning)) ++ Observations @\(assign inhibit-output-lst '(observation)) ++ Proof commentary @\(assign inhibit-output-lst '(prove)) ++ Proof tree @\(assign inhibit-output-lst '(prove)) ++ Non-proof commentary @\(assign inhibit-output-lst '(event)) ++ Summary @\(assign inhibit-output-lst '(summary))@end(menu) ++ ++Unused Variables@begin(menu) ++ Ignore @\(set-ignore-ok t) ++ Fail @\(set-ignore-ok nil) ++ Warn @\(set-ignore-ok :warn)@end(menu) ++ ++Irrelevant formulas@begin(menu) ++ Ok @\(set-irrelevant-formals-ok t) ++ Fail @\(set-irrelevant-formals-ok nil) ++ Warn @\(set-irrelevant-formals-ok :warn)@end(menu) ++ ++Load@begin(menu) ++Error action@begin(menu) ++ Continue @\(set-ld-error-actions :continue) ++ Return @\(set-ld-error-actions :return) ++ Error @\(set-ld-error-actions :error)@end(menu) ++ ++Error triples@begin(menu) ++ On @\(set-ld-error-triples t) ++ Off @\(set-ld-error-triples nil)@end(menu) ++ ++Post eval print@begin(menu) ++ On @\(set-ld-post-eval-print t) ++ Off @\(set-ld-post-eval-print nil) ++ Command conventions @\(set-ld-post-eval-print :command-conventions)@end(menu) ++ ++Pre eval filter@begin(menu) ++ All @\(set-ld-pre-eval-filter :all) ++ Query @\(set-ld-pre-eval-filter :query)@end(menu) ++ ++Prompt@begin(menu) ++ On @\(set-ld-prompt t) ++ Off @\(set-ld-prompt nil)@end(menu) ++ ++Skip proofs@begin(menu) ++ On @\(set-ld-skip-proofs t) ++ Off @\(set-ld-skip-proofs nil)@end(menu) ++ ++Verbose: on@begin(menu) ++ On @\(set-ld-verbose t) ++ Off @\(set-ld-verbose nil)@end(menu) ++ ++ Redefinition permitted @\(redef) ++ Reset specials @\(reset-ld-specials t) ++HACKERS. DANGER!@begin(menu) ++ RED redefinition! @\(redef!)@end(menu) ++@end(menu) ++ ++ ++Books@begin(menu) ++ Print connected book directory @\(cbd) ++ Set connected book directory ... @\(set-cbd filename) ++ Certify-book ... @\(certify-book filename) ++ Include-book ... @\(include-book filename)@end(menu) ++ ++ACL2 Help@begin(menu) ++ Documentation @\(doc '<symbol>) ++ Arguments @\(args '<symbol>) ++ More @\(more) ++ Apropos ... @\(docs '<symbol>) ++ Info @\(cl2-info) ++ Tutorial @\(acl2-info-tutorial) ++ Release Notes @\(cl2-info-release-notes)@end(menu) ++ ++@end(menu) ++@end(menu) ++ ++ ++ ++@subsubsection<INFERIOR ACL2 POPUP MENU> ++ ++@begin(menu) ++ Recent events @\(pbt '(:here -10)) ++ Print Event @\(pe '<symbol>) ++ Print back to @\(pbt '<cd>) ++ Disable @\(in-theory (disable <symbol>)) ++ Enable @\(in-theory (enable <symbol>)) ++ Undo @\(ubt ':here) ++ Undo thru @\(ubt '<cd>) ++ Documentation @\(doc '<symbol>) ++ Arguments, etc @\(args '<symbol>) ++ Verify @\Take clicked on form into interactive prover. ++@end(menu) ++ ++@subsubsection<KEYS> ++ ++@begin(menu) ++C-x C-e @\Eval last sexp ++C-c C-l @\Load file ++C-c C-a @\Show arglist ++C-c C-d @\Describe symbol ++C-c C-f @\Show function documentation ++C-c C-v @\Show variable documentation ++C-cl @\Load file ++C-ck @\Compile file ++C-ca @\Show arglist ++C-cd @\Describe symbol ++C-cf @\Show function documentation ++C-cv @\Show variable documentation ++@end(menu) ++ +--- /dev/null ++++ acl2-6.0/interface/emacs/load-shell-acl2.el +@@ -0,0 +1,31 @@ ++ ++;; Load the emacs interface for acl2 when it is running in a ++;; shell buffer in shell-mode. ++;; May 13 94 Kaufmann & MKSmith ++ ++;; ASSUMPTION: load path contains the directory this file resides in. ++ ++(defvar *acl2-user-map-interface* ++ '((prooftree-mode-map keys))) ++ ++(require 'key-interface) ++ ++;; (defvar *selected-mode-map*) ++(defvar inferior-acl2-buffer) ++ ++(defun initialize-mfm-buffer-variables () ++ (setq *mfm-buffer* "*shell*") ++ ;; (setq *selected-mode-map* shell-mode-map) ++ (setq inferior-acl2-buffer *mfm-buffer*)) ++ ++(defvar shell-mode-hook nil) ++(setq shell-mode-hook ++ (extend-hook shell-mode-hook 'initialize-mfm-buffer-variables)) ++ ++(defun start-shell-acl2 () ++ (interactive) ++ (require 'shell) ++ ;; Looks redundant. ++ ;;(setq shell-mode-hook ++ ;;(extend-hook 'initialize-mfm-buffer-variables shell-mode-hook)) ++ (shell)) +--- /dev/null ++++ acl2-6.0/interface/emacs/inf-acl2.el +@@ -0,0 +1,623 @@ ++;;; inf-acl2.el --- an inferior-acl2 mode ++;;; Copyright (C) 1988, 1993, 1994 Free Software Foundation, Inc. ++ ++;; Copied from inf-lisp.el ++;; As modified for Acl2 by M. K. Smith (mksmith@cli.com), Feb 17 94 ++;; Keywords: processes, acl2 ++ ++;; Original Author: Olin Shivers <shivers@cs.cmu.edu> ++;; Keywords: processes, lisp ++ ++;;; This file is part of GNU Emacs. ++ ++;;; GNU Emacs 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, or (at your option) ++;;; any later version. ++ ++;;; GNU Emacs 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 GNU Emacs; see the file COPYING. If not, write to ++;;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. ++ ++;;; Commentary: ++ ++;;; Hacked from inf-lisp.el, Feb 17 94 MKS ++;;; Hacked from tea.el by Olin Shivers (shivers@cs.cmu.edu). 8/88 ++ ++;;; This file defines an acl2-in-a-buffer package (inferior-acl2 ++;;; mode) built on top of comint mode. This version is more ++;;; featureful, robust, and uniform than the Emacs 18 version. The ++;;; key bindings are also more compatible with the bindings of Hemlock ++;;; and Zwei (the Lisp Machine emacs). ++ ++;;; Since this mode is built on top of the general command-interpreter-in- ++;;; a-buffer mode (comint mode), it shares a common base functionality, ++;;; and a common set of bindings, with all modes derived from comint mode. ++;;; This makes these modes easier to use. ++ ++;;; For documentation on the functionality provided by comint mode, and ++;;; the hooks available for customising it, see the file comint.el. ++;;; For further information on inferior-lisp mode, see the comments below. ++ ++;;; Needs fixin: ++;;; The load-file/compile-file default mechanism could be smarter -- it ++;;; doesn't know about the relationship between filename extensions and ++;;; whether the file is source or executable. If you compile foo.lisp ++;;; with compile-file, then the next load-file should use foo.bin for ++;;; the default, not foo.lisp. This is tricky to do right, particularly ++;;; because the extension for executable files varies so much (.o, .bin, ++;;; .lbin, .mo, .vo, .ao, ...). ++;;; ++;;; It would be nice if inferior-lisp (and inferior scheme, T, ...) modes ++;;; had a verbose minor mode wherein sending or compiling defuns, etc. ++;;; would be reflected in the transcript with suitable comments, e.g. ++;;; ";;; redefining fact". Several ways to do this. Which is right? ++;;; ++;;; When sending text from a source file to a subprocess, the process-mark can ++;;; move off the window, so you can lose sight of the process interactions. ++;;; Maybe I should ensure the process mark is in the window when I send ++;;; text to the process? Switch selectable? ++ ++;;; Code: ++ ++(require 'comint) ++(require 'acl2-mode) ++ ++;; Was defined in comint, but not any more. ++;; (defun full-copy-sparse-keymap (km) ++;; "Recursively copy the sparse keymap KM." ++;; (cond ((consp km) ++;; (cons (full-copy-sparse-keymap (car km)) ++;; (full-copy-sparse-keymap (cdr km)))) ++;; (t km))) ++ ++ ++;;;###autoload ++(defvar inferior-acl2-program "acl2" ++ ;; or perhaps, "nacl2" or "/slocal/src/acl2/new/allegro-saved_acl2" ++ "*Program name for invoking an inferior Acl2 for inferior Acl2 mode.") ++ ++;;;###autoload ++;;;(defvar inferior-acl2-initialization "(in-package \"acl2\")(lp)\n" ++;;; "String sent to set initial Acl2 state.") ++(defvar inferior-acl2-initialization "" ++ "String sent to set initial Acl2 state.") ++ ++;;;###autoload ++(defvar inferior-acl2-load-command ++ "(ld \"%s\" :ld-pre-eval-print t :ld-error-action :return :ld-verbose nil)\n" ++ "*Format-string for building an Acl2 expression to load a file. ++This format string should use `%s' to substitute a file name ++and should result in an expression that will command the inferior Acl2 ++to load that file. ++ ++The default setting commands the inferior Acl2 to load the file, ++printing the form before evaling but suppressing the ACL2 version ++info.") ++ ++;; (defvar inferior-acl2-silent-load-command ++;; "(ld \"%s\" :ld-pre-eval-print nil :ld-error-action :return :ld-verbose nil )\n" ++;; "*Format-string for building an Acl2 expression to load a temporary file. ++;; This format string should use `%s' to substitute a file name ++;; and should result in an expression that will command the inferior Acl2 ++;; to load that file with a minimum of verbosity.") ++ ++;;;###autoload ++(defvar inferior-acl2-prompt "^[ACL2]* *[!+]*>+ *" ++ "Regexp to recognise prompts in the inferior Acl2 mode. ++This variable is used to initialize `comint-prompt-regexp' in the ++inferior Acl2 buffer.") ++ ++;;;###autoload ++(defvar inferior-acl2-filter-regexp "\\`\\s *\\(:\\(\\w\\|\\s_\\)\\)?\\s *\\'" ++ "*What not to save on inferior Acl2's input history. ++Input matching this regexp is not saved on the input history in inferior Acl2 ++mode. Default is whitespace followed by 0 or 1 single-letter colon-keyword ++(as in :a, :c, etc.)") ++ ++(defvar inferior-acl2-mode-map nil) ++(cond ((not inferior-acl2-mode-map) ++ (setq inferior-acl2-mode-map (copy-keymap comint-mode-map)) ++ (set-keymap-parent inferior-acl2-mode-map (acl2-shared-lisp-mode-map)))) ++ ++ ++;;; This function exists for backwards compatibility. ++;;; Previous versions of this package bound commands to C-c <letter> ++;;; bindings, which is not allowed by the gnumacs standard. ++ ++;;; "This function binds many inferior-acl2 commands to C-c <letter> bindings, ++;;;where they are more accessible. C-c <letter> bindings are reserved for the ++;;;user, so these bindings are non-standard. If you want them, you should ++;;;have this function called by the inferior-acl2-load-hook: ++;;; (setq inferior-acl2-load-hook '(inferior-acl2-install-letter-bindings)) ++;;;You can modify this function to install just the bindings you want." ++ ++;;; ??? This function was commented out. Added back. Jul 22 94 MKS ++ ++(defun temporary-filename (id) ++ (format "/tmp/lisp%d.lisp" id)) ++ ++(defvar inferior-acl2-buffer "*inferior-acl2*" ++"*The current inferior-acl2 process buffer. ++ ++MULTIPLE PROCESS SUPPORT ++=========================================================================== ++To run multiple Lisp processes, you start the first up ++with \\[inferior-acl2]. It will be in a buffer named `*inferior-acl2*'. ++Rename this buffer with \\[rename-buffer]. You may now start up a new ++process with another \\[inferior-acl2]. It will be in a new buffer, ++named `*inferior-acl2*'. You can switch between the different process ++buffers with \\[switch-to-buffer]. ++ ++Commands that send text from source buffers to Lisp processes -- ++like `acl2-eval-event' or `acl2-show-arglist' -- have to choose a process ++to send to, when you have more than one Lisp process around. This ++is determined by the global variable `inferior-acl2-buffer'. Suppose you ++have three inferior Acl2 running: ++ Buffer Process ++ foo inferior-acl2 ++ bar inferior-acl2<2> ++ *inferior-acl2* inferior-acl2<3> ++If you do a \\[acl2-eval-event] command on some Lisp source code, ++what process do you send it to? ++ ++- If you're in a process buffer (foo, bar, or *inferior-acl2*), ++ you send it to that process. ++- If you're in some other buffer (e.g., a source file), you ++ send it to the process attached to buffer `inferior-acl2-buffer'. ++This process selection is performed by function `inferior-acl2-proc'. ++ ++Whenever \\[inferior-acl2] fires up a new process, it resets ++`inferior-acl2-buffer' to be the new process's buffer. If you only run ++one process, this does the right thing. If you run multiple ++processes, you can change `inferior-acl2-buffer' to another process ++buffer with \\[set-variable].") ++ ++;;;###autoload ++(defvar inferior-acl2-mode-hook '() ++ "*Hook for customising inferior Acl2 mode.") ++ ++(defvar inferior-acl2-filter-regexp "\\`\\s *\\(:\\(\\w\\|\\s_\\)\\)?\\s *\\'" ++ "*What not to save on inferior Acl2's input history. ++Input matching this regexp is not saved on the input history in Inferior Acl2 ++mode. Default is whitespace followed by 0 or 1 single-letter colon-keyword ++(as in :a, :c, etc.)") ++ ++(defvar comint-input-sentinel) ++ ++(defun inferior-acl2-mode () ++ "Major mode for interacting with an inferior Acl2 process. ++Runs Acl2 as a subprocess of Emacs, with Acl2 I/O through an ++Emacs buffer. Variable `inferior-acl2-program' controls which version of ++Acl2 is run. Variables `inferior-acl2-prompt', `inferior-acl2-filter-regexp' and ++`inferior-acl2-load-command' can customize this mode for different ++keyword sensitive effects. ++ ++For information on running multiple processes in multiple buffers, see ++documentation for variable `inferior-acl2-buffer'. ++ ++\\{inferior-acl2-mode-map} ++ ++Customisation: Entry to this mode runs the hooks on `comint-mode-hook' and ++`inferior-acl2-mode-hook' (in that order). ++ ++You can send text to the inferior Acl2 process from other buffers containing ++Acl2 source. ++ switch-to-acl2 switches the current buffer to the Lisp process buffer. ++ acl2-eval-event sends the current defun to the Acl2 process. ++ acl2-eval-region sends the current region to the Acl2 process. ++ ++ Prefixing the acl2-eval-event/region commands with ++ a \\[universal-argument] causes a switch to the Acl2 process buffer ++ after sending the text. ++ ++Commands: ++Return after the end of the process' output sends the text from the ++ end of process to point. ++Return before the end of the process' output copies the sexp ending at point ++ to the end of the process' output, and sends it. ++Delete converts tabs to spaces as it moves back. ++Tab indents for Acl2; with argument, shifts rest ++ of expression rigidly with the current line. ++C-M-q does Tab on each line starting within following expression. ++Paragraphs are separated only by blank lines. Semicolons start comments. ++If you accidentally suspend your process, use \\[comint-continue-subjob] ++to continue it." ++ (interactive) ++ (comint-mode) ++ (setq comint-prompt-regexp inferior-acl2-prompt) ++ (setq major-mode 'inferior-acl2-mode) ++ (setq mode-name "Inferior Acl2") ++ ;; ??? ++ (setq mode-line-process '(": %s")) ++ ++ ;;; ??? This was changed to (lisp-mode-variables nil). ++ ;;; Back to acl2-mode. Jul 22 94 MKS ++ ++ (acl2-mode-variables t) ++ (use-local-map inferior-acl2-mode-map) ++ ;; Extend acl2-mode, now that we have an inferior. ++ ;; (inferior-acl2-extend-acl2-mode-map) ++ ;; Now done in acl2-interface. ++ (setq comint-get-old-input (function acl2-get-old-input)) ++ (setq comint-input-filter (function acl2-input-filter)) ++ (setq comint-input-sentinel 'ignore) ++ (run-hooks 'inferior-acl2-mode-hook)) ++ ++(defun acl2-get-old-input () ++ "Return a string containing the sexp ending at point." ++ (save-excursion ++ (let ((end (point))) ++ (backward-sexp) ++ (buffer-substring (point) end)))) ++ ++(defun acl2-input-filter (str) ++ "t if STR does not match `inferior-acl2-filter-regexp'." ++ (not (string-match inferior-acl2-filter-regexp str))) ++ ++;;;###autoload ++(defun inferior-acl2 (cmd) ++ "Run an inferior Acl2 process, input and output via buffer `*inferior-acl2*'. ++If there is a process already running in `*inferior-acl2*', just switch ++to that buffer. ++With argument, allows you to edit the command line (default is value ++of `inferior-acl2-program'). Runs the hooks from ++`inferior-acl2-mode-hook' (after the `comint-mode-hook' is run). ++\(Type \\[describe-mode] in the process buffer for a list of commands.)" ++ ++ ;; Note comment from MAKE-COMINT: ++ ;; Make a comint process NAME in a buffer, running PROGRAM. ++ ;; The name of the buffer is made by surrounding NAME with `*'s." ++ ;; Thus the apply below will create a buffer named "*inferior-acl2*" ++ ++ (interactive (list (if current-prefix-arg ++ (read-string "Run lisp: " inferior-acl2-program) ++ inferior-acl2-program))) ++ (if (not (comint-check-proc "*inferior-acl2*")) ++ (let ((cmdlist (inferior-acl2-args-to-list cmd))) ++ (set-buffer (apply (function make-comint) ++ "inferior-acl2" (car cmdlist) nil (cdr cmdlist))) ++ (inferior-acl2-mode) ++ (comint-send-string (inferior-acl2-proc) inferior-acl2-initialization))) ++ (setq inferior-acl2-buffer "*inferior-acl2*") ++ (switch-to-buffer "*inferior-acl2*")) ++ ++;;;###autoload ++(defalias 'run-acl2 'inferior-acl2) ++ ++;;; Break a string up into a list of arguments. ++;;; This will break if you have an argument with whitespace, as in ++;;; string = "-ab +c -x 'you lose'". ++(defun inferior-acl2-args-to-list (string) ++ (let ((where (string-match "[ \t]" string))) ++ (cond ((null where) (list string)) ++ ((not (= where 0)) ++ (cons (substring string 0 where) ++ (inferior-acl2-args-to-list (substring string (+ 1 where) ++ (length string))))) ++ (t (let ((pos (string-match "[^ \t]" string))) ++ (if (null pos) ++ nil ++ (inferior-acl2-args-to-list (substring string pos ++ (length string))))))))) ++ ++;; send-region-to-acl2-process disappeared ++;; ??? Restored. Jul 22 94 MKS ++ ++;; Hacked for inf-acl2 mode. Feb 28 94 MKS ++(defun send-region-to-acl2-process (begin end other-window-p) ++ "Writes the region of the current buffer delimited by begin and end ++ to a temporary file. If other-window-p is not nil the buffer is selected ++ in the other window, otherwise it is selected in the current window (unless ++ it is currently exposed in another window)." ++ ++ (let* ((process (inferior-acl2-proc)) ++ (buffer-to-select (process-buffer process)) ++ (cmd-string inferior-acl2-load-command) ++ (filename (temporary-filename (process-id process))) ++ (in-package-form-written nil)) ++ ++ ;; Write any IN-PACKAGE form (occuring immediately after a linefeed) ++ ;; preceeding this region. Bevier. 11/5/90 ++ (save-excursion ++ (goto-char begin) ++ (if (re-search-backward "\n(in-package" 0 t) ++ (let ((b (point))) ++ (forward-sexp 1) ++ (let ((e (point))) ++ (setq in-package-form-written t) ++ (write-region b e filename nil 'nomessage))))) ++ ++ (write-region begin end filename in-package-form-written 'nomessage) ++ (process-send-string process (format cmd-string filename)) ++ (if other-window-p (switch-to-acl2 t)))) ++ ++(defvar *inf-acl2-debug-send* nil) ++(defvar *inf-acl2-debug-send-string* nil) ++ ++(defvar verify-wrapper "(lisp %s)\n") ++(defvar verify-prompt-string "->: ") ++ ++(defvar *inf-acl2-echo* t) ++ ++(defun inf-acl2-send-string (command &optional arg) ++ ;; Some printing by Acl2 assumes you are already on ++ ;; a new line. But since comint-send-string doesn't ++ ;; echo this is not always a correct assumption. ++ (if (bufferp (get-buffer inferior-acl2-buffer)) ++ (let ((string (format command arg))) ++ (let ((process (inferior-acl2-proc)) ++ (string (format command arg)) ++ verify) ++ (set-buffer inferior-acl2-buffer) ++ (goto-char (process-mark process)) ++ (save-excursion ++ (beginning-of-line) ++ (setq verify (looking-at verify-prompt-string))) ++ (if verify (setq string (format verify-wrapper string))) ++ ;; The \n below adds a blank line that makes things more ++ ;; readable. ++ (if *inf-acl2-echo* (progn (insert string) (insert "\n"))) ++ (set-marker (process-mark process) (point)) ++ ;; (set-marker comint-last-output-start (point)) ++ ;; (set-marker comint-last-input-end (point)) ++ (if *inf-acl2-debug-send* ++ (setq *inf-acl2-debug-send-string* string)) ++ (comint-send-string process string))) ++ (error "No inferior Acl2 buffer"))) ++ ++;; acl2-eval-region, acl2-eval-event, and acl2-eval-last-sexp disappeared ++;; ??? Restored. Jul 22 94 MKS ++ ++(defun acl2-eval-region (start end &optional and-go) ++ "Send the current region to the inferior Acl2 process. ++Prefix argument means switch to the inferior Acl2 buffer afterwards." ++ (interactive "r\nP") ++ (goto-char end) ++ (send-region-to-acl2-process start end (or and-go *acl2-eval-and-go*))) ++ ++(defun acl2-eval-event (&optional and-go) ++ "Send the current defun to the inferior Acl2 process. ++Prefix argument means switch to the inferior Acl2 buffer afterwards." ++ (interactive "P") ++ (save-excursion ++ (condition-case nil ++ (end-of-defun) ++ (error (error "Current form unbalanced"))) ++ (skip-chars-backward " \t\n\r\f") ; Makes allegro happy ++ (let ((end (point))) ++ (beginning-of-defun) ++ ;; Rather than passing the and-go to eval-region we ++ ;; start the eval and then reposition in this buffer ++ ;; before switching. ++ (acl2-eval-region (point) end))) ++ ;; Same as lisp-eval-defun-and-move ++ ;; Deleted at Bevier's request Apr 20 95 MKS ++ ;; (end-of-defun) ++ (if (or and-go *acl2-eval-and-go*) (switch-to-acl2 t))) ++ ++(defun acl2-eval-last-sexp (&optional and-go) ++ "Send the previous sexp to the inferior Acl2 process. ++Prefix argument means switch to the inferior Acl2 buffer afterwards." ++ (interactive "P") ++ (acl2-eval-region (save-excursion (backward-sexp) (point)) (point) ++ (or and-go *acl2-eval-and-go*))) ++ ++(defun switch-to-acl2 (eob-p) ++ "Switch to the inferior Acl2 process buffer. ++With argument, positions cursor at end of buffer." ++ (interactive "P") ++ (if (get-buffer inferior-acl2-buffer) ++ (pop-to-buffer inferior-acl2-buffer) ++ (error "No current inferior Acl2 buffer")) ++ (cond (eob-p ++ (push-mark) ++ (goto-char (point-max))))) ++ ++(defun switch-to-acl2-eof () ++ "Switch to the inferior Acl2 process buffer & ++position cursor at end of buffer." ++ (interactive) ++ (if (get-buffer inferior-acl2-buffer) ++ (pop-to-buffer inferior-acl2-buffer) ++ (error "No current inferior Acl2 buffer")) ++ (push-mark) ++ (goto-char (point-max))) ++ ++ ++;;; Now that acl2-compile/eval-event/region takes an optional prefix arg, ++;;; these commands are redundant. But they are kept around for the user ++;;; to bind if he wishes, for backwards functionality, and because it's ++;;; easier to type C-c e than C-u C-c C-e. ++ ++(defun acl2-eval-region-and-go (start end) ++ "Send the current region to the inferior Acl2, and switch to its buffer." ++ (interactive "r") ++ (acl2-eval-region start end t)) ++ ++(defun acl2-eval-event-and-go () ++ "Send the current defun to the inferior Acl2, and switch to its buffer." ++ (interactive) ++ (acl2-eval-event t)) ++ ++(defvar acl2-prev-l/c-dir/file nil ++ "Record last directory and file used in loading or compiling. ++This holds a cons cell of the form `(DIRECTORY . FILE)' ++describing the last `acl2-load-file' or `acl2-compile-file' command.") ++ ++(defvar acl2-source-modes '(acl2-mode) ++ "Used to determine if a buffer contains Acl2 source code. ++If it's loaded into a buffer that is in one of these major modes, it's ++considered an Acl2 source file by `acl2-load-file' and `acl2-compile-file'. ++Used by these commands to determine defaults.") ++ ++(defun acl2-load-file (file-name) ++ "Load an Acl2 file into the inferior Acl2 process." ++ ;; 4th param below is NIL because LOAD doesn't need an exact name. ++ ;; But what about LD? ++ (interactive (comint-get-source "Load Acl2 file: " acl2-prev-l/c-dir/file ++ acl2-source-modes nil)) ++ (comint-check-source file-name) ; Check to see if buffer needs saved. ++ (setq acl2-prev-l/c-dir/file (cons (file-name-directory file-name) ++ (file-name-nondirectory file-name))) ++ (comint-send-string (inferior-acl2-proc) ++ (format inferior-acl2-load-command file-name)) ++ (switch-to-acl2 t)) ++ ++ ++;;; Documentation functions: function doc, var doc, arglist, and ++;;; describe symbol. ++;;; =========================================================================== ++ ++;;; Ancillary functions ++;;; =================== ++ ++;;; Reads a string from the user. ++(defun acl2-symprompt (prompt default) ++ (list (let* ((prompt (if default ++ (format "%s (default %s): " prompt default) ++ (concat prompt ": "))) ++ (ans (read-string prompt))) ++ (if (zerop (length ans)) default ans)))) ++ ++ ++;;; Adapted from function-called-at-point in help.el. ++(defun acl2-fn-called-at-pt () ++ "Returns the name of the function called in the current call. ++The value is nil if it can't find one." ++ (condition-case nil ++ (save-excursion ++ (save-restriction ++ (narrow-to-region (max (point-min) (- (point) 1000)) (point-max)) ++ (backward-up-list 1) ++ (forward-char 1) ++ (let ((obj (acl2-var-at-pt))) ++ (and (symbolp obj) obj)))) ++ (error nil))) ++ ++;;; Adapted from variable-at-point in help.el. ++(defun acl2-var-at-pt () ++ (condition-case () ++ (save-excursion ++ (forward-sexp 1) ++ (forward-sexp -1) ++ (skip-chars-forward "'") ++ (let* ((begin (point)) ++ (max (save-excursion (end-of-line) (point))) ++ (end (- (re-search-forward "[ ,()\\.!?#|`';']" max t) 1)) ++ (obj (car (read-from-string (buffer-substring begin end))))) ++ (and (symbolp obj) obj))) ++ (error nil))) ++ ++ ++;;; Documentation functions: fn and var doc, arglist, and symbol describe. ++;;; ====================================================================== ++ ++(defun inf-acl2-last-line-to-top () ++ (save-excursion ++ (set-buffer inferior-acl2-buffer) ++ (goto-char (point-max)) ++ (this-line-to-top))) ++ ++(defun inferior-acl2-proc () ++ "Returns the current inferior Acl2 process. ++See variable `inferior-acl2-buffer'." ++ (let ((proc (get-buffer-process (if (eq major-mode 'inferior-acl2-mode) ++ (current-buffer) ++ inferior-acl2-buffer)))) ++ (or proc ++ (error "No Acl2 subprocess; see variable `inferior-acl2-buffer'")))) ++ ++;; Try to unwedge Acl2. ++ ++(defun acl2-abort-mystery-wedge () ++ (interactive) ++ ;; (let ((inferior-acl2-load-command ":q\n")) ++ ;; (acl2-send-sexp-and-go)) ++ (comint-send-string (inferior-acl2-proc) ":q\n")) ++ ++ ++;;; Do the user's customisation... ++;;;=============================== ++(defvar inferior-acl2-load-hook nil ++ "This hook is run when the library `inf-acl2' is loaded. ++This is a good place to put keybindings.") ++ ++(run-hooks 'inferior-acl2-load-hook) ++ ++;;; CHANGE LOG ++;;; =========================================================================== ++;;; Feb 17 94 MKS - See inf-lisp.el ++ ++(provide 'inf-acl2) ++ ++;;; inf-acl2.el ends here. ++ ++ ++;;; Unused ++;; ++;; (defun acl2-show-function-documentation (fn) ++;; "Send a command to the inferior Acl2 to give documentation for function FN. ++;; See variable `acl2-function-doc-command'." ++;; (interactive (acl2-symprompt "Function doc" (acl2-fn-called-at-pt))) ++;; (inf-acl2-last-line-to-top) ++;; (comint-proc-query (inferior-acl2-proc) ++;; (format acl2-function-doc-command fn))) ++;; ++;; (defun acl2-describe-sym (sym) ++;; "Send a command to the inferior Acl2 to describe symbol SYM. ++;; See variable `acl2-describe-sym-command'." ++;; (interactive (acl2-symprompt "Describe" (acl2-var-at-pt))) ++;; (inf-acl2-last-line-to-top) ++;; (comint-proc-query (inferior-acl2-proc) ++;; (format acl2-describe-sym-command sym))) ++;; ++;; ++;; (defun acl2-show-function-documentation (fn) ++;; "Send a command to the inferior Acl2 to give documentation for function FN. ++;; See variable `acl2-function-doc-command'." ++;; (interactive (acl2-symprompt "Function doc" (acl2-fn-called-at-pt))) ++;; (inf-acl2-last-line-to-top) ++;; (comint-proc-query (inferior-acl2-proc) ++;; (format acl2-function-doc-command fn))) ++;; ++;; (defun acl2-show-variable-documentation (var) ++;; "Send a command to the inferior Acl2 to give documentation for function FN. ++;; See variable `acl2-var-doc-command'." ++;; (interactive (acl2-symprompt "Variable doc" (acl2-var-at-pt))) ++;; (inf-acl2-last-line-to-top) ++;; (comint-proc-query (inferior-acl2-proc) (format acl2-var-doc-command var))) ++;; ++;; (defun acl2-show-arglist (fn) ++;; "Send a query to the inferior Acl2 for the arglist for function FN. ++;; See variable `acl2-arglist-command'." ++;; (interactive (acl2-symprompt "Arglist" (acl2-fn-called-at-pt))) ++;; (inf-acl2-last-line-to-top) ++;; (comint-proc-query (inferior-acl2-proc) (format acl2-arglist-command fn))) ++;; ++;; (defun acl2-describe-sym (sym) ++;; "Send a command to the inferior Acl2 to describe symbol SYM. ++;; See variable `acl2-describe-sym-command'." ++;; (interactive (acl2-symprompt "Describe" (acl2-var-at-pt))) ++;; (inf-acl2-last-line-to-top) ++;; (comint-proc-query (inferior-acl2-proc) ++;; (format acl2-describe-sym-command sym))) ++;; ++;; (defun acl2-show-arglist (fn) ++;; "Send a query to the inferior Acl2 for the arglist for function FN. ++;; See variable `acl2-arglist-command'." ++;; (interactive (acl2-symprompt "Arglist" (acl2-fn-called-at-pt))) ++;; (inf-acl2-last-line-to-top) ++;; (comint-proc-query (inferior-acl2-proc) (format acl2-arglist-command fn))) ++;; ++;; (defun acl2-show-variable-documentation (var) ++;; "Send a command to the inferior Acl2 to give documentation for function FN. ++;; See variable `acl2-var-doc-command'." ++;; (interactive (acl2-symprompt "Variable doc" (acl2-var-at-pt))) ++;; (inf-acl2-last-line-to-top) ++;; (comint-proc-query (inferior-acl2-proc) (format acl2-var-doc-command var))) +--- /dev/null ++++ acl2-6.0/interface/emacs/load-inferior-acl2.el +@@ -0,0 +1,29 @@ ++ ++;; Load the emacs interface for acl2 and start it running in an ++;; inferior-acl2 buffer. ++ ++;; May 13 94 Kaufmann & MKSmith ++;; Sep 25 94 MKSmith ++ ++;; THIS GOES IN THE USER'S .emacs FILE, ++;; after loadpath is set to include this dir. ++ ++; BEGIN INSERT after this line ++; ++; (autoload 'run-acl2 ++; "top-start-inferior-acl2" ++; "Open communication between acl2 running in shell and prooftree." t) ++; ++; END INSERT before this line ++ ++(require 'acl2-interface) ;loads everything else ++ ++(defun initialize-mfm-buffer-variables () ++ (setq *mfm-buffer* inferior-acl2-buffer)) ++ ++(setq inferior-acl2-mode-hook ++ (extend-hook inferior-acl2-mode-hook 'initialize-mfm-buffer-variables)) ++ ++(defun load-inferior-acl2 () ++ (interactive) ++ (run-acl2 inferior-acl2-program)) +--- /dev/null ++++ acl2-6.0/interface/emacs/README-mouse +@@ -0,0 +1,6 @@ ++See the documentation topic PROOF-TREE-EMACS for how to start up and use proof ++trees with emacs. Also see PROOF-TREE for other information about proof trees. ++ ++The file README-mouse.doc in this directory explains additional features, not ++currently supported though they may work, provided by this interface -- notably ++mouse/menu support. +--- /dev/null ++++ acl2-6.0/interface/emacs/README-mouse.doc +@@ -0,0 +1,519 @@ ++ The ACL2 Prooftree and Mouse Interface ++ ++ ++ M. Kaufmann & M. K. Smith ++ ++ ++ ++1. Introduction ++ ++NOTE: This interface should be considered preliminary, although ++it has been used successfully at Computational Logic, Inc. It is ++not part of the ACL2 software in the strictest sense (which is ++co-authored by Matt Kaufmann and J Moore), but we feel that it ++will be useful to ACL2 users. ++ ++This note describes how to get the ACL2/Emacs prooftree and mouse ++support. You just need to add a single autoload form to your ++.emacs file. And then issue the correspoding M-x command. ++ ++The prooftree support has been tested in the following Emacs: ++ ++ Emacs 18 ++ Emacs 19 - with comint and WFS's shell, sshell.el. ++ Lemacs 19 ++ ++The menu and mouse support currently works with Emacs 19. ++ ++If you don't want to deal with any of this: You probably want to ++put the following form in your acl2-customization.lisp file. ++ ++ :STOP-PROOF-TREE ++ ++This will turn off the proof tree printing from ACL2. For ++documentation in ACL2 do ++ :doc proof-tree ++To turn proof trees back on use `:START-PROOF-TREE'. ++NOTE: If you do `:STOP-PROOF-TREE' in ACL2, then M-x ++start-proof-tree will not accomplish anything useful in Emacs. ++ ++ ++2. LOADING EMACS INTERFACE CODE ++ ++ ++2.1 Simplest .emacs Additions ++ ++If you want the full interface, put the following in your .emacs ++file after replacing /projects/acl2/v2-x/ with the full ++pathname of your acl2-sources/ directory. ++ ++ (setq *acl2-interface-dir* ++ "/projects/acl2/v2-x/interface/emacs/") ++ ++ (autoload 'run-acl2 ;;emacs 19.27 only at this time ++ (concat *acl2-interface-dir* "top-start-inferior-acl2") ++ "Begin ACL2 in an inferior ACL2 mode buffer." ++ t) ++ ++Then, to get things started in Emacs do `M-x run-acl2'. Use `M-x ++acl2-mode' to get `<acl2-file>.lisp' into the right mode. The ++commands in the various modes are listed in a later section. But ++you can see most of them by observing the new pull-down menus and ++pop-up menu in inferior ACL2 mode and ACL2 mode. The pop-up menu ++is tied to mouse-3. ++ ++If you just want proof trees, use the following after replacing ++/projects/acl2/v2-x/ with the full pathname of your ++acl2-sources/ directory. ++ ++ (setq *acl2-interface-dir* ++ "/projects/acl2/v2-x/interface/emacs/") ++ ++(autoload 'start-proof-tree ++ (concat *acl2-interface-dir* "top-start-shell-acl2") ++ "Enable proof tree logging in a prooftree buffer." ++ t) ++ ++ ++ ++2.2 More Control from .emacs: Setting preferences ++ ++The alist, *acl2-user-map-interface*, determines what menus you ++get. If a feature is included after a mode name, then you get ++it. ++ ++(defvar *acl2-user-map-interface* ++ '((inferior-acl2-mode menu-bar popup-menu keys) ++ (acl2-mode menu-bar popup-menu keys) ++ (prooftree-mode menu-bar popup-menu keys))) ++ ++ ++If you set the following to T, you will switch to the inferior ++ACL2 buffer when you send forms, regions, or buffers to it. ++ ++ (setq *acl2-eval-and-go* nil) ++ ++If you set the following to NIL you will be queried for their ++values when you start up a prooftree buffer (via M-x ++start-proof-tree). These are the defaults you get based on the ++autoload above. ++ ++ (setq *acl2-proof-tree-height* 17) ++ (setq *checkpoint-recenter-line* 3) ++ ++ ++ ++3. Commands ++ ++Commands are enabled based on the value of the alist, ++*acl2-user-map-interface*, as described above. There are some ++conventions that you need to know regarding arguments to mouse ++commands. ++ ++If a menu bar entry is of the form ++ ++ Print event ... ++ ++the "..." indicates that you will be prompted in the minibuffer ++for an argument. ++ ++If a menu bar entry is of the form ++ ++ Mode > ++ ++the ">" indicates a suborninate menu that will pop up if you ++release on this menu item. ++ ++Pop-up menu items indicate whether they take an argument based on ++a preceding ".". The argument is determined by what you clicked ++on to bring up the menu. Arguments derived from things that ++appear in the chronology are somewhat robust. So that if you had ++a list of events on the screen like: ++ 13 (DEFMACRO TEXT (X) ...) ++ L 14 (DEFUN MSG-P (X) ...) ++ L 15 (DEFUN MAKE-PACKET (X Y Z) ...) ++ L 16 (DEFUN HISTORY-P (L) ...) ++ 17 (DEFMACRO INFROM (X) ...) ++to see event 14 you could click right anywhere on that line and ++select either ". Print Event" or ". Print Command". ++ ++ ++3.1 Prooftree Related ++ ++ M-x start-proof-tree ++ M-x stop-proof-tree ++ ++ ++3.2 Prooftree Mode ++ ++ ++3.2-A POPUP MENU ++ ++ Abort Abort *inferior-acl2*. ++ Goto subgoal Go to clicked on subgoal in *inferior-acl2*. ++ Resume proof tree Resume printing proof tree. ++ Suspend proof tree Suspend printing proof tree. ++ Checkpoint/Suspend Suspend prooftree and go to clicked on checkpoint. ++ Checkpoint Go to clicked on checkpoint. ++ Help ++ ++ ++3.2-B MENU BAR ++ ++ Prooftree ++ ++ Checkpoint Go to next checkpoint ++ Goto subgoal That cursor is on. ++ Checkpoint / Suspend Go to next checkpoint and suspend proof tree. ++ Resume proof tree ++ Suspend proof tree ++ Abort Abort prooftree. (ACL2 will continue to send prooftrees, it just ++ won't go the the prooftree buffer.) ++ Help ++ ++ ++3.2-C KEYS ++ ++ C-z z Previous C-z key binding ++ C-z c Go to checkpoint ++ C-z s Suspend proof tree ++ C-z r Resume proof tree ++ C-z a Mfm abort secondary buffer ++ C-z g Goto subgoal ++ C-z h help ++ C-z ? help ++ ++ ++3.3 ACL2 Mode ++ ++ACL2 Mode is like Lisp mode except that the functions that send ++sexprs to the inferior Lisp process expect an inferior ACL2 ++process in the *inferior-acl2* buffer. ++ ++ ++3.3-A POPUP MENU ++ ++ Send to ACL2 Send top level form clicked on to ACL2. ++ Add hint Add the hint form to the clicked on defun. ++ ++ Do not induct. ++ Do not generalize. ++ Do not fertilize. ++ Expand expand form. Requests you mouse it. ++ Hands off. ++ Disable Disable symbol. Requests you mouse it. ++ Enable Enable symbol. Requests you mouse it. ++ Induct Induct based on form. Requests you mouse it. ++ Cases Perform case split on form.Requests you mouse it. ++ ++ Go to inferior ACL2 ++ Verify Take clicked on form into interactive prover. ++ ++ ++3.3-B KEYS ++ ++ C-x C-e eval last sexp ++ C-c C-r eval region ++ C-M-x eval defun ++ C-c C-e eval defun ++ C-c C-z switch to ACL2 ++ C-c C-l load file ++ C-c C-a show arglist ++ C-c C-d describe symbol ++ C-c C-f show function documentation ++ C-c C-v show variable documentation ++ C-ce eval defun and go to ACL2 ++ C-cr eval region and go to ACL2 ++ ++ ++3.4 Inferior ACL2 Mode ++ ++ ++3.4-A MENU BAR ++ ++ Events ++ ++ Recent events (pbt '(:here -10)) ++ Print back through ... (pbt <event>) ++ Undo (ubt ':here) ++ Oops (oops) ++ Undo through ... (ubt '<event>) ++ Undo through ... (ubt! '<cd>) ++ ++ Load file ... (cl2-load-file) ++ ++ Disable ... (in-theory (disable <symbol>)) ++ Enable ... (in-theory (enable <symbol>)) ++ ++ Verify guards ... (verify-guards '<symbol>) ++ Verify termination ... (verify-guards '<symbol>) ++ ++ Certify-book ... (certify-book <filename>) ++ Include-book ... (include-book <filename> ) ++ ++ Compound commands ++ ++ Expand compound command ... (puff '<cd>) ++ Expand compound command! ... (puff* '<cd>) ++ ++ Table ++ ++ Print value ... (table symbol) ++ Clear ... (table <symbol> nil nil :clear ++ Print guard ... (table <symbol> nil nil :guard) ++ ++ Print ++ ++ Event ... (pe 'event) ++ Event! ... (pe! 'event) ++ Back through ... (pbt 'event) ++ ++ Command ... (pc '<cd>) ++ Command block ... (pcb '<cd>) ++ Full Command block ... (pcb! '<cd>) ++ ++ Signature ... (args 'event) ++ Formula ... (pf 'event) ++ Properties ... (props 'event) ++ ++ Print connected book directory (cbd) ++ ++ Rules whose top function symbol is ... (pl 'event) ++ Rules stored by event ... (pr 'event) ++ Rules stored by command ... (pr! '<cd>) ++ ++ Monitored-runes (monitored-runes) ++ ++ Control ++ ++ Load ... (ld filename) ++ Accumulated Persistence ++ ++ Activate (accumulated-persistence t) ++ Deactivate (accumulated-persistence nil) ++ Display statistics ordered by ++ ++ frames (show-accumulated-persistence :frames) ++ times tried (show-accumulated-persistence :tries) ++ ratio (show-accumulated-persistence :ratio) ++ ++ Break rewrite ++ ++ Start general rule monitoring (brr t) ++ Stop general rule monitoring (brr nil) ++ Print monitored runes (monitored-runes) ++ Monitor rune: ... (monitor '(:definition <event>) 't) ++ Unmonitor rune: ... (unmonitor '(:definition <event>)) ++ ++ Commands ++ ++ Abort to ACL2 top-level #. ++ Term being rewritten :target ++ Substitution making :lhs equal :target :unify-subst ++ Hypotheses :hyps ++ Ith hypothesis ... :hyp <integer> ++ Left-hand side of conclusion :lhs ++ Right-hand side of conclusion :rhs ++ Type assumptions governing :target :type-alist ++ Ttree before :eval :initial-ttree ++ Negations of backchaining hyps pursued :ancestors ++ ++ Rewrite's path from top clause to :target :path ++ Top-most frame in :path :top ++ Ith frame in :path ... :frame <integer> ++ ++ AFTER :EVAL ++ ++ Did application succeed? :wonp ++ Rewritten :rhs :rewritten-rhs ++ Ttree :final-ttree ++ Reason rule failed :failure-reason ++ ++ CONTROL ++ ++ Exit break :ok ++ Exit break, printing result :go ++ Try rule and re-enter break afterwards :eval ++ ++ WITH NO RECURSIVE BREAKS ++ ++ :ok! (:ok!) ++ :go! (:go!) ++ :eval! (:eval!) ++ ++ WITH RUNES MONITORED DURING RECURSION ++ ++ :ok ... (:ok$ sexpr) ++ :go ... (:go$ sexpr) ++ :eval ... (:eval$ sexpr) ++ ++ Help (:help) ++ ++ Enter ACL2 Loop (lp) ++ Quit to Common Lisp :Q ++ ABORT (:good-bye) ++ ++ Settings ++ ++ Mode ++ ++ Logic (logic) ++ Program (program) ++ Guard checking on (set-guard-checking t) ++ Guard checking off (set-guard-checking nil) ++ ++ Forcing ++ ++ On (enable-forcing) ++ Off (disable-forcing) ++ ++ Compile functions ++ ++ On (set-compile-fns t) ++ Off (set-compile-fns nil) ++ ++ Proof tree ++ ++ Start prooftree (start-proof-tree)pre (start-proof-tree nil)) ++ Stop prooftree (stop-proof-tree)post (stop-proof-tree)) ++ Checkpoint forced goals on (checkpoint-forced-goals) ++ ++ Inhibit Display of ++ ++ Error messages (assign inhibit-output-lst '(error)) ++ Warnings (assign inhibit-output-lst '(warning)) ++ Observations (assign inhibit-output-lst '(observation)) ++ Proof commentary (assign inhibit-output-lst '(prove)) ++ Proof tree (assign inhibit-output-lst '(prove)) ++ Non-proof commentary (assign inhibit-output-lst '(event)) ++ Summary (assign inhibit-output-lst '(summary)) ++ ++ Unused Variables ++ ++ Ignore (set-ignore-ok t) ++ Fail (set-ignore-ok nil) ++ Warn (set-ignore-ok :warn) ++ ++ Irrelevant formulas ++ ++ Ok (set-irrelevant-formals-ok t) ++ Fail (set-irrelevant-formals-ok nil) ++ Warn (set-irrelevant-formals-ok :warn) ++ ++ Load ++ ++ Error action ++ ++ Continue (set-ld-error-actions :continue) ++ Return (set-ld-error-actions :return) ++ Error (set-ld-error-actions :error) ++ ++ Error triples ++ ++ On (set-ld-error-triples t) ++ Off (set-ld-error-triples nil) ++ ++ Post eval print ++ ++ On (set-ld-post-eval-print t) ++ Off (set-ld-post-eval-print nil) ++ Command conventions (set-ld-post-eval-print :command-conventions) ++ ++ Pre eval filter ++ ++ All (set-ld-pre-eval-filter :all) ++ Query (set-ld-pre-eval-filter :query) ++ ++ Prompt ++ ++ On (set-ld-prompt t) ++ Off (set-ld-prompt nil) ++ ++ Skip proofs ++ ++ On (set-ld-skip-proofs t) ++ Off (set-ld-skip-proofs nil) ++ ++ Verbose: on ++ ++ On (set-ld-verbose t) ++ Off (set-ld-verbose nil) ++ ++ Redefinition permitted (redef) ++ Reset specials (reset-ld-specials t) ++ HACKERS. DANGER! ++ ++ RED redefinition! (redef!) ++ ++ ++ Books ++ ++ Print connected book directory (cbd) ++ Set connected book directory ... (set-cbd filename) ++ Certify-book ... (certify-book filename) ++ Include-book ... (include-book filename) ++ ++ ACL2 Help ++ ++ Documentation (doc '<symbol>) ++ Arguments (args '<symbol>) ++ More (more) ++ Apropos ... (docs '<symbol>) ++ Release Notes (cl2-info-release-notes) ++ ++ ++ ++3.4-B INFERIOR ACL2 POPUP MENU ++ ++ Recent events (pbt '(:here -10)) ++ Print Event (pe '<symbol>) ++ Print back to (pbt '<cd>) ++ Disable (in-theory (disable <symbol>)) ++ Enable (in-theory (enable <symbol>)) ++ Undo (ubt ':here) ++ Undo thru (ubt '<cd>) ++ Documentation (doc '<symbol>) ++ Arguments, etc (args '<symbol>) ++ Verify Take clicked on form into interactive prover. ++ ++ ++3.4-C KEYS ++ ++ C-x C-e Eval last sexp ++ C-c C-l Load file ++ C-c C-a Show arglist ++ C-c C-d Describe symbol ++ C-c C-f Show function documentation ++ C-c C-v Show variable documentation ++ C-cl Load file ++ C-ck Compile file ++ C-ca Show arglist ++ C-cd Describe symbol ++ C-cf Show function documentation ++ C-cv Show variable documentation ++ ++ The ACL2 Prooftree and Mouse Interface ++ ++ ++ ++ Table of Contents ++ ++ ++ ++ 1. Introduction . . . . . . . . . . . . . . . . . . . . 1 ++ 2. LOADING EMACS INTERFACE CODE . . . . . . . . . . . . 1 ++ 2.1. Simplest .emacs Additions . . . . . . . . . . . . 1 ++ 2.2. More Control from .emacs: Setting preferences . . 1 ++ 3. Commands . . . . . . . . . . . . . . . . . . . . . . 1 ++ 3.1. Prooftree Related . . . . . . . . . . . . . . . . 1 ++ 3.2. Prooftree Mode . . . . . . . . . . . . . . . . . 1 ++ 3.2-A. POPUP MENU . . . . . . . . . . . . . . . . . 1 ++ 3.2-B. MENU BAR . . . . . . . . . . . . . . . . . . 1 ++ 3.2-C. KEYS . . . . . . . . . . . . . . . . . . . . 1 ++ 3.3. ACL2 Mode . . . . . . . . . . . . . . . . . . . 1 ++ 3.3-A. POPUP MENU . . . . . . . . . . . . . . . . . 1 ++ 3.3-B. KEYS . . . . . . . . . . . . . . . . . . . . 2 ++ 3.4. Inferior ACL2 Mode . . . . . . . . . . . . . . . 2 ++ 3.4-A. MENU BAR . . . . . . . . . . . . . . . . . . 2 ++ 3.4-B. INFERIOR ACL2 POPUP MENU . . . . . . . . . . 3 ++ 3.4-C. KEYS . . . . . . . . . . . . . . . . . . . . 3 +--- /dev/null ++++ acl2-6.0/interface/emacs/top-start-inferior-acl2.el +@@ -0,0 +1,11 @@ ++(defvar *acl2-interface-dir* ++ "/slocal/src/acl2/v1-8/interface/emacs/") ++ ++(setq *acl2-user-map-interface* ++ '((inferior-acl2-mode-map menu-bar popup-menu keys) ++ (shell-mode-map menu-bar popup-menu keys) ++ (acl2-mode-map menu-bar popup-menu keys) ++ (prooftree-mode-map menu-bar popup-menu keys))) ++ ++(let ((load-path (cons *acl2-interface-dir* load-path))) ++ (load "load-inferior-acl2")) +--- /dev/null ++++ acl2-6.0/interface/emacs/key-interface.el +@@ -0,0 +1,106 @@ ++ ++;; Add key interface for prooftree buffers. ++;; March 3 95 MKS ++ ++;; ---------------------------------------------------------------------- ++;; USER SETTINGS ++ ++;; (defvar *acl2-proof-tree-height* 17) ++;; (defvar *checkpoint-recenter-line* 3) ++ ++;; ---------------------------------------------------------------------- ++;; Load all of the various acl2-interface files, if necessary. ++ ++(load "mfm-acl2.el") ;(require 'mfm-acl2) ++ ++;; (load "interface-macros.el") ;(require 'interface-macros) ++;; Replaced by the following defvar and four functions, which is all this ++;; file used from interface macros. ++ ++;; Begin insert ++ ++(defvar mode-menu-alist nil) ++ ++;; WARNING: Be sure that if should-i-install, update-mode-menu-alist, ++;; remove-mode-menu-alist, define-mode-keys, or extend-hook is changed, then it ++;; is also changed in key-interface.el. ++ ++(defun should-i-install (mode feature) ++ ;; mode is mode-name ++ (memq feature (cdr (assoc mode mode-menu-alist)))) ++ ++(defun update-mode-menu-alist (l) ++ (if (not (consp (car l))) ++ (setq l (cons l nil))) ++ (setq mode-menu-alist ++ (append l (remove-mode-menu-alist mode-menu-alist l)))) ++ ++(defun remove-mode-menu-alist (alist l) ++ (cond ((null alist) l) ++ ((assoc (car (car alist)) l) ++ (remove-mode-menu-alist (cdr alist) l)) ++ (t (cons (car alist) (remove-mode-menu-alist (cdr alist) l))))) ++ ++(defun define-mode-keys (mode-map-name mode-map keys) ++ ;; An entry in keys may have two forms: ++ ;; (key function) ++ ;; (keymap key function) ++ ;; The second allows you to create subkeymaps, e.g. Control-Z ++ (if (should-i-install mode-map-name 'keys) ++ (mapcar ++ (function (lambda (x) ++ (if (equal (length x) 2) ++ (define-key mode-map (car x) (car (cdr x))) ++ (if (keymapp (eval (car x))) ++ (define-key (eval (car x)) (car (cdr x)) (car (cdr (cdr x)))) ++ (error ++ (format "Keymap %s not defined in mode %s" (car x) (car mode-map))))))) ++ keys))) ++ ++(defun extend-hook (hook entry) ++ ;; Add an entry onto a mode-hook, being sensitive to the ++ ;; stupid Emacs permission for it to be a function or list ++ ;; of functions. ++ (cond ((null hook) (list entry)) ++ ((symbolp hook) (if (not (equal entry hook)) (list hook entry) hook)) ++ ((not (consp hook)) ++ (message (format "Strange hook, %s, replaced by %s." hook entry)) ++ (list entry)) ++ ((equal (car hook) 'lambda) ++ (list hook entry)) ++ ((member-equal entry hook) hook) ++ (t (append hook (list entry))))) ++ ++;; end insert ++ ++(update-mode-menu-alist *acl2-user-map-interface*) ++ ++;; Defined in mfm-acl2 so that checkpoint-help can use it. ++(defvar prooftree-subkey) ++(setq prooftree-subkey "\C-z") ++ ++;; prooftree-subkeymap was set by prooftree-mode.el. Now do it here. ++(defvar prooftree-subkeymap (make-sparse-keymap)) ++ ++(defvar old-prooftree-subkey (global-key-binding prooftree-subkey)) ++ ++(define-key (current-global-map) prooftree-subkey prooftree-subkeymap) ++ ++(defconst prooftree-keys ++; WARNING: Keep this in sync with the corresponding definition in ++; acl2-interface.el. ++ (list ++ (list 'prooftree-subkeymap "z" old-prooftree-subkey) ++ (list 'prooftree-subkeymap "c" 'checkpoint) ++ (list 'prooftree-subkeymap "s" 'suspend-proof-tree) ++ (list 'prooftree-subkeymap "r" 'resume-proof-tree) ++ (list 'prooftree-subkeymap "g" 'goto-subgoal) ++ (list 'prooftree-subkeymap "h" 'checkpoint-help) ++ (list 'prooftree-subkeymap "?" 'checkpoint-help) ++ (list 'prooftree-subkeymap "o" 'select-other-frame-with-focus) ++ (list 'prooftree-subkeymap "b" 'visit-proof-tree) ++ (list 'prooftree-subkeymap "B" 'visit-proof-tree-other-frame))) ++ ++(define-mode-keys 'global (current-global-map) prooftree-keys) ++ ++(provide 'key-interface) diff --git a/debian/patches/mips64el-mxgot-flags-on-select-books b/debian/patches/mips64el-mxgot-flags-on-select-books new file mode 100644 index 0000000..d970319 --- /dev/null +++ b/debian/patches/mips64el-mxgot-flags-on-select-books @@ -0,0 +1,48 @@ +Description: <short summary of the patch> + TODO: Put a short summary on the line above and replace this paragraph + with a longer explanation of this change. Complete the meta-information + with other relevant fields (see below for details). To make it easier, the + information below has been extracted from the changelog. Adjust it or drop + it. + . + acl2 (7.4dfsg-2) unstable; urgency=medium + . + * Set GCL_MULTIPROCESS_MEMORY_POOL for certifications + * build-dep latest gcl for mips64el fix + * Bug fix: "build fails on mips (mips-aql-05)", thanks to Héctor Orón + Martínez (Closes: #863224). + * mxgot .acl2 files patch +Author: Camm Maguire <camm@debian.org> +Bug-Debian: https://bugs.debian.org/863224 + +--- +The information above should follow the Patch Tagging Guidelines, please +checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here +are templates for supplementary fields that you might want to add: + +Origin: <vendor|upstream|other>, <url of original patch> +Bug: <url in upstream bugtracker> +Bug-Debian: https://bugs.debian.org/<bugnumber> +Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber> +Forwarded: <no|not-needed|url proving that it has been forwarded> +Reviewed-By: <name and email of someone who approved the patch> +Last-Update: 2017-05-28 + +--- /dev/null ++++ acl2-7.4dfsg/books/centaur/fty/tests/deftagsum-scale.acl2 +@@ -0,0 +1,3 @@ ++:q ++#+(and gcl mips64el)(setq compiler::*cc* (concatenate 'string compiler::*cc* " -mxgot ")) ++(lp) +--- /dev/null ++++ acl2-7.4dfsg/books/centaur/fty/tests/deftranssum.acl2 +@@ -0,0 +1,3 @@ ++:q ++#+(and gcl mips64el)(setq compiler::*cc* (concatenate 'string compiler::*cc* " -mxgot ")) ++(lp) +--- /dev/null ++++ acl2-7.4dfsg/books/centaur/vl2014/parsetree.acl2 +@@ -0,0 +1,3 @@ ++:q ++#+(and gcl mips64el)(setq compiler::*cc* (concatenate 'string compiler::*cc* " -mxgot ")) ++(lp) diff --git a/debian/patches/patches.in-replacement b/debian/patches/patches.in-replacement new file mode 100644 index 0000000..84ff898 --- /dev/null +++ b/debian/patches/patches.in-replacement @@ -0,0 +1,50 @@ +Description: <short summary of the patch> + TODO: Put a short summary on the line above and replace this paragraph + with a longer explanation of this change. Complete the meta-information + with other relevant fields (see below for details). To make it easier, the + information below has been extracted from the changelog. Adjust it or drop + it. + . + acl2 (6.0-1) unstable; urgency=low + . + * New upstream release +Author: Camm Maguire <camm@debian.org> + +--- +The information above should follow the Patch Tagging Guidelines, please +checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here +are templates for supplementary fields that you might want to add: + +Origin: <vendor|upstream|other>, <url of original patch> +Bug: <url in upstream bugtracker> +Bug-Debian: http://bugs.debian.org/<bugnumber> +Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber> +Forwarded: <no|not-needed|url proving that it has been forwarded> +Reviewed-By: <name and email of someone who approved the patch> +Last-Update: <YYYY-MM-DD> + +--- acl2-6.0.orig/books/interface/emacs/acl2-interface.el ++++ acl2-6.0/books/interface/emacs/acl2-interface.el +@@ -28,13 +28,18 @@ + ;; ---------------------------------------------------------------------- + ;; Load all of the various acl2-interface files, if necessary. + +-(load "inf-acl2.el") ;(require 'inf-acl2) +-(load "mfm-acl2.el") ;(require 'mfm-acl2) +-(load "interface-macros.el") ;(require 'interface-macros) ++;(load "inf-acl2.el") ;(require 'inf-acl2) ++;(load "mfm-acl2.el") ;(require 'mfm-acl2) ++;(load "interface-macros.el") ;(require 'interface-macros) ++ ++(require 'inf-acl2) ++(require 'mfm-acl2) ++(require 'interface-macros) + + (update-mode-menu-alist *acl2-user-map-interface*) + +-(load "acl2-interface-functions.el") ++;(load "acl2-interface-functions.el") ++(load "acl2-interface-functions") + + ;; ---------------------------------------------------------------------- + ;; Specials used by functions in interface-macros.el. diff --git a/debian/patches/pathnames b/debian/patches/pathnames new file mode 100644 index 0000000..4619ca0 --- /dev/null +++ b/debian/patches/pathnames @@ -0,0 +1,47 @@ +Description: <short summary of the patch> + TODO: Put a short summary on the line above and replace this paragraph + with a longer explanation of this change. Complete the meta-information + with other relevant fields (see below for details). To make it easier, the + information below has been extracted from the changelog. Adjust it or drop + it. + . + acl2 (7.2dfsg-3) unstable; urgency=medium + . + * build-dep against latest gcl + * upstream pathname patch +Author: Camm Maguire <camm@debian.org> + +--- +The information above should follow the Patch Tagging Guidelines, please +checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here +are templates for supplementary fields that you might want to add: + +Origin: <vendor|upstream|other>, <url of original patch> +Bug: <url in upstream bugtracker> +Bug-Debian: https://bugs.debian.org/<bugnumber> +Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber> +Forwarded: <no|not-needed|url proving that it has been forwarded> +Reviewed-By: <name and email of someone who approved the patch> +Last-Update: 2016-10-15 + +--- acl2-7.2dfsg.orig/other-events.lisp ++++ acl2-7.2dfsg/other-events.lisp +@@ -8692,9 +8692,15 @@ + (and (implies dir-p + (not (or (stringp name) (stringp type)))) + (assert$ (and (true-listp dir) +- (eq (car dir) +- #+gcl :ROOT +- #-gcl :ABSOLUTE)) ++ #+gcl ++ (member (car dir) ++ '(:ROOT ; for backward compatibility ++ #+cltl2 ++ :ABSOLUTE) ++ :test #'eq) ++ #-gcl ++ (eq (car dir) :ABSOLUTE) ++ ) + (let* ((mswindows-drive + (mswindows-drive (namestring truename) state)) + (tmp (if mswindows-drive diff --git a/debian/patches/remove-pcert-elementary-bounders-for-final-file b/debian/patches/remove-pcert-elementary-bounders-for-final-file new file mode 100644 index 0000000..f31966a --- /dev/null +++ b/debian/patches/remove-pcert-elementary-bounders-for-final-file @@ -0,0 +1,33 @@ +Description: fix elementary-bounders .final file +pcert appears to interfere with the certification path renaming + mechanism. This patch was suggested by upstream as a workaround. + . + acl2 (7.0-1) unstable; urgency=medium + . + * New upstream release +Author: Camm Maguire <camm@debian.org> + +--- +The information above should follow the Patch Tagging Guidelines, please +checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here +are templates for supplementary fields that you might want to add: + +Origin: <vendor|upstream|other>, <url of original patch> +Bug: <url in upstream bugtracker> +Bug-Debian: https://bugs.debian.org/<bugnumber> +Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber> +Forwarded: <no|not-needed|url proving that it has been forwarded> +Reviewed-By: <name and email of someone who approved the patch> +Last-Update: <YYYY-MM-DD> + +--- acl2-7.0.orig/books/tau/bounders/elementary-bounders.lisp ++++ acl2-7.0/books/tau/bounders/elementary-bounders.lisp +@@ -188,8 +188,6 @@ + + (in-package "ACL2") + +-; cert_param: (pcert=1) +- + (local (include-book "arithmetic-5/top" :dir :system)) + + (local (deftheory jared-disables diff --git a/debian/patches/remove-pcert-local-elided-for-final-file b/debian/patches/remove-pcert-local-elided-for-final-file new file mode 100644 index 0000000..44e8a89 --- /dev/null +++ b/debian/patches/remove-pcert-local-elided-for-final-file @@ -0,0 +1,36 @@ +Description: <short summary of the patch> + TODO: Put a short summary on the line above and replace this paragraph + with a longer explanation of this change. Complete the meta-information + with other relevant fields (see below for details). To make it easier, the + information below has been extracted from the changelog. Adjust it or drop + it. + . + acl2 (7.0-1) unstable; urgency=medium + . + * New upstream release +Author: Camm Maguire <camm@debian.org> + +--- +The information above should follow the Patch Tagging Guidelines, please +checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here +are templates for supplementary fields that you might want to add: + +Origin: <vendor|upstream|other>, <url of original patch> +Bug: <url in upstream bugtracker> +Bug-Debian: https://bugs.debian.org/<bugnumber> +Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber> +Forwarded: <no|not-needed|url proving that it has been forwarded> +Reviewed-By: <name and email of someone who approved the patch> +Last-Update: <YYYY-MM-DD> + +--- acl2-7.0.orig/books/make-event/local-elided.lisp ++++ acl2-7.0/books/make-event/local-elided.lisp +@@ -10,8 +10,6 @@ + ;; as a proxy for checking whether it was provisionally or regularly certified, + ;; and that's just sort of wrong... + +-; cert_param: (pcert) +- + (local (make-event '(defun foo (x) x))) + + (make-event '(local (defun foo (x) x))) diff --git a/debian/patches/series b/debian/patches/series new file mode 100644 index 0000000..39660bd --- /dev/null +++ b/debian/patches/series @@ -0,0 +1,3 @@ +remove-pcert-elementary-bounders-for-final-file +remove-pcert-local-elided-for-final-file +do-not-pre-allocate-contiguous-blocks-in-acl2.lisp diff --git a/debian/patches/tight-memory-for-centaur-toplint b/debian/patches/tight-memory-for-centaur-toplint new file mode 100644 index 0000000..18e5933 --- /dev/null +++ b/debian/patches/tight-memory-for-centaur-toplint @@ -0,0 +1,40 @@ +Description: <short summary of the patch> + TODO: Put a short summary on the line above and replace this paragraph + with a longer explanation of this change. Complete the meta-information + with other relevant fields (see below for details). To make it easier, the + information below has been extracted from the changelog. Adjust it or drop + it. + . + acl2 (6.0-3) unstable; urgency=low + . + * Lintian cleanups + * certify centaur books with memory adjustments (lint.acl2, top.acl2) +Author: Camm Maguire <camm@debian.org> + +--- +The information above should follow the Patch Tagging Guidelines, please +checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here +are templates for supplementary fields that you might want to add: + +Origin: <vendor|upstream|other>, <url of original patch> +Bug: <url in upstream bugtracker> +Bug-Debian: http://bugs.debian.org/<bugnumber> +Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber> +Forwarded: <no|not-needed|url proving that it has been forwarded> +Reviewed-By: <name and email of someone who approved the patch> +Last-Update: <YYYY-MM-DD> + +--- /dev/null ++++ acl2-6.0/books/centaur/vl/top.acl2 +@@ -0,0 +1,4 @@ ++(acl2::value :q) ++(setq si::*optimize-maximum-pages* nil) ++(acl2::lp) ++(include-book "portcullis") +--- /dev/null ++++ acl2-6.0/books/centaur/vl/lint/lint.acl2 +@@ -0,0 +1,4 @@ ++(acl2::value :q) ++(setq si::*optimize-maximum-pages* nil) ++(acl2::lp) ++(include-book "../portcullis") diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..b680e79 --- /dev/null +++ b/debian/rules @@ -0,0 +1,356 @@ +#!/usr/bin/make -f +# Sample debian/rules that uses debhelper. +# GNU copyright 1997 by Joey Hess. +# +# This version is for a hypothetical package that builds an +# architecture-dependant package, as well as an architecture-independent +# package. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +# This is the debhelper compatability version to use. +#export DH_COMPAT=4 + +# This has to be exported to make some magic below work. +export DH_OPTIONS + +PN:=acl2 +VR:=$(shell awk '{if (i) next;i=1;a=$$2;gsub("[()]","",a);split(a,A,"-");print A[1];}' debian/changelog) +PD:=$(PN)-$(VR) + + +NO_STRIP:= +# ifeq ($(DEB_BUILD_ARCH),powerpc) +# NO_STRIP:=--exclude=saved_acl2 +# endif + +NUMJOBS:=1 +ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) + NUMJOBS:=$(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) +endif +NUMJOBS:=$(shell if test $(NUMJOBS) -gt 8; then echo 8 ; else echo $(NUMJOBS); fi) + +#books/workshops: +# mkdir $@ + +#init.lsp.ori: +# [ -e $@ ] || mv init.lsp $@ + +DLOPEN_T:=debian/dlopen.lisp #init.lsp.ori + +#ifeq ($(DEB_BUILD_ARCH),ia64) +#DLOPEN?=$(DLOPEN_T) +#endif +#ifeq ($(DEB_BUILD_ARCH),alpha) +#DLOPEN?=$(DLOPEN_T) +#endif +#ifeq ($(DEB_BUILD_ARCH),mips) +#DLOPEN?=$(DLOPEN_T) +#endif +#ifeq ($(DEB_BUILD_ARCH),mipsel) +#DLOPEN?=$(DLOPEN_T) +#endif +#ifeq ($(DEB_BUILD_ARCH),hppa) +#DLOPEN?=$(DLOPEN_T) +#endif + +debian/dlopen.lisp: debian/dlopen.lisp.in + cat $< | sed "s,@VR@,$(VR),g" > $@ + +debian/acl2-emacs.emacsen-startup: debian/acl2-emacs.emacsen-startup.in + cat $< | sed "s,@VR@,$(VR),g" > $@ + +#pgcl: +# echo "(progn #+:x86_64(setq si::*code-block-reserve* (make-array 50000000 :element-type (quote character) :static t))" \ +# "(si::save-system \"$@\"))" | GCL_ANSI=t gcl + +saved_acl2: $(DLOPEN_T) #debian/patches_applied pgcl +# echo '(progn (load "debian/sublis_patch.lsp")(si::save-system "pgcl"))' | gcl + gcl -batch -eval "(bye #-native-reloc 1)" || \ + (gcl -batch -eval '(load "debian/dlopen.lisp")' && $(MAKE) do_saved) + gcl -batch -eval "(bye #+native-reloc 1)" || $(MAKE) GCL_ANSI=t LISP=gcl + mv *$@.gcl $@ + +saved_acl2.c: saved_acl2 + echo "(f-put-global 'old-certification-dir \"$$(pwd)/books\" state)" \ + "(f-put-global 'new-certification-dir \"/usr/share/$(PD)/books\" state)" \ + ":q #-native-reloc (setq si::*multiply-stacks* 4) :q (in-package :acl2) " \ + "#+(or sparc sparc64)(progn (si::sgc-on nil) (fmakunbound 'si::sgc-on))" \ + "(save-exec \"$@\" \"Modified to produce final certification files\")" | HOME=$$(pwd) ./$< + mv $@.gcl $@ + +debian/mini-proveall.out: saved_acl2 + HOME=$$(pwd) $(MAKE) mini-proveall + mv $(@F) $@ + +books/short-test.log: saved_acl2.c + cp saved_acl2 saved_acl2.ori + HOME=$$(pwd) $(MAKE) certify-books-short + cp saved_acl2.ori saved_acl2 + +# tail -f --pid=$$j --retry $@ $$(find books -name "*.lisp" | sed 's,\.lisp$$,.out,1') & \ + +debian/test.log: saved_acl2.c + mv saved_acl2 saved_acl2.ori + cp $< saved_acl2 + BUILDDIR="$$(dirname $$(pwd))" \ + FINALDIR="/usr/share/$(PD)" \ + HOME=$$(pwd) \ + EXCLUDED_PREFIXES=centaur/tutorial/alu16-book \ + GCL_MULTIPROCESS_MEMORY_POOL=t \ + $(MAKE) -j $(NUMJOBS) -l 2.95 certify-books 2>&1 | tee $@ & j=$$! ; \ + while sleep 1800; do echo Tick; done & k=$$! ; \ + wait $$j ; kill $$k +# >$@ 2>&1 & j=$$! ; \ +# while sleep 1800; do echo Tick; done & k=$$! ; tail -f debian/test.log & l=$$! ; \ +# wait $$j ; kill $$k $$l +# [ -f $@ ] && ! fgrep '**' $@ || (echo FULL TEST FAILS ;\ +# for i in $$(find books -name "*.out"); do \ +# if ! [ -e $${i%out}cert ] ; then \ +# echo $$i ; \ +# cat $$i ; \ +# fi ; \ + done) + mv saved_acl2.ori saved_acl2 + [ -f $@ ] && ( ! fgrep '**' $@ || \ + gcl -batch -eval "(bye #-native-reloc 0 #+native-reloc (let ((w (multiple-value-bind (a b c d) (si::heap-report) (/ (- d c) (/ a 8))))) (format t \"certification run with ~s heap words~%\" w) (if (< w 500000000) 0 1)))") + +books/interface/infix/Makefile: books/interface/infix/makefile + sed -e "s,^DIR = .*,DIR = $$(pwd)/books/interface/infix,1" \ + -e "s,^LISP = .*,LISP = $$(pwd)/saved_acl2,1" $< > $@ + +infix-stamp: books/interface/infix/Makefile saved_acl2 + cd books/interface/infix && make -f Makefile compile + cd books/interface/infix && make -f Makefile example +# cd books/interface/infix && make -f Makefile events + touch $@ + +doc/TEX/acl2-book.ps.gz: saved_acl2 + HOME=$$(pwd) $(MAKE) DOC + rm -f doc/HTML/LICENSE + find doc -empty -exec rm {} \; + +build: build-arch build-indep +build-arch: build-stamp +build-indep: build-stamp +build-stamp: debian/mini-proveall.out debian/test.log infix-stamp # doc/TEX/acl2-book.ps.gz + dh_testdir + +# $(MAKE) + + touch build-stamp + +infix_clean: books/interface/infix/Makefile + rm -f infix-stamp + cd books/interface/infix && make -f Makefile clean + rm -f books/interface/infix/Makefile + + +debian/dpatches: debian/patches.in + debian/rules debian/patches_unapplied + cat $< | sed -e "s,@BDIR@,$$(pwd),1" -e "s,@DDIR@,/usr/share/$(PD),1" >$@ + +debian/patches_applied: debian/dpatches + ! [ -e debian/patches_unapplied ] || \ + (patch -p1 < $< && rm -f debian/patches_unapplied) + touch $@ + +debian/patches_unapplied: + ! [ -e debian/patches_applied ] || ! [ -e debian/dpatches ] || \ + (patch -p1 -R < debian/dpatches && rm -f debian/patches_applied) + touch $@ + + +INSTALLS:=$(addprefix debian/,$(addsuffix .install,acl2 acl2-source acl2-emacs acl2-doc acl2-books acl2-books-source acl2-books-certs acl2-infix acl2-infix-source)) +LINKS:=$(addprefix debian/,$(addsuffix .links,acl2 acl2-books acl2-infix)) +IFILES:=$(INSTALLS) $(shell ls -1 debian/*.examples debian/*.docs) +debian/README.Debian: debian/README.Debian.in $(IFILES) + awk '/@PLIST@/ {exit 0} {print}' $< >$@ + for i in $(filter %.install,$^); do\ + awk '/^debian\// {next} {sub(".final$$","",$$1);$$2="/" $$2;print $$0 " " p}' \ + p=$$(basename $${i%.install}) $$i >>$@ ; done + for i in $(filter %.info,$^); do\ + awk '/^debian\// {next} {print $$0 " /usr/share/info " p}' p=$$(basename $${i%.info}) $$i >>$@ ; done + for i in $(filter %.examples,$^); do\ + awk '/^debian\// {next} {print $$0 " /usr/share/doc/" p "/examples " p}' \ + p=$$(basename $${i%.examples}) $$i >>$@ ; done + for i in $(filter %.docs,$^); do\ + awk '/^debian\// {next} {print $$0 " /usr/share/doc/" p " " p}' p=$$(basename $${i%.docs}) $$i >>$@ ; done + awk '/@PLIST@/ {i=1;next} {if (i) print}' $< >>$@ + +clean: infix_clean #debian/patches_unapplied books/workshops + dh_testdir + dh_testroot + rm -f build-stamp + + $(MAKE) clean + $(MAKE) clean-books + find books -name "*.final" -exec rm {} \; + rm -f saved_acl2 init_nsaved1_acl2.lsp worklispext + rm -f debian/mini-proveall.out books/short-test.log debian/test.log +# ! [ -e init.lsp.ori ] || mv init.lsp.ori init.lsp + rm -f foo.lsp nsaved_acl2 + for i in data c h ; do \ + for j in $$(find -name "*.$$i") ; do\ + k=$$(echo $$j | sed "s,\.$$i$$,,1") ;\ + ! [ -e $$k.lisp ] || rm $$j ; \ + done ; \ + done + rm -f books/bdd/benchmarks.data acl2r.lisp tmp + rm -f debian/dpatches $(INSTALLS) $(LINKS) debian/README.Debian saved_acl2* + rm -f debian/dlopen.lisp debian/acl2-emacs.emacsen-startup + rm -f debian/acl2.sh pgcl books/Makefile-tmp books/coi/gensym/gensym.out sys-proclaim.lisp + rm -f books/coi/gensym/Makefile-deps books/coi/gensym/workxxx.gensym books/system/doc/rendered-doc.lsp + rm -rf doc/HTML-old doc/EMACS-old doc/acl2-wc.txt books/std/io/test.sao + rm -f books/centaur/bitops/bitsets-opt-raw.o books/centaur/vl/util/gc-raw.o \ + books/centaur/misc/tshell-raw.o books/centaur/vl/Makefile-tmp \ + books/build/Makefile-sources books/build/Makefile-certs + rm -f debian/acl2-books-certs.lintian-overrides + dh_clean -XTAGS + +debian/acl2-infix.install:: + find books/interface/infix -name "*.o" | awk '{a=$$1;sub("/[^/]*$$","",a);printf("%s usr/lib/$(PD)/%s\n",$$1,a);}' >>$@ + find books/interface/infix -name "*.sty" | \ + awk '{a=$$1;sub("/[^/]*$$","",a);printf("%s usr/share/texmf/tex/latex\n",$$1);}' >>$@ + +debian/acl2-infix-source.install:: + find books/interface/infix -name "*.lisp" | awk '{a=$$1;sub("/[^/]*$$","",a);printf("%s usr/lib/$(PD)/%s\n",$$1,a);}' >>$@ + +debian/acl2-emacs.install:: + find books/interface/emacs -name "*.el" | awk '{printf("%s usr/share/emacs/site-lisp/$(PN)\n",$$1);}' >>$@ + find emacs -name "*.el" | awk '{printf("%s usr/share/emacs/site-lisp/$(PN)\n",$$1);}' >>$@ + +debian/acl2.install:: + echo debian/acl2.sh usr/bin >>$@ + echo saved_acl2 usr/lib/$(PD) >>$@ + +debian/acl2-books.install:: + find books -name "*.o" | grep -v interface/ | awk '{a=$$1;sub("/[^/]*$$","",a);printf("%s usr/lib/$(PD)/%s\n",$$1,a);}' >>$@ + +debian/acl2-source.install:: + find * -name "*.lisp" -maxdepth 0 | grep -v TMP1.lisp | awk '{printf("%s usr/share/$(PD)\n",$$1);}' >$@ + find * -name "TAGS" -maxdepth 0 | awk '{printf("%s usr/share/$(PD)\n",$$1);}' >>$@ + +debian/acl2-books-certs.install:: + find books -name "*.cert" | grep -v fix-cert/moved | grep -v system/pcert | \ + awk '{a=$$1;sub("/[^/]*$$","",a);printf("%s usr/share/$(PD)/%s\n",$$1,a);}' >>$@ + find books -name "*.pcert0.final" | \ + awk '{a=$$1;sub(".pcert0.final",".cert",a);printf("%s usr/share/$(PD)/%s\n",$$1,a);}' >>$@ + +debian/acl2-books-source.install:: + find books -name "*.lisp" | awk '{a=$$1;sub("/[^/]*$$","",a);printf("%s usr/share/$(PD)/%s\n",$$1,a);}' >>$@ + find books -name "*.acl2" | awk '{a=$$1;sub("/[^/]*$$","",a);printf("%s usr/share/$(PD)/%s\n",$$1,a);}' >>$@ + find books/bdd -name "bit-vector-reader.lsp" | awk '{a=$$1;sub("/[^/]*$$","",a);printf("%s usr/share/$(PD)/%s\n",$$1,a);}' >>$@ + +debian/acl2-doc.install:: + echo doc usr/share/doc/acl2-doc >$@ + find books -name "README*" | \ + awk '{a=$$1;sub("/[^/]*$$","",a);printf("%s usr/share/doc/$(PN)-doc/%s\n",$$1,a);}' >>$@ + find books/textbook -name "*.txt" | \ + awk '{a=$$1;sub("/[^/]*$$","",a);printf("%s usr/share/doc/$(PN)-doc/%s\n",$$1,a);}' >>$@ + find books/textbook -name "*.html" | \ + awk '{a=$$1;sub("/[^/]*$$","",a);printf("%s usr/share/doc/$(PN)-doc/%s\n",$$1,a);}' >>$@ + find books/bdd/be/ -type f | awk '{a=$$1;sub("/[^/]*$$","",a);printf("%s usr/share/doc/$(PN)-doc/%s\n",$$1,a);}' >>$@ + find books/misc -name "simplify-defuns.txt" | \ + awk '{a=$$1;sub("/[^/]*$$","",a);printf("%s usr/share/doc/$(PN)-doc/%s\n",$$1,a);}' >>$@ + find books/interface/infix -name "README*" | \ + awk '{a=$$1;sub("/[^/]*$$","",a);printf("%s usr/share/doc/$(PN)-doc/%s\n",$$1,a);}' >>$@ + find books/interface/infix -name "*.ps" | \ + awk '{a=$$1;sub("/[^/]*$$","",a);printf("%s usr/share/doc/$(PN)-doc/%s\n",$$1,a);}' >>$@ + find books/interface/infix -name "*.dvi" | \ + awk '{a=$$1;sub("/[^/]*$$","",a);printf("%s usr/share/doc/$(PN)-doc/%s\n",$$1,a);}' >>$@ + find books/interface/emacs -name "README*" | \ + awk '{a=$$1;sub("/[^/]*$$","",a);printf("%s usr/share/doc/$(PN)-doc/%s\n",$$1,a);}' >>$@ + find books/arithmetic-2/pass1/arithmetic-axioms.txt | \ + awk '{a=$$1;sub("/[^/]*$$","",a);printf("%s usr/share/doc/$(PN)-doc/%s\n",$$1,a);}' >>$@ + +debian/acl2.links:: + echo usr/lib/$(PD)/saved_acl2 usr/share/$(PD)/saved_acl2 >$@ + +debian/acl2-books.links:: + find books -name "*.o" | grep -v interface/ | awk '{printf("usr/lib/$(PD)/%s usr/share/$(PD)/%s\n",$$1,$$1);}' >>$@ + +debian/acl2-infix.links:: + find books/interface/infix -name "*.o" | awk '{printf("usr/lib/$(PD)/%s usr/share/$(PD)/%s\n",$$1,$$1);}' >>$@ + +debian/acl2.sh: + echo "#!/bin/bash" >$@ + echo >>$@ + echo "export ACL2_SYSTEM_BOOKS=/usr/share/$(PD)/books" >>$@ + echo "exec /usr/lib/$(PD)/saved_acl2 -dir /usr/share/$(PD)" >>$@ + chmod 755 $@ + +debian/acl2-books-certs.lintian-overrides: debian/acl2-books-certs.lintian-overrides.in + cat $< | sed "s,@PD@,$(PD),g" > $@ + +install: DH_OPTIONS= +install: build $(INSTALLS) $(LINKS) debian/acl2.sh debian/acl2-emacs.emacsen-startup debian/README.Debian debian/acl2-books-certs.lintian-overrides + dh_testdir + dh_testroot + dh_prep -XTAGS + dh_installdirs + + dh_install + + rm -f debian/acl2-doc/usr/share/doc/acl2-doc/doc/manual/LICENSE + rm -f debian/acl2-doc/usr/share/doc/acl2-doc/doc/.gitignore + + find debian/acl2-books-source/usr/share/$(PD)/books/centaur/quicklisp/bundle/software/ -type f -name release.lisp -exec rm {} \; + + for i in $$(find debian -name "*.final"); do mv $$i $${i%.final} ; done + find debian/acl2-source -name "*.lisp" -type f -exec chmod 444 {} \; + find debian/acl2-source -name "*.acl2" -type f -exec chmod 444 {} \; + find debian/acl2-source -name "*.lsp" -type f -exec chmod 444 {} \; + find debian/acl2-books-source -name "*.lisp" -type f -exec chmod 444 {} \; + find debian/acl2-books-source -name "*.acl2" -type f -exec chmod 444 {} \; + find debian/acl2-books-source -name "*.lsp" -type f -exec chmod 444 {} \; + + mv debian/acl2/usr/bin/acl2.sh debian/acl2/usr/bin/acl2 + +binary-indep: DH_OPTIONS:=-i +binary-indep: build install + dh_testdir + dh_testroot + dh_installdocs + dh_installexamples + dh_installmenu + dh_installemacsen + dh_installtex -p acl2-infix + dh_installcron + DH_OPTIONS= dh_installinfo -p acl2-doc #$$(find doc/EMACS -name "*.info*") + dh_installchangelogs + dh_link + dh_compress + dh_lintian + dh_fixperms + dh_installdeb + dh_gencontrol + dh_md5sums + dh_builddeb + +binary-arch: DH_OPTIONS=-a +binary-arch: build install + dh_testdir + dh_testroot + dh_installdocs + dh_installexamples + dh_installmenu + dh_installemacsen + dh_installcron + dh_installman + dh_installinfo + dh_installchangelogs + dh_strip $(NO_STRIP) + dh_link + dh_compress + dh_fixperms + dh_installdeb + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build build-arch build-indep clean binary-indep binary-arch binary install + diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 0000000..163aaf8 --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/debian/sublis_patch.lsp b/debian/sublis_patch.lsp new file mode 100644 index 0000000..6fd25c2 --- /dev/null +++ b/debian/sublis_patch.lsp @@ -0,0 +1,9 @@ +(in-package 'compiler) +(defun sublis1-inline (a b c) + (let ((tst (or (car (find (cadr c) *objects* :key 'cadr)) + (let ((v (member (cadr c) *top-level-forms* :key 'cadr))) + (and v + (eq (caar v) 'sharp-comma) + (cmp-eval (caddar v))))))) + (or (member tst '(eq equal eql)) (error "bad test")) + (wt "(check_alist(" a "),sublis1("a "," b "," (format nil "~(&~a~)))" tst)))) diff --git a/debian/watch b/debian/watch new file mode 100644 index 0000000..b9bee31 --- /dev/null +++ b/debian/watch @@ -0,0 +1,10 @@ +version=2 +# Example watch control file for uscan +# Rename this file to "watch" and then you can run the "uscan" command +# to check for upstream updates and more. +# Site Directory Pattern Version Script +#opts=pasv ftp://ftp.cs.utexas.edu/pub/moore/acl2/ acl2-([0-9.]*)\.tar\.gz debian uupdate +#opts=filenamemangle=s/.+\/v?(\d\S*)\.tar\.gz/acl2-$1\.tar\.gz/ \ +# https://github.com/acl2-devel/acl2-devel/tags .*/v?(\d\S*)\.tar\.gz +opts=dversionmangle=s/dfsg\d*$// https://github.com/acl2-devel/acl2-devel/releases .*/acl2-v?(\d\S*)\.tar\.gz + |