mirror of
https://github.com/trwnh/hugo-theme-paradox.git
synced 2024-12-25 15:58:46 +00:00
feature bringup
This commit is contained in:
parent
13c5b18a1a
commit
e004f35404
34 changed files with 816 additions and 113 deletions
225
assets/scripts/search.js
Normal file
225
assets/scripts/search.js
Normal file
|
@ -0,0 +1,225 @@
|
|||
/*
|
||||
tutorials used:
|
||||
- https://aaronluna.dev/blog/add-search-to-static-site-lunrjs-hugo-vanillajs/#codepen-with-final-code
|
||||
- https://victoria.dev/blog/add-search-to-hugo-static-sites-with-lunr/
|
||||
*/
|
||||
|
||||
let pagesIndex, searchIndex
|
||||
const MAX_SUMMARY_LENGTH = 30
|
||||
const SENTENCE_BOUNDARY_REGEX = /\b\.\s/gm
|
||||
const WORD_REGEX = /\b(\w*)[\W|\s|\b]?/gm
|
||||
|
||||
async function initSearch() {
|
||||
try {
|
||||
const response = await fetch("/index.json");
|
||||
pagesIndex = await response.json();
|
||||
searchIndex = lunr(function () {
|
||||
this.field("title");
|
||||
this.field("content");
|
||||
this.ref("href");
|
||||
pagesIndex.forEach((page) => this.add(page));
|
||||
});
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
console.log("Search index initialized")
|
||||
// Get the query parameter(s)
|
||||
const params = new URLSearchParams(window.location.search)
|
||||
const query = params.get('query')
|
||||
|
||||
// Perform a search if there is a query
|
||||
if (query) {
|
||||
// Retain the search input in the form when displaying results
|
||||
document.getElementById('search-input').setAttribute('value', query)
|
||||
|
||||
// Update the list with results
|
||||
console.log("search performed")
|
||||
let results = searchSite(query)
|
||||
renderSearchResults(query, results)
|
||||
}
|
||||
}
|
||||
|
||||
initSearch();
|
||||
|
||||
function searchSite(query) {
|
||||
const originalQuery = query;
|
||||
query = getLunrSearchQuery(query);
|
||||
let results = getSearchResults(query);
|
||||
return results.length
|
||||
? results
|
||||
: query !== originalQuery
|
||||
? getSearchResults(originalQuery)
|
||||
: [];
|
||||
}
|
||||
|
||||
function getLunrSearchQuery(query) {
|
||||
const searchTerms = query.split(" ");
|
||||
if (searchTerms.length === 1) {
|
||||
return query;
|
||||
}
|
||||
query = "";
|
||||
for (const term of searchTerms) {
|
||||
query += `+${term} `;
|
||||
}
|
||||
return query.trim();
|
||||
}
|
||||
|
||||
function getSearchResults(query) {
|
||||
return searchIndex.search(query).flatMap((hit) => {
|
||||
if (hit.ref == "undefined") return [];
|
||||
let pageMatch = pagesIndex.filter((page) => page.href === hit.ref)[0];
|
||||
pageMatch.score = hit.score;
|
||||
return [pageMatch];
|
||||
});
|
||||
}
|
||||
|
||||
function renderSearchResults(query, results) {
|
||||
clearSearchResults();
|
||||
updateSearchResults(query, results);
|
||||
}
|
||||
|
||||
function clearSearchResults() {
|
||||
const results = document.querySelector("#search-results");
|
||||
while (results.firstChild) results.removeChild(results.firstChild);
|
||||
}
|
||||
|
||||
function updateSearchResults(query, results) {
|
||||
document.getElementById("results-query").innerHTML = query;
|
||||
document.querySelector("#search-results").innerHTML = results
|
||||
.map(
|
||||
(hit) => `
|
||||
<li class="search-result-item" data-score="${hit.score.toFixed(2)}">
|
||||
<a href="${hit.href}" class="search-result-page-title">${createTitleBlurb(query, hit.title)}</a>
|
||||
<p>${createSearchResultBlurb(query, hit.content)}</p>
|
||||
</li>
|
||||
`
|
||||
)
|
||||
.join("");
|
||||
const searchResultListItems = document.querySelectorAll("#search-results li");
|
||||
document.getElementById("results-count").innerHTML = searchResultListItems.length;
|
||||
document.getElementById("results-count-text").innerHTML = searchResultListItems.length === 1 ? "result" : "results";
|
||||
// searchResultListItems.forEach(
|
||||
// (li) => (li.firstElementChild.style.color = getColorForSearchResult(li.dataset.score))
|
||||
// );
|
||||
}
|
||||
|
||||
function createTitleBlurb(query, title) {
|
||||
const searchQueryRegex = new RegExp(createQueryStringRegex(query), "gmi");
|
||||
return title.replace(
|
||||
searchQueryRegex,
|
||||
"<strong>$&</strong>"
|
||||
)
|
||||
}
|
||||
|
||||
function createSearchResultBlurb(query, pageContent) {
|
||||
const searchQueryRegex = new RegExp(createQueryStringRegex(query), "gmi");
|
||||
const searchQueryHits = Array.from(
|
||||
pageContent.matchAll(searchQueryRegex),
|
||||
(m) => m.index
|
||||
);
|
||||
const sentenceBoundaries = Array.from(
|
||||
pageContent.matchAll(SENTENCE_BOUNDARY_REGEX),
|
||||
(m) => m.index
|
||||
);
|
||||
let searchResultText = "";
|
||||
let lastEndOfSentence = 0;
|
||||
for (const hitLocation of searchQueryHits) {
|
||||
if (hitLocation > lastEndOfSentence) {
|
||||
for (let i = 0; i < sentenceBoundaries.length; i++) {
|
||||
if (sentenceBoundaries[i] > hitLocation) {
|
||||
const startOfSentence = i > 0 ? sentenceBoundaries[i - 1] + 1 : 0;
|
||||
const endOfSentence = sentenceBoundaries[i];
|
||||
lastEndOfSentence = endOfSentence;
|
||||
parsedSentence = pageContent.slice(startOfSentence, endOfSentence).trim();
|
||||
searchResultText += `${parsedSentence} ... `;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
const searchResultWords = tokenize(searchResultText);
|
||||
const pageBreakers = searchResultWords.filter((word) => word.length > 50);
|
||||
if (pageBreakers.length > 0) {
|
||||
searchResultText = fixPageBreakers(searchResultText, pageBreakers);
|
||||
}
|
||||
if (searchResultWords.length >= MAX_SUMMARY_LENGTH) break;
|
||||
}
|
||||
return ellipsize(searchResultText, MAX_SUMMARY_LENGTH).replace(
|
||||
searchQueryRegex,
|
||||
"<strong>$&</strong>"
|
||||
);
|
||||
}
|
||||
|
||||
function createQueryStringRegex(query) {
|
||||
const searchTerms = query.split(" ");
|
||||
if (searchTerms.length == 1) {
|
||||
return query;
|
||||
}
|
||||
query = "";
|
||||
for (const term of searchTerms) {
|
||||
query += `${term}|`;
|
||||
}
|
||||
query = query.slice(0, -1);
|
||||
return `(${query})`;
|
||||
}
|
||||
|
||||
function tokenize(input) {
|
||||
const wordMatches = Array.from(input.matchAll(WORD_REGEX), (m) => m);
|
||||
return wordMatches.map((m) => ({
|
||||
word: m[0],
|
||||
start: m.index,
|
||||
end: m.index + m[0].length,
|
||||
length: m[0].length,
|
||||
}));
|
||||
}
|
||||
|
||||
function fixPageBreakers(input, largeWords) {
|
||||
largeWords.forEach((word) => {
|
||||
const chunked = chunkify(word.word, 20);
|
||||
input = input.replace(word.word, chunked);
|
||||
});
|
||||
return input;
|
||||
}
|
||||
|
||||
function chunkify(input, chunkSize) {
|
||||
let output = "";
|
||||
let totalChunks = (input.length / chunkSize) | 0;
|
||||
let lastChunkIsUneven = input.length % chunkSize > 0;
|
||||
if (lastChunkIsUneven) {
|
||||
totalChunks += 1;
|
||||
}
|
||||
for (let i = 0; i < totalChunks; i++) {
|
||||
let start = i * chunkSize;
|
||||
let end = start + chunkSize;
|
||||
if (lastChunkIsUneven && i === totalChunks - 1) {
|
||||
end = input.length;
|
||||
}
|
||||
output += input.slice(start, end) + " ";
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
function ellipsize(input, maxLength) {
|
||||
const words = tokenize(input);
|
||||
if (words.length <= maxLength) {
|
||||
return input;
|
||||
}
|
||||
return input.slice(0, words[maxLength].end) + "...";
|
||||
}
|
||||
|
||||
if (!String.prototype.matchAll) {
|
||||
String.prototype.matchAll = function (regex) {
|
||||
"use strict";
|
||||
function ensureFlag(flags, flag) {
|
||||
return flags.includes(flag) ? flags : flags + flag;
|
||||
}
|
||||
function* matchAll(str, regex) {
|
||||
const localCopy = new RegExp(regex, ensureFlag(regex.flags, "g"));
|
||||
let match;
|
||||
while ((match = localCopy.exec(str))) {
|
||||
match.index = localCopy.lastIndex - match[0].length;
|
||||
yield match;
|
||||
}
|
||||
}
|
||||
return matchAll(this, regex);
|
||||
};
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
.page {
|
||||
.content {
|
||||
/* text */
|
||||
h1 {font-size: 1.8em}
|
||||
h2 {font-size: 1.6em}
|
||||
|
@ -15,6 +15,7 @@
|
|||
p {
|
||||
line-height: 2;
|
||||
margin-bottom: 1em;
|
||||
max-width: 80ch;
|
||||
}
|
||||
a {
|
||||
word-wrap: break-word;
|
||||
|
@ -90,15 +91,36 @@
|
|||
}
|
||||
pre {
|
||||
font-family: monospace;
|
||||
background: #333;
|
||||
color: white;
|
||||
background: var(--ui-overlay);
|
||||
color: var(--ui-overlay-text);
|
||||
padding: 1em;
|
||||
line-height: 1.4;
|
||||
overflow-x: scroll;
|
||||
overflow-x: auto;
|
||||
white-space: pre;
|
||||
display: grid;
|
||||
tab-size: 3;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
code {
|
||||
font-family: monospace;
|
||||
background: var(--ui-overlay);
|
||||
color: var(--ui-overlay-text);
|
||||
padding: 0.25rem;
|
||||
}
|
||||
:not(.highlight) > pre {
|
||||
line-height: 1.5;
|
||||
background: var(--ui-overlay);
|
||||
padding: 1em;
|
||||
}
|
||||
pre code {
|
||||
background: inherit;
|
||||
padding: 0;
|
||||
}
|
||||
pre code > span {
|
||||
padding: 0 1em;
|
||||
}
|
||||
.highlight pre {
|
||||
padding: 1em 0;
|
||||
}
|
||||
/* figures */
|
||||
figure {
|
||||
|
@ -162,25 +184,25 @@
|
|||
content: ']';
|
||||
}
|
||||
}
|
||||
/* toc */
|
||||
.toc-title {
|
||||
margin-bottom: 0.5em;
|
||||
font-weight: 900;
|
||||
text-transform: uppercase;
|
||||
color: var(--ui-text-muted);
|
||||
}
|
||||
#TableOfContents {
|
||||
ul {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
}
|
||||
li {
|
||||
margin: 0;
|
||||
line-height: 1.5;
|
||||
}
|
||||
li > ul { /* indent subheadings */
|
||||
margin: 0;
|
||||
margin-left: 1em;
|
||||
/* the actual footnotes section */
|
||||
.footnotes {
|
||||
hr {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border: 0;
|
||||
&:before {
|
||||
content: 'Footnotes';
|
||||
color: var(--ui-text);
|
||||
text-transform: uppercase;
|
||||
font-weight: 900;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
&:after {
|
||||
content: '';
|
||||
width: 100%;
|
||||
margin-left: 1rem;
|
||||
border-bottom: 1px solid var(--ui-text-muted);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
17
assets/styles/components/breadcrumbs.scss
Normal file
17
assets/styles/components/breadcrumbs.scss
Normal file
|
@ -0,0 +1,17 @@
|
|||
.breadcrumbs {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
li:not(:first-child) {
|
||||
margin-left: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
li::marker {
|
||||
content: "> ";
|
||||
}
|
||||
li:first-child::marker {
|
||||
content: "";
|
||||
}
|
||||
li:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
.header-nav {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
justify-content: center;
|
||||
}
|
|
@ -23,13 +23,22 @@
|
|||
margin-top: 1em;
|
||||
> li {
|
||||
margin-bottom: 1em;
|
||||
> a {
|
||||
display: block;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
li {line-height: 2}
|
||||
.sub-menu {
|
||||
margin-left: 1em;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
gap: 0.5rem;
|
||||
li {
|
||||
line-height: 1.5;
|
||||
}
|
||||
li::marker {
|
||||
content: '⟣ ';
|
||||
content: '→ ';
|
||||
}
|
||||
.sub-menu li::marker {
|
||||
content: '↳ ';
|
16
assets/styles/components/nav-header.scss
Normal file
16
assets/styles/components/nav-header.scss
Normal file
|
@ -0,0 +1,16 @@
|
|||
.header-nav {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
.menu {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
gap: 1em;
|
||||
a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5em;
|
||||
}
|
||||
}
|
||||
}
|
37
assets/styles/components/nav-section.scss
Normal file
37
assets/styles/components/nav-section.scss
Normal file
|
@ -0,0 +1,37 @@
|
|||
.section-nav {
|
||||
.container {
|
||||
display: grid;
|
||||
grid-gap: 1em;
|
||||
}
|
||||
a {
|
||||
border-radius: 0.25rem;
|
||||
display: flex;
|
||||
padding: 1em;
|
||||
gap: 1em;
|
||||
text-decoration: none;
|
||||
background: var(--ui-overlay);
|
||||
color: var(--ui-overlay-text);
|
||||
&:focus {
|
||||
padding: 1em;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
.previous {
|
||||
justify-content: start;
|
||||
}
|
||||
.arrow {
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
font-size: 2em;
|
||||
}
|
||||
@media (min-width: 30rem) {
|
||||
.container {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
.next {
|
||||
grid-column: 2;
|
||||
}
|
||||
}
|
||||
}
|
20
assets/styles/components/single/page-header.scss
Normal file
20
assets/styles/components/single/page-header.scss
Normal file
|
@ -0,0 +1,20 @@
|
|||
.page {
|
||||
.page-title {
|
||||
font-size: 2em;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.page-summary {
|
||||
line-height: 1.5;
|
||||
max-width: 80ch;
|
||||
}
|
||||
.lastmod {
|
||||
margin-top: 1rem;
|
||||
line-height: 1.5;
|
||||
color: var(--ui-text-muted);
|
||||
}
|
||||
.language-list {
|
||||
display: flex;
|
||||
flex-flow: wrap;
|
||||
list-style: none;
|
||||
}
|
||||
}
|
|
@ -1,11 +1,18 @@
|
|||
.site-footer {
|
||||
height: var(--footer-height);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 1em 0;
|
||||
}
|
||||
.site-footer hr {display: none;}
|
||||
.site-footer .container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-flow: row wrap;
|
||||
gap: 1em;
|
||||
}
|
||||
.breadcrumbs {display: flex; flex-flow: row wrap;}
|
||||
|
||||
.footer-nav .menu {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
gap: 1em;
|
||||
}
|
|
@ -3,7 +3,7 @@
|
|||
flex-flow: row;
|
||||
align-items: center;
|
||||
gap: 1em;
|
||||
padding: 4px;
|
||||
text-decoration: none;
|
||||
}
|
||||
.site-icon {
|
||||
height: 2em;
|
||||
|
@ -24,10 +24,11 @@
|
|||
.site-header {padding: 1em 0;}
|
||||
|
||||
.site-header a {
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
}
|
||||
.site-header .container {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
justify-content: space-between;
|
||||
gap: 1em;
|
||||
}
|
27
assets/styles/components/table-of-contents.scss
Normal file
27
assets/styles/components/table-of-contents.scss
Normal file
|
@ -0,0 +1,27 @@
|
|||
.toc-title {
|
||||
margin-bottom: 0.5em;
|
||||
font-weight: 900;
|
||||
text-transform: uppercase;
|
||||
color: var(--ui-text-muted);
|
||||
}
|
||||
#TableOfContents {
|
||||
ul {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
}
|
||||
li {
|
||||
margin: 0;
|
||||
line-height: 1.5;
|
||||
}
|
||||
li > ul { /* indent subheadings */
|
||||
margin: 0;
|
||||
margin-left: 1em;
|
||||
}
|
||||
ol {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
}
|
||||
li > ol {
|
||||
margin-left: 1em;
|
||||
}
|
||||
}
|
74
assets/styles/features/headings.scss
Normal file
74
assets/styles/features/headings.scss
Normal file
|
@ -0,0 +1,74 @@
|
|||
h2.heading {
|
||||
border-bottom: 1px solid var(--ui-text-muted);
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
/* headings with no numbers */
|
||||
|
||||
article:not([autonumbering]) .heading {
|
||||
position: relative;
|
||||
margin-right: 2.5rem;
|
||||
&__anchor-link {
|
||||
display: inline-flex;
|
||||
align-content: center;
|
||||
margin-left: 0.25em;
|
||||
position: absolute;
|
||||
right: -2.5rem;
|
||||
top: 3px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* headings with autonumbering support */
|
||||
|
||||
body {counter-reset: h2}
|
||||
h2 {counter-reset: h3}
|
||||
h3 {counter-reset: h4}
|
||||
h4 {counter-reset: h5}
|
||||
|
||||
article[autonumbering] {
|
||||
h2:before {
|
||||
counter-increment: h2;
|
||||
content: counter(h2) " ";
|
||||
}
|
||||
h3:before {
|
||||
counter-increment: h3;
|
||||
content: counter(h2) "." counter(h3) " ";
|
||||
}
|
||||
h4:before {
|
||||
counter-increment: h4;
|
||||
content: counter(h2) "." counter(h3) "." counter(h4) " ";
|
||||
}
|
||||
h2:before,
|
||||
h3:before,
|
||||
h4:before
|
||||
{
|
||||
margin-right: 1em;
|
||||
font-family: monospace;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.heading {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto;
|
||||
grid-template-rows: auto auto;
|
||||
grid-gap: 0.5rem;
|
||||
&__text {
|
||||
grid-column: span 2;
|
||||
}
|
||||
&__anchor-link {
|
||||
font-size: 1rem;
|
||||
grid-column: 2;
|
||||
grid-row: 1;
|
||||
justify-self: end;
|
||||
}
|
||||
}
|
||||
|
||||
#TableOfContents :is(ol, ul) {
|
||||
counter-reset: item;
|
||||
}
|
||||
#TableOfContents li:before {
|
||||
content: counters(item, ".") ". ";
|
||||
counter-increment: item;
|
||||
}
|
||||
}
|
48
assets/styles/features/search.scss
Normal file
48
assets/styles/features/search.scss
Normal file
|
@ -0,0 +1,48 @@
|
|||
.search-results__title {
|
||||
display: block;
|
||||
font-size: 2em;
|
||||
line-height: 1;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.search-results strong {
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
#search-results {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
}
|
||||
|
||||
#search-results li:not(:first-child) {
|
||||
border-top: 1px solid var(--ui-text-muted);
|
||||
}
|
||||
|
||||
#search-results li {
|
||||
padding: 1em 0;
|
||||
}
|
||||
|
||||
#search-form {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
#search-input {
|
||||
background: var(--ui-overlay);
|
||||
color: var(--ui-overlay-text);
|
||||
border-radius: 100rem;
|
||||
border: 0;
|
||||
padding: 0.5rem 1rem;
|
||||
margin-right: 0.5rem;
|
||||
flex-shrink: 1;
|
||||
}
|
||||
|
||||
#search-submit {
|
||||
padding: 0.5rem 1rem;
|
||||
border: 0;
|
||||
background: var(--primary-accent);
|
||||
color: var(--primary-accent-text);
|
||||
border-radius: 4px;
|
||||
}
|
110
assets/styles/features/syntax-highlighting.scss
Normal file
110
assets/styles/features/syntax-highlighting.scss
Normal file
|
@ -0,0 +1,110 @@
|
|||
/* syntax highlighting */
|
||||
|
||||
.highlight {
|
||||
|
||||
--error: #cc0000;
|
||||
--keyword: #3361a7;
|
||||
--class: #f57900;
|
||||
--variable: #c049dd;
|
||||
--number: #53ca24;
|
||||
--operator: #5400c2;
|
||||
--highlight: rgb(196, 196, 196);
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
|
||||
--error: #cc0000;
|
||||
--keyword: #e0d56e;
|
||||
--class: #8700f5;
|
||||
--variable: #008eb9;
|
||||
--number: #53ca24;
|
||||
--operator: #fffd6f;
|
||||
--highlight: #555;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Background */ .bg { background-color: #f8f8f8; }
|
||||
/* PreWrapper */ .chroma { background-color: #f8f8f8; }
|
||||
/* Other */ .chroma .x { color: var(--ui-text-bold) }
|
||||
/* Error */ .chroma .err { color: var(--error) }
|
||||
/* CodeLine */ .chroma .cl { color: var(--ui-text) }
|
||||
/* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; }
|
||||
/* LineTable */ .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; }
|
||||
/* LineHighlight */ .chroma .hl { background-color: var(--highlight) }
|
||||
/* LineNumbersTable */ .chroma .lnt { white-space: pre; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f }
|
||||
/* LineNumbers */ .chroma .ln { white-space: pre; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f }
|
||||
/* Line */ .chroma .line { display: flex; white-space: pre }
|
||||
/* Keyword */ .chroma .k { color: var(--keyword); font-weight: bold }
|
||||
/* KeywordConstant */ .chroma .kc { color: var(--keyword); font-weight: bold }
|
||||
/* KeywordDeclaration */ .chroma .kd { color: var(--keyword); font-weight: bold }
|
||||
/* KeywordNamespace */ .chroma .kn { color: var(--keyword); font-weight: bold }
|
||||
/* KeywordPseudo */ .chroma .kp { color: var(--keyword); font-weight: bold }
|
||||
/* KeywordReserved */ .chroma .kr { color: var(--keyword); font-weight: bold }
|
||||
/* KeywordType */ .chroma .kt { color: var(--keyword); font-weight: bold }
|
||||
/* Name */ .chroma .n { color: var(--ui-text-bold) }
|
||||
/* NameAttribute */ .chroma .na { color: var(--ui-text-bold) }
|
||||
/* NameBuiltin */ .chroma .nb { color: var(--name) }
|
||||
/* NameBuiltinPseudo */ .chroma .bp { color: #3465a4 }
|
||||
/* NameClass */ .chroma .nc { color: var(--ui-text-bold) }
|
||||
/* NameConstant */ .chroma .no { color: var(--ui-text-bold) }
|
||||
/* NameDecorator */ .chroma .nd { color: var(--class); font-weight: bold }
|
||||
/* NameEntity */ .chroma .ni { color: var(--name) }
|
||||
/* NameException */ .chroma .ne { color: var(--error); font-weight: bold }
|
||||
/* NameFunction */ .chroma .nf { color: var(--ui-text-bold) }
|
||||
/* NameFunctionMagic */ .chroma .fm { color: var(--ui-text-bold) }
|
||||
/* NameLabel */ .chroma .nl { color: var(--name) }
|
||||
/* NameNamespace */ .chroma .nn { color: var(--ui-text-bold) }
|
||||
/* NameOther */ .chroma .nx { color: var(--ui-text-bold)}
|
||||
/* NameProperty */ .chroma .py { color: var(--ui-text-bold) }
|
||||
/* NameTag */ .chroma .nt { color: var(--keyword); font-weight: bold }
|
||||
/* NameVariable */ .chroma .nv { color: var(--variable) }
|
||||
/* NameVariableClass */ .chroma .vc { color: var(--ui-text-bold)}
|
||||
/* NameVariableGlobal */ .chroma .vg { color: var(--ui-text-bold) }
|
||||
/* NameVariableInstance */ .chroma .vi { color: var(--ui-text-bold) }
|
||||
/* NameVariableMagic */ .chroma .vm { color: var(--ui-text-bold) }
|
||||
/* Literal */ .chroma .l { color: var(--ui-text-bold) }
|
||||
/* LiteralDate */ .chroma .ld { color: var(--ui-text-bold) }
|
||||
/* LiteralString */ .chroma .s { color: var(--variable) }
|
||||
/* LiteralStringAffix */ .chroma .sa { color: var(--variable) }
|
||||
/* LiteralStringBacktick */ .chroma .sb { color: var(--variable) }
|
||||
/* LiteralStringChar */ .chroma .sc { color: var(--variable) }
|
||||
/* LiteralStringDelimiter */ .chroma .dl { color: var(--variable) }
|
||||
/* LiteralStringDoc */ .chroma .sd { color: var(--keyword); font-style: italic }
|
||||
/* LiteralStringDouble */ .chroma .s2 { color: var(--variable) }
|
||||
/* LiteralStringEscape */ .chroma .se { color: var(--variable) }
|
||||
/* LiteralStringHeredoc */ .chroma .sh { color: var(--variable) }
|
||||
/* LiteralStringInterpol */ .chroma .si { color: var(--variable) }
|
||||
/* LiteralStringOther */ .chroma .sx { color: var(--variable) }
|
||||
/* LiteralStringRegex */ .chroma .sr { color: var(--variable) }
|
||||
/* LiteralStringSingle */ .chroma .s1 { color: var(--variable) }
|
||||
/* LiteralStringSymbol */ .chroma .ss { color: var(--variable) }
|
||||
/* LiteralNumber */ .chroma .m { color: var(--number); font-weight: bold }
|
||||
/* LiteralNumberBin */ .chroma .mb { color: var(--number); font-weight: bold }
|
||||
/* LiteralNumberFloat */ .chroma .mf { color: var(--number); font-weight: bold }
|
||||
/* LiteralNumberHex */ .chroma .mh { color: var(--number); font-weight: bold }
|
||||
/* LiteralNumberInteger */ .chroma .mi { color: var(--number); font-weight: bold }
|
||||
/* LiteralNumberIntegerLong */ .chroma .il { color: var(--number); font-weight: bold }
|
||||
/* LiteralNumberOct */ .chroma .mo { color: var(--number); font-weight: bold }
|
||||
/* Operator */ .chroma .o { color: var(--operator); font-weight: bold }
|
||||
/* OperatorWord */ .chroma .ow { color: var(--keyword); font-weight: bold }
|
||||
/* Punctuation */ .chroma .p { color: var(--ui-text-bold); font-weight: bold }
|
||||
/* Comment */ .chroma .c { color: var(--ui-text-muted); font-style: italic }
|
||||
/* CommentHashbang */ .chroma .ch { color: var(--ui-text-muted); font-style: italic }
|
||||
/* CommentMultiline */ .chroma .cm { color: var(--ui-text-muted); font-style: italic }
|
||||
/* CommentSingle */ .chroma .c1 { color: var(--ui-text-muted); font-style: italic }
|
||||
/* CommentSpecial */ .chroma .cs { color: var(--ui-text-muted); font-style: italic }
|
||||
/* CommentPreproc */ .chroma .cp { color: var(--ui-text-muted); font-style: italic }
|
||||
/* CommentPreprocFile */ .chroma .cpf { color: var(--ui-text-muted); font-style: italic }
|
||||
/* Generic */ .chroma .g { color: var(--ui-text-bold) }
|
||||
/* GenericDeleted */ .chroma .gd { color: var(--error) }
|
||||
/* GenericEmph */ .chroma .ge { color: var(--ui-text-bold); font-style: italic }
|
||||
/* GenericError */ .chroma .gr { color: var(--error) }
|
||||
/* GenericHeading */ .chroma .gh { color: var(--ui-text-bold); font-weight: bold }
|
||||
/* GenericInserted */ .chroma .gi { color: var(--ui-text) }
|
||||
/* GenericOutput */ .chroma .go { color: var(--ui-text-bold); font-style: italic }
|
||||
/* GenericPrompt */ .chroma .gp { color: var(--ui-text) }
|
||||
/* GenericStrong */ .chroma .gs { color: var(--ui-text-bold); font-weight: bold }
|
||||
/* GenericSubheading */ .chroma .gu { color: var(--ui-text-bold); font-weight: bold }
|
||||
/* GenericTraceback */ .chroma .gt { color: var(--error); font-weight: bold }
|
||||
/* GenericUnderline */ .chroma .gl { color: var(--ui-text-bold); text-decoration: underline }
|
||||
/* TextWhitespace */ .chroma .w { color: var(--ui-text-muted); text-decoration: underline }
|
|
@ -1,15 +1,22 @@
|
|||
@import "common/reset";
|
||||
@import "common/colors";
|
||||
@import "common/base";
|
||||
@import "common/page";
|
||||
@import "common/content";
|
||||
|
||||
@import "components/site-header";
|
||||
@import "components/single/page-header";
|
||||
@import "components/breadcrumbs";
|
||||
@import "components/table-of-contents";
|
||||
@import "features/headings";
|
||||
|
||||
#search-form,
|
||||
.header-nav,
|
||||
.docs-nav,
|
||||
.site-footer,
|
||||
.edit-link,
|
||||
.footnote-backref
|
||||
.footnote-backref,
|
||||
.heading__anchor-link,
|
||||
.section-nav
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
|
|
|
@ -1,12 +1,21 @@
|
|||
@import "common/reset";
|
||||
@import "common/colors";
|
||||
@import "common/base";
|
||||
@import "common/page";
|
||||
@import "common/content";
|
||||
|
||||
@import "components/site-header";
|
||||
@import "components/header-menu";
|
||||
@import "components/docs-menu";
|
||||
@import "components/nav-header";
|
||||
@import "components/nav-docs";
|
||||
@import "components/site-footer";
|
||||
|
||||
@import "components/single/page-header";
|
||||
@import "components/breadcrumbs";
|
||||
@import "components/table-of-contents";
|
||||
@import "components/nav-section";
|
||||
|
||||
@import "features/headings";
|
||||
@import "features/syntax-highlighting";
|
||||
@import "features/search";
|
||||
|
||||
@import "screen/layout";
|
||||
@import "screen/links";
|
||||
|
|
|
@ -1,18 +1,3 @@
|
|||
/* single layout */
|
||||
|
||||
.page {
|
||||
.page-title {margin-top: 0;}
|
||||
.lastmod {
|
||||
margin-top: 1em;
|
||||
color: var(--ui-text-muted)
|
||||
}
|
||||
.language-list {
|
||||
display: flex;
|
||||
flex-flow: wrap;
|
||||
list-style: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* [responsive] re-show the navigation menu as a sidebar */
|
||||
|
||||
@media (min-width: 60rem) {
|
||||
|
@ -24,6 +9,11 @@
|
|||
.site-header, .scroll-margin, .site-footer {
|
||||
grid-column: span 2
|
||||
}
|
||||
|
||||
.site-footer { /* fixed height footer */
|
||||
height: var(--footer-height);
|
||||
}
|
||||
|
||||
.docs-nav {
|
||||
grid-column: 1;
|
||||
height: calc(100 * var(--vh, 1vh) - var(--header-height) - var(--footer-height));
|
||||
|
@ -102,7 +92,8 @@
|
|||
|
||||
/* start limiting content since it can exceed 80ch now */
|
||||
|
||||
.page .content .container {
|
||||
.content .container
|
||||
{
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) minmax(auto, 80ch) minmax(0, 1fr);
|
||||
> * {
|
||||
|
@ -114,9 +105,20 @@
|
|||
}
|
||||
}
|
||||
|
||||
.section-nav,
|
||||
.page-footer .container
|
||||
{
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) minmax(auto, 80ch) minmax(0, 1fr);
|
||||
> .container {
|
||||
padding: 0;
|
||||
grid-column: 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* also make the page header line up */
|
||||
|
||||
.page .page-header {
|
||||
.page-header {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) minmax(auto, 80ch) minmax(0, 1fr);
|
||||
> .container {
|
||||
|
|
|
@ -26,4 +26,21 @@ a:hover {
|
|||
|
||||
@media (prefers-reduced-motion) {
|
||||
a:link {transition: none}
|
||||
}
|
||||
}
|
||||
|
||||
/* mark external links */
|
||||
|
||||
a[href^="http"]:after {
|
||||
content: "🡕";
|
||||
}
|
||||
|
||||
a[href^="{{.Site.BaseURL}}"]:after
|
||||
{
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
a[href^="http://localhost"]:after
|
||||
{
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
|
|
6
layouts/_default/_markup/render-heading.html
Normal file
6
layouts/_default/_markup/render-heading.html
Normal file
|
@ -0,0 +1,6 @@
|
|||
<h{{.Level}} class="heading" id="{{.Anchor | safeURL}}">
|
||||
<span class="heading__text">{{.Text | safeHTML}}</span>
|
||||
<a class="heading__anchor-link" href="#{{.Anchor | safeURL}}">
|
||||
[link]
|
||||
</a>
|
||||
</h{{.Level}}>
|
|
@ -1,29 +1,30 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="{{.Site.Language.Lang }}" xml:lang="{{.Site.Language.Lang }}">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
{{ $screen := resources.Get "styles/screen.scss" | toCSS | minify | fingerprint }}
|
||||
<link rel="stylesheet"
|
||||
href="{{ $screen.Permalink }}"
|
||||
integrity="{{ $screen.Data.Integrity }}"
|
||||
media="screen" />
|
||||
{{ $print := resources.Get "styles/print.scss" | toCSS | minify | fingerprint }}
|
||||
<link rel="stylesheet"
|
||||
href="{{ $print.Permalink }}"
|
||||
integrity="{{ $print.Data.Integrity }}"
|
||||
media="print" />
|
||||
{{ $script := resources.Get "scripts/main.js" | js.Build "script.js" | minify | fingerprint }}
|
||||
<script type="text/javascript"
|
||||
src="{{ $script.Permalink }}"
|
||||
integrity="{{ $script.Data.Integrity }}">
|
||||
</script>
|
||||
{{ partial "seo.html" . }}
|
||||
{{ block "head" . }}
|
||||
{{ end }}
|
||||
</head>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
{{ $screen := resources.Get "styles/screen.scss" | toCSS | minify | fingerprint }}
|
||||
<link rel="stylesheet"
|
||||
href="{{ $screen.Permalink }}"
|
||||
integrity="{{ $screen.Data.Integrity }}"
|
||||
media="screen" />
|
||||
{{ $print := resources.Get "styles/print.scss" | toCSS | minify | fingerprint }}
|
||||
<link rel="stylesheet"
|
||||
href="{{ $print.Permalink }}"
|
||||
integrity="{{ $print.Data.Integrity }}"
|
||||
media="print" />
|
||||
{{ $script := resources.Get "scripts/main.js" | js.Build "script.js" | minify | fingerprint }}
|
||||
<script type="text/javascript"
|
||||
src="{{ $script.Permalink }}"
|
||||
integrity="{{ $script.Data.Integrity }}">
|
||||
</script>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/fork-awesome@1.2.0/css/fork-awesome.min.css" integrity="sha256-XoaMnoYC5TH6/+ihMEnospgm0J1PM/nioxbOUdnM8HY=" crossorigin="anonymous">
|
||||
{{ partial "seo.html" . }}
|
||||
{{ block "head" . }}
|
||||
{{ end }}
|
||||
</head>
|
||||
<body>
|
||||
{{ partial "site-header.html" . }}
|
||||
{{ block "main" . }}
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
{{ define "main" }}
|
||||
<main>
|
||||
<article class="page">
|
||||
<article class="page" {{- if .Param "autonumbering" }} autonumbering {{- end }}>
|
||||
<header class="section page-header">
|
||||
<div class="container">
|
||||
{{ partial "breadcrumbs.html" . }}
|
||||
<h1 class="page-title">{{ .Title }}</h1>
|
||||
<p class="page-summary">{{.Page.Summary}}</p>
|
||||
<p class="page-summary">{{.Page.Summary | plainify}}</p>
|
||||
|
||||
<p class="lastmod">Last modified <datetime class="date">{{ .Lastmod.Format "Mon Jan 2, 2006" }}</datetime><span class="edit-link"> - <a href='{{if eq .Site.Params.forge "github"}}{{printf "https://github.com/%s/edit/%s/%s/%s" .Site.Params.repo .Site.Params.branch .Site.Language.ContentDir .File.Path}}{{else if eq .Site.Params.forge "gitea"}}{{printf "%s/%s/_edit/%s/%s/%s" .Site.Params.forgeUrl .Site.Params.repo .Site.Params.branch (cond (isset .Site.Language "ContentDir") .Site.Language.ContentDir "content") .File.Path}}{{else}}#{{end}}'>Edit this page</a></span></p>
|
||||
<p class="lastmod">Last modified <datetime class="date">{{ .Lastmod.Format "Mon Jan 2, 2006" }}</datetime><span class="edit-link"><br><a href='{{if eq .Site.Params.forge "github"}}{{printf "https://github.com/%s/edit/%s/%s/%s" .Site.Params.repo .Site.Params.branch .Site.Language.ContentDir .File.Path}}{{else if eq .Site.Params.forge "gitea"}}{{printf "%s/%s/_edit/%s/%s/%s" .Site.Params.forgeUrl .Site.Params.repo .Site.Params.branch (cond (isset .Site.Language "ContentDir") .Site.Language.ContentDir "content") .File.Path}}{{else}}#{{end}}'>Edit this page</a></span></p>
|
||||
|
||||
{{ partial "i18nlist.html" . }}
|
||||
</div>
|
||||
</header>
|
||||
|
@ -21,6 +23,12 @@
|
|||
{{ .Content }}
|
||||
</div>
|
||||
</section>
|
||||
{{ partial "nav-section.html" . }}
|
||||
<footer class="section page-footer">
|
||||
<div class="container">
|
||||
{{ partial "page-footer.html" . }}
|
||||
</div>
|
||||
</footer>
|
||||
</article>
|
||||
</main>
|
||||
{{ end }}
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<section class="content section">
|
||||
<div class="container">
|
||||
{{ .Content }}
|
||||
<p class="lastmod">Last modified <datetime class="date"><span class="edit-link">{{ .Lastmod.Format "Mon Jan 2, 2006" }}</datetime> - <a href='{{if eq .Site.Params.forge "github"}}{{printf "https://github.com/%s/edit/%s/%s/%s" .Site.Params.repo .Site.Params.branch .Site.Language.ContentDir .File.Path}}{{else if eq .Site.Params.forge "gitea"}}{{printf "%s/%s/_edit/%s/%s/%s" .Site.Params.forgeUrl .Site.Params.repo .Site.Params.branch (cond (isset .Site.Language "ContentDir") .Site.Language.ContentDir "content") .File.Path}}{{else}}#{{end}}'>Edit this page</a></span></p>
|
||||
<p class="lastmod">Last modified <datetime class="date">{{ .Lastmod.Format "Mon Jan 2, 2006" }}</datetime><span class="edit-link"><br><a href='{{if eq .Site.Params.forge "github"}}{{printf "https://github.com/%s/edit/%s/%s/%s" .Site.Params.repo .Site.Params.branch .Site.Language.ContentDir .File.Path}}{{else if eq .Site.Params.forge "gitea"}}{{printf "%s/%s/_edit/%s/%s/%s" .Site.Params.forgeUrl .Site.Params.repo .Site.Params.branch (cond (isset .Site.Language "ContentDir") .Site.Language.ContentDir "content") .File.Path}}{{else}}#{{end}}'>Edit this page</a></span></p>
|
||||
</div>
|
||||
</section>
|
||||
</article>
|
||||
|
|
8
layouts/index.json
Normal file
8
layouts/index.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{{- $.Scratch.Add "pagesIndex" slice -}}
|
||||
{{- range $index, $page := .Site.RegularPages -}}
|
||||
{{- if gt (len $page.Content) 0 -}}
|
||||
{{- $pageData := (dict "title" $page.Title "href" $page.Permalink "content" $page.Plain) -}}
|
||||
{{- $.Scratch.Add "pagesIndex" $pageData -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- $.Scratch.Get "pagesIndex" | jsonify -}}
|
|
@ -12,7 +12,7 @@
|
|||
{{ if .HasChildren}}
|
||||
<li
|
||||
class='section-title{{ if or ($currentPage.IsMenuCurrent "docs" .) (eq $currentPage.Section .Identifier) }} active{{ end }}'>
|
||||
<a href="{{ .URL | absLangURL }}">
|
||||
<a href="{{ .URL | relLangURL }}">
|
||||
{{ .Pre }}
|
||||
<span>{{ .Name }}</span>
|
||||
{{ .Post }}
|
||||
|
@ -22,7 +22,7 @@
|
|||
{{ if .HasChildren}}
|
||||
<li
|
||||
class='{{ if or ($currentPage.IsMenuCurrent "docs" .) (eq $currentPage.Section .Identifier) }} active{{ end }}'>
|
||||
<a href="{{ .URL | absLangURL }}">
|
||||
<a href="{{ .URL | relLangURL }}">
|
||||
{{ .Pre }}
|
||||
<span>{{ .Name }}</span>
|
||||
{{ .Post }}
|
||||
|
@ -31,7 +31,7 @@
|
|||
{{ range .Children }}
|
||||
<li
|
||||
class='{{ if or ($currentPage.IsMenuCurrent "docs" .) (eq $currentPage.Section .Identifier) }}active{{ end }}'>
|
||||
<a href="{{ .URL | absLangURL }}">
|
||||
<a href="{{ .URL | relLangURL }}">
|
||||
{{ .Pre }}
|
||||
<span>{{ .Name }}</span>
|
||||
{{ .Post }}
|
||||
|
@ -43,7 +43,7 @@
|
|||
{{ else }}
|
||||
<li
|
||||
class='{{ if or ($currentPage.IsMenuCurrent "docs" .) (eq $currentPage.Section .Identifier) }}active{{ end }}'>
|
||||
<a href="{{ .URL | absLangURL }}">
|
||||
<a href="{{ .URL | relLangURL }}">
|
||||
{{ .Pre }}
|
||||
<span>{{ .Name }}</span>
|
||||
{{ .Post }}
|
||||
|
@ -56,7 +56,7 @@
|
|||
{{ else }}
|
||||
<li
|
||||
class='{{ if or ($currentPage.IsMenuCurrent "docs" .) (eq $currentPage.Section .Identifier) }}active{{ end }}'>
|
||||
<a href="{{ .URL | absLangURL }}">
|
||||
<a href="{{ .URL | relLangURL }}">
|
||||
{{ .Pre }}
|
||||
<span>{{ .Name }}</span>
|
||||
{{ .Post }}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
{{ range .Site.Menus.footer }}
|
||||
<li
|
||||
class='{{ if or ($currentPage.IsMenuCurrent "footer" .) (eq $currentPage.Section .Identifier) }}active{{ end }}'>
|
||||
<a href="{{ .URL | absLangURL }}">
|
||||
<a href="{{ .URL | relLangURL }}">
|
||||
{{ .Pre }}
|
||||
<span>{{ .Name }}</span>
|
||||
{{ .Post }}
|
||||
|
|
|
@ -1,19 +1,15 @@
|
|||
<nav class="header-nav">
|
||||
<div class="container">
|
||||
|
||||
<ul class="menu">
|
||||
{{ $currentPage := . }}
|
||||
{{ range .Site.Menus.main }}
|
||||
<li
|
||||
class='{{ if or ($currentPage.IsMenuCurrent "main" .) (eq $currentPage.Section .Identifier) }}active{{ end }}'>
|
||||
<a href="{{ .URL | absLangURL }}">
|
||||
{{ .Pre }}
|
||||
<span>{{ .Name }}</span>
|
||||
{{ .Post }}
|
||||
</a>
|
||||
</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
<ul class="menu">
|
||||
{{ $currentPage := . }}
|
||||
{{ range .Site.Menus.main }}
|
||||
<li
|
||||
class='{{ if or ($currentPage.IsMenuCurrent "main" .) (eq $currentPage.Section .Identifier) }}active{{ end }}'>
|
||||
<a href="{{ .URL | relLangURL }}">
|
||||
{{ .Pre }}
|
||||
<span>{{ .Name }}</span>
|
||||
{{ .Post }}
|
||||
</a>
|
||||
</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
</nav>
|
10
layouts/partials/nav-section.html
Normal file
10
layouts/partials/nav-section.html
Normal file
|
@ -0,0 +1,10 @@
|
|||
<nav class="section-nav">
|
||||
<div class="container">
|
||||
{{ with .PrevInSection }}
|
||||
<a class="previous" href="{{.Permalink}}"><span class="arrow">←</span><span class="text">Previous page:<br/>{{.Title}}</span></a>
|
||||
{{ end }}
|
||||
{{ with .NextInSection }}
|
||||
<a class="next" href="{{.Permalink}}"><span class="text">Next page:<br/>{{.Title}}</span><span class="arrow">→</span></a>
|
||||
{{ end }}
|
||||
</div>
|
||||
</nav>
|
4
layouts/partials/page-footer.html
Normal file
4
layouts/partials/page-footer.html
Normal file
|
@ -0,0 +1,4 @@
|
|||
{{/*
|
||||
Override this partial if you want stuff
|
||||
to show up at the bottom of each page
|
||||
*/}}
|
5
layouts/partials/search/search-form.html
Normal file
5
layouts/partials/search/search-form.html
Normal file
|
@ -0,0 +1,5 @@
|
|||
<form id="search-form" action='{{ with .GetPage "/search" }}{{.Permalink}}{{end}}' method="get">
|
||||
<label hidden for="search-input">Search site</label>
|
||||
<input id="search-input" type="text" name="query" placeholder="Type here to search">
|
||||
<input id="search-submit" type="submit" value="search">
|
||||
</form>
|
3
layouts/partials/search/search-index.html
Normal file
3
layouts/partials/search/search-index.html
Normal file
|
@ -0,0 +1,3 @@
|
|||
<script src="https://unpkg.com/lunr/lunr.js"></script>
|
||||
{{ $js := resources.Get "scripts/search.js" | minify | fingerprint }}
|
||||
<script type="text/javascript" src="{{ $js.Permalink }}" integrity="{{ $js.Data.Integrity }}"></script>
|
|
@ -1,10 +1,6 @@
|
|||
{{ $icon := "images/icon.png" | absURL }}
|
||||
<link rel="shortcut icon" href='{{ $icon }}' sizes="765x765">
|
||||
{{ if .IsPage }}
|
||||
{{ with .Params.tags }}
|
||||
<meta name="keywords" content='{{ delimit . " "}}'>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ if .IsPage }}{{ with .Params.tags }}<meta name="keywords" content='{{ delimit . " "}}'>{{ end }}{{ end }}
|
||||
{{ if .IsHome }}<title>{{ .Site.Title }}</title>
|
||||
<title itemprop="name">{{ .Site.Title }}</title>
|
||||
<meta property="og:title" content="{{ .Site.Title }}" />
|
||||
|
|
|
@ -5,4 +5,5 @@
|
|||
<a href="#top">back to top</a>
|
||||
</div>
|
||||
</footer>
|
||||
{{ partial "search/search-index.html" . }}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
<img class="site-icon" height="32" src="{{.Site.Params.icon}}">
|
||||
<p class="site-title">{{.Site.Params.title}}</p>
|
||||
</a>
|
||||
{{ partial "search/search-form.html" . }}
|
||||
{{ partial "nav-header.html" . }}
|
||||
</div>
|
||||
</header>
|
||||
|
|
21
layouts/search/list.html
Normal file
21
layouts/search/list.html
Normal file
|
@ -0,0 +1,21 @@
|
|||
{{ define "main" }}
|
||||
<main>
|
||||
<div class="search-results section">
|
||||
<header>
|
||||
<div class="container">
|
||||
<h2 class="search-results__title"><span id="results-count"></span> <span id="results-count-text"></span> for "<span id="results-query"></span>"</h2>
|
||||
</div>
|
||||
</header>
|
||||
<section>
|
||||
<div class="container">
|
||||
<ul id="search-results">
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</main>
|
||||
<style>
|
||||
a[href="#top"] {display: none;}
|
||||
</style>
|
||||
{{ end }}
|
Loading…
Reference in a new issue