Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/flex-development/docast

Docblock Abstract Syntax Tree format
https://github.com/flex-development/docast

ast doc docblock markdown mdast syntax-tree unist unist-spec

Last synced: about 2 months ago
JSON representation

Docblock Abstract Syntax Tree format

Awesome Lists containing this project

README

        

# docast

[![github release](https://img.shields.io/github/v/release/flex-development/docast.svg?include_prereleases&sort=semver)](https://github.com/flex-development/docast/releases/latest)
[![npm](https://img.shields.io/npm/v/@flex-development/docast.svg)](https://npmjs.com/package/@flex-development/docast)
[![module type: esm](https://img.shields.io/badge/module%20type-esm-brightgreen)](https://github.com/voxpelli/badges-cjs-esm)
[![license](https://img.shields.io/github/license/flex-development/docast.svg)](LICENSE.md)
[![conventional commits](https://img.shields.io/badge/-conventional%20commits-fe5196?logo=conventional-commits&logoColor=ffffff)](https://conventionalcommits.org/)
[![typescript](https://img.shields.io/badge/-typescript-3178c6?logo=typescript&logoColor=ffffff)](https://typescriptlang.org/)
[![vitest](https://img.shields.io/badge/-vitest-6e9f18?style=flat&logo=vitest&logoColor=ffffff)](https://vitest.dev/)
[![yarn](https://img.shields.io/badge/-yarn-2c8ebb?style=flat&logo=yarn&logoColor=ffffff)](https://yarnpkg.com/)

**Doc**block **A**bstract **S**yntax **T**ree.

---

**docast** is a specification for representing [docblock comments](#docblock-comment) as [abstract syntax trees][unist-syntax-tree].

It implements the [**unist**][unist] spec.

## Contents

- [Introduction](#introduction)
- [Where this specification fits](#where-this-specification-fits)
- [Types](#types)
- [Nodes (abstract)](#nodes-abstract)
- [`Node`](#node)
- [`Literal`](#literal)
- [`Parent`](#parent)
- [Nodes](#nodes)
- [`BlockTag`](#blocktag)
- [`Comment`](#comment)
- [`CodeSegment`](#codesegment)
- [`Description`](#description)
- [`InlineTag`](#inlinetag)
- [`Root`](#root)
- [`TypeMetadata`](#typemetadata)
- [Mixins](#mixins)
- [`Tag`](#tag)
- [`TagName`](#tagname)
- [Content model](#content-model)
- [`BlockTagContent`](#blocktagcontent)
- [`DescriptionContent`](#descriptioncontent)
- [`FlowContent`](#flowcontent)
- [`PhrasingContent`](#phrasingcontent)
- [`TypeExpression`](#typeexpression)
- [Glossary](#glossary)
- [List of utilities](#list-of-utilities)
- [Contribute](#contribute)

## Introduction

This document defines a format for representing [docblock comments](#docblock-comment) as [abstract syntax trees][unist-syntax-tree].
Development of docast started in October 2022. This specification is written in a [TypeScript][typescript]-like grammar.

### Where this specification fits

docast extends [unist][unist], a format for syntax trees, to benefit from its [ecosystem of utilities][unist-utilities].
It also integrates with [mdast][mdast], a specification for representing markdown.

docast relates to [JavaScript][javascript] and [TypeScript][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][jsdoc], [TSDoc][tsdoc], and [typedoc][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][eslint] rule, or a
setting akin to [`jsdoc/check-tag-names`][check-tag-names] or [`jsdoc.structuredTags`][structuredtags].

## Types

TypeScript users can integrate `docast` type definitions into their project by installing the appropriate packages:

```sh
yarn add @flex-development/docast
```

## Nodes (abstract)

### `Node`

```ts
interface Node extends unist.Node {}
```

**Node** ([**unist.Node**][unist-node]) is a syntactic unit in docast syntax trees.

### `Literal`

```ts
interface Literal extends Node {
value: bigint | boolean | number | string | null | undefined
}
```

**Literal** represents an abstract interface in docast containing the smallest possible value.

### `Parent`

```ts
interface Parent extends unist.Parent {
children: Child[]
}
```

**Parent** ([**unist.Parent**][unist-parent]) represents an abstract interface in docast containing other nodes (said to
be [*children*][unist-child]).

Its content is limited to [docast content](#content-model) and [mdast content][mdast-content].

## Nodes

### `BlockTag`

```ts
interface BlockTag extends Parent, Tag {
children:
| Exclude[]
| [TypeMetadata, ...Exclude[]]
data?: BlockTagData | undefined
type: 'blockTag'
}
```

**BlockTag** ([**Parent**](#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](#tagname), up until the start of the next block tag name, or comment closer
(`*/`), is considered to be the block tag's [*tag content*](#tag-content).

**BlockTag** can be used in [**comment**](#comment) nodes. Its content model is [**block tag**](#blocktagcontent)
content.

### `Comment`

```ts
interface Comment extends Parent {
children:
| Exclude[]
| [summary: Description, ...Exclude[]]
code?: CodeSegment | null | undefined
data?: CommentData | undefined
type: 'comment'
}
```

**Comment** ([**Parent**](#parent)) represents a [*docblock comment*](#docblock-comment) in a source [*file*][unist-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`](#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**](#root) nodes. Its content model is [**flow**](#flowcontent) content.

#### `CodeSegment`

```ts
interface CodeSegment {
position: unist.Position
type: string
}
```

**CodeSegment** represents the code segment in a [*file*][unist-file] that is documented by a [**comment**](#comment).

The value of the `type` field is the node type of the code segment.

### `Description`

```ts
interface Description extends Parent {
children: DescriptionContent[]
data?: DescriptionData | undefined
type: 'description'
}
```

**Description** ([**Parent**](#parent)) represents the text of a [**comment**](#comment). It is located at the start of
a comment, before any [**block tags**](#blocktag), and may contain [Markdown][mdast] content.

**Description** can be used in [**comment**](#comment) nodes. Its content model is [**description**](#descriptioncontent).

### `InlineTag`

```ts
interface InlineTag extends Literal, Tag {
data?: InlineTagData | undefined
type: 'inlineTag'
value: string
}
```

**InlineTag** ([**Literal**](#literal)) represents inline metadata.

Inline tags are denoted by wrapping a [tag name](#tagname) and any [*tag content*](#tag-content) in angle brackets (`{`
and `}`).

**InlineTag** can be used in [**block tag**](#blocktag) and [**description**](#description) nodes. It cannot contain any
children — it is a [*leaf*][unist-leaf].

### `Root`

```ts
interface Root extends Parent {
children: Comment[]
data?: RootData | undefined
type: 'root'
}
```

**Root** ([**Parent**](#parent)) represents a document.

**Root** can be used as the [*root*][unist-root] of a [*tree*][unist-tree], never as a [*child*][unist-child]. It can
contain [**comment**](#comment) nodes.

### `TypeMetadata`

```ts
interface TypeMetadata extends Parent {
children: TypeExpression[]
data?: TypeMetadataData | undefined
raw: string
type: 'typeMetadata'
}
```

**TypeMetadata** ([**Parent**](#parent)) represents an inlined type expression (e.g. `{number}`).

**TypeMetadata** can be used in [**block tag**](#blocktag) nodes. Its content model is [**type expresssion**](#typeexpression).

A `raw` field must be present. Its value is the raw type expression (e.g. `number`).

## Mixins

### `Tag`

```ts
interface Tag {
name: TagName
}
```

**Tag** represents metadata associated with a [**comment**](#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.

#### `TagName`

```ts
type TagName = `@${T}`
```

## Content model

```ts
type Content = BlockTagContent | DescriptionContent | FlowContent | PhrasingContent
```

Nodes are grouped by content type, if applicable. Each node in docast, with the exception of [`Comment`](#comment),
falls into one or more categories of `Content`.

### `BlockTagContent`

```ts
type BlockTagContent = PhrasingContent | TypeMetadata
```

**Block** content represents [**block tag**](#blocktag) text, and its markup.

### `DescriptionContent`

```ts
type DescriptionContent =
| mdast.Blockquote
| mdast.Definition
| mdast.FootnoteDefinition
| mdast.List
| mdast.ListItem
| mdast.Paragraph
| mdast.Table
| mdast.ThematicBreak
| PhrasingContent
```

**Description** content represents [**description**](#description) text, and its markup.

### `FlowContent`

```ts
type FlowContent = BlockTag | Description
```

**Flow** content represents the sections of [**comment**](#comment).

### `PhrasingContent`

```ts
type PhrasingContent = InlineTag | mdast.Code | mdast.PhrasingContent
```

**Phrasing** content represents [**comment**](#comment) text, and its markup.

### `TypeExpression`

```ts
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! :wink:) to register custom nodes:

```ts
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
}
}
```

## Glossary

See the [unist glossary][unist-glossary] for more terms.

### Docblock comment

A specially formatted [comment][wiki-comment] in a source [*file*][unist-file] used to document a segment of code or
provide additional information.

### Tag content

Any text following a [block tag](#blocktag) name (e.g. `@example`, `@param`), up until the start of the next block tag
or comment closer (`*/`), or any text following an [inline tag](#inlinetag) name, up until the closing punctuator (`}`).

## List of utilities

See the [unist list of utilities][unist-utilities] for more utilities.

- [`docast-util-from-docs`][docast-util-from-docs] - parse docblocks

## Contribute

See [`CONTRIBUTING.md`](CONTRIBUTING.md).

Ideas for new utilities and tools can be posted in [docast/ideas][docast-ideas].

This project has a [code of conduct](CODE_OF_CONDUCT.md). By interacting with this repository, organization, or
community you agree to abide by its terms.

[check-tag-names]: https://github.com/gajus/eslint-plugin-jsdoc-check-tag-names
[docast-ideas]: https://github.com/flex-development/docast/discussions/new?category=idea
[docast-util-from-docs]: https://github.com/flex-development/docast-util-from-docs
[eslint]: https://eslint.org
[javascript]: https://www.ecma-international.org/ecma-262/9.0/index.html
[jsdoc]: https://jsdoc.app
[mdast-content]: https://github.com/syntax-tree/mdast#content-model
[mdast]: https://github.com/syntax-tree/mdast
[structuredtags]: https://github.com/gajus/eslint-plugin-jsdoc-structuredtags
[tsdoc]: https://tsdoc.org
[typedoc]: https://github.com/TypeStrong/typedoc
[typescript]: https://typescriptlang.org
[unist-child]: https://github.com/syntax-tree/unist#child
[unist-file]: https://github.com/syntax-tree/unist#file
[unist-glossary]: https://github.com/syntax-tree/unist#glossary
[unist-leaf]: https://github.com/syntax-tree/unist#leaf
[unist-node]: https://github.com/syntax-tree/unist#node
[unist-parent]: https://github.com/syntax-tree/unist#parent
[unist-root]: https://github.com/syntax-tree/unist#root
[unist-syntax-tree]: https://github.com/syntax-tree/unist#syntax-tree
[unist-tree]: https://github.com/syntax-tree/unist#tree
[unist-utilities]: https://github.com/syntax-tree/unist#list-of-utilities
[unist]: https://github.com/syntax-tree/unist
[wiki-comment]: https://en.wikipedia.org/wiki/Comment_(computer_programming)