-
-
Notifications
You must be signed in to change notification settings - Fork 21
/
documentation.lisp
629 lines (449 loc) · 19.6 KB
/
documentation.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
(in-package #:org.shirakumo.plump.dom)
;; dom.lisp
(docs:define-docs
(type node
"Base DOM node class.")
(type nesting-node
"Node class that can contain child nodes.")
(function children
"Returns a vector of child-nodes that are contained within the node.")
(type child-node
"Node class that is a child and thus has a parent.")
(function parent
"Returns the node's parent that should contain this element as a child.")
(type textual-node
"Node class that represents a textual node and thus contains a TEXT field.")
(function text
"Returns the node's textual content.")
(type root
"Root DOM node, practically equivalent to a \"document\".")
(type text-node
"Text node that can only contain a single text string.")
(type comment
"Comment node that can only contain a single comment string.")
(type element
"Standard DOM element/block including attributes, tag-name, parent and children.")
(function tag-name
"Returns the element's tag name.")
(function attributes
"Returns an EQUALP hash-table of the element's attributes.")
(type doctype
"Special DOM node for the doctype declaration.")
(function doctype
"Returns the doctype node's actual doctype string.")
(type fulltext-element
"Special DOM element that contains full, un-entitied text like SCRIPT and STYLE.")
(type xml-header
"XML header element")
(type cdata
"XML CDATA section node.")
(type processing-instruction
"XML processing instruction node.")
(function make-child-array
"Creates an array to contain child elements")
(function ensure-child-array
"If the ARRAY is suitable as a child-array, it is returned.
Otherwise the array's elements are copied over into a proper
child-array.")
(function make-attribute-map
"Creates a map to contain attributes.")
(function ensure-attribute-map
"Ensures that the TABLE is suitable as an attribute-map.
If it is not, the table is copied into a proper attribute-map.")
(function make-root
"Creates a root node with the given children.
Children should be a vector with fill-pointer.")
(function make-element
"Creates a standard DOM element with the given tag name and parent.
Optionally a vector (with fill-pointer) containing children and an
attribute-map (a hash-table with equalp test) can be supplied.
Note that the element is automatically appended to the parent's child list.")
(function make-text-node
"Creates a new text node under the parent.
Note that the node is automatically appended to the parent's child list.")
(function make-comment
"Creates a new comment node under the parent.
Note that the node is automatically appended to the parent's child list.")
(function make-doctype
"Creates a new doctype node under the parent.
Note that the node is automatically appended to the parent's child list.")
(function make-fulltext-element
"Creates a fulltext element under the parent.
Optionally a text and an attribute-map (a hash-table with equalp test)
can be supplied.
Note that the element is automatically appended to the parent's child list.")
(function make-xml-header
"Creates an XML header object under the parent.
Note that the element is automatically appended to the parent's child list.")
(function make-cdata
"Creates an XML CDATA section under the parent.
Note that the element is automatically appended to the parent's child list.")
(function make-processing-instruction
"Creates an XML processing instruction under the parent.
Note that the element is automatically appended to the parent's child list.")
(function clear
"Clears all children from the node.
Note that the PARENT of all child elements is set to NIL.")
(function siblings
"Returns the array of siblings of the given child.
Note that this is a copy of the array, modifying it is safe.")
(function family
"Returns the direct array of children of the parent of the given child.
Note that modifying this array directly modifies that of the parent.")
(function child-position
"Returns the index of the child within its parent.")
(function append-child
"Appends the given child onto the parent's child list.
Returns the child.")
(function prepend-child
"Prepends the given child onto the parent's child list.
Returns the child.
Note that this operation is costly, see VECTOR-PUSH-EXTEND-FRONT")
(function remove-child
"Removes the child from its parent.
Returns the child.
Note that this operation is potentially very costly.
See VECTOR-POP-POSITION")
(function replace-child
"Replace the old child with a new one.
Returns the old child.")
(function insert-before
"Inserts the new-child before the given element in the parent's list.
Returns the new child.
Note that this operation is potentially very costly.
See VECTOR-PUSH-EXTEND-POSITION")
(function insert-after
"Inserts the new-child after the given element in the parent's list.
Returns the new child.
Note that this operation is potentially very costly.
See VECTOR-PUSH-EXTEND-POSITION")
(function splice
"Splices the contents of element into the position of the element in its parent.
Returns the parent.
Note that this operation is potentially very costly.
See ARRAY-SHIFT")
(function clone-children
"Clone the array of children.
If DEEP is non-NIL, each child is cloned as per (CLONE-NODE NODE T).
When copying deeply, you can also pass a NEW-PARENT to set on each child.")
(function clone-attributes
"Clone the attribute map.
Note that keys and values are NOT copied/cloned.")
(function clone-node
"Clone the given node, creating a new instance with the same contents.
If DEEP is non-NIL, the following applies:
The text of COMMENT and TEXT-NODEs is copied as per COPY-SEQ.
The children of NESTING-NODEs are copied as per (CLONE-CHILDREN CHILD T)")
(function first-child
"Returns the first child within the parent or NIL
if the parent is empty.")
(function last-child
"Returns the last child within the parent or NIL
if the parent is empty.")
(function previous-sibling
"Returns the sibling before this one or NIL if
it is already the first.")
(function next-sibling
"Returns the sibling next to this one or NIL if
it is already the last.")
(function child-elements
"Returns a new vector of children of the given node, filtered to elements.")
(function element-position
"Returns the index of the child within its parent, counting only elements.
This excludes comments, text-nodes and the like.")
(function sibling-elements
"Returns the array of sibling elements of the given child.
Note that this is a copy of the array, modifying it is safe.
This excludes comments, text-nodes and the like.")
(function family-elements
"Returns the direct array of children elements of the parent of the given child.
Note that this is a copy of the array, modifying it is safe.
This excludes comments, text-nodes and the like.")
(function first-element
"Returns the first child element within the parent or NIL
if the parent is empty. This excludes comments, text-nodes and the like.")
(function last-element
"Returns the last child element within the parent or NIL
if the parent is empty. This excludes comments, text-nodes and the like.")
(function previous-element
"Returns the sibling element before this one or NIL if
it is already the first. This excludes comments, text-nodes and the like.")
(function next-element
"Returns the sibling element next to this one or NIL if
it is already last. This excludes comments, text-nodes and the like.")
(function has-child-nodes
"Returns T if the node can contain children and
the child array is not empty.")
(function attribute
"Returns the asked attribute from the element
or NIL. If the attribute could not be found, the
second return value is set to NIL.")
(function (setf attribute)
"Set an attribute on an element to the given value.")
(function get-attribute
"Synonymous to ATTRIBUTE.")
(function set-attribute
"Synonymous to (SETF (ATTRIBUTE ..) ..)")
(function remove-attribute
"Remove the specified attribute if it exists.
Returns NIL.")
(function has-attribute
"Returns T if the provided attribute exists.")
(function render-text
"\"Renders\" the text of this element and its children.
In effect the text is gathered from the component and all of
its children, but transforming the text in such a way that:
- All ASCII white space (Space, Tab, CR, LF) is converted into spaces.
- There are no consecutive spaces.
- There are no spaces at the beginning or end.
This is somewhat analogous to how the text will be shown to
the user when rendered by a browser. Hence, render-text.")
(function get-elements-by-tag-name
"Searches the given node and returns an unordered
list of child nodes at arbitrary depth that match
the given tag.")
(function get-element-by-id
"Searches the given node and returns the first
node at arbitrary depth that matches the given ID
attribute.")
(variable *stream*
"The stream to serialize to during SERIALIZE-OBJECT.")
(function serialize
"Serializes NODE to STREAM.
STREAM can be a stream, T for *standard-output* or NIL to serialize to string.")
(function serialize-object
"Serialize the given node and print it to *stream*.")
(function traverse
"Traverse the NODE and all its children recursively,
calling FUNCTION on the current node if calling TEST on the current node
returns a non-NIL value. It is safe to modify the child array of the
parent of each node passed to FUNCTION.
NODE is returned.")
(function trim
"Trim all text-nodes within NODE (at any depth) of leading and trailing whitespace.")
(function strip
"Trim all text-nodes within NODE (at any depth) of leading and trailing whitespace.
If their TEXT should be an empty string after trimming, remove them."))
;; entities.lisp
(docs:define-docs
(variable *entity-map*
"String hash-table containing the entity names and mapping them to their respective characters.")
(function translate-entity
"Translates the given entity identifier (a name, #Dec or #xHex) into their respective strings if possible.
Otherwise returns NIL.")
(variable *alpha-chars*
"All alphabetic characters and #")
(function decode-entities
"Translates all entities in the text into their character counterparts if possible.
If an entity does not match, it is left in place unless REMOVE-INVALID is non-NIL.")
(function allowed-char-p
"Returns T if the character is a permitted XML character.")
(function discouraged-char-p
"Returns T if the character is a discouraged XML character.")
(type invalid-xml-character
"Error signalled when an invalid XML character is encountered during WRITE-ENCODE-CHAR.")
(type discouraged-xml-character
"Warning signalled when a discouraged XML character is encountered during WRITE-ENCODE-CHAR.")
(function write-encode-char
"Write and possibly encode the CHAR to STREAM.
This also properly handles detection of invalid or discouraged XML characters.
The following restarts are available in the case of a faulty character:
ABORT Do not output the faulty character at all.
USE-NEW-CHARACTER Output a replacement character instead.
CONTINUE Continue and output the faulty character anyway.
See INVALID-XML-CHARACTER
See DISCOURAGED-XML-CHARACTER")
(function encode-entities
"Encodes the characters < > & \" with their XML entity equivalents.
If no STREAM is given, it encodes to a new string."))
(in-package #:org.shirakumo.plump.lexer)
;; lexer.lisp
(docs:define-docs
(variable *string*
"Contains the current string to lex.")
(variable *length*
"Set to the length of the string for bounds checking.")
(variable *index*
"Set to the current reading index.")
(variable *matchers*
"Hash table containing matching rules.")
(function with-lexer-environment
"Sets up the required lexing environment for the given string.")
(function consume
"Consumes a single character if possible and returns it.
Otherwise returns NIL.")
(function advance
"Skips a character if possible.
Returns the new index or NIL.")
(function unread
"Steps back a single character if possible.
Returns the new *INDEX*.")
(function peek
"Returns the next character, if any.")
(function advance-n
"Advances by N characters if possible.
Returns the new *INDEX*.")
(function unread-n
"Steps back by N characters if possible.
Returns the new *INDEX*.")
(function consume-until
"Consumes until the provided matcher function returns positively.
Returns the substring that was consumed.")
(function matcher-character
"Creates a matcher function that attempts to match the given character.")
(function matcher-string
"Creates a matcher function that attempts to match the given string.")
(function matcher-range
"Creates a matcher that checks a range according to the next character's CHAR-CODE.")
(function matcher-find
"Creates a matcher function that returns T if the character is found in the given list.")
(function matcher-or
"Creates a matcher function that returns successfully if any of the
sub-expressions return successfully. The first match is returned, if any.")
(function matcher-and
"Creates a matcher function that returns if all of the sub-expressions
return successfully. The last match is returned, if all.")
(function matcher-not
"Creates a matcher function that inverts the result of the sub-expression.")
(function matcher-next
"Creates a matcher environment that peeks ahead one farther.")
(function matcher-prev
"Creates a matcher environment that peeks behind.")
(function matcher-any
"Shorthand for (or (is a) (is b)..)")
(function make-matcher
"Macro to create a matcher chain.")
(function define-matcher
"Associates NAME as a keyword to the matcher form. You can then use the keyword in further matcher rules."))
(in-package #:org.shirakumo.plump.parser)
;; parser.lisp
(docs:define-docs
(variable *whitespace*
"List containing all whitespace characters.")
(variable *root*
"Object containing the current node to set as parent.")
(variable *tagstack*
"")
(function skip-whitespace
"")
(function read-name
"Reads and returns a tag name.")
(function read-text
"Reads and returns a text-node.")
(function read-tag-contents
"Reads and returns all tag contents.
E.g. <foo bar baz> => bar baz")
(function read-children
"Read all children of the current *root* until the closing tag for *root* is encountered.")
(function read-attribute-value
"Reads an attribute value, either enclosed in quotation marks or until a space or tag end.")
(function read-attribute-name
"Reads an attribute name.")
(function read-attribute
"Reads an attribute and returns it as a key value cons.")
(function read-attributes
"Reads as many attributes as possible from a tag and returns them as an attribute map.")
(function read-standard-tag
"Reads an arbitrary tag and returns it.
This recurses with READ-CHILDREN.")
(function read-tag
"Attempts to read a tag and dispatches or defaults to READ-STANDARD-TAG.
Returns the completed node if one can be read.")
(function read-root
"Creates a root element and reads nodes into it.
Optionally uses the specified root to append child nodes to.
Returns the root.")
(function slurp-stream
"Quickly slurps the stream's contents into an array with fill pointer.")
(function parse
"Parses the given input into a DOM representation.
By default, methods for STRING, PATHNAME and STREAM are defined.
If supplied, the given root is used to append children to as per READ-ROOT.
Returns the root."))
;; processing.lisp
(docs:define-docs
(function processing-parser
"Return the processing-parser function for PROCESS-NAME. SETF-able.")
(function (setf processing-parser)
"Set the processing-parser function for PROCESS-NAME.")
(function remove-processing-parser
"Remove the processing-parser for PROCESS-NAME.")
(function define-processing-parser
"Defines a new processing-instruction parser.
It is invoked if a processing-instruction (<?) with PROCESS-NAME is encountered.
The lexer will be at the point straight after reading in the PROCESS-NAME.
Expected return value is a string to use as the processing-instructions' TEXT.
The closing tag (?>) should NOT be consumed by a processing-parser."))
;; special-tags.lisp
(docs:define-docs
(function starts-with
"")
(function ends-with
"")
(function define-self-closing-element
"Defines an element that does not need to be closed with /> and cannot contain child nodes.")
(function read-fulltext-element-content
"Reads the contents of a fulltext element. This slurps everything until the matching closing tag is encountered.")
(function define-fulltext-element
"Defines an element to be read as a full-text element.
This means that it cannot contain any child-nodes and everything up until its closing
tag is used as its text."))
;; tag-dispatcher.lisp
(docs:define-docs
(variable *all-tag-dispatchers*
"All defined tag dispatchers")
(variable *tag-dispatchers*
"Active tag dispatcher functions")
(variable *xml-tags*
"List of XML tag dispatchers")
(variable *html-tags*
"List of HTML tag dispatchers")
(type tag-dispatcher
"Encapsulates the processing for a given tag.
See TAG-DISPATCHER-NAME
See TAG-DISPATCHER-TEST
See TAG-DISPATCHER-PARSER
See TAG-DISPATCHER-PRINTER")
(function tag-dispatcher-name
"Returns the name of the tag dispatcher.")
(function tag-dispatcher-test
"Returns the test function of the tag dispatcher.
The function takes one argument, a string, denoting the tag name.
It returns a boolean as to whether the tag name matches.")
(function tag-dispatcher-parser
"Parses the node for the given tag.
The function takes one argument, a string, denoting the tag name.
It returns a node, or NIL, if the matching was refused for some reason.")
(function tag-dispatcher-printer
"Prints the node for the given tag.
The function takes one argument, a node, the element to print.
It returns the same node, or NIL, if the printing was refused for some reason.")
(function tag-dispatcher
"Accessor to the tag-dispatcher of the given name.")
(function remove-tag-dispatcher
"Removes the tag-dispatcher of the given name from the list.")
(function define-tag-dispatcher
"Defines a new tag dispatcher. It is invoked if TEST-FORM passes.
NAME --- Name to discern the dispatcher with.
LISTS --- Symbols of lists to which the dispatcher should be added.
TAGVAR --- Symbol bound to the tag name.
BODY --- Body forms describing the test to match the tag.")
(function define-tag-parser
"Defines the parser function for a tag dispatcher.
NAME --- The name of the tag dispatcher. If one with this name
cannot be found, an error is signalled.
TAGVAR --- Symbol bound to the tag name.
BODY --- Body forms describing the tag parsing behaviour.")
(function define-tag-printer
"Defines the printer function for a tag dispatcher.
NAME --- The name of the tag dispatcher. If one with this name
cannot be found, an error is signalled.
TAGVAR --- Symbol bound to the tag name.
BODY --- Body forms describing the printing behaviour. Write to
the stream bound to PLUMP-DOM:*STREAM*.")
(function do-tag-parsers
"Iterates over the current *TAG-DISPATCHERS*, binding the TEST and PARSER functions.
Returns RESULT-FORM's evaluated value.")
(function do-tag-printers
"Iterates over the current *TAG-DISPATCHERS*, binding the TEST and PRINTER functions.
Returns RESULT-FORM's evaluated value."))