added atsign syntax plugin
[parse-docstrings.git] / classes.lisp
blobb0a770f26e7ff6e142d323fadedba7fbfa152bbc
1 ;;; -*- lisp; show-trailing-whitespace: t; indent-tabs: nil -*-
3 ;;;; Part of this software was originally written as docstrings.lisp in
4 ;;;; SBCL, but is now part of the parse-docstrings project. The file
5 ;;;; docstrings.lisp was written by Rudi Schlatte <rudi@constantly.at>,
6 ;;;; mangled by Nikodemus Siivola, turned into a stand-alone project by
7 ;;;; Luis Oliveira. SBCL is in the public domain and is provided with
8 ;;;; absolutely no warranty.
10 ;;;; parse-docstrings is:
11 ;;;;
12 ;;;; Copyright (c) 2008 David Lichteblau:
13 ;;;;
14 ;;;; Permission is hereby granted, free of charge, to any person
15 ;;;; obtaining a copy of this software and associated documentation
16 ;;;; files (the "Software"), to deal in the Software without
17 ;;;; restriction, including without limitation the rights to use, copy,
18 ;;;; modify, merge, publish, distribute, sublicense, and/or sell copies
19 ;;;; of the Software, and to permit persons to whom the Software is
20 ;;;; furnished to do so, subject to the following conditions:
21 ;;;;
22 ;;;; The above copyright notice and this permission notice shall be
23 ;;;; included in all copies or substantial portions of the Software.
24 ;;;;
25 ;;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 ;;;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 ;;;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 ;;;; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
29 ;;;; HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
30 ;;;; WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
31 ;;;; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
32 ;;;; DEALINGS IN THE SOFTWARE.
34 #+sbcl ;; FIXME: should handle this in the .asd file
35 (eval-when (:compile-toplevel :load-toplevel :execute)
36 (require 'sb-introspect))
38 (in-package #:parse-docstrings)
41 ;;; The DOCUMENTATION* class
43 (defvar *documentation-package*)
44 (defvar *documentation-package-name*)
46 (defclass documentation* (parent-mixin)
47 ((name :initarg :name
48 :reader get-name)
49 (kind :initarg :kind
50 :reader get-kind)
51 (package :initform *documentation-package*
52 :reader get-package)
53 (package-name :initform *documentation-package-name*
54 :reader get-package-name)
55 (annotations :initform nil
56 :accessor documentation-annotations)
57 (methods :initform nil
58 :initarg :methods
59 :accessor method-documentation-objects)))
62 ;;;; Markup classes
64 (defclass markup-element ()
66 (:documentation
67 "MARKUP-ELEMENT is the superclass of all markup elements in
68 parse-docstrings.
70 Wikipedia says: `A markup language is an artificial language using a set
71 of annotations to text that give instructions regarding the structure of
72 text or how it is to be displayed.'
74 Documentation, usually stored in .lisp files in the form of docstrings
75 and their annotations, is parsed into a structured CLOS representation by
76 parse-docstrings. At the highest level, instances of BLOCK-CONTENT as
77 used, for example PARAGRAPH object, CODE-BLOCK objects, or ITEMIZATION.
78 At lower levels, elements like BOLD or HYPERLINK provide structure
79 within paragraphs."))
81 (annotate-documentation (markup-element type)
82 (:see-also-type documentation*)
83 (:see-also-function documentation-content)
84 (:see-also-type documentation-annotations)
85 (:see-also-type parent-mixin)
86 (:see-also-function markup-to-sexp)
87 (:see-also-function sexp-to-markup))
89 (defclass block-content (markup-element)
91 (:documentation
92 "The common superclass of all markup elements that can appear directly
93 as children of a DOCUMENTATION* object, for example PARAGRAPH objects.
95 The distinction between BLOCK-CONTENT and INLINE-CONTENT is not being
96 enforced strictly by parse-docstring functions currently. However, output
97 generation will to many formats is expected to be easier if syntax
98 plugins adhere to the convention that inline elements don't appear at
99 the top themselves and don't have block elements as children."))
101 (annotate-documentation (block-content type)
102 (:see-also-type inline-content))
104 (defclass inline-content (markup-element)
106 (:documentation
107 "The common superclass of all markup elements that can appear at a lower
108 level in the markup tree, e.g. as a part of paragraphs.
110 The distinction between BLOCK-CONTENT and INLINE-CONTENT is not being
111 enforced strictly by parse-docstring functions currently. However, output
112 generation will to many formats is expected to be easier if syntax
113 plugins adhere to the convention that inline elements don't appear at
114 the top themselves and don't have block elements as children."))
116 (annotate-documentation (inline-content type)
117 (:see-also-type block-content))
119 (defclass parent-mixin ()
120 ((child-elements :initarg :child-elements
121 :accessor child-elements))
122 (:documentation
123 "The mixin superclass of all markup elements that have child elements.
124 This mixin is used by almost every markup class, except those that are
125 actual leafs (like TEXT) and those that have non-markup child objects
126 interposed before the next level of markup (like DEFINITION-LIST
127 with its DEFINITION-LIST-ITEM objects as non-element children).")
128 (:default-initargs :child-elements nil))
130 (annotate-documentation (parent-mixin type)
131 (:slot-accessor child-elements)
132 (:see-also-type markup-element))
134 (annotate-documentation (child-elements function)
135 (:argument object "An instance of PARENT-MIXIN")
136 (:return-value "A list of MARKUP-ELEMENT instances.")
137 "Returns the children of this parent.
139 For elements of type BLOCK-CONTENT, the children are expected
140 to be of type BLOCK-CONTENT or INLINE-CONTENT, while element of type
141 INLINE-CONTENT are expected to have only INLINE-CONTENT children.
142 This distinction is not being enforced by parse-docstrings at this
143 point, however.")
145 (defmethod print-object ((object parent-mixin) stream)
146 (print-unreadable-object (object stream :type t)
147 (prin1 (child-elements object) stream)))
149 (defclass text (inline-content)
150 ((characters :initarg :characters
151 :accessor characters))
152 (:documentation
153 "Instances of this class wrap all strings that constitute the actual
154 text of a documentation string."))
156 (annotate-documentation (text type)
157 (:slot-accessor characters)
158 (:constructor make-text))
160 (annotate-documentation (characters function)
161 (:argument object "An instance of TEXT")
162 (:return-value "STRING")
163 "Returns the contents of this TEXT node as string.
165 Since TEXT nodes represent parsed markup, there are no special
166 characters in this text.
168 However, it is strongly recommended that ASCII control character not
169 be used in the string, except for whitespace characters, because such
170 characters cannot be represented at all in XML and HTML output formats.
172 Normally, newlines and other kinds of whitespace behave like an ordinary
173 space character, and sequences of whitespace are condensed into a single
174 space. However, some parent elements will specify different rules.
175 In particular, the PREFORMATTED and CODE-BLOCK element will render whitespace
176 exactly as contained in the original string.")
178 (defclass preformatted (parent-mixin block-content)
180 (:documentation
181 "Instances of this class define an exception from the usual formatting
182 of TEXT nodes for their children (and ancestor elements).
184 Here, newlines are preserved as line breaks, and sequences of space
185 are not condensed into a single space.
187 This element is similar to HTML's pre element, or the CSS assignment
188 `white-space: pre'.
190 When rendered to HTML, output formats may want to use different CSS
191 classes for PREFORMATTED and CODE-BLOCK, so that users can customize appearance
192 easily in a CSS file."))
194 (annotate-documentation (preformatted type)
195 (:constructor make-preformatted))
197 (defclass code-block (preformatted)
199 (:documentation
200 "A subclass of PREFORMATTED, this element can be used for code written
201 in a programming language.
203 Output formats might render CODE-BLOCK elements in a slightly different
204 style than ordinary PREFORMATTED elements, but are not required to do
207 When rendered to HTML, output formats may want to use different CSS
208 classes for PREFORMATTED and CODE-BLOCK, so that users can customize appearance
209 easily in a CSS file.
211 Currently, the programming language used is not presented in markup.
212 (Future versions of parse-docstrings might provide such an annotation,
213 to allow language-specific syntax highlighting.)"))
215 (annotate-documentation (code-block type)
216 (:constructor make-code-block))
218 ;; these aren't parents, because their children aren't markup
219 (defclass list-mixin ()
220 ((items :initarg :items
221 :accessor list-items))
222 (:documentation
223 "The mixin is a superclass of markup elements with a list of `children'
224 that are not proper markup elements, because they cannot appear as
225 child elements of other nodes."))
227 (annotate-documentation (list-mixin type)
228 (:slot-accessor list-items)
229 (:see-also-type list-element)
230 (:see-also-type markup-element))
232 (annotate-documentation (list-items function)
233 (:argument object "An instance of LIST-MIXIN")
234 (:return-value "A list of LIST-ITEM instances.")
235 "Returns the items of this list.")
237 (defclass definition-list (list-mixin block-content)
239 (:documentation
240 "Instances of this class represent lists of markup elements that is
241 rendered with special heading for each element.
243 Only objects of type DEFINITION-LIST-ITEM can occur as items
244 in this list.
246 This class is similar to DL element in HTML, with its LIST-ITEM children
247 corresponding to DT and DL elements."))
249 ;; theres aren't markup by themselves, because they can only appear in a
250 ;; list, but their children are markup again
251 (defclass list-item (parent-mixin)
253 (:documentation
254 "Instances of this class represent items in an object of type LIST-MIXIN.
256 Items have children of type MARKUP-ELEMENT, but are not markup themselves,
257 because they can only appear as children of LIST-MIXINs."))
259 (defclass definition-list-item (list-item)
260 ((title :initarg :title
261 :accessor definition-title))
262 (:documentation
263 "Instances of this class represent items in an object of type
264 DEFINITION-LIST.
266 Each item has a title and children, which are rendered next to each
267 other at the item's position in the list.
269 This class is similar to the DT and DL elements in HTML, which appear
270 as children of a DL list."))
272 (annotate-documentation (definition-list-item type)
273 (:slot-accessor definition-title)
274 (:constructor make-definition-list-item))
276 (annotate-documentation (definition-title function)
277 (:argument object "An instance of DEFINITION-LIST-ITEM")
278 (:return-value "STRING")
279 "Returns the title that is rendered as a header for this item.")
281 (defclass itemization (list-mixin block-content)
283 (:documentation
284 "Instances of this class represent lists of markup elements that will
285 be rendered similarly to paragraphs, but usually with indentation and
286 bullet points.
288 This class is similar to UL element in HTML, with its LIST-ITEM children
289 corresponding to LI elements."))
291 (annotate-documentation (itemization type)
292 (:constructor make-itemization))
294 (defclass enumeration (list-mixin block-content)
296 (:documentation
297 "Instances of this class represent lists of markup elements that will
298 be rendered similarly to paragraphs, but usually with indentation and
299 a sequential numbering starting with 1.
301 This class is similar to OL element in HTML, with its LIST-ITEM children
302 corresponding to LI elements."))
304 (annotate-documentation (enumeration type)
305 (:constructor make-enumeration))
307 (defclass paragraph (parent-mixin block-content)
309 (:documentation
310 "Instances of this class represent blocks of content beginning on a
311 fresh line and ending with a line break.
313 In contrast to DIV, the first line should have a margin of white space at
314 the top,and the last a margin of white space at the bottom.
316 This class is similar to the P element in HTML."))
318 (defclass div (parent-mixin block-content)
320 (:documentation
321 "Instances of this class represent blocks of content beginning on a
322 fresh line and ending with a line break.
324 In contrast to PARAGRAPH, there should be no margin of white space at
325 the top or bottom for the content of this element.
327 This class is similar to the DIV element in HTML."))
329 (defclass span (parent-mixin inline-content)
331 (:documentation
332 "Instances of this class represent a sequence of inline markup that is
333 rendered together, in the specified order.
335 This class is similar to the SPAN element in HTML."))
337 (defclass bold (parent-mixin inline-content)
339 (:documentation
340 "Instances of this class render their text in a bold font.
342 This class is similar to the B element in HTML, or the font-weight: bold
343 assignment in CSS."))
345 (defclass italic (parent-mixin inline-content)
347 (:documentation
348 "Instances of this class render their text in an italic font.
350 This class is similar to the I element in HTML, or the font-style: italic
351 assignment in CSS."))
353 (defclass fixed-width (parent-mixin inline-content)
355 (:documentation
356 "Instances of this class render their text in a fixed-width font.
358 This class is similar to the TT element in HTML, or the
359 font-family: monospace assignment in CSS."))
361 (defclass inline-code (parent-mixin inline-content)
363 (:documentation
364 "Similar to FIXED-WIDTH, this element can be used for code written
365 in a programming language.
367 When rendered to HTML, output formats may want to use different CSS
368 classes for FIXED-WIDTH and INLINE-CODE, so that users can customize
369 appearance easily in a CSS file.
371 Currently, the programming language used is not presented in markup.
372 (Future versions of parse-docstrings might provide such an annotation,
373 to allow language-specific syntax highlighting."))
375 (defclass underline (parent-mixin inline-content)
377 (:documentation
378 "Instances of this class render their text underlined.
380 This class is similar to the U element in HTML, or the text-decoration:
381 underline assignment in CSS."))
383 (defclass hyperlink (parent-mixin inline-content)
384 ((href :initarg :href
385 :accessor href))
386 (:documentation
387 "Instances of this class represent Hyperlinks. Their href attribute
388 specifies an URL as a string.
390 If possible,output formats should render the children of the element,
391 and use the href attribute only as the action when the element is
392 selected -- just like the A element behaves in HTML.
394 As an exception, output formats without native support for links, such
395 as plaintext formatting, are encourages to display the URL verbatim,
396 for example as a footnote or just following the child elements, using
397 using brackets to distinguish the URL from surrounding text.
399 If at all possible, do not use HYPERLINK elements to link to documentation
400 of individual Lisp functions. Instead, use cross references, either
401 in the form of an INLINE-CROSS-REFERENCE or as a
402 CROSS-REFERENCE-ANNOTATION, and use hyperdoc to define URLs for
403 functions in the target package.
405 Used this way, internal cross references to functions documented
406 in the same run of parse-docstrings can use links native to the output
407 format (for example, using relative URLs in #anchor format instead of
408 absolute URLs) and will use the absolute URLs for external
409 references only, with the URL format currently declared to be correct
410 by the library being referenced."))
412 (annotate-documentation (href function)
413 (:argument object "An instance of HYPERLINK")
414 (:return-value "STRING")
415 "Returns the title that is rendered as a header for this item.")
417 (defclass cross-reference-mixin ()
418 ((target :initarg :target
419 :accessor cross-reference-target)
420 (doc-type :initarg :doc-type
421 :accessor cross-reference-doc-type))
422 (:documentation
423 "Instances of this class specify cross references between documentation
424 strings. The target of a cross-reference is specified as a pair
425 of a documentation name (for example, a symbol) and a doc-type, which
426 would be suitable as an argument to DOCUMENTATION or DOCUMENTATION*."))
428 (annotate-documentation (cross-reference-mixin type)
429 (:slot-accessor cross-reference-target)
430 (:slot-accessor cross-reference-doc-type))
432 (defclass inline-cross-reference
433 (parent-mixin
434 cross-reference-mixin
435 inline-content)
436 ((annotation-category :initarg :annotation-category
437 :accessor annotation-category))
438 (:documentation
439 "Instances of this class represent cross references (or links) to
440 Lisp documentation.
442 (If at all possible, use this class or CROSS-REFERENCE-ANNOTATION over
443 HYPERLINK whenever possible.)
445 The ANNOTATION-CATEGORY slot in this class can specify what kind
446 of conceptual relationship the reference's target has to the documentation
447 it is being used in. Depending on the category, it will be listed
448 as a slot accessor, constructor function, condition type signalled,
449 or just listed under `see also'. Refer to ANNOTATION-CATEGORY for
450 permissible values.
452 This class will render internal cross references to functions documented
453 in the same run of parse-docstrings can use links native to the output
454 format (for example, using relative URLs in #anchor format instead of
455 absolute URLs) and will use the absolute URLs for external
456 references only, with the URL format currently declared to be correct
457 by the library being referenced."))
459 (annotate-documentation (inline-cross-reference type)
460 (:slot-accessor annotation-category)
461 (:constructor make-inline-cross-reference))
463 (annotate-documentation (annotation-category function)
464 (:argument object "An instance of INLINE-CROSS-REFERENCE")
465 (:return-value "One of :CONDITION, :CONSTRUCTOR, :SLOT-ACCESSOR, or NIL")
466 "Returns the ANNOTATION-CATEGORY of the cross reference.
468 The category specifies what kind of conceptual relationship the
469 reference's target has to the documentation it is being used in.
471 Possible values are:
473 * NIL -- will be listed as `See Also'
474 * :SLOT-ACCESSOR -- will be listed as `Slot Accessor Function'
475 * :CONSTRUCTOR -- will be listed as `Constructor Function'
476 * :CONDITION -- will be listed as `Condition Types Signalled'")
478 (defclass unknown-element (parent-mixin inline-content)
479 ((name :initarg :name
480 :accessor name)
481 (plist :initarg :plist
482 :accessor plist))
483 (:documentation
484 "This fallback class is used for unknown markup elements encountered
485 in a docstring.
487 A property list mapping strings (or symbols) to strings is provided
488 as PLIST.
490 Users are advised against use of unknown elements, because not all output
491 formats will render them identically.
493 Examples:
495 * An XML serialization might pass unknown elements through under the
496 specified name, perhaps in a special namespace.
497 * An HTML serialization might pass those elements through that happen
498 to have a name permitted in HTML, and ignore others. Alternatively, it
499 might allow all unknown elements, leaving it up to the docstring author
500 to ensure that no invalid HTML will result.
501 * Other output formats might ignore unknown elements completely, or
502 render only their children.
504 All output formats are encouraged (but not required to) continue
505 execution without errors when encountering unknown elements, but also
506 to print a warning alterting the user to their presence."))
508 (annotate-documentation (unknown-element type)
509 (:slot-accessor name)
510 (:slot-accessor plist)
511 (:constructor make-unknown-element))
513 (annotate-documentation (name function)
514 (:argument object "An instance of UNKNOWN-ELEMENT")
515 (:return-value "STRING")
516 "Returns the name of the unknown element.
518 For example, an atdoc tag @foo[bar]{baz} would result in an
519 UNKNOWN-ELEMENT with a NAME of \"foo\".")
521 (annotate-documentation (plist function)
522 (:argument object "An instance of UNKNOWN-ELEMENT")
523 (:return-value "A property list mapping strings or symbols to strings")
524 "Returns the plist of the unknown element.
526 For example, an atdoc tag @foo[bar]{baz} would result in an
527 UNKNOWN-ELEMENT with a PLIST mapping \"foo\" to \"bar\".")
529 (defun make-inline-cross-reference
530 (target doc-type annotation-category &rest children)
531 (make-instance 'inline-cross-reference
532 :target target
533 :doc-type doc-type
534 :annotation-category annotation-category
535 :child-elements children))
537 (defun make-text (characters)
538 (check-type characters string)
539 (make-instance 'text :characters characters))
541 (macrolet ((%simple-parent (constructor class)
542 `(defun ,constructor (&rest children)
543 (dolist (child children)
544 (check-type child markup-element))
545 (make-instance ',class :child-elements children))))
546 (%simple-parent make-preformatted preformatted)
547 (%simple-parent make-code-block code-block)
548 (%simple-parent make-paragraph paragraph)
549 (%simple-parent make-div div)
550 (%simple-parent make-span span)
551 (%simple-parent make-bold bold)
552 (%simple-parent make-italic italic)
553 (%simple-parent make-fixed-width fixed-width)
554 (%simple-parent make-inline-code inline-code)
555 (%simple-parent make-underline underline))
557 (macrolet ((%list-parent (constructor class)
558 `(defun ,constructor (&rest items)
559 (dolist (item items)
560 (check-type item list-item))
561 (make-instance ',class :items items))))
562 (%list-parent make-itemization itemization)
563 (%list-parent make-enumeration enumeration))
565 (defun make-definition-list (&rest items)
566 (dolist (item items)
567 (check-type item definition-list-item))
568 (make-instance 'definition-list :items items))
570 (defun make-definition-list-item (title &rest children)
571 (check-type title string)
572 (dolist (child children)
573 (check-type child markup-element))
574 (make-instance 'definition-list-item :title title :child-elements children))
576 (defun make-list-item (&rest children)
577 (dolist (child children)
578 (check-type child markup-element))
579 (make-instance 'list-item :child-elements children))
581 (defun make-hyperlink (href &rest children)
582 (check-type href string)
583 (dolist (child children)
584 (check-type child markup-element))
585 (make-instance 'hyperlink :href href :child-elements children))
587 (defun make-unknown-element (name plist &rest children)
588 (check-type name string)
589 (dolist (child children)
590 (check-type child markup-element))
591 (iter (for (name value) on plist by #'cddr)
592 (check-type name (or symbol string))
593 (check-type value string))
594 (make-instance 'unknown-element :name name
595 :plist plist
596 :child-elements children))
599 ;;;; Annotation Classes
601 (defclass documentation-annotations ()
602 ((arguments :initform nil
603 :accessor argument-annotations)
604 (return-values :initform nil
605 :accessor return-value-annotations)
606 (conditions :initform nil
607 :accessor condition-annotations)
608 (slot-accessors :initform nil
609 :accessor slot-accessor-annotations)
610 (constructors :initform nil
611 :accessor constructor-annotations)
612 (see-also-list :initform nil
613 :accessor see-also-annotations)
614 ;; FIXME: shouldn't the following slots are contain lists, so that
615 ;; multiple annotations can be merged properly?
616 (summary :initform nil
617 :accessor summary-annotation)
618 (implementation-note :initform nil
619 :accessor implementation-note-annotation))
620 (:documentation
621 "This class stores annotations for docstrings, specifing for additional
622 information on arguments, return values, and cross references.
624 Depending on the docstring syntax in use, annotation can be specified
625 directly in the docstring using special markup.
627 Alternatively, the plist of symbol that names a definition can be used
628 to store annotations separately from the docstring. Refer to the
629 ANNOTATE-DOCUMENTATION macro for details."))
631 (annotate-documentation (documentation-annotations type)
632 (:slot-accessor argument-annotations)
633 (:slot-accessor return-value-annotations)
634 (:slot-accessor condition-annotations)
635 (:slot-accessor slot-accessor-annotations)
636 (:slot-accessor constructor-annotation)
637 (:slot-accessor see-also-annotations)
638 (:slot-accessor summary-annotation)
639 (:slot-accessor implementation-note-annotation)
640 (:constructor annotations))
642 (annotate-documentation (argument-annotations function)
643 (:argument object "An instance of DOCUMENTATION-ANNOTATIONS")
644 (:return-value "A list of PARAMETER-LIKE-ANNOTATION objects")
645 "Returns annotations for this function's arguments.
647 Each annotation records the name of the argument, and a docstring
648 describing details of the argument, e.g. its type.
650 It is recommended (but currently not required) that arguments
651 in list correspond to the original names in the lambda list, and that
652 their order is preserved.")
654 (annotate-documentation (return-value-annotations function)
655 (:argument object "An instance of DOCUMENTATION-ANNOTATIONS")
656 (:return-value "A list of PARAMETER-LIKE-ANNOTATION objects")
657 "Returns annotations for this function's return values.
659 Each annotation records a docstring describing details of return value,
660 e.g. its type. Additionally, a name can be specified for annotation,
661 allowing HyperSpec-like descriptions of each return value.
663 Only functions using multiple values will have more than one annotation
664 in this slot.
666 Where multiple values are used, annotations in this list are stored in the
667 order of their return values.")
669 (annotate-documentation (condition-annotations function)
670 (:argument object "An instance of DOCUMENTATION-ANNOTATIONS")
671 (:return-value "A list of CROSS-REFERENCE-ANNOTATION objects")
672 "Returns annotations for condition classes signalled by this function.
674 Each entry is this list is a cross reference for a type, referring to
675 a condition class that might be signalled.
677 Entries in this list can occur in any order.")
679 (annotate-documentation (constructor-annotations function)
680 (:argument object "An instance of DOCUMENTATION-ANNOTATIONS")
681 (:return-value "A list of CROSS-REFERENCE-ANNOTATION objects")
682 "Returns annotations for functions serving as constructors for this type.
684 In this documentation, constructor for a type is any function that
685 returns fresh instances of that type.
687 This kind of annotation is useful when a type FOO is usually created
688 through a wrapper function MAKE-FOO rather than direct calls to
689 MAKE-INSTANCE.
691 Entries in this list can occur in any order.")
693 (annotate-documentation (slot-accessor-annotations function)
694 (:argument object "An instance of DOCUMENTATION-ANNOTATIONS")
695 (:return-value "A list of CROSS-REFERENCE-ANNOTATION objects")
696 "Returns annotations for functions serving as slot readers or accessors.
698 Annotations in this list document that this class has a slot accessible
699 through the function designated by the cross reference, and possibly
700 settable through a setf function for the same name.
702 This kind of annotation is most useful for programs that opt not to
703 document slots directly, and prefer to document the slot accessors as
704 ordinary functions instead.
706 Entries in this list can occur in any order.")
708 (annotate-documentation (see-also-annotations function)
709 (:argument object "An instance of DOCUMENTATION-ANNOTATIONS")
710 (:return-value "A list of CROSS-REFERENCE-ANNOTATION objects")
711 "Returns annotations for related definitions.
713 Cross-reference annotations in this list are meant to augment the
714 CONDITION-ANNOTATIONS, CONSTRUCTOR-ANNOTATIONS, and
715 SLOT-ACCESSOR-ANNOTATIONS. Any cross reference can be added to this list,
716 assuming that the target of the cross reference is related to the current
717 function, and that relation is not made explict in the docstring.
719 Entries in this list can occur in any order.")
721 (annotate-documentation (summary-annotation function)
722 (:argument object "An instance of DOCUMENTATION-ANNOTATIONS")
723 (:return-value "NIL or a MARKUP-ELEMENT")
724 "Returns markup with a short summary of the documentation.
726 This markup node may contain a short description of the object being
727 documented, suitable for an abbreviated display in a table of contents
728 or similar.
730 If not set explicitly, it is customary to use the first line or first
731 paragraph of the documentation in its place.")
733 (annotate-documentation (implementation-note-annotation function)
734 (:argument object "An instance of DOCUMENTATION-ANNOTATIONS")
735 (:return-value "NIL or a MARKUP-ELEMENT")
736 "Returns markup with implementation notes.
738 This markup node may contain notes relating to the implementation of
739 documentation.")
741 (defclass cross-reference-annotation (cross-reference-mixin)
743 (:documentation
744 "Instances of this class specify cross references that are
745 included in documentation only as annotations, i.e. not as a part
746 of the main docstring's text.
748 Cross reference annotations are recorded as a part of
749 DOCUMENTATION-ANNOTATIONS objects, as CONDITION-ANNOTATIONS,
750 SLOT-ACCESSOR-ANNOTATIONS, CONSTRUCTOR-ANNOTATIONS, or
751 SEE-ALSO-ANNOTATIONS."))
753 (annotate-documentation (cross-reference-annotation type)
754 (:constructor make-cross-reference-annotation))
756 (defun make-cross-reference-annotation (target doc-type)
757 "Returns a fresh instance of CROSS-REFERENCE-ANNOTATION with the
758 slots for CROSS-REFERENCE-TARGET and CROSS-REFERENCE-DOC-TYPE bound
759 to TARGET and DOC-TYPE, respectively."
760 (make-instance 'cross-reference-annotation
761 :target target
762 :doc-type doc-type))
764 (annotate-documentation (make-cross-reference-annotation function)
765 (:argument target "A documentation name, for example a symbol.")
766 (:argument doc-type "A documentation type as accepted by DOCUMENTATION*"
767 "as a second argument.")
768 (:return-value "An instance of cross-reference-annotation"))
770 (defclass parameter-annotation (parent-mixin)
771 ((name :initarg :name
772 :accessor parameter-name))
773 (:documentation
774 "Instances of this class specify documentation on function arguments and
775 return values.
777 The annotation specifies a name, which is required or at least highly
778 recommended for arguments, and optional for return values.
780 Parameter annotations are a markup parent. Their child elements
781 are meant to document the argument or return value and
782 should usually specify at least its type, but ideally also describe
783 its purpose."))
785 (annotate-documentation (parameter-annotation type)
786 (:slot-accessor parameter-name)
787 (:constructor make-parameter-annotation))
789 (defun make-parameter-annotation (name &rest children)
790 "Returns a fresh instance of PARAMETER-ANNOTATION with the slot for
791 PARAMETER-NAME bound to name and CHILD-ELEMENTS bound to CHILDREN."
792 (make-instance 'parameter-annotation
793 :name name
794 :child-elements children))
796 (annotate-documentation (make-parameter-annotation function)
797 (:argument name "Symbol naming the argument or return value.")
798 (:argument children "List of MARKUP-ELEMENT objects")
799 (:return-value "A fresh PARAMETER-ANNOTATION."))
802 ;;; allow cross references to symbols in packages that aren't currently
803 ;;; loaded. (At least in theory, hyperdoc can resolve these using
804 ;;; its pre-generated index.)
806 (defclass missing-symbol ()
807 ((symbol-name :initarg :symbol-name
808 :accessor missing-symbol-name)
809 (package-name :initarg :package-name
810 :accessor missing-symbol-package-name)))
812 (defmethod missing-symbol-name ((symbol symbol))
813 (symbol-name symbol))
815 (defmethod missing-symbol-package-name ((symbol symbol))
816 (package-name (symbol-package symbol)))
818 (defun make-missing-symbol (name package)
819 (make-instance 'missing-symbol
820 :symbol-name name
821 :package (etypecase package
822 (string package)
823 (package (package-name package)))))