首页
分类
记录
时间轴
lcnoob.cn

markdownIt源代码分析 等待伊始-lcnoob

lcnoob

markdownIt,源码,分析

markdownIt源代码分析

入口类:MarkdownIt

​ 实例属性:

​ 1,ParserInline类

​ 2,ParserBlock类

​ 3,ParserCore类

​ 4,Renderer类

​ 5,LinkifyIt模块(具有完全Unicode支持的链接识别库。专注于纯文本的高质量链接模式检测。)

​ 6,validateLink函数

​ 7,normalizeLink函数

​ 8,normalizeLinkText函数

​ 9,utils工具函数集

​ 10,helpers解析链接函数集

​ 11,options配置属性

​ 12,configure函数

​ 13,set函数

​ 14,enable函数

​ 15,disable函数

​ 16,use函数

​ 17,parse函数

​ 18,render函数

​ 19,parseInline函数

​ 20,renderInline函数

options配置属性

​ 默认配置:

配置路径(基于/lib下的相对路径)
./presets/default(在没有给出预设名称时会启用,(包括)所有可用的规则)
./presets/zero(所有的规则都被禁用)
./presets/commonmark(将解析器配置为严格的 CommonMark模式)
validateLink函数

​ 验证链接:parame:url:<u>string</u>,return:<u>boolean</u>

验证规则
/^(vbscript|javascript|file|data):/
/^data:image/(gif|png|jpeg|webp);/
normalizeLink函数

​ 1,markdown-it解析器的URL实用程序。(使用mdurl模块进行url解析)

​ 2,国际化域名编码。(使用punycode模块进行域名编码)

​ 标准化链接 :parame:url:<u>string</u>,return:<u>string</u>

configure函数

​ 1,MarkdownIt.set函数进行配置属性的合并。(默认配置参考config)

​ 2,启用规则

​ 对MarkdownIt进行配置:parame:presets: <u>object</u>,return:MarkdownIt

set函数

​ 合并解析器属性:parame:options:<u>object</u>,return:MarkdownIt

enable函数
  • list (String|Array) -- 要启用的规则名称或规则名称列表。
  • ignoreInvalid (Boolean) -- 设为 true 来忽略规则未发现时的错误。

​ 启用规则:parame:list:<u>array</u>, ignoreInvalid:<u>boolean</u>,return:MarkdownIt

disable函数
  • list (String|Array) -- 要禁用的规则名称或规则名称列表。
  • ignoreInvalid (Boolean) -- 设为 true 来忽略规则未发现时的错误。

​ 禁用规则:parame:list:<u>array</u>,ignoreInvalid:<u>boolean</u>,return MarkdownIt

use函数

​ 注入插件:parame:plugin:<u>function</u>,(arguments?),return:MarkdownIt

parse函数

​ 1,实例化Core类 => StateCore类

​ 2,通过Core.process函数对StateCore实例进行处理

​ 解析文档:parame:src:<u>string</u>,env:<u>object</u>,return:<u>array</u>(tokens流)

render函数

​ 1,通过MarkdownIt.parse函数解析文档

​ 2,通过renderer.render函数对解析后的文档进行渲染

​ 渲染文档:parame:src:<u>string</u>,env:<u>object</u>,return:<u>string</u>

parseInline函数

​ 1,实例化Core类 => StateCore类

​ 2,修改StateCore.inlineMode为True

​ 3,通过Core.process函数对StateCore实例进行处理

​ 解析内联元素:parame:src:<u>string</u>,env:<u>object</u>,return:<u>array</u>(tokens流)

renderInline函数

​ 1,通过MarkdownIt.parse函数解析文档

​ 2,通过renderer.render函数对解析后的文档进行渲染

​ 渲染内联文档:parame:src:<u>string</u>,env:<u>object</u>,return:<u>string</u>

helpers解析链接函数集

parseLinkLabel函数

​ 1,对链接进行解析,并记录光标当前位置

​ 解析链接标签:parame:state:<u>State类</u>,start:<u>number</u>,disableNested:<u>boolean</u>,return:<u>number</u>

parseLinkDestination函数

​ 1,初始化返回值({ok: 状态,pos:光标位置,str:链接目标,lines:路?})

​ 2,对链接目标进行解析,并返回记录链接目标相关信息对象

​ 解析链接目标:parame:str:<u>string</u>,pos:<u>number</u>, max:<u>number</u>,return:<u>object</u>

parseLinkTitle函数

​ 1,初始化返回值({ok: 状态,pos:光标位置,str:链接目标,lines:路?})

​ 2,对链接目标进行解析,并返回记录链接目标相关信息对象

​ 解析链接标题:parame:str:<u>string</u>,pos:<u>number</u>, max:<u>number</u>,return:<u>object</u>

utils工具函数集

_class函数

​ 判断参数类型:parame:obj:<u>any</u>,return:<u>string</u>

isString函数

​ 1,调用_class函数,并判断返回的结果是否为字符串类型

​ 参数是否为字符串类型:parame:obj:<u>any</u>,return:<u>boolean</u>

has函数

​ 1,借用Object.prototype.hasOwnProperty函数,判断属性是否存在于当前对象的自有属性上

​ 判断该自有属性是否存在:parame:object:<u>object</u>,key:<u>string</u>,return:<u>boolean</u>

assign函数

​ 1,通过arguments,进行兼容性的对象合并

​ 合并对象:parame:obj:<u>array|?</u>,(arguments),return:<u>object</u>

arrayReplaceAt函数

​ 1,在目标某个位置插入一段新的元素,并返回插入后的数组([].concat(src.slice(0, pos), newElements, src.slice(pos + 1)))

​ 合并数组:parame:src:<u>string</u>,pos:<u>number</u>,newElements:<u>string?</u>,return:<u>array</u>

isValidEntityCode函数

​ 是否为有效的实体(代码):parame:c:<u>hex(16进制的ascii)</u>,return:<u>boolean</u>

判断规则
0xD800~0xDFFF(无效字符)
0xFDD0~0xFDEF,0xFFFF,0xFFFE(无效字符)
0x00~0x08,0x0B,0x0E~0x1F,0x7F~0x9F(控制字符)
>0x10FFFF(未定义字符)
fromCodePoint函数

​ 1,对大于0xffff的字符进行处理,并返回由新代码点序列创建的字符串

​ 2,c -= 0x10000, surrogate1 = 0xd800 + (c >> 10) ,surrogate2 = 0xdc00 + (c & 0x3ff)

​ 返回使用指定的代码点序列创建的字符串:parame:c:<u>hex(16进制的ascii)</u>,return:<u>string</u>

replaceEntityPattern函数

​ 1,轻松编码和解码XML和HTML实体。(使用entities模块对文档进行解析)

​ 2,判断name是否为entities的自有属性,是则返回entities[name]

​ 3,判断name是否为**name.charCodeAt(0) === 0x23/ # / && /^#((?:x[a-f0-9]{1,8}|[0-9]{1,8}))/i.test(name)**,后按16进制或10进制解析,最后判断解析的code码是否为实体代码,是则返回

​ 4,返回match

​ 替换实体(代码):parame:match:<u>string?</u>,name:<u>string</u>,return:<u>string?</u>

unescapeMd函数

​ 1,str是否存在“\”,不存在则返回

​ 2,对str进行正则替换(**str.replace(/\([!"#$%&'()+,-./:;<=>?@[\]^_`{|}~])/g, '$1')***)

​ 替换指定字符:parame:str:<u>string</u>,return:<u>string</u>

unescapeAll函数

​ 1,str是否存在“\” 且 '&',都不存在则返回

​ 2,对str进行正则替换(**str.replace(/\([!"#$%&'()+,-./:;<=>?@[\]^_`{|}~])|&([a-z#][a-z0-9]{1,31});/gi, fn)***)

​ 3,**function fn (match, escaped, entity) { **
​ if (escaped) { return escaped; }
​ return replaceEntityPattern(match, entity);
​ }

​ 替换指定字符:parame:str:<u>string</u>,return:<u>string</u>

replaceUnsafeChar函数

​ 1,默认不安全字符(&,<,>,")

​ 替换不安全的字符:parame:ch:<u>string</u>,return:<u>string</u>

escapeHtml函数

​ 1,判断**/[&<>"]/.test(str)**,为否则不进行转义

​ 2,对str进行正则替换(***str.replace(/[&<>"]/g, replaceUnsafeChar)***)

​ 转义html实体:parame:str:<u>string</u>*,return:<u>string</u>

escapeRE函数

​ 1,对str进行正则替换(**str.replace(/[.?+^$[]\(){}|-]/g, '\$&')***),并返回

​ 转义re实体:parame:str:<u>string</u>,return:<u>string</u>

isSpace函数

​ 1,空字符:0x09,0x20

​ 是否为"空字符":parame:code:<u>hex(16进制的ascii)</u>,return:<u>boolean</u>

isWhiteSpace函数

​ 是否为空白字符:parame:code:<u>hex(16进制的ascii)</u>,return:<u>boolean</u>

空白字符
0x09~0x0D,0x20,0xA0,0x1680,0x202F,0x205F,0x3000
isPunctChar函数

​ 1,markdown-it项目的unicode数据文件的微型子集。(使用uc.micro模块的正则)

​ 未定义的字符:parame:ch:<u>string</u>,return:<u>boolean</u>

isMdAsciiPunct函数

​ Markdown ASCII标点符号:parame:ch:<u>hex(16进制的ascii)</u>,return:<u>boolean</u>

Markdown ASCII标点符号
0x21~0x2F,0x3A~0x40,0x5B~0x60,0x7B~0x7E
normalizeReference函数

​ 1,去除str两端空格,使用正则替换空白字符为空格

​ 2,**'ẞ'与'Ṿ'**的标准化

​ 标准化参考:parame:str:<u>string</u>,return:<u>string</u>

lib对象

​ mdurl:markdown-it解析器的URL实用程序。

​ ucmicro:markdown-it项目的unicode数据文件的微型子集。

解析内联:ParserInline类

​ 实例属性:

​ Ruler类

​ ruler(实例化Ruler类)

​ ruler2(实例化Ruler类)

​ skipToken函数

​ tokenize函数

​ parse函数

​ State类

默认ruler与ruler2:

ruler默认规则 ruler2默认规则
[ 'text', require('./rules_inline/text') ], [ 'balance_pairs', require('./rules_inline/balance_pairs') ],
[ 'newline', require('./rules_inline/newline') ], [ 'strikethrough', require('./rules_inline/strikethrough').postProcess ],
[ 'escape', require('./rules_inline/escape') ], [ 'emphasis', require('./rules_inline/emphasis').postProcess ],
[ 'backticks', require('./rules_inline/backticks') ], [ 'text_collapse', require('./rules_inline/text_collapse') ]
[ 'strikethrough', require('./rules_inline/strikethrough').tokenize ],
[ 'emphasis', require('./rules_inline/emphasis').tokenize ],
[ 'link', require('./rules_inline/link') ],
[ 'image', require('./rules_inline/image') ],
[ 'autolink', require('./rules_inline/autolink') ],
[ 'html_inline', require('./rules_inline/html_inline') ],
[ 'entity', require('./rules_inline/entity') ]
skipToken函数

​ 1,获取rules规则,获取md文档的最大嵌套层

​ 2,判断是否存在缓存,存在返回缓存

​ 3,判断当前层级 **< ** 最大嵌套层,不满足,state.pos = state.posMax

​ 4,循环对state使用规则进行解析

​ 5,根据条件对结果进行缓存

​ 跳过token流:parame:State类,return:<u>undefined</u>

tokenize函数

​ 1,获取rules规则,获取md文档的最大嵌套层

​ 2,循环判断state.pos < state.posMax,满足

​ 3,判断当前层级 **< **最大嵌套层,满足

​ 4,循环对state使用规则进行解析

​ 5,根据使用规则解析后的结果,来判断是否结束循环

​ 6,根据条件执行state.pushPending函数

​ 生成输入范围的token流:parame:State类,return:<u>undefined</u>

parse函数

​ 1,实例化State类

​ 2,使用tokemize函数解析State类

​ 3,获取rules规则,循环对state使用规则进行解析

​ 解析内联文档:parame:str:<u>string</u>,md:Markdown实例,env:<u>object</u>,outTokens:<u>array</u>,return:<u>undefined</u>

解析块级:ParserBlock类

​ 实例属性:

​ Ruler类

​ tokenize函数

​ parse函数

​ State类

默认rules:

rules默认规则
[ 'table', require('./rules_block/table'), [ 'paragraph', 'reference' ] ],
[ 'code', require('./rules_block/code') ],
[ 'fence', require('./rules_block/fence'), [ 'paragraph', 'reference', 'blockquote', 'list' ] ],
[ 'blockquote', require('./rules_block/blockquote'), [ 'paragraph', 'reference', 'blockquote', 'list' ] ],
[ 'hr', require('./rules_block/hr'), [ 'paragraph', 'reference', 'blockquote', 'list' ] ],
[ 'list', require('./rules_block/list'), [ 'paragraph', 'reference', 'blockquote' ] ],
[ 'reference', require('./rules_block/reference') ],
[ 'heading', require('./rules_block/heading'), [ 'paragraph', 'reference', 'blockquote' ] ],
[ 'lheading', require('./rules_block/lheading') ],
[ 'html_block', require('./rules_block/html_block'), [ 'paragraph', 'reference', 'blockquote' ] ],
[ 'paragraph', require('./rules_block/paragraph') ]
parse函数

​ 1,实例化State类

​ 2,使用tokemize函数解析State类

​ 解析块级文档:parame:str:<u>string</u>,md:Markdown实例,env:<u>object</u>,outTokens:<u>array</u>,return:<u>undefined</u>

tokenize函数

​ 1,获取rules规则,获取md文档的最大嵌套层

​ 2,循环判断line < endLine,满足

​ 3,通过state.skipEmptyLines函数去掉空行

​ 4,判断光标是否到了文档结尾,判断是否满足嵌套调用的终止条件,否

​ 5,判断当前层级 >= 最大嵌套层,满足state.line = endLine

​ 6,循环对state使用规则进行解析,并根据返回的结果,判断是否跳出当前循环

​ 7,通过state.isEmpty函数判断是否在前一字符存在空行

​ 生成输入范围的token流:parame:State类,startLine:<u>number</u>,endLine:<u>number</u>,return:<u>undefined</u>

解析核心:ParserCore类

​ 实例属性:

​ Ruler类

​ process函数

​ State类

默认rules:

rules默认规则
[ 'normalize', require('./rules_core/normalize') ],
[ 'block', require('./rules_core/block') ],
[ 'inline', require('./rules_core/inline') ],
[ 'linkify', require('./rules_core/linkify') ],
[ 'replacements', require('./rules_core/replacements') ],
[ 'smartquotes', require('./rules_core/smartquotes') ]
process函数

​ 1,获取rules规则,循环对state使用规则进行解析

​ 解析state类:parame:state类,return:<u>undefined</u>

渲染类:Renderer类

​ 实例属性:

​ rules对象

​ renderAttrs函数

​ renderToken函数

​ renderInline函数

​ renderInlineAsText函数

​ render函数

默认rules对象:

code_inline函数

​ 内联code文档:parame:tokens:<u>array</u>,idx:<u>string</u>,options:<u>object</u>,env:<u>object</u>,slf:Renderer实例,return:<u>string</u>

code_block函数

​ 块级code文档:parame:tokens:<u>array</u>,idx:<u>string</u>,options:<u>object</u>,env:<u>object</u>,slf:Renderer实例,return:<u>string</u>

fence函数

​ 1,获取相关信息state.info(标签属性)

​ 2,判断是否存在info,存在langName = info.split(/\s+/g)[0]

​ 3,判断options配置属性中是否存在highlight函数,存在,根据返回结果来自适应调用哪种解析函数,不存在,调用默认escapeHtml函数

​ 4,判断解析后结果中是否存在"<pre",存在加上换行符"\n",返回

​ 5,判断是否存在info,存在,解析出标签属性,并设置

​ 围栏(转义code区域):parame:tokens:<u>array</u>,idx:<u>string</u>,options:<u>object</u>,env:<u>object</u>,slf:Renderer实例,return:<u>string</u>

image函数

​ 1,通过Renderer.renderInlineAsText函数渲染imgage标签

​ 2,通过Renderer.renderToken函数处理要渲染的imgage标签,并返回处理后的结果

​ 渲染imgage标签:parame:tokens:<u>array</u>,idx:<u>string</u>,options:<u>object</u>,env:<u>object</u>,slf:Renderer实例,return:<u>string</u>

hardbreak函数

​ 1,根据optios.xhtmlOut配置来兼容不同换行标签

​ 兼容不同换行标签:parame:tokens:<u>array</u>,idx:<u>string</u>,options:<u>object</u>,return:<u>string</u>

softbreak函数

​ 1,根据options.breaks与optios.xhtmlOut配置来兼容不同换行标签

​ 兼容不同换行标签:parame:tokens:<u>array</u>,idx:<u>string</u>,options:<u>object</u>,return:<u>string</u>

text函数

​ 转义html:parame:tokens:<u>array</u>,idx:<u>string</u>,return:<u>string</u>

html_block函数

​ 返回块级文档:parame:tokens:<u>array</u>,idx:<u>string</u>,return:<u>string</u>

html_inline函数

​ 返回内联文档:parame:tokens:<u>array</u>,idx:<u>string</u>,return:<u>string</u>

renderAttrs函数

​ 1,通过escapeHtml函数对文档进行转义

​ 渲染标签中的属性:parame:token:<u>array</u>,return:<u>string</u>

renderToken函数

​ 1,根据条件进行渲染,最后返回

​ 渲染token流:parame:tokens:<u>array</u>,idx:<u>string</u>,return:<u>string</u>

renderInline函数

​ 1,循环tokens流,同时判断是否存在rules规则,不存在,调用Renderer.renderToken函数处理要渲染tokens流,存在,调用相关的rules规则进行渲染,最后返回渲染的文档

​ 渲染内联文档:parame:tokens:<u>array</u>,idx:<u>string</u>,return:<u>string</u>

renderInlineAsText函数

​ 1,循环tokens流,同时判断token的类型,如果token的类型为image,那么通过递归来渲染出它的Text内容,最后返回渲染后的文档

​ 渲染内联文档(包括image):parame:tokens:<u>array</u>,idx:<u>string</u>,options:<u>object</u>,return:<u>string</u>

render函数

​ 1,循环tokens流,同时判断token的类型,根据不同类型进行不同的处理,最后返回渲染的文档

​ 渲染文档:parame:tokens:<u>array</u>,idx:<u>string</u>,options:<u>object</u>,return:<u>string</u>

规则类:Ruler类

​ 实例属性:

​ __rules__对象

​ __cache__对象

​ __find__ 函数

​ __compile__函数

​ at函数

​ before函数

​ after函数

​ push函数

​ enable函数

​ enableOnly函数

​ disable函数

​ getRules函数

__find__ 函数

​ 1,遍历__rules__对象,查询与之对应的规则,并返回其索引,否则返回-1

​ 查询是否有此规则:parame:name:<u>string</u>,return:<u>number</u>

__compile__函数

​ 1,遍历**Ruler.__rules__**对象,(待续)

​ 编译规则:parame:<u>undefined</u>,return:<u>undefined</u>

at函数

​ 1,调用Ruler.__find__函数,传入name,查询是存在此规则,存在

​ 2,用fn,对此规则的功能进行替换

​ 替换已有规则的功能:parame:name:<u>string</u>,fn:<u>function</u>,options:<u>object</u>,return:<u>number</u>

before函数

​ 1,调用Ruler.__find__函数,传入beforeName,查询是存在此规则,存在

​ 2,则在**Ruler.__rules__**对象最前面添加新规则

​ 3,{

		**name: ruleName,**

		**enabled: true,**

		**fn: fn,**

		**alt: opt.alt || []**

	**}**

​ *在**Ruler.__rules__*对象最前面添加新规则:parame:beforeName:<u>string</u>,ruleName:<u>string</u>,fn:<u>function</u>,options:<u>object</u>,return:<u>undefined</u>

after函数

​ 1,调用**Ruler.__find__**函数,传入afterName,查询是存在此规则,存在

​ 2,则在**Ruler.__rules__**对象最后面添加新规则

​ 3,{

		**name: ruleName,**

		**enabled: true,**

		**fn: fn,**

		**alt: opt.alt || []**

	**}**

​ *在**Ruler.__rules__*对象最后面添加新规则:parame:beforeName:<u>string</u>,ruleName:<u>string</u>,fn:<u>function</u>,options:<u>object</u>,return:<u>undefined</u>

push函数

​ 1,则在**Ruler.__rules__**对象末端添加新规则

​ 3,{

		**name: ruleName,**

		**enabled: true,**

		**fn: fn,**

		**alt: opt.alt || []**

	**}**

​ *在**Ruler.__rules__*对象末端添加新规则:parame:ruleName:<u>string</u>,fn:<u>function</u>,options:<u>object</u>,return:<u>undefined</u>

enable函数

​ 0,传入ignoreInvalid:true,可以禁止报错

​ 1,遍历list,调用**Ruler.__find__**函数,传入afterName,查询是存在此规则,存在

​ 2,则启用此规则,并把规则名称放入result对象里,最后返回

​ 启用规则:parame:list:<u>array</u>,ignoreInvalid:<u>boolean</u>,return:<u>array</u>

disable函数

​ 0,传入ignoreInvalid:true,可以禁止报错

​ 1,遍历list,调用**Ruler.__find__**函数,传入afterName,查询是存在此规则,存在

​ 2,则禁用此规则,并把规则名称放入result对象里,最后返回

​ 禁用规则:parame:list:<u>array</u>,ignoreInvalid:<u>boolean</u>,return:<u>array</u>

enableOnly函数

​ 1,先禁用所有规则

​ 2,调用Ruler.enable函数,启用传入list中的规则

​ 仅启用传入的规则:parame:list:<u>array</u>,ignoreInvalid:<u>boolean</u>,return:<u>array</u>

getRules函数

​ 1,如果this.cache ==== null,则调用**Ruler.__compile__**函数,编译规则

​ 2,返回chainName指定的规则

​ 获取规则:parame:chainName:<u>string</u>,return:<u>array</u>

核心状态类:StateCore类

​ 实例属性:

​ src

​ env

​ md(Markdown实例)

​ tokens对象

​ inlineMode(是否为内联模式)

​ Token类

Token流类:Token类

​ 实例属性:

​ type

​ tag

​ attrs

​ map

​ nesting

​ level

​ children

​ content

​ markup

​ info

​ meta

​ block

​ hidden

​ attrIndex函数

​ attrPush函数

​ attrSet函数

​ attrGet函数

​ attrJoin函数

attrs

​ html属性:格式:[ [ name1, value1 ], [ name2, value2 ] ]

block

​ 渲染时用于计算换行:对于块级 token 来说为 true,对于 inline 令牌来说为 false

children

​ 字节点:内联和图片 token

content

​ 标签的内容

hidden

​ 隐藏段落:如果设为 true,渲染时会忽略这个元素

info

​ 围栏(代码块)信息字符串

level

​ 嵌套级别

map

​ 源映射信息:格式:[ line_begin, line_end ]

markup

​ '*' 或 '_' (形式)的强调

meta

​ 一个给插件用于存储任意数据的地方

nesting

​ 级别变化(-1, 0, 1):

  • 1 意味着标签打开。
  • 0 意味着标签是自动关闭的。
  • -1 意味着标签正在关闭。
tag

​ html标签名

type

​ token的类型

attrIndex函数

​ 按名称搜索属性索引:parame:<u>string</u>,return:<u>number</u>

attrPush函数

​ 将 [ name, value ] 的属性添加到列表中:parame:attrData:<u>array</u>,return:<u>undefined</u>

attrSet函数

​ 将 name 属性设置为 value,如果(旧值)存在,则重写旧值:parame:name:<u>string</u>,value:<u>any</u>,return:<u>undefined</u>

attrGet函数

​ 获取属性 name 的值,如果不存在,则为 null:parame:name:<u>string</u>,return:<u>string | null</u>

attrJoin函数

​ 通过间隔将值添加到现有属性中(或创建新属性):parame:name:<u>string</u>,value:<u>any</u>,return:<u>undefined</u>

入口类:MarkdownIt

helpers解析链接函数集

utils工具函数集

解析内联:ParserInline类

解析块级:ParserBlock类

解析核心:ParserCore类

渲染类:Renderer类

规则类:Ruler类

核心状态类:StateCore类

Token流类:Token类

蜀ICP备19019069号-1

beian

川公网安备51068102510801号