refactor: replace gulp by webpack and npm scripts (#258)

BREAKING CHANGE: We have replaced `gulp` with `webpack` and `npm scripts` to build this theme. If you build it on your own or use build commands during the deployment, you may have to adjust your setup.

BREAKING CHANGE: The `GeekblogIcons` font is using the icon name as Unicode now. As a consequence, you have to replace all references to Icons from this font if you have customized the theme.

BREAKING CHANGE: We have refactored the search integration to split Hugo templates from JavaScript code. To get it working again, you need to adjust the `outputFormats` and `outputs` in your Hugo configuration file, as [documented](https://geekdocs.de/usage/configuration/#site-configuration).
This commit is contained in:
Robert Kaussow 2022-01-06 13:58:10 +01:00 committed by GitHub
parent 2ac2a9faab
commit 5c5e2d59cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
122 changed files with 18705 additions and 5208 deletions

View File

@ -7,11 +7,20 @@ platform:
arch: amd64 arch: amd64
steps: steps:
- name: eslint
image: node:lts
commands:
- npm install > /dev/null
- npm run lint
environment:
FORCE_COLOR: true
NPM_CONFIG_LOGLEVEL: error
- name: assets - name: assets
image: node:lts image: node:lts
commands: commands:
- npm install > /dev/null - npm install > /dev/null
- npx gulp default - npm run build
environment: environment:
FORCE_COLOR: true FORCE_COLOR: true
NPM_CONFIG_LOGLEVEL: error NPM_CONFIG_LOGLEVEL: error
@ -94,7 +103,7 @@ steps:
image: node:lts image: node:lts
commands: commands:
- npm install > /dev/null - npm install > /dev/null
- npx gulp default - npm run build
environment: environment:
FORCE_COLOR: true FORCE_COLOR: true
NPM_CONFIG_LOGLEVEL: error NPM_CONFIG_LOGLEVEL: error
@ -172,7 +181,7 @@ steps:
image: node:lts image: node:lts
commands: commands:
- npm install > /dev/null - npm install > /dev/null
- npx gulp svg-sprite-list - npm run svg-sprite-list
- mkdir -p exampleSite/themes/hugo-geekdoc/ - mkdir -p exampleSite/themes/hugo-geekdoc/
- curl -sSL https://github.com/thegeeklab/hugo-geekdoc/releases/latest/download/hugo-geekdoc.tar.gz | tar -xz -C exampleSite/themes/hugo-geekdoc/ --strip-components=1 - curl -sSL https://github.com/thegeeklab/hugo-geekdoc/releases/latest/download/hugo-geekdoc.tar.gz | tar -xz -C exampleSite/themes/hugo-geekdoc/ --strip-components=1
when: when:
@ -184,8 +193,8 @@ steps:
image: node:lts image: node:lts
commands: commands:
- npm install > /dev/null - npm install > /dev/null
- npx gulp default - npm run build
- npx gulp svg-sprite-list - npm run svg-sprite-list
- mkdir exampleSite/themes/ && ln -s $(pwd)/ exampleSite/themes/hugo-geekdoc - mkdir exampleSite/themes/ && ln -s $(pwd)/ exampleSite/themes/hugo-geekdoc
environment: environment:
FORCE_COLOR: true FORCE_COLOR: true
@ -276,6 +285,6 @@ depends_on:
--- ---
kind: signature kind: signature
hmac: a61d16aa7a47108fbef3836588111f16f52d280497cfe0aab14bcd726728b297 hmac: e715545ce951b15ce1ab5f7d7f107e2ab37aa08e94a681f27646a543d1e6ac3c
... ...

22
.eslintrc.json Normal file
View File

@ -0,0 +1,22 @@
{
"env": {
"browser": true,
"es6": true,
"amd": true
},
"extends": ["plugin:prettier/recommended"],
"parser": "@babel/eslint-parser",
"parserOptions": {
"sourceType": "module",
"requireConfigFile": false,
"allowImportExportEverywhere": true
},
"plugins": ["prettier"],
"rules": {
"require-await": "warn"
},
"globals": {
"require": false,
"requirejs": false
}
}

29
.gitignore vendored
View File

@ -1,26 +1,21 @@
# local environments # local environments
.swp .swp
.env* .env*
dist/ /dist/
build/ /build/
node_modules/ /node_modules/
lhci_reports/ /lhci_reports/
exampleSite/themes/ /exampleSite/themes/
exampleSite/public/ /exampleSite/public/
CHANGELOG.md CHANGELOG.md
# auto-generated files # auto-generated files
assets/sprites/ /data/
static/*.min.css /static/
static/*.min.css.map /assets/sprites/
static/js/ /resources/
static/favicon/ /exampleSite/resources/
static/fonts/GeekdocIcons.* /exampleSite/data/sprites/
static/fonts/KaTeX_*
resources/
exampleSite/resources/
exampleSite/data/sprites/
data/assets.json
# testing # testing
.lighthouseci/ .lighthouseci/

View File

@ -2,6 +2,7 @@
ci: ci:
collect: collect:
numberOfRuns: 3 numberOfRuns: 3
psiStrategy: desktop
staticDistDir: exampleSite/public staticDistDir: exampleSite/public
url: url:
- http://localhost/ - http://localhost/

View File

@ -1,9 +1,8 @@
*.html
.drone.yml .drone.yml
search*.js
_normalize.css _normalize.css
.lighthouseci/ list.json.json
themes/ /.lighthouseci/
static/js/ /themes/
src/favicon/ /static/js/
/src/favicon/
LICENSE LICENSE

View File

@ -1,4 +1,8 @@
{ {
"printWidth": 99,
"singleQuote": false,
"semi": false,
"trailingComma": "none",
"overrides": [ "overrides": [
{ {
"files": ["*.html"], "files": ["*.html"],

View File

@ -8,10 +8,11 @@
.markdownlint* .markdownlint*
.jsbeautify* .jsbeautify*
.prettier* .prettier*
.vnu* .eslintrc*
.chglog .chglog
example* example*
gulp* webpack*
svgsprite*
package* package*
node* node*
local* local*

View File

@ -1,171 +0,0 @@
'use strict';
{{ $searchDataFile := printf "%s.search-data.json" .Language.Lang }}
{{ $searchData := resources.Get "search-data.json" | resources.ExecuteAsTemplate $searchDataFile . | resources.Minify }}
(function() {
const input = document.querySelector('#gdoc-search-input');
const results = document.querySelector('#gdoc-search-results');
let showParent = {{ if .Site.Params.GeekdocSearchShowParent }}true{{ else }}false{{ end }}
if (input) {
input.addEventListener('focus', init);
input.addEventListener('keyup', search);
}
function init() {
input.removeEventListener('focus', init); // init once
loadScript('{{ index .Site.Data.assets "js/groupBy.min.js" | relURL }}');
loadScript('{{ index .Site.Data.assets "js/flexsearch.min.js" | relURL }}', function() {
const indexCfgDefaults = {
tokenize: 'forward'
}
const indexCfg = {{ with .Scratch.Get "geekdocSearchConfig" }}{{ . | jsonify }}{{ else }}indexCfgDefaults{{ end }};
const dataUrl = '{{ $searchData.RelPermalink }}'
indexCfg.document = {
key: 'id',
index: ['title', 'content'],
store: ['title', 'href', 'parent'],
};
const index = new FlexSearch.Document(indexCfg);
window.geekdocSearchIndex = index;
getJson(dataUrl, function(data) {
data.forEach(obj => {
window.geekdocSearchIndex.add(obj);
});
});
});
}
function search() {
const searchCfg = {
enrich: true,
limit: 10
};
while (results.firstChild) {
results.removeChild(results.firstChild);
}
if (!input.value) {
return results.classList.remove('has-hits');
}
let searchHits = flattenHits(window.geekdocSearchIndex.search(input.value, searchCfg));
if (searchHits.length < 1) {
return results.classList.remove('has-hits');
}
results.classList.add('has-hits');
if (showParent === true) {
searchHits = groupBy(searchHits, hit => hit.parent);
}
const items = [];
if (showParent === true) {
for (const section in searchHits) {
const item = document.createElement('li'),
title = item.appendChild(document.createElement('span')),
subList = item.appendChild(document.createElement('ul'));
title.textContent = section;
createLinks(searchHits[section], subList);
items.push(item);
}
} else {
const item = document.createElement('li'),
title = item.appendChild(document.createElement('span')),
subList = item.appendChild(document.createElement('ul'));
title.textContent = 'Results';
createLinks(searchHits, subList);
items.push(item);
}
items.forEach(item => {
results.appendChild(item);
})
}
/**
* Creates links to given fields and either returns them in an array or attaches them to a target element
* @param {Object} fields Page to which the link should point to
* @param {HTMLElement} target Element to which the links should be attatched
* @returns {Array} If target is not specified, returns an array of built links
*/
function createLinks(pages, target) {
const items = [];
for (const page of pages) {
const item = document.createElement("li"),
entry = item.appendChild(document.createElement("span")),
a = entry.appendChild(document.createElement("a"));
entry.classList.add('flex')
a.href = page.href;
a.textContent = page.title;
a.classList.add('gdoc-search__entry')
if (target) {
target.appendChild(item);
continue
}
items.push(item);
}
return items;
}
function fetchErrors(response) {
if (!response.ok) {
throw Error(response.statusText);
}
return response;
}
function getJson(src, callback) {
fetch(src)
.then(fetchErrors)
.then(response => response.json())
.then(json => callback(json))
.catch(function(error) {
console.log(error);
});
}
function flattenHits(results) {
const items = [];
const map = new Map();
for (const field of results) {
for (const page of field.result) {
if(!map.has(page.doc.href)){
map.set(page.doc.href, true);
items.push(page.doc);
}
}
}
return items
}
function loadScript(src, callback) {
let script = document.createElement('script');
script.defer = true;
script.async = false;
script.src = src;
script.onload = callback;
document.body.appendChild(script);
}
})();

View File

@ -1,3 +0,0 @@
{
"custom.css": "custom.css"
}

View File

@ -23,9 +23,22 @@ markup:
taxonomies: taxonomies:
tag: tags tag: tags
outputFormats:
Search:
name: "Search"
mediaType: "application/json"
# generated file: <baseName>.<mediaType."application/feed+json".suffixes[0]> = feed.json
baseName: "searchconfig"
isPlainText: false
rel: "alternate"
isHTML: false
noUgly: true
permalinkable: false
outputs: outputs:
home: home:
- HTML - HTML
- SEARCH
page: page:
- HTML - HTML
section: section:

View File

@ -4,10 +4,12 @@ title: Buttons
Buttons are styled links that can lead to local page or external link. Buttons are styled links that can lead to local page or external link.
<!-- prettier-ignore-start -->
```tpl ```tpl
{{</* button relref="/" [class="...", size="large|regular"] */>}}Get Home{{</* /button */>}} {{</* button relref="/" [class="...", size="large|regular"] */>}}Get Home{{</* /button */>}}
{{</* button href="https://github.com/thegeeklab/hugo-geekdoc" */>}}Contribute{{</* /button */>}} {{</* button href="https://github.com/thegeeklab/hugo-geekdoc" */>}}Contribute{{</* /button */>}}
``` ```
<!-- prettier-ignore-end -->
## Example ## Example

View File

@ -8,12 +8,14 @@ Expand shortcode can help to decrease clutter on screen by hiding part of text.
### Default ### Default
<!-- prettier-ignore-start -->
```tpl ```tpl
{{</* expand */>}} {{</* expand */>}}
## Markdown content ## Markdown content
Dolor sit, sumo unique ... Dolor sit, sumo unique ...
{{</* /expand */>}} {{</* /expand */>}}
``` ```
<!-- prettier-ignore-end -->
{{< expand >}} {{< expand >}}
@ -24,12 +26,14 @@ Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclima
### With Custom Label ### With Custom Label
<!-- prettier-ignore-start -->
```tpl ```tpl
{{</* expand "Custom Label" "..." */>}} {{</* expand "Custom Label" "..." */>}}
## Markdown content ## Markdown content
Dolor sit, sumo unique ... Dolor sit, sumo unique ...
{{</* /expand */>}} {{</* /expand */>}}
``` ```
<!-- prettier-ignore-end -->
{{< expand "Custom Label" "..." >}} {{< expand "Custom Label" "..." >}}

View File

@ -5,6 +5,7 @@ title: Hints
Hint shortcode can be used as hint/alerts/notification block. Hint shortcode can be used as hint/alerts/notification block.
There are four colors to choose: `info`, `ok`, `warning` and `danger`. There are four colors to choose: `info`, `ok`, `warning` and `danger`.
<!-- prettier-ignore-start -->
```tpl ```tpl
{{</* hint [info|warning|danger] */>}} {{</* hint [info|warning|danger] */>}}
**Markdown content**\ **Markdown content**\
@ -12,6 +13,7 @@ Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclima
Ornateness bland it ex enc, est yeti am bongo detract re. Ornateness bland it ex enc, est yeti am bongo detract re.
{{</* /hint */>}} {{</* /hint */>}}
``` ```
<!-- prettier-ignore-end -->
## Example ## Example

View File

@ -4,9 +4,11 @@ title: Icons
Simple shortcode to include icons from SVG sprites outside of menus. Simple shortcode to include icons from SVG sprites outside of menus.
<!-- prettier-ignore-start -->
```tpl ```tpl
{{</* icon "thumbs-up" */>}} {{</* icon "thumbs-up" */>}}
``` ```
<!-- prettier-ignore-end -->
**Example:** **Example:**

View File

@ -6,9 +6,11 @@ title: Includes
Include shortcode can include files of different types. By specifying a language, the included file will have syntax highlighting. Include shortcode can include files of different types. By specifying a language, the included file will have syntax highlighting.
<!-- prettier-ignore-start -->
```tpl ```tpl
{{</* include file="relative/path/from/hugo/root" language="go" markdown=[false|true] */>}} {{</* include file="relative/path/from/hugo/root" language="go" markdown=[false|true] */>}}
``` ```
<!-- prettier-ignore-end -->
Attributes: Attributes:
@ -30,9 +32,11 @@ If no other options are specified, files will be rendered as Markdown using the
If you include markdown files that should not get a menu entry, place them outside the content folder or exclude them otherwise. If you include markdown files that should not get a menu entry, place them outside the content folder or exclude them otherwise.
{{< /hint >}} {{< /hint >}}
<!-- prettier-ignore-start -->
```tpl ```tpl
{{</* include file="/static/_includes/example.md.part" */>}} {{</* include file="/static/_includes/example.md.part" */>}}
``` ```
<!-- prettier-ignore-end -->
<!-- prettier-ignore-start --> <!-- prettier-ignore-start -->
<!-- spellchecker-disable --> <!-- spellchecker-disable -->
@ -44,9 +48,13 @@ If you include markdown files that should not get a menu entry, place them outsi
This method can be used to include source code files and keep them automatically up to date. This method can be used to include source code files and keep them automatically up to date.
<!-- prettier-ignore-start -->
```tpl ```tpl
{{</* include file="config.yaml" language="yaml" options="linenos=table,hl_lines=5-6,linenostart=100" */>}} {{</* include file="config.yaml" language="yaml" options="linenos=table,hl_lines=5-6,linenostart=100" */>}}
``` ```
<!-- prettier-ignore-end -->
Result:
<!-- prettier-ignore-start --> <!-- prettier-ignore-start -->
<!-- spellchecker-disable --> <!-- spellchecker-disable -->
@ -60,9 +68,11 @@ This method can be used to include source code files and keep them automatically
HTML content will be filtered by the `safeHTML` filter and added to the rendered page output. HTML content will be filtered by the `safeHTML` filter and added to the rendered page output.
<!-- prettier-ignore-start -->
```tpl ```tpl
{{</* include file="/static/_includes/example.html.part" */>}} {{</* include file="/static/_includes/example.html.part" */>}}
``` ```
<!-- prettier-ignore-end -->
{{< include file="/static/_includes/example.html.part" type="html" >}} {{< include file="/static/_includes/example.html.part" type="html" >}}

View File

@ -4,6 +4,7 @@ title: Tabs
Tabs let you organize content by context, for example installation instructions for each supported platform. Tabs let you organize content by context, for example installation instructions for each supported platform.
<!-- prettier-ignore-start -->
```tpl ```tpl
{{</* tabs "uniqueid" */>}} {{</* tabs "uniqueid" */>}}
{{</* tab "macOS" */>}} # macOS Content {{</* /tab */>}} {{</* tab "macOS" */>}} # macOS Content {{</* /tab */>}}
@ -11,6 +12,7 @@ Tabs let you organize content by context, for example installation instructions
{{</* tab "Windows" */>}} # Windows Content {{</* /tab */>}} {{</* tab "Windows" */>}} # Windows Content {{</* /tab */>}}
{{</* /tabs */>}} {{</* /tabs */>}}
``` ```
<!-- prettier-ignore-end -->
## Example ## Example

View File

@ -4,9 +4,11 @@ title: ToC-Tree
The `toc-tree` shortcode will generate a Table of Content from a section file tree of your content directory. The root of the resulting ToC will be the page on which you define the shortcode. The `toc-tree` shortcode will generate a Table of Content from a section file tree of your content directory. The root of the resulting ToC will be the page on which you define the shortcode.
<!-- prettier-ignore-start -->
```tpl ```tpl
{{</* toc-tree */>}} {{</* toc-tree */>}}
``` ```
<!-- prettier-ignore-end -->
## Example ## Example

View File

@ -4,9 +4,11 @@ title: ToC
Simple wrapper to generate a page Table of Content from a shortcode. Simple wrapper to generate a page Table of Content from a shortcode.
<!-- prettier-ignore-start -->
```tpl ```tpl
{{</* toc */>}} {{</* toc */>}}
``` ```
<!-- prettier-ignore-end -->
{{< toc >}} {{< toc >}}

View File

@ -32,6 +32,19 @@ enableRobotsTXT = true
startLevel = 1 startLevel = 1
endLevel = 9 endLevel = 9
[outputFormats.Search]
name = "Search"
mediaType = "application/json"
baseName = "searchconfig"
isPlainText = false
rel = "alternate"
isHTML = false
noUgly = true
permalinkable = false
[outputs]
home = [ "HTML", "SEARCH" ]
[taxonomies] [taxonomies]
tag = "tags" tag = "tags"
@ -70,7 +83,8 @@ enableRobotsTXT = true
# You can also specify this parameter per page in front matter. # You can also specify this parameter per page in front matter.
geekdocEditPath = "edit/main/exampleSite/content" geekdocEditPath = "edit/main/exampleSite/content"
# (Optional, default true) Enables search function with flexsearch. # (Optional, default true) Enables search function with flexsearch. To use the search you
# have to ensure `outputFormats` and `outputs` are properly configured as well (see below).
# Index is built on the fly and might slow down your website. # Index is built on the fly and might slow down your website.
geekdocSearch = false geekdocSearch = false
@ -148,6 +162,23 @@ markup:
taxonomies: taxonomies:
tag: tags tag: tags
outputFormats:
Search:
name: "Search"
mediaType: "application/json"
# generated file: <baseName>.<mediaType."application/feed+json".suffixes[0]> = feed.json
baseName: "searchconfig"
isPlainText: false
rel: "alternate"
isHTML: false
noUgly: true
permalinkable: false
outputs:
home:
- HTML
- SEARCH
params: params:
# (Optional, default 6) Set how many table of contents levels to be showed on page. # (Optional, default 6) Set how many table of contents levels to be showed on page.
# Use false to hide ToC, note that 0 will default to 6 (https://gohugo.io/functions/default/) # Use false to hide ToC, note that 0 will default to 6 (https://gohugo.io/functions/default/)
@ -183,8 +214,9 @@ params:
# You can also specify this parameter per page in front matter. # You can also specify this parameter per page in front matter.
geekdocEditPath: edit/main/exampleSite/content geekdocEditPath: edit/main/exampleSite/content
# (Optional, default true) Enables search function with flexsearch. # (Optional, default true) Enables search function with flexsearch. To use the search you
# Index is built on the fly and might slowdown your website. # have to ensure `outputFormats` and `outputs` are properly configured as well (see below).
# Index is built on the fly and might slow down your website.
geekdocSearch: false geekdocSearch: false
# (Optional, default false) Display search results with the parent folder as prefix. This # (Optional, default false) Display search results with the parent folder as prefix. This

View File

@ -69,6 +69,19 @@ To prepare your new site environment just a few steps are required:
[taxonomies] [taxonomies]
tag = "tags" tag = "tags"
[outputFormats.Search]
name = "Search"
mediaType = "application/json"
baseName = "searchconfig"
isPlainText = false
rel = "alternate"
isHTML = false
noUgly = true
permalinkable = false
[outputs]
home = [ "HTML", "SEARCH" ]
``` ```
5. Test your site. 5. Test your site.

View File

@ -1,11 +1,11 @@
<div class="flex flex-wrap justify-center"> <div class="flex flex-wrap justify-center">
{{ range .Site.Data.sprites.geekdoc }} {{ range $key, $value := .Site.Data.sprites.geekdoc }}
<div class="flex flex-grid icon-grid"> <div class="flex flex-grid icon-grid">
<div class="flex align-center justify-center icon-grid__line"> <div class="flex align-center justify-center icon-grid__line">
<svg class="icon gdoc_{{ . }}"><use xlink:href="#gdoc_{{ . }}"></use></svg> <svg class="icon {{ $key }}"><use xlink:href="#{{ $key }}"></use></svg>
</div> </div>
<div class="flex align-center justify-center icon-grid__line icon-grid__line--text"> <div class="flex align-center justify-center icon-grid__line icon-grid__line--text">
<span>#gdoc_{{ (replace . "_" "_<wbr>") | safeHTML }}</span> <span>#{{ (replace $key "_" "_<wbr>") | safeHTML }}</span>
</div> </div>
</div> </div>
{{ end }} {{ end }}

View File

@ -1,344 +0,0 @@
const devBuild = !(
(process.env.NODE_ENV || "prod").trim().toLowerCase() === "prod"
);
const gulp = require("gulp");
const rename = require("gulp-rename");
const { sass } = require("@mr-hope/gulp-sass");
const cleanCSS = require("gulp-clean-css");
const autoprefixer = require("gulp-autoprefixer");
const iconfont = require("gulp-iconfont");
const filelist = require("gulp-filelist");
const uglify = require("gulp-uglify");
const sourcemaps = require("gulp-sourcemaps");
const realFavicon = require("gulp-real-favicon");
const svgSprite = require("gulp-svg-sprite");
const rev = require("gulp-rev");
const replace = require("gulp-replace");
const path = require("path");
const fs = require("fs");
const del = require("del");
const through = require("through2");
var BUILD = "build";
var CSS_BUILD = BUILD + "/assets";
var JS_BUILD = BUILD + "/assets/js";
var FONTS = "static/fonts";
var FAVICON_DATA_FILE = BUILD + "/faviconData.json";
var TIMESTAMP = Math.round(Date.now() / 1000);
function noop() {
return through.obj();
}
gulp.task("sass", function () {
return gulp
.src("src/sass/{main,print,mobile}.scss")
.pipe(devBuild ? sourcemaps.init() : noop())
.pipe(sass().on("error", sass.logError))
.pipe(cleanCSS({ format: "beautify" }))
.pipe(
autoprefixer({
cascade: false,
})
)
.pipe(gulp.dest(CSS_BUILD))
.pipe(cleanCSS())
.pipe(rename({ extname: ".min.css" }))
.pipe(devBuild ? sourcemaps.write(".") : noop())
.pipe(gulp.dest(CSS_BUILD));
});
gulp.task("favicon-svg", function () {
return gulp
.src("src/favicon/favicon-master.svg")
.pipe(rename("favicon.svg"))
.pipe(gulp.dest("static/favicon/"));
});
gulp.task("favicon-generate", function (done) {
realFavicon.generateFavicon(
{
masterPicture: "src/favicon/favicon-master.svg",
dest: "static/favicon",
iconsPath: "/favicon",
design: {
ios: {
pictureAspect: "backgroundAndMargin",
backgroundColor: "#2f333e",
margin: "14%",
assets: {
ios6AndPriorIcons: false,
ios7AndLaterIcons: false,
precomposedIcons: false,
declareOnlyDefaultIcon: true,
},
},
desktopBrowser: {},
windows: {
pictureAspect: "whiteSilhouette",
backgroundColor: "#2f333e",
onConflict: "override",
assets: {
windows80Ie10Tile: false,
windows10Ie11EdgeTiles: {
small: false,
medium: true,
big: false,
rectangle: false,
},
},
},
androidChrome: {
pictureAspect: "shadow",
themeColor: "#2f333e",
manifest: {
display: "standalone",
orientation: "notSet",
onConflict: "override",
declared: true,
},
assets: {
legacyIcon: false,
lowResolutionIcons: false,
},
},
safariPinnedTab: {
pictureAspect: "silhouette",
themeColor: "#2f333e",
},
},
settings: {
scalingAlgorithm: "Mitchell",
errorOnImageTooSmall: false,
readmeFile: false,
htmlCodeFile: false,
usePathAsIs: false,
},
markupFile: FAVICON_DATA_FILE,
},
function () {
done();
}
);
});
gulp.task("favicon-check-update", function (done) {
var currentVersion = JSON.parse(fs.readFileSync(FAVICON_DATA_FILE)).version;
realFavicon.checkForUpdates(currentVersion, function (err) {
if (err) {
throw err;
}
});
done();
});
gulp.task("svg-sprite", function () {
config = {
shape: {
id: {
generator: "gdoc_%s",
},
dimension: {
maxWidth: 28,
maxHeight: 28,
attributes: false,
},
spacing: {
padding: 2,
box: "content",
},
dest: BUILD + "/intermediate-svg",
},
svg: {
xmlDeclaration: false,
rootAttributes: {
class: "svg-sprite",
},
},
mode: {
inline: true,
symbol: {
dest: "assets/sprites/",
sprite: "geekdoc.svg",
bust: false,
},
},
};
return gulp
.src("src/icons/*.svg")
.pipe(svgSprite(config))
.pipe(gulp.dest("."));
});
gulp.task("svg-sprite-list", function () {
config = { removeExtensions: true, flatten: true };
return gulp
.src("src/icons/*.svg")
.pipe(filelist("exampleSite/data/sprites/geekdoc.json", config))
.pipe(gulp.dest("."));
});
gulp.task("iconfont", function () {
var lastUnicode = 0xea01;
var files = fs.readdirSync("src/iconfont");
// Filter files with containing unicode value and set last unicode
files.forEach(function (file) {
var basename = path.basename(file);
var matches = basename.match(/^(?:((?:u[0-9a-f]{4,6},?)+)\-)?(.+)\.svg$/i);
var currentCode = -1;
if (matches && matches[1]) {
currentCode = parseInt(matches[1].split("u")[1], 16);
}
if (currentCode >= lastUnicode) {
lastUnicode = ++currentCode;
}
});
return gulp
.src(["src/iconfont/*.svg"])
.pipe(
iconfont({
startUnicode: lastUnicode,
fontName: "GeekdocIcons",
prependUnicode: true,
normalize: true,
fontHeight: 1001,
centerHorizontally: true,
formats: ["woff", "woff2"],
timestamp: TIMESTAMP,
})
)
.pipe(gulp.dest(FONTS));
});
gulp.task("js", function () {
return gulp
.src(["src/js/*.js"])
.pipe(devBuild ? sourcemaps.init() : noop())
.pipe(uglify())
.pipe(rename({ extname: ".min.js" }))
.pipe(devBuild ? sourcemaps.write(".") : noop())
.pipe(gulp.dest(JS_BUILD));
});
gulp.task("asset-sync-js", function () {
return gulp
.src([
"node_modules/clipboard/dist/clipboard.min.js",
"node_modules/flexsearch/dist/flexsearch.compact.js",
"node_modules/mermaid/dist/mermaid.min.js",
"node_modules/katex/dist/katex.min.js",
"node_modules/katex/dist/contrib/auto-render.min.js",
])
.pipe(replace(/\/\/# sourceMappingURL=.+$/, ""))
.pipe(
rename(function (path) {
path.basename = path.basename.replace(/compact/, "min");
})
)
.pipe(gulp.dest(JS_BUILD));
});
gulp.task("asset-sync-css", function () {
return gulp
.src(["node_modules/katex/dist/katex.min.css"])
.pipe(replace(/\/\/# sourceMappingURL=.+$/, ""))
.pipe(
rename(function (path) {
path.basename = path.basename.replace(/compact/, "min");
})
)
.pipe(gulp.dest(CSS_BUILD));
});
gulp.task("asset-sync-font", function () {
return gulp
.src(["node_modules/katex/dist/fonts/KaTeX_*"])
.pipe(gulp.dest(FONTS));
});
gulp.task("asset-rev", function () {
return gulp
.src(
[
CSS_BUILD + "/*.min.css",
JS_BUILD + "/*.min.js",
JS_BUILD + "/*.compact.js",
],
{
base: BUILD + "/assets",
}
)
.pipe(rev())
.pipe(gulp.dest("static"))
.pipe(
rev.manifest("data/assets-static.json", {
base: "data",
merge: true,
})
)
.pipe(rename("assets.json"))
.pipe(gulp.dest("data"));
});
gulp.task("asset-map", function () {
return gulp
.src([CSS_BUILD + "/*.min.css.map", JS_BUILD + "/*.min.js.map"], {
base: BUILD + "/assets",
})
.pipe(gulp.dest("static"));
});
gulp.task("clean", function () {
return del([
BUILD,
"assets/sprites/",
"static/js/",
"static/favicon/",
"static/*.min.css",
"static/*.css.map",
"data/assets.json",
"resources",
]);
});
/* Task series */
gulp.task(
"asset",
gulp.series("asset-sync-font", "asset-sync-css", "asset-sync-js", "asset-rev")
);
gulp.task("favicon", gulp.series("favicon-svg", "favicon-generate"));
gulp.task("svg", gulp.series("svg-sprite"));
gulp.task(
"default",
gulp.series([
devBuild ? [] : "clean",
"sass",
"js",
"asset",
devBuild ? "asset-map" : [],
"svg",
"iconfont",
"favicon",
])
);
gulp.task("watch", function () {
gulp.series("default")();
gulp.watch(
"src/sass/**/*.*css",
gulp.series("sass", "asset-rev", "asset-map")
);
gulp.watch("src/js/*.js", gulp.series("js", "asset-rev", "asset-map"));
});

View File

@ -1,21 +1,22 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="{{ .Site.Language.Lang }}"> <html lang="{{ .Site.Language.Lang }}">
<head>
<head>
{{ partial "head/meta" . }} {{ partial "head/meta" . }}
<title>Lost? Don't worry</title> <title>Lost? Don't worry</title>
{{ partial "head/favicons" . }} {{ partial "head/favicons" . }}
{{ partial "head/others" . }} {{ partial "head/others" . }}
</head> </head>
<body> <body>
{{ partial "svg-icon-symbols" . }} {{ partial "svg-icon-symbols" . }}
<div class="wrapper"> <div class="wrapper">
<input type="checkbox" class="hidden" id="menu-header-control" /> <input type="checkbox" class="hidden" id="menu-header-control" />
{{ partial "site-header" (dict "Root" . "MenuEnabled" false) }} {{ partial "site-header" (dict "Root" . "MenuEnabled" false) }}
<main class="gdoc-error flex-even"> <main class="gdoc-error flex-even">
<div class="flex align-center justify-center"> <div class="flex align-center justify-center">
<div class="gdoc-error__icon"> <div class="gdoc-error__icon">
@ -25,8 +26,8 @@
<div class="gdoc-error__line gdoc-error__title">Lost?</div> <div class="gdoc-error__line gdoc-error__title">Lost?</div>
<div class="gdoc-error__line gdoc-error__code">Error 404</div> <div class="gdoc-error__line gdoc-error__code">Error 404</div>
<div class="gdoc-error__line gdoc-error__help"> <div class="gdoc-error__line gdoc-error__help">
Seems like what you are looking for can't be found. Don't worry we can Seems like what you are looking for can't be found. Don't worry we can bring you back
bring you back to the <a class="gdoc-error__link" href="{{ .Site.BaseURL }}">homepage</a>. to the <a class="gdoc-error__link" href="{{ .Site.BaseURL }}">homepage</a>.
</div> </div>
</div> </div>
</div> </div>
@ -35,6 +36,5 @@
{{ partial "site-footer" . }} {{ partial "site-footer" . }}
</div> </div>
</body> </body>
</html> </html>

View File

@ -1,5 +1,7 @@
{{- $showAnchor := (and (default true .Page.Params.GeekdocAnchor) (default true .Page.Site.Params.GeekdocAnchor)) -}} {{- $showAnchor := (and (default true .Page.Params.GeekdocAnchor) (default true .Page.Site.Params.GeekdocAnchor)) -}}
<!-- prettier-ignore-start -->
{{- if $showAnchor -}} {{- if $showAnchor -}}
<div class="gdoc-page__anchorwrap"> <div class="gdoc-page__anchorwrap">
<h{{ .Level }} id="{{ .Anchor | safeURL }}"> <h{{ .Level }} id="{{ .Anchor | safeURL }}">
@ -16,3 +18,4 @@
</h{{ .Level }}> </h{{ .Level }}>
</div> </div>
{{- end -}} {{- end -}}
<!-- prettier-ignore-end -->

View File

@ -1,2 +1,6 @@
<img src="{{ .Destination | safeURL }}" alt="{{ .Text }}" {{ with .Title}} title="{{ . }}"{{ end }} /> <img
src="{{ .Destination | safeURL }}"
alt="{{ .Text }}"
{{ with .Title }}title="{{ . }}"{{ end }}
/>
{{- /* Drop trailing newlines */ -}} {{- /* Drop trailing newlines */ -}}

View File

@ -1,3 +1,8 @@
{{- $raw := or (hasPrefix .Text "<img") (hasPrefix .Text "<figure") -}} {{- $raw := or (hasPrefix .Text "<img") (hasPrefix .Text "<figure") -}}
<a class="gdoc-markdown__link{{ if $raw }}--raw{{ end }}" href="{{ .Destination | safeURL }}"{{ with .Title}} title="{{ . }}"{{ end }}>{{ .Text | safeHTML }}</a> <a
class="gdoc-markdown__link{{ if $raw }}--raw{{ end }}"
href="{{ .Destination | safeURL }}"
{{ with .Title }}title="{{ . }}"{{ end }}
>{{ .Text | safeHTML }}</a
>
{{- /* Drop trailing newlines */ -}} {{- /* Drop trailing newlines */ -}}

View File

@ -1,9 +1,10 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="{{ .Site.Language.Lang }}" class="color-toggle-hidden"> <html lang="{{ .Site.Language.Lang }}" class="color-toggle-hidden">
<head>
<head>
{{ partial "head/meta" . }} {{ partial "head/meta" . }}
<title>{{ if not (eq .Kind "home") }}{{ partial "title" . }} | {{ end }}{{ .Site.Title }}</title> <title>
{{ if not (eq .Kind "home") }}{{ partial "title" . }} |{{ end }}{{ .Site.Title }}
</title>
{{ partial "head/favicons" . }} {{ partial "head/favicons" . }}
{{ partial "head/rel-me" . }} {{ partial "head/rel-me" . }}
@ -11,17 +12,21 @@
{{ partial "head/others" . }} {{ partial "head/others" . }}
{{ partial "head/schema" . }} {{ partial "head/schema" . }}
{{ partial "head/custom" . }} {{ partial "head/custom" . }}
</head> </head>
<body itemscope itemtype="https://schema.org/WebPage"> <body itemscope itemtype="https://schema.org/WebPage">
{{ partial "svg-icon-symbols" . }} {{ partial "svg-icon-symbols" . }}
<div class="wrapper {{ if default false .Site.Params.GeekdocDarkModeDim }}dark-mode-dim{{ end }}">
<div
class="wrapper {{ if default false .Site.Params.GeekdocDarkModeDim }}dark-mode-dim{{ end }}"
>
<input type="checkbox" class="hidden" id="menu-control" /> <input type="checkbox" class="hidden" id="menu-control" />
<input type="checkbox" class="hidden" id="menu-header-control" /> <input type="checkbox" class="hidden" id="menu-header-control" />
{{ $navEnabled := default true .Page.Params.GeekdocNav }} {{ $navEnabled := default true .Page.Params.GeekdocNav }}
{{ partial "site-header" (dict "Root" . "MenuEnabled" $navEnabled) }} {{ partial "site-header" (dict "Root" . "MenuEnabled" $navEnabled) }}
<main class="container flex flex-even"> <main class="container flex flex-even">
{{ if $navEnabled }} {{ if $navEnabled }}
<aside class="gdoc-nav"> <aside class="gdoc-nav">
@ -29,6 +34,7 @@
</aside> </aside>
{{ end }} {{ end }}
<div class="gdoc-page"> <div class="gdoc-page">
{{ template "main" . }} {{ template "main" . }}
{{ partial "page-footer" . }} {{ partial "page-footer" . }}
@ -39,5 +45,5 @@
</div> </div>
{{ partial "foot" . }} {{ partial "foot" . }}
</body> </body>
</html> </html>

View File

@ -1,7 +1,10 @@
{{ define "main" }} {{ define "main" }}
{{ partial "page-header" . }} {{ partial "page-header" . }}
<article class="gdoc-markdown gdoc-markdown__align--{{ default "left" (.Page.Params.GeekdocAlign | lower) }}">
<article
class="gdoc-markdown gdoc-markdown__align--{{ default "left" (.Page.Params.GeekdocAlign | lower) }}"
>
<h1>{{ partial "title" . }}</h1> <h1>{{ partial "title" . }}</h1>
{{ partial "content" . }} {{ partial "content" . }}
</article> </article>

View File

@ -0,0 +1,7 @@
{{- $searchDataFile := printf "%s.searchdata.json" .Language.Lang -}}
{{- $searchData := resources.Get "search/searchdata.json" | resources.ExecuteAsTemplate $searchDataFile . | resources.Minify -}}
{
"dataFile": {{ $searchData.RelPermalink | jsonify }},
"indexConfig": {{ .Site.Params.GeekdocSearchConfig | jsonify }},
"showParent": {{ if .Site.Params.GeekdocSearchShowParent }}true{{ else }}false{{ end }}
}

View File

@ -1,7 +1,10 @@
{{ define "main" }} {{ define "main" }}
{{ partial "page-header" . }} {{ partial "page-header" . }}
<article class="gdoc-markdown gdoc-markdown__align--{{ default "left" (.Page.Params.GeekdocAlign | lower) }}">
<article
class="gdoc-markdown gdoc-markdown__align--{{ default "left" (.Page.Params.GeekdocAlign | lower) }}"
>
<h1>{{ partial "title" . }}</h1> <h1>{{ partial "title" . }}</h1>
{{ partial "content" . }} {{ partial "content" . }}
</article> </article>

View File

@ -1,14 +1,3 @@
{{ if default true .Site.Params.GeekdocSearch }} {{ if default true .Site.Params.GeekdocSearch }}
{{ .Scratch.Set "geekdocSearchConfig" .Site.Params.GeekdocSearchConfig }} <script defer src="{{ index (index .Site.Data.assets "search.js") "src" | relURL }}"></script>
<!-- Remove after https://github.com/gohugoio/hugo/issues/6331 -->
{{ $searchJSFile := printf "js/%s.search.js" .Language.Lang }}
{{ $searchJS := resources.Get "js/search.js" | resources.ExecuteAsTemplate $searchJSFile . | resources.Minify | fingerprint }}
<script defer src="{{ $searchJS.RelPermalink }}"></script>
{{ end }} {{ end }}
{{ if default true .Site.Params.GeekdocAnchorCopy }}
<script defer src="{{ index .Site.Data.assets "js/clipboard.min.js" | relURL }}"></script>
<script defer src="{{ index .Site.Data.assets "js/clipboard-loader.min.js" | relURL }}"></script>
{{ end }}
<script defer src="{{ index .Site.Data.assets "js/copycode.min.js" | relURL }}"></script>

View File

@ -1,3 +1,13 @@
<link rel="icon" type="image/svg+xml" href="{{ "favicon/favicon.svg" | relURL }}"> <link rel="icon" type="image/svg+xml" href="{{ "favicon/favicon.svg" | relURL }}" />
<link rel="icon" type="image/png" sizes="32x32" href="{{ "favicon/favicon-32x32.png" | relURL }}"> <link
<link rel="icon" type="image/png" sizes="16x16" href="{{ "favicon/favicon-16x16.png" | relURL }}"> rel="icon"
type="image/png"
sizes="32x32"
href="{{ "favicon/favicon-32x32.png" | relURL }}"
/>
<link
rel="icon"
type="image/png"
sizes="16x16"
href="{{ "favicon/favicon-16x16.png" | relURL }}"
/>

View File

@ -1,13 +1,13 @@
<meta charset="UTF-8"> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="color-scheme" content="light dark" /> <meta name="color-scheme" content="light dark" />
{{ $description := default (default .Site.Title .Site.Params.description) (default .Summary .Description) }} {{ $description := default (default .Site.Title .Site.Params.description) (default .Summary .Description) }}
{{ $keywords := default .Site.Params.Keywords .Keywords }} {{ $keywords := default .Site.Params.Keywords .Keywords }}
{{ with $description }} {{ with $description }}
<meta name="description" content="{{ . }}"> <meta name="description" content="{{ . }}" />
{{ end }} {{ end }}
{{ with $keywords }} {{ with $keywords }}
<meta name="keywords" content="{{ delimit . "," }}"> <meta name="keywords" content="{{ delimit . "," }}" />
{{ end }} {{ end }}

View File

@ -1,22 +1,66 @@
<script src="{{ index .Site.Data.assets "js/darkmode.min.js" | relURL }}"></script> <script src="{{ index (index .Site.Data.assets "bundle.js") "src" | relURL }}"></script>
<link rel="preload" as="font" href="{{ "fonts/Metropolis.woff2" | relURL }}" type="font/woff2" crossorigin="anonymous"> <link
<link rel="preload" as="font" href="{{ "fonts/LiberationSans.woff2" | relURL }}" type="font/woff2" crossorigin="anonymous"> rel="preload"
as="font"
href="{{ "fonts/Metropolis.woff2" | relURL }}"
type="font/woff2"
crossorigin="anonymous"
/>
<link
rel="preload"
as="font"
href="{{ "fonts/LiberationSans.woff2" | relURL }}"
type="font/woff2"
crossorigin="anonymous"
/>
<link rel="preload" href="{{ index .Site.Data.assets "main.min.css" | relURL }}" as="style"> <link
<link rel="stylesheet" href="{{ index .Site.Data.assets "main.min.css" | relURL }}" media="all"> rel="preload"
href="{{ index (index .Site.Data.assets "main.scss") "src" | relURL }}"
as="style"
/>
<link
rel="stylesheet"
href="{{ index (index .Site.Data.assets "main.scss") "src" | relURL }}"
media="all"
/>
<link rel="preload" href="{{ index .Site.Data.assets "mobile.min.css" | relURL }}" as="style"> <link
<link rel="stylesheet" href="{{ index .Site.Data.assets "mobile.min.css" | relURL }}" media="screen and (max-width: 45rem)"> rel="preload"
href="{{ index (index .Site.Data.assets "mobile.scss") "src" | relURL }}"
as="style"
/>
<link
rel="stylesheet"
href="{{ index (index .Site.Data.assets "mobile.scss") "src" | relURL }}"
media="screen and (max-width: 45rem)"
/>
<link rel="preload" href="{{ index .Site.Data.assets "print.min.css" | relURL }}" as="style"> <link
<link rel="stylesheet" href="{{ index .Site.Data.assets "print.min.css" | relURL }}" media="print"> rel="preload"
href="{{ index (index .Site.Data.assets "print.scss") "src" | relURL }}"
as="style"
/>
<link
rel="stylesheet"
href="{{ index (index .Site.Data.assets "print.scss") "src" | relURL }}"
media="print"
/>
<link rel="preload" href="{{ index .Site.Data.assets "custom.css" | relURL }}" as="style"> <link
<link rel="stylesheet" href="{{ index .Site.Data.assets "custom.css" | relURL }}" media="all"> rel="preload"
href="{{ index (index .Site.Data.assets "custom.css") "src" | relURL }}"
as="style"
/>
<link
rel="stylesheet"
href="{{ index (index .Site.Data.assets "custom.css") "src" | relURL }}"
media="all"
/>
{{ if (default false $.Site.Params.GeekdocOverwriteHTMLBase) }} {{ if (default false $.Site.Params.GeekdocOverwriteHTMLBase) }}
<base href="{{ .Site.BaseURL }}"> <base href="{{ .Site.BaseURL }}" />
{{ end }} {{ end }}
{{ printf "<!-- %s -->" "Made with Geekdoc theme https://github.com/thegeeklab/hugo-geekdoc" | safeHTML }} {{ printf "<!-- %s -->" "Made with Geekdoc theme https://github.com/thegeeklab/hugo-geekdoc" | safeHTML }}

View File

@ -1,6 +1,5 @@
{{ if .IsHome -}} {{ if .IsHome -}}
{{ $thumbnail := default (default "brand.svg" .Site.Params.logo) (index (default slice .Site.Params.images) 0) | absURL }} {{ $thumbnail := default (default "brand.svg" .Site.Params.logo) (index (default slice .Site.Params.images) 0) | absURL }}<script type="application/ld+json">
<script type="application/ld+json">
{ {
"@context": "http://schema.org", "@context": "http://schema.org",
"@type": "WebSite", "@type": "WebSite",
@ -10,7 +9,7 @@
"description": "{{ . }}", "description": "{{ . }}",
{{- end }} {{- end }}
"thumbnailUrl": "{{ $thumbnail }}" "thumbnailUrl": "{{ $thumbnail }}"
{{- with .Site.Params.GeekblogContentLicense }}, {{- with .Site.Params.GeekdocContentLicense }},
"license": "{{ .name }}" "license": "{{ .name }}"
{{- end }} {{- end }}
} }

View File

@ -1,19 +1,22 @@
{{ $current := .current }} {{ $current := .current }}
{{ template "menu-file" dict "sect" .source "current" $current "site" $current.Site }} {{ template "menu-file" dict "sect" .source "current" $current "site" $current.Site }}
<!-- template --> <!-- template -->
{{ define "menu-file" }} {{ define "menu-file" }}
{{ $current := .current }} {{ $current := .current }}
{{ $site := .site }} {{ $site := .site }}
<ul class="gdoc-nav__list">
{{ range sort (default (seq 0) .sect) "weight" }} <ul class="gdoc-nav__list">
{{ range sort (default (seq 0) .sect) "weight" }}
{{ $current.Scratch.Set "current" $current }} {{ $current.Scratch.Set "current" $current }}
{{ $current.Scratch.Set "site" $site }} {{ $current.Scratch.Set "site" $site }}
<li> <li>
{{ $ref := default false .ref }} {{ $ref := default false .ref }}
{{ if $ref}} {{ if $ref }}
{{ $site := $current.Scratch.Get "site" }} {{ $site := $current.Scratch.Get "site" }}
{{ $this := $site.GetPage .ref }} {{ $this := $site.GetPage .ref }}
{{ $current := $current.Scratch.Get "current" }} {{ $current := $current.Scratch.Get "current" }}
@ -24,22 +27,47 @@
{{ $id := substr (sha1 $this.Permalink) 0 8 }} {{ $id := substr (sha1 $this.Permalink) 0 8 }}
{{ $doCollapse := and (isset . "sub") (or $this.Params.GeekdocCollapseSection (default false .Site.Params.GeekdocCollapseAllSections)) }} {{ $doCollapse := and (isset . "sub") (or $this.Params.GeekdocCollapseSection (default false .Site.Params.GeekdocCollapseAllSections)) }}
<input
type="checkbox"
{{ if $doCollapse }} {{ if $doCollapse }}
<input type="checkbox" id="{{ printf "navtree-%s" $id }}" class="gdoc-nav__toggle" {{ if or $isCurrent $isAncestor }}checked{{ end }}> class="gdoc-nav__toggle" id="{{ printf "navtree-%s" $id }}"
<label for="{{ printf "navtree-%s" $id }}" class="flex justify-between"> {{ if or $isCurrent $isAncestor }}checked{{ end }}
{{ else }}
class="hidden"
{{ end }} {{ end }}
/>
<label
{{ if $doCollapse }}
for="{{ printf "navtree-%s" $id }}" class="flex justify-between"
{{ end }}
>
<span class="flex"> <span class="flex">
{{ if $icon }}<svg class="icon {{ .icon }}"><use xlink:href="#{{ .icon }}"></use></svg>{{ end }} {{ if $icon }}
<a href="{{ if .external }}{{ .ref }}{{ else }}{{ relref $current .ref }}{{ end }}" <svg class="icon {{ .icon }}"><use xlink:href="#{{ .icon }}"></use></svg>
class="gdoc-nav__entry {{ if not .external }}{{ if $isCurrent }}is-active{{ end }}{{ end }}"> {{ end }}
<a
href="{{ if .external }}
{{ .ref }}
{{ else }}
{{ relref $current .ref }}
{{ end }}"
class="gdoc-nav__entry {{ if not .external }}
{{ if $isCurrent }}is-active{{ end }}
{{ end }}"
>
{{ .name }} {{ .name }}
</a> </a>
</span> </span>
{{ if $doCollapse }} {{ if $doCollapse }}
<svg class="icon gdoc_keyborad_arrow_left"><use xlink:href="#gdoc_keyborad_arrow_left"></use></svg> <svg class="icon gdoc_keyborad_arrow_left">
<svg class="icon gdoc_keyborad_arrow_down hidden"><use xlink:href="#gdoc_keyborad_arrow_down"></use></svg> <use xlink:href="#gdoc_keyborad_arrow_left"></use>
</label> </svg>
<svg class="icon gdoc_keyborad_arrow_down hidden">
<use xlink:href="#gdoc_keyborad_arrow_down"></use>
</svg>
{{ end }} {{ end }}
</label>
{{ else }} {{ else }}
<span class="flex">{{ .name }}</span> <span class="flex">{{ .name }}</span>
{{ end }} {{ end }}
@ -48,7 +76,6 @@
{{ template "menu-file" dict "sect" . "current" ($current.Scratch.Get "current") "site" ($current.Scratch.Get "site") }} {{ template "menu-file" dict "sect" . "current" ($current.Scratch.Get "current") "site" ($current.Scratch.Get "site") }}
{{ end }} {{ end }}
</li> </li>
{{ end }}
{{ end }} </ul>
</ul>
{{ end }} {{ end }}

View File

@ -1,14 +1,15 @@
{{ $current := .current }} {{ $current := .current }}
{{ template "menu-extra" dict "sect" .source "current" $current "site" $current.Site "target" .target }} {{ template "menu-extra" dict "sect" .source "current" $current "site" $current.Site "target" .target }}
<!-- template --> <!-- template -->
{{ define "menu-extra" }} {{ define "menu-extra" }}
{{ $current := .current }} {{ $current := .current }}
{{ $site := .site }} {{ $site := .site }}
{{ $target := .target }} {{ $target := .target }}
{{ $sect := .sect }} {{ $sect := .sect }}
{{ range sort (default (seq 0) $sect) "weight" }} {{ range sort (default (seq 0) $sect) "weight" }}
{{ if isset . "ref" }} {{ if isset . "ref" }}
{{ $this := $site.GetPage .ref }} {{ $this := $site.GetPage .ref }}
{{ $isCurrent := eq $current $this }} {{ $isCurrent := eq $current $this }}
@ -20,7 +21,14 @@
{{ if eq $target "header" }} {{ if eq $target "header" }}
<span> <span>
<a href="{{ if .external }}{{ .ref }}{{ else }}{{ relref $current .ref }}{{ end }}" class="gdoc-header__link"> <a
href="{{ if .external }}
{{ .ref }}
{{ else }}
{{ relref $current .ref }}
{{ end }}"
class="gdoc-header__link"
>
<svg class="icon {{ .icon }}"> <svg class="icon {{ .icon }}">
<title>{{ .name }}</title> <title>{{ .name }}</title>
<use xlink:href="#{{ .icon }}"></use> <use xlink:href="#{{ .icon }}"></use>
@ -29,5 +37,5 @@
</span> </span>
{{ end }} {{ end }}
{{ end }} {{ end }}
{{ end }} {{ end }}
{{ end }} {{ end }}

View File

@ -1,10 +1,12 @@
{{ $current := . }} {{ $current := . }}
{{ template "tree-nav" dict "sect" .Site.Home.Sections "current" $current }} {{ template "tree-nav" dict "sect" .Site.Home.Sections "current" $current }}
<!-- templates --> <!-- templates -->
{{ define "tree-nav" }} {{ define "tree-nav" }}
{{ $current := .current }} {{ $current := .current }}
<ul class="gdoc-nav__list"> <ul class="gdoc-nav__list">
{{ $sortBy := (default "title" .current.Site.Params.GeekdocFileTreeSortBy | lower) }} {{ $sortBy := (default "title" .current.Site.Params.GeekdocFileTreeSortBy | lower) }}
{{ range .sect.GroupBy "Weight" }} {{ range .sect.GroupBy "Weight" }}
@ -46,14 +48,28 @@
{{ $id := substr (sha1 .Permalink) 0 8 }} {{ $id := substr (sha1 .Permalink) 0 8 }}
{{ $doCollapse := and $isParent (or .Params.GeekdocCollapseSection (default false .Site.Params.GeekdocCollapseAllSections)) }} {{ $doCollapse := and $isParent (or .Params.GeekdocCollapseSection (default false .Site.Params.GeekdocCollapseAllSections)) }}
<li> <li>
<input
type="checkbox"
{{ if $doCollapse }} {{ if $doCollapse }}
<input type="checkbox" id="{{ printf "navtree-%s" $id }}" class="gdoc-nav__toggle" {{ if or $isCurrent $isAncestor }}checked{{ end }}> class="gdoc-nav__toggle" id="{{ printf "navtree-%s" $id }}"
<label for="{{ printf "navtree-%s" $id }}" class="flex justify-between"> {{ if or $isCurrent $isAncestor }}checked{{ end }}
{{ else }}
class="hidden"
{{ end }} {{ end }}
/>
<label
{{ if $doCollapse }}
for="{{ printf "navtree-%s" $id }}" class="flex justify-between"
{{ end }}
>
{{ if or .Content .Params.GeekdocFlatSection }} {{ if or .Content .Params.GeekdocFlatSection }}
<span class="flex"> <span class="flex">
<a href="{{ .RelPermalink }}" class="gdoc-nav__entry {{ if eq $current . }}is-active{{ end }}"> <a
href="{{ .RelPermalink }}"
class="gdoc-nav__entry {{ if eq $current . }}is-active{{ end }}"
>
{{ partial "title" . }} {{ partial "title" . }}
</a> </a>
</span> </span>
@ -61,13 +77,17 @@
<span class="flex">{{ partial "title" . }}</span> <span class="flex">{{ partial "title" . }}</span>
{{ end }} {{ end }}
{{ if $doCollapse }} {{ if $doCollapse }}
<svg class="icon gdoc_keyborad_arrow_left"><use xlink:href="#gdoc_keyborad_arrow_left"></use></svg> <svg class="icon gdoc_keyborad_arrow_left">
<svg class="icon gdoc_keyborad_arrow_down"><use xlink:href="#gdoc_keyborad_arrow_down"></use></svg> <use xlink:href="#gdoc_keyborad_arrow_left"></use>
</label> </svg>
<svg class="icon gdoc_keyborad_arrow_down">
<use xlink:href="#gdoc_keyborad_arrow_down"></use>
</svg>
{{ end }} {{ end }}
</label>
{{ if $isParent }} {{ if $isParent }}
{{ template "tree-nav" dict "sect" .Pages "current" $current}} {{ template "tree-nav" dict "sect" .Pages "current" $current }}
{{ end }} {{ end }}
</li> </li>
{{ end }} {{ end }}

View File

@ -1,6 +1,7 @@
<nav> <nav>
{{ partial "search" . }} {{ partial "search" . }}
<section class="gdoc-nav--main"> <section class="gdoc-nav--main">
<h2>Navigation</h2> <h2>Navigation</h2>
{{ if .Site.Params.GeekdocMenuBundle }} {{ if .Site.Params.GeekdocMenuBundle }}
@ -18,7 +19,12 @@
{{ range $name, $taxonomy := .Site.Taxonomies.tags }} {{ range $name, $taxonomy := .Site.Taxonomies.tags }}
{{ with $.Site.GetPage (printf "/tags/%s" $name) }} {{ with $.Site.GetPage (printf "/tags/%s" $name) }}
<li> <li>
<a class="gdoc-nav__entry {{ if eq $currentPage .RelPermalink }} is-active {{ end }}" href="{{ .RelPermalink }}">{{ .Title }}</a> <a
class="gdoc-nav__entry {{ if eq $currentPage .RelPermalink }}is-active{{ end }}"
href="{{ .RelPermalink }}"
>
{{ .Title }}
</a>
</li> </li>
{{ end }} {{ end }}
{{ end }} {{ end }}
@ -26,6 +32,7 @@
</section> </section>
{{ end }} {{ end }}
<section class="gdoc-nav--more"> <section class="gdoc-nav--more">
{{ if .Site.Data.menu.more.more }} {{ if .Site.Data.menu.more.more }}
<h2>More</h2> <h2>More</h2>

View File

@ -17,7 +17,7 @@
{{ $current.Scratch.Set "site" $site }} {{ $current.Scratch.Set "site" $site }}
{{ $ref := default false .ref }} {{ $ref := default false .ref }}
{{ if $ref}} {{ if $ref }}
{{ $site := $current.Scratch.Get "site" }} {{ $site := $current.Scratch.Get "site" }}
{{ $this := $site.GetPage .ref }} {{ $this := $site.GetPage .ref }}
{{ $current := $current.Scratch.Get "current" }} {{ $current := $current.Scratch.Get "current" }}
@ -48,12 +48,24 @@
{{ if $showPrevNext }} {{ if $showPrevNext }}
<span class="gdoc-page__nav"> <span class="gdoc-page__nav">
{{ with ($current.Scratch.Get "prevPage") }} {{ with ($current.Scratch.Get "prevPage") }}
<a class="gdoc-page__nav--prev flex align-center" href="{{.this.RelPermalink}}" title="{{ .name }}"> {{ .name }}</a> <a
class="gdoc-page__nav--prev flex align-center"
href="{{ .this.RelPermalink }}"
title="{{ .name }}"
>
{{ .name }}
</a>
{{ end }} {{ end }}
</span> </span>
<span class="gdoc-page__nav"> <span class="gdoc-page__nav">
{{ with ($current.Scratch.Get "nextPage") }} {{ with ($current.Scratch.Get "nextPage") }}
<a class="gdoc-page__nav--next flex align-center" href="{{.this.RelPermalink}}" title="{{ .name }}">{{ .name }} </a> <a
class="gdoc-page__nav--next flex align-center"
href="{{ .this.RelPermalink }}"
title="{{ .name }}"
>
{{ .name }}
</a>
{{ end }} {{ end }}
</span> </span>
{{ end }} {{ end }}

View File

@ -20,11 +20,18 @@
{{ $showBreadcrumb := (and (default true .Page.Params.GeekdocBreadcrumb) (default true .Site.Params.GeekdocBreadcrumb)) }} {{ $showBreadcrumb := (and (default true .Page.Params.GeekdocBreadcrumb) (default true .Site.Params.GeekdocBreadcrumb)) }}
{{ $showEdit := (and ($.Scratch.Get "geekdocFilePath") $geekdocRepo $geekdocEditPath) }} {{ $showEdit := (and ($.Scratch.Get "geekdocFilePath") $geekdocRepo $geekdocEditPath) }}
<div class="gdoc-page__header flex flex-wrap <div
{{ if $showBreadcrumb }} justify-between {{ else }} justify-end {{ end }} class="gdoc-page__header flex flex-wrap
{{ if not $showEdit }} hidden-mobile {{ end }} {{ if $showBreadcrumb }}
{{ if (and (not $showBreadcrumb) (not $showEdit)) }} hidden {{ end }}" itemprop="breadcrumb"> justify-between
{{if $showBreadcrumb }} {{ else }}
justify-end
{{ end }}
{{ if not $showEdit }}hidden-mobile{{ end }}
{{ if (and (not $showBreadcrumb) (not $showEdit)) }}hidden{{ end }}"
itemprop="breadcrumb"
>
{{ if $showBreadcrumb }}
<div> <div>
<svg class="icon gdoc_path hidden-mobile"><use xlink:href="#gdoc_path"></use></svg> <svg class="icon gdoc_path hidden-mobile"><use xlink:href="#gdoc_path"></use></svg>
<ol class="breadcrumb" itemscope itemtype="https://schema.org/BreadcrumbList"> <ol class="breadcrumb" itemscope itemtype="https://schema.org/BreadcrumbList">
@ -39,7 +46,9 @@
<div> <div>
<span class="editpage"> <span class="editpage">
<svg class="icon gdoc_code"><use xlink:href="#gdoc_code"></use></svg> <svg class="icon gdoc_code"><use xlink:href="#gdoc_code"></use></svg>
<a href="{{ $geekdocRepo }}/{{ path.Join $geekdocEditPath ($.Scratch.Get "geekdocFilePath") }}"> <a
href="{{ $geekdocRepo }}/{{ path.Join $geekdocEditPath ($.Scratch.Get "geekdocFilePath") }}"
>
Edit this page Edit this page
</a> </a>
</span> </span>

View File

@ -1,8 +1,14 @@
{{ if default true .Site.Params.GeekdocSearch }} {{ if default true .Site.Params.GeekdocSearch }}
<div class="gdoc-search"> <div class="gdoc-search">
<svg class="icon gdoc_search"><use xlink:href="#gdoc_search"></use></svg> <svg class="icon gdoc_search"><use xlink:href="#gdoc_search"></use></svg>
<input type="text" id="gdoc-search-input" class="gdoc-search__input" placeholder="Search..." <input
aria-label="Search" maxlength="64" /> type="text"
id="gdoc-search-input"
class="gdoc-search__input"
placeholder="Search..."
aria-label="Search"
maxlength="64"
/>
<div class="gdoc-search__spinner spinner hidden"></div> <div class="gdoc-search__spinner spinner hidden"></div>
<ul id="gdoc-search-results" class="gdoc-search__list"></ul> <ul id="gdoc-search-results" class="gdoc-search__list"></ul>
</div> </div>

View File

@ -20,7 +20,10 @@
<div class="flex flex-25 justify-end"> <div class="flex flex-25 justify-end">
<span class="gdoc-footer__item text-right"> <span class="gdoc-footer__item text-right">
<a class="gdoc-footer__link fake-link" href="#" aria-label="Back to top"> <a class="gdoc-footer__link fake-link" href="#" aria-label="Back to top">
<svg class="icon gdoc_keyborad_arrow_up"><use xlink:href="#gdoc_keyborad_arrow_up"></use></svg> <span class="hidden-mobile">Back to top</span> <svg class="icon gdoc_keyborad_arrow_up">
<use xlink:href="#gdoc_keyborad_arrow_up"></use>
</svg>
<span class="hidden-mobile">Back to top</span>
</a> </a>
</span> </span>
</div> </div>

View File

@ -14,13 +14,17 @@
{{ end }} {{ end }}
<a class="gdoc-header__link" href="{{ .Root.Site.BaseURL }}"> <a class="gdoc-header__link" href="{{ .Root.Site.BaseURL }}">
<span class="gdoc-brand flex align-center"> <span class="gdoc-brand flex align-center">
<img class="gdoc-brand__img" src="{{ (default "brand.svg" .Root.Site.Params.GeekdocLogo) | relURL }}" alt=""> <img
class="gdoc-brand__img"
src="{{ (default "brand.svg" .Root.Site.Params.GeekdocLogo) | relURL }}"
alt=""
/>
<span class="gdoc-brand__title">{{ .Root.Site.Title }}</span> <span class="gdoc-brand__title">{{ .Root.Site.Title }}</span>
</span> </span>
</a> </a>
<div class="gdoc-menu-header"> <div class="gdoc-menu-header">
<span {{ if .Root.Site.Data.menu.extra.header }}class="gdoc-menu-header__items"{{ end }}>
{{ if .Root.Site.Data.menu.extra.header }} {{ if .Root.Site.Data.menu.extra.header }}
<span class="gdoc-menu-header__items">
{{ partial "menu-extra" (dict "current" .Root "source" .Root.Site.Data.menu.extra.header "target" "header") }} {{ partial "menu-extra" (dict "current" .Root "source" .Root.Site.Data.menu.extra.header "target" "header") }}
{{ end }} {{ end }}
<span id="gdoc-dark-mode"> <span id="gdoc-dark-mode">
@ -54,7 +58,9 @@
</svg> </svg>
</label> </label>
</span> </span>
{{ end }}
</span> </span>
{{ if .Root.Site.Data.menu.extra.header }}
<label for="menu-header-control" class="gdoc-menu-header__control"> <label for="menu-header-control" class="gdoc-menu-header__control">
<svg class="icon gdoc_keyborad_arrow_left"> <svg class="icon gdoc_keyborad_arrow_left">
<use xlink:href="#gdoc_keyborad_arrow_left"></use> <use xlink:href="#gdoc_keyborad_arrow_left"></use>

View File

@ -1,4 +1,4 @@
{{ range resources.Match "sprites/*.svg" }} {{ range resources.Match "sprites/*.svg" }}
{{ printf "<!-- geekdoc include: %s -->" . | safeHTML }} {{ printf "<!-- geekdoc include: %s -->" . | safeHTML }}
{{ .Content | safeHTML }} {{ .Content | safeHTML }}
{{ end }} {{ end }}

View File

@ -9,7 +9,13 @@
</section> </section>
<div class="gdoc-post__readmore"> <div class="gdoc-post__readmore">
{{ if .Truncated }} {{ if .Truncated }}
<a class="flex-inline align-center fake-link" title="Read full post" href="{{ .RelPermalink }}">Read full post</a> <a
class="flex-inline align-center fake-link"
title="Read full post"
href="{{ .RelPermalink }}"
>
Read full post
</a>
{{ end }} {{ end }}
</div> </div>
@ -54,9 +60,15 @@
{{ end }} {{ end }}
{{ define "post-tag" }} {{ define "post-tag" }}
<span class="gdoc-post__tag"> <span class="gdoc-post__tag">
<span class="gdoc-button"> <span class="gdoc-button">
<a class="gdoc-button__link" href="{{ .page.RelPermalink }}" title="All posts tagged with '{{ .name }}'">{{ .name }}</a> <a
class="gdoc-button__link"
href="{{ .page.RelPermalink }}"
title="All posts tagged with '{{ .name }}'"
>
{{ .name }}
</a>
</span>
</span> </span>
</span>
{{ end }} {{ end }}

View File

@ -3,7 +3,7 @@
{{ $size := default "regular" (.Get "size" | lower) }} {{ $size := default "regular" (.Get "size" | lower) }}
{{ if not (in (slice "regular" "large") $size) }} {{ if not (in (slice "regular" "large") $size) }}
{{ $size = "regular" }} {{ $size = "regular" }}
{{ end }} {{ end }}
{{ with .Get "href" }} {{ with .Get "href" }}
@ -15,8 +15,13 @@
{{ $ref = relref $ . }} {{ $ref = relref $ . }}
{{ end }} {{ end }}
<span class="gdoc-button gdoc-button--{{ $size }}{{ with .Get "class" }} {{ . }}{{ end }}">
<a {{ with $ref }} href="{{.}}" {{ end }} {{ with $target }} target="{{.}}" {{ end }} class="gdoc-button__link"> <span class="gdoc-button gdoc-button--{{ $size }}{{ with .Get "class" }}{{ . }}{{ end }}">
<a
{{ with $ref }}href="{{ . }}"{{ end }}
{{ with $target }}target="{{ . }}"{{ end }}
class="gdoc-button__link"
>
{{ $.Inner }} {{ $.Inner }}
</a> </a>
</span> </span>

View File

@ -1,5 +1,5 @@
{{ $id := .Get 0 }} {{ $id := .Get 0 }}
{{- with $id -}} {{- with $id -}}
<svg class="icon {{ . }}"><use xlink:href="#{{ . }}"></use></svg> <svg class="icon {{ . }}"><use xlink:href="#{{ . }}"></use></svg>
{{- end -}} {{- end -}}

View File

@ -4,26 +4,41 @@
{{ $lazyLoad := default (default true $.Site.Params.GeekdocImageLazyLoading) (.Get "lazy") }} {{ $lazyLoad := default (default true $.Site.Params.GeekdocImageLazyLoading) (.Get "lazy") }}
{{ with $source }} {{ with $source }}
{{ $caption := default .Title $customAlt }} {{ $caption := default .Title $customAlt }}
{{ $tiny := (.Resize "320x").RelPermalink }} {{ $tiny := (.Resize "320x").RelPermalink }}
{{ $small := (.Resize "600x").RelPermalink }} {{ $small := (.Resize "600x").RelPermalink }}
{{ $medium := (.Resize "1200x").RelPermalink }} {{ $medium := (.Resize "1200x").RelPermalink }}
{{ $large := (.Resize "1800x").RelPermalink }} {{ $large := (.Resize "1800x").RelPermalink }}
{{ $size := dict "tiny" $tiny "small" $small "medium" $medium "large" $large }} {{ $size := dict "tiny" $tiny "small" $small "medium" $medium "large" $large }}
<div class="flex justify-center">
<figure class="gdoc-markdown__figure"> <div class="flex justify-center">
<figure class="gdoc-markdown__figure">
<a class="gdoc-markdown__link--raw" href="{{ .RelPermalink }}"> <a class="gdoc-markdown__link--raw" href="{{ .RelPermalink }}">
<picture> <picture>
<source {{ with $customSize }}srcset="{{ index $size $customSize }}"{{ else }}srcset="{{ $size.small }} 600w, {{ $size.medium }} 1200w" sizes="100vw"{{ end }} /> <source
<img {{ if $lazyLoad }}loading="lazy" {{ end }}src="{{ $size.large }}" alt="{{ $caption }}" /> {{ with $customSize }}
srcset="{{ index $size $customSize }}"
{{ else }}
srcset="{{ $size.small }} 600w, {{ $size.medium }} 1200w" sizes="100vw"
{{ end }}
/>
<img
{{ if $lazyLoad }}
loading="lazy"
{{ end }}
src="{{ $size.large }}"
alt="{{ $caption }}"
/>
</picture> </picture>
</a> </a>
{{ with $caption -}} {{ with $caption -}}
<figcaption>{{ . }}{{ with $source.Params.credits }} ({{ . | $.Page.RenderString }}){{ end }}</figcaption> <figcaption>
{{ . }}{{ with $source.Params.credits }}({{ . | $.Page.RenderString }}){{ end }}
</figcaption>
{{- end }} {{- end }}
</figure> </figure>
</div> </div>
{{ end }} {{ end }}

View File

@ -4,14 +4,15 @@
{{ $language := .Get "language" }} {{ $language := .Get "language" }}
{{ $options :=.Get "options" }} {{ $options :=.Get "options" }}
<div class="gdoc-include"> <div class="gdoc-include">
{{- if (.Get "language") -}} {{- if (.Get "language") -}}
{{- highlight ($file | readFile) $language (default "linenos=table" $options) -}} {{- highlight ($file | readFile) $language (default "linenos=table" $options) -}}
{{- else if eq $type "html" -}} {{- else if eq $type "html" -}}
{{- $file | readFile | safeHTML -}} {{- $file | readFile | safeHTML -}}
{{- else if eq $type "page" -}} {{- else if eq $type "page" -}}
{{- with $page }}{{ .Content }}{{ end -}} {{- with $page }}{{ .Content }}{{ end -}}
{{- else -}} {{- else -}}
{{- $file | readFile | $.Page.RenderString -}} {{- $file | readFile | $.Page.RenderString -}}
{{- end -}} {{- end -}}
</div> </div>

View File

@ -1,13 +1,14 @@
{{ if not (.Page.Scratch.Get "katex") }} {{ if not (.Page.Scratch.Get "katex") }}
<!-- Include katext only first time --> <!-- Include katext only first time -->
<link rel="stylesheet" href="{{ index .Site.Data.assets "katex.min.css" | relURL }}" /> <link
<script defer src="{{ index .Site.Data.assets "js/katex.min.js" | relURL }}"></script> rel="stylesheet"
<script defer src="{{ index .Site.Data.assets "js/auto-render.min.js" | relURL }}"></script> href="{{ index (index .Site.Data.assets "katex.css") "src" | relURL }}"
<script defer src="{{ index .Site.Data.assets "js/katex-loader.min.js" | relURL }}"></script> /><script defer src="{{ index (index .Site.Data.assets "katex.js") "src" | relURL }}"></script>
{{ .Page.Scratch.Set "katex" true }} {{ .Page.Scratch.Set "katex" true }}
{{ end }} {{ end }}
<span class="gdoc-katex katex{{ with .Get "class" }} {{ . }}{{ end }}">
<span class="gdoc-katex katex{{ with .Get "class" }}{{ . }}{{ end }}">
{{ cond (in .Params "display") "\\[" "\\(" -}} {{ cond (in .Params "display") "\\[" "\\(" -}}
{{- trim .Inner "\n" -}} {{- trim .Inner "\n" -}}
{{- cond (in .Params "display") "\\]" "\\)" }} {{- cond (in .Params "display") "\\]" "\\)" }}

View File

@ -1,10 +1,9 @@
{{ if not (.Page.Scratch.Get "mermaid") }} {{ if not (.Page.Scratch.Get "mermaid") }}
<!-- Include mermaid only first time --> <!-- Include mermaid only first time --><script defer src="{{ index (index .Site.Data.assets "mermaid.js") "src" | relURL }}"></script>
<script defer src="{{ index .Site.Data.assets "js/mermaid.min.js" | relURL }}"></script> {{ .Page.Scratch.Set "mermaid" true }}
<script defer src="{{ index .Site.Data.assets "js/mermaid-loader.min.js" | relURL }}"></script>
{{ .Page.Scratch.Set "mermaid" true }}
{{ end }} {{ end }}
<pre class="gdoc-mermaid mermaid{{ with .Get "class" }} {{ . }}{{ end }}">
<pre class="gdoc-mermaid mermaid{{ with .Get "class" }}{{ printf " %s" . }}{{ end }}">
{{- .Inner -}} {{- .Inner -}}
</pre> </pre>

View File

@ -9,4 +9,4 @@
{{ .Parent.Scratch.Add $group (dict "Name" $name "Content" .Inner) }} {{ .Parent.Scratch.Add $group (dict "Name" $name "Content" .Inner) }}
{{ else }} {{ else }}
{{ errorf "%q: 'tab' shortcode must be inside 'tabs' shortcode" .Page.Path }} {{ errorf "%q: 'tab' shortcode must be inside 'tabs' shortcode" .Page.Path }}
{{ end}} {{ end }}

View File

@ -2,10 +2,16 @@
{{ $id := .Get 0 }} {{ $id := .Get 0 }}
{{ $group := printf "tabs-%s" $id }} {{ $group := printf "tabs-%s" $id }}
<div class="gdoc-tabs"> <div class="gdoc-tabs">
{{ range $index, $tab := .Scratch.Get $group }} {{ range $index, $tab := .Scratch.Get $group }}
<input type="radio" class="gdoc-tabs__control hidden" name="{{ $group }}" id="{{ printf "%s-%d" $group $index }}" <input
{{ if not $index }}checked="checked" {{ end }} /> type="radio"
class="gdoc-tabs__control hidden"
name="{{ $group }}"
id="{{ printf "%s-%d" $group $index }}"
{{ if not $index }}checked="checked"{{ end }}
/>
<label for="{{ printf "%s-%d" $group $index }}" class="gdoc-tabs__label"> <label for="{{ printf "%s-%d" $group $index }}" class="gdoc-tabs__label">
{{ $tab.Name }} {{ $tab.Name }}
</label> </label>

View File

@ -1,11 +1,12 @@
{{ $tocLevels := default (default 6 .Site.Params.GeekdocToC) .Page.Params.GeekdocToC }} {{ $tocLevels := default (default 6 .Site.Params.GeekdocToC) .Page.Params.GeekdocToC }}
{{ if $tocLevels }} {{ if $tocLevels }}
<div class="gdoc-toc gdoc-toc__level--{{$tocLevels}}"> <div class="gdoc-toc gdoc-toc__level--{{ $tocLevels }}">
{{ template "toc-tree" dict "sect" .Page.Pages }} {{ template "toc-tree" dict "sect" .Page.Pages }}
</div> </div>
{{ end }} {{ end }}
<!-- templates --> <!-- templates -->
{{ define "toc-tree" }} {{ define "toc-tree" }}
<ul> <ul>
@ -15,10 +16,15 @@
<li> <li>
{{ if or .Content .Params.GeekdocFlatSection }} {{ if or .Content .Params.GeekdocFlatSection }}
<span> <span>
<a href="{{ .RelPermalink }}" class="gdoc-toc__entry">{{ partial "title" . }}{{ with .Params.GeekdocDescription }}:</a> {{ . }}{{ else }}</a>{{ end }} <a href="{{ .RelPermalink }}" class="gdoc-toc__entry">
{{ partial "title" . }}{{ with .Params.GeekdocDescription }}:{{ end }}
</a>
{{ with .Params.GeekdocDescription }}{{ . }}{{ end }}
</span> </span>
{{ else }} {{ else }}
<span>{{ partial "title" . }}{{ with .Params.GeekdocDescription }}: {{ . }}{{ end }}</span> <span>
{{ partial "title" . }}{{ with .Params.GeekdocDescription }}: {{ . }}{{ end }}
</span>
{{ end }} {{ end }}
{{ $numberOfPages := (add (len .Pages) (len .Sections)) }} {{ $numberOfPages := (add (len .Pages) (len .Sections)) }}

View File

@ -1,5 +1,8 @@
{{ $tocLevels := default (default 6 .Site.Params.GeekdocToC) .Page.Params.GeekdocToC }} {{ $tocLevels := default (default 6 .Site.Params.GeekdocToC) .Page.Params.GeekdocToC }}
{{ if and $tocLevels .Page.TableOfContents }} {{ if and $tocLevels .Page.TableOfContents }}
<div class="gdoc-toc gdoc-toc__level--{{$tocLevels}}">{{ .Page.TableOfContents }}<hr></div> <div class="gdoc-toc gdoc-toc__level--{{ $tocLevels }}">
{{ .Page.TableOfContents }}
<hr />
</div>
{{ end }} {{ end }}

View File

@ -9,7 +9,13 @@
</section> </section>
<div class="gdoc-post__readmore"> <div class="gdoc-post__readmore">
{{ if .Truncated }} {{ if .Truncated }}
<a class="flex-inline align-center fake-link" title="Read full post" href="{{ .RelPermalink }}">Read full post</a> <a
class="flex-inline align-center fake-link"
title="Read full post"
href="{{ .RelPermalink }}"
>
Read full post
</a>
{{ end }} {{ end }}
</div> </div>
@ -54,9 +60,15 @@
{{ end }} {{ end }}
{{ define "post-tag" }} {{ define "post-tag" }}
<span class="gdoc-post__tag"> <span class="gdoc-post__tag">
<span class="gdoc-button"> <span class="gdoc-button">
<a class="gdoc-button__link" href="{{ .page.RelPermalink }}" title="All posts tagged with '{{ .name }}'">{{ .name }}</a> <a
class="gdoc-button__link"
href="{{ .page.RelPermalink }}"
title="All posts tagged with '{{ .name }}'"
>
{{ .name }}
</a>
</span>
</span> </span>
</span>
{{ end }} {{ end }}

20912
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -2,10 +2,23 @@
"name": "geekdoc", "name": "geekdoc",
"version": "1.0.0", "version": "1.0.0",
"description": "Hugo theme made for documentation", "description": "Hugo theme made for documentation",
"main": "gulpfile.js", "main": "index.js",
"scripts": { "scripts": {
"gulp": "gulp", "build": "run-s prep:clean prep:make svg build:webpack",
"server": "hugo server -D -F -s exampleSite/" "build:webpack": "webpack --mode=production",
"build:webpack-devel": "webpack --mode=development",
"start": "run-s prep:clean prep:make svg build:webpack-devel ; run-p start:webpack start:hugo",
"start:webpack": "webpack --mode=development --watch",
"start:build": "webpack --mode=development",
"start:hugo": "hugo server -D -F -s exampleSite/",
"svg": "run-s svg:*",
"svg:sprite": "svg-sprite -C svgsprite.config.json 'src/icons/*.svg'",
"svg:font": "svgtofont --sources build/icons --output build/fonts",
"prep:clean": "shx rm -rf build/ static/",
"prep:clean-all": "shx rm -rf build/ static/ data/ assets/sprites/ exampleSite/data/sprites",
"prep:make": "mkdir -p build/icons build/fonts",
"svg-sprite-list": "run-s prep:make svg ; mkdir -p exampleSite/data/sprites/ ; cp build/fonts/GeekdocIcons.json exampleSite/data/sprites/geekdoc.json",
"lint": "eslint src/js/ --color"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
@ -14,34 +27,53 @@
"author": "Robert Kaussow", "author": "Robert Kaussow",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"ajv": "8.8.2",
"clipboard": "2.0.8", "clipboard": "2.0.8",
"flexsearch": "0.7.21", "flexsearch": "0.7.21",
"katex": "0.15.1", "katex": "0.15.1",
"mermaid": "8.13.6" "mermaid": "8.13.8",
"store2": "2.13.1"
}, },
"devDependencies": { "devDependencies": {
"@mr-hope/gulp-sass": "2.0.0", "@babel/eslint-parser": "7.16.5",
"del": "6.0.0", "autoprefixer": "10.4.1",
"gulp": "4.0.2", "copy-webpack-plugin": "10.2.0",
"gulp-autoprefixer": "8.0.0", "css-loader": "6.5.1",
"gulp-clean-css": "4.3.0", "eslint": "8.5.0",
"gulp-filelist": "2.0.5", "eslint-config-prettier": "8.3.0",
"gulp-iconfont": "11.0.1", "eslint-plugin-prettier": "4.0.0",
"gulp-real-favicon": "0.3.2", "favicons-webpack-plugin": "5.0.2",
"gulp-rename": "2.0.0", "npm-run-all": "4.1.5",
"gulp-replace": "1.1.3", "postcss-loader": "6.2.1",
"gulp-rev": "9.0.0",
"gulp-sourcemaps": "3.0.0",
"gulp-svg-sprite": "1.5.0",
"gulp-uglify": "3.0.2",
"prettier": "2.5.1", "prettier": "2.5.1",
"prettier-plugin-go-template": "0.0.11", "prettier-plugin-go-template": "0.0.11",
"through2": "4.0.2" "sass": "1.45.1",
"sass-loader": "12.4.0",
"shx": "0.3.3",
"svg-sprite": "1.5.3",
"svgtofont": "3.13.1",
"webpack": "5.65.0",
"webpack-cli": "4.9.1",
"webpack-manifest-plugin": "4.0.2",
"webpack-remove-empty-scripts": "0.7.2"
}, },
"browserslist": [ "browserslist": [
"last 2 version", "last 2 version",
"> 5%", "> 5%",
"not dead", "not dead",
"Firefox ESR" "Firefox ESR"
] ],
"svgtofont": {
"fontName": "GeekdocIcons",
"css": false,
"html": false,
"emptyDist": true,
"useNameAsUnicode": true,
"svgicons2svgfont": {
"fontHeight": 1001,
"normalize": true,
"centerHorizontally": true,
"centerVertically": true
}
}
} }

View File

@ -1 +0,0 @@
{"result":{"status":"success"},"favicon":{"package_url":"https://realfavicongenerator.net/files/a14c093dfa827ba277aadc2d7a936885d5b564aa/favicon_package_v0.16.zip","files_urls":["https://realfavicongenerator.net/files/a14c093dfa827ba277aadc2d7a936885d5b564aa/package_files/android-chrome-192x192.png","https://realfavicongenerator.net/files/a14c093dfa827ba277aadc2d7a936885d5b564aa/package_files/android-chrome-512x512.png","https://realfavicongenerator.net/files/a14c093dfa827ba277aadc2d7a936885d5b564aa/package_files/apple-touch-icon.png","https://realfavicongenerator.net/files/a14c093dfa827ba277aadc2d7a936885d5b564aa/package_files/browserconfig.xml","https://realfavicongenerator.net/files/a14c093dfa827ba277aadc2d7a936885d5b564aa/package_files/favicon-16x16.png","https://realfavicongenerator.net/files/a14c093dfa827ba277aadc2d7a936885d5b564aa/package_files/favicon-32x32.png","https://realfavicongenerator.net/files/a14c093dfa827ba277aadc2d7a936885d5b564aa/package_files/favicon.ico","https://realfavicongenerator.net/files/a14c093dfa827ba277aadc2d7a936885d5b564aa/package_files/mstile-144x144.png","https://realfavicongenerator.net/files/a14c093dfa827ba277aadc2d7a936885d5b564aa/package_files/mstile-150x150.png","https://realfavicongenerator.net/files/a14c093dfa827ba277aadc2d7a936885d5b564aa/package_files/mstile-310x150.png","https://realfavicongenerator.net/files/a14c093dfa827ba277aadc2d7a936885d5b564aa/package_files/mstile-310x310.png","https://realfavicongenerator.net/files/a14c093dfa827ba277aadc2d7a936885d5b564aa/package_files/mstile-70x70.png","https://realfavicongenerator.net/files/a14c093dfa827ba277aadc2d7a936885d5b564aa/package_files/safari-pinned-tab.svg","https://realfavicongenerator.net/files/a14c093dfa827ba277aadc2d7a936885d5b564aa/package_files/site.webmanifest"],"html_code":"<link rel=\"apple-touch-icon\" sizes=\"180x180\" href=\"/apple-touch-icon.png\">\n<link rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/favicon-32x32.png\">\n<link rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/favicon-16x16.png\">\n<link rel=\"manifest\" href=\"/site.webmanifest\">\n<link rel=\"mask-icon\" href=\"/safari-pinned-tab.svg\" color=\"#5bbad5\">\n<meta name=\"msapplication-TileColor\" content=\"#2b5797\">\n<meta name=\"msapplication-TileImage\" content=\"/mstile-144x144.png\">\n<meta name=\"theme-color\" content=\"#ffffff\">","compression":"false","overlapping_markups":["link[rel=\"apple-touch-icon\"]","link[rel=\"shortcut\"]","link[rel=\"shortcut icon\"]","link[rel=\"icon\",sizes=\"16x16\"]","link[rel=\"icon\",sizes=\"32x32\"]","meta[name=\"msapplication-TileColor\"]","meta[name=\"msapplication-TileImage\"]","link[rel=\"manifest\"]","meta[name=\"theme-color\"]","link[rel=\"mask-icon\"]"]},"files_location":{"type":"path","path":"/"},"preview_picture_url":"https://realfavicongenerator.net/files/a14c093dfa827ba277aadc2d7a936885d5b564aa/favicon_preview.png","version":"0.16"}

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="-6.67 -6.67 37.33 37.33"><path d="M24 10.526v2.947H5.755l8.351 8.421-2.105 2.105-12-12 12-12 2.105 2.105-8.351 8.421H24z"/></svg>

Before

Width:  |  Height:  |  Size: 202 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="-6.67 -6.67 37.33 37.33"><path d="M18.035 10.526V6.035L24 12l-5.965 5.965v-4.491H0v-2.947h18.035z"/></svg>

Before

Width:  |  Height:  |  Size: 179 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="-6.67 -6.67 37.33 37.33"><path d="M15.268 4.392q.868 0 1.532.638t.664 1.506v17.463l-7.659-3.268-7.608 3.268V6.536q0-.868.664-1.506t1.532-.638h10.876zm4.34 14.144V4.392q0-.868-.638-1.532t-1.506-.664H6.537q0-.868.664-1.532T8.733 0h10.876q.868 0 1.532.664t.664 1.532v17.412z"/></svg>

Before

Width:  |  Height:  |  Size: 353 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="-6.67 -6.67 41.33 41.33"><path d="M9.917 24.5a1.75 1.75 0 10-3.501.001 1.75 1.75 0 003.501-.001zm0-21a1.75 1.75 0 10-3.501.001A1.75 1.75 0 009.917 3.5zm11.666 2.333a1.75 1.75 0 10-3.501.001 1.75 1.75 0 003.501-.001zm1.75 0a3.502 3.502 0 01-1.75 3.026c-.055 6.581-4.721 8.039-7.82 9.023-2.898.911-3.846 1.349-3.846 3.117v.474a3.502 3.502 0 011.75 3.026c0 1.932-1.568 3.5-3.5 3.5s-3.5-1.568-3.5-3.5c0-1.294.711-2.424 1.75-3.026V6.526A3.502 3.502 0 014.667 3.5c0-1.932 1.568-3.5 3.5-3.5s3.5 1.568 3.5 3.5a3.502 3.502 0 01-1.75 3.026v9.06c.93-.456 1.914-.766 2.807-1.039 3.391-1.075 5.323-1.878 5.359-5.687a3.502 3.502 0 01-1.75-3.026c0-1.932 1.568-3.5 3.5-3.5s3.5 1.568 3.5 3.5z"/></svg>

Before

Width:  |  Height:  |  Size: 757 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="-6.67 -6.67 45.33 45.33"><path d="M27.192 28.844V11.192H4.808v17.652h22.384zm0-25.689q1.277 0 2.253.976t.976 2.253v22.459q0 1.277-.976 2.216t-2.253.939H4.808q-1.352 0-2.291-.901t-.939-2.253V6.385q0-1.277.939-2.253t2.291-.976h1.577V.001h3.23v3.155h12.769V.001h3.23v3.155h1.577zm-3.155 11.267v3.155h-3.23v-3.155h3.23zm-6.46 0v3.155h-3.155v-3.155h3.155zm-6.384 0v3.155h-3.23v-3.155h3.23z"/></svg>

Before

Width:  |  Height:  |  Size: 466 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="-6.67 -6.67 45.33 45.33"><path d="M2.866 28.209h26.269v3.79H2.866v-3.79zm26.268-16.925L16 24.418 2.866 11.284h7.493V.001h11.283v11.283h7.493z"/></svg>

Before

Width:  |  Height:  |  Size: 223 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="-6.67 -6.67 45.33 45.33"><path d="M28.845 9.615v-3.23L16 14.422 3.155 6.385v3.23L16 17.577zm0-6.46q1.277 0 2.216.977T32 6.385v19.23q0 1.277-.939 2.253t-2.216.977H3.155q-1.277 0-2.216-.977T0 25.615V6.385q0-1.277.939-2.253t2.216-.977h25.69z"/></svg>

Before

Width:  |  Height:  |  Size: 320 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="-6.67 -6.67 45.33 45.33"><path d="M16 .394c8.833 0 15.999 7.166 15.999 15.999 0 7.062-4.583 13.062-10.937 15.187-.813.146-1.104-.354-1.104-.771 0-.521.021-2.25.021-4.396 0-1.5-.5-2.458-1.083-2.958 3.562-.396 7.312-1.75 7.312-7.896 0-1.75-.625-3.167-1.646-4.291.167-.417.708-2.042-.167-4.25-1.333-.417-4.396 1.646-4.396 1.646a15.032 15.032 0 00-8 0S8.937 6.602 7.603 7.018c-.875 2.208-.333 3.833-.167 4.25-1.021 1.125-1.646 2.542-1.646 4.291 0 6.125 3.729 7.5 7.291 7.896-.458.417-.875 1.125-1.021 2.146-.917.417-3.25 1.125-4.646-1.333-.875-1.521-2.458-1.646-2.458-1.646-1.562-.021-.104.979-.104.979 1.042.479 1.771 2.333 1.771 2.333.938 2.854 5.396 1.896 5.396 1.896 0 1.333.021 2.583.021 2.979 0 .417-.292.917-1.104.771C4.582 29.455-.001 23.455-.001 16.393-.001 7.56 7.165.394 15.998.394zM6.063 23.372c.042-.083-.021-.187-.146-.25-.125-.042-.229-.021-.271.042-.042.083.021.187.146.25.104.062.229.042.271-.042zm.646.709c.083-.062.062-.208-.042-.333-.104-.104-.25-.146-.333-.062-.083.062-.062.208.042.333.104.104.25.146.333.062zm.625.937c.104-.083.104-.25 0-.396-.083-.146-.25-.208-.354-.125-.104.062-.104.229 0 .375s.271.208.354.146zm.875.875c.083-.083.042-.271-.083-.396-.146-.146-.333-.167-.417-.062-.104.083-.062.271.083.396.146.146.333.167.417.062zm1.187.521c.042-.125-.083-.271-.271-.333-.167-.042-.354.021-.396.146s.083.271.271.312c.167.062.354 0 .396-.125zm1.313.104c0-.146-.167-.25-.354-.229-.187 0-.333.104-.333.229 0 .146.146.25.354.229.187 0 .333-.104.333-.229zm1.208-.208c-.021-.125-.187-.208-.375-.187-.187.042-.312.167-.292.312.021.125.187.208.375.167s.312-.167.292-.292z"/></svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="-6.67 -6.67 45.33 45.33"><path d="M16 29.714a1.11 1.11 0 01-.786-.321L4.072 18.643c-.143-.125-4.071-3.714-4.071-8 0-5.232 3.196-8.357 8.535-8.357 3.125 0 6.053 2.464 7.464 3.857 1.411-1.393 4.339-3.857 7.464-3.857 5.339 0 8.535 3.125 8.535 8.357 0 4.286-3.928 7.875-4.089 8.035L16.785 29.392c-.214.214-.5.321-.786.321z"/></svg>

Before

Width:  |  Height:  |  Size: 400 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="-6.67 -6.67 45.33 45.33"><path d="M24.037 7.963q3.305 0 5.634 2.366T32 16t-2.329 5.671-5.634 2.366h-6.46v-3.08h6.46q2.028 0 3.493-1.465t1.465-3.493-1.465-3.493-3.493-1.465h-6.46v-3.08h6.46zM9.615 17.578v-3.155h12.77v3.155H9.615zM3.005 16q0 2.028 1.465 3.493t3.493 1.465h6.46v3.08h-6.46q-3.305 0-5.634-2.366T0 16.001t2.329-5.671 5.634-2.366h6.46v3.08h-6.46q-2.028 0-3.493 1.465t-1.465 3.493z"/></svg>

Before

Width:  |  Height:  |  Size: 472 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="-6.67 -6.67 45.33 45.33"><path d="M.001 5.334h31.998v3.583H.001V5.334zm0 12.416v-3.5h31.998v3.5H.001zm0 8.916v-3.583h31.998v3.583H.001z"/></svg>

Before

Width:  |  Height:  |  Size: 217 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="-6.67 -6.67 41.33 41.33"><path d="M22.615 19.384l2.894 2.894v1.413H2.49v-1.413l2.894-2.894V12.25q0-3.365 1.716-5.856t4.745-3.231v-1.01q0-.875.606-1.514T13.999 0t1.548.639.606 1.514v1.01q3.029.74 4.745 3.231t1.716 5.856v7.134zM14 27.999q-1.211 0-2.053-.808t-.841-2.019h5.788q0 1.144-.875 1.986T14 27.999z"/></svg>

Before

Width:  |  Height:  |  Size: 385 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="-6.67 -6.67 41.33 41.33"><path d="M28 12.62h-9.793V8.414h-2.826v11.173h2.826v-4.206H28V26.62h-9.793v-4.206H12.62v-14H9.794v4.206H.001V1.381h9.793v4.206h8.413V1.381H28V12.62z"/></svg>

Before

Width:  |  Height:  |  Size: 255 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="-6.67 -6.67 45.33 45.33"><path d="M16 20.023q5.052 0 10.526 2.199t5.473 5.754v4.023H0v-4.023q0-3.555 5.473-5.754t10.526-2.199zM16 16q-3.275 0-5.614-2.339T8.047 8.047t2.339-5.661T16 0t5.614 2.386 2.339 5.661-2.339 5.614T16 16z"/></svg>

Before

Width:  |  Height:  |  Size: 307 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="-6.67 -6.67 45.33 45.33"><path d="M11.925 20.161q3.432 0 5.834-2.402t2.402-5.834-2.402-5.834-5.834-2.402-5.834 2.402-2.402 5.834 2.402 5.834 5.834 2.402zm10.981 0L32 29.255 29.255 32l-9.094-9.094v-1.458l-.515-.515q-3.26 2.831-7.721 2.831-4.976 0-8.45-3.432T.001 11.925t3.474-8.45 8.45-3.474 8.407 3.474 3.432 8.45q0 1.802-.858 4.075t-1.973 3.646l.515.515h1.458z"/></svg>

Before

Width:  |  Height:  |  Size: 443 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="-6.67 -6.67 41.33 41.33"><path d="M22.167 15.166V3.5h-8.166v20.726c.93-.492 2.424-1.349 3.883-2.497 1.95-1.531 4.284-3.919 4.284-6.562zm3.499-13.999v14c0 7.674-10.737 12.523-11.192 12.724-.146.073-.31.109-.474.109s-.328-.036-.474-.109c-.456-.201-11.192-5.049-11.192-12.724v-14C2.334.529 2.863 0 3.501 0H24.5c.638 0 1.167.529 1.167 1.167z"/></svg>

Before

Width:  |  Height:  |  Size: 419 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="-6.67 -6.67 41.33 41.33"><path d="M6.606 7.549c0-1.047-.84-1.887-1.887-1.887s-1.887.84-1.887 1.887.84 1.887 1.887 1.887 1.887-.84 1.887-1.887zm15.732 8.493c0 .501-.206.988-.546 1.327l-7.239 7.254c-.354.339-.84.546-1.342.546s-.988-.206-1.327-.546L1.342 14.066C.59 13.329 0 11.899 0 10.852V4.718a1.9 1.9 0 011.887-1.887h6.134c1.047 0 2.477.59 3.229 1.342L21.792 14.7c.339.354.546.84.546 1.342zm5.661 0c0 .501-.206.988-.546 1.327l-7.239 7.254c-.354.339-.84.546-1.342.546-.767 0-1.15-.354-1.651-.87l6.93-6.93c.339-.339.546-.826.546-1.327s-.206-.988-.546-1.342L13.609 4.173c-.752-.752-2.182-1.342-3.229-1.342h3.303c1.047 0 2.477.59 3.229 1.342L27.454 14.7c.339.354.546.84.546 1.342z"/></svg>

Before

Width:  |  Height:  |  Size: 759 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="-6.67 -6.67 37.33 37.33"><path d="M5.965 10.526V6.035L0 12l5.965 5.965v-4.491H24v-2.947H5.965z"/></svg>

Before

Width:  |  Height:  |  Size: 176 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="-6.67 -6.67 45.33 45.33"><path d="M25.875 28.25L22.125 32 6.126 16.001 22.125.002l3.75 3.75-12.25 12.25z"/></svg>

Before

Width:  |  Height:  |  Size: 186 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="-6.67 -6.67 45.33 45.33"><path d="M6.125 28.25L18.375 16 6.125 3.75 9.875 0l15.999 15.999L9.875 31.998z"/></svg>

Before

Width:  |  Height:  |  Size: 185 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="-2.67 -2.67 33.33 33.33"><path d="M15.905 13.355c.189 1.444-1.564 2.578-2.784 1.839-1.375-.602-1.375-2.784-.034-3.403 1.151-.705 2.818.223 2.818 1.564zm1.907-.361c-.309-2.44-3.076-4.056-5.328-3.042-1.426.636-2.389 2.148-2.32 3.747.086 2.097 2.08 3.815 4.176 3.626s3.729-2.234 3.472-4.331zm4.108-9.315c-.756-.997-2.045-1.169-3.179-1.358-3.214-.516-6.513-.533-9.727.034-1.066.172-2.269.361-2.939 1.323 1.1 1.031 2.664 1.186 4.073 1.358 2.544.327 5.156.344 7.699.017 1.426-.172 3.008-.309 4.073-1.375zm.979 17.788c-.481 1.684-.206 3.953-1.994 4.932-3.076 1.701-6.806 1.89-10.191 1.289-1.787-.327-3.884-.894-4.864-2.578-.43-1.65-.705-3.334-.98-5.018l.103-.275.309-.155c5.121 3.386 12.288 3.386 17.427 0 .808.241.206 1.22.189 1.805zM26.01 4.951c-.584 3.764-1.255 7.51-1.908 11.257-.189 1.1-1.255 1.719-2.148 2.183-3.214 1.615-6.96 1.89-10.483 1.512-2.389-.258-4.829-.894-6.771-2.389-.911-.705-.911-1.908-1.083-2.922-.602-3.523-1.289-7.046-1.719-10.604.206-1.547 1.942-2.217 3.231-2.698C6.848.654 8.686.362 10.508.19c3.884-.378 7.854-.241 11.618.859 1.341.395 2.784.945 3.695 2.097.412.533.275 1.203.189 1.805z"/></svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="-2.67 -2.67 33.33 33.33"><path d="M27.472 12.753L15.247.529a1.803 1.803 0 00-2.55 0l-2.84 2.84 2.137 2.137a2.625 2.625 0 013.501 3.501l3.499 3.499a2.625 2.625 0 11-1.237 1.237l-3.499-3.499c-.083.04-.169.075-.257.106v7.3a2.626 2.626 0 11-1.75 0v-7.3a2.626 2.626 0 01-1.494-3.607L8.62 4.606l-8.09 8.09a1.805 1.805 0 000 2.551l12.225 12.224a1.803 1.803 0 002.55 0l12.168-12.168a1.805 1.805 0 000-2.551z"/></svg>

Before

Width:  |  Height:  |  Size: 481 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="-2.67 -2.67 33.33 33.33"><path d="M1.629 11.034L14 26.888.442 17.048a1.09 1.09 0 01-.39-1.203l1.578-4.811zm7.217 0h10.309l-5.154 15.854zM5.753 1.475l3.093 9.559H1.63l3.093-9.559a.548.548 0 011.031 0zm20.618 9.559l1.578 4.811c.141.437-.016.922-.39 1.203l-13.558 9.84 12.371-15.854zm0 0h-7.216l3.093-9.559a.548.548 0 011.031 0z"/></svg>

Before

Width:  |  Height:  |  Size: 407 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="-2.29 -2.29 32.57 32.57"><path d="M14 21.435q3.079 0 5.257-2.178T21.435 14t-2.178-5.257T14 6.565q-1.51 0-3.079.697 1.917.871 3.108 2.701T15.22 14t-1.191 4.037-3.108 2.701q1.568.697 3.079.697zm9.933-11.559L27.999 14l-4.066 4.124v5.809h-5.809L14 27.999l-4.124-4.066H4.067v-5.809L.001 14l4.066-4.124V4.067h5.809L14 .001l4.124 4.066h5.809v5.809z"/></svg>

Before

Width:  |  Height:  |  Size: 422 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="-2.29 -2.29 32.57 32.57"><path d="M14 21.435q3.079 0 5.257-2.178T21.435 14t-2.178-5.257T14 6.565 8.743 8.743 6.565 14t2.178 5.257T14 21.435zm9.933-3.311v5.809h-5.809L14 27.999l-4.124-4.066H4.067v-5.809L.001 14l4.066-4.124V4.067h5.809L14 .001l4.124 4.066h5.809v5.809L27.999 14z"/></svg>

Before

Width:  |  Height:  |  Size: 357 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="-2.29 -2.29 32.57 32.57"><path d="M16.846 18.938h2.382L15.22 7.785h-2.44L8.772 18.938h2.382l.871-2.44h3.95zm7.087-9.062L27.999 14l-4.066 4.124v5.809h-5.809L14 27.999l-4.124-4.066H4.067v-5.809L.001 14l4.066-4.124V4.067h5.809L14 .001l4.124 4.066h5.809v5.809zm-11.385 4.937L14 10.282l1.452 4.531h-2.904z"/></svg>

Before

Width:  |  Height:  |  Size: 381 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="-2.29 -2.29 32.57 32.57"><path d="M3.281 5.36L14 16.079 24.719 5.36 28 8.641l-14 14-14-14z"/></svg>

Before

Width:  |  Height:  |  Size: 171 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="-2.29 -2.29 32.57 32.57"><path d="M24.719 22.64L14 11.921 3.281 22.64 0 19.359l14-14 14 14z"/></svg>

Before

Width:  |  Height:  |  Size: 172 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="-2.29 -2.29 32.57 32.57"><path d="M24.003 15.695v8.336c0 .608-.504 1.111-1.111 1.111h-6.669v-6.669h-4.446v6.669H5.108a1.119 1.119 0 01-1.111-1.111v-8.336c0-.035.017-.069.017-.104L14 7.359l9.986 8.232a.224.224 0 01.017.104zm3.873-1.198l-1.077 1.285a.578.578 0 01-.365.191h-.052a.547.547 0 01-.365-.122L14 5.831 1.983 15.851a.594.594 0 01-.417.122.578.578 0 01-.365-.191L.124 14.497a.57.57 0 01.069-.781L12.679 3.314c.729-.608 1.91-.608 2.64 0l4.237 3.543V3.471c0-.313.243-.556.556-.556h3.334c.313 0 .556.243.556.556v7.085l3.803 3.161c.226.191.26.556.069.781z"/></svg>

Before

Width:  |  Height:  |  Size: 638 B

View File

@ -1,21 +1,31 @@
import { applyTheme } from "./darkmode"
import { createCopyButton } from "./copycode.js"
import Clipboard from "clipboard"
;(() => {
applyTheme()
})()
document.addEventListener("DOMContentLoaded", function (event) { document.addEventListener("DOMContentLoaded", function (event) {
var clipboard = new ClipboardJS(".clip"); let clipboard = new Clipboard(".clip")
clipboard.on("success", function (e) { clipboard.on("success", function (e) {
const trigger = e.trigger; const trigger = e.trigger
if (trigger.hasAttribute("data-copy-feedback")) { if (trigger.hasAttribute("data-copy-feedback")) {
trigger.classList.add("gdoc-post__codecopy--success"); trigger.classList.add("gdoc-post__codecopy--success")
trigger.querySelector(".icon.copy").classList.add("hidden"); trigger.querySelector(".icon.copy").classList.add("hidden")
trigger.querySelector(".icon.check").classList.remove("hidden"); trigger.querySelector(".icon.check").classList.remove("hidden")
setTimeout(function () { setTimeout(function () {
trigger.classList.remove("gdoc-post__codecopy--success"); trigger.classList.remove("gdoc-post__codecopy--success")
trigger.querySelector(".icon.copy").classList.remove("hidden"); trigger.querySelector(".icon.copy").classList.remove("hidden")
trigger.querySelector(".icon.check").classList.add("hidden"); trigger.querySelector(".icon.check").classList.add("hidden")
}, 3000); }, 3000)
} }
e.clearSelection(); e.clearSelection()
}); })
});
document.querySelectorAll(".highlight").forEach((highlightDiv) => createCopyButton(highlightDiv))
})

5
src/js/config.js Normal file
View File

@ -0,0 +1,5 @@
export const DARK_MODE = "dark"
export const LIGHT_MODE = "light"
export const AUTO_MODE = "auto"
export const THEME = "hugo-geekdoc"
export const TOGGLE_MODES = [AUTO_MODE, DARK_MODE, LIGHT_MODE]

View File

@ -1,34 +1,23 @@
function createCopyButton(highlightDiv) { export function createCopyButton(highlightDiv) {
const button = document.createElement("span"); const button = document.createElement("span")
let selector = "pre > code"
if (highlightDiv.querySelector(".lntable")) { if (highlightDiv.querySelector(".lntable")) {
selector = ".lntable .lntd:last-child pre > code"; selector = ".lntable .lntd:last-child pre > code"
} else {
selector = "pre > code";
} }
const codeToCopy = highlightDiv.querySelector(selector).innerText.trim(); const codeToCopy = highlightDiv.querySelector(selector).innerText.trim()
button.classList.add( button.classList.add("flex", "align-center", "justify-center", "clip", "gdoc-post__codecopy")
"flex", button.type = "button"
"align-center",
"justify-center",
"clip",
"gdoc-post__codecopy"
);
button.type = "button";
button.innerHTML = button.innerHTML =
'<svg class="icon copy"><use xlink:href="#gdoc_copy"></use></svg>' + '<svg class="icon copy"><use xlink:href="#gdoc_copy"></use></svg>' +
'<svg class="icon check hidden"><use xlink:href="#gdoc_check"></use></svg>'; '<svg class="icon check hidden"><use xlink:href="#gdoc_check"></use></svg>'
button.setAttribute("data-clipboard-text", codeToCopy); button.setAttribute("data-clipboard-text", codeToCopy)
button.setAttribute("data-copy-feedback", "Copied!"); button.setAttribute("data-copy-feedback", "Copied!")
button.setAttribute("role", "button"); button.setAttribute("role", "button")
button.setAttribute("aria-label", "Copy"); button.setAttribute("aria-label", "Copy")
highlightDiv.classList.add("gdoc-post__codecontainer"); highlightDiv.classList.add("gdoc-post__codecontainer")
highlightDiv.insertBefore(button, highlightDiv.firstChild); highlightDiv.insertBefore(button, highlightDiv.firstChild)
} }
document
.querySelectorAll(".highlight")
.forEach((highlightDiv) => createCopyButton(highlightDiv));

View File

@ -1,51 +1,53 @@
const DARK_MODE = "dark"; import Storage from "store2"
const LIGHT_MODE = "light";
const AUTO_MODE = "auto";
const THEME = "hugo-geekdoc";
const TOGGLE_MODES = [AUTO_MODE, DARK_MODE, LIGHT_MODE]; import { TOGGLE_MODES, THEME, AUTO_MODE } from "./config.js"
(applyTheme = function (init = true) { document.addEventListener("DOMContentLoaded", (event) => {
let html = document.documentElement; const darkModeToggle = document.getElementById("gdoc-dark-mode")
let currentMode = TOGGLE_MODES.includes(localStorage.getItem(THEME))
? localStorage.getItem(THEME)
: AUTO_MODE;
html.setAttribute("class", "color-toggle-" + currentMode); darkModeToggle.onclick = function () {
localStorage.setItem(THEME, currentMode); let lstore = Storage.namespace(THEME)
let currentMode = lstore.get("color-mode")
let nextMode = toggle(TOGGLE_MODES, currentMode)
lstore.set("color-mode", TOGGLE_MODES[nextMode])
applyTheme(false)
}
})
export function applyTheme(init = true) {
if (Storage.isFake()) return
let lstore = Storage.namespace(THEME)
let html = document.documentElement
let currentMode = TOGGLE_MODES.includes(lstore.get("color-mode"))
? lstore.get("color-mode")
: AUTO_MODE
html.setAttribute("class", "color-toggle-" + currentMode)
lstore.set("color-mode", currentMode)
if (currentMode === AUTO_MODE) { if (currentMode === AUTO_MODE) {
html.removeAttribute("color-mode"); html.removeAttribute("color-mode")
} else { } else {
html.setAttribute("color-mode", currentMode); html.setAttribute("color-mode", currentMode)
} }
if (!init) { if (!init) {
// Reload required to re-initialise e.g. Mermaid with the new theme and re-parse the Mermaid code blocks. // Reload required to re-initialise e.g. Mermaid with the new theme
location.reload(); // and re-parse the Mermaid code blocks.
location.reload()
} }
})(); }
document.addEventListener("DOMContentLoaded", (event) => {
const darkModeToggle = document.getElementById("gdoc-dark-mode");
darkModeToggle.onclick = function () {
let currentMode = localStorage.getItem(THEME);
let nextMode = toggle(TOGGLE_MODES, currentMode);
localStorage.setItem(THEME, TOGGLE_MODES[nextMode]);
applyTheme(false);
};
});
function toggle(list = [], value) { function toggle(list = [], value) {
current = list.indexOf(value); let current = list.indexOf(value)
max = list.length - 1; let max = list.length - 1
next = 0; let next = 0
if (current < max) { if (current < max) {
next = current + 1; next = current + 1
} }
return next; return next
} }

View File

@ -7,30 +7,25 @@
* strings for iteratees. * strings for iteratees.
*/ */
const groupBy = (e, ...t) => { export const groupBy = (e, ...t) => {
let r = e.map((e) => t.map((t) => t(e))), let r = e.map((e) => t.map((t) => t(e))),
a = {}; a = {}
return ( return (
r.forEach((t, r) => { r.forEach((t, r) => {
let l = (_simpleAt(a, t) || []).concat([e[r]]); let l = (_simpleAt(a, t) || []).concat([e[r]])
_simpleSet(a, t, l); _simpleSet(a, t, l)
}), }),
a a
); )
}, },
_isPlainObject = (e) => _isPlainObject = (e) => null != e && "object" == typeof e && e.constructor == Object,
null != e && "object" == typeof e && e.constructor == Object,
_parsePath = (e) => (Array.isArray(e) ? e : `${e}`.split(".")), _parsePath = (e) => (Array.isArray(e) ? e : `${e}`.split(".")),
_simpleAt = (e, t) => _simpleAt = (e, t) =>
_parsePath(t).reduce( _parsePath(t).reduce((e, t) => (null != e && e.hasOwnProperty(t) ? e[t] : void 0), e),
(e, t) => (null != e && e.hasOwnProperty(t) ? e[t] : void 0),
e
),
_simpleSet = (e, t, r) => _simpleSet = (e, t, r) =>
_parsePath(t).reduce((e, t, a, l) => { _parsePath(t).reduce((e, t, a, l) => {
let s = a === l.length - 1; let s = a === l.length - 1
return ( return (
(e.hasOwnProperty(t) && (s || _isPlainObject(e[t]))) || (e[t] = {}), (e.hasOwnProperty(t) && (s || _isPlainObject(e[t]))) || (e[t] = {}), s ? (e[t] = r) : e[t]
s ? (e[t] = r) : e[t] )
); }, e)
}, e);

View File

@ -1,3 +0,0 @@
document.addEventListener("DOMContentLoaded", function () {
renderMathInElement(document.body);
});

9
src/js/katex.js Normal file
View File

@ -0,0 +1,9 @@
import "katex/dist/katex.css"
document.addEventListener("DOMContentLoaded", function () {
import("katex/dist/contrib/auto-render")
.then(({ default: renderMathInElement }) => {
renderMathInElement(document.body)
})
.catch((error) => console.error(error))
})

View File

@ -1,23 +0,0 @@
document.addEventListener("DOMContentLoaded", function (event) {
let currentMode = localStorage.getItem(THEME);
let darkModeQuery = window.matchMedia("(prefers-color-scheme: dark)");
let primaryColor = "#ececff";
let darkMode = false;
if (
currentMode === DARK_MODE ||
(currentMode === AUTO_MODE && darkModeQuery.matches)
) {
primaryColor = "#6C617E";
darkMode = true;
}
mermaid.initialize({
flowchart: { useMaxWidth: true },
theme: "base",
themeVariables: {
darkMode: darkMode,
primaryColor: primaryColor,
},
});
});

29
src/js/mermaid.js Normal file
View File

@ -0,0 +1,29 @@
import Storage from "store2"
import { DARK_MODE, THEME, AUTO_MODE } from "./config.js"
document.addEventListener("DOMContentLoaded", function (event) {
let lstore = Storage.namespace(THEME)
let currentMode = lstore.get("color-mode")
let darkModeQuery = window.matchMedia("(prefers-color-scheme: dark)")
let primaryColor = "#ececff"
let darkMode = false
if (currentMode === DARK_MODE || (currentMode === AUTO_MODE && darkModeQuery.matches)) {
primaryColor = "#6C617E"
darkMode = true
}
import("mermaid")
.then(({ default: md }) => {
md.initialize({
flowchart: { useMaxWidth: true },
theme: "base",
themeVariables: {
darkMode: darkMode,
primaryColor: primaryColor
}
})
})
.catch((error) => console.error(error))
})

200
src/js/search.js Normal file
View File

@ -0,0 +1,200 @@
const { groupBy } = require("./groupBy")
const FlexSearch = require("flexsearch")
const Ajv = require("ajv")
document.addEventListener("DOMContentLoaded", function (event) {
const ajv = new Ajv()
const input = document.querySelector("#gdoc-search-input")
const results = document.querySelector("#gdoc-search-results")
const configSchema = {
type: "object",
properties: {
dataFile: {
type: "string"
},
indexConfig: {
type: ["object", "null"]
},
showParent: {
type: "boolean"
}
},
additionalProperties: false
}
getJson("/searchconfig.json", function (searchConfig) {
const configValidate = ajv.compile(configSchema)
const valid = configValidate(searchConfig)
if (!valid)
throw AggregateError(
configValidate.errors.map(
(err) =>
new Error(["Validation error:", err.instancePath, err.keyword, err.message].join(" "))
),
"Schema validation failed"
)
if (input) {
input.addEventListener("focus", () => {
init(input, searchConfig)
})
input.addEventListener("keyup", () => {
search(input, results, searchConfig)
})
}
})
})
function init(input, searchConfig) {
input.removeEventListener("focus", init)
const indexCfgDefaults = {
tokenize: "forward"
}
const indexCfg = searchConfig.indexConfig ? searchConfig.indexConfig : indexCfgDefaults
const dataUrl = searchConfig.dataFile
indexCfg.document = {
key: "id",
index: ["title", "content"],
store: ["title", "href", "parent"]
}
const index = new FlexSearch.Document(indexCfg)
window.geekdocSearchIndex = index
getJson(dataUrl, function (data) {
data.forEach((obj) => {
window.geekdocSearchIndex.add(obj)
})
})
}
function search(input, results, searchConfig) {
const searchCfg = {
enrich: true,
limit: 10
}
while (results.firstChild) {
results.removeChild(results.firstChild)
}
if (!input.value) {
return results.classList.remove("has-hits")
}
let searchHits = flattenHits(window.geekdocSearchIndex.search(input.value, searchCfg))
if (searchHits.length < 1) {
return results.classList.remove("has-hits")
}
results.classList.add("has-hits")
if (searchConfig.showParent === true) {
searchHits = groupBy(searchHits, (hit) => hit.parent)
}
const items = []
if (searchConfig.showParent === true) {
for (const section in searchHits) {
const item = document.createElement("li"),
title = item.appendChild(document.createElement("span")),
subList = item.appendChild(document.createElement("ul"))
title.textContent = section
createLinks(searchHits[section], subList)
items.push(item)
}
} else {
const item = document.createElement("li"),
title = item.appendChild(document.createElement("span")),
subList = item.appendChild(document.createElement("ul"))
title.textContent = "Results"
createLinks(searchHits, subList)
items.push(item)
}
items.forEach((item) => {
results.appendChild(item)
})
}
/**
* Creates links to given fields and either returns them in an array or attaches them to a target element
* @param {Object} fields Page to which the link should point to
* @param {HTMLElement} target Element to which the links should be attatched
* @returns {Array} If target is not specified, returns an array of built links
*/
function createLinks(pages, target) {
const items = []
for (const page of pages) {
const item = document.createElement("li"),
entry = item.appendChild(document.createElement("span")),
a = entry.appendChild(document.createElement("a"))
entry.classList.add("flex")
a.href = page.href
a.textContent = page.title
a.classList.add("gdoc-search__entry")
if (target) {
target.appendChild(item)
continue
}
items.push(item)
}
return items
}
function fetchErrors(response) {
if (!response.ok) {
throw Error("Failed to fetch '" + response.url + "': " + response.statusText)
}
return response
}
function getJson(src, callback) {
fetch(src)
.then(fetchErrors)
.then((response) => response.json())
.then((json) => callback(json))
.catch(function (error) {
if (error instanceof AggregateError) {
console.error(error.message)
error.errors.forEach((element) => {
console.error(element)
})
} else {
console.error(error)
}
})
}
function flattenHits(results) {
const items = []
const map = new Map()
for (const field of results) {
for (const page of field.result) {
if (!map.has(page.doc.href)) {
map.set(page.doc.href, true)
items.push(page.doc)
}
}
}
return items
}

Some files were not shown because too many files have changed in this diff Show More