Better doc search (#8260)
* Modified the doc generation to produce a custom data attribute to allow for better search functionality * Implemented fuzzy matching for the Nim Doc search instead of the simple regex match. * Fix to the WordBoundry state transition from code review with @Varriount. Also removed silly testing template that is no longer used. * Update fuzzysearch.nim * Update fuzzysearch.nim * Update fuzzysearch.nim * Update dochack.nim * Update dochack.nim
This commit is contained in:
parent
f92d61b1f4
commit
060871e64a
3 changed files with 167 additions and 20 deletions
|
|
@ -1,6 +1,5 @@
|
|||
|
||||
|
||||
import karax
|
||||
import fuzzysearch
|
||||
|
||||
proc findNodeWith(x: Element; tag, content: cstring): Element =
|
||||
if x.nodeName == tag and x.textContent == content:
|
||||
|
|
@ -88,11 +87,11 @@ proc toHtml(x: TocEntry; isRoot=false): Element =
|
|||
if ul.len != 0: result.add ul
|
||||
if result.len == 0: result = nil
|
||||
|
||||
proc containsWord(a, b: cstring): bool {.asmNoStackFrame.} =
|
||||
{.emit: """
|
||||
var escaped = `b`.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
|
||||
return new RegExp("\\b" + escaped + "\\b").test(`a`);
|
||||
""".}
|
||||
#proc containsWord(a, b: cstring): bool {.asmNoStackFrame.} =
|
||||
#{.emit: """
|
||||
#var escaped = `b`.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
|
||||
#return new RegExp("\\b" + escaped + "\\b").test(`a`);
|
||||
#""".}
|
||||
|
||||
proc isWhitespace(text: cstring): bool {.asmNoStackFrame.} =
|
||||
{.emit: """
|
||||
|
|
@ -252,24 +251,29 @@ proc dosearch(value: cstring): Element =
|
|||
|
||||
`stuff` = doc.documentElement;
|
||||
""".}
|
||||
db = stuff.getElementsByClass"reference external"
|
||||
db = stuff.getElementsByClass"reference"
|
||||
contents = @[]
|
||||
for ahref in db:
|
||||
contents.add ahref.textContent.normalize
|
||||
contents.add ahref.getAttribute("data-doc-search-tag")
|
||||
let ul = tree("UL")
|
||||
result = tree("DIV")
|
||||
result.setClass"search_results"
|
||||
var matches: seq[(Element, int)] = @[]
|
||||
let key = value.normalize
|
||||
for i in 0..<db.len:
|
||||
let c = contents[i]
|
||||
if c.containsWord(key):
|
||||
matches.add((db[i], -(30_000 - c.len)))
|
||||
elif c.contains(key):
|
||||
matches.add((db[i], c.len))
|
||||
if c == "Examples" or c == "PEG construction":
|
||||
# Some manual exclusions.
|
||||
# Ideally these should be fixed in the index to be more
|
||||
# descriptive of what they are.
|
||||
continue
|
||||
let (score, matched) = fuzzymatch(value, c)
|
||||
if matched:
|
||||
matches.add((db[i], score))
|
||||
|
||||
matches.sort do (a, b: auto) -> int:
|
||||
a[1] - b[1]
|
||||
for i in 0..min(<matches.len, 19):
|
||||
b[1] - a[1]
|
||||
for i in 0 ..< min(matches.len, 19):
|
||||
matches[i][0].innerHTML = matches[i][0].getAttribute("data-doc-search-tag")
|
||||
ul.add(tree("LI", matches[i][0]))
|
||||
if ul.len == 0:
|
||||
result.add tree("B", text"no search results")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue