From 98a6649a395d811c0b769a05fac3aa68d193f412 Mon Sep 17 00:00:00 2001
From: Alvie Rahman
Date: Thu, 16 Feb 2023 17:20:17 +0000
Subject: [PATCH] add search bar to all browsing menus
---
Makefile | 1 +
indexsearch.js | 75 ++++++++++++++++++++++++++++++++++++++++
notes2web.py | 11 +++---
templates/indexfoot.html | 3 ++
templates/indexhead.html | 9 ++++-
5 files changed, 93 insertions(+), 6 deletions(-)
create mode 100644 indexsearch.js
diff --git a/Makefile b/Makefile
index 9b9e26f..148a0ac 100644
--- a/Makefile
+++ b/Makefile
@@ -7,6 +7,7 @@ install:
cp styles.css /opt/notes2web
cp fuse.js /opt/notes2web
cp search.js /opt/notes2web
+ cp indexsearch.js /opt/notes2web
cp toc_search.js /opt/notes2web
cp permalink.js /opt/notes2web
diff --git a/indexsearch.js b/indexsearch.js
new file mode 100644
index 0000000..84eb2c9
--- /dev/null
+++ b/indexsearch.js
@@ -0,0 +1,75 @@
+const HEADERS = "headers"
+const PATH = "path"
+const TAGS = "tags"
+const TITLE = "title"
+
+const SEARCH_TIMEOUT_MS = 100
+var SEARCH_TIMEOUT_ID = -1
+
+const fuse = new Fuse(data, {
+ keys: [ 'title' ],
+ ignoreLocation: true,
+ threshhold: 0.4,
+ minMatchCharLength: 0,
+})
+
+const RESULTS_MAX = 15
+
+const searchBar = document.getElementById('search')
+const resultsDiv = document.getElementById('searchResults')
+
+var results = []
+
+function updateResultsWithTimeout() {
+ console.log("clearing timeout")
+ if (SEARCH_TIMEOUT_ID) SEARCH_TIMEOUT_ID = clearTimeout(SEARCH_TIMEOUT_ID)
+ SEARCH_TIMEOUT_ID = setTimeout(updateResults, SEARCH_TIMEOUT_MS)
+}
+
+function updateResults() {
+ console.log("updating results")
+ resultsDiv.innerHTML = ''
+ if (searchBar.value) results = fuse.search(searchBar.value, { limit: RESULTS_MAX }).map(r => r.item)
+ else results = data
+
+ results.forEach(r => {
+ wrapper = document.createElement('li')
+ wrapper.className = "article"
+
+ atag = document.createElement('a')
+ atag.href = r.path
+
+ ptag = document.createElement('p')
+ ptag.innerHTML = r.title + (r.isdirectory ? '/' : '')
+
+ atag.appendChild(ptag)
+ wrapper.appendChild(atag)
+ resultsDiv.appendChild(wrapper)
+ })
+}
+
+searchBar.addEventListener('keyup', e => {
+ console.log(e)
+ // if user pressed enter
+ if (e.keyCode === 13) {
+ if (e.shiftKey) {
+ window.open(results[0].path, '_blank')
+ } else {
+ window.location.href = results[0].path
+ }
+ return
+ }
+ updateResultsWithTimeout()
+})
+
+searchBar.addEventListener('change', updateResultsWithTimeout)
+
+const searchParams = new URL(window.location.href).searchParams;
+searchBar.value = searchParams.get('q');
+updateResults();
+
+console.log(results)
+
+if (searchParams.has('lucky')) {
+ window.location.href = results[0].path;
+}
diff --git a/notes2web.py b/notes2web.py
index 31846fc..a983fe4 100755
--- a/notes2web.py
+++ b/notes2web.py
@@ -153,6 +153,7 @@ def get_args():
parser.add_argument('-F', '--force', action="store_true", help="Generate new output html even if source file was modified before output html")
parser.add_argument('--fuse', type=pathlib.Path, default=pathlib.Path('/opt/notes2web/fuse.js'))
parser.add_argument('--searchjs', type=pathlib.Path, default=pathlib.Path('/opt/notes2web/search.js'))
+ parser.add_argument('--indexsearchjs', type=pathlib.Path, default=pathlib.Path('/opt/notes2web/indexsearch.js'))
parser.add_argument('--permalinkjs', type=pathlib.Path, default=pathlib.Path('/opt/notes2web/permalink.js'))
parser.add_argument('--tocsearchjs', type=pathlib.Path, default=pathlib.Path('/opt/notes2web/toc_search.js'))
parser.add_argument('--toc-depth', type=int, default=6, dest='toc_depth')
@@ -317,14 +318,13 @@ def main(args):
html = re.sub(r'\$extra_content\$', '', html)
for entry in tag_dict[tag]:
- html += f""
- html += INDEX_TEMPLATE_FOOT
+ entry['path'] = '/' + entry['path']
+ html += f""
+ html += re.sub('\$data\$', json.dumps(tag_dict[tag]), INDEX_TEMPLATE_FOOT)
with open(tagdir.joinpath(f'{tag}.html'), 'w+') as fp:
fp.write(html)
-
-
dirs_to_index = [args.output_dir.name] + get_dirs_to_index(args.output_dir)
print(f"{dirs_to_index=}")
print(f"{dirs_with_index_article=}")
@@ -389,7 +389,7 @@ def main(args):
'
'
''
)
- html += INDEX_TEMPLATE_FOOT
+ html += re.sub(r'\$data\$', json.dumps(indexentries), INDEX_TEMPLATE_FOOT)
with open(directory.joinpath('index.html'), 'w+') as fp:
fp.write(html)
@@ -397,6 +397,7 @@ def main(args):
shutil.copyfile(args.stylesheet, args.output_dir.joinpath('styles.css'))
shutil.copyfile(args.fuse, args.output_dir.joinpath('fuse.js'))
shutil.copyfile(args.searchjs, args.output_dir.joinpath('search.js'))
+ shutil.copyfile(args.indexsearchjs, args.output_dir.joinpath('indexsearch.js'))
shutil.copyfile(args.tocsearchjs, args.output_dir.joinpath('toc_search.js'))
shutil.copyfile(args.permalinkjs, args.output_dir.joinpath('permalink.js'))
with open(args.output_dir.joinpath('index.html'), 'w+') as fp:
diff --git a/templates/indexfoot.html b/templates/indexfoot.html
index a52a4eb..c76c924 100644
--- a/templates/indexfoot.html
+++ b/templates/indexfoot.html
@@ -1,4 +1,7 @@
page generated by notes2web
+
+
+