|
|
|
@ -219,66 +219,65 @@ func (d *document) DocumentLinks() ([]documentLink, error) {
|
|
|
|
|
lines := d.GetLines()
|
|
|
|
|
for lineIndex, line := range lines {
|
|
|
|
|
|
|
|
|
|
appendLink := func(href string, start, end int, hasTitle bool, isWikiLink bool) {
|
|
|
|
|
if href == "" {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Go regexes work with bytes, but the LSP client expects character indexes.
|
|
|
|
|
start = strutil.ByteIndexToRuneIndex(line, start)
|
|
|
|
|
end = strutil.ByteIndexToRuneIndex(line, end)
|
|
|
|
|
|
|
|
|
|
links = append(links, documentLink{
|
|
|
|
|
Href: href,
|
|
|
|
|
RelativeToDir: filepath.Dir(d.Path),
|
|
|
|
|
Range: protocol.Range{
|
|
|
|
|
Start: protocol.Position{
|
|
|
|
|
Line: protocol.UInteger(lineIndex),
|
|
|
|
|
Character: protocol.UInteger(start),
|
|
|
|
|
},
|
|
|
|
|
End: protocol.Position{
|
|
|
|
|
Line: protocol.UInteger(lineIndex),
|
|
|
|
|
Character: protocol.UInteger(end),
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
HasTitle: hasTitle,
|
|
|
|
|
IsWikiLink: isWikiLink,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Checks to ignore lines within code fences and indented code blocks
|
|
|
|
|
if insideFenced {
|
|
|
|
|
if fencedEndRegex.FindStringIndex(line) != nil &&
|
|
|
|
|
lines[currentCodeBlockStart][:3] == line[:3] {
|
|
|
|
|
// Fenced code block ending with this line
|
|
|
|
|
// Fenced code block ends with this line
|
|
|
|
|
insideFenced = false
|
|
|
|
|
currentCodeBlockStart = -1
|
|
|
|
|
}
|
|
|
|
|
// Within fenced code block, skip link checks
|
|
|
|
|
continue
|
|
|
|
|
} else if insideIndented {
|
|
|
|
|
if indentedRegex.FindStringIndex(line) == nil && len(line) > 0 {
|
|
|
|
|
// No longer indented, will process links
|
|
|
|
|
// Indeted code block ends with this line
|
|
|
|
|
insideIndented = false
|
|
|
|
|
currentCodeBlockStart = -1
|
|
|
|
|
} else {
|
|
|
|
|
// Still indented, skip link checks
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// Check whether we are in fenced / indented code check
|
|
|
|
|
// Check whether the current line is the start of a code fence or
|
|
|
|
|
// indented code block
|
|
|
|
|
if fencedStartRegex.FindStringIndex(line) != nil {
|
|
|
|
|
insideFenced = true
|
|
|
|
|
currentCodeBlockStart = lineIndex
|
|
|
|
|
continue
|
|
|
|
|
} else if indentedRegex.FindStringIndex(line) != nil &&
|
|
|
|
|
(lineIndex > 0 && len(lines[lineIndex-1]) == 0 || lineIndex == 0) {
|
|
|
|
|
// Indented code block starts on this line
|
|
|
|
|
insideIndented = true
|
|
|
|
|
currentCodeBlockStart = lineIndex
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
appendLink := func(href string, start, end int, hasTitle bool, isWikiLink bool) {
|
|
|
|
|
if href == "" {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Go regexes work with bytes, but the LSP client expects character indexes.
|
|
|
|
|
start = strutil.ByteIndexToRuneIndex(line, start)
|
|
|
|
|
end = strutil.ByteIndexToRuneIndex(line, end)
|
|
|
|
|
|
|
|
|
|
links = append(links, documentLink{
|
|
|
|
|
Href: href,
|
|
|
|
|
RelativeToDir: filepath.Dir(d.Path),
|
|
|
|
|
Range: protocol.Range{
|
|
|
|
|
Start: protocol.Position{
|
|
|
|
|
Line: protocol.UInteger(lineIndex),
|
|
|
|
|
Character: protocol.UInteger(start),
|
|
|
|
|
},
|
|
|
|
|
End: protocol.Position{
|
|
|
|
|
Line: protocol.UInteger(lineIndex),
|
|
|
|
|
Character: protocol.UInteger(end),
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
HasTitle: hasTitle,
|
|
|
|
|
IsWikiLink: isWikiLink,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// extract link paths from [title](path) patterns
|
|
|
|
|
// note: match[0:1] is the entire match, match[2:3] is the contents of
|
|
|
|
|
// brackets, match[4:5] is contents of parentheses
|
|
|
|
@ -321,7 +320,9 @@ func (d *document) DocumentLinks() ([]documentLink, error) {
|
|
|
|
|
hasTitle := match[4] != -1
|
|
|
|
|
appendLink(href, match[0], match[1], hasTitle, true)
|
|
|
|
|
}
|
|
|
|
|
if strings.Count(line, "`") % 2 == 1 {
|
|
|
|
|
// if there are an odd number of back ticks, the state of insideInline
|
|
|
|
|
// for the following link will be true
|
|
|
|
|
if strings.Count(line, "`")%2 == 1 {
|
|
|
|
|
insideInline = !insideInline
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|