Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 33 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ console.log(attributes) //=> { title: 'Awesome Title', description: 'Describe th
### Options

```ts
mode?: ('html' | 'toc' | 'react' | 'vue')[]
mode?: ('html' | 'toc' | 'tokens' | 'react' | 'vue')[]
markdown?: (body: string) => string
markdownIt?: MarkdownIt | MarkdownIt.Options
```
Expand All @@ -66,11 +66,12 @@ import { Mode } from 'vite-plugin-markdown'

console.log(Mode.HTML) //=> 'html'
console.log(Mode.TOC) //=> 'toc'
console.log(Mode.TOKENS) //=> 'tokens'
console.log(Mode.REACT) //=> 'react'
console.log(Mode.VUE) //=> 'vue'
```

"Mode" enables you to import markdown file in various formats (HTML, ToC, React/Vue Component)
"Mode" enables you to import markdown file in various formats (HTML, ToC, Tokens, React/Vue Component)

#### `Mode.HTML`

Expand Down Expand Up @@ -216,6 +217,31 @@ export default {
</details>
</details>

#### `Mode.TOKENS`

<details>
<summary>Import as parsed markdown tokens from MarkdownIt</summary>

```md
# vite

Vite is an opinionated web dev build tool that serves your code via native ES Module imports during dev and bundles it with Rollup for production.

## Status

## Getting Started

# Notes
```

```ts
import { tokens } from './contents/the-doc.md'

console.log(tokens) //=> [{ type: 'heading_open', tag: 'h1', ... }, ...]
```

</details>

### Type declarations

In TypeScript project, need to declare typedefs for `.md` file as you need.
Expand All @@ -231,6 +257,10 @@ declare module '*.md' {
// When "Mode.HTML" is requested
const html: string;

// When "Mode.Tokens" is requested
import Token from '@types/markdown-it/lib/token';
const tokens: Token[];

// When "Mode.React" is requested. VFC could take a generic like React.VFC<{ MyComponent: TypeOfMyComponent }>
import React from 'react'
const ReactComponent: React.VFC;
Expand All @@ -241,7 +271,7 @@ declare module '*.md' {
const VueComponentWith: (components: Record<string, Component>) => ComponentOptions;

// Modify below per your usage
export { attributes, toc, html, ReactComponent, VueComponent, VueComponentWith };
export { attributes, toc, html, tokens, ReactComponent, VueComponent, VueComponentWith };
}
```

Expand Down
10 changes: 9 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Element, Node as DomHandlerNode } from 'domhandler'
export enum Mode {
TOC = 'toc',
HTML = 'html',
TOKENS = 'tokens',
REACT = 'react',
VUE = 'vue',
}
Expand Down Expand Up @@ -56,7 +57,8 @@ const tf = (code: string, id: string, options: PluginOptions): TransformResult =
content.addContext(`const attributes = ${JSON.stringify(fm.attributes)}`)
content.addExporting('attributes')

const html = markdownCompiler(options).render(fm.body)
const compiler = markdownCompiler(options)
const html = compiler.render(fm.body)
if (options.mode?.includes(Mode.HTML)) {
content.addContext(`const html = ${JSON.stringify(html)}`)
content.addExporting('html')
Expand All @@ -77,6 +79,12 @@ const tf = (code: string, id: string, options: PluginOptions): TransformResult =
content.addExporting('toc')
}

if (options.mode?.includes(Mode.TOKENS) && 'parse' in compiler) {
const tokens = compiler.parse(fm.body, {})
content.addContext(`const tokens = ${JSON.stringify(tokens)}`)
content.addExporting('tokens')
}

if (options.mode?.includes(Mode.REACT)) {
const root = parseDOM(html, { lowerCaseTags: false })
const subComponentNamespace = 'SubReactComponent'
Expand Down