@iandx/markit
v0.1.6
Published
A powerful markdown parser and renderer for react * 👐 build for high extensibility * ⚡️ yet still very fast * 💫 best practice for react * ✨ incremental parsing to avoid unnecessary dom re-render * 🎨 easy to customize
Downloads
79
Readme
Markit
A powerful markdown parser and renderer for react
- 👐 build for high extensibility
- ⚡️ yet still very fast
- 💫 best practice for react
- ✨ incremental parsing to avoid unnecessary dom re-render
- 🎨 easy to customize
Install
npm install @iandx/markit
Quick start
import { ReactMarkit } from '@iandx/markit';
function App () {
const content = '# Welcome to **use** *Markit*';
return(
<ReactMarkit content={content}/>
)
}
Usage
ReactMarkit
Basic React component. Give it a
content
orchildren
prop as its rendering contentUse whichever you like
let content = "* this is a list"
const Markit1 = () =>
<ReactMarkit content={content} />
const Markit2 = () =>
<ReactMarkit>{content}<ReactMarkit/>
Markit
Global init markit
import {Markit} from "@iandx/markit"
Markit.init({
tabSpaceNum: 2,
softBreak: true,
geneId: false
})
| properties | type | default | description | |--------|---|------------------------------------------------------------------------------|------------------------------------------------------------------------------| | tabSpaceNum | number | 2 | a tab "\t" equals to how many spaces | | softBreak | number | true | if set "true", "\n" will be recognized as a soft break instead of a new line | | geneId | number | false | give each AST a unique id, useful for increnmental parsing |
Default rules and drop rules
Inline
| type | description | | ----------- | -------------------------------------------------- | | Bold | **bold** | | Italic | *italic* | | Strike | ~~strike through~~ | | Underline | <u>underline<u>, _!also underline!_ | | Code | `code` | | Link | [link title](link_url) | | Escape | character like \*, \_, \~ | | Superscript | ^superscript^ | | Subscript | ~subscript~ | | Highlight | ==hightlight== | | HtmlTag | <anyTag>content</anyTag> | | Math | $latex math formula like \frac{1}{2}$ | | FootnoteSup | [^footnotesup] will link to the end of the page | | LinkTag | [link tag] will be a link if supply a link block |
if you don't want some provided inline features, you can easily drop it by using
import {Markit} from "@iandx/markit" Markit.dropRule.inline(["Math", "LinkTag"])
block
| type | blockType | description | | ------------- |----------------------------------------------------------------------------------| ------------------------------------------------------------ | | Heading | leaf | # this is heading1this is also heading1===== | | Blockquote | leaf | > blockquote>> level2 | | CodeBlock | leaf | ``` javascript function test() {console.log("hi")}``` | | Divider | leaf | ----[dashed] | | Image | leaf | ![alt_content](url hover_title 50% center) | | MathBlock | leaf | $$Math block \sqrt{a}$$ | | Latex | leaf | $$$Latex block \sqrt{a}$$$ | | Footnote | leaf | [^footnotesup]: content | | LinkTagBlock | leaf | [^linkTag]: replaced url | | Comment | leaf | // any comment | | UnorderedList | container | * unordered list+ also unordered list- still unordered list | | OrderedList | container | 1. OrderedList1. will display 2 in this line | | CheckList | container | - [x] GFM to-do list |
if you don't want some provided inline features, you can easily drop it by using
import {Markit} from "@iandx/markit" Markit.dropRule.block(["Comment", "Image", "Divider"])
Add new rules
inline First we will introduce the structure of the syntax rule. Following are the properties.
tags
An object to define syntax token. You may use the following properties to config.
leading
A String which will be recognized as syntax token used before text, e.g. '##'round
A String which will be recognized as syntax token used around text, e.g. '**'wrap
A array which will be recognized as syntax token used in the left and right of the text. e.g. ['','']exact
A String or a regular expression
trimText
A callback function which recieves a raw text and usually returns the text after triming the tags. Note: using leading, round, wrap, the parser will help you trim the tags token by default
parseContent
A callback function which recieve the trimmed text
getProps
A callback function which recieve the raw text, get the additional props, then return.
recheckMatch
A callback function which recieve the raw text to recheck if the raw text match the syntax token.
order
Now, you may use addRule
to custom your own syntax.
addRule({name,rule,view})
name
A string used to identify the rule.rule
A object introducing before to describe the custom syntax.view
A function which returns a React component matching your custom token.
Following is an example.
// add a block syntax
Markit.addRule.block({
name: "CustomHeading",
rule: {
tags: {
leading: /#{1,5} /,
exact: [/(?:\n|^).+?\n===+ */, /(?:\n|^).+? ?\n---+ */]
},
getProps: (raw) => {
let headingLevel: number
let hashHeadingMatch = raw.match(/^#+ /)
if (hashHeadingMatch) {
headingLevel = hashHeadingMatch![0].trim().length
} else {
let heading1Match = raw.match(/\n===+/)
headingLevel = !!heading1Match ? 1 : 2
}
return {headingLevel}
},
trimText: raw => raw.replaceAll(/\n((===+)|(---+))/g, "").replaceAll(/^#{1,5} /g, ""),
parseContent: text => text,
recheckMatch: raw => {
return true
},
blockType: "leaf"
},
view: (content: any, {headingLevel, blockProp}) =>
Span(content+(!!blockProp ? blockProp.a:"")).fontSize(`${(5 - (headingLevel ?? 1)) * 6 + 15}px`)
})
// add a inline syntax
Markit.addRule.inline({
name: "Italic",
rule: {
tags: {
round: "[em]",
exact: [
/\*(?!\s)(?:(?:[^*]*?(?:\*\*[^*]+?\*\*[^*]*?)+?)+?|[^*]+)\*/,
]
},
trimText: (text: string) => text.replace(/^\*|\*$/g, ""),
},
// view: (content) => ()
})
you may use dropRule
to remove one of the syntax rule.
// remove a block syntax rule
Markit.dropRule.block(["Heading"])
// remove a inline syntax rule
Markit.dropRule.inline(["Italic"])
Advanced
MarkitView
API
Markit
API
| function | description | parameter | |------------------------------------|-----------|----------| | init | to certain props init a Markit | object | | parse | return a markdonwerTree array | string | Usage
import { Markit } from '@iandx/markit'
Markit.init({softBreak: false})
const markitASTs = Markit.parse('## Markit **fast** ')
MarkdonwerTree
Markit.parse will parse the text iteratively where there is a markdown syntax. We design a tree to contain the parsed result called MarkdonwerTrees.
Note: The type of leaf node must be "Text" or "Heading"
The node of MarkdonwerTree has the following properties.
| properties | description | type | value | |------------|---------------------------------------------------------|--------|-----------------| | content | its children which are also the markdownTrees or string | | | | id | block id | | | | level | block level or inline level | string | "block"/"inline" | | props | additional properties | object | | | raw | the text inclues markdown syntax | string | | | type | the markdown type. e.g."OrderedList", "Heading" | string | |