From b030b50b95d3ac8f0e64ecac55db1ff5d4323a24 Mon Sep 17 00:00:00 2001 From: Kalle Fagerberg <kalle.f8@proton.me> Date: Thu, 28 Jul 2022 22:09:51 +0200 Subject: [PATCH 01/54] Added stork search --- default/templates/layouts/book.tpl | 36 ++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/default/templates/layouts/book.tpl b/default/templates/layouts/book.tpl index 45f805202..b2bbf99c5 100644 --- a/default/templates/layouts/book.tpl +++ b/default/templates/layouts/book.tpl @@ -1,5 +1,21 @@ <apply template="base"> - <bind tag="head-main"></bind> + <bind tag="head-main"> + <link rel="stylesheet" href="https://files.stork-search.net/releases/v1.5.0/basic.css" /> + <style> + .stork-wrapper .stork-output { + margin-top: 0; + border-radius: 0; + position: sticky; + } + .stork-wrapper .stork-message { + padding: 0.5rem 1rem; + border-radius: 0; + margin-top: 1px; + margin-bottom: 1px; + border-color: rgba(99,102,241,var(--tw-border-opacity)); + } + </style> + </bind> <bind tag="body-main"> <div class="container mx-auto"> @@ -10,6 +26,9 @@ <!-- Sidebar column --> <nav id="sidebar" class="flex-shrink hidden leading-relaxed md:block md:sticky md:top-0 md:h-full md:w-48 xl:w-64"> + <div class="stork-wrapper"> + <input data-stork="federalist" class="px-4 py-2 block w-full rounded-none border border-gray-300 focus:ring-indigo-500 focus:border-indigo-500 focus:outline-none" placeholder="Search..." /> + </div> <div class="px-2 py-2 text-gray-800"> <div id="indexing-links" class="flex flex-row float-right p-2 space-x-2 text-gray-500"> @@ -61,6 +80,9 @@ <!-- Main body column --> <div class="flex-1 w-full overflow-x-auto bg-white"> + <div class="stork-wrapper md:sticky top-0"> + <div data-stork="federalist-output" class="stork-output"></div> + </div> <main class="px-4 py-4"> <apply template="components/note-title" /> <apply template="components/note-body" /> @@ -75,5 +97,15 @@ </div> <apply template="components/footer" /> </div> + <script src="https://files.stork-search.net/releases/v1.5.0/stork.js"></script> + <script> + if (document.readyState == 'loading') { + stork.register( + 'federalist', + //'https://files.stork-search.net/releases/v1.5.0/federalist.st' + '/stork.st' + ); + } + </script> </bind> -</apply> \ No newline at end of file +</apply> From 116265a77469094d235311941cc7c989afab673f Mon Sep 17 00:00:00 2001 From: Kalle Fagerberg <kalle.f8@proton.me> Date: Thu, 28 Jul 2022 22:19:05 +0200 Subject: [PATCH 02/54] Added search tmp docs --- docs/tips/search.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 docs/tips/search.md diff --git a/docs/tips/search.md b/docs/tips/search.md new file mode 100644 index 000000000..e4abd8c09 --- /dev/null +++ b/docs/tips/search.md @@ -0,0 +1,18 @@ +# Search + +**These are temporary private notes!** TODO: Cleanup and write actual docs + +```bash +emanote gen result -L 'docs;default' + +cd result + +echo '[input]' > stork.toml +echo 'files = [' >> stork.toml +rg -g '!-/' '<title>' -A1 | grep html- | sed 's/\(.*\)- *\(.*\)/ {path = "\1", url="\1", title = "\2"},/' >> stork.toml +echo ']' >> stork.toml + +stork build --input stork.toml --output stork.st + +podman run --rm -it -v $PWD:/usr/share/nginx/html:Z -p 8080:80 nginx:alpine +``` From 46a5c0eef360c0bf59a23da7135e8576e717103f Mon Sep 17 00:00:00 2001 From: Kalle Fagerberg <kalle.f8@proton.me> Date: Thu, 28 Jul 2022 23:44:30 +0200 Subject: [PATCH 03/54] Fixed rg cmd --- docs/tips/search.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tips/search.md b/docs/tips/search.md index e4abd8c09..48767b754 100644 --- a/docs/tips/search.md +++ b/docs/tips/search.md @@ -9,7 +9,7 @@ cd result echo '[input]' > stork.toml echo 'files = [' >> stork.toml -rg -g '!-/' '<title>' -A1 | grep html- | sed 's/\(.*\)- *\(.*\)/ {path = "\1", url="\1", title = "\2"},/' >> stork.toml +rg -g '!-/' '<title>' -A1 | grep html- | sed 's/\(.*.html\)- *\(.*\)/ {path = "\1", url="\1", title = """\2"""},/' >> stork.toml echo ']' >> stork.toml stork build --input stork.toml --output stork.st From 6a29a32e0b4d0ca84634d6da088df12db8aa5fe5 Mon Sep 17 00:00:00 2001 From: Kalle Fagerberg <kalle.f8@proton.me> Date: Sat, 30 Jul 2022 15:29:16 +0200 Subject: [PATCH 04/54] Extracted to hooks --- default/templates/base.tpl | 3 +- default/templates/layouts/book.tpl | 38 +++------------------ docs/templates/hooks/after-body.tpl | 16 +++++++++ docs/templates/hooks/before-nav-content.tpl | 5 +++ docs/templates/hooks/more-head.tpl | 32 +++++++++++++++++ 5 files changed, 60 insertions(+), 34 deletions(-) create mode 100644 docs/templates/hooks/after-body.tpl create mode 100644 docs/templates/hooks/before-nav-content.tpl create mode 100644 docs/templates/hooks/more-head.tpl diff --git a/default/templates/base.tpl b/default/templates/base.tpl index a0d092f2a..6eabbabeb 100644 --- a/default/templates/base.tpl +++ b/default/templates/base.tpl @@ -44,6 +44,7 @@ <body class="${bodyClass}"> <body-main /> + <apply template="/templates/hooks/after-body" /> </body> -</html> \ No newline at end of file +</html> diff --git a/default/templates/layouts/book.tpl b/default/templates/layouts/book.tpl index b2bbf99c5..affca4023 100644 --- a/default/templates/layouts/book.tpl +++ b/default/templates/layouts/book.tpl @@ -1,21 +1,5 @@ <apply template="base"> - <bind tag="head-main"> - <link rel="stylesheet" href="https://files.stork-search.net/releases/v1.5.0/basic.css" /> - <style> - .stork-wrapper .stork-output { - margin-top: 0; - border-radius: 0; - position: sticky; - } - .stork-wrapper .stork-message { - padding: 0.5rem 1rem; - border-radius: 0; - margin-top: 1px; - margin-bottom: 1px; - border-color: rgba(99,102,241,var(--tw-border-opacity)); - } - </style> - </bind> + <bind tag="head-main"></bind> <bind tag="body-main"> <div class="container mx-auto"> @@ -26,9 +10,7 @@ <!-- Sidebar column --> <nav id="sidebar" class="flex-shrink hidden leading-relaxed md:block md:sticky md:top-0 md:h-full md:w-48 xl:w-64"> - <div class="stork-wrapper"> - <input data-stork="federalist" class="px-4 py-2 block w-full rounded-none border border-gray-300 focus:ring-indigo-500 focus:border-indigo-500 focus:outline-none" placeholder="Search..." /> - </div> + <apply template="hooks/before-nav-content" /> <div class="px-2 py-2 text-gray-800"> <div id="indexing-links" class="flex flex-row float-right p-2 space-x-2 text-gray-500"> @@ -76,13 +58,12 @@ </ema:route-tree> </div> + <apply template="hooks/after-nav-content" /> </nav> <!-- Main body column --> <div class="flex-1 w-full overflow-x-auto bg-white"> - <div class="stork-wrapper md:sticky top-0"> - <div data-stork="federalist-output" class="stork-output"></div> - </div> + <apply template="/templates/hooks/before-main" /> <main class="px-4 py-4"> <apply template="components/note-title" /> <apply template="components/note-body" /> @@ -93,19 +74,10 @@ <apply template="components/metadata" /> <apply template="/templates/hooks/note-end" /> </main> + <apply template="/templates/hooks/after-main" /> </div> </div> <apply template="components/footer" /> </div> - <script src="https://files.stork-search.net/releases/v1.5.0/stork.js"></script> - <script> - if (document.readyState == 'loading') { - stork.register( - 'federalist', - //'https://files.stork-search.net/releases/v1.5.0/federalist.st' - '/stork.st' - ); - } - </script> </bind> </apply> diff --git a/docs/templates/hooks/after-body.tpl b/docs/templates/hooks/after-body.tpl new file mode 100644 index 000000000..bb840c801 --- /dev/null +++ b/docs/templates/hooks/after-body.tpl @@ -0,0 +1,16 @@ +<!-- Stork search scripts, styling are at end of <head> --> +<script src="https://files.stork-search.net/releases/v1.5.0/stork.js"></script> +<script> + if (document.readyState !== "complete") { + stork.register( + 'emanote-search', // has to match input[data-stork] attribute value + (document.querySelector('head > base').getAttribute('href') || '')+'stork.st' + ); + } else { + stork.downloadIndex( + 'emanote-search', // has to match input[data-stork] attribute value + (document.querySelector('head > base').getAttribute('href') || '')+'stork.st', + { forceOverwrite: true } // needed for Ema's hot-reload + ); + } +</script> diff --git a/docs/templates/hooks/before-nav-content.tpl b/docs/templates/hooks/before-nav-content.tpl new file mode 100644 index 000000000..616a41041 --- /dev/null +++ b/docs/templates/hooks/before-nav-content.tpl @@ -0,0 +1,5 @@ + +<div class="stork-wrapper"> + <input data-stork="emanote-search" class="px-4 py-2 block w-full rounded-none border border-gray-300 focus:ring-indigo-500 focus:border-indigo-500 focus:outline-none" placeholder="Search..." /> + <div data-stork="emanote-search-output" class="stork-output"></div> +</div> diff --git a/docs/templates/hooks/more-head.tpl b/docs/templates/hooks/more-head.tpl new file mode 100644 index 000000000..8ea0a36d3 --- /dev/null +++ b/docs/templates/hooks/more-head.tpl @@ -0,0 +1,32 @@ +<!-- Stork search styling, scripts are at end of <body> --> +<link rel="stylesheet" href="https://files.stork-search.net/releases/v1.5.0/basic.css" /> +<style> +/* Applies changes to Stork search (https://stork-search.net/) + to make it fit in with Emanote's styling. +*/ + +.stork-wrapper .stork-output { + margin-top: 0; + border-radius: 0; + position: sticky; +} + +.stork-wrapper .stork-message { + padding: 0.5rem 1rem; + border-radius: 0; + margin-top: 1px; + margin-bottom: 1px; + border-color: rgba(99,102,241,var(--tw-border-opacity)); +} + +.stork-wrapper .stork-close-button { + top: 0; + margin: 0.8em 0.6em; +} + +.stork-wrapper .stork-close-button svg { + top: unset; + margin-left: auto; + margin-right: auto; +} +</style> From 22965ee3f0551c0e28a2fd1191bcfcbab54e667d Mon Sep 17 00:00:00 2001 From: Kalle Fagerberg <kalle.f8@proton.me> Date: Sat, 30 Jul 2022 15:44:16 +0200 Subject: [PATCH 05/54] Removed search.md --- docs/tips/search.md | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 docs/tips/search.md diff --git a/docs/tips/search.md b/docs/tips/search.md deleted file mode 100644 index 48767b754..000000000 --- a/docs/tips/search.md +++ /dev/null @@ -1,18 +0,0 @@ -# Search - -**These are temporary private notes!** TODO: Cleanup and write actual docs - -```bash -emanote gen result -L 'docs;default' - -cd result - -echo '[input]' > stork.toml -echo 'files = [' >> stork.toml -rg -g '!-/' '<title>' -A1 | grep html- | sed 's/\(.*.html\)- *\(.*\)/ {path = "\1", url="\1", title = """\2"""},/' >> stork.toml -echo ']' >> stork.toml - -stork build --input stork.toml --output stork.st - -podman run --rm -it -v $PWD:/usr/share/nginx/html:Z -p 8080:80 nginx:alpine -``` From a5a67a2b1ac65b2c36993a30bf77fad9fc6293e3 Mon Sep 17 00:00:00 2001 From: Kalle Fagerberg <kalle.f8@proton.me> Date: Sat, 30 Jul 2022 16:22:59 +0200 Subject: [PATCH 06/54] Style so search results overlap notes --- docs/templates/hooks/more-head.tpl | 45 ++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/docs/templates/hooks/more-head.tpl b/docs/templates/hooks/more-head.tpl index 8ea0a36d3..c20bdfa51 100644 --- a/docs/templates/hooks/more-head.tpl +++ b/docs/templates/hooks/more-head.tpl @@ -9,13 +9,50 @@ margin-top: 0; border-radius: 0; position: sticky; + border-color: rgba(99,102,241,var(--tw-border-opacity)); + --tw-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1),0 4px 6px -2px rgba(0, 0, 0, 0.05); + box-shadow: var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow); +} + +@media (min-width: 768px) { + .stork-wrapper .stork-output { + top: 0; + left: 100%; + position: absolute; + width: calc(768px - 12rem); + } +} + +@media (min-width: 1024px) { + .stork-wrapper .stork-output { + top: 0; + left: 100%; + position: absolute; + width: calc(1024px - 12rem); + } +} + +@media (min-width: 1280px) { + .stork-wrapper .stork-output { + top: 0; + left: 100%; + position: absolute; + width: calc(1280px - 16rem); + } +} + +@media (min-width: 1536px) { + .stork-wrapper .stork-output { + top: 0; + left: 100%; + position: absolute; + width: calc(1536px - 16rem); + } } .stork-wrapper .stork-message { padding: 0.5rem 1rem; border-radius: 0; - margin-top: 1px; - margin-bottom: 1px; border-color: rgba(99,102,241,var(--tw-border-opacity)); } @@ -29,4 +66,8 @@ margin-left: auto; margin-right: auto; } + +nav#sidebar { + z-index: 100; +} </style> From b49c00b506a66fe9a908dc6f7070b0ac022f4a83 Mon Sep 17 00:00:00 2001 From: Kalle Fagerberg <kalle.f8@proton.me> Date: Sat, 30 Jul 2022 16:28:34 +0200 Subject: [PATCH 07/54] Removed duplicate stylings --- docs/templates/hooks/more-head.tpl | 9 --------- 1 file changed, 9 deletions(-) diff --git a/docs/templates/hooks/more-head.tpl b/docs/templates/hooks/more-head.tpl index c20bdfa51..93f7d4cfb 100644 --- a/docs/templates/hooks/more-head.tpl +++ b/docs/templates/hooks/more-head.tpl @@ -25,27 +25,18 @@ @media (min-width: 1024px) { .stork-wrapper .stork-output { - top: 0; - left: 100%; - position: absolute; width: calc(1024px - 12rem); } } @media (min-width: 1280px) { .stork-wrapper .stork-output { - top: 0; - left: 100%; - position: absolute; width: calc(1280px - 16rem); } } @media (min-width: 1536px) { .stork-wrapper .stork-output { - top: 0; - left: 100%; - position: absolute; width: calc(1536px - 16rem); } } From 809d5ddd9f391eefac69f47b24b9c404a079231c Mon Sep 17 00:00:00 2001 From: Kalle Fagerberg <kalle.f8@proton.me> Date: Sat, 30 Jul 2022 16:38:16 +0200 Subject: [PATCH 08/54] Cleaned up JS a little --- docs/templates/hooks/after-body.tpl | 22 ++++++++++++---------- docs/templates/hooks/more-head.tpl | 2 +- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/docs/templates/hooks/after-body.tpl b/docs/templates/hooks/after-body.tpl index bb840c801..b76bb6668 100644 --- a/docs/templates/hooks/after-body.tpl +++ b/docs/templates/hooks/after-body.tpl @@ -1,16 +1,18 @@ -<!-- Stork search scripts, styling are at end of <head> --> +<!-- Stork search scripts, styling added in more-head.tpl --> <script src="https://files.stork-search.net/releases/v1.5.0/stork.js"></script> <script> +(function () { + const indexName = 'emanote-search'; // used to match input[data-stork] attribute value + const baseUrl = document.querySelector('head > base').getAttribute('href') || '/'; + const indexUrl = baseUrl + 'stork.st'; + if (document.readyState !== "complete") { - stork.register( - 'emanote-search', // has to match input[data-stork] attribute value - (document.querySelector('head > base').getAttribute('href') || '')+'stork.st' - ); + stork.register(indexName, indexUrl); } else { - stork.downloadIndex( - 'emanote-search', // has to match input[data-stork] attribute value - (document.querySelector('head > base').getAttribute('href') || '')+'stork.st', - { forceOverwrite: true } // needed for Ema's hot-reload - ); + // In case of Ema hot-reload: only update index + stork.downloadIndex(indexName, indexUrl, { + forceOverwrite: true + }); } +})(); </script> diff --git a/docs/templates/hooks/more-head.tpl b/docs/templates/hooks/more-head.tpl index 93f7d4cfb..b206e5274 100644 --- a/docs/templates/hooks/more-head.tpl +++ b/docs/templates/hooks/more-head.tpl @@ -1,4 +1,4 @@ -<!-- Stork search styling, scripts are at end of <body> --> +<!-- Stork search styling, scripts added in after-body.tpl --> <link rel="stylesheet" href="https://files.stork-search.net/releases/v1.5.0/basic.css" /> <style> /* Applies changes to Stork search (https://stork-search.net/) From 79f23c4c9787177b682b1052638fde1d788b8473 Mon Sep 17 00:00:00 2001 From: Kalle Fagerberg <kalle.f8@proton.me> Date: Sat, 30 Jul 2022 16:57:48 +0200 Subject: [PATCH 09/54] Added shift 1px so borders align --- docs/templates/hooks/more-head.tpl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/templates/hooks/more-head.tpl b/docs/templates/hooks/more-head.tpl index b206e5274..5d9919fa8 100644 --- a/docs/templates/hooks/more-head.tpl +++ b/docs/templates/hooks/more-head.tpl @@ -17,10 +17,14 @@ @media (min-width: 768px) { .stork-wrapper .stork-output { top: 0; - left: 100%; + left: calc(100% - 1px); position: absolute; width: calc(768px - 12rem); } + + .stork-wrapper { + margin-right: -1px; + } } @media (min-width: 1024px) { From 1a1c9e805183fa6a4be8a46ed48b1a1f8fada97e Mon Sep 17 00:00:00 2001 From: Kalle Fagerberg <kalle.f8@proton.me> Date: Sat, 30 Jul 2022 19:40:02 +0200 Subject: [PATCH 10/54] Get baseUrl from Emanote instead of <base> --- docs/templates/hooks/after-body.tpl | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/templates/hooks/after-body.tpl b/docs/templates/hooks/after-body.tpl index b76bb6668..f1ff9f36c 100644 --- a/docs/templates/hooks/after-body.tpl +++ b/docs/templates/hooks/after-body.tpl @@ -1,9 +1,11 @@ <!-- Stork search scripts, styling added in more-head.tpl --> <script src="https://files.stork-search.net/releases/v1.5.0/stork.js"></script> -<script> +<ema:metadata> +<with var="template"> +<script data-emanote-base-url="${value:baseUrl}"> (function () { const indexName = 'emanote-search'; // used to match input[data-stork] attribute value - const baseUrl = document.querySelector('head > base').getAttribute('href') || '/'; + const baseUrl = document.currentScript.getAttribute('data-emanote-base-url') || '/'; const indexUrl = baseUrl + 'stork.st'; if (document.readyState !== "complete") { @@ -16,3 +18,5 @@ } })(); </script> +</with> +</ema:metadata> From b47037361fdbf675649aa2b0a55d747cbcbc683d Mon Sep 17 00:00:00 2001 From: Kalle Fagerberg <kalle.f8@proton.me> Date: Sun, 31 Jul 2022 15:12:31 +0200 Subject: [PATCH 11/54] Moved JS & CSS to default/index.yaml --- default/index.yaml | 102 ++++++++++++++++++ default/templates/base.tpl | 1 - default/templates/layouts/book.tpl | 5 +- default/templates/layouts/note.tpl | 5 +- docs/templates/hooks/after-body.tpl | 22 ---- docs/templates/hooks/more-head.tpl | 68 ------------ ...{before-nav-content.tpl => search-box.tpl} | 1 - 7 files changed, 106 insertions(+), 98 deletions(-) delete mode 100644 docs/templates/hooks/after-body.tpl delete mode 100644 docs/templates/hooks/more-head.tpl rename docs/templates/hooks/{before-nav-content.tpl => search-box.tpl} (99%) diff --git a/default/index.yaml b/default/index.yaml index d13765034..aabb9ec64 100644 --- a/default/index.yaml +++ b/default/index.yaml @@ -117,6 +117,108 @@ js: </script> <script async="" id="MathJax-script" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script> + stork-search-base: | + <link rel="stylesheet" href="https://files.stork-search.net/releases/v1.5.0/basic.css" /> + <!-- Stork-search styling base stylings --> + <style> + .stork-wrapper .stork-output { + margin-top: 0; + border-radius: 0; + position: sticky; + border-color: rgba(99,102,241,var(--tw-border-opacity)); + --tw-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1),0 4px 6px -2px rgba(0, 0, 0, 0.05); + box-shadow: var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow); + } + + .stork-wrapper .stork-message { + padding: 0.5rem 1rem; + border-radius: 0; + border-color: rgba(99,102,241,var(--tw-border-opacity)); + } + + .stork-wrapper .stork-close-button { + top: 0; + margin: 0.8em 0.6em; + } + + .stork-wrapper .stork-close-button svg { + top: unset; + margin-left: auto; + margin-right: auto; + } + </style> + <!-- Stork search scripts, styling added in more-head.tpl --> + <script src="https://files.stork-search.net/releases/v1.5.0/stork.js"></script> + <ema:metadata> + <with var="template"> + <script data-emanote-base-url="${value:baseUrl}"> + (function() { + const indexName = 'emanote-search'; // used to match input[data-stork] attribute value + const baseUrl = document.currentScript.getAttribute('data-emanote-base-url') || '/'; + const indexUrl = baseUrl + 'stork.st'; + if (document.readyState !== 'complete') { + window.addEventListener('load', function() { + stork.register(indexName, indexUrl); + }); + } else { + stork.register(indexName, indexUrl, {forceOverwrite: true}); + } + })(); + </script> + </with> + </ema:metadata> + stork-search-book: | + <snippet var="js.stork-search-base"/> + <!-- Stork-search styling, specific to Emanote's book layout --> + <style> + @media (min-width: 768px) { + .stork-wrapper .stork-output { + top: 0; + left: calc(100% - 1px); + position: absolute; + width: calc(768px - 12rem); + } + + .stork-wrapper { + margin-right: -1px; + } + } + + @media (min-width: 1024px) { + .stork-wrapper .stork-output { + width: calc(1024px - 12rem); + } + } + + @media (min-width: 1280px) { + .stork-wrapper .stork-output { + width: calc(1280px - 16rem); + } + } + + @media (min-width: 1536px) { + .stork-wrapper .stork-output { + width: calc(1536px - 16rem); + } + } + + nav#sidebar { + z-index: 100; + } + </style> + stork-search-note: | + <snippet var="js.stork-search-base"/> + <!-- Stork-search styling, specific to Emanote's Neuron-like layout --> + <style> + .stork-wrapper .stork-output { + position: absolute; + } + </style> + # This adds styling for the "default layout", and should + # be used if you rely on Emanote's default layout. + stork-search: | + <snippet var="js.stork-search-book"/> + emanote: # Whether to automatically treat folder notes as a folgezettel parent of its contents folder-folgezettel: true diff --git a/default/templates/base.tpl b/default/templates/base.tpl index 6eabbabeb..7a85417ba 100644 --- a/default/templates/base.tpl +++ b/default/templates/base.tpl @@ -44,7 +44,6 @@ <body class="${bodyClass}"> <body-main /> - <apply template="/templates/hooks/after-body" /> </body> </html> diff --git a/default/templates/layouts/book.tpl b/default/templates/layouts/book.tpl index affca4023..25cbe0bd8 100644 --- a/default/templates/layouts/book.tpl +++ b/default/templates/layouts/book.tpl @@ -10,7 +10,7 @@ <!-- Sidebar column --> <nav id="sidebar" class="flex-shrink hidden leading-relaxed md:block md:sticky md:top-0 md:h-full md:w-48 xl:w-64"> - <apply template="hooks/before-nav-content" /> + <apply template="hooks/search-box" /> <div class="px-2 py-2 text-gray-800"> <div id="indexing-links" class="flex flex-row float-right p-2 space-x-2 text-gray-500"> @@ -58,12 +58,10 @@ </ema:route-tree> </div> - <apply template="hooks/after-nav-content" /> </nav> <!-- Main body column --> <div class="flex-1 w-full overflow-x-auto bg-white"> - <apply template="/templates/hooks/before-main" /> <main class="px-4 py-4"> <apply template="components/note-title" /> <apply template="components/note-body" /> @@ -74,7 +72,6 @@ <apply template="components/metadata" /> <apply template="/templates/hooks/note-end" /> </main> - <apply template="/templates/hooks/after-main" /> </div> </div> <apply template="components/footer" /> diff --git a/default/templates/layouts/note.tpl b/default/templates/layouts/note.tpl index ca301e626..e9fc567fc 100644 --- a/default/templates/layouts/note.tpl +++ b/default/templates/layouts/note.tpl @@ -6,12 +6,13 @@ <apply template="base"> <bind tag="head-main"> - <link rel="stylesheet" href="${ema:emanoteStaticLayerUrl}/inverted-tree.css" /> + <link rel="stylesheet" href="/${ema:emanoteStaticLayerUrl}/inverted-tree.css" /> </bind> <bind tag="body-main"> <div class="${containerClass}"> <div class="mt-2 md:mt-4"> <apply template="components/note-uptree" /> + <apply template="hooks/search-box" /> <div class="md:shadow-2xl md:mb-8"> <div class="flex-1 w-full overflow-x-auto bg-white"> <main class="px-4 py-4"> @@ -30,4 +31,4 @@ </div> </div> </bind> -</apply> \ No newline at end of file +</apply> diff --git a/docs/templates/hooks/after-body.tpl b/docs/templates/hooks/after-body.tpl deleted file mode 100644 index f1ff9f36c..000000000 --- a/docs/templates/hooks/after-body.tpl +++ /dev/null @@ -1,22 +0,0 @@ -<!-- Stork search scripts, styling added in more-head.tpl --> -<script src="https://files.stork-search.net/releases/v1.5.0/stork.js"></script> -<ema:metadata> -<with var="template"> -<script data-emanote-base-url="${value:baseUrl}"> -(function () { - const indexName = 'emanote-search'; // used to match input[data-stork] attribute value - const baseUrl = document.currentScript.getAttribute('data-emanote-base-url') || '/'; - const indexUrl = baseUrl + 'stork.st'; - - if (document.readyState !== "complete") { - stork.register(indexName, indexUrl); - } else { - // In case of Ema hot-reload: only update index - stork.downloadIndex(indexName, indexUrl, { - forceOverwrite: true - }); - } -})(); -</script> -</with> -</ema:metadata> diff --git a/docs/templates/hooks/more-head.tpl b/docs/templates/hooks/more-head.tpl deleted file mode 100644 index 5d9919fa8..000000000 --- a/docs/templates/hooks/more-head.tpl +++ /dev/null @@ -1,68 +0,0 @@ -<!-- Stork search styling, scripts added in after-body.tpl --> -<link rel="stylesheet" href="https://files.stork-search.net/releases/v1.5.0/basic.css" /> -<style> -/* Applies changes to Stork search (https://stork-search.net/) - to make it fit in with Emanote's styling. -*/ - -.stork-wrapper .stork-output { - margin-top: 0; - border-radius: 0; - position: sticky; - border-color: rgba(99,102,241,var(--tw-border-opacity)); - --tw-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1),0 4px 6px -2px rgba(0, 0, 0, 0.05); - box-shadow: var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow); -} - -@media (min-width: 768px) { - .stork-wrapper .stork-output { - top: 0; - left: calc(100% - 1px); - position: absolute; - width: calc(768px - 12rem); - } - - .stork-wrapper { - margin-right: -1px; - } -} - -@media (min-width: 1024px) { - .stork-wrapper .stork-output { - width: calc(1024px - 12rem); - } -} - -@media (min-width: 1280px) { - .stork-wrapper .stork-output { - width: calc(1280px - 16rem); - } -} - -@media (min-width: 1536px) { - .stork-wrapper .stork-output { - width: calc(1536px - 16rem); - } -} - -.stork-wrapper .stork-message { - padding: 0.5rem 1rem; - border-radius: 0; - border-color: rgba(99,102,241,var(--tw-border-opacity)); -} - -.stork-wrapper .stork-close-button { - top: 0; - margin: 0.8em 0.6em; -} - -.stork-wrapper .stork-close-button svg { - top: unset; - margin-left: auto; - margin-right: auto; -} - -nav#sidebar { - z-index: 100; -} -</style> diff --git a/docs/templates/hooks/before-nav-content.tpl b/docs/templates/hooks/search-box.tpl similarity index 99% rename from docs/templates/hooks/before-nav-content.tpl rename to docs/templates/hooks/search-box.tpl index 616a41041..189de0cf8 100644 --- a/docs/templates/hooks/before-nav-content.tpl +++ b/docs/templates/hooks/search-box.tpl @@ -1,4 +1,3 @@ - <div class="stork-wrapper"> <input data-stork="emanote-search" class="px-4 py-2 block w-full rounded-none border border-gray-300 focus:ring-indigo-500 focus:border-indigo-500 focus:outline-none" placeholder="Search..." /> <div data-stork="emanote-search-output" class="stork-output"></div> From 69a26055e32fc90f44d78912a66792c660adf7c2 Mon Sep 17 00:00:00 2001 From: Kalle Fagerberg <kalle.f8@proton.me> Date: Sun, 31 Jul 2022 15:32:31 +0200 Subject: [PATCH 12/54] Add search snippets to docs --- docs/demo/neuron-layout.md | 4 ++++ docs/index.yaml | 1 + 2 files changed, 5 insertions(+) diff --git a/docs/demo/neuron-layout.md b/docs/demo/neuron-layout.md index 4e83522f5..81ed2ae8d 100644 --- a/docs/demo/neuron-layout.md +++ b/docs/demo/neuron-layout.md @@ -1,6 +1,10 @@ --- template: name: /templates/layouts/note +page: + headHtml: | + <snippet var="js.prism" /> + <snippet var="js.stork-search-note" /> --- # Neuron-like layout diff --git a/docs/index.yaml b/docs/index.yaml index 13688aa6b..9272d7fc4 100644 --- a/docs/index.yaml +++ b/docs/index.yaml @@ -5,3 +5,4 @@ page: siteTitle: Emanote headHtml: | <snippet var="js.prism" /> + <snippet var="js.stork-search" /> From a6c915d189ac24ae72e17d99d66ce5e2f167aa04 Mon Sep 17 00:00:00 2001 From: "kalle (jag)" <kalle.f8@proton.me> Date: Sun, 31 Jul 2022 15:19:15 +0200 Subject: [PATCH 13/54] Update default/templates/layouts/note.tpl --- default/templates/layouts/note.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/default/templates/layouts/note.tpl b/default/templates/layouts/note.tpl index e9fc567fc..ba7ed83ac 100644 --- a/default/templates/layouts/note.tpl +++ b/default/templates/layouts/note.tpl @@ -6,7 +6,7 @@ <apply template="base"> <bind tag="head-main"> - <link rel="stylesheet" href="/${ema:emanoteStaticLayerUrl}/inverted-tree.css" /> + <link rel="stylesheet" href="${ema:emanoteStaticLayerUrl}/inverted-tree.css" /> </bind> <bind tag="body-main"> <div class="${containerClass}"> From b3489fffbd6d9694a95a7b81f2f155783d5867c5 Mon Sep 17 00:00:00 2001 From: Kalle Fagerberg <kalle.f8@proton.me> Date: Sun, 31 Jul 2022 15:42:47 +0200 Subject: [PATCH 14/54] Moved from hook to component, and enable via snippet --- default/index.yaml | 5 +++++ .../templates/components/stork-search.tpl | 3 ++- default/templates/layouts/book.tpl | 2 +- default/templates/layouts/note.tpl | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) rename docs/templates/hooks/search-box.tpl => default/templates/components/stork-search.tpl (73%) diff --git a/default/index.yaml b/default/index.yaml index aabb9ec64..6e1076c57 100644 --- a/default/index.yaml +++ b/default/index.yaml @@ -121,6 +121,11 @@ js: <link rel="stylesheet" href="https://files.stork-search.net/releases/v1.5.0/basic.css" /> <!-- Stork-search styling base stylings --> <style> + .stork-wrapper.hidden { + /* undo the hidden styling, in effect enabling the search box */ + display: block; + } + .stork-wrapper .stork-output { margin-top: 0; border-radius: 0; diff --git a/docs/templates/hooks/search-box.tpl b/default/templates/components/stork-search.tpl similarity index 73% rename from docs/templates/hooks/search-box.tpl rename to default/templates/components/stork-search.tpl index 189de0cf8..08cbbcefa 100644 --- a/docs/templates/hooks/search-box.tpl +++ b/default/templates/components/stork-search.tpl @@ -1,4 +1,5 @@ -<div class="stork-wrapper"> +<!-- the "hidden" is disabled via "js.stork-search" snippet --> +<div class="stork-wrapper hidden"> <input data-stork="emanote-search" class="px-4 py-2 block w-full rounded-none border border-gray-300 focus:ring-indigo-500 focus:border-indigo-500 focus:outline-none" placeholder="Search..." /> <div data-stork="emanote-search-output" class="stork-output"></div> </div> diff --git a/default/templates/layouts/book.tpl b/default/templates/layouts/book.tpl index 25cbe0bd8..9900bc7f6 100644 --- a/default/templates/layouts/book.tpl +++ b/default/templates/layouts/book.tpl @@ -10,7 +10,7 @@ <!-- Sidebar column --> <nav id="sidebar" class="flex-shrink hidden leading-relaxed md:block md:sticky md:top-0 md:h-full md:w-48 xl:w-64"> - <apply template="hooks/search-box" /> + <apply template="components/stork-search" /> <div class="px-2 py-2 text-gray-800"> <div id="indexing-links" class="flex flex-row float-right p-2 space-x-2 text-gray-500"> diff --git a/default/templates/layouts/note.tpl b/default/templates/layouts/note.tpl index ba7ed83ac..f645a97b7 100644 --- a/default/templates/layouts/note.tpl +++ b/default/templates/layouts/note.tpl @@ -12,7 +12,7 @@ <div class="${containerClass}"> <div class="mt-2 md:mt-4"> <apply template="components/note-uptree" /> - <apply template="hooks/search-box" /> + <apply template="components/stork-search" /> <div class="md:shadow-2xl md:mb-8"> <div class="flex-1 w-full overflow-x-auto bg-white"> <main class="px-4 py-4"> From 64cc2f1278da2dcff5f095404a5e54dddfc2b6f7 Mon Sep 17 00:00:00 2001 From: Kalle Fagerberg <kalle.f8@proton.me> Date: Sun, 31 Jul 2022 16:05:06 +0200 Subject: [PATCH 15/54] Fixed borders --- default/index.yaml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/default/index.yaml b/default/index.yaml index 6e1076c57..1a61ddb3e 100644 --- a/default/index.yaml +++ b/default/index.yaml @@ -176,7 +176,18 @@ js: <snippet var="js.stork-search-base"/> <!-- Stork-search styling, specific to Emanote's book layout --> <style> + .stork-wrapper > input { + border-top-color: rgba(209,213,219,var(--tw-border-opacity)); + border-left-color: transparent; + border-right-color: transparent; + } + @media (min-width: 768px) { + .stork-wrapper > input { + border-top-color: transparent; + border-right-color: rgba(209,213,219,var(--tw-border-opacity)); + } + .stork-wrapper .stork-output { top: 0; left: calc(100% - 1px); @@ -218,6 +229,12 @@ js: .stork-wrapper .stork-output { position: absolute; } + + .stork-wrapper > input { + border-top-color: transparent; + border-left-color: transparent; + border-right-color: transparent; + } </style> # This adds styling for the "default layout", and should # be used if you rely on Emanote's default layout. From ba3363f15d7c8565e75f183044095297535e33ce Mon Sep 17 00:00:00 2001 From: Sridhar Ratnakumar <srid@srid.ca> Date: Mon, 1 Aug 2022 16:01:20 -0400 Subject: [PATCH 16/54] Add stork to nix shell --- flake.nix | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index a2f082f36..4aedbcc63 100644 --- a/flake.nix +++ b/flake.nix @@ -29,7 +29,8 @@ buildTools = hp: { inherit (pkgs) treefmt - nixpkgs-fmt; + nixpkgs-fmt + stork; inherit (hp) cabal-fmt ormolu; From 12cf3a129da289607126655517a2947f3381ac93 Mon Sep 17 00:00:00 2001 From: Sridhar Ratnakumar <srid@srid.ca> Date: Mon, 1 Aug 2022 17:32:19 -0400 Subject: [PATCH 17/54] Build stork.st index in Haskell We just add a route for Stork index, and let Haskell build it behind the scenes. Performance and correctness is 100% yet. --- default/index.yaml | 9 ++-- emanote.cabal | 3 ++ flake.lock | 8 ++-- flake.nix | 2 +- src/Emanote/Route/SiteRoute/Class.hs | 1 + src/Emanote/Route/SiteRoute/Type.hs | 9 ++++ src/Emanote/View/Stork.hs | 67 ++++++++++++++++++++++++++++ src/Emanote/View/Template.hs | 28 +++++++----- 8 files changed, 105 insertions(+), 22 deletions(-) create mode 100644 src/Emanote/View/Stork.hs diff --git a/default/index.yaml b/default/index.yaml index 1a61ddb3e..3184af9bf 100644 --- a/default/index.yaml +++ b/default/index.yaml @@ -15,7 +15,7 @@ template: # Layout specific settings layout: # For base.tpl - base: + base: # The class to apply for <body> element when using base.tpl (used by note and book layouts) bodyClass: bg-gray-400 overflow-y-scroll note: @@ -52,10 +52,10 @@ pandoc: emanote:inline-tag:a/red/tag: bg-red-100 emanote:placeholder-message: text-gray-400 border-t-2 inline-block pt-0.5 emanote:error: text-l bg-red-100 p-2 border-2 border-black m-2 font-mono - emanote:error:aside: font-mono align-top text-xs mr-1 tracking-tighter opacity-50 hover:opacity-100 + emanote:error:aside: font-mono align-top text-xs mr-1 tracking-tighter opacity-50 hover:opacity-100 # You can also add your own class -> style mappings. We provide a sample below. sticky-note: px-3 py-1 rounded shadow bg-yellow-100 mx-2 transform -skew-y-1 scale-95 hover:scale-100 hover:border-yellow-400 hover:shadow-lg border-t-8 border-yellow-200 mb-8 mt-8 - note: p-2 mb-3 rounded shadow bg-gray-100 w-full float-none md:float-right md:w-1/2 md:clear-both + note: p-2 mb-3 rounded shadow bg-gray-100 w-full float-none md:float-right md:w-1/2 md:clear-both highlight-block: px-3 py-1 mb-3 rounded bg-${theme}-100 hover:border-${theme}-400 hover:shadow border-t-8 border-${theme}-200 highlight-inline: bg-yellow-200 px-2 py-0.5 rounded-xl center: flex justify-center items-center mx-auto @@ -160,7 +160,7 @@ js: (function() { const indexName = 'emanote-search'; // used to match input[data-stork] attribute value const baseUrl = document.currentScript.getAttribute('data-emanote-base-url') || '/'; - const indexUrl = baseUrl + 'stork.st'; + const indexUrl = baseUrl + '-/stork.st'; if (document.readyState !== 'complete') { window.addEventListener('load', function() { stork.register(indexName, indexUrl); @@ -244,4 +244,3 @@ js: emanote: # Whether to automatically treat folder notes as a folgezettel parent of its contents folder-folgezettel: true - diff --git a/emanote.cabal b/emanote.cabal index e25b21276..34f01b277 100644 --- a/emanote.cabal +++ b/emanote.cabal @@ -126,6 +126,7 @@ common library-common , pandoc-types , parsec , path-tree >=0.2 + , process-extras , profunctors , relude >=1.0 , shower @@ -135,6 +136,7 @@ common library-common , tailwind >=0.3 , text , time + , tomland , unionmount >=0.2 , unliftio , unordered-containers @@ -196,6 +198,7 @@ library Emanote.View.Common Emanote.View.Export Emanote.View.LiveServerFiles + Emanote.View.Stork Emanote.View.TagIndex Emanote.View.TaskIndex Emanote.View.Template diff --git a/flake.lock b/flake.lock index 4eacc51cd..bbe8e1374 100644 --- a/flake.lock +++ b/flake.lock @@ -3,16 +3,16 @@ "ema": { "flake": false, "locked": { - "lastModified": 1658331162, - "narHash": "sha256-13PYisWFUbrS+HOegqBMA1SRuG5fZNOVXccAlfOIylY=", + "lastModified": 1659387161, + "narHash": "sha256-7RZT1J6E2GSomxNMBi6VX+0l0xa9uKj0caaUJ2wSK1w=", "owner": "srid", "repo": "ema", - "rev": "67da7235a14e93e468112bb8d2217fb0e092304b", + "rev": "fcba11484741a211633a58d995baa749ca473c50", "type": "github" }, "original": { "owner": "srid", - "ref": "multisite", + "ref": "multisite-siteOutputIO", "repo": "ema", "type": "github" } diff --git a/flake.nix b/flake.nix index 4aedbcc63..ed38b769d 100644 --- a/flake.nix +++ b/flake.nix @@ -10,7 +10,7 @@ haskell-flake.url = "github:srid/haskell-flake"; # Haskell dependency overrides - ema.url = "github:srid/ema/multisite"; + ema.url = "github:srid/ema/multisite-siteOutputIO"; ema.flake = false; tailwind-haskell.url = "github:srid/tailwind-haskell/master"; tailwind-haskell.inputs.nixpkgs.follows = "nixpkgs"; diff --git a/src/Emanote/Route/SiteRoute/Class.hs b/src/Emanote/Route/SiteRoute/Class.hs index 5907c3b9c..367184274 100644 --- a/src/Emanote/Route/SiteRoute/Class.hs +++ b/src/Emanote/Route/SiteRoute/Class.hs @@ -60,6 +60,7 @@ emanoteGeneratableRoutes model = NE.filter (not . null) $ NE.inits tagPath in VirtualRoute_Index : VirtualRoute_Export : + VirtualRoute_StorkIndex : VirtualRoute_TaskIndex : (VirtualRoute_TagIndex <$> toList tagPaths) in htmlRoutes diff --git a/src/Emanote/Route/SiteRoute/Type.hs b/src/Emanote/Route/SiteRoute/Type.hs index 0dfe10548..75297bee8 100644 --- a/src/Emanote/Route/SiteRoute/Type.hs +++ b/src/Emanote/Route/SiteRoute/Type.hs @@ -24,6 +24,7 @@ data VirtualRoute = VirtualRoute_Index | VirtualRoute_TagIndex [HT.TagNode] | VirtualRoute_Export + | VirtualRoute_StorkIndex | VirtualRoute_TaskIndex deriving stock (Eq, Ord, Show, Generic) deriving anyclass (ToJSON) @@ -65,6 +66,7 @@ decodeVirtualRoute fp = (VirtualRoute_Index <$ decodeIndexR fp) <|> (VirtualRoute_TagIndex <$> decodeTagIndexR fp) <|> (VirtualRoute_Export <$ decodeExportR fp) + <|> (VirtualRoute_StorkIndex <$ decodeStorkIndexR fp) <|> (VirtualRoute_TaskIndex <$ decodeTaskIndexR fp) decodeIndexR :: FilePath -> Maybe () @@ -77,6 +79,11 @@ decodeExportR fp = do "-" :| ["export.json"] <- R.unRoute <$> R.decodeAnyRoute fp pass +decodeStorkIndexR :: FilePath -> Maybe () +decodeStorkIndexR fp = do + "-" :| ["stork.st"] <- R.unRoute <$> R.decodeAnyRoute fp + pass + decodeTagIndexR :: FilePath -> Maybe [HT.TagNode] decodeTagIndexR fp = do "-" :| "tags" : tagPath <- pure $ R.unRoute $ R.decodeHtmlRoute fp @@ -97,6 +104,8 @@ encodeVirtualRoute = \case R.encodeRoute $ R.R @() @'Ext.Html $ "-" :| ["all"] VirtualRoute_Export -> R.encodeRoute $ R.R @Ext.SourceExt @'Ext.AnyExt $ "-" :| ["export.json"] + VirtualRoute_StorkIndex -> + R.encodeRoute $ R.R @Ext.SourceExt @'Ext.AnyExt $ "-" :| ["stork.st"] VirtualRoute_TaskIndex -> R.encodeRoute $ R.R @() @'Ext.Html $ "-" :| ["tasks"] diff --git a/src/Emanote/View/Stork.hs b/src/Emanote/View/Stork.hs new file mode 100644 index 000000000..ce100e240 --- /dev/null +++ b/src/Emanote/View/Stork.hs @@ -0,0 +1,67 @@ +{-# LANGUAGE TemplateHaskell #-} + +module Emanote.View.Stork + ( renderStorkIndex, + ) +where + +import Control.Monad.Logger (MonadLoggerIO) +import Data.IxSet.Typed qualified as Ix +import Emanote.Model (Model) +import Emanote.Model.Note qualified as N +import Emanote.Model.Title qualified as Tit +import Emanote.Model.Type qualified as M +import Emanote.Prelude (log, logW) +import Emanote.Route qualified as R +import Emanote.Source.Loc qualified as Loc +import Optics.Core ((^.)) +import Relude +import System.FilePath ((</>)) +import System.Process.ByteString (readProcessWithExitCode) +import System.Which (staticWhich) +import Toml + +storkBin :: FilePath +storkBin = $(staticWhich "stork") + +data Input = Input + { inputFiles :: [File] + } + deriving stock (Eq, Show) + +data File = File + { filePath :: FilePath, + fileUrl :: Text, + fileTitle :: Text + } + deriving stock (Eq, Show) + +fileCodec :: TomlCodec File +fileCodec = + File + <$> Toml.string "path" .= filePath + <*> Toml.text "url" .= fileUrl + <*> Toml.text "title" .= fileTitle + +inputCodec :: TomlCodec Input +inputCodec = + Input + <$> Toml.list fileCodec "input.files" .= inputFiles + +renderStorkIndex :: (MonadIO m, MonadLoggerIO m) => Model -> m LByteString +renderStorkIndex model = do + -- TODO: this should retrieve from cache if model hasn't changed + logW "Generating search index using Stork (this may be expensive)" + let storkToml = Toml.encode inputCodec $ Input $ storkFiles model + (_, !index, _) <- liftIO $ readProcessWithExitCode storkBin ["build", "-t", "--input", "-", "--output", "-"] (encodeUtf8 storkToml) + log "Done generating Stork index" + pure $ toLazy index + +storkFiles :: Model -> [File] +storkFiles model = + let baseDir = Loc.locPath . Loc.primaryLayer $ model ^. M.modelLayers + in Ix.toList (model ^. M.modelNotes) <&> \note -> + File + ((baseDir </>) $ R.withLmlRoute R.encodeRoute $ note ^. N.noteRoute) + (toText $ R.encodeRoute $ N.noteHtmlRoute note) + (Tit.toPlain $ note ^. N.noteTitle) diff --git a/src/Emanote/View/Template.hs b/src/Emanote/View/Template.hs index db743d12e..7c06fbaa0 100644 --- a/src/Emanote/View/Template.hs +++ b/src/Emanote/View/Template.hs @@ -1,5 +1,6 @@ module Emanote.View.Template (emanoteSiteOutput, render) where +import Control.Monad.Logger (MonadLoggerIO) import Data.Aeson.Types qualified as Aeson import Data.List (partition) import Data.List.NonEmpty qualified as NE @@ -22,6 +23,7 @@ import Emanote.Route.SiteRoute qualified as SR import Emanote.Route.SiteRoute.Class (indexRoute) import Emanote.View.Common qualified as C import Emanote.View.Export (renderGraphExport) +import Emanote.View.Stork (renderStorkIndex) import Emanote.View.TagIndex qualified as TagIndex import Emanote.View.TaskIndex qualified as TaskIndex import Heist qualified as H @@ -37,10 +39,10 @@ import Relude import Text.Pandoc.Builder qualified as B import Text.Pandoc.Definition (Pandoc (..)) -emanoteSiteOutput :: Prism' FilePath SiteRoute -> ModelEma -> SR.SiteRoute -> Ema.Asset LByteString -emanoteSiteOutput rp model' r = +emanoteSiteOutput :: (MonadIO m, MonadLoggerIO m) => Prism' FilePath SiteRoute -> ModelEma -> SR.SiteRoute -> m (Ema.Asset LByteString) +emanoteSiteOutput rp model' r = do let model = M.withRoutePrism rp model' - in render model r <&> fixStaticUrl + render model r <&> fmap fixStaticUrl where -- See the FIXME in more-head.tpl. fixStaticUrl :: LByteString -> LByteString @@ -62,7 +64,7 @@ emanoteSiteOutput rp model' r = guard $ not $ T.null prefix pure prefix -render :: Model -> SR.SiteRoute -> Ema.Asset LByteString +render :: (MonadIO m, MonadLoggerIO m) => Model -> SR.SiteRoute -> m (Ema.Asset LByteString) render m sr = let setErrorPageMeta = MN.noteMeta .~ SData.mergeAesons (withTemplateName "/templates/error" :| [withSiteTitle "Emanote Error"]) @@ -73,14 +75,14 @@ render m sr = MN.missingNote hereRoute (toText urlPath) & setErrorPageMeta & MN.noteTitle .~ "! Missing link" - Ema.AssetGenerated Ema.Html $ renderLmlHtml m note404 + pure $ Ema.AssetGenerated Ema.Html $ renderLmlHtml m note404 SR.SiteRoute_AmbiguousR urlPath notes -> do let noteAmb = MN.ambiguousNoteURL urlPath notes & setErrorPageMeta & MN.noteTitle .~ "! Ambiguous link" - Ema.AssetGenerated Ema.Html $ renderLmlHtml m noteAmb - SR.SiteRoute_ResourceRoute r -> renderResourceRoute m r + pure $ Ema.AssetGenerated Ema.Html $ renderLmlHtml m noteAmb + SR.SiteRoute_ResourceRoute r -> pure $ renderResourceRoute m r SR.SiteRoute_VirtualRoute r -> renderVirtualRoute m r renderResourceRoute :: Model -> SR.ResourceRoute -> Ema.Asset LByteString @@ -95,16 +97,18 @@ renderResourceRoute m = \case SR.ResourceRoute_StaticFile _ fpAbs -> Ema.AssetStatic fpAbs -renderVirtualRoute :: Model -> SR.VirtualRoute -> Ema.Asset LByteString +renderVirtualRoute :: (MonadIO m, MonadLoggerIO m) => Model -> SR.VirtualRoute -> m (Ema.Asset LByteString) renderVirtualRoute m = \case SR.VirtualRoute_TagIndex mtag -> - Ema.AssetGenerated Ema.Html $ TagIndex.renderTagIndex m mtag + pure $ Ema.AssetGenerated Ema.Html $ TagIndex.renderTagIndex m mtag SR.VirtualRoute_Index -> - Ema.AssetGenerated Ema.Html $ renderSRIndex m + pure $ Ema.AssetGenerated Ema.Html $ renderSRIndex m SR.VirtualRoute_Export -> - Ema.AssetGenerated Ema.Other $ renderGraphExport m + pure $ Ema.AssetGenerated Ema.Other $ renderGraphExport m + SR.VirtualRoute_StorkIndex -> + Ema.AssetGenerated Ema.Other <$> renderStorkIndex m SR.VirtualRoute_TaskIndex -> - Ema.AssetGenerated Ema.Html $ TaskIndex.renderTasks m + pure $ Ema.AssetGenerated Ema.Html $ TaskIndex.renderTasks m renderSRIndex :: Model -> LByteString renderSRIndex model = do From b216807f212cb13561c966750625b1f4231ba3c5 Mon Sep 17 00:00:00 2001 From: Sridhar Ratnakumar <srid@srid.ca> Date: Mon, 1 Aug 2022 17:37:49 -0400 Subject: [PATCH 18/54] Fix autoformat --- src/Emanote/View/Stork.hs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Emanote/View/Stork.hs b/src/Emanote/View/Stork.hs index ce100e240..0157383f6 100644 --- a/src/Emanote/View/Stork.hs +++ b/src/Emanote/View/Stork.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE BangPatterns #-} {-# LANGUAGE TemplateHaskell #-} module Emanote.View.Stork @@ -19,7 +20,7 @@ import Relude import System.FilePath ((</>)) import System.Process.ByteString (readProcessWithExitCode) import System.Which (staticWhich) -import Toml +import Toml (TomlCodec, encode, list, string, text, (.=)) storkBin :: FilePath storkBin = $(staticWhich "stork") From 79f04dd0caa0c1317a4186901c1e546f9f089cfc Mon Sep 17 00:00:00 2001 From: Sridhar Ratnakumar <srid@srid.ca> Date: Mon, 1 Aug 2022 17:42:42 -0400 Subject: [PATCH 19/54] Fix hlint warning --- src/Emanote/View/Stork.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Emanote/View/Stork.hs b/src/Emanote/View/Stork.hs index 0157383f6..0301b7468 100644 --- a/src/Emanote/View/Stork.hs +++ b/src/Emanote/View/Stork.hs @@ -25,7 +25,7 @@ import Toml (TomlCodec, encode, list, string, text, (.=)) storkBin :: FilePath storkBin = $(staticWhich "stork") -data Input = Input +newtype Input = Input { inputFiles :: [File] } deriving stock (Eq, Show) From 62ff42ed3f24caae594258c52f74433bed928ae4 Mon Sep 17 00:00:00 2001 From: Sridhar Ratnakumar <srid@srid.ca> Date: Mon, 1 Aug 2022 17:53:22 -0400 Subject: [PATCH 20/54] Up ver --- emanote.cabal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emanote.cabal b/emanote.cabal index 34f01b277..c4543d94e 100644 --- a/emanote.cabal +++ b/emanote.cabal @@ -1,6 +1,6 @@ cabal-version: 2.4 name: emanote -version: 0.6.19.0 +version: 0.6.20.0 license: AGPL-3.0-only copyright: 2021 Sridhar Ratnakumar maintainer: srid@srid.ca From 5dc1c38ab2767550e26838b6ddfeefffe1f3bfae Mon Sep 17 00:00:00 2001 From: Sridhar Ratnakumar <srid@srid.ca> Date: Mon, 1 Aug 2022 17:53:28 -0400 Subject: [PATCH 21/54] nix: add stork as runtime dependency --- flake.nix | 2 ++ 1 file changed, 2 insertions(+) diff --git a/flake.nix b/flake.nix index ed38b769d..4e099ee61 100644 --- a/flake.nix +++ b/flake.nix @@ -48,6 +48,8 @@ inherit (inputs'.tailwind-haskell.packages) tailwind; }; + modifier = drv: with pkgs.haskell.lib; + addBuildDepends drv [ pkgs.stork ]; }; packages.test = pkgs.runCommand "emanote-test" { } '' From dc82292bade41cf85b11d7758ad3888c4991a531 Mon Sep 17 00:00:00 2001 From: Kalle Fagerberg <kalle.f8@proton.me> Date: Tue, 2 Aug 2022 07:20:44 +0200 Subject: [PATCH 22/54] Added missing stork-search from headHtml --- docs/demo/orgmode.yaml | 1 + docs/resources/zk.md | 1 + docs/tips/js/math.md | 3 ++- docs/tips/js/mermaid.md | 3 ++- 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/demo/orgmode.yaml b/docs/demo/orgmode.yaml index 26aea6e1d..025f8a4f3 100644 --- a/docs/demo/orgmode.yaml +++ b/docs/demo/orgmode.yaml @@ -2,3 +2,4 @@ page: headHtml: | <snippet var="js.prism" /> <snippet var="js.mathjax" /> + <snippet var="js.stork-search" /> diff --git a/docs/resources/zk.md b/docs/resources/zk.md index dac791339..c627886c8 100644 --- a/docs/resources/zk.md +++ b/docs/resources/zk.md @@ -3,6 +3,7 @@ page: headHtml: | <snippet var="js.highlightjs" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.5.1/languages/ini.min.js"></script> + <snippet var="js.stork-search" /> --- # zk diff --git a/docs/tips/js/math.md b/docs/tips/js/math.md index 9782eba25..dc53895c2 100644 --- a/docs/tips/js/math.md +++ b/docs/tips/js/math.md @@ -3,6 +3,7 @@ page: headHtml: | <snippet var="js.prism" /> <snippet var="js.mathjax" /> + <snippet var="js.stork-search" /> --- @@ -29,4 +30,4 @@ page: ## Demo When $a \ne 0$, there are two solutions to $ax^2 + bx + c = 0$ and they are -$$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$ \ No newline at end of file +$$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$ diff --git a/docs/tips/js/mermaid.md b/docs/tips/js/mermaid.md index ab9810256..70e08a80f 100644 --- a/docs/tips/js/mermaid.md +++ b/docs/tips/js/mermaid.md @@ -3,6 +3,7 @@ page: headHtml: | <snippet var="js.highlightjs" /> <snippet var="js.mermaid" /> + <snippet var="js.stork-search" /> --- # Mermaid Diagrams @@ -89,4 +90,4 @@ gantt Describe gantt syntax :after doc1, 3d Add gantt diagram to demo page :20h Add another diagram to demo page :48h -``` \ No newline at end of file +``` From b82c6ff497052cdbcf445a0efdb81335267c08dd Mon Sep 17 00:00:00 2001 From: Sridhar Ratnakumar <srid@srid.ca> Date: Wed, 3 Aug 2022 13:51:10 -0400 Subject: [PATCH 23/54] Advance ema --- flake.lock | 8 ++++---- flake.nix | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/flake.lock b/flake.lock index bbe8e1374..19ef28d41 100644 --- a/flake.lock +++ b/flake.lock @@ -3,16 +3,16 @@ "ema": { "flake": false, "locked": { - "lastModified": 1659387161, - "narHash": "sha256-7RZT1J6E2GSomxNMBi6VX+0l0xa9uKj0caaUJ2wSK1w=", + "lastModified": 1659481510, + "narHash": "sha256-R8KdVEaWxeAGRuNs6FIn0Zge+E0L+mtzfNgcaflzuTA=", "owner": "srid", "repo": "ema", - "rev": "fcba11484741a211633a58d995baa749ca473c50", + "rev": "94b19ea2a04f3fa08261a8a07fefde3f117c2a74", "type": "github" }, "original": { "owner": "srid", - "ref": "multisite-siteOutputIO", + "ref": "multisite", "repo": "ema", "type": "github" } diff --git a/flake.nix b/flake.nix index 4e099ee61..84c6fa582 100644 --- a/flake.nix +++ b/flake.nix @@ -10,7 +10,7 @@ haskell-flake.url = "github:srid/haskell-flake"; # Haskell dependency overrides - ema.url = "github:srid/ema/multisite-siteOutputIO"; + ema.url = "github:srid/ema/multisite"; ema.flake = false; tailwind-haskell.url = "github:srid/tailwind-haskell/master"; tailwind-haskell.inputs.nixpkgs.follows = "nixpkgs"; @@ -42,6 +42,7 @@ ema; }; overrides = self: super: with pkgs.haskell.lib; { + ema = dontCheck super.ema; heist-emanote = dontCheck (doJailbreak (unmarkBroken super.heist-emanote)); # Tests are broken. ixset-typed = unmarkBroken super.ixset-typed; pandoc-link-context = unmarkBroken super.pandoc-link-context; From bcd9ee7c48ee71a465fadca56794ab2f9a622c8e Mon Sep 17 00:00:00 2001 From: Kalle Fagerberg <kalle.f8@proton.me> Date: Sat, 13 Aug 2022 17:04:20 +0200 Subject: [PATCH 24/54] Revert "Added missing stork-search from headHtml" This reverts commit dc82292bade41cf85b11d7758ad3888c4991a531. --- docs/demo/orgmode.yaml | 1 - docs/resources/zk.md | 1 - docs/tips/js/math.md | 3 +-- docs/tips/js/mermaid.md | 3 +-- 4 files changed, 2 insertions(+), 6 deletions(-) diff --git a/docs/demo/orgmode.yaml b/docs/demo/orgmode.yaml index 025f8a4f3..26aea6e1d 100644 --- a/docs/demo/orgmode.yaml +++ b/docs/demo/orgmode.yaml @@ -2,4 +2,3 @@ page: headHtml: | <snippet var="js.prism" /> <snippet var="js.mathjax" /> - <snippet var="js.stork-search" /> diff --git a/docs/resources/zk.md b/docs/resources/zk.md index c627886c8..dac791339 100644 --- a/docs/resources/zk.md +++ b/docs/resources/zk.md @@ -3,7 +3,6 @@ page: headHtml: | <snippet var="js.highlightjs" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.5.1/languages/ini.min.js"></script> - <snippet var="js.stork-search" /> --- # zk diff --git a/docs/tips/js/math.md b/docs/tips/js/math.md index dc53895c2..9782eba25 100644 --- a/docs/tips/js/math.md +++ b/docs/tips/js/math.md @@ -3,7 +3,6 @@ page: headHtml: | <snippet var="js.prism" /> <snippet var="js.mathjax" /> - <snippet var="js.stork-search" /> --- @@ -30,4 +29,4 @@ page: ## Demo When $a \ne 0$, there are two solutions to $ax^2 + bx + c = 0$ and they are -$$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$ +$$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$ \ No newline at end of file diff --git a/docs/tips/js/mermaid.md b/docs/tips/js/mermaid.md index 70e08a80f..ab9810256 100644 --- a/docs/tips/js/mermaid.md +++ b/docs/tips/js/mermaid.md @@ -3,7 +3,6 @@ page: headHtml: | <snippet var="js.highlightjs" /> <snippet var="js.mermaid" /> - <snippet var="js.stork-search" /> --- # Mermaid Diagrams @@ -90,4 +89,4 @@ gantt Describe gantt syntax :after doc1, 3d Add gantt diagram to demo page :20h Add another diagram to demo page :48h -``` +``` \ No newline at end of file From d7d7cb5512853cb2f03b99490fe95081fccfa03f Mon Sep 17 00:00:00 2001 From: Kalle Fagerberg <kalle.f8@proton.me> Date: Sat, 13 Aug 2022 17:22:51 +0200 Subject: [PATCH 25/54] Moved back to be in templates instead of snippet --- default/index.yaml | 124 ------------------ .../components/stork-search-js-book.tpl | 49 +++++++ .../components/stork-search-js-note.tpl | 13 ++ .../templates/components/stork-search-js.tpl | 20 +++ default/templates/components/stork-search.tpl | 3 +- default/templates/layouts/book.tpl | 1 + default/templates/layouts/note.tpl | 13 ++ docs/demo/neuron-layout.md | 4 - docs/index.yaml | 1 - 9 files changed, 97 insertions(+), 131 deletions(-) create mode 100644 default/templates/components/stork-search-js-book.tpl create mode 100644 default/templates/components/stork-search-js-note.tpl create mode 100644 default/templates/components/stork-search-js.tpl diff --git a/default/index.yaml b/default/index.yaml index a94d98e3e..5047a09cd 100644 --- a/default/index.yaml +++ b/default/index.yaml @@ -123,130 +123,6 @@ js: </script> <script async="" id="MathJax-script" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script> - stork-search-base: | - <link rel="stylesheet" href="https://files.stork-search.net/releases/v1.5.0/basic.css" /> - <!-- Stork-search styling base stylings --> - <style> - .stork-wrapper.hidden { - /* undo the hidden styling, in effect enabling the search box */ - display: block; - } - - .stork-wrapper .stork-output { - margin-top: 0; - border-radius: 0; - position: sticky; - border-color: rgba(99,102,241,var(--tw-border-opacity)); - --tw-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1),0 4px 6px -2px rgba(0, 0, 0, 0.05); - box-shadow: var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow); - } - - .stork-wrapper .stork-message { - padding: 0.5rem 1rem; - border-radius: 0; - border-color: rgba(99,102,241,var(--tw-border-opacity)); - } - - .stork-wrapper .stork-close-button { - top: 0; - margin: 0.8em 0.6em; - } - - .stork-wrapper .stork-close-button svg { - top: unset; - margin-left: auto; - margin-right: auto; - } - </style> - <!-- Stork search scripts, styling added in more-head.tpl --> - <script src="https://files.stork-search.net/releases/v1.5.0/stork.js"></script> - <ema:metadata> - <with var="template"> - <script data-emanote-base-url="${value:baseUrl}"> - (function() { - const indexName = 'emanote-search'; // used to match input[data-stork] attribute value - const baseUrl = document.currentScript.getAttribute('data-emanote-base-url') || '/'; - const indexUrl = baseUrl + '-/stork.st'; - if (document.readyState !== 'complete') { - window.addEventListener('load', function() { - stork.register(indexName, indexUrl); - }); - } else { - stork.register(indexName, indexUrl, {forceOverwrite: true}); - } - })(); - </script> - </with> - </ema:metadata> - stork-search-book: | - <snippet var="js.stork-search-base"/> - <!-- Stork-search styling, specific to Emanote's book layout --> - <style> - .stork-wrapper > input { - border-top-color: rgba(209,213,219,var(--tw-border-opacity)); - border-left-color: transparent; - border-right-color: transparent; - } - - @media (min-width: 768px) { - .stork-wrapper > input { - border-top-color: transparent; - border-right-color: rgba(209,213,219,var(--tw-border-opacity)); - } - - .stork-wrapper .stork-output { - top: 0; - left: calc(100% - 1px); - position: absolute; - width: calc(768px - 12rem); - } - - .stork-wrapper { - margin-right: -1px; - } - } - - @media (min-width: 1024px) { - .stork-wrapper .stork-output { - width: calc(1024px - 12rem); - } - } - - @media (min-width: 1280px) { - .stork-wrapper .stork-output { - width: calc(1280px - 16rem); - } - } - - @media (min-width: 1536px) { - .stork-wrapper .stork-output { - width: calc(1536px - 16rem); - } - } - - nav#sidebar { - z-index: 100; - } - </style> - stork-search-note: | - <snippet var="js.stork-search-base"/> - <!-- Stork-search styling, specific to Emanote's Neuron-like layout --> - <style> - .stork-wrapper .stork-output { - position: absolute; - } - - .stork-wrapper > input { - border-top-color: transparent; - border-left-color: transparent; - border-right-color: transparent; - } - </style> - # This adds styling for the "default layout", and should - # be used if you rely on Emanote's default layout. - stork-search: | - <snippet var="js.stork-search-book"/> - emanote: # Whether to automatically treat folder notes as a folgezettel parent of its contents folder-folgezettel: true diff --git a/default/templates/components/stork-search-js-book.tpl b/default/templates/components/stork-search-js-book.tpl new file mode 100644 index 000000000..85d20e882 --- /dev/null +++ b/default/templates/components/stork-search-js-book.tpl @@ -0,0 +1,49 @@ +<apply template="components/stork-search-js" /> +<!-- Stork-search styling, specific to Emanote's book layout --> +<style> + .stork-wrapper > input { + border-top-color: rgba(209,213,219,var(--tw-border-opacity)); + border-left-color: transparent; + border-right-color: transparent; + } + + @media (min-width: 768px) { + .stork-wrapper > input { + border-top-color: transparent; + border-right-color: rgba(209,213,219,var(--tw-border-opacity)); + } + + .stork-wrapper .stork-output { + top: 0; + left: calc(100% - 1px); + position: absolute; + width: calc(768px - 12rem); + } + + .stork-wrapper { + margin-right: -1px; + } + } + + @media (min-width: 1024px) { + .stork-wrapper .stork-output { + width: calc(1024px - 12rem); + } + } + + @media (min-width: 1280px) { + .stork-wrapper .stork-output { + width: calc(1280px - 16rem); + } + } + + @media (min-width: 1536px) { + .stork-wrapper .stork-output { + width: calc(1536px - 16rem); + } + } + + nav#sidebar { + z-index: 100; + } +</style> diff --git a/default/templates/components/stork-search-js-note.tpl b/default/templates/components/stork-search-js-note.tpl new file mode 100644 index 000000000..2b4f20cd0 --- /dev/null +++ b/default/templates/components/stork-search-js-note.tpl @@ -0,0 +1,13 @@ +<apply template="components/stork-search-js" /> +<!-- Stork-search styling, specific to Emanote's Neuron-like layout --> +<style> + .stork-wrapper .stork-output { + position: absolute; + } + + .stork-wrapper > input { + border-top-color: transparent; + border-left-color: transparent; + border-right-color: transparent; + } +</style> diff --git a/default/templates/components/stork-search-js.tpl b/default/templates/components/stork-search-js.tpl new file mode 100644 index 000000000..54df28a94 --- /dev/null +++ b/default/templates/components/stork-search-js.tpl @@ -0,0 +1,20 @@ +<link rel="stylesheet" href="https://files.stork-search.net/releases/v1.5.0/basic.css" /> +<script src="https://files.stork-search.net/releases/v1.5.0/stork.js"></script> +<ema:metadata> + <with var="template"> + <script data-emanote-base-url="${value:baseUrl}"> + (function() { + const indexName = 'emanote-search'; // used to match input[data-stork] attribute value + const baseUrl = document.currentScript.getAttribute('data-emanote-base-url') || '/'; + const indexUrl = baseUrl + '-/stork.st'; + if (document.readyState !== 'complete') { + window.addEventListener('load', function() { + stork.register(indexName, indexUrl); + }); + } else { + stork.register(indexName, indexUrl, {forceOverwrite: true}); + } + })(); + </script> + </with> +</ema:metadata> diff --git a/default/templates/components/stork-search.tpl b/default/templates/components/stork-search.tpl index 08cbbcefa..189de0cf8 100644 --- a/default/templates/components/stork-search.tpl +++ b/default/templates/components/stork-search.tpl @@ -1,5 +1,4 @@ -<!-- the "hidden" is disabled via "js.stork-search" snippet --> -<div class="stork-wrapper hidden"> +<div class="stork-wrapper"> <input data-stork="emanote-search" class="px-4 py-2 block w-full rounded-none border border-gray-300 focus:ring-indigo-500 focus:border-indigo-500 focus:outline-none" placeholder="Search..." /> <div data-stork="emanote-search-output" class="stork-output"></div> </div> diff --git a/default/templates/layouts/book.tpl b/default/templates/layouts/book.tpl index 9900bc7f6..aa63d914d 100644 --- a/default/templates/layouts/book.tpl +++ b/default/templates/layouts/book.tpl @@ -77,4 +77,5 @@ <apply template="components/footer" /> </div> </bind> + <apply template="components/stork-search-js-book" /> </apply> diff --git a/default/templates/layouts/note.tpl b/default/templates/layouts/note.tpl index f645a97b7..84803ec37 100644 --- a/default/templates/layouts/note.tpl +++ b/default/templates/layouts/note.tpl @@ -31,4 +31,17 @@ </div> </div> </bind> + <apply template="components/stork-search-js-note" /> + <!-- Stork-search styling, specific to Emanote's Neuron-like layout --> + <style> + .stork-wrapper .stork-output { + position: absolute; + } + + .stork-wrapper > input { + border-top-color: transparent; + border-left-color: transparent; + border-right-color: transparent; + } + </style> </apply> diff --git a/docs/demo/neuron-layout.md b/docs/demo/neuron-layout.md index 81ed2ae8d..4e83522f5 100644 --- a/docs/demo/neuron-layout.md +++ b/docs/demo/neuron-layout.md @@ -1,10 +1,6 @@ --- template: name: /templates/layouts/note -page: - headHtml: | - <snippet var="js.prism" /> - <snippet var="js.stork-search-note" /> --- # Neuron-like layout diff --git a/docs/index.yaml b/docs/index.yaml index c227db7f8..38dd0734a 100644 --- a/docs/index.yaml +++ b/docs/index.yaml @@ -5,4 +5,3 @@ page: siteTitle: Emanote headHtml: | <snippet var="js.highlightjs" /> - <snippet var="js.stork-search" /> From 460a1f2a0ada991d75c6dc1d357e5a8eb14708fa Mon Sep 17 00:00:00 2001 From: Sridhar Ratnakumar <srid@srid.ca> Date: Sat, 13 Aug 2022 12:18:14 -0400 Subject: [PATCH 26/54] Fix compilation --- src/Emanote.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Emanote.hs b/src/Emanote.hs index 3ee1dbdb2..c381188f5 100644 --- a/src/Emanote.hs +++ b/src/Emanote.hs @@ -50,7 +50,7 @@ instance IsRoute SiteRoute where instance EmaSite SiteRoute where type SiteArg SiteRoute = EmanoteConfig siteInput = emanoteSiteInput - siteOutput rp m r = pure $ View.emanoteSiteOutput rp m r + siteOutput rp m r = View.emanoteSiteOutput rp m r defaultEmanoteConfig :: CLI.Cli -> EmanoteConfig defaultEmanoteConfig cli = From 4957829f125a465a053cfcd49f452bd69bec429e Mon Sep 17 00:00:00 2001 From: Kalle Fagerberg <kalle.f8@proton.me> Date: Sat, 13 Aug 2022 18:39:48 +0200 Subject: [PATCH 27/54] Fixed template --- .../templates/components/stork-search-js-book.tpl | 2 +- .../templates/components/stork-search-js-note.tpl | 2 +- default/templates/layouts/book.tpl | 2 +- default/templates/layouts/note.tpl | 14 +------------- 4 files changed, 4 insertions(+), 16 deletions(-) diff --git a/default/templates/components/stork-search-js-book.tpl b/default/templates/components/stork-search-js-book.tpl index 85d20e882..622dbe364 100644 --- a/default/templates/components/stork-search-js-book.tpl +++ b/default/templates/components/stork-search-js-book.tpl @@ -1,4 +1,4 @@ -<apply template="components/stork-search-js" /> +<apply template="stork-search-js" /> <!-- Stork-search styling, specific to Emanote's book layout --> <style> .stork-wrapper > input { diff --git a/default/templates/components/stork-search-js-note.tpl b/default/templates/components/stork-search-js-note.tpl index 2b4f20cd0..880d96d4f 100644 --- a/default/templates/components/stork-search-js-note.tpl +++ b/default/templates/components/stork-search-js-note.tpl @@ -1,4 +1,4 @@ -<apply template="components/stork-search-js" /> +<apply template="stork-search-js" /> <!-- Stork-search styling, specific to Emanote's Neuron-like layout --> <style> .stork-wrapper .stork-output { diff --git a/default/templates/layouts/book.tpl b/default/templates/layouts/book.tpl index aa63d914d..c5904068b 100644 --- a/default/templates/layouts/book.tpl +++ b/default/templates/layouts/book.tpl @@ -76,6 +76,6 @@ </div> <apply template="components/footer" /> </div> + <apply template="components/stork-search-js-book" /> </bind> - <apply template="components/stork-search-js-book" /> </apply> diff --git a/default/templates/layouts/note.tpl b/default/templates/layouts/note.tpl index 84803ec37..cd4f3d2da 100644 --- a/default/templates/layouts/note.tpl +++ b/default/templates/layouts/note.tpl @@ -30,18 +30,6 @@ <apply template="components/footer" /> </div> </div> + <apply template="components/stork-search-js-note" /> </bind> - <apply template="components/stork-search-js-note" /> - <!-- Stork-search styling, specific to Emanote's Neuron-like layout --> - <style> - .stork-wrapper .stork-output { - position: absolute; - } - - .stork-wrapper > input { - border-top-color: transparent; - border-left-color: transparent; - border-right-color: transparent; - } - </style> </apply> From d957084be1377b18676093a208dadec84d1dc5f6 Mon Sep 17 00:00:00 2001 From: Kalle Fagerberg <kalle.f8@proton.me> Date: Sat, 13 Aug 2022 19:06:16 +0200 Subject: [PATCH 28/54] lint fix --- src/Emanote.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Emanote.hs b/src/Emanote.hs index c381188f5..cbb642a02 100644 --- a/src/Emanote.hs +++ b/src/Emanote.hs @@ -50,7 +50,7 @@ instance IsRoute SiteRoute where instance EmaSite SiteRoute where type SiteArg SiteRoute = EmanoteConfig siteInput = emanoteSiteInput - siteOutput rp m r = View.emanoteSiteOutput rp m r + siteOutput = View.emanoteSiteOutput defaultEmanoteConfig :: CLI.Cli -> EmanoteConfig defaultEmanoteConfig cli = From a30533932c7abddaeb2c0233f0b3cd6ebb492413 Mon Sep 17 00:00:00 2001 From: Sridhar Ratnakumar <srid@srid.ca> Date: Sat, 13 Aug 2022 13:44:36 -0400 Subject: [PATCH 29/54] nix: Use master branch of ema --- flake.lock | 8 ++++---- flake.nix | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/flake.lock b/flake.lock index 19ef28d41..5593f087c 100644 --- a/flake.lock +++ b/flake.lock @@ -3,16 +3,16 @@ "ema": { "flake": false, "locked": { - "lastModified": 1659481510, - "narHash": "sha256-R8KdVEaWxeAGRuNs6FIn0Zge+E0L+mtzfNgcaflzuTA=", + "lastModified": 1660337803, + "narHash": "sha256-5HKR+T8/OuNzATvdA/ZmTOQmEVODAfTkna+0VkYxpG8=", "owner": "srid", "repo": "ema", - "rev": "94b19ea2a04f3fa08261a8a07fefde3f117c2a74", + "rev": "459d3899e0b9ea13e23c81126279dc62530b994c", "type": "github" }, "original": { "owner": "srid", - "ref": "multisite", + "ref": "master", "repo": "ema", "type": "github" } diff --git a/flake.nix b/flake.nix index 84c6fa582..ffa81536c 100644 --- a/flake.nix +++ b/flake.nix @@ -10,7 +10,7 @@ haskell-flake.url = "github:srid/haskell-flake"; # Haskell dependency overrides - ema.url = "github:srid/ema/multisite"; + ema.url = "github:srid/ema/master"; ema.flake = false; tailwind-haskell.url = "github:srid/tailwind-haskell/master"; tailwind-haskell.inputs.nixpkgs.follows = "nixpkgs"; From f93922e7fb952a0d5b63271caa9e160eba7f99c2 Mon Sep 17 00:00:00 2001 From: Kalle Fagerberg <kalle.f8@proton.me> Date: Sat, 13 Aug 2022 20:12:40 +0200 Subject: [PATCH 30/54] Added missing styling --- .../templates/components/stork-search-js.tpl | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/default/templates/components/stork-search-js.tpl b/default/templates/components/stork-search-js.tpl index 54df28a94..f44e859b4 100644 --- a/default/templates/components/stork-search-js.tpl +++ b/default/templates/components/stork-search-js.tpl @@ -18,3 +18,31 @@ </script> </with> </ema:metadata> +<!-- Stork-search styling base stylings --> +<style> + .stork-wrapper .stork-output { + margin-top: 0; + border-radius: 0; + position: sticky; + border-color: rgba(99,102,241,var(--tw-border-opacity)); + --tw-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1),0 4px 6px -2px rgba(0, 0, 0, 0.05); + box-shadow: var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow); + } + + .stork-wrapper .stork-message { + padding: 0.5rem 1rem; + border-radius: 0; + border-color: rgba(99,102,241,var(--tw-border-opacity)); + } + + .stork-wrapper .stork-close-button { + top: 0; + margin: 0.8em 0.6em; + } + + .stork-wrapper .stork-close-button svg { + top: unset; + margin-left: auto; + margin-right: auto; + } +</style> From 9f47d007797851555e59e5d53a2d156d39f897da Mon Sep 17 00:00:00 2001 From: Kalle Fagerberg <kalle.f8@proton.me> Date: Sat, 13 Aug 2022 21:38:48 +0200 Subject: [PATCH 31/54] Changed to modal --- default/templates/base.tpl | 1 + default/templates/components/breadcrumbs.tpl | 7 ++- .../templates/components/stork-search-css.tpl | 18 +++++++ .../components/stork-search-js-book.tpl | 49 ------------------- .../components/stork-search-js-note.tpl | 13 ----- .../templates/components/stork-search-js.tpl | 43 ++++++---------- .../templates/components/stork-search-nav.tpl | 8 +++ default/templates/components/stork-search.tpl | 30 ++++++++++-- default/templates/layouts/book.tpl | 3 +- default/templates/layouts/note.tpl | 5 +- 10 files changed, 78 insertions(+), 99 deletions(-) create mode 100644 default/templates/components/stork-search-css.tpl delete mode 100644 default/templates/components/stork-search-js-book.tpl delete mode 100644 default/templates/components/stork-search-js-note.tpl create mode 100644 default/templates/components/stork-search-nav.tpl diff --git a/default/templates/base.tpl b/default/templates/base.tpl index 7a85417ba..92660a578 100644 --- a/default/templates/base.tpl +++ b/default/templates/base.tpl @@ -44,6 +44,7 @@ <body class="${bodyClass}"> <body-main /> + <apply template="components/stork-search" /> </body> </html> diff --git a/default/templates/components/breadcrumbs.tpl b/default/templates/components/breadcrumbs.tpl index 0bf79750f..30b315e63 100644 --- a/default/templates/components/breadcrumbs.tpl +++ b/default/templates/components/breadcrumbs.tpl @@ -25,6 +25,11 @@ </ema:breadcrumbs> </ul> </div> + <button + class="inline px-2 py-1 text-white bg-${theme}-100 outline-none cursor-pointer focus:outline-none" + title="Search documents" type="button" + onclick="toggleSearch()" + >🔍</button> <button class="inline px-2 py-1 text-white bg-${theme}-600 outline-none cursor-pointer focus:outline-none" title="Toggle sidebar" type="button" onclick="toggleHidden('sidebar')"> @@ -40,4 +45,4 @@ } </script> </div> -</nav> \ No newline at end of file +</nav> diff --git a/default/templates/components/stork-search-css.tpl b/default/templates/components/stork-search-css.tpl new file mode 100644 index 000000000..0ca3701e4 --- /dev/null +++ b/default/templates/components/stork-search-css.tpl @@ -0,0 +1,18 @@ +<link rel="stylesheet" href="https://files.stork-search.net/releases/v1.5.0/flat.css" /> +<!-- Custom Stork-search styling for Emanote --> +<style> + #stork-search-container { + z-index: 1000; + background-color: rgb(15 23 42/.8); + } + + .stork-overflow-hidden-important { + overflow: hidden !important; + } + + .stork-wrapper-flat .stork-close-button svg { + /* small bugfix in Stork's stock styling */ + margin: auto; + } +</style> + diff --git a/default/templates/components/stork-search-js-book.tpl b/default/templates/components/stork-search-js-book.tpl deleted file mode 100644 index 622dbe364..000000000 --- a/default/templates/components/stork-search-js-book.tpl +++ /dev/null @@ -1,49 +0,0 @@ -<apply template="stork-search-js" /> -<!-- Stork-search styling, specific to Emanote's book layout --> -<style> - .stork-wrapper > input { - border-top-color: rgba(209,213,219,var(--tw-border-opacity)); - border-left-color: transparent; - border-right-color: transparent; - } - - @media (min-width: 768px) { - .stork-wrapper > input { - border-top-color: transparent; - border-right-color: rgba(209,213,219,var(--tw-border-opacity)); - } - - .stork-wrapper .stork-output { - top: 0; - left: calc(100% - 1px); - position: absolute; - width: calc(768px - 12rem); - } - - .stork-wrapper { - margin-right: -1px; - } - } - - @media (min-width: 1024px) { - .stork-wrapper .stork-output { - width: calc(1024px - 12rem); - } - } - - @media (min-width: 1280px) { - .stork-wrapper .stork-output { - width: calc(1280px - 16rem); - } - } - - @media (min-width: 1536px) { - .stork-wrapper .stork-output { - width: calc(1536px - 16rem); - } - } - - nav#sidebar { - z-index: 100; - } -</style> diff --git a/default/templates/components/stork-search-js-note.tpl b/default/templates/components/stork-search-js-note.tpl deleted file mode 100644 index 880d96d4f..000000000 --- a/default/templates/components/stork-search-js-note.tpl +++ /dev/null @@ -1,13 +0,0 @@ -<apply template="stork-search-js" /> -<!-- Stork-search styling, specific to Emanote's Neuron-like layout --> -<style> - .stork-wrapper .stork-output { - position: absolute; - } - - .stork-wrapper > input { - border-top-color: transparent; - border-left-color: transparent; - border-right-color: transparent; - } -</style> diff --git a/default/templates/components/stork-search-js.tpl b/default/templates/components/stork-search-js.tpl index f44e859b4..ffe6583ce 100644 --- a/default/templates/components/stork-search-js.tpl +++ b/default/templates/components/stork-search-js.tpl @@ -1,8 +1,20 @@ -<link rel="stylesheet" href="https://files.stork-search.net/releases/v1.5.0/basic.css" /> <script src="https://files.stork-search.net/releases/v1.5.0/stork.js"></script> <ema:metadata> <with var="template"> <script data-emanote-base-url="${value:baseUrl}"> + function toggleSearch() { + document.getElementById('stork-search-container').classList.toggle('hidden'); + const shown = document.body.classList.toggle('stork-overflow-hidden-important'); + if (shown) { + document.getElementById('stork-search-input').focus(); + } + } + + function clearSearch() { + document.getElementById('stork-search-container').classList.add('hidden'); + document.body.classList.remove('stork-overflow-hidden-important'); + } + (function() { const indexName = 'emanote-search'; // used to match input[data-stork] attribute value const baseUrl = document.currentScript.getAttribute('data-emanote-base-url') || '/'; @@ -12,37 +24,10 @@ stork.register(indexName, indexUrl); }); } else { + // Override existing on Ema's hot-reload stork.register(indexName, indexUrl, {forceOverwrite: true}); } })(); </script> </with> </ema:metadata> -<!-- Stork-search styling base stylings --> -<style> - .stork-wrapper .stork-output { - margin-top: 0; - border-radius: 0; - position: sticky; - border-color: rgba(99,102,241,var(--tw-border-opacity)); - --tw-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1),0 4px 6px -2px rgba(0, 0, 0, 0.05); - box-shadow: var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow); - } - - .stork-wrapper .stork-message { - padding: 0.5rem 1rem; - border-radius: 0; - border-color: rgba(99,102,241,var(--tw-border-opacity)); - } - - .stork-wrapper .stork-close-button { - top: 0; - margin: 0.8em 0.6em; - } - - .stork-wrapper .stork-close-button svg { - top: unset; - margin-left: auto; - margin-right: auto; - } -</style> diff --git a/default/templates/components/stork-search-nav.tpl b/default/templates/components/stork-search-nav.tpl new file mode 100644 index 000000000..c96a0d276 --- /dev/null +++ b/default/templates/components/stork-search-nav.tpl @@ -0,0 +1,8 @@ +<div class="px-2 pt-2"> + <button type="button" + class="p-2 bg-white text-gray-400 border-gray-200 rounded w-full ring-1 ring-gray-200 text-sm flex items-center" + onclick="toggleSearch()"> + <span>🔍 Search...</span> + <span class="ml-auto pl-3 flex-none text-xs font-semibold">Ctrl K</span> + </button> +</div> diff --git a/default/templates/components/stork-search.tpl b/default/templates/components/stork-search.tpl index 189de0cf8..67745f00d 100644 --- a/default/templates/components/stork-search.tpl +++ b/default/templates/components/stork-search.tpl @@ -1,4 +1,28 @@ -<div class="stork-wrapper"> - <input data-stork="emanote-search" class="px-4 py-2 block w-full rounded-none border border-gray-300 focus:ring-indigo-500 focus:border-indigo-500 focus:outline-none" placeholder="Search..." /> - <div data-stork="emanote-search-output" class="stork-output"></div> +<div id="stork-search-container" + class="hidden fixed w-screen h-screen inset-0 backdrop-filter backdrop-blur-sm"> + <div + class="fixed w-screen h-screen inset-0" + onclick="toggleSearch()"></div> + + <div class="container mx-auto p-10 mt-10"> + <div class="stork-wrapper-flat container mx-auto"> + <input id="stork-search-input" data-stork="emanote-search" class="stork-input" placeholder="Search..." /> + + <button class="stork-close-button" + onclick="clearSearch()"> + <svg height="0.8em" viewBox="0 0 23 24" xmlns="http://www.w3.org/2000/svg"> + <g fill="none" fill-rule="evenodd" stroke-linecap="round"> + <g transform="translate(-700 -149)" stroke="currentcolor" stroke-width="4"> + <line id="a" x1="702.5" x2="720" y1="152.5" y2="170"></line> + <line transform="translate(711 161) rotate(-90) translate(-711 -161)" x1="702.5" x2="720" y1="152.5" y2="170"></line> + </g> + </g> + </svg> + </button> + + <div data-stork="emanote-search-output" class="stork-output"></div> + </div> + </div> </div> +<apply template="stork-search-css" /> +<apply template="stork-search-js" /> diff --git a/default/templates/layouts/book.tpl b/default/templates/layouts/book.tpl index c5904068b..4e99076fe 100644 --- a/default/templates/layouts/book.tpl +++ b/default/templates/layouts/book.tpl @@ -10,7 +10,7 @@ <!-- Sidebar column --> <nav id="sidebar" class="flex-shrink hidden leading-relaxed md:block md:sticky md:top-0 md:h-full md:w-48 xl:w-64"> - <apply template="components/stork-search" /> + <apply template="components/stork-search-nav" /> <div class="px-2 py-2 text-gray-800"> <div id="indexing-links" class="flex flex-row float-right p-2 space-x-2 text-gray-500"> @@ -76,6 +76,5 @@ </div> <apply template="components/footer" /> </div> - <apply template="components/stork-search-js-book" /> </bind> </apply> diff --git a/default/templates/layouts/note.tpl b/default/templates/layouts/note.tpl index cd4f3d2da..4796ea346 100644 --- a/default/templates/layouts/note.tpl +++ b/default/templates/layouts/note.tpl @@ -12,9 +12,11 @@ <div class="${containerClass}"> <div class="mt-2 md:mt-4"> <apply template="components/note-uptree" /> - <apply template="components/stork-search" /> <div class="md:shadow-2xl md:mb-8"> <div class="flex-1 w-full overflow-x-auto bg-white"> + <div class="px-2 pt-2"> + <apply template="components/stork-search-nav" /> + </div> <main class="px-4 py-4"> <apply template="components/note-title" /> <apply template="components/note-body" /> @@ -30,6 +32,5 @@ <apply template="components/footer" /> </div> </div> - <apply template="components/stork-search-js-note" /> </bind> </apply> From a5fe67b1d5cc1f45620df33e3455f58b4b524637 Mon Sep 17 00:00:00 2001 From: Kalle Fagerberg <kalle.f8@proton.me> Date: Sat, 13 Aug 2022 21:49:20 +0200 Subject: [PATCH 32/54] Added listener for Ctrl+K --- default/templates/components/stork-search-js.tpl | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/default/templates/components/stork-search-js.tpl b/default/templates/components/stork-search-js.tpl index ffe6583ce..fd201d708 100644 --- a/default/templates/components/stork-search-js.tpl +++ b/default/templates/components/stork-search-js.tpl @@ -23,6 +23,13 @@ window.addEventListener('load', function() { stork.register(indexName, indexUrl); }); + + document.addEventListener('keydown', event => { + if ((event.key == 'k' || event.key == 'K') && event.ctrlKey) { + toggleSearch(); + event.preventDefault(); + } + }); } else { // Override existing on Ema's hot-reload stork.register(indexName, indexUrl, {forceOverwrite: true}); From 2c2be4698dbeccea408854e905bdfb7bf28c7f34 Mon Sep 17 00:00:00 2001 From: Sridhar Ratnakumar <srid@srid.ca> Date: Sun, 14 Aug 2022 10:50:27 -0400 Subject: [PATCH 33/54] Update nix inputs to use Stock 1.5.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit • Updated input 'haskell-flake': 'github:srid/haskell-flake/4c0b0ff295f0b97238a600d2381c37ee46b67f9c' (2022-05-31) → 'github:srid/haskell-flake/1ca2be3c354ef2a3296cac7e54ae21e1d6ead6d7' (2022-08-12) • Updated input 'nixpkgs': 'path:/nix/store/a885zpv9ys2p2x7qnzqvxlsy321mclip-source?lastModified=1657447684&narHash=sha256-FCP9AuU1q6PE3vOeM5SFf58f%2fUKPBAsoSGDUGamNBbo=&rev=5f43d8b088d3771274bcfb69d3c7435b1121ac88' (2022-07-10) → 'path:/nix/store/1ha33ma070pyxw5kkcx61qi7ypzzxzah-source?lastModified=1659077768&narHash=sha256-P0XIHBVty6WIuIrk2DZNvLcYev9956y1prT4zL212H8=&rev=2a93ea177c3d7700b934bf95adfe00c435f696b8' (2022-07-29) • Updated input 'tailwind-haskell': 'github:srid/tailwind-haskell/96f4c7f8c59eb1103b75ff7d4a753d2d4b9c1ee7' (2022-07-14) → 'github:srid/tailwind-haskell/09a102164b1a4559892277ff38efdc9b949c5433' (2022-07-21) --- flake.lock | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/flake.lock b/flake.lock index 5593f087c..c792dbb97 100644 --- a/flake.lock +++ b/flake.lock @@ -55,11 +55,11 @@ }, "haskell-flake": { "locked": { - "lastModified": 1654001497, - "narHash": "sha256-GfrpyoQrVT9Z/j9its8BQs3I5O5X5Lc2IkK922bz7zg=", + "lastModified": 1660319056, + "narHash": "sha256-MX6PLEtXVyXXUEk3t1e0c20XRL4m4u9TFET2X0TpTdE=", "owner": "srid", "repo": "haskell-flake", - "rev": "4c0b0ff295f0b97238a600d2381c37ee46b67f9c", + "rev": "1ca2be3c354ef2a3296cac7e54ae21e1d6ead6d7", "type": "github" }, "original": { @@ -70,10 +70,10 @@ }, "nixpkgs": { "locked": { - "lastModified": 1657447684, - "narHash": "sha256-FCP9AuU1q6PE3vOeM5SFf58f/UKPBAsoSGDUGamNBbo=", - "path": "/nix/store/a885zpv9ys2p2x7qnzqvxlsy321mclip-source", - "rev": "5f43d8b088d3771274bcfb69d3c7435b1121ac88", + "lastModified": 1659077768, + "narHash": "sha256-P0XIHBVty6WIuIrk2DZNvLcYev9956y1prT4zL212H8=", + "path": "/nix/store/1ha33ma070pyxw5kkcx61qi7ypzzxzah-source", + "rev": "2a93ea177c3d7700b934bf95adfe00c435f696b8", "type": "path" }, "original": { @@ -98,11 +98,11 @@ ] }, "locked": { - "lastModified": 1657796772, - "narHash": "sha256-4JD3a9frE26VjaJysyd+DIHUJUiWsx/bFrk8tsGMSpU=", + "lastModified": 1658431129, + "narHash": "sha256-AtTxP0AMXdeU0ZTJP5R1lCtx5az3ejrmGP1klEdu1qU=", "owner": "srid", "repo": "tailwind-haskell", - "rev": "96f4c7f8c59eb1103b75ff7d4a753d2d4b9c1ee7", + "rev": "09a102164b1a4559892277ff38efdc9b949c5433", "type": "github" }, "original": { From b308b8db9006ead61a74ebda2f08cddae20d794a Mon Sep 17 00:00:00 2001 From: Kalle Fagerberg <kalle.f8@proton.me> Date: Sun, 14 Aug 2022 16:54:13 +0200 Subject: [PATCH 34/54] Use /dev/stdout instead of --output=- --- src/Emanote/View/Stork.hs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Emanote/View/Stork.hs b/src/Emanote/View/Stork.hs index 0301b7468..ee3ab4b9c 100644 --- a/src/Emanote/View/Stork.hs +++ b/src/Emanote/View/Stork.hs @@ -54,7 +54,9 @@ renderStorkIndex model = do -- TODO: this should retrieve from cache if model hasn't changed logW "Generating search index using Stork (this may be expensive)" let storkToml = Toml.encode inputCodec $ Input $ storkFiles model - (_, !index, _) <- liftIO $ readProcessWithExitCode storkBin ["build", "-t", "--input", "-", "--output", "-"] (encodeUtf8 storkToml) + -- NOTE: Cannot use "--output -" due to bug in Rust or Stork: + -- https://github.com/jameslittle230/stork/issues/262 + (_, !index, _) <- liftIO $ readProcessWithExitCode storkBin ["build", "-t", "--input", "-", "--output", "/dev/stdout"] (encodeUtf8 storkToml) log "Done generating Stork index" pure $ toLazy index From 2b8ff2540dfbbf52b574f5257c12d7cd62ab886b Mon Sep 17 00:00:00 2001 From: Sridhar Ratnakumar <srid@srid.ca> Date: Sun, 14 Aug 2022 11:22:15 -0400 Subject: [PATCH 35/54] nix: Unmark stork as broken (on intel mac only) --- flake.nix | 9 +++++---- nix/stork.nix | 10 ++++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) create mode 100644 nix/stork.nix diff --git a/flake.nix b/flake.nix index ffa81536c..17cff59d1 100644 --- a/flake.nix +++ b/flake.nix @@ -22,20 +22,21 @@ haskell-flake.flakeModule ./nix/emanote.nix ./nix/docker.nix + ./nix/stork.nix ]; - perSystem = { pkgs, inputs', self', ... }: { + perSystem = { system, pkgs, inputs', self', ... }: { haskellProjects.default = { root = ./.; buildTools = hp: { inherit (pkgs) treefmt - nixpkgs-fmt - stork; + nixpkgs-fmt; inherit (hp) cabal-fmt ormolu; inherit (inputs'.tailwind-haskell.packages) tailwind; + inherit (self'.packages) stork; }; source-overrides = { inherit (inputs) @@ -50,7 +51,7 @@ tailwind; }; modifier = drv: with pkgs.haskell.lib; - addBuildDepends drv [ pkgs.stork ]; + addBuildDepends drv [ self'.packages.stork ]; }; packages.test = pkgs.runCommand "emanote-test" { } '' diff --git a/nix/stork.nix b/nix/stork.nix new file mode 100644 index 000000000..bfc1d94bc --- /dev/null +++ b/nix/stork.nix @@ -0,0 +1,10 @@ +{ ... }: + +{ + perSystem = { system, pkgs, ... }: { + packages.stork = + # Stork is marked as broken on intel mac, but it does work. + # Unfortunately we cannot test this code PATH due to lack of CI for intel mac (#335). + if system == "x86_64-darwin" then pkgs.stork.overrideAttrs (_oa: { meta.broken = false; }) else pkgs.stork; + }; +} From 0d96667f514c4bb8829f9e4430080664ceeeab63 Mon Sep 17 00:00:00 2001 From: Kalle Fagerberg <kalle.f8@proton.me> Date: Sun, 14 Aug 2022 17:23:21 +0200 Subject: [PATCH 36/54] Added hotkeys Cmd+K and Esc --- default/templates/components/stork-search-js.tpl | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/default/templates/components/stork-search-js.tpl b/default/templates/components/stork-search-js.tpl index fd201d708..b220b14c8 100644 --- a/default/templates/components/stork-search-js.tpl +++ b/default/templates/components/stork-search-js.tpl @@ -2,10 +2,11 @@ <ema:metadata> <with var="template"> <script data-emanote-base-url="${value:baseUrl}"> + window.searchShown = false; function toggleSearch() { document.getElementById('stork-search-container').classList.toggle('hidden'); - const shown = document.body.classList.toggle('stork-overflow-hidden-important'); - if (shown) { + window.searchShown = document.body.classList.toggle('stork-overflow-hidden-important'); + if (window.searchShown) { document.getElementById('stork-search-input').focus(); } } @@ -13,6 +14,7 @@ function clearSearch() { document.getElementById('stork-search-container').classList.add('hidden'); document.body.classList.remove('stork-overflow-hidden-important'); + window.searchShown = false; } (function() { @@ -25,7 +27,10 @@ }); document.addEventListener('keydown', event => { - if ((event.key == 'k' || event.key == 'K') && event.ctrlKey) { + if (window.searchShown && event.key === 'Escape') { + clearSearch(); + event.preventDefault(); + } else if ((event.key == 'k' || event.key == 'K') && (event.ctrlKey || event.metaKey)) { toggleSearch(); event.preventDefault(); } From 6c5c6041b6a999e912f1f91ed7f65dbf91b74120 Mon Sep 17 00:00:00 2001 From: Sridhar Ratnakumar <srid@srid.ca> Date: Sun, 14 Aug 2022 11:33:40 -0400 Subject: [PATCH 37/54] refactor: rename module --- emanote.cabal | 2 +- flake.nix | 2 +- src/Emanote/{View => Model}/Stork.hs | 2 +- src/Emanote/View/Template.hs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename src/Emanote/{View => Model}/Stork.hs (98%) diff --git a/emanote.cabal b/emanote.cabal index 99ed79a24..b2d81e6bc 100644 --- a/emanote.cabal +++ b/emanote.cabal @@ -169,6 +169,7 @@ library Emanote.Model.QuerySpec Emanote.Model.SData Emanote.Model.StaticFile + Emanote.Model.Stork Emanote.Model.Task Emanote.Model.Title Emanote.Model.Type @@ -198,7 +199,6 @@ library Emanote.View.Common Emanote.View.Export Emanote.View.LiveServerFiles - Emanote.View.Stork Emanote.View.TagIndex Emanote.View.TaskIndex Emanote.View.Template diff --git a/flake.nix b/flake.nix index 17cff59d1..3a8b3bcac 100644 --- a/flake.nix +++ b/flake.nix @@ -24,7 +24,7 @@ ./nix/docker.nix ./nix/stork.nix ]; - perSystem = { system, pkgs, inputs', self', ... }: { + perSystem = { pkgs, inputs', self', ... }: { haskellProjects.default = { root = ./.; buildTools = hp: { diff --git a/src/Emanote/View/Stork.hs b/src/Emanote/Model/Stork.hs similarity index 98% rename from src/Emanote/View/Stork.hs rename to src/Emanote/Model/Stork.hs index ee3ab4b9c..19acf58ba 100644 --- a/src/Emanote/View/Stork.hs +++ b/src/Emanote/Model/Stork.hs @@ -1,7 +1,7 @@ {-# LANGUAGE BangPatterns #-} {-# LANGUAGE TemplateHaskell #-} -module Emanote.View.Stork +module Emanote.Model.Stork ( renderStorkIndex, ) where diff --git a/src/Emanote/View/Template.hs b/src/Emanote/View/Template.hs index 7c06fbaa0..a50d86f34 100644 --- a/src/Emanote/View/Template.hs +++ b/src/Emanote/View/Template.hs @@ -15,6 +15,7 @@ import Emanote.Model.Graph qualified as G import Emanote.Model.Meta qualified as Meta import Emanote.Model.Note qualified as MN import Emanote.Model.SData qualified as SData +import Emanote.Model.Stork (renderStorkIndex) import Emanote.Model.Title qualified as Tit import Emanote.Pandoc.BuiltinFilters (prepareNoteDoc) import Emanote.Route qualified as R @@ -23,7 +24,6 @@ import Emanote.Route.SiteRoute qualified as SR import Emanote.Route.SiteRoute.Class (indexRoute) import Emanote.View.Common qualified as C import Emanote.View.Export (renderGraphExport) -import Emanote.View.Stork (renderStorkIndex) import Emanote.View.TagIndex qualified as TagIndex import Emanote.View.TaskIndex qualified as TaskIndex import Heist qualified as H From 2f603bb8124d31f547908774e0430d5c106dbeeb Mon Sep 17 00:00:00 2001 From: Sridhar Ratnakumar <srid@srid.ca> Date: Sun, 14 Aug 2022 12:11:35 -0400 Subject: [PATCH 38/54] Cache stork index for reuse (when notes haven't been changed) This is more of a hacky implementation aimed towards establishing correctness first. It is also not concurrency-friendly. All of this need to be fixed next. --- src/Emanote/Model/Stork.hs | 35 +++++++++++++++++++++++++-------- src/Emanote/Model/Type.hs | 5 +++-- src/Emanote/Source/Dynamic.hs | 5 +++-- src/Emanote/Source/Patch.hs | 37 ++++++++++++++++++++--------------- 4 files changed, 54 insertions(+), 28 deletions(-) diff --git a/src/Emanote/Model/Stork.hs b/src/Emanote/Model/Stork.hs index 19acf58ba..6cc96b2f8 100644 --- a/src/Emanote/Model/Stork.hs +++ b/src/Emanote/Model/Stork.hs @@ -3,6 +3,7 @@ module Emanote.Model.Stork ( renderStorkIndex, + runStork, ) where @@ -12,7 +13,7 @@ import Emanote.Model (Model) import Emanote.Model.Note qualified as N import Emanote.Model.Title qualified as Tit import Emanote.Model.Type qualified as M -import Emanote.Prelude (log, logW) +import Emanote.Prelude (log, logD, logW) import Emanote.Route qualified as R import Emanote.Source.Loc qualified as Loc import Optics.Core ((^.)) @@ -51,13 +52,31 @@ inputCodec = renderStorkIndex :: (MonadIO m, MonadLoggerIO m) => Model -> m LByteString renderStorkIndex model = do - -- TODO: this should retrieve from cache if model hasn't changed - logW "Generating search index using Stork (this may be expensive)" - let storkToml = Toml.encode inputCodec $ Input $ storkFiles model - -- NOTE: Cannot use "--output -" due to bug in Rust or Stork: - -- https://github.com/jameslittle230/stork/issues/262 - (_, !index, _) <- liftIO $ readProcessWithExitCode storkBin ["build", "-t", "--input", "-", "--output", "/dev/stdout"] (encodeUtf8 storkToml) - log "Done generating Stork index" + let indexTVar = model ^. M.modelStorkIndex + readTVarIO indexTVar >>= \case + Just index -> do + logD "STORK: Returning cached search index" + pure index + Nothing -> do + -- TODO: What if there are concurrent reads? We probably need a lock. + -- And we want to encapsulate this whole thing. + logW "STORK: Generating search index (this may be expensive)" + index <- runStork $ Input $ storkFiles model + atomically $ modifyTVar' indexTVar $ \_ -> Just index + log "STORK: Done generating search index" + pure index + +runStork :: MonadIO m => Input -> m LByteString +runStork input = do + let storkToml = Toml.encode inputCodec input + (_, !index, _) <- + liftIO $ + readProcessWithExitCode + storkBin + -- NOTE: Cannot use "--output -" due to bug in Rust or Stork: + -- https://github.com/jameslittle230/stork/issues/262 + ["build", "-t", "--input", "-", "--output", "/dev/stdout"] + (encodeUtf8 storkToml) pure $ toLazy index storkFiles :: Model -> [File] diff --git a/src/Emanote/Model/Type.hs b/src/Emanote/Model/Type.hs index 930166c93..0035ca5ea 100644 --- a/src/Emanote/Model/Type.hs +++ b/src/Emanote/Model/Type.hs @@ -63,7 +63,8 @@ data ModelT encF = Model _modelStaticFiles :: IxStaticFile, _modelTasks :: IxTask, _modelNav :: [Tree Slug], - _modelHeistTemplate :: TemplateState + _modelHeistTemplate :: TemplateState, + _modelStorkIndex :: TVar (Maybe LByteString) } deriving stock (Generic) @@ -90,7 +91,7 @@ withRoutePrism enc Model {..} = let _modelRoutePrism = Identity enc in Model {..} -emptyModel :: Set Loc -> Some Ema.CLI.Action -> EmanotePandocRenderers Model LMLRoute -> Bool -> UUID -> ModelEma +emptyModel :: Set Loc -> Some Ema.CLI.Action -> EmanotePandocRenderers Model LMLRoute -> Bool -> UUID -> TVar (Maybe LByteString) -> ModelEma emptyModel layers act ren ctw instanceId = Model Status_Loading layers act (Const ()) ren ctw instanceId Ix.empty Ix.empty Ix.empty Ix.empty mempty mempty def diff --git a/src/Emanote/Source/Dynamic.hs b/src/Emanote/Source/Dynamic.hs index 8298db068..e778108cd 100644 --- a/src/Emanote/Source/Dynamic.hs +++ b/src/Emanote/Source/Dynamic.hs @@ -53,15 +53,16 @@ emanoteSiteInput :: (MonadUnliftIO m, MonadLoggerIO m) => Some Ema.CLI.Action -> emanoteSiteInput cliAct EmanoteConfig {..} = do defaultLayer <- Loc.defaultLayer <$> liftIO Paths_emanote.getDataDir instanceId <- liftIO UUID.nextRandom + storkIndexTVar <- newTVarIO mempty let layers = Loc.userLayers (CLI.layers _emanoteConfigCli) <> one defaultLayer - initialModel = Model.emptyModel layers cliAct _emanoteConfigPandocRenderers _emanoteCompileTailwind instanceId + initialModel = Model.emptyModel layers cliAct _emanoteConfigPandocRenderers _emanoteCompileTailwind instanceId storkIndexTVar Dynamic <$> UM.unionMount (layers & Set.map (id &&& Loc.locPath)) Pattern.filePatterns Pattern.ignorePatterns initialModel - (mapFsChanges $ Patch.patchModel layers _emanoteConfigNoteFn) + (mapFsChanges $ Patch.patchModel layers _emanoteConfigNoteFn storkIndexTVar) type ChangeHandler tag model m = tag -> diff --git a/src/Emanote/Source/Patch.hs b/src/Emanote/Source/Patch.hs index 96137967a..3b4ca782f 100644 --- a/src/Emanote/Source/Patch.hs +++ b/src/Emanote/Source/Patch.hs @@ -35,6 +35,7 @@ patchModel :: (MonadIO m, MonadLogger m, MonadLoggerIO m) => LocLayers -> (N.Note -> N.Note) -> + TVar (Maybe LByteString) -> -- | Type of the file being changed R.FileType R.SourceExt -> -- | Path to the file being changed @@ -42,19 +43,20 @@ patchModel :: -- | Specific change to the file, along with its paths from other "layers" UM.FileAction (NonEmpty (Loc, FilePath)) -> m (ModelEma -> ModelEma) -patchModel layers noteF fpType fp action = do +patchModel layers noteF storkIndexTVar fpType fp action = do logger <- askLoggerIO now <- liftIO getCurrentTime -- Prefix all patch logging with timestamp. let newLogger loc src lvl s = logger loc src lvl $ fromString (formatTime defaultTimeLocale "[%H:%M:%S] " now) <> s - runLoggingT (patchModel' layers noteF fpType fp action) newLogger + runLoggingT (patchModel' layers noteF storkIndexTVar fpType fp action) newLogger -- | Map a filesystem change to the corresponding model change. patchModel' :: (MonadIO m, MonadLogger m) => LocLayers -> (N.Note -> N.Note) -> + TVar (Maybe LByteString) -> -- | Type of the file being changed R.FileType R.SourceExt -> -- | Path to the file being changed @@ -62,25 +64,28 @@ patchModel' :: -- | Specific change to the file, along with its paths from other "layers" UM.FileAction (NonEmpty (Loc, FilePath)) -> m (ModelEma -> ModelEma) -patchModel' layers noteF fpType fp action = do +patchModel' layers noteF storkIndexTVar fpType fp action = do + let clearStorkIndex = atomically $ writeTVar storkIndexTVar mempty case fpType of R.LMLType lmlType -> do case R.mkLMLRouteFromKnownFilePath lmlType fp of Nothing -> pure id -- Impossible - Just r -> case action of - UM.Refresh refreshAction overlays -> do - let fpAbs = locResolve $ head overlays - -- TODO: This should automatically be computed, instead of being passed. - -- We need access to the model though! With dependency management to boot. - -- Until this, `layers` is threaded through as a hack. - currentLayerPath = locPath $ primaryLayer layers - s <- readRefreshedFile refreshAction fpAbs - note <- N.parseNote currentLayerPath r fpAbs (decodeUtf8 s) - pure $ M.modelInsertNote $ noteF note - UM.Delete -> do - log $ "Removing note: " <> toText fp - pure $ M.modelDeleteNote r + Just r -> do + clearStorkIndex + case action of + UM.Refresh refreshAction overlays -> do + let fpAbs = locResolve $ head overlays + -- TODO: This should automatically be computed, instead of being passed. + -- We need access to the model though! With dependency management to boot. + -- Until this, `layers` is threaded through as a hack. + currentLayerPath = locPath $ primaryLayer layers + s <- readRefreshedFile refreshAction fpAbs + note <- N.parseNote currentLayerPath r fpAbs (decodeUtf8 s) + pure $ M.modelInsertNote $ noteF note + UM.Delete -> do + log $ "Removing note: " <> toText fp + pure $ M.modelDeleteNote r R.Yaml -> case R.mkRouteFromFilePath fp of Nothing -> From e683c784eda3dd7c035428ad192d98f4519d6470 Mon Sep 17 00:00:00 2001 From: Sridhar Ratnakumar <srid@srid.ca> Date: Sun, 14 Aug 2022 12:28:37 -0400 Subject: [PATCH 39/54] Refactor: re-organize around, do newtype wrappers --- emanote.cabal | 1 + src/Emanote/Model/Stork.hs | 65 ++---------------------- src/Emanote/Model/Stork/Index.hs | 84 ++++++++++++++++++++++++++++++++ src/Emanote/Model/Type.hs | 5 +- src/Emanote/Source/Dynamic.hs | 3 +- src/Emanote/Source/Patch.hs | 17 +++++-- 6 files changed, 106 insertions(+), 69 deletions(-) create mode 100644 src/Emanote/Model/Stork/Index.hs diff --git a/emanote.cabal b/emanote.cabal index b2d81e6bc..f050ff83b 100644 --- a/emanote.cabal +++ b/emanote.cabal @@ -170,6 +170,7 @@ library Emanote.Model.SData Emanote.Model.StaticFile Emanote.Model.Stork + Emanote.Model.Stork.Index Emanote.Model.Task Emanote.Model.Title Emanote.Model.Type diff --git a/src/Emanote/Model/Stork.hs b/src/Emanote/Model/Stork.hs index 6cc96b2f8..c0b209557 100644 --- a/src/Emanote/Model/Stork.hs +++ b/src/Emanote/Model/Stork.hs @@ -1,83 +1,24 @@ -{-# LANGUAGE BangPatterns #-} -{-# LANGUAGE TemplateHaskell #-} - module Emanote.Model.Stork ( renderStorkIndex, - runStork, ) where import Control.Monad.Logger (MonadLoggerIO) import Data.IxSet.Typed qualified as Ix -import Emanote.Model (Model) import Emanote.Model.Note qualified as N +import Emanote.Model.Stork.Index (File (File), Input (Input), readOrBuildStorkIndex) import Emanote.Model.Title qualified as Tit +import Emanote.Model.Type (Model) import Emanote.Model.Type qualified as M -import Emanote.Prelude (log, logD, logW) import Emanote.Route qualified as R import Emanote.Source.Loc qualified as Loc import Optics.Core ((^.)) import Relude import System.FilePath ((</>)) -import System.Process.ByteString (readProcessWithExitCode) -import System.Which (staticWhich) -import Toml (TomlCodec, encode, list, string, text, (.=)) - -storkBin :: FilePath -storkBin = $(staticWhich "stork") - -newtype Input = Input - { inputFiles :: [File] - } - deriving stock (Eq, Show) - -data File = File - { filePath :: FilePath, - fileUrl :: Text, - fileTitle :: Text - } - deriving stock (Eq, Show) - -fileCodec :: TomlCodec File -fileCodec = - File - <$> Toml.string "path" .= filePath - <*> Toml.text "url" .= fileUrl - <*> Toml.text "title" .= fileTitle - -inputCodec :: TomlCodec Input -inputCodec = - Input - <$> Toml.list fileCodec "input.files" .= inputFiles renderStorkIndex :: (MonadIO m, MonadLoggerIO m) => Model -> m LByteString renderStorkIndex model = do - let indexTVar = model ^. M.modelStorkIndex - readTVarIO indexTVar >>= \case - Just index -> do - logD "STORK: Returning cached search index" - pure index - Nothing -> do - -- TODO: What if there are concurrent reads? We probably need a lock. - -- And we want to encapsulate this whole thing. - logW "STORK: Generating search index (this may be expensive)" - index <- runStork $ Input $ storkFiles model - atomically $ modifyTVar' indexTVar $ \_ -> Just index - log "STORK: Done generating search index" - pure index - -runStork :: MonadIO m => Input -> m LByteString -runStork input = do - let storkToml = Toml.encode inputCodec input - (_, !index, _) <- - liftIO $ - readProcessWithExitCode - storkBin - -- NOTE: Cannot use "--output -" due to bug in Rust or Stork: - -- https://github.com/jameslittle230/stork/issues/262 - ["build", "-t", "--input", "-", "--output", "/dev/stdout"] - (encodeUtf8 storkToml) - pure $ toLazy index + readOrBuildStorkIndex (model ^. M.modelStorkIndex) (Input $ storkFiles model) storkFiles :: Model -> [File] storkFiles model = diff --git a/src/Emanote/Model/Stork/Index.hs b/src/Emanote/Model/Stork/Index.hs new file mode 100644 index 000000000..eeecd27ba --- /dev/null +++ b/src/Emanote/Model/Stork/Index.hs @@ -0,0 +1,84 @@ +{-# LANGUAGE BangPatterns #-} +{-# LANGUAGE TemplateHaskell #-} + +module Emanote.Model.Stork.Index + ( IndexVar, + newIndex, + clearStorkIndex, + readOrBuildStorkIndex, + File (File), + Input (Input), + ) +where + +import Control.Monad.Logger (MonadLoggerIO) +import Emanote.Prelude (log, logD, logW) +import Relude +import System.Process.ByteString (readProcessWithExitCode) +import System.Which (staticWhich) +import Toml (TomlCodec, encode, list, string, text, (.=)) + +-- | In-memory Stork index tracked in a @TVar@ +newtype IndexVar = IndexVar (TVar (Maybe LByteString)) + +newIndex :: MonadIO m => m IndexVar +newIndex = + IndexVar <$> newTVarIO mempty + +clearStorkIndex :: (MonadIO m) => IndexVar -> m () +clearStorkIndex (IndexVar var) = atomically $ writeTVar var mempty + +readOrBuildStorkIndex :: (MonadIO m, MonadLoggerIO m) => IndexVar -> Input -> m LByteString +readOrBuildStorkIndex (IndexVar indexVar) input = do + readTVarIO indexVar >>= \case + Just index -> do + logD "STORK: Returning cached search index" + pure index + Nothing -> do + -- TODO: What if there are concurrent reads? We probably need a lock. + -- And we want to encapsulate this whole thing. + logW "STORK: Generating search index (this may be expensive)" + index <- runStork input + atomically $ modifyTVar' indexVar $ \_ -> Just index + log "STORK: Done generating search index" + pure index + +storkBin :: FilePath +storkBin = $(staticWhich "stork") + +runStork :: MonadIO m => Input -> m LByteString +runStork input = do + let storkToml = Toml.encode inputCodec input + (_, !index, _) <- + liftIO $ + readProcessWithExitCode + storkBin + -- NOTE: Cannot use "--output -" due to bug in Rust or Stork: + -- https://github.com/jameslittle230/stork/issues/262 + ["build", "-t", "--input", "-", "--output", "/dev/stdout"] + (encodeUtf8 storkToml) + pure $ toLazy index + +newtype Input = Input + { inputFiles :: [File] + } + deriving stock (Eq, Show) + +data File = File + { filePath :: FilePath, + fileUrl :: Text, + fileTitle :: Text + } + deriving stock (Eq, Show) + +fileCodec :: TomlCodec File +fileCodec = + File + <$> Toml.string "path" .= filePath + <*> Toml.text "url" .= fileUrl + <*> Toml.text "title" .= fileTitle + +inputCodec :: TomlCodec Input +inputCodec = + Input + <$> Toml.list fileCodec "input.files" .= inputFiles diff --git a/src/Emanote/Model/Type.hs b/src/Emanote/Model/Type.hs index 0035ca5ea..262f889ac 100644 --- a/src/Emanote/Model/Type.hs +++ b/src/Emanote/Model/Type.hs @@ -27,6 +27,7 @@ import Emanote.Model.StaticFile ( IxStaticFile, StaticFile (StaticFile), ) +import Emanote.Model.Stork.Index qualified as Stork import Emanote.Model.Task (IxTask) import Emanote.Model.Task qualified as Task import Emanote.Model.Title qualified as Tit @@ -64,7 +65,7 @@ data ModelT encF = Model _modelTasks :: IxTask, _modelNav :: [Tree Slug], _modelHeistTemplate :: TemplateState, - _modelStorkIndex :: TVar (Maybe LByteString) + _modelStorkIndex :: Stork.IndexVar } deriving stock (Generic) @@ -91,7 +92,7 @@ withRoutePrism enc Model {..} = let _modelRoutePrism = Identity enc in Model {..} -emptyModel :: Set Loc -> Some Ema.CLI.Action -> EmanotePandocRenderers Model LMLRoute -> Bool -> UUID -> TVar (Maybe LByteString) -> ModelEma +emptyModel :: Set Loc -> Some Ema.CLI.Action -> EmanotePandocRenderers Model LMLRoute -> Bool -> UUID -> Stork.IndexVar -> ModelEma emptyModel layers act ren ctw instanceId = Model Status_Loading layers act (Const ()) ren ctw instanceId Ix.empty Ix.empty Ix.empty Ix.empty mempty mempty def diff --git a/src/Emanote/Source/Dynamic.hs b/src/Emanote/Source/Dynamic.hs index e778108cd..f2290fb89 100644 --- a/src/Emanote/Source/Dynamic.hs +++ b/src/Emanote/Source/Dynamic.hs @@ -20,6 +20,7 @@ import Ema (Dynamic (..)) import Ema.CLI qualified import Emanote.CLI qualified as CLI import Emanote.Model.Note (Note) +import Emanote.Model.Stork.Index qualified as Stork import Emanote.Model.Type qualified as Model import Emanote.Pandoc.Renderer (EmanotePandocRenderers) import Emanote.Prelude (chainM) @@ -53,7 +54,7 @@ emanoteSiteInput :: (MonadUnliftIO m, MonadLoggerIO m) => Some Ema.CLI.Action -> emanoteSiteInput cliAct EmanoteConfig {..} = do defaultLayer <- Loc.defaultLayer <$> liftIO Paths_emanote.getDataDir instanceId <- liftIO UUID.nextRandom - storkIndexTVar <- newTVarIO mempty + storkIndexTVar <- Stork.newIndex let layers = Loc.userLayers (CLI.layers _emanoteConfigCli) <> one defaultLayer initialModel = Model.emptyModel layers cliAct _emanoteConfigPandocRenderers _emanoteCompileTailwind instanceId storkIndexTVar Dynamic diff --git a/src/Emanote/Source/Patch.hs b/src/Emanote/Source/Patch.hs index 3b4ca782f..8a9acfa89 100644 --- a/src/Emanote/Source/Patch.hs +++ b/src/Emanote/Source/Patch.hs @@ -14,6 +14,7 @@ import Data.Time (defaultTimeLocale, formatTime, getCurrentTime) import Emanote.Model qualified as M import Emanote.Model.Note qualified as N import Emanote.Model.SData qualified as SD +import Emanote.Model.Stork.Index qualified as Stork import Emanote.Model.Type (ModelEma) import Emanote.Prelude ( BadInput (BadInput), @@ -35,7 +36,7 @@ patchModel :: (MonadIO m, MonadLogger m, MonadLoggerIO m) => LocLayers -> (N.Note -> N.Note) -> - TVar (Maybe LByteString) -> + Stork.IndexVar -> -- | Type of the file being changed R.FileType R.SourceExt -> -- | Path to the file being changed @@ -56,7 +57,7 @@ patchModel' :: (MonadIO m, MonadLogger m) => LocLayers -> (N.Note -> N.Note) -> - TVar (Maybe LByteString) -> + Stork.IndexVar -> -- | Type of the file being changed R.FileType R.SourceExt -> -- | Path to the file being changed @@ -65,14 +66,22 @@ patchModel' :: UM.FileAction (NonEmpty (Loc, FilePath)) -> m (ModelEma -> ModelEma) patchModel' layers noteF storkIndexTVar fpType fp action = do - let clearStorkIndex = atomically $ writeTVar storkIndexTVar mempty case fpType of R.LMLType lmlType -> do case R.mkLMLRouteFromKnownFilePath lmlType fp of Nothing -> pure id -- Impossible Just r -> do - clearStorkIndex + -- Stork doesn't support incremental building of index, so we must + -- clear it to pave way for a rebuild later when requested. + -- + -- From https://github.com/jameslittle230/stork/discussions/112#discussioncomment-252861 + -- + -- > Stork also doesn't support incremental index updates today -- + -- you'd have to re-index everything when users added a new document, + -- which might be prohibitively long. + Stork.clearStorkIndex storkIndexTVar + case action of UM.Refresh refreshAction overlays -> do let fpAbs = locResolve $ head overlays From 084b873fa287c7cd1a5d3020865a54b839bea0f5 Mon Sep 17 00:00:00 2001 From: Sridhar Ratnakumar <srid@srid.ca> Date: Sun, 14 Aug 2022 12:47:44 -0400 Subject: [PATCH 40/54] Log the time it took for stork to run (1 second here) --- src/Emanote/Model/Stork/Index.hs | 16 ++++++++++++++-- src/Emanote/Source/Dynamic.hs | 6 +++--- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/Emanote/Model/Stork/Index.hs b/src/Emanote/Model/Stork/Index.hs index eeecd27ba..1f75f96d9 100644 --- a/src/Emanote/Model/Stork/Index.hs +++ b/src/Emanote/Model/Stork/Index.hs @@ -12,7 +12,9 @@ module Emanote.Model.Stork.Index where import Control.Monad.Logger (MonadLoggerIO) +import Data.Time (NominalDiffTime, diffUTCTime, getCurrentTime) import Emanote.Prelude (log, logD, logW) +import Numeric (showGFloat) import Relude import System.Process.ByteString (readProcessWithExitCode) import System.Which (staticWhich) @@ -38,10 +40,20 @@ readOrBuildStorkIndex (IndexVar indexVar) input = do -- TODO: What if there are concurrent reads? We probably need a lock. -- And we want to encapsulate this whole thing. logW "STORK: Generating search index (this may be expensive)" - index <- runStork input + liftIO $ print =<< getCurrentTime + (diff, !index) <- timeIt $ runStork input + liftIO $ print =<< getCurrentTime atomically $ modifyTVar' indexVar $ \_ -> Just index - log "STORK: Done generating search index" + log $ toText $ "STORK: Done generating search index in " <> showGFloat (Just 2) diff "" <> " seconds" pure index + where + timeIt :: MonadIO m => m b -> m (Double, b) + timeIt m = do + t0 <- liftIO getCurrentTime + !x <- m + t1 <- liftIO getCurrentTime + let diff :: NominalDiffTime = diffUTCTime t1 t0 + pure (realToFrac diff, x) storkBin :: FilePath storkBin = $(staticWhich "stork") diff --git a/src/Emanote/Source/Dynamic.hs b/src/Emanote/Source/Dynamic.hs index f2290fb89..e578892f7 100644 --- a/src/Emanote/Source/Dynamic.hs +++ b/src/Emanote/Source/Dynamic.hs @@ -54,16 +54,16 @@ emanoteSiteInput :: (MonadUnliftIO m, MonadLoggerIO m) => Some Ema.CLI.Action -> emanoteSiteInput cliAct EmanoteConfig {..} = do defaultLayer <- Loc.defaultLayer <$> liftIO Paths_emanote.getDataDir instanceId <- liftIO UUID.nextRandom - storkIndexTVar <- Stork.newIndex + storkIndex <- Stork.newIndex let layers = Loc.userLayers (CLI.layers _emanoteConfigCli) <> one defaultLayer - initialModel = Model.emptyModel layers cliAct _emanoteConfigPandocRenderers _emanoteCompileTailwind instanceId storkIndexTVar + initialModel = Model.emptyModel layers cliAct _emanoteConfigPandocRenderers _emanoteCompileTailwind instanceId storkIndex Dynamic <$> UM.unionMount (layers & Set.map (id &&& Loc.locPath)) Pattern.filePatterns Pattern.ignorePatterns initialModel - (mapFsChanges $ Patch.patchModel layers _emanoteConfigNoteFn storkIndexTVar) + (mapFsChanges $ Patch.patchModel layers _emanoteConfigNoteFn storkIndex) type ChangeHandler tag model m = tag -> From dbdef65005a0a5c13bbbfa7b154f0821c172ac1f Mon Sep 17 00:00:00 2001 From: Sridhar Ratnakumar <srid@srid.ca> Date: Sun, 14 Aug 2022 12:48:11 -0400 Subject: [PATCH 41/54] remove debug --- src/Emanote/Model/Stork/Index.hs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Emanote/Model/Stork/Index.hs b/src/Emanote/Model/Stork/Index.hs index 1f75f96d9..8bafc1716 100644 --- a/src/Emanote/Model/Stork/Index.hs +++ b/src/Emanote/Model/Stork/Index.hs @@ -40,9 +40,7 @@ readOrBuildStorkIndex (IndexVar indexVar) input = do -- TODO: What if there are concurrent reads? We probably need a lock. -- And we want to encapsulate this whole thing. logW "STORK: Generating search index (this may be expensive)" - liftIO $ print =<< getCurrentTime (diff, !index) <- timeIt $ runStork input - liftIO $ print =<< getCurrentTime atomically $ modifyTVar' indexVar $ \_ -> Just index log $ toText $ "STORK: Done generating search index in " <> showGFloat (Just 2) diff "" <> " seconds" pure index From 415c4af522fc899b3d3509e14dd05a2b35156eda Mon Sep 17 00:00:00 2001 From: Sridhar Ratnakumar <srid@srid.ca> Date: Sun, 14 Aug 2022 12:49:10 -0400 Subject: [PATCH 42/54] Exclude tvar modification from the measure --- src/Emanote/Model/Stork/Index.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Emanote/Model/Stork/Index.hs b/src/Emanote/Model/Stork/Index.hs index 8bafc1716..5179f00b7 100644 --- a/src/Emanote/Model/Stork/Index.hs +++ b/src/Emanote/Model/Stork/Index.hs @@ -41,8 +41,8 @@ readOrBuildStorkIndex (IndexVar indexVar) input = do -- And we want to encapsulate this whole thing. logW "STORK: Generating search index (this may be expensive)" (diff, !index) <- timeIt $ runStork input - atomically $ modifyTVar' indexVar $ \_ -> Just index log $ toText $ "STORK: Done generating search index in " <> showGFloat (Just 2) diff "" <> " seconds" + atomically $ modifyTVar' indexVar $ \_ -> Just index pure index where timeIt :: MonadIO m => m b -> m (Double, b) From b26171d2616755c8b055f1b1acecba0fa662191f Mon Sep 17 00:00:00 2001 From: Sridhar Ratnakumar <srid@srid.ca> Date: Mon, 15 Aug 2022 21:07:43 -0400 Subject: [PATCH 43/54] Group stork templates under components/stork --- default/templates/base.tpl | 4 ++-- default/templates/components/{ => stork}/stork-search-css.tpl | 0 default/templates/components/{ => stork}/stork-search-js.tpl | 0 default/templates/components/{ => stork}/stork-search-nav.tpl | 0 default/templates/components/{ => stork}/stork-search.tpl | 0 default/templates/layouts/book.tpl | 4 ++-- default/templates/layouts/note.tpl | 4 ++-- 7 files changed, 6 insertions(+), 6 deletions(-) rename default/templates/components/{ => stork}/stork-search-css.tpl (100%) rename default/templates/components/{ => stork}/stork-search-js.tpl (100%) rename default/templates/components/{ => stork}/stork-search-nav.tpl (100%) rename default/templates/components/{ => stork}/stork-search.tpl (100%) diff --git a/default/templates/base.tpl b/default/templates/base.tpl index 92660a578..f19720607 100644 --- a/default/templates/base.tpl +++ b/default/templates/base.tpl @@ -44,7 +44,7 @@ <body class="${bodyClass}"> <body-main /> - <apply template="components/stork-search" /> + <apply template="components/stork/stork-search" /> </body> -</html> +</html> \ No newline at end of file diff --git a/default/templates/components/stork-search-css.tpl b/default/templates/components/stork/stork-search-css.tpl similarity index 100% rename from default/templates/components/stork-search-css.tpl rename to default/templates/components/stork/stork-search-css.tpl diff --git a/default/templates/components/stork-search-js.tpl b/default/templates/components/stork/stork-search-js.tpl similarity index 100% rename from default/templates/components/stork-search-js.tpl rename to default/templates/components/stork/stork-search-js.tpl diff --git a/default/templates/components/stork-search-nav.tpl b/default/templates/components/stork/stork-search-nav.tpl similarity index 100% rename from default/templates/components/stork-search-nav.tpl rename to default/templates/components/stork/stork-search-nav.tpl diff --git a/default/templates/components/stork-search.tpl b/default/templates/components/stork/stork-search.tpl similarity index 100% rename from default/templates/components/stork-search.tpl rename to default/templates/components/stork/stork-search.tpl diff --git a/default/templates/layouts/book.tpl b/default/templates/layouts/book.tpl index 4e99076fe..17331fd90 100644 --- a/default/templates/layouts/book.tpl +++ b/default/templates/layouts/book.tpl @@ -10,7 +10,7 @@ <!-- Sidebar column --> <nav id="sidebar" class="flex-shrink hidden leading-relaxed md:block md:sticky md:top-0 md:h-full md:w-48 xl:w-64"> - <apply template="components/stork-search-nav" /> + <apply template="components/stork/stork-search-nav" /> <div class="px-2 py-2 text-gray-800"> <div id="indexing-links" class="flex flex-row float-right p-2 space-x-2 text-gray-500"> @@ -77,4 +77,4 @@ <apply template="components/footer" /> </div> </bind> -</apply> +</apply> \ No newline at end of file diff --git a/default/templates/layouts/note.tpl b/default/templates/layouts/note.tpl index 4796ea346..20ac30963 100644 --- a/default/templates/layouts/note.tpl +++ b/default/templates/layouts/note.tpl @@ -15,7 +15,7 @@ <div class="md:shadow-2xl md:mb-8"> <div class="flex-1 w-full overflow-x-auto bg-white"> <div class="px-2 pt-2"> - <apply template="components/stork-search-nav" /> + <apply template="components/stork/stork-search-nav" /> </div> <main class="px-4 py-4"> <apply template="components/note-title" /> @@ -33,4 +33,4 @@ </div> </div> </bind> -</apply> +</apply> \ No newline at end of file From 029609d3503328e94ea0e697ff04af8c17c8f1d9 Mon Sep 17 00:00:00 2001 From: Sridhar Ratnakumar <srid@srid.ca> Date: Wed, 17 Aug 2022 19:26:04 -0400 Subject: [PATCH 44/54] design: use icon to initiate search in all 3 places (note, book, breadcrumb) --- default/templates/components/breadcrumbs.tpl | 11 +++-- .../templates/components/stork/stork-icon.tpl | 5 +++ .../components/stork/stork-search-nav.tpl | 8 ---- .../components/stork/stork-search.tpl | 43 +++++++++---------- default/templates/layouts/book.tpl | 5 ++- default/templates/layouts/note.tpl | 12 ++++-- 6 files changed, 42 insertions(+), 42 deletions(-) create mode 100644 default/templates/components/stork/stork-icon.tpl delete mode 100644 default/templates/components/stork/stork-search-nav.tpl diff --git a/default/templates/components/breadcrumbs.tpl b/default/templates/components/breadcrumbs.tpl index 30b315e63..1f64e6dce 100644 --- a/default/templates/components/breadcrumbs.tpl +++ b/default/templates/components/breadcrumbs.tpl @@ -25,11 +25,10 @@ </ema:breadcrumbs> </ul> </div> - <button - class="inline px-2 py-1 text-white bg-${theme}-100 outline-none cursor-pointer focus:outline-none" - title="Search documents" type="button" - onclick="toggleSearch()" - >🔍</button> + <button class="inline px-2 py-1 bg-gray-50 outline-none cursor-pointer focus:outline-none" + title="Search (Ctrl+K)" type="button" onclick="toggleSearch()"> + <apply template="stork/stork-icon" /> + </button> <button class="inline px-2 py-1 text-white bg-${theme}-600 outline-none cursor-pointer focus:outline-none" title="Toggle sidebar" type="button" onclick="toggleHidden('sidebar')"> @@ -45,4 +44,4 @@ } </script> </div> -</nav> +</nav> \ No newline at end of file diff --git a/default/templates/components/stork/stork-icon.tpl b/default/templates/components/stork/stork-icon.tpl new file mode 100644 index 000000000..476771c8a --- /dev/null +++ b/default/templates/components/stork/stork-icon.tpl @@ -0,0 +1,5 @@ +<svg xmlns="http://www.w3.org/2000/svg" style="width: 1rem;" class="hover:text-${theme}-700" f + fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"> + <path stroke-linecap="round" stroke-linejoin="round" + d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" /> +</svg> \ No newline at end of file diff --git a/default/templates/components/stork/stork-search-nav.tpl b/default/templates/components/stork/stork-search-nav.tpl deleted file mode 100644 index c96a0d276..000000000 --- a/default/templates/components/stork/stork-search-nav.tpl +++ /dev/null @@ -1,8 +0,0 @@ -<div class="px-2 pt-2"> - <button type="button" - class="p-2 bg-white text-gray-400 border-gray-200 rounded w-full ring-1 ring-gray-200 text-sm flex items-center" - onclick="toggleSearch()"> - <span>🔍 Search...</span> - <span class="ml-auto pl-3 flex-none text-xs font-semibold">Ctrl K</span> - </button> -</div> diff --git a/default/templates/components/stork/stork-search.tpl b/default/templates/components/stork/stork-search.tpl index 67745f00d..8a5420805 100644 --- a/default/templates/components/stork/stork-search.tpl +++ b/default/templates/components/stork/stork-search.tpl @@ -1,28 +1,27 @@ <div id="stork-search-container" - class="hidden fixed w-screen h-screen inset-0 backdrop-filter backdrop-blur-sm"> - <div - class="fixed w-screen h-screen inset-0" - onclick="toggleSearch()"></div> + class="hidden fixed w-screen h-screen inset-0 backdrop-filter backdrop-blur-sm"> + <div class="fixed w-screen h-screen inset-0" onclick="toggleSearch()"></div> - <div class="container mx-auto p-10 mt-10"> - <div class="stork-wrapper-flat container mx-auto"> - <input id="stork-search-input" data-stork="emanote-search" class="stork-input" placeholder="Search..." /> + <div class="container mx-auto p-10 mt-10"> + <div class="stork-wrapper-flat container mx-auto"> + <input id="stork-search-input" data-stork="emanote-search" class="stork-input" + placeholder="Search (Ctrl+K) ..." /> - <button class="stork-close-button" - onclick="clearSearch()"> - <svg height="0.8em" viewBox="0 0 23 24" xmlns="http://www.w3.org/2000/svg"> - <g fill="none" fill-rule="evenodd" stroke-linecap="round"> - <g transform="translate(-700 -149)" stroke="currentcolor" stroke-width="4"> - <line id="a" x1="702.5" x2="720" y1="152.5" y2="170"></line> - <line transform="translate(711 161) rotate(-90) translate(-711 -161)" x1="702.5" x2="720" y1="152.5" y2="170"></line> - </g> - </g> - </svg> - </button> + <button class="stork-close-button" onclick="clearSearch()"> + <svg height="0.8em" viewBox="0 0 23 24" xmlns="http://www.w3.org/2000/svg"> + <g fill="none" fill-rule="evenodd" stroke-linecap="round"> + <g transform="translate(-700 -149)" stroke="currentcolor" stroke-width="4"> + <line id="a" x1="702.5" x2="720" y1="152.5" y2="170"></line> + <line transform="translate(711 161) rotate(-90) translate(-711 -161)" x1="702.5" + x2="720" y1="152.5" y2="170"></line> + </g> + </g> + </svg> + </button> - <div data-stork="emanote-search-output" class="stork-output"></div> - </div> - </div> + <div data-stork="emanote-search-output" class="stork-output"></div> + </div> + </div> </div> <apply template="stork-search-css" /> -<apply template="stork-search-js" /> +<apply template="stork-search-js" /> \ No newline at end of file diff --git a/default/templates/layouts/book.tpl b/default/templates/layouts/book.tpl index 17331fd90..986d71cb8 100644 --- a/default/templates/layouts/book.tpl +++ b/default/templates/layouts/book.tpl @@ -10,9 +10,7 @@ <!-- Sidebar column --> <nav id="sidebar" class="flex-shrink hidden leading-relaxed md:block md:sticky md:top-0 md:h-full md:w-48 xl:w-64"> - <apply template="components/stork/stork-search-nav" /> <div class="px-2 py-2 text-gray-800"> - <div id="indexing-links" class="flex flex-row float-right p-2 space-x-2 text-gray-500"> <a href="${ema:tagIndexUrl}" title="View tags"> <svg style="width: 1rem;" class="hover:text-${theme}-700" fill="none" @@ -30,6 +28,9 @@ </path> </svg> </a> + <a title="Search (Ctrl+K)" class="cursor-pointer" onclick="toggleSearch()"> + <apply template="components/stork/stork-icon" /> + </a> </div> <div id="site-logo" class="pl-2"> diff --git a/default/templates/layouts/note.tpl b/default/templates/layouts/note.tpl index 20ac30963..932f63f2a 100644 --- a/default/templates/layouts/note.tpl +++ b/default/templates/layouts/note.tpl @@ -12,11 +12,15 @@ <div class="${containerClass}"> <div class="mt-2 md:mt-4"> <apply template="components/note-uptree" /> - <div class="md:shadow-2xl md:mb-8"> + + <div class="relative md:shadow-2xl md:mb-8"> + + <div class="absolute -top-6 right-0 flex flex-row items-center justify-center"> + <a title="Search (Ctrl+K)" class="cursor-pointer" onclick="toggleSearch()"> + <apply template="components/stork/stork-icon" /> + </a> + </div> <div class="flex-1 w-full overflow-x-auto bg-white"> - <div class="px-2 pt-2"> - <apply template="components/stork/stork-search-nav" /> - </div> <main class="px-4 py-4"> <apply template="components/note-title" /> <apply template="components/note-body" /> From 92bacc8f2096d69b402cf8585109ee7198d32ac7 Mon Sep 17 00:00:00 2001 From: Sridhar Ratnakumar <srid@srid.ca> Date: Fri, 19 Aug 2022 16:48:57 -0400 Subject: [PATCH 45/54] Update ema --- emanote.cabal | 3 ++- flake.lock | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/emanote.cabal b/emanote.cabal index f050ff83b..3be68cbcc 100644 --- a/emanote.cabal +++ b/emanote.cabal @@ -103,7 +103,7 @@ common library-common , data-default , dependent-sum , directory - , ema >=0.7.2 + , ema >=0.8 , filepath , filepattern , fsnotify @@ -142,6 +142,7 @@ common library-common , unordered-containers , uri-encode , url-slug + , stm , uuid , which , with-utf8 diff --git a/flake.lock b/flake.lock index c792dbb97..e9621af06 100644 --- a/flake.lock +++ b/flake.lock @@ -3,11 +3,11 @@ "ema": { "flake": false, "locked": { - "lastModified": 1660337803, - "narHash": "sha256-5HKR+T8/OuNzATvdA/ZmTOQmEVODAfTkna+0VkYxpG8=", + "lastModified": 1660941244, + "narHash": "sha256-gGhvmSjjr07u8uWaBIv6F5WE+VCGngSVXN9mhb4BmQo=", "owner": "srid", "repo": "ema", - "rev": "459d3899e0b9ea13e23c81126279dc62530b994c", + "rev": "d74daa4d0d1f7a14cebd415787166fe7909fc33b", "type": "github" }, "original": { From 2de10a81f4e5645464725e4264c7a09d741851b9 Mon Sep 17 00:00:00 2001 From: Sridhar Ratnakumar <srid@srid.ca> Date: Fri, 19 Aug 2022 16:49:04 -0400 Subject: [PATCH 46/54] Inc major ver --- emanote.cabal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emanote.cabal b/emanote.cabal index 3be68cbcc..63e16f12d 100644 --- a/emanote.cabal +++ b/emanote.cabal @@ -1,6 +1,6 @@ cabal-version: 2.4 name: emanote -version: 0.6.23.1 +version: 0.7.0.0 license: AGPL-3.0-only copyright: 2021 Sridhar Ratnakumar maintainer: srid@srid.ca From 1374943922bb8444d7bfe299a5b540956634f07c Mon Sep 17 00:00:00 2001 From: Sridhar Ratnakumar <srid@srid.ca> Date: Fri, 19 Aug 2022 16:53:47 -0400 Subject: [PATCH 47/54] Format! --- emanote.cabal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emanote.cabal b/emanote.cabal index 63e16f12d..b63e068e4 100644 --- a/emanote.cabal +++ b/emanote.cabal @@ -131,6 +131,7 @@ common library-common , relude >=1.0 , shower , some + , stm , tagged , tagtree , tailwind >=0.3 @@ -142,7 +143,6 @@ common library-common , unordered-containers , uri-encode , url-slug - , stm , uuid , which , with-utf8 From a383d1c27345e911b33443b61f83af7b4ee0d48a Mon Sep 17 00:00:00 2001 From: Sridhar Ratnakumar <srid@srid.ca> Date: Fri, 19 Aug 2022 18:37:34 -0400 Subject: [PATCH 48/54] Workaround the unicode issue with tomland Resolves #336 --- src/Emanote/Model/Stork/Index.hs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/Emanote/Model/Stork/Index.hs b/src/Emanote/Model/Stork/Index.hs index 5179f00b7..d80f95712 100644 --- a/src/Emanote/Model/Stork/Index.hs +++ b/src/Emanote/Model/Stork/Index.hs @@ -12,6 +12,7 @@ module Emanote.Model.Stork.Index where import Control.Monad.Logger (MonadLoggerIO) +import Data.Text qualified as T import Data.Time (NominalDiffTime, diffUTCTime, getCurrentTime) import Emanote.Prelude (log, logD, logW) import Numeric (showGFloat) @@ -58,7 +59,7 @@ storkBin = $(staticWhich "stork") runStork :: MonadIO m => Input -> m LByteString runStork input = do - let storkToml = Toml.encode inputCodec input + let storkToml = handleTomlandBug $ Toml.encode inputCodec input (_, !index, _) <- liftIO $ readProcessWithExitCode @@ -68,6 +69,15 @@ runStork input = do ["build", "-t", "--input", "-", "--output", "/dev/stdout"] (encodeUtf8 storkToml) pure $ toLazy index + where + handleTomlandBug = + -- HACK: Deal with tomland's bug. + -- https://github.com/EmaApps/emanote/issues/336 + -- https://github.com/kowainik/tomland/issues/408 + -- + -- This could be problematic if the user literally uses \\U in their note + -- title (but why would they?) + T.replace "\\\\U" "\\U" newtype Input = Input { inputFiles :: [File] From 5959f67c1306b0d1f44c33c9028f615ee3df6c4b Mon Sep 17 00:00:00 2001 From: Sridhar Ratnakumar <srid@srid.ca> Date: Fri, 19 Aug 2022 18:42:59 -0400 Subject: [PATCH 49/54] docs: add full-text search Very basic intro. Could be expanded. --- docs/guide/search.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 docs/guide/search.md diff --git a/docs/guide/search.md b/docs/guide/search.md new file mode 100644 index 000000000..1c027febc --- /dev/null +++ b/docs/guide/search.md @@ -0,0 +1,5 @@ +# Full-text search + +Emanote provides client-side full-text search using [Stork](https://stork-search.net/)[^1]. The keyboard shortcut `Ctrl+K` (or `⌘K` on macOS) can be used to access the search input. Search should work in both live server and the statically generated site. + +[^1]: The Stork index file can be accessed at [`-/stork.st`](-/stork.st). \ No newline at end of file From ebaa0b6d960d4195b3871feb76dcef06d44de1e6 Mon Sep 17 00:00:00 2001 From: Sridhar Ratnakumar <srid@srid.ca> Date: Sun, 21 Aug 2022 11:23:25 -0400 Subject: [PATCH 50/54] refactor: merge stork js/css into a single file, and include that in <head> (not <body>) --- default/templates/base.tpl | 1 + .../components/stork/stork-search-css.tpl | 18 ------ .../components/stork/stork-search-head.tpl | 64 +++++++++++++++++++ .../components/stork/stork-search-js.tpl | 45 ------------- .../components/stork/stork-search.tpl | 4 +- 5 files changed, 66 insertions(+), 66 deletions(-) delete mode 100644 default/templates/components/stork/stork-search-css.tpl create mode 100644 default/templates/components/stork/stork-search-head.tpl delete mode 100644 default/templates/components/stork/stork-search-js.tpl diff --git a/default/templates/base.tpl b/default/templates/base.tpl index f19720607..cfbff4e25 100644 --- a/default/templates/base.tpl +++ b/default/templates/base.tpl @@ -34,6 +34,7 @@ <apply template="/templates/hooks/more-head" /> <head-main /> + <apply template="components/stork/stork-search-head" /> </head> <!-- DoNotFormat --> diff --git a/default/templates/components/stork/stork-search-css.tpl b/default/templates/components/stork/stork-search-css.tpl deleted file mode 100644 index 0ca3701e4..000000000 --- a/default/templates/components/stork/stork-search-css.tpl +++ /dev/null @@ -1,18 +0,0 @@ -<link rel="stylesheet" href="https://files.stork-search.net/releases/v1.5.0/flat.css" /> -<!-- Custom Stork-search styling for Emanote --> -<style> - #stork-search-container { - z-index: 1000; - background-color: rgb(15 23 42/.8); - } - - .stork-overflow-hidden-important { - overflow: hidden !important; - } - - .stork-wrapper-flat .stork-close-button svg { - /* small bugfix in Stork's stock styling */ - margin: auto; - } -</style> - diff --git a/default/templates/components/stork/stork-search-head.tpl b/default/templates/components/stork/stork-search-head.tpl new file mode 100644 index 000000000..a552500c3 --- /dev/null +++ b/default/templates/components/stork/stork-search-head.tpl @@ -0,0 +1,64 @@ +<link rel="stylesheet" href="https://files.stork-search.net/releases/v1.5.0/flat.css" /> +<!-- Custom Stork-search styling for Emanote --> +<style> + #stork-search-container { + z-index: 1000; + background-color: rgb(15 23 42/.8); + } + + .stork-overflow-hidden-important { + overflow: hidden !important; + } + + .stork-wrapper-flat .stork-close-button svg { + /* small bugfix in Stork's stock styling */ + margin: auto; + } +</style> + + +<script src="https://files.stork-search.net/releases/v1.5.0/stork.js"></script> +<ema:metadata> + <with var="template"> + <script data-emanote-base-url="${value:baseUrl}"> + window.searchShown = false; + function toggleSearch() { + document.getElementById('stork-search-container').classList.toggle('hidden'); + window.searchShown = document.body.classList.toggle('stork-overflow-hidden-important'); + if (window.searchShown) { + document.getElementById('stork-search-input').focus(); + } + } + + function clearSearch() { + document.getElementById('stork-search-container').classList.add('hidden'); + document.body.classList.remove('stork-overflow-hidden-important'); + window.searchShown = false; + } + + (function () { + const indexName = 'emanote-search'; // used to match input[data-stork] attribute value + const baseUrl = document.currentScript.getAttribute('data-emanote-base-url') || '/'; + const indexUrl = baseUrl + '-/stork.st'; + if (document.readyState !== 'complete') { + window.addEventListener('load', function () { + stork.register(indexName, indexUrl); + }); + + document.addEventListener('keydown', event => { + if (window.searchShown && event.key === 'Escape') { + clearSearch(); + event.preventDefault(); + } else if ((event.key == 'k' || event.key == 'K') && (event.ctrlKey || event.metaKey)) { + toggleSearch(); + event.preventDefault(); + } + }); + } else { + // Override existing on Ema's hot-reload + stork.register(indexName, indexUrl, { forceOverwrite: true }); + } + })(); + </script> + </with> +</ema:metadata> \ No newline at end of file diff --git a/default/templates/components/stork/stork-search-js.tpl b/default/templates/components/stork/stork-search-js.tpl deleted file mode 100644 index b220b14c8..000000000 --- a/default/templates/components/stork/stork-search-js.tpl +++ /dev/null @@ -1,45 +0,0 @@ -<script src="https://files.stork-search.net/releases/v1.5.0/stork.js"></script> -<ema:metadata> - <with var="template"> - <script data-emanote-base-url="${value:baseUrl}"> - window.searchShown = false; - function toggleSearch() { - document.getElementById('stork-search-container').classList.toggle('hidden'); - window.searchShown = document.body.classList.toggle('stork-overflow-hidden-important'); - if (window.searchShown) { - document.getElementById('stork-search-input').focus(); - } - } - - function clearSearch() { - document.getElementById('stork-search-container').classList.add('hidden'); - document.body.classList.remove('stork-overflow-hidden-important'); - window.searchShown = false; - } - - (function() { - const indexName = 'emanote-search'; // used to match input[data-stork] attribute value - const baseUrl = document.currentScript.getAttribute('data-emanote-base-url') || '/'; - const indexUrl = baseUrl + '-/stork.st'; - if (document.readyState !== 'complete') { - window.addEventListener('load', function() { - stork.register(indexName, indexUrl); - }); - - document.addEventListener('keydown', event => { - if (window.searchShown && event.key === 'Escape') { - clearSearch(); - event.preventDefault(); - } else if ((event.key == 'k' || event.key == 'K') && (event.ctrlKey || event.metaKey)) { - toggleSearch(); - event.preventDefault(); - } - }); - } else { - // Override existing on Ema's hot-reload - stork.register(indexName, indexUrl, {forceOverwrite: true}); - } - })(); - </script> - </with> -</ema:metadata> diff --git a/default/templates/components/stork/stork-search.tpl b/default/templates/components/stork/stork-search.tpl index 8a5420805..f879eb755 100644 --- a/default/templates/components/stork/stork-search.tpl +++ b/default/templates/components/stork/stork-search.tpl @@ -22,6 +22,4 @@ <div data-stork="emanote-search-output" class="stork-output"></div> </div> </div> -</div> -<apply template="stork-search-css" /> -<apply template="stork-search-js" /> \ No newline at end of file +</div> \ No newline at end of file From 1bde67133f58b746d6f897e7e4ac817268b4661d Mon Sep 17 00:00:00 2001 From: Sridhar Ratnakumar <srid@srid.ca> Date: Sun, 21 Aug 2022 11:24:28 -0400 Subject: [PATCH 51/54] add right padding to search icon in mobile view of note layout --- default/templates/layouts/note.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/default/templates/layouts/note.tpl b/default/templates/layouts/note.tpl index 932f63f2a..6f2fa08f9 100644 --- a/default/templates/layouts/note.tpl +++ b/default/templates/layouts/note.tpl @@ -15,7 +15,7 @@ <div class="relative md:shadow-2xl md:mb-8"> - <div class="absolute -top-6 right-0 flex flex-row items-center justify-center"> + <div class="absolute -top-6 right-1 md:right-0 flex flex-row items-center justify-center"> <a title="Search (Ctrl+K)" class="cursor-pointer" onclick="toggleSearch()"> <apply template="components/stork/stork-icon" /> </a> From f83d1caa81c0716813101f35ab3f578f0cc4c2e9 Mon Sep 17 00:00:00 2001 From: Sridhar Ratnakumar <srid@srid.ca> Date: Sun, 21 Aug 2022 11:25:31 -0400 Subject: [PATCH 52/54] remove close button --- default/templates/components/stork/stork-search.tpl | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/default/templates/components/stork/stork-search.tpl b/default/templates/components/stork/stork-search.tpl index f879eb755..49a8724d0 100644 --- a/default/templates/components/stork/stork-search.tpl +++ b/default/templates/components/stork/stork-search.tpl @@ -6,19 +6,6 @@ <div class="stork-wrapper-flat container mx-auto"> <input id="stork-search-input" data-stork="emanote-search" class="stork-input" placeholder="Search (Ctrl+K) ..." /> - - <button class="stork-close-button" onclick="clearSearch()"> - <svg height="0.8em" viewBox="0 0 23 24" xmlns="http://www.w3.org/2000/svg"> - <g fill="none" fill-rule="evenodd" stroke-linecap="round"> - <g transform="translate(-700 -149)" stroke="currentcolor" stroke-width="4"> - <line id="a" x1="702.5" x2="720" y1="152.5" y2="170"></line> - <line transform="translate(711 161) rotate(-90) translate(-711 -161)" x1="702.5" - x2="720" y1="152.5" y2="170"></line> - </g> - </g> - </svg> - </button> - <div data-stork="emanote-search-output" class="stork-output"></div> </div> </div> From c5649715f21400eab1221f835713c4c1e0c27fe8 Mon Sep 17 00:00:00 2001 From: Sridhar Ratnakumar <srid@srid.ca> Date: Sun, 21 Aug 2022 11:36:01 -0400 Subject: [PATCH 53/54] Namespace the stork JS functions --- .../components/stork/stork-search-head.tpl | 74 ++++++++++--------- .../components/stork/stork-search.tpl | 2 +- default/templates/layouts/book.tpl | 3 +- default/templates/layouts/note.tpl | 3 +- 4 files changed, 44 insertions(+), 38 deletions(-) diff --git a/default/templates/components/stork/stork-search-head.tpl b/default/templates/components/stork/stork-search-head.tpl index a552500c3..a81fc8f22 100644 --- a/default/templates/components/stork/stork-search-head.tpl +++ b/default/templates/components/stork/stork-search-head.tpl @@ -21,44 +21,48 @@ <ema:metadata> <with var="template"> <script data-emanote-base-url="${value:baseUrl}"> - window.searchShown = false; - function toggleSearch() { - document.getElementById('stork-search-container').classList.toggle('hidden'); - window.searchShown = document.body.classList.toggle('stork-overflow-hidden-important'); - if (window.searchShown) { - document.getElementById('stork-search-input').focus(); - } - } - - function clearSearch() { - document.getElementById('stork-search-container').classList.add('hidden'); - document.body.classList.remove('stork-overflow-hidden-important'); - window.searchShown = false; - } + window.emanote = {}; + window.emanote.stork = { + searchShown: false, + toggleSearch: function () { + document.getElementById('stork-search-container').classList.toggle('hidden'); + window.emanote.stork.searchShown = document.body.classList.toggle('stork-overflow-hidden-important'); + if (window.emanote.stork.searchShown) { + document.getElementById('stork-search-input').focus(); + } + }, + clearSearch: function () { + document.getElementById('stork-search-container').classList.add('hidden'); + document.body.classList.remove('stork-overflow-hidden-important'); + window.emanote.stork.searchShown = false; + }, - (function () { - const indexName = 'emanote-search'; // used to match input[data-stork] attribute value - const baseUrl = document.currentScript.getAttribute('data-emanote-base-url') || '/'; - const indexUrl = baseUrl + '-/stork.st'; - if (document.readyState !== 'complete') { - window.addEventListener('load', function () { - stork.register(indexName, indexUrl); - }); + init: function () { + const indexName = 'emanote-search'; // used to match input[data-stork] attribute value + const baseUrl = document.currentScript.getAttribute('data-emanote-base-url') || '/'; + const indexUrl = baseUrl + '-/stork.st'; + if (document.readyState !== 'complete') { + window.addEventListener('load', function () { + stork.register(indexName, indexUrl); + }); - document.addEventListener('keydown', event => { - if (window.searchShown && event.key === 'Escape') { - clearSearch(); - event.preventDefault(); - } else if ((event.key == 'k' || event.key == 'K') && (event.ctrlKey || event.metaKey)) { - toggleSearch(); - event.preventDefault(); - } - }); - } else { - // Override existing on Ema's hot-reload - stork.register(indexName, indexUrl, { forceOverwrite: true }); + document.addEventListener('keydown', event => { + if (window.emanote.stork.searchShown && event.key === 'Escape') { + window.emanote.stork.clearSearch(); + event.preventDefault(); + } else if ((event.key == 'k' || event.key == 'K') && (event.ctrlKey || event.metaKey)) { + window.emanote.stork.toggleSearch(); + event.preventDefault(); + } + }); + } else { + // Override existing on Ema's hot-reload + stork.register(indexName, indexUrl, { forceOverwrite: true }); + } } - })(); + }; + + window.emanote.stork.init(); </script> </with> </ema:metadata> \ No newline at end of file diff --git a/default/templates/components/stork/stork-search.tpl b/default/templates/components/stork/stork-search.tpl index 49a8724d0..14c0f5e26 100644 --- a/default/templates/components/stork/stork-search.tpl +++ b/default/templates/components/stork/stork-search.tpl @@ -1,6 +1,6 @@ <div id="stork-search-container" class="hidden fixed w-screen h-screen inset-0 backdrop-filter backdrop-blur-sm"> - <div class="fixed w-screen h-screen inset-0" onclick="toggleSearch()"></div> + <div class="fixed w-screen h-screen inset-0" onclick="window.emanote.stork.toggleSearch()"></div> <div class="container mx-auto p-10 mt-10"> <div class="stork-wrapper-flat container mx-auto"> diff --git a/default/templates/layouts/book.tpl b/default/templates/layouts/book.tpl index 986d71cb8..cb443051e 100644 --- a/default/templates/layouts/book.tpl +++ b/default/templates/layouts/book.tpl @@ -28,7 +28,8 @@ </path> </svg> </a> - <a title="Search (Ctrl+K)" class="cursor-pointer" onclick="toggleSearch()"> + <a title="Search (Ctrl+K)" class="cursor-pointer" + onclick="window.emanote.stork.toggleSearch()"> <apply template="components/stork/stork-icon" /> </a> </div> diff --git a/default/templates/layouts/note.tpl b/default/templates/layouts/note.tpl index 6f2fa08f9..1932231f7 100644 --- a/default/templates/layouts/note.tpl +++ b/default/templates/layouts/note.tpl @@ -16,7 +16,8 @@ <div class="relative md:shadow-2xl md:mb-8"> <div class="absolute -top-6 right-1 md:right-0 flex flex-row items-center justify-center"> - <a title="Search (Ctrl+K)" class="cursor-pointer" onclick="toggleSearch()"> + <a title="Search (Ctrl+K)" class="cursor-pointer" + onclick="window.emanote.stork.toggleSearch()"> <apply template="components/stork/stork-icon" /> </a> </div> From b97f69021d6d6c72861f3ee3ec0818aef709da5b Mon Sep 17 00:00:00 2001 From: Sridhar Ratnakumar <srid@srid.ca> Date: Sun, 21 Aug 2022 11:39:10 -0400 Subject: [PATCH 54/54] remove redundant --- default/templates/components/stork/stork-search-head.tpl | 5 ----- 1 file changed, 5 deletions(-) diff --git a/default/templates/components/stork/stork-search-head.tpl b/default/templates/components/stork/stork-search-head.tpl index a81fc8f22..18de8c2bc 100644 --- a/default/templates/components/stork/stork-search-head.tpl +++ b/default/templates/components/stork/stork-search-head.tpl @@ -9,11 +9,6 @@ .stork-overflow-hidden-important { overflow: hidden !important; } - - .stork-wrapper-flat .stork-close-button svg { - /* small bugfix in Stork's stock styling */ - margin: auto; - } </style>