UNPKG

markdown-to-jsx

Version:

A very fast and versatile markdown toolchain. AST, React, and HTML output available with full customization.

347 lines (346 loc) 11 kB
import * as React2 from "react"; import * as React from "react"; /** * Analogous to `node.type`. Please note that the values here may change at any time, * so do not hard code against the value directly. */ declare const RuleTypeConst: { readonly blockQuote: 0; readonly breakLine: 1; readonly breakThematic: 2; readonly codeBlock: 3; readonly codeInline: 4; readonly footnote: 5; readonly footnoteReference: 6; readonly frontmatter: 7; readonly gfmTask: 8; readonly heading: 9; readonly htmlBlock: 10; readonly htmlComment: 11; readonly htmlSelfClosing: 12; readonly image: 13; readonly link: 14; readonly orderedList: 15; readonly paragraph: 16; readonly ref: 17; readonly refCollection: 18; readonly table: 19; readonly text: 20; readonly textFormatted: 21; readonly unorderedList: 22; }; type RuleTypeValue = (typeof RuleTypeConst)[keyof typeof RuleTypeConst]; /** * markdown-to-jsx types and interfaces */ declare namespace MarkdownToJSX { /** * RequireAtLeastOne<{ ... }> <- only requires at least one key */ type RequireAtLeastOne< T, Keys extends keyof T = keyof T > = Pick<T, Exclude<keyof T, Keys>> & { [K in Keys]-? : Required<Pick<T, K>> & Partial<Pick<T, Exclude<Keys, K>>> }[Keys]; export type CreateElement = typeof React.createElement; export type HTMLTags = keyof React.JSX.IntrinsicElements & (string & {}); export type State = { /** true if the current content is inside anchor link grammar */ inAnchor?: boolean; /** true if inside a blockquote */ inBlockQuote?: boolean; /** true if parsing in an HTML context */ inHTML?: boolean; /** true if in a list */ inList?: boolean; /** true if parsing in an inline context (subset of rules around formatting and links) */ inline?: boolean; /** use this for the `key` prop */ key?: React.Key; /** reference definitions (footnotes are stored with '^' prefix) */ refs?: { [key: string]: { target: string; title: string | undefined; }; }; /** current recursion depth during rendering */ renderDepth?: number; }; export interface BlockQuoteNode { alert?: string; children: MarkdownToJSX.ASTNode[]; type: typeof RuleType2.blockQuote; } export interface BreakLineNode { type: typeof RuleType2.breakLine; } export interface BreakThematicNode { type: typeof RuleType2.breakThematic; } export interface CodeBlockNode { type: typeof RuleType2.codeBlock; attrs?: React.JSX.IntrinsicAttributes; lang?: string; text: string; } export interface CodeInlineNode { type: typeof RuleType2.codeInline; text: string; } export interface FootnoteNode { type: typeof RuleType2.footnote; } export interface FootnoteReferenceNode { type: typeof RuleType2.footnoteReference; target: string; text: string; } export interface FrontmatterNode { type: typeof RuleType2.frontmatter; text: string; } export interface GFMTaskNode { type: typeof RuleType2.gfmTask; completed: boolean; } export interface HeadingNode { type: typeof RuleType2.heading; children: MarkdownToJSX.ASTNode[]; id: string; level: 1 | 2 | 3 | 4 | 5 | 6; } export interface HTMLCommentNode { type: typeof RuleType2.htmlComment; text: string; } export interface ImageNode { type: typeof RuleType2.image; alt?: string; target: string; title?: string; } export interface LinkNode { type: typeof RuleType2.link; children: MarkdownToJSX.ASTNode[]; target: string | null; title?: string; } export interface OrderedListNode { type: typeof RuleType2.orderedList; items: MarkdownToJSX.ASTNode[][]; start?: number; } export interface UnorderedListNode { type: typeof RuleType2.unorderedList; items: MarkdownToJSX.ASTNode[][]; } export interface ParagraphNode { type: typeof RuleType2.paragraph; children: MarkdownToJSX.ASTNode[]; } export interface ReferenceNode { type: typeof RuleType2.ref; } export interface ReferenceCollectionNode { type: typeof RuleType2.refCollection; refs: { [key: string]: { target: string; title: string | undefined; }; }; } export interface TableNode { type: typeof RuleType2.table; /** * alignment for each table column */ align: ("left" | "right" | "center")[]; cells: MarkdownToJSX.ASTNode[][][]; header: MarkdownToJSX.ASTNode[][]; } export interface TextNode { type: typeof RuleType2.text; text: string; } export interface FormattedTextNode { type: typeof RuleType2.textFormatted; /** * the corresponding html tag */ tag: string; children: MarkdownToJSX.ASTNode[]; } export interface HTMLNode { type: typeof RuleType2.htmlBlock; attrs?: Record<string, any>; children?: ASTNode[] | undefined; noInnerParse?: Boolean; tag: string; text?: string | undefined; } export interface HTMLSelfClosingNode { type: typeof RuleType2.htmlSelfClosing; attrs?: Record<string, any>; isClosingTag?: boolean; tag: string; } export type ASTNode = BlockQuoteNode | BreakLineNode | BreakThematicNode | CodeBlockNode | CodeInlineNode | FootnoteNode | FootnoteReferenceNode | FrontmatterNode | GFMTaskNode | HeadingNode | HTMLCommentNode | ImageNode | LinkNode | OrderedListNode | UnorderedListNode | ParagraphNode | ReferenceNode | ReferenceCollectionNode | TableNode | TextNode | FormattedTextNode | HTMLNode | HTMLSelfClosingNode; export type ASTRender = (ast: MarkdownToJSX.ASTNode | MarkdownToJSX.ASTNode[], state: MarkdownToJSX.State) => React.ReactNode; export type Override = RequireAtLeastOne<{ component: React.ElementType; props: Object; }> | React.ElementType; export type Overrides = { [tag in HTMLTags]? : Override } & { [customComponent: string]: Override; }; export type Options = Partial<{ /** * Ultimate control over the output of all rendered JSX. */ createElement: (tag: Parameters<CreateElement>[0], props: React.JSX.IntrinsicAttributes, ...children: React.ReactNode[]) => React.ReactNode; /** * The library automatically generates an anchor tag for bare URLs included in the markdown * document, but this behavior can be disabled if desired. */ disableAutoLink: boolean; /** * Disable the compiler's best-effort transcription of provided raw HTML * into JSX-equivalent. This is the functionality that prevents the need to * use `dangerouslySetInnerHTML` in React. */ disableParsingRawHTML: boolean; /** * Enable GFM tagfilter extension to filter potentially dangerous HTML tags. * When enabled, the following tags are escaped: title, textarea, style, xmp, * iframe, noembed, noframes, script, plaintext. * https://github.github.com/gfm/#disallowed-raw-html-extension- * @default true */ tagfilter?: boolean; /** * Forces the compiler to have space between hash sign and the header text which * is explicitly stated in the most of the markdown specs. * https://github.github.com/gfm/#atx-heading * `The opening sequence of # characters must be followed by a space or by the end of line.` */ enforceAtxHeadings: boolean; /** * Forces the compiler to always output content with a block-level wrapper * (`<p>` or any block-level syntax your markdown already contains.) */ forceBlock: boolean; /** * Forces the compiler to always output content with an inline wrapper (`<span>`) */ forceInline: boolean; /** * Forces the compiler to wrap results, even if there is only a single * child or no children. */ forceWrapper: boolean; /** * Selectively control the output of particular HTML tags as they would be * emitted by the compiler. */ overrides: Overrides; /** * Allows for full control over rendering of particular rules. * For example, to implement a LaTeX renderer such as `react-katex`: * * ``` * renderRule(next, node, renderChildren, state) { * if (node.type === RuleType.codeBlock && node.lang === 'latex') { * return ( * <TeX as="div" key={state.key}> * {String.raw`${node.text}`} * </TeX> * ) * } * * return next(); * } * ``` * * Thar be dragons obviously, but you can do a lot with this * (have fun!) To see how things work internally, check the `render` * method in source for a particular rule. */ renderRule: (next: () => React.ReactNode, node: ASTNode, renderChildren: ASTRender, state: State) => React.ReactNode; /** * Override the built-in sanitizer function for URLs, etc if desired. The built-in version is available as a library export called `sanitizer`. */ sanitizer: (value: string, tag: HTMLTags, attribute: string) => string | null; /** * Override normalization of non-URI-safe characters for use in generating * HTML IDs for anchor linking purposes. */ slugify: (input: string, defaultFn: (input: string) => string) => string; /** * Declare the type of the wrapper to be used when there are multiple * children to render. Set to `null` to get an array of children back * without any wrapper, or use `React.Fragment` to get a React element * that won't show up in the DOM. */ wrapper: React.ElementType | null; /** * Props to apply to the wrapper element. */ wrapperProps?: React.JSX.IntrinsicAttributes; /** * Preserve frontmatter in the output by rendering it as a <pre> element. * By default, frontmatter is parsed but not rendered. * @default false */ preserveFrontmatter?: boolean; }>; } declare const RuleType2: typeof RuleTypeConst; type RuleType2 = RuleTypeValue; declare global { var parseMetrics: { blockParsers: { [key: string]: { attempts: number; hits: number; hitTimings: number[]; }; }; inlineParsers: { [key: string]: { attempts: number; hits: number; hitTimings: number[]; }; }; totalOperations: number; blockParseIterations: number; inlineParseIterations: number; } | null; var parseMetricsStartTimes: Map<string, number> | null; } /** * Given a markdown string, return an abstract syntax tree (AST) of the markdown. * * The first node in the AST is a reference collection node. This node contains all the * reference definitions found in the markdown. These reference definitions are used to * resolve reference links and images in the markdown. * * @param source - The markdown string to parse. * @param options - The options for the parser. * @returns The AST of the markdown. */ declare function parser(source: string, options?: MarkdownToJSX.Options): MarkdownToJSX.ASTNode[]; declare function sanitizer(input: string): string | null; declare function slugify(str: string): string; declare function compiler(markdown?: string, options?: MarkdownToJSX.Options): React2.ReactNode; /** * A simple HOC for easy React use. Feed the markdown content as a direct child * and the rest is taken care of automatically. */ declare const Markdown: React2.FC<Omit<React2.HTMLAttributes<Element>, "children"> & { children?: string | null; options?: MarkdownToJSX.Options; }>; export { slugify, sanitizer, parser, Markdown as default, compiler, RuleType2 as RuleType, MarkdownToJSX, Markdown };