wiki/dexp.lisp
The current package as a plain uppercase name, for operator lookups.
Symbol names of the lambda list of the form whose docstring is being rendered; an uppercase word naming one is a parameter reference.
Layouts
A list is drawn according to a layout object. The layout is chosen by
the list's operator and by the role its parent gave it: a LET chooses a
bindings-layout for itself, and the child it marks as \"bindings\" is
drawn by a grid-layout no matter what its first element is. Each layout
answers child-role for the children and render-layout for the whole;
the stylesheet only knows the roles.
How the children of a list are arranged.
The default: children flow and wrap; the first symbol is the operator.
How many arguments after the operator are the head; the rest are body forms that take the full width.
Head arguments inline, then body forms stacked.
The index of the argument that is a list of bindings, drawn as a two-column grid.
A binding form: LET, FLET, DEFCLASS, DO.
MULTIPLE-VALUE-BIND and friends: the first argument is a list of variables drawn like a lambda list.
DOLIST, WITH-OPEN-FILE: the first argument is one (var form ...) clause, not a list of bindings.
A defining or lambda form whose head ends with a lambda list: the lambda list's sublists are (var default) clauses.
DEFMETHOD: the head runs through qualifiers to the lambda list.
How many leading elements of each clause are its key: one for COND and CASE, two for HANDLER-CASE, whose clauses name a type and then a lambda list.
COND, CASE, HANDLER-CASE: body forms are clauses whose first element is a key or test, not an operator, and whose rest stacks; drawn as a table of key and rest.
A list of bindings or slots: each element a clause, aligned in two columns, name and rest.
A binding or slot: a name and the rest, no operator.
The index of a lambda list among the head elements, as in a HANDLER-CASE clause, or NIL.
A COND-style clause: a key or test, then body forms stacked.
A lambda list: parameters flow; (var default) sublists are clauses, not calls.
LOOP: its clause keywords start new rows.
SETF, SETQ, PSETF: the arguments are place value pairs; with more than one pair each is a row of a two-column table.
Give each operator in names (strings) a fresh class layout.
The layout for operator name of list, from the table or, for operators
that only follow a naming convention, by inspecting the form: a WITH- form
has one head argument; a DEF form whose second argument is a list is a
lambda form; any other DEF form is a name followed by options.
The layout for list given the role its parent assigned.
The children of list that count as arguments: everything but comments.
The role string for child, the INDEXth argument of list
under layout (comments are not counted and never asked), or NIL.
Qualifiers precede the lambda list; the first list after the name is it.
Values are body forms when there is more than one pair, so the pairs stack as rows; a single pair stays inline.
Layouts derived from real lambda lists (see introspect.lisp)
(PACKAGE . NAME) -> facts plist gathered by scripts/wiki introspect, and NAME -> facts for lookup without a package.
Read the operator facts written by write-arglists into *ARGLISTS*.
The introspected facts for operator name in package (a name or NIL).
Alist of (argument-index . role) from the lambda list: a destructuring pattern is a clause, a parameter named BINDINGS or SLOTS a binding grid, one named LAMBDA-LIST a lambda list.
A layout computed from an operator's real lambda list.
The role a parameter's name or shape suggests for the argument in its position: a destructuring pattern is a clause; a name that says BINDINGS or SLOTS is a binding grid; LAMBDA-LIST is a lambda list.
Derive a layout from facts, walking the lambda list at its base level.
Anything after &rest/&body except &key does not count.
The keyword options of a defining macro stack as rows.
The argument index where key value pairs begin under
layout, or NIL; the default guesses a trailing run of :keyword value
pairs from the arguments themselves.
The lambda list of list under layout, if the layout has one.
True when child is a string in documentation position: the first body
form of a defining form, or the value after :documentation.
Emit the children of list arranged by layout, inside the
list's own box, which the caller has opened.
The index in arguments from which the rest is :keyword value pairs, or NIL.
The tail must have even length and a keyword at every even offset; the
earliest such start after the operator wins.
Drawing
The children of a list are first grouped into ITEMs -- a comment, one
child with its role, or a :keyword value pair -- and then drawn. A list
with body items is stacked: its head items go in a .head row and each
body item is a row of its own, so the box is a grid of rows and hugs its
widest row instead of stretching to the parent (#993QQQ).
One drawn unit of a list: KIND is :comment, :child, or :pair. ROLE is
the role the layout gave it (a pair takes its value's role); node the
child or the key; VALUE and COMMENTS the pair's value and the comments
between key and value; INDEX and PREVIOUS the argument index and previous
argument, for docstring position.
The children of list grouped for drawing under layout. Comments are
kept where they occur and are not counted. A trailing run of :keyword
value pairs is grouped pair by pair, keeping the key with its value.
A key: group it with its value.
Draw item of list under layout.
items before the first body item as the head, and the rest as rows;
comments just before the first body item are rows, not head.
Emit every child of list with the role layout assigns it. When some
child is a body form the list is stacked: the head children go in a .head
span and every body form is a row.
Extra CSS classes for the box of list under layout.
A clause: its first element in the name column, the rest in one flowing cell, so the parent's grid can align them.
A COND-style clause, one row of its parent's clause table (#4175NC): the key or test in a .head cell, then the body forms stacked in a .rest cell.
Write text, turning #ID figure mentions into links like prose does.
True when the first symbol of a list under layout names
an operator, worth a data-callee attribute; false for clauses, binding
grids, and lambda lists, whose first element is data.
The package prefix, if shown, and the name of symbol.
An uppercase word in code prose that names a symbol: a parameter of the enclosing form or a definition in the corpus.
True when word is written the way docstrings write symbols: at least two
characters, all uppercase letters, digits, or symbol punctuation, with at
least one letter.
An uppercase word is a symbol reference when it names a parameter of the
enclosing form, a definition in the corpus, or is a *special* name.
Split the strings among inlines so that symbol words become
symbol-reference objects.
Drawn like a symbol in the boxes: lowercase code, linked to its definition when the corpus has one.
Turn symbol words in the paragraphs of element into references.
Render text, the content of a docstring or comment, as wiki prose:
paragraphs, lists, and inline markup, with #ID mentions as links and
uppercase symbol words as symbol references.
The parameter names in the lambda list list (a lisp-list), including
those inside specializer or default forms and skipping &keywords.
The characters of a string literal string, without the quotes and with
\" and \\ escapes undone.
Remove the indentation common to every non-blank line after the first.
Documentation, or any multi-line string, is rendered as prose.
The text of comment without its ; prefixes or #| |# delimiters.
The skipped branch is shown as its text.
Emit a .lisp container holding nodes rendered as dexp boxes.
Read text and render it structurally; on any failure fall back to a
plain <pre>, so a page never loses its code.
The layout role of the node being rendered: "operator", "body", or NIL.
The package prefix considered current while rendering, hidden on symbols.
Logical conjunction of tests and raw truth values.
True while rendering a string in documentation position.
Symbol names of the lambda list of the form whose docstring is being rendered; an uppercase word naming one is a parameter reference.
How the children of a list are arranged.
A binding form: LET, FLET, DEFCLASS, DO.
A list of bindings or slots: each element a clause, aligned in two columns, name and rest.
(parent child-index)(layout list)Emit the children of LIST arranged by LAYOUT, inside the list's own box, which the caller has opened.
The default: children flow and wrap; the first symbol is the operator.
Head arguments inline, then body forms stacked.
MULTIPLE-VALUE-BIND and friends: the first argument is a list of variables drawn like a lambda list.
DOLIST, WITH-OPEN-FILE: the first argument is one (var form ...) clause, not a list of bindings.
A defining or lambda form whose head ends with a lambda list: the lambda list's sublists are (var default) clauses.
DEFMETHOD: the head runs through qualifiers to the lambda list.
COND, CASE, HANDLER-CASE: body forms are clauses whose first element is a key or test, not an operator, and whose rest stacks; drawn as a table of key and rest.
A binding or slot: a name and the rest, no operator.
A COND-style clause: a key or test, then body forms stacked.
A lambda list: parameters flow; (var default) sublists are clauses, not calls.
LOOP: its clause keywords start new rows.
SETF, SETQ, PSETF: the arguments are place value pairs; with more than one pair each is a row of a two-column table.
(names class &rest initargs)(name list)The layout for operator NAME of LIST, from the table or, for operators that only follow a naming convention, by inspecting the form: a WITH- form has one head argument; a DEF form whose second argument is a list is a lambda form; any other DEF form is a name followed by options.
(list)(name package)Logical disjunction of tests and raw truth values.
A symbol token; nothing is interned.
(facts &optional name)(prefix string &key (start 0))A parenthesized list; CHILDREN are nodes in order.
(role name)(node)A ; or #| |# comment, TEXT included.
Test whether two compatible scalars are equal.
Test whether one compatible scalar is greater than another.
Test whether one compatible scalar is at most another.
Test whether one compatible scalar is at least another.
(PACKAGE . NAME) -> facts plist gathered by scripts/wiki introspect, and NAME -> facts for lookup without a package.
(pathname)(source-files pathname)A layout computed from an operator's real lambda list.
(parameter)The role a parameter's name or shape suggests for the argument in its position: a destructuring pattern is a clause; a name that says BINDINGS or SLOTS is a binding grid; LAMBDA-LIST is a lambda list.
Logical negation of one test or raw truth value.
Test whether one compatible scalar is less than another.
(layout arguments)The argument index where key value pairs begin under LAYOUT, or NIL; the default guesses a trailing run of :keyword value pairs from the arguments themselves.
(arguments)The index in ARGUMENTS from which the rest is :keyword value pairs, or NIL. The tail must have even length and a keyword at every even offset; the earliest such start after the operator wins.
(layout list)The minimum of compatible quantities.
(layout list index previous child)True when CHILD is a string in documentation position: the first body form of a defining form, or the value after :documentation.
(node)Anything in a stylesheet: a declaration, rule, at-rule, or style group.
Subtraction or unary negation.
A list with body forms is a grid of rows: the .head row, then one row per body form, so the box hugs its widest row instead of stretching to its parent (#993QQQ).
(item)(layout list)The children of LIST grouped for drawing under LAYOUT. Comments are kept where they occur and are not counted. A trailing run of :keyword value pairs is grouped pair by pair, keeping the key with its value.
(layout list item)(element)Emit Spinneret markup for ELEMENT into SPINNERET:*HTML*. Strings are plain text; each element and inline class contributes its own method.
(&rest classes)(items)ITEMS before the first body item as the head, and the rest as rows; comments just before the first body item are rows, not head.
(layout list)Emit every child of LIST with the role LAYOUT assigns it. When some child is a body form the list is stacked: the head children go in a .head span and every body form is a row.
(string start)If a #ID mention (six capitals or digits, not all of them hex digits) begins at START, return the index after it.
A light #ID reference to a figure: a hash and six capitals or digits.
(layout)True when the first symbol of a list under LAYOUT names an operator, worth a data-callee attribute; false for clauses, binding grids, and lambda lists, whose first element is data.
(list)The parameter names in the lambda list LIST (a lisp-list), including those inside specializer or default forms and skipping &keywords.
A #( ) vector literal.
One top-level defining form of a source file.
(name &optional (site *site*))The best definition for the bare symbol NAME: a defining form of the generic, function, macro, or class before any method, else the first.
(definition &optional (site *site*))The href of DEFINITION's line in its source page, or NIL when the site has no page for its file.
(definition)(symbol package current-p keyword-p)Any other atom, kept as its source text: numbers, strings, characters, pathnames, and reader-macro results we do not model.
An uppercase word in code prose that names a symbol: a parameter of the enclosing form or a definition in the corpus.
(word)True when WORD is written the way docstrings write symbols: at least two characters, all uppercase letters, digits, or symbol punctuation, with at least one letter.
(word)An uppercase WORD is a symbol reference when it names a parameter of the enclosing form, a definition in the corpus, or is a *special* name.
(name)(inlines)Split the strings among INLINES so that symbol words become SYMBOL-REFERENCE objects.
(string)Emphasized text; VERBATIM and CODE hold one string child.
An Org bracket link.
(element)A block-level piece of an Org document.
(function element)A run of prose; CHILDREN are inline objects.
(text)Render TEXT, the content of a docstring or comment, as wiki prose: paragraphs, lists, and inline markup, with #ID mentions as links and uppercase symbol words as symbol references.
True while reading docstrings and comments as prose: there *name* without spaces is a Lisp special variable and reads as code, not bold.
(lines)(string)The characters of a string literal STRING, without the quotes and with \" and \\ escapes undone.
(text)(line)(line)(comment)The maximum of compatible quantities.
(suffix string)A quote-like prefix applied to one form.
A #+ or #- guarded form.
Input the reader skipped for another reason.
(nodes &key package)(text &key package)Read TEXT and render it structurally; on any failure fall back to a plain <pre>, so a page never loses its code.
(text &key (name "string"))Read TEXT into a list of top-level LISP-NODEs, comments included, in order. Reader errors are recovered from where Eclector offers a restart and otherwise end the read; NAME labels warnings.
Intent. In the rendered source pages a nested body form stretches to its parent's full width (.body is flex-basis: 100%), and worse, a wrapping flex box's intrinsic width is the single-line sum of its children, so even an argument box like a multi-line (lambda …) comes out far wider than its tallest row. Closing…
Intent. A cond clause today stacks its test and its result as two identical rows, so (null vectors) and (find-shader-type :float) look like siblings and the reader cannot tell test from consequent. What the let grid did for bindings (#BGIM3I) should be done for clauses: a two-column table, key or test in the first…
Rendering Lisp source as dexp boxes.
After wisp's structure editor: every list is a flex-wrapping box whose left and right borders are its parentheses; atoms are inline spans. Forms flow horizontally while they fit and wrap when they do not, so the layout is responsive without any line-breaking logic. The only structural knowledge is a small table of operator roles: which leading children are the head and which are body forms that should take the full width and stack. Roles are assigned here, in Lisp; the stylesheet needs only `.lisp .body { flex-basis: 100% }`.