diff --git a/scripts/generate.py b/scripts/generate.py
index 80b3900..e883e7f 100644
--- a/scripts/generate.py
+++ b/scripts/generate.py
@@ -530,6 +530,12 @@ def render_results_block(element, acc, headline, graph):
if len(content.strip()) > 0:
render_block(content, acc, _class='results lang-text', is_code=False)
+def render_generic_drawer_block(element, acc, headline, graph):
+ items = [e.get_raw() for e in element.children]
+ content = '\n'.join(items)
+ if len(content.strip()) > 0:
+ render_block(content, acc, _class='generic-drawer {}-drawer lang-text'.format(element.drawer_name), is_code=False)
+
def render_org_text(element, acc, headline, graph):
as_dom = org_rw.text_to_dom(element.contents, element)
render_text_tokens(as_dom, acc, headline, graph)
@@ -662,6 +668,7 @@ def render_tag(element, acc, headline, graph):
dom.CodeBlock: render_code_block,
dom.Text: render_text,
dom.ResultsDrawerNode: render_results_block,
+ dom.GenericDrawerNode: render_generic_drawer_block,
org_rw.Text: render_org_text,
}[type(element)](element, acc, headline, graph)
diff --git a/scripts/search-server.sh b/scripts/search-server.sh
index 49f0250..62abda0 100644
--- a/scripts/search-server.sh
+++ b/scripts/search-server.sh
@@ -12,4 +12,4 @@ cd ../../_gen/notes/
set -x
-exec docker run -it --rm -p $PORT:80 -e PORT=80 -e DB_PATH=/db.sqlite3 -v `pwd`/db.sqlite3:/db.sqlite3:ro search-server
+exec docker run -it --rm -p $PORT:80 -e SNIPPET_SIZE=256 -e PORT=80 -e DB_PATH=/db.sqlite3 -v `pwd`/db.sqlite3:/db.sqlite3:ro search-server
diff --git a/scripts/search-server/server.go b/scripts/search-server/server.go
index 8914956..be6ab0d 100644
--- a/scripts/search-server/server.go
+++ b/scripts/search-server/server.go
@@ -33,6 +33,22 @@ func main() {
port = port_num
}
+ snippet_size := 128
+ snippet_size_str, ok := os.LookupEnv("SNIPPET_SIZE")
+ if ok {
+ snippet_size_num, err := strconv.Atoi(snippet_size_str)
+
+ if err != nil {
+ log.Fatal(err)
+ os.Exit(1)
+ }
+ if (snippet_size_num < 64) {
+ log.Fatal("Environment variale $SNIPPET_SIZE must be >= 64.")
+ os.Exit(1)
+ }
+ snippet_size = snippet_size_num
+ }
+
db, err := sql.Open("sqlite3", database_path)
if err != nil {
log.Fatal(err)
@@ -63,8 +79,23 @@ func main() {
c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, OPTIONS")
query := c.Query("q")
+ body_type := c.Query("body")
+
+ if ((body_type != "all") && (body_type != "none") && (body_type != "snippet")) {
+ body_type = "none"
+ }
+
+ var stm *sql.Stmt
+ var err error
+
+ if (body_type == "snippet") {
+ stm, err = db.Prepare("SELECT note_id, highlight(note_search, 1, '', ''), top_level_title, is_done, is_todo, snippet(note_search, 2, '', '', '', ?) FROM note_search(?)")
+ } else if (body_type == "all") {
+ stm, err = db.Prepare("SELECT note_id, highlight(note_search, 1, '', ''), top_level_title, is_done, is_todo, highlight(note_search, 2, '', '') FROM note_search(?)")
+ } else if (body_type == "none") {
+ stm, err = db.Prepare("SELECT note_id, highlight(note_search, 1, '', ''), top_level_title, is_done, is_todo FROM note_search(?)")
+ }
- stm, err := db.Prepare("SELECT note_id, title, top_level_title, is_done, is_todo FROM note_search(?)")
if err != nil {
log.Fatal(err)
@@ -76,8 +107,13 @@ func main() {
}
results := make([]map[string]string, 0)
+ var rows *sql.Rows
- rows, err := stm.Query(query)
+ if (body_type == "snippet") {
+ rows, err = stm.Query(snippet_size, query)
+ } else {
+ rows, err = stm.Query(query)
+ }
if err != nil {
log.Fatal(err)
c.JSON(500, gin.H{
@@ -94,13 +130,31 @@ func main() {
var note_is_done string
var note_is_todo string
- err = rows.Scan(
- ¬e_id,
- ¬e_title,
- ¬e_top_level_title,
- ¬e_is_done,
- ¬e_is_todo,
- )
+ item := make(map[string]string)
+
+ if (body_type != "none") {
+ var note_highlight string
+
+ err = rows.Scan(
+ ¬e_id,
+ ¬e_title,
+ ¬e_top_level_title,
+ ¬e_is_done,
+ ¬e_is_todo,
+ ¬e_highlight,
+ )
+ if (body_type != "none") {
+ item["highlight"] = note_highlight
+ }
+ } else {
+ err = rows.Scan(
+ ¬e_id,
+ ¬e_title,
+ ¬e_top_level_title,
+ ¬e_is_done,
+ ¬e_is_todo,
+ )
+ }
if err != nil {
log.Fatal(err)
c.JSON(500, gin.H{
@@ -110,7 +164,6 @@ func main() {
return
}
- item := make(map[string]string)
item["id"] = note_id
item["title"] = note_title
item["top_level_title"] = note_top_level_title
diff --git a/static/search-box.js b/static/search-box.js
index 5e412a5..08b81f0 100644
--- a/static/search-box.js
+++ b/static/search-box.js
@@ -1,4 +1,9 @@
function _codigoparallevar_enable_search_box(selector, options) {
+ const unescape = (str, tag) => {
+ const prev = tag.replaceAll('<', '<').replaceAll('>', '>');
+ return str.replaceAll(prev, tag);
+ }
+
const element = document.querySelector(selector);
if ('placeholder' in options) {
element.setAttribute('placeholder', options.placeholder);
@@ -69,7 +74,7 @@ function _codigoparallevar_enable_search_box(selector, options) {
lastVal = val;
resultsBox.classList.add('loading');
- const uri = SEARCH_ENDPOINT + '?q=' + encodeURIComponent(val);
+ const uri = SEARCH_ENDPOINT + '?q=' + encodeURIComponent(val) + '&body=snippet';
let query = fetch(uri);
currentQuery = query;
query
@@ -94,14 +99,32 @@ function _codigoparallevar_enable_search_box(selector, options) {
const resultTitle = document.createElement('h2');
resultTitle.innerText = `${note.title} (${note.top_level_title})`;
+ resultTitle.innerHTML = unescape(unescape(
+ resultTitle.innerHTML,
+ ''), ''
+ );
if (note.is_todo === "1") {
- resultTitle.setAttribute('class', 'is-todo');
+ resultCard.setAttribute('class', 'is-todo');
}
else if (note.is_done === "1") {
- resultTitle.setAttribute('class', 'is-done');
+ resultCard.setAttribute('class', 'is-done');
}
resultContents.appendChild(resultTitle);
+
+ if (note.highlight) {
+ const resultBody = document.createElement('p');
+ resultBody.innerText = note.highlight;
+ resultBody.innerHTML = unescape(
+ unescape(
+ unescape(
+ resultBody.innerHTML,
+ ''),
+ ''),
+ '');
+ resultContents.appendChild(resultBody);
+ }
+
resultCard.appendChild(resultContents);
resultsList.appendChild(resultCard);
}
diff --git a/static/style.css b/static/style.css
index e362552..493a929 100644
--- a/static/style.css
+++ b/static/style.css
@@ -126,13 +126,30 @@ body nav input {
box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.25);
}
+.results-box ul li a {
+ text-decoration: none;
+}
.results-box ul li h2 {
font-size: 110%;
padding: 1.25ex;
display: block;
margin: 0;
+ text-decoration: underline;
}
+.results-box ul li p {
+ padding: 1.25ex;
+ color: black;
+}
+
+.results-box ul li span.match {
+ background: yellow;
+}
+
+.results-box ul li .search-result-break::before {
+ content: '…';
+ color: #777;
+}
.results-box li h2.is-todo::before {
content: 'TODO';
display: inline-block;
@@ -659,10 +676,19 @@ tr.__table-separator {
.results-box ul li h2 {
color: white;
}
+ .results-box ul li p {
+ padding: 1.25ex;
+ color: white;
+ }
+
.results-box-container .results-box input:focus {
border-bottom: 1px solid #fff;
}
+ .results-box ul li span.match {
+ background: #886600;
+ }
+
/* Code blocks */
.highlight pre {
padding: 1ex;