From 060871e64ac9d665430d4d9ae912bf7a379ee976 Mon Sep 17 00:00:00 2001 From: Ray Imber Date: Fri, 20 Jul 2018 02:58:42 -0700 Subject: [PATCH] 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 --- lib/packages/docutils/rstgen.nim | 12 ++- tools/dochack/dochack.nim | 36 ++++---- tools/dochack/fuzzysearch.nim | 139 +++++++++++++++++++++++++++++++ 3 files changed, 167 insertions(+), 20 deletions(-) create mode 100644 tools/dochack/fuzzysearch.nim diff --git a/lib/packages/docutils/rstgen.nim b/lib/packages/docutils/rstgen.nim index ef456f0938..43a429a17b 100644 --- a/lib/packages/docutils/rstgen.nim +++ b/lib/packages/docutils/rstgen.nim @@ -449,10 +449,11 @@ proc generateSymbolIndex(symbols: seq[IndexEntry]): string = desc = if not symbols[j].linkDesc.isNil: symbols[j].linkDesc else: "" if desc.len > 0: result.addf("""
  • $2
  • + title="$3" data-doc-search-tag="$2" href="$1">$2 """, [url, text, desc]) else: - result.addf("""
  • $2
  • + result.addf("""
  • $2
  • """, [url, text]) inc j result.add("\n") @@ -493,6 +494,7 @@ proc generateDocumentationTOC(entries: seq[IndexEntry]): string = # Build a list of levels and extracted titles to make processing easier. var titleRef: string + titleTag: string levels: seq[tuple[level: int, text: string]] L = 0 level = 1 @@ -519,10 +521,12 @@ proc generateDocumentationTOC(entries: seq[IndexEntry]): string = let link = entries[L].link if link.isDocumentationTitle: titleRef = link + titleTag = levels[L].text else: result.add(level.indentToLevel(levels[L].level)) - result.add("
  • " & - levels[L].text & "
  • \n") + result.addf("""
  • + $3
  • + """, [titleTag & " : " & levels[L].text, link, levels[L].text]) inc L result.add(level.indentToLevel(1) & "\n") assert(not titleRef.isNil, diff --git a/tools/dochack/dochack.nim b/tools/dochack/dochack.nim index 79a0e74827..8cc27b6eb6 100644 --- a/tools/dochack/dochack.nim +++ b/tools/dochack/dochack.nim @@ -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.. int: - a[1] - b[1] - for i in 0..min( 0), + )