huge upgrade to theme and pagefind search bar.

This commit is contained in:
2026-04-17 13:28:48 -06:00
parent a6a38f7ea7
commit 235d40da0b
442 changed files with 18933 additions and 2893 deletions

View File

@@ -0,0 +1,14 @@
/*
You can add custom styles here.
It could be plugins:
@import "plugins/numbered";
@import "plugins/scrollbars";
Or custom styles:
body { background: white; }
Or even theme mixins:
@mixin theme-light {
--body-background: white;
--body-font-color: black;
...
}
*/

View File

@@ -0,0 +1,99 @@
// Used in layout
$padding-1: 1px !default;
$padding-4: 0.25rem !default;
$padding-8: 0.5rem !default;
$padding-16: 1rem !default;
$body-min-width: 20rem !default;
$container-max-width: 80rem !default;
$menu-width: 16rem !default;
$toc-width: 16rem !default;
$mobile-breakpoint: $menu-width + $body-min-width * 1.2 + $toc-width !default;
:root {
--font-size: 16px;
--font-size-smaller: 0.875rem;
--font-size-smallest: 0.75rem;
--body-font-weight: 400;
--body-background: white;
--body-background-tint: transparent;
--body-font-color: black;
// --pagefind-ui-background: #84DE02;
--border-radius: 0.25rem;
}
// Themes
@mixin theme-light {
--body-background: white;
--body-background-tint: none;
--body-font-color: black;
--color-link: #0055bb;
--color-visited-link: #5500bb;
--icon-filter: none;
--gray-100: #f8f9fa;
--gray-200: #e9ecef;
--gray-500: #adb5bd;
// --pagefind-ui-background: #84DE02;
@include accent("default", #64748b);
@include accent("note", #4486dd);
@include accent("tip", #3bad3b);
@include accent("important", #8144dd);
@include accent("warning", #f59e42);
@include accent("caution", #d84747);
// Fallback for {{< hint >}} shortcodes
@include accent("info", #4486dd);
@include accent("success", #3bad3b);
@include accent("danger", #d84747);
}
@mixin theme-dark {
--body-background: #343a40;
--body-background-tint: none;
--body-font-color: #e9ecef;
--color-link: #84b2ff;
--color-visited-link: #b88dff;
--icon-filter: brightness(0) invert(1);
--gray-100: #494e54;
--gray-200: #5c6165;
--gray-500: #999d9f;
@include accent("default", #64748b);
@include accent("note", #4486dd);
@include accent("tip", #3bad3b);
@include accent("important", #8144dd);
@include accent("warning", #f59e42);
@include accent("caution", #d84747);
// Fallback for {{< hint >}} shortcodes
@include accent("info", #4486dd);
@include accent("success", #3bad3b);
@include accent("danger", #d84747);
}
@mixin theme-auto {
@include theme-light;
@media (prefers-color-scheme: dark) {
@include theme-dark;
}
}
// Convenience mixing to declare a color and a transparent tint
@mixin accent($name, $color, $tint: 0.1) {
--color-accent-#{$name}: #{$color};
--color-accent-#{$name}-tint: #{rgba($color, $tint)};
}

View File

@@ -0,0 +1,5 @@
/*
This is an empty file for backward compatibility.
Custom font used to be defined here.
It will be removed eventually.
*/

View File

@@ -0,0 +1,442 @@
html {
font-size: var(--font-size);
scroll-behavior: smooth;
touch-action: manipulation;
scrollbar-gutter: stable;
}
body {
min-width: $body-min-width;
color: var(--body-font-color);
background: var(--body-background) var(--body-background-tint);
font-weight: var(--body-font-weight);
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-weight: inherit;
}
a {
flex: auto;
align-items: center;
gap: .5em;
text-decoration: none;
cursor: default;
&[href], &[role=button] {
color: var(--color-link);
cursor: pointer;
}
}
small {
@extend .text-small;
}
:focus-visible, input.toggle:focus-visible + label {
@include outline;
}
nav ul {
padding: 0;
margin: 0;
list-style: none;
li {
position: relative;
}
a {
padding: 0.5em 0;
display: flex;
transition: opacity 0.1s ease-in-out;
}
a[href]:hover, a[role=button]:hover {
opacity: 0.5;
}
ul {
padding-inline-start: 1.5em;
}
}
ul.pagination {
display: flex;
justify-content: center;
list-style-type: none;
padding-inline-start: 0px;
.page-item a {
padding: $padding-16;
}
}
.container {
max-width: $container-max-width;
margin: 0 auto;
}
.book-icon {
filter: var(--icon-filter);
}
a .book-icon {
height: 1em;
width: 1em;
}
.book-brand {
margin-top: 0;
margin-bottom: $padding-16;
img {
height: 1.5em;
width: 1.5em;
}
}
.book-menu {
flex: 0 0 $menu-width;
font-size: var(--font-size-smaller);
.book-menu-content {
width: $menu-width;
padding: $padding-16;
@include fixed;
}
a, label {
color: inherit;
word-wrap: break-word;
display: flex;
}
a.active {
color: var(--color-link);
}
label > img:last-child {
height: 1em;
width: 1em;
cursor: pointer;
align-self: center;
transition: transform 0.1s ease-in-out;
}
input.toggle + label + ul {
display: none;
}
input.toggle:checked + label {
> img:last-child {
transform: rotate(90deg);
}
+ ul {
display: block;
}
}
}
// for RTL support
body[dir="rtl"] .book-menu {
input.toggle + label > img:last-child {
transform: rotate(180deg);
}
input.toggle:checked + label > img:last-child {
transform: rotate(90deg);
}
}
.book-section-flat {
margin: $padding-16 0;
> a,
> span,
> label {
font-weight: bolder;
}
> ul {
padding-inline-start: 0;
}
}
.book-page {
min-width: $body-min-width;
flex-grow: 1;
padding: $padding-16;
}
.book-post {
margin-bottom: $padding-16 * 4;
.book-post-date img {
height: 1em;
width: 1em;
margin-inline-end: .5em;
}
.book-post-content {
margin-top: $padding-16;
}
.book-post-thumbnail {
flex: 0 0 34%;
img {
width: 100%;
aspect-ratio: 4 / 3;
object-fit: cover;
}
}
}
.book-header {
margin-bottom: $padding-16;
label {
line-height: 0;
}
h3 {
overflow: hidden;
text-overflow: ellipsis;
margin: 0 $padding-16;
}
}
.book-layout-landing .book-header {
display: block;
position: relative;
z-index: 1;
nav > ul {
display: flex;
gap: $padding-16;
justify-content: end;
> li {
display: block;
white-space: nowrap;
> ul {
display: none;
position: absolute;
padding: 0;
}
&:hover > ul, &:focus-within > ul {
display: block;
}
}
}
}
.pagefind-ui {
// --pagefind-ui-background: #84DE02;
// --pagefind-ui-text: #0048BA;
// --pagefind-ui-text: var(--body-font-color);
--pagefind-ui-border: var(--gray-100);
--pagefind-ui-background: var(--gray-100);
--pagefind-ui-text: var(--gray-500);
}
.book-search {
position: relative;
margin: $padding-8 0;
input {
width: 100%;
padding: $padding-8;
border: $padding-1 solid var(--gray-200);
border-radius: var(--border-radius);
background: var(--gray-100);
color: var(--body-font-color);
&:required + .book-search-spinner {
display: block;
}
}
.book-search-spinner {
position: absolute;
top: 0;
margin: $padding-8;
margin-inline-start: calc(100% - #{$padding-16 + $padding-8});
width: $padding-16;
height: $padding-16;
border: $padding-1 solid transparent;
border-top-color: var(--body-font-color);
border-radius: 50%;
@include spin(1s);
}
ul a {
padding-bottom: 0;
}
small {
opacity: 0.5;
}
}
.book-toc {
flex: 0 0 $toc-width;
font-size: var(--font-size-smallest);
.book-toc-content {
width: $toc-width;
padding: $padding-16;
@include fixed;
}
a {
display: block;
}
img {
height: 1em;
width: 1em;
}
nav > ul > li:first-child {
margin-top: 0;
}
}
.book-footer {
padding-top: $padding-16;
font-size: var(--font-size-smaller);
a {
margin: $padding-4 0;
padding: $padding-4 0;
}
}
.book-comments {
margin-top: $padding-16;
}
.book-copyright {
margin-top: $padding-16;
}
.book-languages {
margin-bottom: $padding-16;
span {
padding: 0;
}
ul {
padding-inline-start: 1.5em;
}
}
// Responsive styles
.book-menu-content,
.book-toc-content {
transition: 0.2s ease-in-out;
transition-property: transform, margin, opacity, visibility;
will-change: transform, margin, opacity;
}
@media screen and (max-width: $mobile-breakpoint) {
.book-menu {
visibility: hidden;
margin-inline-start: -$menu-width;
z-index: 1;
.book-menu-content {
background: var(--body-background);
}
}
.book-toc {
display: none;
}
.book-header {
display: block;
}
.book-post-container {
flex-direction: column-reverse;
}
#menu-control,
#toc-control {
display: inline;
}
#menu-control:checked ~ main {
.book-menu {
visibility: initial;
}
.book-menu .book-menu-content {
transform: translateX($menu-width);
box-shadow: 0 0 $padding-8 rgba(0, 0, 0, 0.1);
}
.book-page {
opacity: 0.25;
}
.book-menu-overlay {
display: block;
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
}
#toc-control:checked ~ main {
.book-header aside {
display: block;
}
}
// for RTL support
body[dir="rtl"] #menu-control:checked ~ main {
.book-menu .book-menu-content {
transform: translateX(-$menu-width);
}
}
}
// Extra space for big screens
@media screen and (min-width: $container-max-width) {
.book-page,
.book-menu .book-menu-content,
.book-toc .book-toc-content {
padding: $padding-16 * 2 $padding-16;
}
}

View File

@@ -0,0 +1,233 @@
@import "variables";
.markdown {
line-height: 1.6;
// remove padding at the beginning of page
> :first-child {
margin-top: 0;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-weight: inherit;
line-height: 1;
margin-top: 1.5em;
margin-bottom: $padding-16;
a.anchor {
opacity: 0;
font-size: 0.75em;
margin-inline-start: .25em;
}
&:hover a.anchor, a.anchor:focus-visible {
opacity: initial;
text-decoration: none;
}
}
h1 { font-size: 2rem; }
h2 { font-size: 1.5rem; }
h3 { font-size: 1.25rem; }
h4 { font-size: 1.125rem; }
h5 { font-size: 1rem; }
h6 { font-size: 0.875rem; }
b,
optgroup,
strong {
font-weight: bolder;
}
a {
text-decoration: none;
&[href]:hover {
text-decoration: underline;
}
&[href]:visited {
color: var(--color-visited-link);
}
}
img {
max-width: 100%;
height: auto;
}
code {
direction: ltr;
unicode-bidi: embed;
padding: .125em .25em;
background: var(--gray-100);
border: $padding-1 solid var(--gray-200);
border-radius: var(--border-radius);
font-size: 0.875em;
}
pre {
padding: $padding-16;
background: var(--gray-100);
border: $padding-1 solid var(--gray-200);
border-radius: var(--border-radius);
overflow-x: auto;
&:focus {
@include outline;
}
code {
padding: 0;
border: 0;
background: none;
}
}
p {
word-wrap: break-word;
}
blockquote {
margin: $padding-16 0;
padding: $padding-8 $padding-16 $padding-8 ($padding-16 - $padding-4); //to keep total left space 16dp
border-inline-start: $padding-4 solid var(--gray-200);
border-radius: var(--border-radius);
:first-child {
margin-top: 0;
}
:last-child {
margin-bottom: 0;
}
}
table {
overflow: auto;
display: block;
border-spacing: 0;
border-collapse: collapse;
margin-top: $padding-16;
margin-bottom: $padding-16;
tr th,
tr td {
padding: $padding-8 $padding-16;
border: $padding-1 solid var(--gray-200);
text-align: start;
}
tr:nth-child(2n) {
background: var(--gray-100);
}
}
hr {
height: $padding-1;
border: none;
background: var(--gray-200);
}
ul,
ol {
padding-inline-start: $padding-16 * 2;
word-wrap: break-word;
}
dl {
dt {
font-weight: bolder;
margin-top: $padding-16;
}
dd {
margin-inline-start: 0;
margin-bottom: $padding-16;
}
}
// Special case for highlighted code with line numbers
.highlight {
direction: ltr;
unicode-bidi: embed;
border-radius: var(--border-radius);
table tbody {
border: $padding-1 solid var(--gray-200);
}
table tr {
pre {
border: 0;
}
td pre code > span {
display: flex;
}
td:nth-child(1) pre {
margin: 0;
padding-inline-end: 0;
}
td:nth-child(2) pre {
margin: 0;
padding-inline-start: 0;
}
}
}
details {
padding: $padding-16;
margin: $padding-16 0;
border: $padding-1 solid var(--gray-200);
border-radius: var(--border-radius);
summary {
line-height: 1;
padding: $padding-16;
margin: -$padding-16;
cursor: pointer;
list-style: none;
&::before {
content: "";
display: inline-block;
margin-inline-end: $padding-8;
transition: transform 0.1s ease-in-out;
}
}
&[open] summary {
margin-bottom: 0;
&::before {
transform: rotate(90deg);
}
}
}
figure {
margin: $padding-16 0;
figcaption {
@extend .markdown-inner;
margin-top: $padding-16;
}
}
}
.markdown-inner {
// Utility class to remove extra margin in nested markdown content
> :first-child {
margin-top: 0;
}
> :last-child {
margin-bottom: 0;
}
}

View File

@@ -0,0 +1,17 @@
@media print {
.book-menu,
.book-footer,
.book-toc {
display: none;
}
.book-header,
.book-header aside {
display: block;
}
main {
// Fix for https://bugzilla.mozilla.org/show_bug.cgi?id=939897
display: block !important;
}
}

View File

@@ -0,0 +1,254 @@
.markdown {
// {{< tabs >}}
.book-tabs {
margin-top: $padding-16;
margin-bottom: $padding-16;
border: $padding-1 solid var(--gray-200);
border-radius: var(--border-radius);
display: flex;
flex-wrap: wrap;
label {
display: inline-block;
padding: $padding-8 $padding-16;
border-bottom: $padding-1 transparent;
cursor: pointer;
}
.book-tabs-content {
order: 999; //Move content blocks to the end
width: 100%;
border-top: $padding-1 solid var(--gray-100);
padding: $padding-16;
display: none;
}
input[type="radio"]:checked+label {
border-bottom: $padding-1 solid var(--color-link);
}
input[type="radio"]:checked+label+.book-tabs-content {
display: block;
}
}
// {{< columns >}}
.book-columns {
gap: $padding-16;
>div {
margin: $padding-16 0;
min-width: $body-min-width * 0.66;
}
>ul {
list-style: none;
display: flex;
padding: 0;
flex-wrap: wrap;
gap: $padding-16;
>li {
flex: 1 1;
min-width: $body-min-width * 0.66;
}
}
}
// {{< button >}}
a.book-btn[href] {
display: inline-block;
font-size: var(--font-size-smaller);
color: var(--color-link);
line-height: $padding-16 * 2;
padding: 0 $padding-16;
border: $padding-1 solid var(--color-link);
border-radius: var(--border-radius);
cursor: pointer;
&:hover {
text-decoration: none;
}
}
.book-hint {
@each $name in (note, tip, important, warning, caution, default, info, success, danger) {
&.#{$name} {
border-color: var(--color-accent-#{$name});
background-color: var(--color-accent-#{$name}-tint);
}
}
}
// {{< badge >}}
.book-badge {
@each $name in (note, tip, important, warning, caution, default, info, success, danger) {
&.#{$name} {
--accent-color: var(--color-accent-#{$name});
}
}
display: inline-block;
font-size: var(--font-size-smaller);
font-weight: var(--body-font-weight);
vertical-align: middle;
border-radius: var(--border-radius);
border: $padding-1 solid var(--accent-color);
overflow: hidden;
text-wrap: nowrap;
color: var(--body-font-color);
span {
display: inline-block;
padding: 0 $padding-8;
}
span.book-badge-value {
color: var(--body-background);
background-color: var(--accent-color);
}
}
// {{< steps >}}
.book-steps {
position: relative;
>ol {
counter-reset: steps;
list-style: none;
padding-inline-start: $padding-16 + $padding-4;
margin-top: $padding-16 * 2;
>li::before {
content: counter(steps);
counter-increment: steps;
position: absolute;
display: flex;
justify-content: center;
left: $padding-8;
height: $padding-16 * 1.5;
width: $padding-16 * 1.5;
padding: $padding-4;
border-radius: $padding-8;
white-space: nowrap;
line-height: $padding-16;
color: var(--body-background);
background: var(--gray-500);
outline: $padding-4 solid var(--body-background);
}
>li {
@extend .markdown-inner;
border-inline-start: $padding-1 solid var(--gray-500);
padding-inline-start: $padding-16 * 3;
padding-bottom: $padding-16 * 2;
}
>li:last-child {
border: 0;
}
}
}
// {{< card >}}
.book-card {
display: block;
overflow: hidden;
height: 100%;
border-radius: var(--border-radius);
border: $padding-1 solid var(--gray-200);
> a {
display: block;
height: 100%;
&[href], &[href]:visited {
color: var(--body-font-color);
}
&[href]:hover {
text-decoration: none;
background: var(--gray-100);
}
}
> a > img, > img {
width: 100%;
display: block;
aspect-ratio: 4 / 3;
object-fit: cover;
}
.markdown-inner {
padding: $padding-16;
}
}
// {{< image >}}
.book-image {
input + img {
cursor: zoom-in;
transition: transform 0.2s ease-in-out;
}
input:checked + img {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: var(--body-background);
object-fit: contain;
width: 100%;
height: 100%;
z-index: 1;
cursor: zoom-out;
padding: $padding-16;
}
}
// {{< asciinema >}}
.book-asciinema {
margin: $padding-16 0;
}
.book-hero {
min-height: $padding-16 * 24;
align-content: center;
h1 {
font-size: 3em;
}
}
.book-codeblock-filename {
background: var(--gray-100);
border: $padding-1 solid var(--gray-200);
border-bottom: 0;
font-size: var(--font-size-smaller);
margin-top: $padding-16;
padding: $padding-4 $padding-8;
border-start-start-radius: var(--border-radius);
border-start-end-radius: var(--border-radius);
a {
color: var(--body-font-color);
}
+ .highlight pre {
margin-top: 0;
border-start-start-radius: 0;
border-start-end-radius: 0;
}
}
}

View File

@@ -0,0 +1,93 @@
.flex {
display: flex;
&.gap {
gap: $padding-16;
}
}
.flex-auto {
flex: 1 1 auto;
}
.flex-even {
flex: 1 1;
}
.flex-wrap {
flex-wrap: wrap;
}
.justify-start {
justify-content: flex-start;
}
.justify-end {
justify-content: flex-end;
}
.justify-center {
justify-content: center;
}
.justify-between {
justify-content: space-between;
}
.align-center {
align-items: center;
}
.mx-auto {
margin: 0 auto;
}
.text-center {
text-align: center;
}
.text-left {
text-align: left;
}
.text-right {
text-align: right;
}
.text-small {
font-size: .875em;
}
.hidden {
display: none;
}
input.toggle {
height: 0;
width: 0;
overflow: hidden;
opacity: 0;
position: absolute;
}
@mixin spin($duration) {
animation: spin $duration ease infinite;
@keyframes spin {
100% {
transform: rotate(360deg);
}
}
}
@mixin fixed {
position: fixed;
top: 0;
bottom: 0;
overflow-x: hidden;
overflow-y: auto;
}
@mixin outline {
outline-style: auto;
outline-color: var(--color-link);
}

View File

@@ -0,0 +1,5 @@
/* You can override SCSS variables here. */
// :root {
// --pagefind-ui-background: #84DE02;
// }
// $pagefind-ui-background: #84DE02;

View File

@@ -0,0 +1,19 @@
@import "defaults";
@import "variables";
@import "normalize";
@import "utils";
@import "main";
@import "fonts";
@import "print";
@import "markdown";
@import "shortcodes";
// Custom defined styles, theme mixins also placed there
@import "custom";
// Select theme mixing based on site parameter
:root {
@include theme-{{ default "light" .Site.Params.BookTheme }};
}

View File

@@ -0,0 +1,12 @@
(function () {
document.querySelectorAll("pre:has(code)").forEach(code => {
code.addEventListener("click", code.focus);
code.addEventListener("copy", function (event) {
event.preventDefault();
if (navigator.clipboard) {
const content = window.getSelection().toString() || code.textContent;
navigator.clipboard.writeText(content);
}
});
});
})();

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#1f1f1f"><path d="m313-440 196 196q12 12 11.5 28T508-188q-12 11-28 11.5T452-188L188-452q-6-6-8.5-13t-2.5-15q0-8 2.5-15t8.5-13l264-264q11-11 27.5-11t28.5 11q12 12 12 28.5T508-715L313-520h447q17 0 28.5 11.5T800-480q0 17-11.5 28.5T760-440H313Z"/></svg>

After

Width:  |  Height:  |  Size: 347 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#1f1f1f"><path d="M200-80q-33 0-56.5-23.5T120-160v-560q0-33 23.5-56.5T200-800h40v-40q0-17 11.5-28.5T280-880q17 0 28.5 11.5T320-840v40h320v-40q0-17 11.5-28.5T680-880q17 0 28.5 11.5T720-840v40h40q33 0 56.5 23.5T840-720v560q0 33-23.5 56.5T760-80H200Zm0-80h560v-400H200v400Zm0-480h560v-80H200v80Zm0 0v-80 80Z"/></svg>

After

Width:  |  Height:  |  Size: 411 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#1f1f1f"><path d="M504-480 320-664l56-56 240 240-240 240-56-56 184-184Z"/></svg>

After

Width:  |  Height:  |  Size: 178 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#1f1f1f"><path d="M560-120v-66q0-8 3-15.5t9-13.5l209-208q9-9 20-13t22-4q12 0 23 4.5t20 13.5l37 37q8 9 12.5 20t4.5 22q0 11-4 22.5T903-300L695-92q-6 6-13.5 9T666-80h-66q-17 0-28.5-11.5T560-120Zm300-223-37-37 37 37ZM620-140h38l121-122-37-37-122 121v38ZM240-80q-33 0-56.5-23.5T160-160v-640q0-33 23.5-56.5T240-880h287q16 0 30.5 6t25.5 17l194 194q11 11 17 25.5t6 30.5v57q0 17-11.5 28.5T760-510q-17 0-28.5-11.5T720-550v-50H560q-17 0-28.5-11.5T520-640v-160H240v640h200q17 0 28.5 11.5T480-120q0 17-11.5 28.5T440-80H240Zm0-80v-640 640Zm521-121-19-18 37 37-18-19Z"/></svg>

After

Width:  |  Height:  |  Size: 659 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#1f1f1f"><path d="M647-440H200q-17 0-28.5-11.5T160-480q0-17 11.5-28.5T200-520h447L451-716q-12-12-11.5-28t12.5-28q12-11 28-11.5t28 11.5l264 264q6 6 8.5 13t2.5 15q0 8-2.5 15t-8.5 13L508-188q-11 11-27.5 11T452-188q-12-12-12-28.5t12-28.5l195-195Z"/></svg>

After

Width:  |  Height:  |  Size: 349 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#1f1f1f"><path d="M160-240q-17 0-28.5-11.5T120-280q0-17 11.5-28.5T160-320h640q17 0 28.5 11.5T840-280q0 17-11.5 28.5T800-240H160Zm0-200q-17 0-28.5-11.5T120-480q0-17 11.5-28.5T160-520h640q17 0 28.5 11.5T840-480q0 17-11.5 28.5T800-440H160Zm0-200q-17 0-28.5-11.5T120-680q0-17 11.5-28.5T160-720h640q17 0 28.5 11.5T840-680q0 17-11.5 28.5T800-640H160Z"/></svg>

After

Width:  |  Height:  |  Size: 451 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#1f1f1f"><path d="M160-280q-17 0-28.5-11.5T120-320q0-17 11.5-28.5T160-360h480q17 0 28.5 11.5T680-320q0 17-11.5 28.5T640-280H160Zm0-160q-17 0-28.5-11.5T120-480q0-17 11.5-28.5T160-520h480q17 0 28.5 11.5T680-480q0 17-11.5 28.5T640-440H160Zm0-160q-17 0-28.5-11.5T120-640q0-17 11.5-28.5T160-680h480q17 0 28.5 11.5T680-640q0 17-11.5 28.5T640-600H160Zm640 320q-17 0-28.5-11.5T760-320q0-17 11.5-28.5T800-360q17 0 28.5 11.5T840-320q0 17-11.5 28.5T800-280Zm0-160q-17 0-28.5-11.5T760-480q0-17 11.5-28.5T800-520q17 0 28.5 11.5T840-480q0 17-11.5 28.5T800-440Zm0-160q-17 0-28.5-11.5T760-640q0-17 11.5-28.5T800-680q17 0 28.5 11.5T840-640q0 17-11.5 28.5T800-600Z"/></svg>

After

Width:  |  Height:  |  Size: 753 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#1f1f1f"><path d="m603-202-34 97q-4 11-14 18t-22 7q-20 0-32.5-16.5T496-133l152-402q5-11 15-18t22-7h30q12 0 22 7t15 18l152 403q8 19-4 35.5T868-80q-13 0-22.5-7T831-106l-34-96H603ZM362-401 188-228q-11 11-27.5 11.5T132-228q-11-11-11-28t11-28l174-174q-35-35-63.5-80T190-640h84q20 39 40 68t48 58q33-33 68.5-92.5T484-720H80q-17 0-28.5-11.5T40-760q0-17 11.5-28.5T80-800h240v-40q0-17 11.5-28.5T360-880q17 0 28.5 11.5T400-840v40h240q17 0 28.5 11.5T680-760q0 17-11.5 28.5T640-720h-76q-21 72-63 148t-83 116l96 98-30 82-122-125Zm266 129h144l-72-204-72 204Z"/></svg>

After

Width:  |  Height:  |  Size: 650 B

View File

@@ -0,0 +1,7 @@
{
"delimiters": [
{"left": "$$", "right": "$$", "display": true},
{"left": "\\(", "right": "\\)", "display": false},
{"left": "\\[", "right": "\\]", "display": true}
]
}

View File

@@ -0,0 +1,15 @@
{
"name": "{{ .Site.Title }}",
"short_name": "{{ .Site.Title }}",
"start_url": "{{ "./" | relURL }}",
"scope": "{{ "./" | relURL }}",
"display": "standalone",
"background_color": "#000000",
"theme_color": "#000000",
"icons": [
{
"src": "{{ "./favicon.svg" | relURL }}",
"sizes": "512x512"
}
]
}

View File

@@ -0,0 +1,7 @@
(function() {
var menu = document.querySelector("aside .book-menu-content");
addEventListener("beforeunload", function(event) {
localStorage.setItem("menu.scrollTop", menu.scrollTop);
});
menu.scrollTop = localStorage.getItem("menu.scrollTop");
})();

View File

@@ -0,0 +1,6 @@
{
"flowchart": {
"useMaxWidth":true
},
"theme": "default"
}

View File

@@ -0,0 +1,213 @@
/*! modern-normalize v3.0.1 | MIT License | https://github.com/sindresorhus/modern-normalize */
/*
Document
========
*/
/**
Use a better box model (opinionated).
*/
*,
::before,
::after {
box-sizing: border-box;
}
html {
/* Improve consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3) */
font-family:
system-ui,
'Segoe UI',
Roboto,
Helvetica,
Arial,
sans-serif,
'Apple Color Emoji',
'Segoe UI Emoji';
line-height: 1.15; /* 1. Correct the line height in all browsers. */
-webkit-text-size-adjust: 100%; /* 2. Prevent adjustments of font size after orientation changes in iOS. */
tab-size: 4; /* 3. Use a more readable tab size (opinionated). */
}
/*
Sections
========
*/
body {
margin: 0; /* Remove the margin in all browsers. */
}
/*
Text-level semantics
====================
*/
/**
Add the correct font weight in Chrome and Safari.
*/
b,
strong {
font-weight: bolder;
}
/**
1. Improve consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3)
2. Correct the odd 'em' font sizing in all browsers.
*/
code,
kbd,
samp,
pre {
font-family:
ui-monospace,
SFMono-Regular,
Consolas,
'Liberation Mono',
Menlo,
monospace; /* 1 */
font-size: 1em; /* 2 */
}
/**
Add the correct font size in all browsers.
*/
small {
font-size: 80%;
}
/**
Prevent 'sub' and 'sup' elements from affecting the line height in all browsers.
*/
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
/*
Tabular data
============
*/
/**
Correct table border color inheritance in Chrome and Safari. (https://issues.chromium.org/issues/40615503, https://bugs.webkit.org/show_bug.cgi?id=195016)
*/
table {
border-color: currentcolor;
}
/*
Forms
=====
*/
/**
1. Change the font styles in all browsers.
2. Remove the margin in Firefox and Safari.
*/
button,
input,
optgroup,
select,
textarea {
font-family: inherit; /* 1 */
font-size: 100%; /* 1 */
line-height: 1.15; /* 1 */
margin: 0; /* 2 */
}
/**
Correct the inability to style clickable types in iOS and Safari.
*/
button,
[type='button'],
[type='reset'],
[type='submit'] {
-webkit-appearance: button;
}
/**
Remove the padding so developers are not caught out when they zero out 'fieldset' elements in all browsers.
*/
legend {
padding: 0;
}
/**
Add the correct vertical alignment in Chrome and Firefox.
*/
progress {
vertical-align: baseline;
}
/**
Correct the cursor style of increment and decrement buttons in Safari.
*/
::-webkit-inner-spin-button,
::-webkit-outer-spin-button {
height: auto;
}
/**
1. Correct the odd appearance in Chrome and Safari.
2. Correct the outline style in Safari.
*/
[type='search'] {
-webkit-appearance: textfield; /* 1 */
outline-offset: -2px; /* 2 */
}
/**
Remove the inner padding in Chrome and Safari on macOS.
*/
::-webkit-search-decoration {
-webkit-appearance: none;
}
/**
1. Correct the inability to style clickable types in iOS and Safari.
2. Change font properties to 'inherit' in Safari.
*/
::-webkit-file-upload-button {
-webkit-appearance: button; /* 1 */
font: inherit; /* 2 */
}
/*
Interactive
===========
*/
/*
Add the correct display in Chrome and Safari.
*/
summary {
display: list-item;
}

View File

@@ -0,0 +1,32 @@
$startLevel: 1;
$endLevel: 6;
.book-page .markdown.book-article {
@for $currentLevel from $startLevel through $endLevel {
h#{$currentLevel} {
counter-increment: h#{$currentLevel};
counter-reset: h#{$currentLevel + 1};
$content: "";
@for $n from $startLevel through $currentLevel {
$content: $content + 'counter(h#{$n})"."';
}
&::before {
content: unquote($content) " ";
}
}
}
}
.book-toc nav#TableOfContents ul {
counter-reset: item;
li {
counter-increment: item;
> a:before {
content: counters(item, ".") ". ";
}
}
}

View File

@@ -0,0 +1,26 @@
@import "defaults";
@import "variables";
// Webkit
::-webkit-scrollbar {
width: $padding-8;
}
::-webkit-scrollbar-thumb {
background: transparent;
border-radius: $padding-8;
}
:hover::-webkit-scrollbar-thumb {
background: var(--gray-500);
}
// MS
body {
-ms-overflow-style: -ms-autohiding-scrollbar;
}
// Future
.book-menu nav {
scrollbar-color: transparent var(--gray-500);
}

View File

@@ -0,0 +1,17 @@
[
{{- $pages := where .Site.Pages "Kind" "in" (slice "page" "section") -}}
{{- $pages = where $pages "Params.bookSearchExclude" "!=" true -}}
{{/* Remove until we know why it does not work, see https://github.com/alex-shpak/hugo-book/issues/528 */}}
{{/*- $pages = where $pages "Content" "not in" (slice nil "") -*/}}
{{- $pages = where $pages "Content" "!=" "" -}}
{{ range $index, $page := $pages }}
{{ if gt $index 0}},{{end}} {
"id": {{ $index }},
"href": "{{ $page.RelPermalink }}",
"title": {{ (partial "docs/title" $page) | jsonify }},
"section": {{ (partial "docs/title" $page.Parent) | default $.Site.Title | jsonify }},
"content": {{ $page.Plain | jsonify }}
}
{{- end -}}
]

View File

@@ -0,0 +1,113 @@
'use strict';
{{ $searchDataFile := printf "%s.search-data.json" .Language.Lang }}
{{ $searchData := resources.Get "search-data.json" | resources.ExecuteAsTemplate $searchDataFile . | resources.Minify | resources.Fingerprint }}
{{ $searchConfig := i18n "bookSearchConfig" | default "{}" }}
(function () {
const searchDataURL = '{{ partial "docs/links/resource-precache" $searchData }}';
const indexConfig = Object.assign({{ $searchConfig }}, {
includeScore: true,
useExtendedSearch: true,
fieldNormWeight: 1.5,
threshold: 0.2,
ignoreLocation: true,
keys: [
{
name: 'title',
weight: 0.7
},
{
name: 'content',
weight: 0.3
}
]
});
const input = document.querySelector('#book-search-input');
const results = document.querySelector('#book-search-results');
if (!input) {
return
}
input.addEventListener('focus', init);
input.addEventListener('keyup', search);
document.addEventListener('keypress', focusSearchFieldOnKeyPress);
/**
* @param {Event} event
*/
function focusSearchFieldOnKeyPress(event) {
if (event.target.value !== undefined) {
return;
}
if (input === document.activeElement) {
return;
}
const characterPressed = String.fromCharCode(event.charCode);
if (!isHotkey(characterPressed)) {
return;
}
input.focus();
event.preventDefault();
}
/**
* @param {String} character
* @returns {Boolean}
*/
function isHotkey(character) {
const dataHotkeys = input.getAttribute('data-hotkeys') || '';
return dataHotkeys.indexOf(character) >= 0;
}
function init() {
input.removeEventListener('focus', init); // init once
input.required = true;
fetch(searchDataURL)
.then(pages => pages.json())
.then(pages => {
window.bookSearchIndex = new Fuse(pages, indexConfig);
})
.then(() => input.required = false)
.then(search);
}
function search() {
while (results.firstChild) {
results.removeChild(results.firstChild);
}
if (!input.value) {
return;
}
const searchHits = window.bookSearchIndex.search(input.value).slice(0,10);
searchHits.forEach(function (page) {
const li = element('<li><a href></a><small></small></li>');
const a = li.querySelector('a'), small = li.querySelector('small');
a.href = page.item.href;
a.textContent = page.item.title;
small.textContent = page.item.section;
results.appendChild(li);
});
}
/**
* @param {String} content
* @returns {Node}
*/
function element(content) {
const div = document.createElement('div');
div.innerHTML = content;
return div.firstChild;
}
})();

View File

@@ -0,0 +1,7 @@
{{- $swJS := resources.Get "sw.js" | resources.ExecuteAsTemplate "sw.js" . -}}
if (navigator.serviceWorker) {
navigator.serviceWorker.register(
"{{ $swJS.RelPermalink }}",
{ scope: "{{ "./" | relURL }}" }
);
}

View File

@@ -0,0 +1,58 @@
const cacheName = self.location.pathname
const pages = [
{{ if eq .Site.Params.BookServiceWorker "precache" }}
{{ range .Site.AllPages -}}
"{{ .RelPermalink }}",
{{ end -}}
{{ range $permalink, $ok := site.Store.Get "book-sw-precache" -}}
"{{ $permalink }}",
{{ end -}}
{{ end }}
];
self.addEventListener("install", function (event) {
self.skipWaiting();
caches.open(cacheName).then((cache) => {
return cache.addAll(pages);
});
});
self.addEventListener("fetch", (event) => {
const request = event.request;
if (request.method !== "GET") {
return;
}
/**
* @param {Response} response
* @returns {Promise<Response>}
*/
function saveToCache(response) {
if (cacheable(response)) {
return caches
.open(cacheName)
.then((cache) => cache.put(request, response.clone()))
.then(() => response);
} else {
return response;
}
}
/**
* @param {Error} error
*/
function serveFromCache(error) {
return caches.open(cacheName).then((cache) => cache.match(request.url));
}
/**
* @param {Response} response
* @returns {Boolean}
*/
function cacheable(response) {
return response.type === "basic" && response.ok && !response.headers.has("Content-Disposition")
}
event.respondWith(fetch(request).then(saveToCache).catch(serveFromCache));
});