commit:     7f13e9b5f59ee496db5b8af7ab093a17c8f76066
Author:     Lucas Ramage <ramage.lucas <AT> protonmail <DOT> com>
AuthorDate: Thu Apr 11 19:21:27 2019 +0000
Commit:     Göktürk Yüksek <gokturk <AT> gentoo <DOT> org>
CommitDate: Thu Dec 19 20:52:49 2019 +0000
URL:        https://gitweb.gentoo.org/proj/devmanual.git/commit/?id=7f13e9b5

Implement search functionality via lunr.js

Bug: https://bugs.gentoo.org/674378
Signed-off-by: Lucas Ramage <ramage.lucas <AT> protonmail.com>
Signed-off-by: Göktürk Yüksek <gokturk <AT> gentoo.org>

 .gitignore      |  1 +
 Makefile        |  6 +++++-
 devbook.xsl     | 48 +++++++++++++++++++++++++++++++++++++++++++++
 search.js       | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 search_index.py | 26 +++++++++++++++++++++++++
 5 files changed, 140 insertions(+), 1 deletion(-)

diff --git a/.gitignore b/.gitignore
index 720d4d6..ce644c7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
 *.html
 *.png
+documents.js
 eclass-reference/

diff --git a/Makefile b/Makefile
index 61daef4..4a52cc0 100644
--- a/Makefile
+++ b/Makefile
@@ -19,6 +19,10 @@ prereq:
        { echo "dev-libs/libxml2 is required" >&2;\
          exit 1; }
 
+index:
+       @echo -n "var documents = " > documents.js
+       @./search_index.py text.xml >> documents.js
+
 %.png : %.svg
        convert $< $@
 
@@ -42,6 +46,6 @@ validate: prereq
          && echo "xmllint validation successful"
 
 clean:
-       rm -f $(HTMLS) $(IMAGES)
+       rm -f $(HTMLS) $(IMAGES) documents.js
 
 .PHONY: all prereq validate clean

diff --git a/devbook.xsl b/devbook.xsl
index 96a0508..71dde54 100644
--- a/devbook.xsl
+++ b/devbook.xsl
@@ -536,7 +536,45 @@
             </div>
           </div>
         </nav>
+        <nav class="navbar navbar-grey navbar-stick" id="devmanual-actions" 
role="navigation">
+          <div class="container">
+            <div class="row">
+              <div class="navbar-header">
+                <button type="button" class="navbar-toggle" 
data-toggle="collapse" data-target="#gw-toolbar">
+                  <span class="sr-only">Toggle navigation</span>
+                  <span class="icon-bar"></span>
+                  <span class="icon-bar"></span>
+                  <span class="icon-bar"></span>
+                </button>
+              </div>
+              <div class="collapse navbar-collapse" id="gw-toolbar">
+              <div class="input-group">
+                <input type="search" name="search" placeholder="Search" 
title="Search Gentoo Developer Manual [f]" accesskey="f" id="searchInput" 
class="form-control"/>
+                <div class="input-group-btn">
+                  <input type="submit" name="fulltext" value="Search" 
title="Search the pages for this text" id="mw-searchButton" class="searchButton 
btn btn-default" onclick="search()"/>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </nav>
       </header>
+      <div id="searchResults" class="modal fade" role="dialog">
+        <div class="modal-dialog">
+          <div class="modal-content">
+            <div class="modal-header">
+              <button type="button" class="close" 
data-dismiss="modal">x</button>
+              <h4 class="modal-title">Search Results</h4>
+            </div>
+            <div class="modal-body">
+              <p>No results found.</p>
+            </div>
+            <div class="modal-footer">
+              <button type="button" class="btn btn-default" 
data-dismiss="modal">Close</button>
+            </div>
+          </div>
+        </div>
+      </div>
       <div class="container">
         <div class="row">
           <div class="col-md010">
@@ -583,6 +621,16 @@
       </footer>
       <script src="https://assets.gentoo.org/tyrian/jquery.min.js";></script>
       <script src="https://assets.gentoo.org/tyrian/bootstrap.min.js";></script>
+      <script src="https://unpkg.com/lunr/lunr.js";></script>
+      <xsl:variable name="relative_path_depth" 
select="string-length(/guide/@self)-string-length(translate(/guide/@self, '/' , 
''))"/>
+      <xsl:variable name="relative_path_depth_recursion">
+          <xsl:call-template name="str:repeatString">
+            <xsl:with-param name="count" select="$relative_path_depth"/>
+            <xsl:with-param name="append">../</xsl:with-param>
+          </xsl:call-template>
+      </xsl:variable>
+      <script src="{$relative_path_depth_recursion}documents.js"></script>
+      <script src="{$relative_path_depth_recursion}search.js"></script>
     </body>
     </html>
   </xsl:template>

diff --git a/search.js b/search.js
new file mode 100644
index 0000000..0b9292f
--- /dev/null
+++ b/search.js
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2019 Gentoo Authors
+ * Distributed under the terms of the GNU GPL version 2 or later
+ */
+"use strict";
+
+var search_index = lunr(function () {
+  this.ref('name');
+  this.field('text');
+  this.field('url');
+
+  documents.forEach(function (doc) {
+    this.add(doc);
+  }, this);
+});
+
+var search_input = document.getElementById("searchInput");
+
+search_input.addEventListener("keyup", function(event) {
+  if(event.keyCode === 13) {
+    event.preventDefault();
+    document.getElementById("mw-searchButton").click();
+  }
+});
+
+function getContents(docs, article) {
+  var contents = { text: "", url: "" };
+
+  for (var i = 0; i< docs.length; i++) {
+    if (docs[i].name == article) {
+      contents.text = docs[i].text;
+      contents.url = docs[i].url;
+    }
+  }
+  return contents;
+}
+
+function search() {
+  var term = document.getElementById("searchInput").value;
+  if (term !== "") {
+    var results = search_index.search(term);
+    if (results.length > 0) {
+      $("#searchResults .modal-body").empty();
+      $.each(results, function(index, result) {
+        var title = result.ref;
+        var contents = getContents(documents, title);
+
+        $("#searchResults .modal-body").append(`<article><h5><a 
href="${contents.url}">
+                                                
${title}</a></h5><p>${contents.text}</p></article>`);
+      });
+    } else {
+      $("#searchResults .modal-body").empty();
+      $("#searchResults .modal-body").append("<p>No results found.</p>");
+    }
+  } else {
+      $("#searchResults .modal-body").empty();
+      $("#searchResults .modal-body").append("<p>No search term defined.</p>");
+  }
+  $("#searchResults").modal();
+}

diff --git a/search_index.py b/search_index.py
new file mode 100755
index 0000000..2ab79f1
--- /dev/null
+++ b/search_index.py
@@ -0,0 +1,26 @@
+#!/usr/bin/python
+# Copyright 2019 Gentoo Authors
+# Distributed under the terms of the GNU GPL version 2 or later
+import json
+import os
+import sys
+import xml.etree.ElementTree as ET
+
+xmlFile = sys.argv[1]
+documents = []
+
+for path, dirs, files in os.walk('.'):
+    if xmlFile in files:
+        tree = ET.parse(path + '/' + xmlFile)
+        root = tree.getroot()
+        for chapter in root.findall('chapter'):
+            try:
+                documents.append({"name": chapter.find('title').text,
+                    "text": chapter.find('body').find('p').text,
+                    "url": path })
+            except:
+                pass
+    if '.git' in dirs:
+        dirs.remove('.git')  # don't visit git directories
+
+print(json.dumps(documents))

Reply via email to