marked-react
Version:
Render Markdown as React components
1 lines • 19.9 kB
Source Map (JSON)
{"version":3,"file":"index.cjs","names":["htmlUnescapes: Record<string, string>","path: string","base?: string","options: ReactParserOptions","tokens: Token[]","options: ReactRendererOptions","#options","#incrementElId","el: T","children: ReactNode","level: HeadingLevels","#h","href: string","text: ReactNode","src: string","alt: string","title: string | null","code: ReactNode","lang: string | null","lang: string | undefined","ordered: boolean","start: number | undefined","children: ReactNode[]","checked: ReactNode","flags: TableFlags","html: ReactNode","props: MarkdownProps","Marked","marked","ReactRenderer","ReactParser","Fragment","Markdown"],"sources":["../src/helpers.ts","../src/ReactParser.ts","../src/ReactRenderer.ts","../src/Markdown.ts","../src/index.ts"],"sourcesContent":["const htmlUnescapes: Record<string, string> = {\n '&': '&',\n '<': '<',\n '>': '>',\n '"': '\"',\n ''': \"'\",\n};\n\n/** Used to match HTML entities and HTML characters. */\nconst reEscapedHtml = /&(?:amp|lt|gt|quot|#(?:0+)?39);/g;\nconst reHasEscapedHtml = RegExp(reEscapedHtml.source);\n\nexport const unescape = (str = '') => {\n return reHasEscapedHtml.test(str) ? str.replace(reEscapedHtml, (entity) => htmlUnescapes[entity] || \"'\") : str;\n};\n\nexport const joinBase = (path: string, base?: string) => {\n if (!base) {\n return path;\n }\n\n try {\n return new URL(path, base).href;\n } catch {\n return path;\n }\n};\n","import { ReactNode } from 'react';\nimport type { Token, Tokens } from 'marked';\n\nimport ReactRenderer, { HeadingLevels } from './ReactRenderer';\nimport { unescape } from './helpers';\n\ninterface ReactParserOptions {\n renderer: ReactRenderer;\n}\n\nclass ReactParser {\n renderer: ReactRenderer;\n\n constructor(options: ReactParserOptions) {\n this.renderer = options.renderer;\n }\n\n parse(tokens: Token[]): ReactNode[] {\n this.renderer.elIdList.push(0);\n const result = tokens.map((token) => {\n switch (token.type) {\n case 'space': {\n return null;\n }\n\n case 'heading': {\n const level = token.depth as HeadingLevels;\n return this.renderer.heading(this.parseInline(token.tokens), level);\n }\n\n case 'paragraph': {\n return this.renderer.paragraph(this.parseInline(token.tokens));\n }\n\n case 'text': {\n const textToken = token as Tokens.Text;\n return textToken.tokens ? this.parseInline(textToken.tokens) : token.text;\n }\n\n case 'blockquote': {\n const blockquoteToken = token as Tokens.Blockquote;\n const quote = this.parse(blockquoteToken.tokens);\n return this.renderer.blockquote(quote);\n }\n\n case 'list': {\n const listToken = token as Tokens.List;\n\n this.renderer.elIdList.push(0);\n const children = listToken.items.map((item) => {\n const listItemChildren = [];\n\n if (item.task) {\n listItemChildren.push(this.renderer.checkbox(item.checked ?? false));\n }\n\n listItemChildren.push(this.parse(item.tokens));\n\n return this.renderer.listItem(listItemChildren);\n });\n this.renderer.elIdList.pop();\n\n return this.renderer.list(children, token.ordered, token.ordered ? token.start : undefined);\n }\n\n case 'code': {\n return this.renderer.code(token.text, token.lang);\n }\n\n case 'html': {\n return this.renderer.html(token.text);\n }\n\n case 'table': {\n const tableToken = token as Tokens.Table;\n\n this.renderer.elIdList.push(0);\n const headerCells = tableToken.header.map((cell, index) => {\n return this.renderer.tableCell(this.parseInline(cell.tokens), {\n header: true,\n align: token.align[index],\n });\n });\n this.renderer.elIdList.pop();\n\n const headerRow = this.renderer.tableRow(headerCells);\n const header = this.renderer.tableHeader(headerRow);\n\n this.renderer.elIdList.push(0);\n const bodyChilren = tableToken.rows.map((row) => {\n this.renderer.elIdList.push(0);\n const rowChildren = row.map((cell, index) => {\n return this.renderer.tableCell(this.parseInline(cell.tokens), {\n header: false,\n align: token.align[index],\n });\n });\n this.renderer.elIdList.pop();\n\n return this.renderer.tableRow(rowChildren);\n });\n this.renderer.elIdList.pop();\n\n const body = this.renderer.tableBody(bodyChilren);\n\n return this.renderer.table([header, body]);\n }\n\n case 'hr': {\n return this.renderer.hr();\n }\n\n default: {\n console.warn(`Token with \"${token.type}\" type was not found`); // eslint-disable-line no-console\n return null;\n }\n }\n });\n this.renderer.elIdList.pop();\n return result;\n }\n\n parseInline(tokens: Token[] = []): ReactNode[] {\n this.renderer.elIdList.push(0);\n const result = tokens.map((token) => {\n switch (token.type) {\n case 'text': {\n return this.renderer.text(unescape(token.text));\n }\n\n case 'strong': {\n return this.renderer.strong(this.parseInline(token.tokens));\n }\n\n case 'em': {\n return this.renderer.em(this.parseInline(token.tokens));\n }\n\n case 'del': {\n return this.renderer.del(this.parseInline(token.tokens));\n }\n\n case 'codespan': {\n return this.renderer.codespan(unescape(token.text));\n }\n\n case 'link': {\n return this.renderer.link(token.href, this.parseInline(token.tokens));\n }\n\n case 'image': {\n return this.renderer.image(token.href, token.text, token.title);\n }\n\n case 'html': {\n return this.renderer.html(token.text);\n }\n\n case 'br': {\n return this.renderer.br();\n }\n\n case 'escape': {\n return this.renderer.text(token.text);\n }\n\n default: {\n console.warn(`Token with \"${token.type}\" type was not found`); // eslint-disable-line no-console\n return null;\n }\n }\n });\n this.renderer.elIdList.pop();\n return result;\n }\n}\n\nexport default ReactParser;\n","import { createElement, ElementType, ReactElement, ReactNode } from 'react';\n\nimport { joinBase } from './helpers';\n\nexport type HeadingLevels = 1 | 2 | 3 | 4 | 5 | 6;\nexport interface TableFlags {\n header?: boolean;\n align?: 'center' | 'left' | 'right' | null;\n}\n\nexport type CustomReactRenderer = Partial<ReactRenderer>;\nexport type RendererMethods = keyof ReactRenderer;\n\nexport interface ReactRendererOptions {\n baseURL?: string;\n openLinksInNewTab?: boolean;\n langPrefix?: string;\n renderer?: CustomReactRenderer;\n}\n\nclass ReactRenderer {\n elIdList: number[] = [];\n #options: ReactRendererOptions;\n\n constructor(options: ReactRendererOptions = {}) {\n const { renderer } = options;\n\n this.#options = options;\n\n if (renderer && typeof renderer === 'object') {\n Object.entries(renderer as ReactRenderer).forEach(([key, value]) => {\n const rendererName = key as keyof ReactRenderer;\n const rendererFunction = value;\n\n if (\n !this[rendererName] ||\n rendererName === 'elementId' ||\n rendererName === 'elIdList' ||\n typeof rendererFunction !== 'function'\n ) {\n return;\n }\n\n Object.defineProperty(this, rendererName, {\n value(this: ReactRenderer, ...args: Parameters<(typeof this)[typeof rendererName]>) {\n this.#incrementElId();\n return rendererFunction.apply(this, args);\n },\n writable: true,\n enumerable: true,\n configurable: true,\n });\n });\n }\n }\n\n #h<T extends ElementType>(el: T, children: ReactNode = null, props = {}): ReactElement {\n const elProps = {\n key: `marked-react-${this.elementId}`,\n suppressHydrationWarning: true,\n };\n\n this.#incrementElId();\n return createElement(el, { ...props, ...elProps }, children);\n }\n\n #incrementElId() {\n this.elIdList[this.elIdList.length - 1] += 1;\n }\n\n get elementId() {\n return this.elIdList.join('-');\n }\n\n heading(children: ReactNode, level: HeadingLevels) {\n return this.#h(`h${level}`, children);\n }\n\n paragraph(children: ReactNode) {\n return this.#h('p', children);\n }\n\n link(href: string, text: ReactNode) {\n const url = joinBase(href, this.#options.baseURL);\n const target = this.#options.openLinksInNewTab ? '_blank' : null;\n return this.#h('a', text, { href: url, target });\n }\n\n image(src: string, alt: string, title: string | null = null) {\n const url = joinBase(src, this.#options.baseURL);\n return this.#h('img', null, { src: url, alt, title });\n }\n\n codespan(code: ReactNode, lang: string | null = null) {\n const className = lang ? `${this.#options.langPrefix}${lang}` : null;\n return this.#h('code', code, { className });\n }\n\n code(code: ReactNode, lang: string | undefined) {\n return this.#h('pre', this.codespan(code, lang));\n }\n\n blockquote(children: ReactNode) {\n return this.#h('blockquote', children);\n }\n\n list(children: ReactNode, ordered: boolean, start: number | undefined) {\n return this.#h(ordered ? 'ol' : 'ul', children, ordered && start !== 1 ? { start } : {});\n }\n\n listItem(children: ReactNode[]) {\n return this.#h('li', children);\n }\n\n checkbox(checked: ReactNode) {\n return this.#h('input', null, {\n type: 'checkbox',\n disabled: true,\n checked,\n });\n }\n\n table(children: ReactNode[]) {\n return this.#h('table', children);\n }\n\n tableHeader(children: ReactNode) {\n return this.#h('thead', children);\n }\n\n tableBody(children: ReactNode[]) {\n return this.#h('tbody', children);\n }\n\n tableRow(children: ReactNode[]) {\n return this.#h('tr', children);\n }\n\n tableCell(children: ReactNode[], flags: TableFlags) {\n const tag = flags.header ? 'th' : 'td';\n return this.#h(tag, children, { align: flags.align });\n }\n\n strong(children: ReactNode) {\n return this.#h('strong', children);\n }\n\n em(children: ReactNode) {\n return this.#h('em', children);\n }\n\n del(children: ReactNode) {\n return this.#h('del', children);\n }\n\n text(text: ReactNode) {\n return text;\n }\n\n html(html: ReactNode) {\n return html;\n }\n\n hr() {\n return this.#h('hr');\n }\n\n br() {\n return this.#h('br');\n }\n}\n\nexport default ReactRenderer;\n","import { createElement, Fragment } from 'react';\nimport { Marked, MarkedOptions } from 'marked';\n\nimport ReactParser from './ReactParser';\nimport ReactRenderer, { ReactRendererOptions } from './ReactRenderer';\n\ntype LexerOptions = Pick<MarkedOptions, 'breaks' | 'gfm'>;\n\nexport interface MarkdownProps extends ReactRendererOptions, LexerOptions {\n value?: string;\n children?: string;\n isInline?: boolean;\n instance?: Marked;\n}\n\nconst validateComponentProps = (props: MarkdownProps) => {\n if (props.value && typeof props.value !== 'string') {\n throw new TypeError(`[marked-react]: Expected value to be of type string but got ${typeof props.value}`);\n }\n\n if (props.children && typeof props.children !== 'string') {\n throw new TypeError(`[marked-react]: Expected children to be of type string but got ${typeof props.children}`);\n }\n};\n\nconst defaultProps = {\n isInline: false,\n breaks: false,\n gfm: true,\n baseURL: undefined,\n openLinksInNewTab: true,\n langPrefix: 'language-',\n renderer: undefined,\n};\n\nconst markedInstance = new Marked();\n\nconst Markdown = (props: MarkdownProps) => {\n validateComponentProps(props);\n\n const options = { ...defaultProps, ...props };\n const marked = options.instance ?? markedInstance;\n\n // lexer options\n const lexerOptions = {\n breaks: options.breaks,\n gfm: options.gfm,\n tokenizer: marked.defaults.tokenizer,\n };\n\n // convert input markdown into tokens\n const markdownString = options.value ?? options.children ?? '';\n\n const tokens = options.isInline\n ? marked.Lexer.lexInline(markdownString, lexerOptions)\n : marked.lexer(markdownString, lexerOptions);\n\n // parser options\n const parserOptions = {\n renderer: new ReactRenderer({\n renderer: options.renderer,\n baseURL: options.baseURL,\n openLinksInNewTab: options.openLinksInNewTab,\n langPrefix: options.langPrefix,\n }),\n };\n\n const parser = new ReactParser(parserOptions);\n const children = options.isInline ? parser.parseInline(tokens) : parser.parse(tokens);\n\n return createElement(Fragment, null, children);\n};\n\nexport default Markdown;\n","import Markdown from './Markdown';\n\nexport { default as ReactParser } from './ReactParser';\nexport { default as ReactRenderer } from './ReactRenderer';\nexport default Markdown;\n"],"mappings":"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"}