Skip to content

Commit

Permalink
feat(markdown): parseMarkdown
Browse files Browse the repository at this point in the history
Signed-off-by: Lexus Drumgold <[email protected]>
  • Loading branch information
unicornware committed Apr 14, 2024
1 parent 8b5871a commit e9a0d57
Show file tree
Hide file tree
Showing 16 changed files with 445 additions and 102 deletions.
129 changes: 80 additions & 49 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@
- [Use](#use)
- [API](#api)
- [`fromDocs(value[, options])`](#fromdocsvalue-options)
- [`parseMarkdown<T>(value, options)`](#parsemarkdowntvalue-options)
- [`MarkdownOptions`](#markdownoptions)
- [`Options`](#options)
- [`ParseMarkdownOptions`](#parsemarkdownoptions)
- [`Transform`](#transform)
- [Syntax](#syntax)
- [Docblock](#docblock)
Expand Down Expand Up @@ -203,14 +206,11 @@ console.log(inspect(tree))
root[9]
├─0 comment[3] (1:1-5:4, 0-122)
│ │ code: null
│ ├─0 blockTag<file>[1] (2:4-2:27, 7-30)
│ │ │ tag: "@file"
│ ├─0 blockTag<@file>[1] (2:4-2:27, 7-30)
│ │ └─0 text "FibonacciSequence" (2:10-2:27, 13-30)
│ ├─1 blockTag<module>[1] (3:4-3:29, 34-59)
│ │ │ tag: "@module"
│ ├─1 blockTag<@module>[1] (3:4-3:29, 34-59)
│ │ └─0 text "FibonacciSequence" (3:12-3:29, 42-59)
│ └─2 blockTag<see>[1] (4:4-4:59, 63-118)
│ │ tag: "@see"
│ └─2 blockTag<@see>[1] (4:4-4:59, 63-118)
│ └─0 text "https://codewars.com/kata/55695bc4f75bbaea5100016b" (4:9-4:59, 68-118)
├─1 comment[2] (7:1-19:4, 124-414)
│ │ code: null
Expand All @@ -229,97 +229,84 @@ root[9]
│ │ └─1 code "1, 1, 2, 3, 5, 8, 13, ..., 89, 144, 233, 377, ..." (13:4-15:7, 292-358)
│ │ lang: "txt"
│ │ meta: null
│ └─1 blockTag<implements>[1] (18:4-18:42, 372-410)
│ │ tag: "@implements"
│ └─1 blockTag<@implements>[1] (18:4-18:42, 372-410)
│ └─0 typeExpression "Iterator<number, number>" (18:16-18:42, 384-410)
├─2 comment[4] (21:3-27:6, 479-583)
│ │ code: null
│ ├─0 description[1] (22:6-22:35, 488-517)
│ │ └─0 paragraph[1] (22:6-22:35, 488-517)
│ │ └─0 text "First managed sequence value." (22:6-22:35, 488-517)
│ ├─1 blockTag<public>[0] (24:6-24:13, 528-535)
│ │ tag: "@public"
│ ├─2 blockTag<instance>[0] (25:6-25:15, 541-550)
│ │ tag: "@instance"
│ └─3 blockTag<member>[2] (26:6-26:27, 556-577)
│ │ tag: "@member"
│ ├─1 blockTag<@public>[0] (24:6-24:13, 528-535)
│ ├─2 blockTag<@instance>[0] (25:6-25:15, 541-550)
│ └─3 blockTag<@member>[2] (26:6-26:27, 556-577)
│ ├─0 typeExpression "number" (26:14-26:22, 564-572)
│ └─1 text "fib1" (26:23-26:27, 573-577)
├─3 comment[4] (30:3-36:6, 609-714)
│ │ code: null
│ ├─0 description[1] (31:6-31:36, 618-648)
│ │ └─0 paragraph[1] (31:6-31:36, 618-648)
│ │ └─0 text "Second managed sequence value." (31:6-31:36, 618-648)
│ ├─1 blockTag<public>[0] (33:6-33:13, 659-666)
│ │ tag: "@public"
│ ├─2 blockTag<instance>[0] (34:6-34:15, 672-681)
│ │ tag: "@instance"
│ └─3 blockTag<member>[2] (35:6-35:27, 687-708)
│ │ tag: "@member"
│ ├─1 blockTag<@public>[0] (33:6-33:13, 659-666)
│ ├─2 blockTag<@instance>[0] (34:6-34:15, 672-681)
│ └─3 blockTag<@member>[2] (35:6-35:27, 687-708)
│ ├─0 typeExpression "number" (35:14-35:22, 695-703)
│ └─1 text "fib2" (35:23-35:27, 704-708)
├─4 comment[4] (39:3-45:6, 740-834)
│ │ code: null
│ ├─0 description[1] (40:6-40:25, 749-768)
│ │ └─0 paragraph[1] (40:6-40:25, 749-768)
│ │ └─0 text "Max sequence value." (40:6-40:25, 749-768)
│ ├─1 blockTag<private>[0] (42:6-42:14, 779-787)
│ │ tag: "@private"
│ ├─2 blockTag<instance>[0] (43:6-43:15, 793-802)
│ │ tag: "@instance"
│ └─3 blockTag<member>[2] (44:6-44:26, 808-828)
│ │ tag: "@member"
│ ├─1 blockTag<@private>[0] (42:6-42:14, 779-787)
│ ├─2 blockTag<@instance>[0] (43:6-43:15, 793-802)
│ └─3 blockTag<@member>[2] (44:6-44:26, 808-828)
│ ├─0 typeExpression "number" (44:14-44:22, 816-824)
│ └─1 text "max" (44:23-44:26, 825-828)
├─5 comment[2] (48:3-52:6, 862-995)
│ │ code: null
│ ├─0 description[1] (49:6-49:47, 871-912)
│ │ └─0 paragraph[1] (49:6-49:47, 871-912)
│ │ └─0 text "Create a new fibonacci sequence iterator." (49:6-49:47, 871-912)
│ └─1 blockTag<param>[2] (51:6-51:72, 923-989)
│ │ tag: "@param"
│ └─1 blockTag<@param>[2] (51:6-51:72, 923-989)
│ ├─0 typeExpression "number" (51:13-51:21, 930-938)
│ └─1 text "[max=Number.MAX_SAFE_INTEGER] - Max sequence value" (51:22-51:72, 939-989)
├─6 comment[4] (58:3-65:6, 1122-1259)
│ │ code: null
│ ├─0 description[1] (59:6-59:24, 1131-1149)
│ │ └─0 paragraph[1] (59:6-59:24, 1131-1149)
│ │ └─0 text "Iterable protocol." (59:6-59:24, 1131-1149)
│ ├─1 blockTag<public>[0] (61:6-61:13, 1160-1167)
│ │ tag: "@public"
│ ├─2 blockTag<instance>[0] (62:6-62:15, 1173-1182)
│ │ tag: "@instance"
│ └─3 blockTag<return>[2] (64:6-64:66, 1193-1253)
│ │ tag: "@return"
│ ├─1 blockTag<@public>[0] (61:6-61:13, 1160-1167)
│ ├─2 blockTag<@instance>[0] (62:6-62:15, 1173-1182)
│ └─3 blockTag<@return>[2] (64:6-64:66, 1193-1253)
│ ├─0 typeExpression "IterableIterator<number>" (64:14-64:40, 1201-1227)
│ └─1 text "Current sequence iterator" (64:41-64:66, 1228-1253)
├─7 comment[4] (70:3-77:6, 1340-1504)
│ │ code: null
│ ├─0 description[1] (71:6-71:51, 1349-1394)
│ │ └─0 paragraph[1] (71:6-71:51, 1349-1394)
│ │ └─0 text "Get the next value in the fibonacci sequence." (71:6-71:51, 1349-1394)
│ ├─1 blockTag<public>[0] (73:6-73:13, 1405-1412)
│ │ tag: "@public"
│ ├─2 blockTag<instance>[0] (74:6-74:15, 1418-1427)
│ │ tag: "@instance"
│ └─3 blockTag<return>[2] (76:6-76:66, 1438-1498)
│ │ tag: "@return"
│ ├─1 blockTag<@public>[0] (73:6-73:13, 1405-1412)
│ ├─2 blockTag<@instance>[0] (74:6-74:15, 1418-1427)
│ └─3 blockTag<@return>[2] (76:6-76:66, 1438-1498)
│ ├─0 typeExpression "IteratorResult<number, number>" (76:14-76:46, 1446-1478)
│ └─1 text "Next sequence value" (76:47-76:66, 1479-1498)
└─8 comment[2] (79:5-83:8, 1559-1639)
│ code: null
├─0 description[1] (80:8-80:33, 1570-1595)
│ └─0 paragraph[1] (80:8-80:33, 1570-1595)
│ └─0 text "Temporary sequence value." (80:8-80:33, 1570-1595)
└─1 blockTag<const>[2] (82:8-82:29, 1610-1631)
│ tag: "@const"
└─1 blockTag<@const>[2] (82:8-82:29, 1610-1631)
├─0 typeExpression "number" (82:15-82:23, 1617-1625)
└─1 text "value" (82:24-82:29, 1626-1631)
```

## API

This package exports the identifier [`fromDocs`](#fromdocsvalue-options). There is no default export.
This package exports the following identifiers:

- [`fromDocs`](#fromdocsvalue-options)
- [`parseMarkdown`](#parsemarkdowntvalue-options)

There is no default export.

### `fromDocs(value[, options])`

Expand All @@ -334,24 +321,65 @@ Turn docblocks into a syntax tree.

docast tree ([`Root`][docast-tree])

### `parseMarkdown<T>(value, options)`

Turn markdown into [`mdast`][mdast] child nodes, with respect for comment delimiters.

#### Type Parameters

- `T` ([`RootContent`][mdast-content]) &mdash; `mdast` child node type

#### Parameters

- `value` ([`VFile`][vfile] | `string`) &mdash; markdown to parse
- `options` ([`ParseMarkdownOptions`](#parsemarkdownoptions)) &mdash; configuration options

#### Returns

`mdast` child node array (`T[]`)

### `MarkdownOptions`

Markdown configuration options (TypeScript type).

#### Properties

- `mdastExtensions` ([`mdast.Extension[]`][mdast-extension], optional) &mdash; markdown extensions to change how
micromark tokens are converted to nodes
- `micromarkExtensions` ([`micromark.Extension[]`][micromark-extension], optional) &mdash; micromark extensions to
change how markdown is parsed

### `Options`

Configuration options (TypeScript type).

#### Extends

- [`MarkdownOptions`](#markdownoptions)

#### Properties

- `codeblocks` (`OneOrMany<RegExp | string>`, optional) &mdash; block tag names, or regular expressions, matching block
tags that should have their text converted to [`Code`][mdast-code] when parsed as markdown
- **default**: `'example'`
- **default**: `'@example'`
- `from` ([`docast.Point`][docast-point], optional) &mdash; parser start point. node positions will be relative to this
point
- **default**: `{ column: 1, line: 1, offset: 0 }`
- `mdastExtensions` ([`mdast.Extension[]`][mdast-extension], optional) &mdash; markdown extensions to change how
micromark tokens are converted to nodes
- `micromarkExtensions` ([`micromark.Extension[]`][micromark-extension], optional) &mdash; micromark extensions to
change how markdown is parsed
- `transforms` ([`Transform[]`](#transform), optional) &mdash; tree transforms

### `ParseMarkdownOptions`

Options for parsing markdown with respect for comment delimiters (TypeScript type).

#### Extends

- [`MarkdownOptions`](#markdownoptions)

#### Properties

- `code` (`boolean`, optional) &mdash; parse markdown value as fenced code
- `position` ([`Position`][docast-position]) &mdash; position of markdown value

### `Transform`

Change the AST after parsing is complete (TypeScript type).
Expand All @@ -362,7 +390,7 @@ Change the AST after parsing is complete (TypeScript type).

#### Returns

Nothing
nothing (`void`)

## Syntax

Expand Down Expand Up @@ -390,14 +418,17 @@ See [`CONTRIBUTING.md`](CONTRIBUTING.md).

[docast-parse]: https://github.com/flex-development/docast-parse
[docast-point]: https://github.com/flex-development/docast#point
[docast-position]: https://github.com/flex-development/docast#position
[docast-tree]: https://github.com/flex-development/docast#root
[docast]: https://github.com/flex-development/docast
[docblock]: https://github.com/flex-development/docast#docblock-comment
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
[esmsh]: https://esm.sh/
[mdast-code]: https://github.com/syntax-tree/mdast#code
[mdast-content]: https://github.com/syntax-tree/mdast#content-model
[mdast-extension]: https://github.com/syntax-tree/mdast-util-from-markdown#extension
[mdast-util-from-markdown]: https://github.com/syntax-tree/mdast-util-from-markdown
[mdast]: https://github.com/syntax-tree/mdast
[micromark-extension]: https://github.com/micromark/micromark#extensions
[micromark]: https://github.com/micromark/micromark
[typescript]: https://www.typescriptlang.org
Expand Down
95 changes: 95 additions & 0 deletions src/__snapshots__/util.markdown.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`unit:parseMarkdown > should return mdast child node array 1`] = `
root[12] (111:6-128:42, 2397-3216)
├─0 paragraph[5] (111:6-111:53, 2397-2444)
│ ├─0 text "Get a " (111:6-111:12, 2397-2403)
│ ├─1 linkReference[1] (111:12-111:24, 2403-2415)
│ │ │ label: "1"
│ │ │ identifier: "1"
│ │ │ referenceType: "full"
│ │ └─0 emphasis[1] (111:13-111:20, 2404-2411)
│ │ └─0 text "point" (111:14-111:19, 2405-2410)
│ ├─2 text " in the document by " (111:24-111:44, 2415-2435)
│ ├─3 inlineCode "offset" (111:44-111:52, 2435-2443)
│ └─4 text "." (111:52-111:53, 2443-2444)
├─1 break (111:53-112:1, 2444-2445)
├─2 break (112:5-113:1, 2449-2450)
│ data: {"blank":true}
├─3 paragraph[13] (113:6-114:76, 2455-2606)
│ ├─0 text "The given " (113:6-113:16, 2455-2465)
│ ├─1 inlineCode "offset" (113:16-113:24, 2465-2473)
│ ├─2 text " must be an integer in the range " (113:24-113:57, 2473-2506)
│ ├─3 inlineCode "[0, document.length]" (113:57-113:79, 2506-2528)
│ ├─4 text "." (113:79-113:80, 2528-2529)
│ ├─5 break (113:80-113:81, 2529-2530)
│ │ data: {"hard":true}
│ ├─6 text "If invalid, " (114:6-114:18, 2536-2548)
│ ├─7 inlineCode "point.column" (114:18-114:32, 2548-2562)
│ ├─8 text " and " (114:32-114:37, 2562-2567)
│ ├─9 inlineCode "point.line" (114:37-114:49, 2567-2579)
│ ├─10 text " will have a value of " (114:49-114:71, 2579-2601)
│ ├─11 inlineCode "-1" (114:71-114:75, 2601-2605)
│ └─12 text "." (114:75-114:76, 2605-2606)
├─4 break (114:76-115:1, 2606-2607)
├─5 break (115:5-116:1, 2611-2612)
│ data: {"blank":true}
├─6 blockquote[7] (116:6-124:35, 2617-3064)
│ ├─0 paragraph[4] (116:8-116:63, 2619-2674)
│ │ ├─0 strong[1] (116:8-116:17, 2619-2628)
│ │ │ └─0 text "Point" (116:10-116:15, 2621-2626)
│ │ ├─1 text " represents one place in a source " (116:17-116:51, 2628-2662)
│ │ ├─2 linkReference[1] (116:51-116:62, 2662-2673)
│ │ │ │ label: "2"
│ │ │ │ identifier: "2"
│ │ │ │ referenceType: "full"
│ │ │ └─0 emphasis[1] (116:52-116:58, 2663-2669)
│ │ │ └─0 text "file" (116:53-116:57, 2664-2668)
│ │ └─3 text "." (116:62-116:63, 2673-2674)
│ ├─1 break (116:63-117:1, 2674-2675)
│ ├─2 break (117:7-118:1, 2681-2682)
│ │ data: {"blank":true}
│ ├─3 paragraph[13] (118:8-121:35, 2689-2945)
│ │ ├─0 text "The " (118:8-118:12, 2689-2693)
│ │ ├─1 inlineCode "line" (118:12-118:18, 2693-2699)
│ │ ├─2 text " field (" (118:18-118:26, 2699-2707)
│ │ ├─3 inlineCode "1" (118:26-118:29, 2707-2710)
│ │ ├─4 text "-indexed integer) represents a line in a source file. The " (118:29-119:18, 2710-2775)
│ │ ├─5 inlineCode "column" (119:18-119:26, 2775-2783)
│ │ ├─6 text " field (" (119:26-119:34, 2783-2791)
│ │ ├─7 inlineCode "1" (119:34-119:37, 2791-2794)
│ │ ├─8 text "-indexed integer) represents a column in a source file. The " (119:37-120:25, 2794-2861)
│ │ ├─9 inlineCode "offset" (120:25-120:33, 2861-2869)
│ │ ├─10 text " field (" (120:33-120:41, 2869-2877)
│ │ ├─11 inlineCode "0" (120:41-120:44, 2877-2880)
│ │ └─12 text "-indexed integer) represents a character in a source file." (120:44-121:35, 2880-2945)
│ ├─4 break (121:35-122:1, 2945-2946)
│ ├─5 break (122:7-123:1, 2952-2953)
│ │ data: {"blank":true}
│ └─6 paragraph[3] (123:8-124:35, 2960-3064)
│ ├─0 text "The term character means a (UTF-16) code unit which is defined in the " (123:8-124:1, 2960-3030)
│ ├─1 linkReference[1] (124:8-124:20, 3037-3049)
│ │ │ label: "3"
│ │ │ identifier: "3"
│ │ │ referenceType: "full"
│ │ └─0 text "Web IDL" (124:9-124:16, 3038-3045)
│ └─2 text " specification." (124:20-124:35, 3049-3064)
├─7 break (124:35-125:1, 3064-3065)
├─8 break (125:5-126:1, 3069-3070)
│ data: {"blank":true}
├─9 definition (126:6-126:53, 3075-3122)
│ identifier: "1"
│ label: "1"
│ title: null
│ url: "https://github.com/syntax-tree/unist#point"
├─10 definition (127:6-127:52, 3128-3174)
│ identifier: "2"
│ label: "2"
│ title: null
│ url: "https://github.com/syntax-tree/unist#file"
└─11 definition (128:6-128:42, 3180-3216)
identifier: "3"
label: "3"
title: null
url: "https://webidl.spec.whatwg.org/"
`;
2 changes: 1 addition & 1 deletion src/__tests__/index.e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ import * as testSubject from '../index'

describe('e2e:docast-util-from-docs', () => {
it('should expose public api', () => {
expect(testSubject).to.have.keys(['fromDocs'])
expect(testSubject).to.have.keys(['fromDocs', 'parseMarkdown'])
})
})
2 changes: 1 addition & 1 deletion src/__tests__/reader.spec-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @module docast-util-from-docs/tests/unit-d/Reader
*/

import type Location from '../location'
import type Location from '#src/location'
import type TestSubject from '../reader'

describe('unit-d:Reader', () => {
Expand Down
4 changes: 2 additions & 2 deletions src/__tests__/util.integration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* @module docast-util-from-docs/tests/util/integration
*/

import type { Options } from '#src/interfaces'
import type { Point } from '@flex-development/docast'
import { constant, type Assign } from '@flex-development/tutils'
import { directiveFromMarkdown } from 'mdast-util-directive'
Expand All @@ -11,7 +12,6 @@ import { read } from 'to-vfile'
import { inspectNoColor } from 'unist-util-inspect'
import type { VFile } from 'vfile'
import type { TestContext } from 'vitest'
import type { Options } from '../interfaces'
import testSubject from '../util'

describe('integration:fromDocs', () => {
Expand All @@ -36,7 +36,7 @@ describe('integration:fromDocs', () => {
mdastExtensions: [directiveFromMarkdown()],
micromarkExtensions: [directive()]
}],
[await read('__fixtures__/dbl-linear.ts'), { codeblocks: [/example/] }],
[await read('__fixtures__/dbl-linear.ts'), { codeblocks: [/@example/] }],
[await read('__fixtures__/reader.ts')]
])('document sample %#', (file, options) => {
expect(testSubject(file, options)).toMatchSnapshot()
Expand Down
Loading

0 comments on commit e9a0d57

Please sign in to comment.