1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- import path from 'path'
- import fs from 'fs'
- import MarkdownIt from 'markdown-it'
- import mdContainer from 'markdown-it-container'
- import { docRoot } from '@kankan-components/build-utils'
- import externalLinkIcon from '../plugins/external-link-icon'
- import tableWrapper from '../plugins/table-wrapper'
- import tooltip from '../plugins/tooltip'
- import { ApiTableContainer } from '../plugins/api-table'
- import { highlight } from '../utils/highlight'
- import type Token from 'markdown-it/lib/token'
- import type Renderer from 'markdown-it/lib/renderer'
- const localMd = MarkdownIt()
- interface ContainerOpts {
- marker?: string | undefined
- validate?(params: string): boolean
- render?(
- tokens: Token[],
- index: number,
- options: any,
- env: any,
- self: Renderer
- ): string
- }
- export const mdPlugin = (md: MarkdownIt) => {
- md.use(externalLinkIcon)
- md.use(tableWrapper)
- md.use(tooltip)
- // demo apply
- md.use(mdContainer, 'demo', {
- validate(params) {
- return !!params.trim().match(/^demo\s*(.*)$/)
- },
- render(tokens, idx) {
- const m = tokens[idx].info.trim().match(/^demo\s*(.*)$/)
- if (tokens[idx].nesting === 1 /* means the tag is opening */) {
- const description = m && m.length > 1 ? m[1] : ''
- const sourceFileToken = tokens[idx + 2]
- let source = ''
- const sourceFile = sourceFileToken.children?.[0].content ?? ''
- if (sourceFileToken.type === 'inline') {
- source = fs.readFileSync(
- path.resolve(docRoot, 'examples', `${sourceFile}.vue`),
- 'utf-8'
- )
- }
- if (!source) throw new Error(`Incorrect source file: ${sourceFile}`)
- return `<Demo :demos="demos" source="${encodeURIComponent(
- highlight(source, 'vue')
- )}" path="${sourceFile}" raw-source="${encodeURIComponent(
- source
- )}" description="${encodeURIComponent(localMd.render(description))}">`
- } else {
- return '</Demo>'
- }
- },
- } as ContainerOpts)
- // repl apply
- md.use(mdContainer, 'repl', {
- validate(params) {
- return !!params.trim().match(/^repl\s*(.*)$/)
- },
- render(tokens, idx) {
- const m = tokens[idx].info.trim().match(/^repl\s*(.*)$/)
- if (tokens[idx].nesting === 1 /* means the tag is opening */) {
- const description = m && m.length > 1 ? m[1] : ''
- const sourceFileToken = tokens[idx + 2]
- let source = ''
- const sourceFile = sourceFileToken.children?.[0].content ?? ''
- if (sourceFileToken.type === 'inline') {
- source = fs.readFileSync(
- path.resolve(docRoot, 'examples', `${sourceFile}.vue`),
- 'utf-8'
- )
- }
- if (!source) throw new Error(`Incorrect source file: ${sourceFile}`)
- return `<Demo isRepl :demos="demos" source="${encodeURIComponent(
- highlight(source, 'vue')
- )}" path="${sourceFile}" raw-source="${encodeURIComponent(
- source
- )}" description="${encodeURIComponent(localMd.render(description))}">`
- } else {
- return '</Demo>'
- }
- },
- } as ContainerOpts)
- md.use(ApiTableContainer)
- }
|