Skip to content

Commit

Permalink
✨ JS 端支持自定义普通 HTML 渲染 #5
Browse files Browse the repository at this point in the history
  • Loading branch information
88250 committed Feb 13, 2020
1 parent 660121c commit 0727f7e
Show file tree
Hide file tree
Showing 41 changed files with 498 additions and 520 deletions.
48 changes: 24 additions & 24 deletions auto_link.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ import (
)

func (t *Tree) parseGFMAutoEmailLink(node *Node) {
for child := node.firstChild; nil != child; {
next := child.next
if NodeText == child.Typ && nil != child.parent &&
NodeLink != child.parent.Typ /* 不处理链接 label */ {
for child := node.FirstChild; nil != child; {
next := child.Next
if NodeText == child.Typ && nil != child.Parent &&
NodeLink != child.Parent.Typ /* 不处理链接 label */ {
t.parseGFMAutoEmailLink0(child)
} else {
t.parseGFMAutoEmailLink(child) // 递归处理子节点
Expand All @@ -31,8 +31,8 @@ func (t *Tree) parseGFMAutoEmailLink(node *Node) {
}

func (t *Tree) parseGFMAutoLink(node *Node) {
for child := node.firstChild; nil != child; {
next := child.next
for child := node.FirstChild; nil != child; {
next := child.Next
if NodeText == child.Typ {
t.parseGFMAutoLink0(child)
} else {
Expand All @@ -45,7 +45,7 @@ func (t *Tree) parseGFMAutoLink(node *Node) {
var mailto = strToBytes("mailto:")

func (t *Tree) parseGFMAutoEmailLink0(node *Node) {
tokens := node.tokens
tokens := node.Tokens
if 0 >= bytes.IndexByte(tokens, '@') {
return
}
Expand Down Expand Up @@ -76,7 +76,7 @@ loopPart:
}
if i == j {
// 说明积攒组时第一个字符就是空白符,那就把这个空白符作为一个文本节点插到前面
text := &Node{Typ: NodeText, tokens: []byte{tokens[j]}}
text := &Node{Typ: NodeText, Tokens: []byte{tokens[j]}}
node.InsertBefore(text)
i++
continue
Expand All @@ -86,7 +86,7 @@ loopPart:
i = j

if 0 >= atIndex {
text := &Node{Typ: NodeText, tokens: group}
text := &Node{Typ: NodeText, Tokens: group}
node.InsertBefore(text)
continue
}
Expand All @@ -97,7 +97,7 @@ loopPart:
for ; k < atIndex; k++ {
token = group[k]
if !t.isValidEmailSegment1(token) {
text := &Node{Typ: NodeText, tokens: group}
text := &Node{Typ: NodeText, Tokens: group}
node.InsertBefore(text)
continue loopPart
}
Expand All @@ -109,7 +109,7 @@ loopPart:
item = group[k]
token = group[k]
if !t.isValidEmailSegment2(token) {
text := &Node{Typ: NodeText, tokens: group}
text := &Node{Typ: NodeText, Tokens: group}
node.InsertBefore(text)
continue loopPart
}
Expand All @@ -122,18 +122,18 @@ loopPart:
link := t.newLink(NodeLink, group, append(mailto, group...), nil, 2)
node.InsertBefore(link)
// . 作为文本节点插入
node.InsertBefore(&Node{Typ: NodeText, tokens: []byte{item}})
node.InsertBefore(&Node{Typ: NodeText, Tokens: []byte{item}})
} else if itemHyphen == token || itemUnderscore == token {
// 如果以 - 或者 _ 结尾则整个串都不能算作邮件链接
text := &Node{Typ: NodeText, tokens: group}
text := &Node{Typ: NodeText, Tokens: group}
node.InsertBefore(text)
continue loopPart
} else {
// 以字母或者数字结尾
link := &Node{Typ: NodeLink, linkType: 2}
text := &Node{Typ: NodeLinkText, tokens: group}
text := &Node{Typ: NodeLinkText, Tokens: group}
link.AppendChild(text)
dest := &Node{Typ: NodeLinkDest, tokens: append(mailto, group...)}
dest := &Node{Typ: NodeLinkDest, Tokens: append(mailto, group...)}
link.AppendChild(dest)
node.InsertBefore(link)
}
Expand Down Expand Up @@ -168,7 +168,7 @@ func (lute *Lute) AddAutoLinkDomainSuffix(suffix string) {
}

func (t *Tree) parseGFMAutoLink0(node *Node) {
tokens := node.tokens
tokens := node.Tokens
length := len(tokens)
minLinkLen := 10 // 太短的情况肯定不可能有链接,最短的情况是 www.xxx.xx
if minLinkLen > length {
Expand Down Expand Up @@ -203,9 +203,9 @@ func (t *Tree) parseGFMAutoLink0(node *Node) {
if length-i < minLinkLen { // 剩余字符不足,已经不可能形成链接了
if needUnlink {
if textStart < textEnd {
node.InsertBefore(&Node{Typ: NodeText, tokens: tokens[textStart:]})
node.InsertBefore(&Node{Typ: NodeText, Tokens: tokens[textStart:]})
} else {
node.InsertBefore(&Node{Typ: NodeText, tokens: tokens[textEnd:]})
node.InsertBefore(&Node{Typ: NodeText, Tokens: tokens[textEnd:]})
}
node.Unlink()
}
Expand All @@ -216,7 +216,7 @@ func (t *Tree) parseGFMAutoLink0(node *Node) {
}

if textStart < textEnd {
node.InsertBefore(&Node{Typ: NodeText, tokens: tokens[textStart:textEnd]})
node.InsertBefore(&Node{Typ: NodeText, Tokens: tokens[textStart:textEnd]})
needUnlink = true
textStart = textEnd
}
Expand Down Expand Up @@ -264,7 +264,7 @@ func (t *Tree) parseGFMAutoLink0(node *Node) {
}
domain := url[:k]
if !t.isValidDomain(domain) {
node.InsertBefore(&Node{Typ: NodeText, tokens: tokens[textStart:i]})
node.InsertBefore(&Node{Typ: NodeText, Tokens: tokens[textStart:i]})
needUnlink = true
textStart = i
textEnd = i
Expand Down Expand Up @@ -372,7 +372,7 @@ func (t *Tree) parseGFMAutoLink0(node *Node) {
}

if textStart < textEnd {
text := &Node{Typ: NodeText, tokens: tokens[textStart:textEnd]}
text := &Node{Typ: NodeText, Tokens: tokens[textStart:textEnd]}
node.InsertBefore(text)
needUnlink = true
}
Expand Down Expand Up @@ -490,12 +490,12 @@ func (t *Tree) newLink(typ NodeType, text, dest, title []byte, linkType int) (re
ret.AppendChild(&Node{Typ: NodeBang})
}
ret.AppendChild(&Node{Typ: NodeOpenBracket})
ret.AppendChild(&Node{Typ: NodeLinkText, tokens: text})
ret.AppendChild(&Node{Typ: NodeLinkText, Tokens: text})
ret.AppendChild(&Node{Typ: NodeCloseBracket})
ret.AppendChild(&Node{Typ: NodeOpenParen})
ret.AppendChild(&Node{Typ: NodeLinkDest, tokens: dest})
ret.AppendChild(&Node{Typ: NodeLinkDest, Tokens: dest})
if nil != title {
ret.AppendChild(&Node{Typ: NodeLinkTitle, tokens: title})
ret.AppendChild(&Node{Typ: NodeLinkTitle, Tokens: title})
}
ret.AppendChild(&Node{Typ: NodeCloseParen})
return
Expand Down
40 changes: 20 additions & 20 deletions blocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ func (t *Tree) incorporateLine(line []byte) {
allMatched := true
var container *Node
container = t.Root
lastChild := container.lastChild
for ; nil != lastChild && !lastChild.close; lastChild = container.lastChild {
lastChild := container.LastChild
for ; nil != lastChild && !lastChild.close; lastChild = container.LastChild {
container = lastChild
t.context.findNextNonspace()

Expand All @@ -70,7 +70,7 @@ func (t *Tree) incorporateLine(line []byte) {
}

if !allMatched {
container = container.parent // 回到上一个匹配的块
container = container.Parent // 回到上一个匹配的块
break
}
}
Expand Down Expand Up @@ -133,8 +133,8 @@ func (t *Tree) incorporateLine(line []byte) {
// 最终化未匹配的块
t.context.closeUnmatchedBlocks()

if t.context.blank && nil != container.lastChild {
container.lastChild.lastLineBlank = true
if t.context.blank && nil != container.LastChild {
container.LastChild.lastLineBlank = true
}

typ := container.Typ
Expand All @@ -146,10 +146,10 @@ func (t *Tree) incorporateLine(line []byte) {
typ == NodeBlockquote || // 块引用行肯定不会是空行因为至少有一个 >
(typ == NodeCodeBlock && isFenced) || // 围栏代码块不计入空行判断
(typ == NodeMathBlock) || // 数学公式块不计入空行判断
(typ == NodeListItem && nil == container.firstChild)) // 内容为空的列表项也不计入空行判断
(typ == NodeListItem && nil == container.FirstChild)) // 内容为空的列表项也不计入空行判断
// 因为列表是块级容器(可进行嵌套),所以需要在父节点方向上传播 lastLineBlank
// lastLineBlank 目前仅在判断列表紧凑模式上使用
for cont := container; nil != cont; cont = cont.parent {
for cont := container; nil != cont; cont = cont.Parent {
cont.lastLineBlank = lastLineBlank
}

Expand Down Expand Up @@ -223,7 +223,7 @@ var blockStarts = []blockStartFunc{
t.context.closeUnmatchedBlocks()
t.context.advanceOffset(len(label)+2, true)
footnotesDef := t.context.addChild(NodeFootnotesDef, t.context.nextNonspace)
footnotesDef.tokens = label
footnotesDef.Tokens = label
lowerCaseLabel := bytes.ToLower(label)
if _, def := t.context.findFootnotesDef(lowerCaseLabel); nil == def {
t.context.footnotesDefs = append(t.context.footnotesDefs, footnotesDef)
Expand Down Expand Up @@ -274,8 +274,8 @@ var blockStarts = []blockStartFunc{
t.context.closeUnmatchedBlocks()
heading := t.context.addChild(NodeHeading, t.context.nextNonspace)
heading.headingLevel = level
heading.tokens = content
crosshatchMarker := &Node{Typ: NodeHeadingC8hMarker, tokens: markers}
heading.Tokens = content
crosshatchMarker := &Node{Typ: NodeHeadingC8hMarker, Tokens: markers}
heading.AppendChild(crosshatchMarker)
t.context.advanceOffset(t.context.currentLineLen-t.context.offset, false)
return 2
Expand Down Expand Up @@ -322,29 +322,29 @@ var blockStarts = []blockStartFunc{
// 将该段落节点转成表节点
container.Typ = NodeTable
container.tableAligns = table.tableAligns
for tr := table.firstChild; nil != tr; {
nextTr := tr.next
for tr := table.FirstChild; nil != tr; {
nextTr := tr.Next
container.AppendChild(tr)
tr = nextTr
}
container.tokens = nil
container.Tokens = nil
return 0
}
}

t.context.closeUnmatchedBlocks()
// 解析链接引用定义
for tokens := container.tokens; 0 < len(tokens) && itemOpenBracket == tokens[0]; tokens = container.tokens {
for tokens := container.Tokens; 0 < len(tokens) && itemOpenBracket == tokens[0]; tokens = container.Tokens {
if remains := t.context.parseLinkRefDef(tokens); nil != remains {
container.tokens = remains
container.Tokens = remains
} else {
break
}
}

if value := container.tokens; 0 < len(value) {
if value := container.Tokens; 0 < len(value) {
child := &Node{Typ: NodeHeading, headingLevel: level}
child.tokens = trimWhitespace(value)
child.Tokens = trimWhitespace(value)
container.InsertAfter(child)
container.Unlink()
t.context.tip = child
Expand Down Expand Up @@ -376,7 +376,7 @@ var blockStarts = []blockStartFunc{
if ok, markers := t.parseThematicBreak(); ok {
t.context.closeUnmatchedBlocks()
thematicBreak := t.context.addChild(NodeThematicBreak, t.context.nextNonspace)
thematicBreak.tokens = markers
thematicBreak.Tokens = markers
t.context.advanceOffset(t.context.currentLineLen-t.context.offset, false)
return 2
}
Expand All @@ -401,10 +401,10 @@ var blockStarts = []blockStartFunc{
}
listItem := t.context.addChild(NodeListItem, t.context.nextNonspace)
listItem.listData = data
listItem.tokens = data.marker
listItem.Tokens = data.marker
if 1 == listItem.listData.typ || (3 == listItem.listData.typ && 0 == listItem.listData.bulletChar) {
// 修正有序列表项序号
prev := listItem.previous
prev := listItem.Previous
if nil != prev {
listItem.num = prev.num + 1
} else {
Expand Down
4 changes: 2 additions & 2 deletions chinese_punct.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ import (

// chinesePunct 会把文本节点 textNode 中的中文间的英文标点换成对应的中文标点。
func (r *BaseRenderer) chinesePunct(textNode *Node) {
text := bytesToStr(textNode.tokens)
text := bytesToStr(textNode.Tokens)
text = chinesePunct0(text)
textNode.tokens = strToBytes(text)
textNode.Tokens = strToBytes(text)
}

func chinesePunct0(text string) (ret string) {
Expand Down
6 changes: 3 additions & 3 deletions code_block.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func (codeBlock *Node) codeBlockContinue(context *Context) int {

func (codeBlock *Node) codeBlockFinalize(context *Context) {
if codeBlock.isFencedCodeBlock {
content := codeBlock.tokens
content := codeBlock.Tokens
length := len(content)
if 1 > length {
return
Expand All @@ -61,9 +61,9 @@ func (codeBlock *Node) codeBlockFinalize(context *Context) {
break
}
}
codeBlock.tokens = content[i+1:]
codeBlock.Tokens = content[i+1:]
} else { // 缩进代码块
codeBlock.tokens = replaceNewlineSpace(codeBlock.tokens)
codeBlock.Tokens = replaceNewlineSpace(codeBlock.Tokens)
}
}

Expand Down
8 changes: 4 additions & 4 deletions code_block_html_renderer.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func (r *HTMLRenderer) renderCodeBlock(node *Node, entering bool) (WalkStatus, e
// 缩进代码块处理
r.newline()
rendered := false
tokens := node.firstChild.tokens
tokens := node.FirstChild.Tokens
if r.option.CodeSyntaxHighlight {
rendered = highlightChroma(tokens, "", r)
if !rendered {
Expand All @@ -56,9 +56,9 @@ func (r *HTMLRenderer) renderCodeBlock(node *Node, entering bool) (WalkStatus, e
// renderCodeBlockCode 进行代码块 HTML 渲染,实现语法高亮。
func (r *HTMLRenderer) renderCodeBlockCode(node *Node, entering bool) (WalkStatus, error) {
if entering {
tokens := node.tokens
if 0 < len(node.previous.codeBlockInfo) {
infoWords := split(node.previous.codeBlockInfo, itemSpace)
tokens := node.Tokens
if 0 < len(node.Previous.codeBlockInfo) {
infoWords := split(node.Previous.codeBlockInfo, itemSpace)
language := bytesToStr(infoWords[0])
rendered := false
if isGo(language) {
Expand Down
8 changes: 4 additions & 4 deletions code_block_html_rendererjs.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func (r *HTMLRenderer) renderCodeBlock(node *Node, entering bool) (WalkStatus, e
// 缩进代码块处理
r.newline()
r.writeString("<pre><code>")
r.write(escapeHTML(node.firstChild.tokens))
r.write(escapeHTML(node.FirstChild.Tokens))
r.writeString("</code></pre>")
r.newline()
return WalkStop, nil
Expand All @@ -32,9 +32,9 @@ func (r *HTMLRenderer) renderCodeBlock(node *Node, entering bool) (WalkStatus, e
func (r *HTMLRenderer) renderCodeBlockCode(node *Node, entering bool) (WalkStatus, error) {
if entering {
r.newline()
tokens := node.tokens
if 0 < len(node.previous.codeBlockInfo) {
infoWords := split(node.previous.codeBlockInfo, itemSpace)
tokens := node.Tokens
if 0 < len(node.Previous.codeBlockInfo) {
infoWords := split(node.Previous.codeBlockInfo, itemSpace)
language := infoWords[0]
r.writeString("<pre><code class=\"language-")
r.write(language)
Expand Down
Loading

0 comments on commit 0727f7e

Please sign in to comment.