scraps 2.1.0

Scraps is a portable CLI knowledge hub for managing interconnected Markdown documentation with Wiki-link notation.
<!DOCTYPE html>
<html lang="{{ lang_code }}">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta property="og:type" content="website" />
        <meta name="twitter:card" content="summary_large_image" />
        <!-- Page title -->
        {% if scrap %}
            {% set title_var=[ scrap.title,title ] | join(sep=" - ") %}
            <title>{{ title_var }}</title>
            <meta property="og:title" content="{{ title_var }}" />
            <meta name="twitter:title" content="{{ title_var }}" />
        {% else %}
            <title>{{ title }}</title>
            <meta property="og:title" content="{{ title }}" />
            <meta name="twitter:title" content="{{ title }}" />
        {% endif %}
        <!-- Page description -->
        {% if description %}
            <meta name="description" content="{{ description }}" />
            <meta property="og:description" content="{{ description }}" />
            <meta name="twitter:description" content="{{ description }}" />
        {% endif %}
        <!-- Page favicon -->
        {% if favicon %}
            <link rel="icon" type="image/png" href="{{ favicon }}" />
        {% endif %}
        <!-- Rubik font -->
        <link href="https://fonts.cdnfonts.com/css/rubik" rel="stylesheet">
        <!-- Noto Sans JP font -->
        <link rel="preconnect" href="https://fonts.googleapis.com">
        <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
        <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@100;300;400;500;700;900&display=swap" rel="stylesheet">
        <!-- Style sheet -->
        <link rel="stylesheet" href="{{ base_url }}main.css">
        {% block head %}
        {% endblock head %}
    </head>
    <body>
        <div class="shell">
        <aside class="sidebar">
            <div class="brand-block">
                <a class="brand" href="{{ base_url }}">
                    <span class="mark">[[&nbsp;]]</span>
                    <span class="name">{{ title }}</span>
                </a>
                {% if has_readme %}
                    {% if view == "about" %}<span class="about active">about</span>{% else %}<a class="about" href="{{ base_url }}about/">about</a>{% endif %}
                {% endif %}
            </div>
            {% if build_search_index == true %}
                <div class="search">
                    <input
                        type="search"
                        id="search-input"
                        onkeyup="doSearch()"
                        placeholder="Search by title..."
                        autocomplete="off"
                        />
                    <ul id="search-results"></ul>
                </div>
            {% endif %}
            <nav class="views">
                <p class="nav-label">views</p>
                {% if view == "updated" %}<span class="item active">updated</span>{% else %}<a class="item" href="{{ base_url }}">updated</a>{% endif %}
                {% if view == "backlinks" %}<span class="item active">backlinks</span>{% else %}<a class="item" href="{{ base_url }}backlinks/">backlinks</a>{% endif %}
                {% if view == "scraps" %}<span class="item active">all scraps<span class="count">{{ scrap_count }}</span></span>{% else %}<a class="item" href="{{ base_url }}scraps/">all scraps<span class="count">{{ scrap_count }}</span></a>{% endif %}
            </nav>
            <nav class="tags">
                <p class="nav-label">tags</p>
                {% for tag in nav_tags | slice(end=5) %}
                    <a class="item" href="{{ base_url }}tags/{{ tag.slug }}.html"><span class="tag-name"><span class="syntax">#[[</span>{{ tag.title }}<span class="syntax">]]</span></span><span class="count">{{ tag.backlinks_count }}</span></a>
                {% endfor %}
                {% if nav_tags | length > 5 %}
                    <a class="item more" href="{{ base_url }}tags/">+ {{ nav_tags | length - 5 }} more</a>
                {% endif %}
            </nav>
            <p class="version">scraps v{{ scraps_version }}</p>
        </aside>
        <div class="main-wrap">
            <main>
                {% block main %}
                {% endblock main %}
            </main>
            <footer class="status-bar">
                <span class="left">{% block status_left %}{{ scrap_count }} scraps indexed{% endblock status_left %}</span>
                <span class="right">Generated by <a href="https://github.com/boykush/scraps" target="_blank" rel="noopener noreferrer">Scraps</a></span>
            </footer>
        </div>
        </div>
        <!-- Code syntax highlight -->
        <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/{{ cdn.highlightjs }}/highlight.min.js"></script>
        <script>hljs.highlightAll();</script>
        <!-- Mermaid -->
        <script type="module">
            import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@{{ cdn.mermaid }}/+esm';
            // A diagram carries its own colours, so it has to be told which
            // scheme the page resolved to; left on the default it draws dark
            // strokes onto the dark ground and the edges disappear.
            const prefersDark = matchMedia('(prefers-color-scheme: dark)');
            const isDark = () => {
                const declared = getComputedStyle(document.documentElement).colorScheme;
                return declared === 'dark' || (declared !== 'light' && prefersDark.matches);
            };
            const draw = () => {
                mermaid.initialize({ startOnLoad: false, theme: isDark() ? 'dark' : 'default' });
                document.querySelectorAll('code.mermaid').forEach((node) => {
                    node.textContent = node.dataset.source ??= node.textContent;
                    node.removeAttribute('data-processed');
                });
                mermaid.run({ querySelector: 'code.mermaid' });
            };
            draw();
            prefersDark.addEventListener('change', draw);
        </script>
        {% if build_search_index == true %}
        <!-- For search scraps -->
        <!--
            fuse.js@7+ ships as ESM only; loading it through a classic <script src>
            fails to evaluate the `export` and leaves window.Fuse undefined. Import it
            from a module script and re-expose it as a global so the classic
            doSearch() handler below can call `new Fuse(...)`.
        -->
        <script type="module">
            import Fuse from "https://cdn.jsdelivr.net/npm/fuse.js@{{ cdn.fusejs }}";
            window.Fuse = Fuse;
            fetch('{{ base_url }}search_index.json')
                .then(response => response.json())
                .then(data => {
                    const fuseOptions = {
                        minMatchCharLength: 3,
                        keys: ["title"]
                    };
                    const fuse = new Fuse(data, fuseOptions);
                    window.search = function (query, numResults) {
                        return fuse.search(query).slice(0, numResults).map(result => [result.item.title, result.item.url]);
                    };
                })
        </script>
        <script>
            function doSearch() {
                const value = document.getElementById("search-input").value;
                const results = search(value, 5);
                const ul = document.getElementById("search-results");
                ul.innerHTML = "";

                results.forEach((result) => {
                    const li = document.createElement("li");
                    const [title, url] = result;
                    const link = document.createElement("a");
                    link.textContent = title;
                    link.setAttribute("href", url);
                    li.appendChild(link);
                    ul.appendChild(li);
                });
            }
        </script>
        {% endif %}
        {% block script %}
        {% endblock script %}
    </body>
</html>