|
Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
;; This file:
;; http://anggtwu.net/lisptree/lisptree-middle.lisp.html
;; http://anggtwu.net/lisptree/lisptree-middle.lisp
;; (find-lisptree "lisptree-middle.lisp")
;; See: http://anggtwu.net/lisptree.html
;; https://github.com/edrx/lisptree
;; Author: Eduardo Ochs <eduardoochs@gmail.com>
;; License: Public Domain.
;; Version: 2025dec14.
;;
;; MANY COMMENTS IN THIS FILE ARE OUTDATED! This used to have lots of
;; functions with cryptic names, now I reduced that to just a few... =/
;;
;; This is the middle-level part of Lisptree. The main top-level
;; function in this file is `tolisptree2d', that works like this:
;;
;; tolisptree2d ([f,2,[g,3,4]]);
;;
;; $F__.
;; | |
;; ==> 2 $G__.
;; | |
;; 3 4
;;
;; tolisptree2d ([f, 4, "5", [g, foo, ?foo, Foo]]);
;;
;; $F__.__.
;; | | |
;; ==> 4 5 $G____.____.
;; | | |
;; $FOO FOO |$Foo|
;;
;; `tolisptree2d' receives a Maxima object that "represents a tree"
;; and returns a string with newlines that is that Maxima object
;; "drawn as a tree".
;;
;; Note that `tolisptree2d'
;; receives this: [f,2,[g,3,4]]
;; and NOT this: f(2,g(3,4))
;; That's because this conversion
;; f(2,g(3,4))
;; -> [f,2,[g,3,4]]
;; is very tricky...
;; See: (find-lisptree "lisptree.mac")
;; This file, lisptree-middle.lisp, is the middle part of LispTree -
;; it implements some Lisp functions callable from Maxima that access
;; functions defined in lisptree.lisp.
;;
;; Links:
;; The middle part of lisptree is this file.
;; The outer part of lisptree is: (find-lisptree "lisptree.mac")
;; The inner part of lisptree is: (find-lisptree "lisptree.lisp")
;;
;; A "Maxima object" is something like f(2,g(3,4)).
;; A "Maxima tree" is something like [f,2,[g,3,4]].
;; A "Lispy tree " is something like ($F 2 ($G 3 4)).
;; A "2D tree" is something like this,
;;
;; f__.
;; | |
;; 2 g__.
;; | |
;; 3 4
;;
;; as a string with newlines.
;; Here is a map of the conversions:
;;
;; Maxima object --> Maxima tree --> Lispy tree --> 2D tree
;;
;; Here - in lisptree-middle.lisp - we do these ones:
;;
;; tolispytree: Maxima tree --> Lispy tree
;; $tolispytreestr: Maxima tree --> Lispy tree --> string
;; $tolispytree2d_: Maxima tree --> Lispy tree --> 2D tree
;; $tolispytree2d: Maxima tree --> Lispy tree --> 2D tree (with newline)
;; «.package» (to "package")
;; «.barematrix» (to "barematrix")
;; «.verbatimbox-mini» (to "verbatimbox-mini")
;; «.verbatimmatrix» (to "verbatimmatrix")
;; «.verbatimbox-tests» (to "verbatimbox-tests")
;; «.verbatimmatrix-tests» (to "verbatimmatrix-tests")
;; «.maximatree» (to "maximatree")
;; «.maximatree-tests» (to "maximatree-tests")
;; «.OLD» (to "OLD")
;; «.tolispytree» (to "tolispytree")
;; «.tolispytree-tests» (to "tolispytree-tests")
;; «.maxima» (to "maxima")
;; «.maxima-tests» (to "maxima-tests")
;; «package» (to ".package")
;; The functions in this file are put in the package `:maxima'.
;; The functions in lisptree.lisp are put in the package `:lisptree'.
;; See: (find-lisptree "lisptree.lisp" "package")
(in-package :maxima)
;; «barematrix» (to ".barematrix")
;; Copied from: (find-angg "MAXIMA/2025-displa-tex.lisp" "barematrix")
;; but without comments and without tex.
(setf (get '$barematrix 'dimension) 'dim-$barematrix)
(setf (get '$barematrixnp 'dimension) 'dim-$barematrixnp)
(defun dim-$barematrix (form result)
(let (($display_matrix_brackets nil))
(dim-$matrix form result)))
(defun dim-$barematrixnp (form result)
(let (($display_matrix_brackets nil)
($display_matrix_padding_vertical nil)
($display_matrix_padding_horizontal nil))
(dim-$matrix form result)))
;; «verbatimbox-mini» (to ".verbatimbox-mini")
;; Copied from edrxbox-examples.lisp, but with most comments removed.
;; See: (find-lisptree "edrxbox.lisp")
;; (find-angg "MAXIMA/edrxbox.lisp")
;; (find-angg "MAXIMA/edrxbox-examples.lisp" "verbatimbox")
;; https://anggtwu.net/maxima-edrxbox.html#verbatimbox
(setf (get '$verbatimbox 'dimension)
'dim-$verbatimbox)
(defun verbatimbox-core (strings)
(let* ((nstrings (length strings)))
(loop for string in strings
for k from 0 to (- nstrings 1)
do (edrxboxvars-push-x-y-string 0 (- k) string))
(edrxboxvars-push-x-y-end)))
(defun verbatimbox-edrxbox (strings)
(run-in-edrxbox
(verbatimbox-core strings)))
(defun verbatimbox-edrxbox-centered (strings)
(edrxbox-vcenter
(verbatimbox-edrxbox strings)))
(defun dim-$verbatimbox (form result)
(let* ((strings (rest form)))
(run-in-edrxbox-dim
(edrxboxvars-from-edrxbox
(verbatimbox-edrxbox-centered strings)))))
;; «verbatimmatrix» (to ".verbatimmatrix")
;; Based on: (find-angg "MAXIMA/2025-displa-tex.lisp" "verbatimmatrix")
;; Used by: (find-lisptree "lisptree.mac" "lisptree_matrix")
;; Look:
;;
;; (%i2) o1 : matrix (["f__."], ["| |"], ["a b"])$
;; (%i3) o2 : barematrix (["f__."], ["| |"], ["a b"])$
;; (%i4) o3 : barematrixnp (["f__."], ["| |"], ["a b"])$
;; (%i5) o4 : verbatimbox ( "f__.", "| |", "a b" )$
;; (%i6) o5 : verbatimmatrix(["f__."], ["| |"], ["a b"])$
;; (%i7) [o1, o2, o3, o4, o5];
;; ┌ ┐
;; │ f__. │ f__.
;; │ │ f__. f__. f__.
;; (%o7) [│ | | │, | | , | |, | |, | |]
;; │ │ a b a b a b
;; │ a b │ a b
;; └ ┘
;;
;; or, in older versions of Maxima:
;;
;; (%i7) [o1, o2, o3, o4, o5];
;; [ f__. ] [ f__. ] [ f__. ]
;; [ ] [ ] [ ] f__. f__.
;; (%o7) [[ | | ], [ | | ], [ | | ], | |, | |]
;; [ ] [ ] [ ] a b a b
;; [ a b ] [ a b ] [ a b ]
;;
;; The simplest way to display a lisptree is with a `matrix' of
;; strings - the o1 above. We can use a `barematrix' to get rid of the
;; outer brackets - the o2 above - but `barematrix'es have interline
;; spacings/paddings, that are ugly; if we replace `barematrix' by
;; `barematrixnp' we get a `barematrix' with no padding, that looks
;; great... but that only appears different from a normal `matrix' in
;; recent versions of Maxima.
;;
;; The objects o4 and o5 above use `verbatimbox' and `verbatimmatrix',
;; that work well on old versions of Maxima, so in most cases I prefer
;; to display lisptrees by using a `verbatimmatrix' instead of a
;; `matrix' or a `barematrixnp'. See:
;;
;; https://anggtwu.net/maxima-edrxbox.html
(defun dim-$verbatimmatrix (form result)
(let* ((lines (rest form))
(strings (map 'list #'second lines))
(verbatimbox `(($verbatimbox) ,@strings)))
(dim-$verbatimbox verbatimbox result)))
(setf (get '$verbatimmatrix 'dimension)
'dim-$verbatimmatrix)
#|
** «verbatimbox-tests» (to ".verbatimbox-tests")
** «verbatimmatrix-tests» (to ".verbatimmatrix-tests")
* (eepitch-maxima)
* (eepitch-kill)
* (eepitch-maxima)
load("edrxbox.lisp");
load("lisptree.lisp");
load("lisptree-middle.lisp");
o1 : matrix (["f__."], ["| |"], ["a b"]);
o2 : barematrix (["f__."], ["| |"], ["a b"]);
o3 : barematrixnp (["f__."], ["| |"], ["a b"]);
o4 : verbatimbox ( "f__.", "| |", "a b" );
o5 : verbatimmatrix(["f__."], ["| |"], ["a b"]);
[o1, o2, o3, o4, o5];
[box(o1), box(o2), box(o3), box(o4), box(o5)];
** (find-lisptree "lisptree.mac")
load ("lisptree.mac");
lisptree_matrix : 'matrix$ lisptree2(f(a,g(b,c)));
lisptree_matrix : 'barematrix$ lisptree2(f(a,g(b,c)));
lisptree_matrix : 'barematrixnp$ lisptree2(f(a,g(b,c)));
lisptree_matrix : 'verbatimmatrix$ lisptree2(f(a,g(b,c)));
|#
;; «maximatree» (to ".maximatree")
;; Functions callable from Maxima that convert "Maxima trees", like
;; [f,a,[g,b,c]], to several 2D representations, that look like:
;;
;; f__.
;; | |
;; a g__.
;; | |
;; b c
;;
(defun $maximatree_to_lisptree_string (mt)
"Convert a Maxima tree `mt' to a Lispy tree and then to a string.
The resulting string looks like \"($F $A ($G $B $C))\".
This is only useful for debugging."
(format nil "~S" (lisptree::convert mt :mt->lt t)))
(defun $maximatree_to_bigstr_ (mt)
"Convert a Maxima tree `mt' to a bigstring without an initial newline."
(lisptree::convert mt :mt->lt t
:lt->strings t
:concat lisptree::newline))
(defun $maximatree_to_bigstr (mt)
"This is like `$maximatree_to_bigstr_', but adds an initial newline."
(format nil "~%~a" ($maximatree_to_bigstr_ mt)))
(defun $maximatree_to_padded_strings (mt)
"See `$maximatree_to_matrix' and `$maximatree_to_barematrix'."
(cons '(mlist simp)
(lisptree::convert mt :mt->lt t
:lt->strings t
:pad #\ )))
(defun $maximatree_to_matrix (mt)
"Convert a Maxima tree `mt' to a matrix in which each line is a string."
(cons '($matrix simp)
(loop for string in (cdr ($maximatree_to_padded_strings mt))
collect `((mlist simp) ,string))))
#|
** «maximatree-tests» (to ".maximatree-tests")
* (eepitch-maxima)
* (eepitch-kill)
* (eepitch-maxima)
load("lisptree.lisp");
load("lisptree-middle.lisp");
maximatree_to_lisptree_string([f,a,[g,b,c]]);
maximatree_to_bigstr ([f,a,[g,b,c]]);
maximatree_to_matrix ([f,a,[g,b,c]]);
"Functions with ugly outputs:"$
maximatree_to_bigstr_ ([f,a,[g,b,c]]);
maximatree_to_padded_strings ([f,a,[g,b,c]]);
|#
;; «OLD» (to ".OLD")
;; «tolispytree» (to ".tolispytree")
(defun tolispytree (o)
"This function converts a Maxima tree `o' to a Lispy tree.
For example, (tolispytree #$[f, 2,[g, 3, 4]]$)
returns: ($F 2 ($G 3 4))"
(if (and (listp o) (eq (caar o) 'mlist))
(map 'list #'tolispytree (cdr o))
o))
(defun $tolispytreestr (o)
"This function converts a Maxima tree `o' to a lispy tree converted to a string.
For example, tolispytreestr([f,2,[g,3,4]])
returns \"($F 2 ($G 3 4))\".
This is mainly for debugging."
(format nil "~S" (tolispytree o)))
#|
** «tolispytree-tests» (to ".tolispytree-tests")
* (eepitch-maxima)
* (eepitch-kill)
* (eepitch-maxima)
load("lisptree.lisp");
load("lisptree-middle.lisp");
to_lisp();
#$[f,2,[g,3,4]]$ ;-> ((MLIST SIMP) $F 2 ((MLIST SIMP) $G 3 4))
(tolispytree #$[f,2,[g,3,4]]$) ;-> ($F 2 ($G 3 4))
(to-maxima)
tolispytreestr ([f,2,[g,3,4]]);
stringdisp : true;
tolispytreestr ([f,2,[g,3,4]]);
|#
;; «maxima» (to ".maxima")
;; Functions callable from Maxima.
;;
(defun $tolisptree2d_ (o)
"This function converts a Maxima tree `o' to a 2D tree.
For example, tolispytreestr([f,2,[g,3,4]])
returns (roughly) this:
\"$F__.
| |
2 $G__.
| |
3 4\""
(lisptree::toplain-lines (lisptree::lispytree (tolispytree o))))
(defun $tolisptree2d (o)
"This is like `$tolisptree2d_', but adds an initial newline."
(format nil "~%~a" ($tolisptree2d_ o)))
#|
** «maxima-tests» (to ".maxima-tests")
* (eepitch-maxima)
* (eepitch-kill)
* (eepitch-maxima)
load("lisptree.lisp");
load("lisptree-middle.lisp");
tolispytreestr([f,2,[g,3,4]]);
tolisptree2d_ ([f,2,[g,3,4]]);
tolisptree2d ([f,2,[g,3,4]]);
tolispytreestr([f, 4, "5", [g, foo, ?foo, Foo]]);
tolisptree2d ([f, 4, "5", [g, foo, ?foo, Foo]]);
|#
;; Local Variables:
;; coding: utf-8-unix
;; End: