Expose range information for markdown text nodes [WIP] (#9067)

* Track positions of markdown text

* Add tests for markdown text ranges
Этот коммит содержится в:
Adrian
2018-07-11 18:12:46 +02:00
коммит произвёл Harrison Healey
родитель 06abe98ba9
Коммит e135cc99e1
2 изменённых файлов: 147 добавлений и 14 удалений

Просмотреть файл

@@ -21,7 +21,8 @@ func (inlineBase) IsInline() bool { return true }
type Text struct {
inlineBase
Text string
Text string
Range Range
}
type CodeSpan struct {
@@ -141,8 +142,10 @@ func (p *inlineParser) parseBackticks() {
return
}
p.position += len(opening)
absPos := relativeToAbsolutePosition(p.ranges, p.position-len(opening))
p.inlines = append(p.inlines, &Text{
Text: opening,
Text: opening,
Range: Range{absPos, absPos + len(opening)},
})
}
@@ -162,13 +165,17 @@ func (p *inlineParser) parseLineEnding() {
func (p *inlineParser) parseEscapeCharacter() {
if p.position+1 < len(p.raw) && isEscapableByte(p.raw[p.position+1]) {
absPos := relativeToAbsolutePosition(p.ranges, p.position+1)
p.inlines = append(p.inlines, &Text{
Text: string(p.raw[p.position+1]),
Text: string(p.raw[p.position+1]),
Range: Range{absPos, absPos + len(string(p.raw[p.position+1]))},
})
p.position += 2
} else {
absPos := relativeToAbsolutePosition(p.ranges, p.position)
p.inlines = append(p.inlines, &Text{
Text: `\`,
Text: `\`,
Range: Range{absPos, absPos + 1},
})
p.position++
}
@@ -176,18 +183,24 @@ func (p *inlineParser) parseEscapeCharacter() {
func (p *inlineParser) parseText() {
if next := strings.IndexAny(p.raw[p.position:], "\r\n\\`&![]"); next == -1 {
absPos := relativeToAbsolutePosition(p.ranges, p.position)
p.inlines = append(p.inlines, &Text{
Text: strings.TrimRightFunc(p.raw[p.position:], isWhitespace),
Text: strings.TrimRightFunc(p.raw[p.position:], isWhitespace),
Range: Range{absPos, absPos + len(p.raw[p.position:])},
})
p.position = len(p.raw)
} else {
absPos := relativeToAbsolutePosition(p.ranges, p.position)
if p.raw[p.position+next] == '\r' || p.raw[p.position+next] == '\n' {
s := strings.TrimRightFunc(p.raw[p.position:p.position+next], isWhitespace)
p.inlines = append(p.inlines, &Text{
Text: strings.TrimRightFunc(p.raw[p.position:p.position+next], isWhitespace),
Text: s,
Range: Range{absPos, absPos + len(s)},
})
} else {
p.inlines = append(p.inlines, &Text{
Text: p.raw[p.position : p.position+next],
Text: p.raw[p.position : p.position+next],
Range: Range{absPos, absPos + next},
})
}
p.position += next
@@ -195,9 +208,11 @@ func (p *inlineParser) parseText() {
}
func (p *inlineParser) parseLinkOrImageDelimiter() {
absPos := relativeToAbsolutePosition(p.ranges, p.position)
if p.raw[p.position] == '[' {
p.inlines = append(p.inlines, &Text{
Text: "[",
Text: "[",
Range: Range{absPos, absPos + 1},
})
p.delimiterStack.PushBack(&delimiter{
Type: linkOpeningDelimiter,
@@ -207,7 +222,8 @@ func (p *inlineParser) parseLinkOrImageDelimiter() {
p.position++
} else if p.raw[p.position] == '!' && p.position+1 < len(p.raw) && p.raw[p.position+1] == '[' {
p.inlines = append(p.inlines, &Text{
Text: "![",
Text: "![",
Range: Range{absPos, absPos + 2},
})
p.delimiterStack.PushBack(&delimiter{
Type: imageOpeningDelimiter,
@@ -217,7 +233,8 @@ func (p *inlineParser) parseLinkOrImageDelimiter() {
p.position += 2
} else {
p.inlines = append(p.inlines, &Text{
Text: "!",
Text: "!",
Range: Range{absPos, absPos + 1},
})
p.position++
}
@@ -347,8 +364,10 @@ func (p *inlineParser) lookForLinkOrImage() {
break
}
}
absPos := relativeToAbsolutePosition(p.ranges, p.position)
p.inlines = append(p.inlines, &Text{
Text: "]",
Text: "]",
Range: Range{absPos, absPos + 1},
})
p.position++
}
@@ -403,19 +422,23 @@ func CharacterReference(ref string) string {
}
func (p *inlineParser) parseCharacterReference() {
absPos := relativeToAbsolutePosition(p.ranges, p.position)
p.position++
if semicolon := strings.IndexByte(p.raw[p.position:], ';'); semicolon == -1 {
p.inlines = append(p.inlines, &Text{
Text: "&",
Text: "&",
Range: Range{absPos, 1},
})
} else if s := CharacterReference(p.raw[p.position : p.position+semicolon]); s != "" {
p.position += semicolon + 1
p.inlines = append(p.inlines, &Text{
Text: s,
Text: s,
Range: Range{absPos, absPos + len(s)},
})
} else {
p.inlines = append(p.inlines, &Text{
Text: "&",
Text: "&",
Range: Range{absPos, 1},
})
}
}