Docblock Abstract Syntax Tree.
docast is a specification for representing docblock comments as abstract syntax trees.
It implements the unist spec.
- Introduction
- Types
- Nodes (abstract)
- Nodes
- Mixins
- Content model
- Glossary
- List of utilities
- Contribute
This document defines a format for representing docblock comments as abstract syntax trees. Development of docast started in October 2022. This specification is written in a TypeScript-like grammar.
docast extends unist, a format for syntax trees, to benefit from its ecosystem of utilities. It also integrates with mdast, a specification for representing markdown.
docast relates to JavaScript and TypeScript in that both languages support docblock comments. docast is language-agnostic, however, and can be used with any programming language that supports docblock comments.
docast relates to JSDoc, TSDoc, and typedoc in that these tools parse docblock comments. These tools also have a limited set of tags that developers are allowed to use. If developers already have a set of tags they're using, they must spend additional time re-configuring those tags for their chosen tool. docast does not enforce any tag semantics — the user does. Tag specifications can be left to an ESLint rule, or a setting akin to jsdoc/check-tag-names or jsdoc.structuredTags.
TypeScript users can integrate docast type definitions into their project by installing the appropriate packages:
yarn add @flex-development/docastinterface Node extends unist.Node {}Node (unist.Node) is a syntactic unit in docast syntax trees.
interface Literal extends Node { value: bigint | boolean | number | string | null | undefined }Literal represents an abstract interface in docast containing the smallest possible value.
interface Parent extends unist.Parent { children: Child[] }Parent (unist.Parent) represents an abstract interface in docast containing other nodes (said to be children).
Its content is limited to docast content and mdast content.
interface BlockTag extends Parent, Tag { children: | Exclude<BlockTagContent, TypeMetadata>[] | [TypeMetadata, ...Exclude<BlockTagContent, TypeMetadata>[]] data?: BlockTagData | undefined type: 'blockTag' }BlockTag (Parent) represents top-level metadata.
Block tags should be the only element on their line, except in cases where special meaning is assigned to succeeding text. All text following a block tag name, up until the start of the next block tag name, or comment closer (*/), is considered to be the block tag's tag content.
BlockTag can be used in comment nodes. Its content model is block tag content.
interface Comment extends Parent { children: | Exclude<FlowContent, Description>[] | [summary: Description, ...Exclude<FlowContent, Description>[]] code?: CodeSegment | null | undefined data?: CommentData | undefined type: 'comment' }Comment (Parent) represents a docblock comment in a source file.
The code field represents the segment of code documented by a comment. The value of the code field may be null, undefined, or implement the CodeSegment interface. The code field must not be present if a comment is used only to provide additional information.
Comment can be used in root nodes. Its content model is flow content.
interface CodeSegment { position: unist.Position type: string }CodeSegment represents the code segment in a file that is documented by a comment.
The value of the type field is the node type of the code segment.
interface Description extends Parent { children: DescriptionContent[] data?: DescriptionData | undefined type: 'description' }Description (Parent) represents the text of a comment. It is located at the start of a comment, before any block tags, and may contain Markdown content.
Description can be used in comment nodes. Its content model is description.
interface InlineTag extends Literal, Tag { data?: InlineTagData | undefined type: 'inlineTag' value: string }InlineTag (Literal) represents inline metadata.
Inline tags are denoted by wrapping a tag name and any tag content in angle brackets ({ and }).
InlineTag can be used in block tag and description nodes. It cannot contain any children — it is a leaf.
interface Root extends Parent { children: Comment[] data?: RootData | undefined type: 'root' }Root (Parent) represents a document.
Root can be used as the root of a tree, never as a child. It can contain comment nodes.
interface TypeMetadata extends Parent { children: TypeExpression[] data?: TypeMetadataData | undefined raw: string type: 'typeMetadata' }TypeMetadata (Parent) represents an inlined type expression (e.g. {number}).
TypeMetadata can be used in block tag nodes. Its content model is type expresssion.
A raw field must be present. Its value is the raw type expression (e.g. number).
interface Tag { name: TagName }Tag represents metadata associated with a comment.
The name field represents the tag name. Tag names start with an at-sign (@) and may contain any ASCII letter after the at-sign.
type TagName<T extends string = string> = `@${T}`type Content = BlockTagContent | DescriptionContent | FlowContent | PhrasingContentNodes are grouped by content type, if applicable. Each node in docast, with the exception of Comment, falls into one or more categories of Content.
type BlockTagContent = PhrasingContent | TypeMetadataBlock content represents block tag text, and its markup.
type DescriptionContent = | mdast.Blockquote | mdast.Definition | mdast.FootnoteDefinition | mdast.List | mdast.ListItem | mdast.Paragraph | mdast.Table | mdast.ThematicBreak | PhrasingContentDescription content represents description text, and its markup.
type FlowContent = BlockTag | DescriptionFlow content represents the sections of comment.
type PhrasingContent = InlineTag | mdast.Code | mdast.PhrasingContentPhrasing content represents comment text, and its markup.
type TypeExpression = TypeExpressionMap[keyof TypeExpressionMap]TypeExpression content is a type expression.
When developing type expression parsers compatible with docast, the TypeExpressionMap map should be augmented (and exported! 😉) to register custom nodes:
declare module '@flex-development/docast' { interface TypeExpressionMap { arrayType: ArrayType assertionPredicate: AssertionPredicate bigint: BigIntLiteral boolean: BooleanLiteral conditionalType: ConditionalType constructorType: ConstructorType functionType: FunctionType genericType: GenericType identifier: Identifier inferType: InferType intersectionType: IntersectionType nonNullableType: NonNullableType null: NullLiteral nullableType: NullableType number: NumberLiteral objectLiteralType: ObjectLiteralType optionalType: OptionalType parenthesizedType: ParenthesizedType propertyAccessType: PropertyAccessType string: StringLiteral super: Super templateLiteral: TemplateLiteral this: This tupleType: TupleType typeOperation: TypeOperation typePredicate: TypePredicate typeSymbol: TypeSymbol undefined: UndefinedLiteral unionType: UnionType variadicType: VariadicType } }See the unist glossary for more terms.
A specially formatted comment in a source file used to document a segment of code or provide additional information.
Any text following a block tag name (e.g. @example, @param), up until the start of the next block tag or comment closer (*/), or any text following an inline tag name, up until the closing punctuator (}).
See the unist list of utilities for more utilities.
docast-util-from-docs- parse docblocks
See CONTRIBUTING.md.
Ideas for new utilities and tools can be posted in docast/ideas.
This project has a code of conduct. By interacting with this repository, organization, or community you agree to abide by its terms.