From da292334cc5e89d020b8b4d6ed3776f0bdf0f44a Mon Sep 17 00:00:00 2001 From: kylemarkleyepa <158192237+kylemarkleyepa@users.noreply.github.com> Date: Tue, 10 Sep 2024 13:42:05 -0400 Subject: [PATCH] Adding page-level table of contents and fix the edit url path (#1629) --- docs/book.toml | 4 +- docs/theme/index.hbs | 351 +++++++++++++++++++++++++++++++++++++++++ docs/theme/pagetoc.css | 101 ++++++++++++ docs/theme/pagetoc.js | 114 +++++++++++++ 4 files changed, 569 insertions(+), 1 deletion(-) create mode 100644 docs/theme/index.hbs create mode 100644 docs/theme/pagetoc.css create mode 100644 docs/theme/pagetoc.js diff --git a/docs/book.toml b/docs/book.toml index 47af59b6..b36ac464 100644 --- a/docs/book.toml +++ b/docs/book.toml @@ -8,7 +8,9 @@ description = "Documentation for developer looking to use the RCRAInfo/e-Manifes [output.html] git-repository-url = "https://github.com/USEPA/e-manifest" -edit-url-template = "https://github.com/USEPA/e-manifest/edit/master/docs/emanifest_book/{path}" +edit-url-template = "https://github.com/USEPA/e-manifest/edit/master/docs/{path}" +additional-css = ["theme/pagetoc.css"] +additional-js = ["theme/pagetoc.js"] [output.html.fold] enable = true diff --git a/docs/theme/index.hbs b/docs/theme/index.hbs new file mode 100644 index 00000000..10e08b4e --- /dev/null +++ b/docs/theme/index.hbs @@ -0,0 +1,351 @@ + + + + + + {{ title }} + {{#if is_print }} + + {{/if}} + {{#if base_url}} + + {{/if}} + + + + {{> head}} + + + + + + {{#if favicon_svg}} + + {{/if}} + {{#if favicon_png}} + + {{/if}} + + + + {{#if print_enable}} + + {{/if}} + + + + {{#if copy_fonts}} + + {{/if}} + + + + + + + + {{#each additional_css}} + + {{/each}} + + {{#if mathjax_support}} + + + {{/if}} + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ {{> header}} + + + + {{#if search_enabled}} + + {{/if}} + + + + +
+
+
+ {{{ content }}} +
+
+ +
+
+ + +
+
+ + + +
+ + {{#if live_reload_endpoint}} + + + {{/if}} + + {{#if google_analytics}} + + + {{/if}} + + {{#if playground_line_numbers}} + + {{/if}} + + {{#if playground_copyable}} + + {{/if}} + + {{#if playground_js}} + + + + + + {{/if}} + + {{#if search_js}} + + + + {{/if}} + + + + + + + {{#each additional_js}} + + {{/each}} + + {{#if is_print}} + {{#if mathjax_support}} + + {{else}} + + {{/if}} + {{/if}} + +
+ + \ No newline at end of file diff --git a/docs/theme/pagetoc.css b/docs/theme/pagetoc.css new file mode 100644 index 00000000..4dff3a37 --- /dev/null +++ b/docs/theme/pagetoc.css @@ -0,0 +1,101 @@ +:root { + --toc-width: 270px; + --center-content-toc-shift: calc(-1 * var(--toc-width) / 2); +} + +.nav-chapters { + /* adjust width of buttons that bring to the previous or the next page */ + min-width: 50px; +} + +.previous { + /* + adjust the space between the left sidebar or the left side of the screen + and the button that leads to the previous page + */ + margin-left: var(--page-padding); +} + +@media only screen { + main { + display: flex; + } + + @media (max-width: 1179px) { + .sidebar-hidden .sidetoc { + display: none; + } + } + + @media (max-width: 1439px) { + .sidebar-visible .sidetoc { + display: none; + } + } + + @media (1180px <= width <= 1439px) { + .sidebar-hidden main { + position: relative; + left: var(--center-content-toc-shift); + } + } + + @media (1440px <= width <= 1700px) { + .sidebar-visible main { + position: relative; + left: var(--center-content-toc-shift); + } + } + + .content-wrap { + overflow-y: auto; + width: 100%; + } + + .sidetoc { + margin-top: 20px; + margin-left: 10px; + margin-right: auto; + } + .pagetoc { + position: fixed; + /* adjust TOC width */ + width: var(--toc-width); + height: calc(100vh - var(--menu-bar-height) - 0.67em * 4); + overflow: auto; + } + .pagetoc a { + border-left: 1px solid var(--sidebar-bg); + color: var(--fg) !important; + display: block; + padding-bottom: 5px; + padding-top: 5px; + padding-left: 10px; + text-align: left; + text-decoration: none; + } + .pagetoc a:hover, + .pagetoc a.active { + background: var(--sidebar-bg); + color: var(--sidebar-fg) !important; + } + .pagetoc .active { + background: var(--sidebar-bg); + color: var(--sidebar-fg); + } + .pagetoc .pagetoc-H2 { + padding-left: 20px; + } + .pagetoc .pagetoc-H3 { + padding-left: 40px; + } + .pagetoc .pagetoc-H4 { + padding-left: 60px; + } +} + +@media print { + .sidetoc { + display: none; + } +} \ No newline at end of file diff --git a/docs/theme/pagetoc.js b/docs/theme/pagetoc.js new file mode 100644 index 00000000..7936bdb8 --- /dev/null +++ b/docs/theme/pagetoc.js @@ -0,0 +1,114 @@ +function forEach(elems, fun) { + Array.prototype.forEach.call(elems, fun); + } + + function getPagetoc(){ + return document.getElementsByClassName("pagetoc")[0] + } + + function getPagetocElems() { + return getPagetoc().children; + } + + function getHeaders(){ + return document.getElementsByClassName("header") + } + + // Un-active everything when you click it + function forPagetocElem(fun) { + forEach(getPagetocElems(), fun); + } + + function getRect(element) { + return element.getBoundingClientRect(); + } + + function overflowTop(container, element) { + return getRect(container).top - getRect(element).top; + } + + function overflowBottom(container, element) { + return getRect(container).bottom - getRect(element).bottom; + } + + var activeHref = location.href; + + var updateFunction = function (elem = undefined) { + var id = elem; + + if (!id && location.href != activeHref) { + activeHref = location.href; + forPagetocElem(function (el) { + if (el.href === activeHref) { + id = el; + } + }); + } + + if (!id) { + var elements = getHeaders(); + let margin = window.innerHeight / 3; + + forEach(elements, function (el, i, arr) { + if (!id && getRect(el).top >= 0) { + if (getRect(el).top < margin) { + id = el; + } else { + id = arr[Math.max(0, i - 1)]; + } + } + // a very long last section + // its heading is over the screen + if (!id && i == arr.length - 1) { + id = el + } + }); + } + + forPagetocElem(function (el) { + el.classList.remove("active"); + }); + + if (!id) return; + + forPagetocElem(function (el) { + if (id.href.localeCompare(el.href) == 0) { + el.classList.add("active"); + let pagetoc = getPagetoc(); + if (overflowTop(pagetoc, el) > 0) { + pagetoc.scrollTop = el.offsetTop; + } + if (overflowBottom(pagetoc, el) < 0) { + pagetoc.scrollTop -= overflowBottom(pagetoc, el); + } + } + }); + }; + + let elements = getHeaders(); + + if (elements.length > 1) { + // Populate sidebar on load + window.addEventListener("load", function () { + var pagetoc = getPagetoc(); + var elements = getHeaders(); + forEach(elements, function (el) { + var link = document.createElement("a"); + link.appendChild(document.createTextNode(el.text)); + link.href = el.hash; + link.classList.add("pagetoc-" + el.parentElement.tagName); + pagetoc.appendChild(link); + link.onclick = function () { + updateFunction(link); + }; + }); + updateFunction(); + }); + + // Handle active elements on scroll + window.addEventListener("scroll", function () { + updateFunction(); + }); + } else { + document.getElementsByClassName("sidetoc")[0].remove(); + } \ No newline at end of file