Compare commits
1 Commits
master
...
b6489e5111
| Author | SHA1 | Date | |
|---|---|---|---|
| b6489e5111 |
@@ -1,22 +0,0 @@
|
||||
LatexListNil @ latexlist(nil, nil) <-;
|
||||
LatexListCons @ latexlist(cons(?x, ?xs), cons(?l_x, ?l_s)) <- latex(?x, ?l_x), latexlist(?xs, ?l_s);
|
||||
|
||||
IntercalateNil @ intercalate(?sep, nil, nil) <-;
|
||||
IntercalateConsCons @ intercalate(?sep, cons(?x_1, cons(?x_2, ?xs)), cons(?x_1, cons(?sep, ?ys))) <- intercalate(?sep, cons(?x_2, ?xs), ?ys);
|
||||
IntercalateConsNil @ intercalate(?sep, cons(?x, nil), cons(?x, nil)) <-;
|
||||
|
||||
NonEmpty @ nonempty(cons(?x, ?xs)) <-;
|
||||
|
||||
LatexInt @ latex(?i, ?l) <- int(?i), tostring(?i, ?l);
|
||||
LatexFloat @ latex(?f, ?l) <- float(?f), tostring(?f, ?l);
|
||||
LatexStr @ latex(?s, ?l) <- str(?s), escapestring(?s, ?l_1), latexifystring(?s, ?l_2), join(["\\texttt{\"", ?l_2, "\"}"], ?l);
|
||||
LatexMeta @ latex(metavariable(?l), ?l) <-;
|
||||
LatexLit @ latex(lit(?i), ?l) <- latex(?i, ?l);
|
||||
LatexVar @ latex(var(?s), ?l) <- latex(?s, ?l);
|
||||
|
||||
LatexIsInt @ latex(int(?e), ?l) <- latex(?e, ?l_e), join([?l_e, " \\in \\texttt{Int}"], ?l);
|
||||
LatexIsFloat @ latex(float(?e), ?l) <- latex(?e, ?l_e), join([?l_e, " \\in \\texttt{Float}"], ?l);
|
||||
LatexIsNum @ latex(num(?e), ?l) <- latex(?e, ?l_e), join([?l_e, " \\in \\texttt{Num}"], ?l);
|
||||
LatexIsStr @ latex(str(?e), ?l) <- latex(?e, ?l_e), join([?l_e, " \\in \\texttt{Str}"], ?l);
|
||||
LatexSym @ latex(?s, ?l) <- sym(?s), tostring(?s, ?l_1), join(["\\text{", ?l_1,"}"], ?l);
|
||||
LatexCall @ latex(?c, ?l) <- call(?c, ?n, ?ts), nonempty(?ts), latexlist(?ts, ?lts_1), intercalate(", ", ?lts_1, ?lts_2), join(?lts_2, ?lts_3), join(["\\text{", ?n, "}", "(", ?lts_3, ")"], ?l);
|
||||
@@ -1,102 +0,0 @@
|
||||
const loadedWidgets = {};
|
||||
const getButtons = (inputGroup) => {
|
||||
return {
|
||||
play: inputGroup.querySelector(".bergamot-play"),
|
||||
reset: inputGroup.querySelector(".bergamot-reset"),
|
||||
close: inputGroup.querySelector(".bergamot-close"),
|
||||
}
|
||||
}
|
||||
const setRunning = (inputGroup, running) => {
|
||||
if (inputGroup !== null) {
|
||||
const buttons = getButtons(inputGroup);
|
||||
if (buttons.play) buttons.play.classList.toggle("bergamot-hidden", running);
|
||||
if (buttons.reset) buttons.reset.classList.toggle("bergamot-hidden", !running);
|
||||
if (buttons.close) buttons.close.classList.toggle("bergamot-hidden", !running);
|
||||
}
|
||||
}
|
||||
|
||||
// The object language parsing is handling by a separate standalone Elm
|
||||
// application in the ObjectLanguage module, which has two ports:
|
||||
//
|
||||
// * `parseString` requests a string to be parsed
|
||||
// * `parsedString` returns the parsed string, or null
|
||||
//
|
||||
// We want there to be a single global ObjectLanguage object, but it works
|
||||
// on a "subscription" model (we have to give a callback to its port).
|
||||
// Configure this callback to invoke `resolve` functions from a list,
|
||||
// so that callers can just get a promise. This way we aren't continuously
|
||||
// registering more and more handlers for each parsed string, and we can
|
||||
// use a convenient promise API.
|
||||
const parsingPromiseResolvers = {};
|
||||
const ensureObjectLanguage = () => {
|
||||
if (!window.Bergamot.ObjectLanguage) {
|
||||
window.Bergamot.ObjectLanguage = Elm.Bergamot.ObjectLanguage.init({});
|
||||
window.Bergamot.ObjectLanguage.ports.parsedString.subscribe(({ string, term }) => {
|
||||
if (string in parsingPromiseResolvers) {
|
||||
for (const resolver of parsingPromiseResolvers[string]) {
|
||||
resolver(term);
|
||||
}
|
||||
parsingPromiseResolvers[string] = [];
|
||||
}
|
||||
});
|
||||
}
|
||||
return window.Bergamot.ObjectLanguage;
|
||||
}
|
||||
const parseBergamotObjectLanguage = (str) => {
|
||||
if (!(str in parsingPromiseResolvers)) {
|
||||
parsingPromiseResolvers[str] = [];
|
||||
}
|
||||
|
||||
return new Promise(resolve => {
|
||||
parsingPromiseResolvers[str].push(resolve);
|
||||
ensureObjectLanguage().ports.parseString.send(str);
|
||||
});
|
||||
}
|
||||
|
||||
window.Bergamot = {};
|
||||
window.Bergamot.run = (inputGroup, nodeId, inputModes, inputPrompt, rules, renderPreset, input) => {
|
||||
var app = Elm.Main.init({
|
||||
node: document.getElementById(nodeId),
|
||||
flags: {
|
||||
inputModes,
|
||||
renderRules: window.Bergamot.renderPresets[renderPreset],
|
||||
rules, input
|
||||
}
|
||||
});
|
||||
app.ports.convertInput.subscribe(async ({ mode, input }) => {
|
||||
if (!(mode in window.Bergamot.inputModes)) {
|
||||
app.ports.receiveConverted.send({ input, result: { error: "Improperly configured desugaring function (this is the website developer's fault)" } });
|
||||
}
|
||||
|
||||
let query = await (window.Bergamot.inputModes[mode])(input);
|
||||
if (query !== null) {
|
||||
query = inputPrompt.replace("TERM", query);
|
||||
app.ports.receiveConverted.send({ input, result: { query } });
|
||||
} else {
|
||||
app.ports.receiveConverted.send({ input, result: { error: "Unable to parse object language term" } });
|
||||
}
|
||||
});
|
||||
loadedWidgets[nodeId] = { app, parentNode: inputGroup ? inputGroup.parentElement : null };
|
||||
setRunning(inputGroup, true);
|
||||
};
|
||||
window.Bergamot.runPreset = (inputGroup, nodeId, presetName) => {
|
||||
const preset = window.Bergamot.presets[presetName];
|
||||
window.Bergamot.run(inputGroup, nodeId, preset.inputModes, preset.inputPrompt, preset.rules, preset.renderPreset, preset.query || "");
|
||||
};
|
||||
window.Bergamot.close = (inputGroup, nodeId) => {
|
||||
if (!(nodeId in loadedWidgets)) return;
|
||||
|
||||
const placeholderDiv = document.createElement('div');
|
||||
placeholderDiv.id = nodeId;
|
||||
|
||||
const widget = loadedWidgets[nodeId];
|
||||
const elmRoot = widget.parentNode.querySelector(".bergamot-root");
|
||||
elmRoot.replaceWith(placeholderDiv)
|
||||
delete loadedWidgets[nodeId];
|
||||
setRunning(inputGroup, false);
|
||||
}
|
||||
window.Bergamot.inputModes = {
|
||||
"Bergamot Object Language": parseBergamotObjectLanguage
|
||||
};
|
||||
window.Bergamot.presets = {};
|
||||
window.Bergamot.renderPresets = {};
|
||||
@@ -1,31 +0,0 @@
|
||||
class KatexExpressionShim extends HTMLElement {
|
||||
static observedAttributes = ["expression", "katex-options"];
|
||||
targetSpan;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
doRender() {
|
||||
if (!this.targetSpan) return;
|
||||
|
||||
const options = this.hasAttribute("katex-options") ?
|
||||
this.getAttribute("katex-options") : {};
|
||||
katex.render(
|
||||
this.getAttribute("expression"),
|
||||
this.targetSpan,
|
||||
JSON.parse(options)
|
||||
);
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.targetSpan = document.createElement('span');
|
||||
this.appendChild(this.targetSpan);
|
||||
this.doRender();
|
||||
}
|
||||
|
||||
attributeChangedCallback(name, oldValue, newValue) {
|
||||
this.doRender();
|
||||
}
|
||||
}
|
||||
customElements.define("katex-expression", KatexExpressionShim);
|
||||
@@ -1,5 +1,10 @@
|
||||
@import "variables.scss";
|
||||
|
||||
$code-color-lineno: grey;
|
||||
$code-color-keyword: black;
|
||||
$code-color-type: black;
|
||||
$code-color-comment: grey;
|
||||
|
||||
.highlight-label {
|
||||
padding: 0.25rem 0.5rem 0.25rem 0.5rem;
|
||||
border: $code-border;
|
||||
@@ -16,7 +21,7 @@
|
||||
|
||||
code {
|
||||
font-family: $font-code;
|
||||
@include var(background-color, code-color);
|
||||
background-color: $code-color;
|
||||
border: $code-border;
|
||||
padding: 0 0.25rem 0 0.25rem;
|
||||
}
|
||||
@@ -32,22 +37,13 @@ pre code {
|
||||
.lntable {
|
||||
border-spacing: 0;
|
||||
padding: 0.5rem 0 0.5rem 0;
|
||||
@include var(background-color, code-color);
|
||||
background-color: $code-color;
|
||||
border-radius: 0;
|
||||
border: $code-border;
|
||||
display: block;
|
||||
overflow: auto;
|
||||
margin-bottom: 1rem;
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
border: none;
|
||||
|
||||
&:hover, &:focus {
|
||||
background-color: rgba($primary-color, 0.25);
|
||||
}
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 0;
|
||||
}
|
||||
@@ -64,12 +60,6 @@ pre code {
|
||||
.lntd:last-child {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
// Insert padding to match the distance of the line number to its
|
||||
// border.
|
||||
.line {
|
||||
padding-left: $code-lineno-spacing;
|
||||
}
|
||||
}
|
||||
|
||||
.lntr {
|
||||
@@ -78,39 +68,30 @@ pre code {
|
||||
|
||||
.lnt {
|
||||
display: block;
|
||||
padding: 0 $code-lineno-spacing 0 $code-lineno-spacing;
|
||||
@include var(color, code-lineno-color);
|
||||
border-right: $standard-border;
|
||||
|
||||
// Even though only highlighted line table numbers get the 'star',
|
||||
// insert a corresponding space on non-highlighted ones to keep
|
||||
// spacing consistent.
|
||||
&::before {
|
||||
content: " ";
|
||||
}
|
||||
padding: 0 1rem 0 1rem;
|
||||
color: $code-color-lineno;
|
||||
}
|
||||
|
||||
.hl {
|
||||
display: block;
|
||||
@include var(background-color, code-highlight-color);
|
||||
background-color: #fffd99;
|
||||
|
||||
.lnt {
|
||||
border-left-color: $border-color;
|
||||
&::before {
|
||||
.lnt::before {
|
||||
content: "*";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.kr, .kd, .k {
|
||||
@include var(color, code-keyword-color);
|
||||
.kr, .k {
|
||||
font-weight: bold;
|
||||
color: $code-color-keyword;
|
||||
}
|
||||
|
||||
.kt {
|
||||
@include var(color, code-type-color);
|
||||
font-weight: bold;
|
||||
color: $code-color-type;
|
||||
}
|
||||
|
||||
.c, .c1, .cm {
|
||||
@include var(color, code-comment-color);
|
||||
.c, .c1 {
|
||||
color: $code-color-comment;
|
||||
}
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
@mixin font-inconsolata($weight) {
|
||||
@font-face {
|
||||
font-family: 'Inconsolata';
|
||||
font-display: swap;
|
||||
font-weight: $weight;
|
||||
src: local('Inconsolata'),
|
||||
url('../fonts/gen/Inconsolata-#{$weight}.woff2');
|
||||
}
|
||||
}
|
||||
|
||||
@mixin font-lora {
|
||||
@font-face {
|
||||
font-family: 'Lora';
|
||||
font-display: swap;
|
||||
src: local('Lora'),
|
||||
url('../fonts/gen/Lora-Regular.woff2'),
|
||||
url('../fonts/gen/Lora-Italic.woff2');
|
||||
}
|
||||
}
|
||||
|
||||
@mixin font-raleway($weight) {
|
||||
@font-face {
|
||||
font-family: 'Raleway';
|
||||
font-display: swap;
|
||||
font-weight: $weight;
|
||||
src: local('Raleway'),
|
||||
url('../fonts/gen/Raleway-#{$weight}.woff2'),
|
||||
url('../fonts/gen/Raleway-#{$weight}-Italic.woff2');
|
||||
}
|
||||
}
|
||||
|
||||
@mixin font-stixgeneral {
|
||||
@font-face {
|
||||
font-family: 'STIXGeneral';
|
||||
font-display: swap;
|
||||
src: local('STIXGeneral-Regular'),
|
||||
url('../fonts/STIXGeneral-Regular.ttf');
|
||||
}
|
||||
}
|
||||
|
||||
@include font-inconsolata(400);
|
||||
@include font-lora();
|
||||
@include font-raleway(400);
|
||||
@include font-raleway(700);
|
||||
@include font-stixgeneral();
|
||||
|
||||
/* Generated from chatgpt-adjust-fallback.py */
|
||||
|
||||
@font-face {
|
||||
font-family: "Raleway Fallback";
|
||||
src: local("Arial");
|
||||
size-adjust: 100.09%;
|
||||
ascent-override: 94.00%;
|
||||
descent-override: 23.40%;
|
||||
line-gap-override: 0.00%;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Lora Fallback";
|
||||
src: local("Times New Roman");
|
||||
size-adjust: 111.79%;
|
||||
ascent-override: 100.60%;
|
||||
descent-override: 27.40%;
|
||||
line-gap-override: 0.00%;
|
||||
}
|
||||
@@ -1,16 +1,16 @@
|
||||
@import "variables.scss";
|
||||
@import "mixins.scss";
|
||||
|
||||
$margin-width: 30rem;
|
||||
$margin-inner-offset: 0.5rem;
|
||||
$margin-outer-offset: 1rem;
|
||||
|
||||
@mixin below-two-margins {
|
||||
@media screen and
|
||||
(max-width: $container-width-threshold +
|
||||
2 * ($margin-width + $margin-inner-offset + $margin-outer-offset)) {
|
||||
@content;
|
||||
}
|
||||
|
||||
@media print {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin below-one-margin {
|
||||
@@ -19,10 +19,6 @@
|
||||
($margin-width + $margin-inner-offset + $margin-outer-offset)) {
|
||||
@content;
|
||||
}
|
||||
|
||||
@media print {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin margin-content {
|
||||
|
||||
@@ -11,22 +11,3 @@
|
||||
}
|
||||
}
|
||||
|
||||
@mixin green-shadow {
|
||||
box-shadow: 0px 0px 5px rgba($primary-color, 0.7);
|
||||
}
|
||||
|
||||
@mixin textual-input {
|
||||
@include bordered-block;
|
||||
box-sizing: border-box;
|
||||
@include var(background-color, background-color);
|
||||
@include var(color, text-color);
|
||||
font-family: $font-body;
|
||||
padding: $input-padding;
|
||||
|
||||
&:active, &:focus {
|
||||
@include green-shadow;
|
||||
border-color: $primary-color;
|
||||
}
|
||||
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
:root {
|
||||
@each $varName, $varDefault in $css-vars {
|
||||
--#{$varName}: #{$varDefault};
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--background-color: #{$background-color-dark};
|
||||
--text-color: white;
|
||||
|
||||
--warning-background-color: #{$warning-background-color-dark};
|
||||
--warning-border-color: #{$warning-border-color-dark};
|
||||
|
||||
--target-background-color: #{$target-background-color-dark};
|
||||
|
||||
--code-color: #{$code-color-dark};
|
||||
--code-lineno-color: white;
|
||||
--code-keyword-color: #{$code-token-color-dark};
|
||||
--code-comment-color: #{$code-comment-color-dark};
|
||||
--code-type-color: #{$code-token-color-dark};
|
||||
--code-highlight-color: #{$code-highlight-color-dark};
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,13 @@
|
||||
@import "variables.scss";
|
||||
@import "mixins.scss";
|
||||
|
||||
$search-input-padding: 0.5rem;
|
||||
$search-element-padding: 0.5rem 1rem 0.5rem 1rem;
|
||||
|
||||
@mixin green-shadow {
|
||||
box-shadow: 0px 0px 5px rgba($primary-color, 0.7);
|
||||
}
|
||||
|
||||
.stork-wrapper {
|
||||
margin-top: 0.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
@@ -15,16 +20,24 @@ $search-element-padding: 0.5rem 1rem 0.5rem 1rem;
|
||||
}
|
||||
|
||||
input.stork-input {
|
||||
@include textual-input;
|
||||
@include bordered-block;
|
||||
font-family: $font-body;
|
||||
padding: $search-input-padding;
|
||||
|
||||
&:active, &:focus {
|
||||
@include green-shadow;
|
||||
border-color: $primary-color;
|
||||
}
|
||||
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.stork-close-button {
|
||||
@include bordered-block;
|
||||
@include var(background-color, background-color);
|
||||
@include var(color, text-color);
|
||||
font-family: $font-body;
|
||||
padding: $input-padding;
|
||||
padding: $search-input-padding;
|
||||
|
||||
background-color: $code-color;
|
||||
padding-left: 1.5rem;
|
||||
padding-right: 1.5rem;
|
||||
|
||||
@@ -56,11 +69,11 @@ input.stork-input {
|
||||
list-style: none;
|
||||
|
||||
&.selected {
|
||||
@include var(background-color, code-color);
|
||||
background-color: $code-color;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
@include var(color, text-color);
|
||||
color: black;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
@import "mixins.scss";
|
||||
@import "margin.scss";
|
||||
|
||||
$sidenote-padding: 1rem;
|
||||
$sidenote-highlight-border-width: .2rem;
|
||||
|
||||
.sidenote {
|
||||
&:hover {
|
||||
.sidenote-label {
|
||||
@@ -48,20 +51,13 @@
|
||||
|
||||
@mixin hidden-sidenote {
|
||||
position: static;
|
||||
// Author can override margin inline to shift sidenote, but when displayed
|
||||
// on mobile (and thus, between text), shifting it would overlap it
|
||||
// with text, so override the shift.
|
||||
margin-top: 1rem !important;
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
width: 100%;
|
||||
|
||||
.sidenote-checkbox:checked ~ & {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@media print {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
@include below-two-margins {
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
@import "variables.scss";
|
||||
@import "mixins.scss";
|
||||
@import "toc.scss";
|
||||
@import "modes.scss";
|
||||
|
||||
body {
|
||||
@include var(background-color, background-color);
|
||||
@include var(color, text-color);
|
||||
font-family: $font-body;
|
||||
font-size: 1.0rem;
|
||||
line-height: 1.5;
|
||||
@@ -25,7 +22,7 @@ h1, h2, h3, h4, h5, h6 {
|
||||
text-align: center;
|
||||
|
||||
&:target {
|
||||
@include var(background-color, target-background-color);
|
||||
background-color: lighten(yellow, 30%);
|
||||
border-radius: 1rem;
|
||||
}
|
||||
|
||||
@@ -38,13 +35,6 @@ h1, h2, h3, h4, h5, h6 {
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
&:target {
|
||||
@include var(background-color, target-background-color);
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
.container {
|
||||
position: relative;
|
||||
margin: auto;
|
||||
@@ -68,9 +58,10 @@ p {
|
||||
}
|
||||
|
||||
.button, input[type="submit"] {
|
||||
@include var(color, text-color);
|
||||
padding: 0.5rem;
|
||||
border: 1px solid $primary-color;
|
||||
background-color: $primary-color;
|
||||
border: none;
|
||||
color: white;
|
||||
transition: color 0.25s, background-color 0.25s;
|
||||
text-align: left;
|
||||
|
||||
@@ -79,15 +70,11 @@ p {
|
||||
}
|
||||
|
||||
&:hover, &:focus {
|
||||
background-color: rgba($primary-color, 0.2);
|
||||
@include var(color, text-color);
|
||||
background-color: white;
|
||||
color: $primary-color;
|
||||
}
|
||||
}
|
||||
|
||||
.input[type="text"], textarea {
|
||||
@include textual-input;
|
||||
}
|
||||
|
||||
nav {
|
||||
width: 100%;
|
||||
margin: 0rem 0rem 1rem 0rem;
|
||||
@@ -101,7 +88,7 @@ nav {
|
||||
a {
|
||||
padding: 0.25rem 0.75rem 0.25rem .75rem;
|
||||
text-decoration: none;
|
||||
@include var(color, text-color);
|
||||
color: black;
|
||||
display: inline-block;
|
||||
border-bottom: none;
|
||||
white-space: nowrap;
|
||||
@@ -109,6 +96,7 @@ nav {
|
||||
}
|
||||
|
||||
.post-subscript {
|
||||
color: #8f8f8f;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@@ -141,32 +129,18 @@ h6 {
|
||||
}
|
||||
|
||||
a {
|
||||
@include var(color, text-color);
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
border-bottom: .2rem solid $primary-color;
|
||||
transition: color 0.25s;
|
||||
|
||||
&:hover {
|
||||
color: $primary-color;
|
||||
transition: color 0.25s;
|
||||
}
|
||||
|
||||
&.external-link, &.same-page-link {
|
||||
.feather {
|
||||
fill: none;
|
||||
margin-left: 0.25rem;
|
||||
position: relative;
|
||||
top: 0.125em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.draft-link {
|
||||
border-bottom: .2rem solid $border-color;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
background-color: white;
|
||||
max-width: 100%
|
||||
}
|
||||
|
||||
table {
|
||||
@@ -192,6 +166,7 @@ td {
|
||||
|
||||
td, th {
|
||||
padding: 0.5rem;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
div.highlight tr {
|
||||
@@ -240,32 +215,9 @@ ul.post-list {
|
||||
display: block;
|
||||
}
|
||||
|
||||
p.post-status {
|
||||
margin-bottom: 0.2rem;
|
||||
margin-top: 0.2rem;
|
||||
}
|
||||
|
||||
p.post-wordcount, p.post-status {
|
||||
p.post-wordcount {
|
||||
text-align: center;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.series-link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
margin-top: 1rem;
|
||||
font-size: 1.1rem;
|
||||
border-top: $standard-border;
|
||||
padding-top: 1rem;
|
||||
|
||||
.feather {
|
||||
fill: none;
|
||||
flex-shrink: 0;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
margin-bottom: 0.6rem;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,11 +226,7 @@ ul.post-list {
|
||||
}
|
||||
|
||||
figure {
|
||||
break-inside: avoid;
|
||||
|
||||
img {
|
||||
border: $standard-border;
|
||||
border-radius: 0.5rem;
|
||||
max-width: 70%;
|
||||
display: block;
|
||||
margin: auto;
|
||||
@@ -307,31 +255,19 @@ figure {
|
||||
&.medium img {
|
||||
max-height: 30rem;
|
||||
}
|
||||
|
||||
&.fullwide {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.twitter-tweet {
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.warning {
|
||||
.draft-warning {
|
||||
@include bordered-block;
|
||||
padding: 0.5rem;
|
||||
@include var(background-color, warning-background-color);
|
||||
@include var(border-color, warning-border-color);
|
||||
background-color: #ffee99;
|
||||
border-color: #f5c827;
|
||||
}
|
||||
|
||||
/*
|
||||
Note: by absolute default (via inline CSS) feather icons are hidden.
|
||||
That's because firefox reader mode doesn't play nice with them, and
|
||||
it seems to ignore all styles in <head>. Then, the inline style
|
||||
in <head> uses !important to restore the display of icons, but provides
|
||||
limited styling. Here, we finally apply the full extent of the feather styles.
|
||||
*/
|
||||
.feather {
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
@@ -382,118 +318,3 @@ figure {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.series-navigation {
|
||||
margin-top: 1em;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.wrapper {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
|
||||
&.previous {
|
||||
justify-content: left;
|
||||
}
|
||||
|
||||
&.next {
|
||||
justify-content: right;
|
||||
}
|
||||
}
|
||||
|
||||
a, .ongoing-placeholder {
|
||||
@include bordered-block;
|
||||
padding: 0.5em 1em 0.5em 1em;
|
||||
font-size: 1.1em;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 1em;
|
||||
|
||||
.feather {
|
||||
height: 1.25em;
|
||||
width: 1.25em;
|
||||
fill: none;
|
||||
&:first-child { margin-right: 0.5em; }
|
||||
&:last-child { margin-left: 0.5em; }
|
||||
}
|
||||
}
|
||||
|
||||
.ongoing-placeholder {
|
||||
border-style: dashed;
|
||||
}
|
||||
|
||||
div.title {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.series-status {
|
||||
&.suspended { --status-color: #f9b005; }
|
||||
&.complete { --status-color: #3dc60b; }
|
||||
&.ongoing { --status-color: #46a0ff; }
|
||||
|
||||
.series-status-keyword {
|
||||
display: inline-block;
|
||||
border-bottom: .2rem solid var(--status-color);
|
||||
margin: 0 0.25rem 0 0.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
details {
|
||||
@include bordered-block;
|
||||
padding: 0.5rem 0.5rem 0 0.5rem;
|
||||
|
||||
&[open] {
|
||||
padding-bottom: 0.5rem;
|
||||
|
||||
summary {
|
||||
border-bottom: $standard-border;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
summary {
|
||||
margin: 0 -0.5rem 0 -0.5rem;
|
||||
padding: 0.5rem;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
border-left: (3 * $standard-border-width) solid $primary-color;
|
||||
margin-left: 0;
|
||||
padding-left: 1rem;
|
||||
}
|
||||
|
||||
.early-navigation-wrapper {
|
||||
margin-bottom: 3rem;
|
||||
}
|
||||
|
||||
.side-by-side {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.side-by-side-item {
|
||||
flex-basis: 0;
|
||||
}
|
||||
|
||||
.internal-ref {
|
||||
text-decoration: underline;
|
||||
break-inside: avoid;
|
||||
|
||||
&:target {
|
||||
@include var(background-color, target-background-color);
|
||||
border-radius: 1rem;
|
||||
|
||||
.internal-ref-counter {
|
||||
@include var(background-color, target-background-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.internal-ref-counter {
|
||||
display: inline-block;
|
||||
border: $standard-border;
|
||||
border-radius: 0.5rem;
|
||||
padding: 0 0.25rem 0 0.25rem;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
@import "mixins.scss";
|
||||
@import "margin.scss";
|
||||
|
||||
$toc-color: $code-color;
|
||||
$toc-border-color: $code-border-color;
|
||||
|
||||
.table-of-contents {
|
||||
@include margin-content;
|
||||
@include margin-content-left;
|
||||
@@ -9,7 +12,6 @@
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
margin-bottom: 1rem;
|
||||
text-align: left;
|
||||
|
||||
em {
|
||||
font-style: normal;
|
||||
@@ -35,15 +37,12 @@
|
||||
|
||||
a {
|
||||
padding: 0;
|
||||
white-space: normal;
|
||||
margin-left: 0.5rem;
|
||||
text-indent: -0.5rem;
|
||||
}
|
||||
|
||||
div.wrapper {
|
||||
@include bordered-block;
|
||||
padding: 1rem;
|
||||
@include var(background-color, code-color);
|
||||
background-color: $toc-color;
|
||||
border-color: $toc-border-color;
|
||||
box-sizing: border-box;
|
||||
max-width: 100%;
|
||||
|
||||
@@ -1,69 +1,16 @@
|
||||
$container-width: 45rem;
|
||||
$container-min-padding: 1rem;
|
||||
$container-width-threshold: $container-width + 2 * $container-min-padding;
|
||||
$standard-border-width: .075rem;
|
||||
|
||||
$primary-color: #36e281;
|
||||
$border-color: #bfbfbf;
|
||||
$background-color: white;
|
||||
$background-color-dark: #1b1d1f;
|
||||
$standard-border-width: .075rem;
|
||||
$standard-border: $standard-border-width solid $border-color;
|
||||
|
||||
$font-heading: "Lora", "Lora Fallback", serif;
|
||||
$font-body: "Raleway", "Raleway Fallback", sans-serif;
|
||||
$font-code: "Inconsolata", monospace, "STIXGeneral";
|
||||
|
||||
$warning-background-color: #ffee99;
|
||||
$warning-border-color: #f5c827;
|
||||
$warning-background-color-dark: #75640a;
|
||||
$warning-border-color-dark: $warning-background-color;
|
||||
|
||||
$target-background-color: lighten(yellow, 30%);
|
||||
$target-background-color-dark: #55511c;
|
||||
|
||||
$code-color: #f0f0f0;
|
||||
$code-color-dark: lighten($background-color-dark, 10%);
|
||||
$code-token-color: darken($primary-color, 25%);
|
||||
$code-token-color-dark: $primary-color;
|
||||
$code-highlight-color: #fffd99;
|
||||
$code-highlight-color-dark: #555538;
|
||||
$code-border-color: darken($code-color, 10%);
|
||||
$code-lineno-color: black;
|
||||
$code-lineno-spacing: 1rem;
|
||||
$code-comment-color: grey;
|
||||
$code-comment-color-dark: #68dcff;
|
||||
|
||||
$font-heading: "Lora", serif;
|
||||
$font-body: "Raleway", serif;
|
||||
$font-code: "Inconsolata", monospace;
|
||||
|
||||
$standard-border: $standard-border-width solid $border-color;
|
||||
$code-border: $standard-border-width solid $code-border-color;
|
||||
|
||||
$input-padding: 0.5rem;
|
||||
|
||||
$sidenote-padding: 1rem;
|
||||
$sidenote-highlight-border-width: .2rem;
|
||||
|
||||
$margin-width: 30rem;
|
||||
$margin-inner-offset: 0.5rem;
|
||||
$margin-outer-offset: 1rem;
|
||||
|
||||
$toc-border-color: $code-border-color;
|
||||
|
||||
// Default values for CSS variables for fallback.
|
||||
$css-vars: (
|
||||
background-color: $background-color,
|
||||
text-color: black,
|
||||
|
||||
warning-background-color: $warning-background-color,
|
||||
warning-border-color: $warning-border-color,
|
||||
|
||||
target-background-color: $target-background-color,
|
||||
|
||||
code-color: $code-color,
|
||||
code-lineno-color: $code-lineno-color,
|
||||
code-keyword-color: $code-token-color,
|
||||
code-comment-color: $code-comment-color,
|
||||
code-type-color: $code-token-color,
|
||||
code-highlight-color: $code-highlight-color,
|
||||
);
|
||||
|
||||
@mixin var($property, $varName) {
|
||||
#{$property}: map-get($css-vars, $varName);
|
||||
#{$property}: var(--#{$varName});
|
||||
}
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
"""
|
||||
Generate @font-face settings to help make the fallback font look similar
|
||||
to the non-fallback font.
|
||||
|
||||
Genererated by ChatGTP 5.2-instant. Not human-modified.
|
||||
"""
|
||||
|
||||
from fontTools.ttLib import TTFont
|
||||
|
||||
USE_TYPO_METRICS = 1 << 7
|
||||
|
||||
def get_metrics(path):
|
||||
font = TTFont(path)
|
||||
|
||||
head = font["head"]
|
||||
os2 = font["OS/2"]
|
||||
hhea = font["hhea"]
|
||||
|
||||
use_typo = bool(os2.fsSelection & USE_TYPO_METRICS)
|
||||
|
||||
if use_typo:
|
||||
asc = os2.sTypoAscender
|
||||
desc = os2.sTypoDescender
|
||||
gap = os2.sTypoLineGap
|
||||
source = "OS/2.sTypo*"
|
||||
else:
|
||||
asc = hhea.ascent
|
||||
desc = -hhea.descent
|
||||
gap = hhea.lineGap
|
||||
source = "hhea.*"
|
||||
|
||||
# x-height ALWAYS comes from OS/2
|
||||
if not hasattr(os2, "sxHeight") or os2.sxHeight <= 0:
|
||||
raise ValueError(f"{path} has no usable sxHeight")
|
||||
|
||||
x_height = os2.sxHeight
|
||||
|
||||
print("Source", path, source)
|
||||
|
||||
return {
|
||||
"unitsPerEm": head.unitsPerEm,
|
||||
"ascender": asc,
|
||||
"descender": desc,
|
||||
"lineGap": gap,
|
||||
"xHeight": x_height,
|
||||
}
|
||||
|
||||
def compute_overrides(target, fallback):
|
||||
# size-adjust: match x-height
|
||||
size_adjust = (
|
||||
(target["xHeight"] / target["unitsPerEm"]) /
|
||||
(fallback["xHeight"] / fallback["unitsPerEm"])
|
||||
)
|
||||
|
||||
# overrides: force target vertical metrics
|
||||
ascent_override = target["ascender"] / target["unitsPerEm"]
|
||||
descent_override = abs(target["descender"]) / target["unitsPerEm"]
|
||||
line_gap_override = target["lineGap"] / target["unitsPerEm"]
|
||||
|
||||
return {
|
||||
"size_adjust": size_adjust * 100,
|
||||
"ascent_override": ascent_override * 100,
|
||||
"descent_override": descent_override * 100,
|
||||
"line_gap_override": line_gap_override * 100,
|
||||
}
|
||||
|
||||
def emit_css(family_name, local_name, values):
|
||||
return f"""
|
||||
@font-face {{
|
||||
font-family: "{family_name}";
|
||||
src: local("{local_name}");
|
||||
size-adjust: {values['size_adjust']:.2f}%;
|
||||
ascent-override: {values['ascent_override']:.2f}%;
|
||||
descent-override: {values['descent_override']:.2f}%;
|
||||
line-gap-override: {values['line_gap_override']:.2f}%;
|
||||
}}
|
||||
""".strip()
|
||||
|
||||
# ---- Example usage ----
|
||||
|
||||
target = get_metrics("static/fonts/gen/Lora-Regular.woff2")
|
||||
fallback = get_metrics("/System/Library/Fonts/Supplemental/Times New Roman.ttf")
|
||||
|
||||
values = compute_overrides(target, fallback)
|
||||
|
||||
print(emit_css(
|
||||
family_name="Lora Fallback",
|
||||
local_name="Times New Roman",
|
||||
values=values,
|
||||
))
|
||||
@@ -1,69 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
Instantiate variable fonts at specific weights/styles, producing static TTF files.
|
||||
No subsetting, no recursive searching—just direct calls with hardcoded axis values.
|
||||
Requires fontTools >= 4.0.
|
||||
|
||||
Genererated by ChatGTP o3-mini-high. Not human-modified.
|
||||
"""
|
||||
|
||||
from fontTools.ttLib import TTFont
|
||||
from fontTools.varLib.instancer import instantiateVariableFont
|
||||
|
||||
def instantiate_variable_font(input_font_path, axis_values, output_font_path):
|
||||
"""
|
||||
1) Loads a variable font from `input_font_path`.
|
||||
2) Instantiates (flattens) it at the specified axis values (e.g. {"wght": 400}).
|
||||
3) Saves the result as a static TTF at `output_font_path`.
|
||||
"""
|
||||
print(f"Instantiating {input_font_path} with axes={axis_values} -> {output_font_path}")
|
||||
vf = TTFont(input_font_path)
|
||||
static_font = instantiateVariableFont(vf, axis_values)
|
||||
static_font.flavor = "woff2"
|
||||
static_font.save(output_font_path)
|
||||
|
||||
def main():
|
||||
# Inconsolata (Variable)
|
||||
instantiate_variable_font(
|
||||
"Inconsolata-VariableFont_wdth,wght.ttf",
|
||||
{"wght": 400},
|
||||
"Inconsolata-400.woff2"
|
||||
)
|
||||
|
||||
# Lora (Variable, normal and italic)
|
||||
instantiate_variable_font(
|
||||
"Lora-VariableFont_wght.ttf",
|
||||
{"wght": 400},
|
||||
"Lora-Regular.woff2"
|
||||
)
|
||||
instantiate_variable_font(
|
||||
"Lora-Italic-VariableFont_wght.ttf",
|
||||
{"wght": 400},
|
||||
"Lora-Italic.woff2"
|
||||
)
|
||||
|
||||
# Raleway (Variable, normal and italic)
|
||||
instantiate_variable_font(
|
||||
"Raleway-VariableFont_wght.ttf",
|
||||
{"wght": 400},
|
||||
"Raleway-400.woff2"
|
||||
)
|
||||
instantiate_variable_font(
|
||||
"Raleway-VariableFont_wght.ttf",
|
||||
{"wght": 700},
|
||||
"Raleway-700.woff2"
|
||||
)
|
||||
instantiate_variable_font(
|
||||
"Raleway-Italic-VariableFont_wght.ttf",
|
||||
{"wght": 400},
|
||||
"Raleway-400-Italic.woff2"
|
||||
)
|
||||
instantiate_variable_font(
|
||||
"Raleway-Italic-VariableFont_wght.ttf",
|
||||
{"wght": 700},
|
||||
"Raleway-700-Italic.woff2"
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,7 +0,0 @@
|
||||
[params]
|
||||
katexCssUrl = "//static.danilafe.com/katex/katex.min.css"
|
||||
katexJsUrl = "//static.danilafe.com/katex/katex.min.js"
|
||||
normalizeCssUrl = "//static.danilafe.com/normalize/normalize.css"
|
||||
visNetworkJsUrl = "//static.danilafe.com/vis-network/vis-network.min.js"
|
||||
bergamotJsUrl = "//static.danilafe.com/bergamot/bergamot.js"
|
||||
bergamotObjectLanguageJsUrl = "//static.danilafe.com/bergamot/objectlang.js"
|
||||
79
i18n/en.toml
79
i18n/en.toml
@@ -1,79 +0,0 @@
|
||||
[home]
|
||||
other = "Home"
|
||||
|
||||
[about]
|
||||
other = "About"
|
||||
|
||||
[resume]
|
||||
other = "Resume"
|
||||
|
||||
[tags]
|
||||
other = "Tags"
|
||||
|
||||
[favorites]
|
||||
other = "Favorites"
|
||||
|
||||
[search]
|
||||
other = "Search"
|
||||
|
||||
[allPosts]
|
||||
other = "All Posts"
|
||||
|
||||
[nWords]
|
||||
one = "one word"
|
||||
other = "{{ .Count }} words"
|
||||
|
||||
[nMinutesToRead]
|
||||
one = "about one minute to read"
|
||||
other = "about {{ .Count }} minutes to read"
|
||||
|
||||
[latestInSeries]
|
||||
other = "Latest in series:"
|
||||
|
||||
[recentPosts]
|
||||
other = "Recent posts"
|
||||
|
||||
[tagged]
|
||||
other = "Tagged \"{{ . }}\""
|
||||
|
||||
[postedOn]
|
||||
other = "Posted on {{ . }}"
|
||||
|
||||
[tableOfContents]
|
||||
other = "Table of Contents"
|
||||
|
||||
[warning]
|
||||
other = "Warning!"
|
||||
|
||||
[postDraft]
|
||||
other = "This post is a draft. At best, it may contain grammar mistakes; at worst, it can include significant errors and bugs. Please use your best judgement!"
|
||||
|
||||
[contactFooter]
|
||||
other = "Liked this article? Have any questions or comments? Please don't hesitate to reach out to me at <a href=\"mailto:danila.fedorin@gmail.com\">danila.fedorin@gmail.com</a>! I love receiving emails from readers, and I'm always happy to provide any additional clarification or assistance."
|
||||
|
||||
[note]
|
||||
other = "note"
|
||||
|
||||
[from]
|
||||
other = "From"
|
||||
|
||||
[searchRequiresJS]
|
||||
other = "Search (requires JavaScript)"
|
||||
|
||||
[series]
|
||||
other = "Series"
|
||||
|
||||
[postsFromTo]
|
||||
other = "First post in {{ .from }}, last post in {{ .to }}"
|
||||
|
||||
[seriesStatus]
|
||||
other = "Series status:"
|
||||
|
||||
[suspendedSeries]
|
||||
other = "Suspended"
|
||||
|
||||
[completeSeries]
|
||||
other = "Complete"
|
||||
|
||||
[ongoingSeries]
|
||||
other = "Ongoing"
|
||||
@@ -1,9 +0,0 @@
|
||||
{{ if and (eq .Type "alert") (eq .AlertType "todo") -}}
|
||||
<div style="background-color: tomato; color: white; padding: 10px;">
|
||||
<em>TODO: </em>{{- .Text | plainify -}}
|
||||
</div>
|
||||
{{- else -}}
|
||||
<blockquote {{- with .Attributes.id }} id="{{ . }}"{{ end }}>
|
||||
{{ .Text -}}
|
||||
</blockquote>
|
||||
{{- end }}
|
||||
@@ -1,6 +0,0 @@
|
||||
{{- .Page.Scratch.SetInMap "definedSections" (printf "#%s" .Anchor) true -}}
|
||||
<a href="#{{ .Anchor }}">
|
||||
<h{{ .Level }} id="{{ .Anchor }}">
|
||||
{{- .Text | safeHTML -}}
|
||||
</h{{ .Level }}>
|
||||
</a>
|
||||
@@ -1,32 +0,0 @@
|
||||
{{- $class := "" -}}
|
||||
{{- $icon := "" -}}
|
||||
{{- $absoluteDest := absLangURL .Destination -}}
|
||||
{{- $siteRootUrl := absLangURL "" -}}
|
||||
{{- $isExternal := not (hasPrefix $absoluteDest $siteRootUrl) -}}
|
||||
{{- $isSamePage := hasPrefix .Destination "#" -}}
|
||||
|
||||
{{- if $isSamePage -}}
|
||||
{{- $class = "same-page-link" -}}
|
||||
{{- if index (.Page.Scratch.Get "definedSections") .Destination -}}
|
||||
{{- $icon = "arrow-up" -}}
|
||||
{{- else -}}
|
||||
{{- /* Do not render "down" links because don't know how to distinguish unseen titles from paragraph links. */ -}}
|
||||
{{- /* $icon = "arrow-down" */ -}}
|
||||
{{- end -}}
|
||||
{{- else if $isExternal -}}
|
||||
{{- $class = "external-link" -}}
|
||||
{{- $icon = "external-link" -}}
|
||||
{{- end -}}
|
||||
<a href="{{ .Destination | safeURL }}"
|
||||
{{- with .Title }} title="{{ . }}"{{ end -}}
|
||||
{{- with $class -}}
|
||||
class="{{ . }}"
|
||||
{{- end -}}
|
||||
{{- if (and site.Params.externalLinksInNewTab $isExternal) -}}
|
||||
target="_blank" rel="noopener noreferrer"
|
||||
{{- end -}}
|
||||
>
|
||||
{{- with .Text | safeHTML }}{{ . }}{{ end -}}
|
||||
{{- with $icon -}}{{- partial "icon.html" . -}}{{- end -}}
|
||||
</a>
|
||||
{{- /* chomp trailing newline */ -}}
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
<ul class="post-list">
|
||||
{{ range .Pages.ByDate.Reverse }}
|
||||
{{ partial "post.html" (dict "page" .) }}
|
||||
{{ partial "post.html" . }}
|
||||
{{ end }}
|
||||
</ul>
|
||||
{{ end }}
|
||||
|
||||
@@ -2,37 +2,41 @@
|
||||
<h2>{{ .Title }}</h2>
|
||||
<div class="post-subscript">
|
||||
<p>
|
||||
{{- range (.GetTerms "tags") -}}
|
||||
<a class="button" href="{{ .Permalink }}">{{ .Title }}</a>
|
||||
{{ end -}}
|
||||
{{ range .Params.tags }}
|
||||
<a class="button" href="{{ $.Site.BaseURL }}/tags/{{ . | urlize }}">{{ . }}</a>
|
||||
{{ end }}
|
||||
</p>
|
||||
<p>{{ i18n "postedOn" (.Date.Format "January 2, 2006") }}.</p>
|
||||
<p>Posted on {{ .Date.Format "January 2, 2006" }}.</p>
|
||||
</div>
|
||||
|
||||
<div class="post-content">
|
||||
{{- if not (eq .TableOfContents "<nav id=\"TableOfContents\"></nav>") -}}
|
||||
{{ if not (eq .TableOfContents "<nav id=\"TableOfContents\"></nav>") }}
|
||||
<div class="table-of-contents">
|
||||
<div class="wrapper">
|
||||
<em>{{- i18n "tableOfContents" -}}</em>
|
||||
{{- .TableOfContents -}}
|
||||
<em>Table of Contents</em>
|
||||
{{ .TableOfContents }}
|
||||
</div>
|
||||
</div>
|
||||
{{- end -}}
|
||||
{{ end }}
|
||||
|
||||
{{- if .Draft -}}
|
||||
{{- partial "warning.html" (i18n "postDraft") -}}
|
||||
{{- end -}}
|
||||
{{ if .Draft }}
|
||||
<div class="draft-warning">
|
||||
<em>Warning!</em> This post is a draft. At best, it may contain grammar mistakes;
|
||||
at worst, it can include significant errors and bugs. Please
|
||||
use your best judgement!
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
{{- .Content -}}
|
||||
</div>
|
||||
{{- end -}}
|
||||
{{- define "after" -}}
|
||||
<div class="container">
|
||||
{{- partial "seriesnav.html" . -}}
|
||||
{{ .Content }}
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ define "after" }}
|
||||
<hr class="container footer-divider">
|
||||
<footer class="container">
|
||||
<p>{{ i18n "contactFooter" | safeHTML }}</p>
|
||||
<p>Liked this article? Have any questions or comments?
|
||||
Please don't hesitate to reach out to me at <a href="mailto:danila.fedorin@gmail.com">
|
||||
danila.fedorin@gmail.com</a>! I love receiving emails from readers, and I'm always happy
|
||||
to provide any additional clarification or assistance.</p>
|
||||
<!--
|
||||
<p>I'm also currently looking for Computer Science internships for the summer
|
||||
of 2021. Take a look at my <a href="/Resume-Danila-Fedorin.pdf">resume</a>,
|
||||
@@ -41,4 +45,4 @@
|
||||
to learn more about me!</p>
|
||||
-->
|
||||
</footer>
|
||||
{{- end -}}
|
||||
{{ end }}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
<ul class="post-list">
|
||||
{{ range (where (where .Site.Pages.ByDate.Reverse "Section" "blog") ".Kind" "!=" "section") }}
|
||||
{{ if .Params.favorite }}{{ partial "post.html" (dict "page" .) }}{{ end }}
|
||||
{{ if .Params.favorite }}{{ partial "post.html" . }}{{ end }}
|
||||
{{ end }}
|
||||
</ul>
|
||||
{{ end }}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
{{ define "main" }}
|
||||
<h2>{{ .Title }} </h2>
|
||||
<script src="{{ .Site.Params.visNetworkJsUrl }}"></script>
|
||||
<script type="module" src="{{ absLangURL "graph/graph.js" }}"></script>
|
||||
<style>
|
||||
#graph-container {
|
||||
width: 100%;
|
||||
height: 50vh;
|
||||
border-radius: 0.2rem;
|
||||
border: .075rem solid #bfbfbf
|
||||
}
|
||||
</style>
|
||||
{{ .Content }}
|
||||
<div id="graph-container">
|
||||
</div>
|
||||
{{ end }}
|
||||
@@ -1,11 +1,10 @@
|
||||
{{ define "main" }}
|
||||
{{ .Content }}
|
||||
|
||||
{{ i18n "recentPosts" }}:
|
||||
{{ partial "uniquebyseries.html" (dict "scratch" .Scratch) }}
|
||||
Recent posts:
|
||||
<ul class="post-list">
|
||||
{{ range first 10 (.Scratch.Get "pages") }}
|
||||
{{ partial "post.html" (dict "page" . "linkSeries" true) }}
|
||||
{{ range first 10 (where (where .Site.Pages.ByDate.Reverse "Section" "blog") ".Kind" "!=" "section") }}
|
||||
{{ partial "post.html" . }}
|
||||
{{ end }}
|
||||
</ul>
|
||||
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
<script>
|
||||
window.addEventListener('load', function() {
|
||||
window.Bergamot.inputModes['{{ .name }}'] = {{ .fn | safeJS }};
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
{
|
||||
{{ if . }}
|
||||
{{ range $name := split . ";" }}
|
||||
{{ if eq $name "query" }}
|
||||
"Query": "query",
|
||||
{{ else }}
|
||||
{{ $pieces := split $name ":" }}
|
||||
{{ $name := index $pieces 0 }}
|
||||
{{ $modestring := index $pieces 1 }}
|
||||
"{{ $name }}": { "custom": "{{ $modestring }}" },
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ else }}
|
||||
"Languge Term": { "custom": "Bergamot Object Language" },
|
||||
"Query": "query",
|
||||
{{ end }}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
<script>
|
||||
window.addEventListener('load', function() {
|
||||
window.Bergamot.presets['{{ .name }}'] = {
|
||||
rules: {{ .file }},
|
||||
inputModes: {{ partial "bergamotparseinputmodes.js" .modes | safeJS }},
|
||||
inputPrompt: '{{ .prompt }}',
|
||||
query: '{{ .query }}',
|
||||
renderPreset: '{{ default "default" .renderPreset }}'
|
||||
};
|
||||
});
|
||||
</script>
|
||||
@@ -1,6 +0,0 @@
|
||||
<script>
|
||||
window.addEventListener('load', function() {
|
||||
window.Bergamot.renderPresets['{{ .name }}'] =
|
||||
{{ .file }};
|
||||
});
|
||||
</script>
|
||||
@@ -1,2 +0,0 @@
|
||||
<link rel="preload" href="{{ .url }}" as="style" onload="this.onload=null;this.rel='stylesheet'" {{ .extra | safeHTMLAttr }}>
|
||||
<noscript><link rel="stylesheet" href="{{ .url }}"></noscript>
|
||||
@@ -1,27 +1,12 @@
|
||||
{{- $siteSourceUrl := site.Params.siteSourceUrl -}}
|
||||
{{- $submoduleLinks := site.Data.submodules -}}
|
||||
{{- $hostData := site.Data.hosts -}}
|
||||
{{- $scratch := .scratch -}}
|
||||
{{- $lines := .lines -}}
|
||||
{{- $scratch.Set "bestLength" -1 -}}
|
||||
{{- $scratch.Set "bestUrl" (printf "%s/code/%s" $siteSourceUrl .path) -}}
|
||||
{{- $scratch.Set "bestPath" "" -}}
|
||||
{{- $filePath := .path -}}
|
||||
{{- range $path, $url := $submoduleLinks -}}
|
||||
{{- $bestLength := $scratch.Get "bestLength" -}}
|
||||
{{- if and (le $bestLength (len $path)) (hasPrefix $filePath $path) -}}
|
||||
{{- $scratch.Set "bestLength" (len $path) -}}
|
||||
{{- $scratch.Set "bestPath" $path -}}
|
||||
{{- $scratch.Set "bestUrl" (printf "%s%s" $url (strings.TrimPrefix $path $filePath)) -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- if .lines -}}
|
||||
{{- /* If the user provided a line range, see if we can tack it on to the end of the link. */ -}}
|
||||
{{- range $host, $data := $hostData -}}
|
||||
{{- if hasPrefix ($scratch.Get "bestUrl") $host -}}
|
||||
{{- with $data.linesSuffix -}}
|
||||
{{- $scratch.Add "bestUrl" (printf . (index $lines 0) (index $lines 1)) -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{ $scratch := .scratch }}
|
||||
{{ $scratch.Set "bestLength" -1 }}
|
||||
{{ $scratch.Set "bestUrl" (printf "https://dev.danilafe.com/Web-Projects/blog-static/src/branch/master/code/%s" .path) }}
|
||||
{{ $filePath := .path }}
|
||||
{{ range $module, $props := .submoduleLinks }}
|
||||
{{ $path := index $props "path" }}
|
||||
{{ $bestLength := $scratch.Get "bestLength" }}
|
||||
{{ if and (le $bestLength (len $path)) (hasPrefix $filePath $path) }}
|
||||
{{ $scratch.Set "bestLength" (len $path) }}
|
||||
{{ $scratch.Set "bestUrl" (printf "%s%s" (index $props "url") (strings.TrimPrefix $path $filePath)) }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<div class="highlight-group" {{ with .attrs }}{{ . | safeHTMLAttr }}{{ end }}>
|
||||
<div class="highlight-label">{{ i18n "from" }} <a href="{{ .url }}">{{ path.Base .path }}</a>{{ .comment }}</div>{{ .content }}
|
||||
<div class="highlight-group">
|
||||
<div class="highlight-label">From <a href="{{ .url }}">{{ path.Base .path }}</a>{{ .comment }}</div>{{ .content }}
|
||||
</div>
|
||||
|
||||
@@ -5,97 +5,35 @@
|
||||
{{ if .Description }}
|
||||
<meta name="description" content="{{ .Description }}">
|
||||
{{ end }}
|
||||
{{ with index (.GetTerms "series") 0 }}
|
||||
<meta name="blog-series" content="{{ .Data.Term }}">
|
||||
{{ end }}
|
||||
|
||||
{{ range .Params.discussionRooms }}
|
||||
<meta name="matrix-highlight-comments" content="{{ . }}">
|
||||
{{ end }}
|
||||
|
||||
<!-- Fonts -->
|
||||
{{ if not (.Site.Params.noCss) }}
|
||||
{{ $fonts := resources.Get "scss/fonts.scss" | css.Sass | resources.Minify }}
|
||||
<link rel="stylesheet" href="{{ $fonts.Permalink }}" media="screen">
|
||||
{{ end }}
|
||||
|
||||
<!-- External CSS (normalize and KaTeX -->
|
||||
{{ if not (.Site.Params.noCss) }}
|
||||
{{ partial "defercss.html" (dict "url" .Site.Params.normalizeCssUrl "extra" "") }}
|
||||
{{ partial "defercss.html" (dict "url" .Site.Params.katexCssUrl "extra" "") }}
|
||||
{{ end }}
|
||||
|
||||
<!-- Links to other formats (RSS, TOML) -->
|
||||
{{ range .Site.Home.AlternativeOutputFormats -}}
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inconsolata:wght@400;700&family=Raleway&family=Lora&display=block" media="screen">
|
||||
<link rel="preload" href="//cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css" as="style"
|
||||
onload="this.onload=null;this.rel='stylesheet'">
|
||||
<link rel="preload" href="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/katex.min.css" as="style"
|
||||
integrity="sha384-zB1R0rpPzHqg7Kpt0Aljp8JPLqbXI3bhnPWROx27a9N0Ll6ZP/+DiW/UqRcLbRjq"
|
||||
crossorigin="anonymous"
|
||||
onload="this.onload=null;this.rel='stylesheet'">
|
||||
<noscript>
|
||||
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css" media="screen" async>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/katex.min.css" integrity="sha384-zB1R0rpPzHqg7Kpt0Aljp8JPLqbXI3bhnPWROx27a9N0Ll6ZP/+DiW/UqRcLbRjq" crossorigin="anonymous" media="screen" async>
|
||||
</noscript>
|
||||
{{ range .AlternativeOutputFormats -}}
|
||||
<link rel="{{ .Rel }}" type="{{ .MediaType.Type | html }}" href="{{ .Permalink | safeURL }}">
|
||||
{{ end -}}
|
||||
|
||||
<!-- In-house CSS -->
|
||||
{{ $style := resources.Get "scss/style.scss" | css.Sass | resources.Minify }}
|
||||
{{ $sidenotes := resources.Get "scss/sidenotes.scss" | css.Sass | resources.Minify }}
|
||||
{{ $code := resources.Get "scss/code.scss" | css.Sass | resources.Minify }}
|
||||
{{ $style := resources.Get "scss/style.scss" | resources.ToCSS | resources.Minify }}
|
||||
{{ $sidenotes := resources.Get "scss/sidenotes.scss" | resources.ToCSS | resources.Minify }}
|
||||
{{ $code := resources.Get "scss/code.scss" | resources.ToCSS | resources.Minify }}
|
||||
{{ $icon := resources.Get "img/favicon.png" }}
|
||||
<style>.feather { display: inline !important; width: 10px; height: 10px; }</style>
|
||||
<style>img { max-width: 70%; }</style>
|
||||
{{ if not (.Site.Params.noCss) }}
|
||||
<link rel="stylesheet" href="{{ $style.Permalink }}">
|
||||
{{ partial "defercss.html" (dict "url" $sidenotes.Permalink "extra" "") }}
|
||||
{{ partial "defercss.html" (dict "url" $code.Permalink "extra" "") }}
|
||||
{{ end }}
|
||||
<style>.sidenote-checkbox { display: none; }</style>
|
||||
<style>.feather { width: 1rem; height: 1rem; }</style>
|
||||
<link rel="stylesheet" href="{{ $style.Permalink }}" media="screen">
|
||||
<link rel="stylesheet" href="{{ $sidenotes.Permalink }}" media="screen">
|
||||
<link rel="preload" href="{{ $code.Permalink }}" as="style"
|
||||
onload="this.onload=null;this.rel='stylesheet'">
|
||||
<noscript>
|
||||
<link rel="stylesheet" href="{{ $code.Permalink }}" media="screen">
|
||||
</noscript>
|
||||
<link rel="icon" type="image/png" href="{{ $icon.Permalink }}">
|
||||
|
||||
{{ if .Params.custom_js }}
|
||||
{{ range $customJs := .Params.custom_js }}
|
||||
<script src="{{ page.Resources.Get $customJs }}"></script>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{ if hugo.IsServer }}
|
||||
<!-- KaTeX auto-rendering for when we don't have a post-processing step. -->
|
||||
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.0/dist/katex.min.js" integrity="sha384-X/XCfMm41VSsqRNQgDerQczD69XqmjOOOwYQvr/uuC+j4OPoNhVgjdGFwhvN02Ja" crossorigin="anonymous"></script>
|
||||
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.0/dist/contrib/auto-render.min.js" integrity="sha384-+XBljXPPiv+OzfbB3cVmLHf4hdUFHlWNZN5spNQ7rmHTXpd7WvJum6fIACpNNfIR" crossorigin="anonymous"
|
||||
onload="renderMathInElement(document.body);"></script>
|
||||
{{ end }}
|
||||
|
||||
{{ if .Params.bergamot }}
|
||||
<!-- Ensure later scripts keep the KaTeX CSS even if the page has no LaTeX !-->
|
||||
<meta name="needs-latex">
|
||||
<!-- Code to support the Bergamot JS widget -->
|
||||
<script defer src="{{ .Site.Params.katexJsUrl }}" crossorigin="anonymous"></script>
|
||||
{{ $katexComponentJs := resources.Get "js/katex-component.js" | resources.Minify }}
|
||||
<script defer src="{{ $katexComponentJs.Permalink }}"></script>
|
||||
<script defer src="{{ .Site.Params.bergamotJsUrl }}"></script>
|
||||
<script defer src="{{ .Site.Params.bergamotObjectLanguageJsUrl }}"></script>
|
||||
{{ $bergamotHelpers := resources.Get "js/bergamot-helpers.js" | resources.Minify }}
|
||||
<script defer src="{{ $bergamotHelpers.Permalink }}"></script>
|
||||
{{ $bergamotStyle := resources.Get "scss/bergamot.scss" | css.Sass | resources.Minify }}
|
||||
{{ partial "defercss.html" (dict "url" $bergamotStyle.Permalink "extra" "") }}
|
||||
{{ if .Params.bergamot.render_presets }}
|
||||
{{ range $name, $rulefile := .Params.bergamot.render_presets }}
|
||||
{{ $file := default (resources.Get $rulefile) (page.Resources.Get $rulefile) }}
|
||||
{{ partial "bergamotrenderpreset.html" (dict "name" $name "file" $file.Content) }}
|
||||
{{ end }}
|
||||
{{ else }}
|
||||
{{ partial "bergamotrenderpreset.html" (dict "name" "default" "file" (resources.Get "bergamot/rendering/minimal.bergamot").Content) }}
|
||||
{{ end }}
|
||||
{{ if .Params.bergamot.presets }}
|
||||
{{ range $name, $preset := .Params.bergamot.presets }}
|
||||
{{ $file := default (resources.Get $preset.file) (page.Resources.Get $preset.file) }}
|
||||
{{ $info := dict "name" $name "prompt" $preset.prompt "query" $preset.query "file" $file.Content "renderPreset" $preset.render_preset "inputModes" $preset.input_modes }}
|
||||
{{ partial "bergamotpreset.html" $info }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ if .Params.bergamot.input_modes }}
|
||||
{{ range $mode := .Params.bergamot.input_modes }}
|
||||
{{ partial "bergamotinputmode.html" (dict "name" $mode.name "fn" $mode.fn) }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{ with .Site.Params.plausibleAnalyticsDomain }}
|
||||
<!-- Plausible analytics, because log parsing is not working all that well. -->
|
||||
<script defer data-domain="{{ . }}" src="https://plausible.io/js/script.js"></script>
|
||||
{{ end }}
|
||||
|
||||
<title>{{ .Title }}</title>
|
||||
</head>
|
||||
|
||||
@@ -1,20 +1,15 @@
|
||||
<div class="container">
|
||||
<h1>{{ .Site.Title }}</h1>
|
||||
<h1>Daniel's Blog</h1>
|
||||
</div>
|
||||
<nav>
|
||||
<div class="container">
|
||||
<a href="{{ .Site.Home.Permalink }}">{{ i18n "home" }}</a>
|
||||
<a href="{{ relref . "about" }}">{{ i18n "about" }}</a>
|
||||
{{ with .Site.Params.githubUsername }}
|
||||
<a href="https://github.com/{{ . }}">GitHub</a>
|
||||
{{ end }}
|
||||
{{ if .Site.Params.resumeStaticFile }}
|
||||
<a href="{{ absLangURL .Site.Params.resumeStaticFile }}">{{ i18n "resume" }}</a>
|
||||
{{ end }}
|
||||
<a href="{{ site.Taxonomies.tags.Page.Permalink }}">{{ i18n "tags" }}</a>
|
||||
<a href="{{ site.Taxonomies.series.Page.Permalink }}">{{ i18n "series" }}</a>
|
||||
<a href="{{ relref . "favorites" }}">{{ i18n "favorites" }}</a>
|
||||
<a href="{{ relref . "search" }}">{{ i18n "search" }}</a>
|
||||
<a href="{{ relref . "blog" }}">{{ i18n "allPosts" }}</a>
|
||||
<a href="/">Home</a>
|
||||
<a href="/about">About</a>
|
||||
<a href="https://github.com/DanilaFe">GitHub</a>
|
||||
<a href="/Resume-Danila-Fedorin.pdf">Resume</a>
|
||||
<a href="/tags">Tags</a>
|
||||
<a href="/favorites">Favorites</a>
|
||||
<a href="/search">Search</a>
|
||||
<a href="/blog">All Posts</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
@@ -1,11 +1 @@
|
||||
{{- $highlightGroupAttrs := (printf "data-base-path=\"%s\" data-file-path=\"%v\"" .basePath .path) -}}
|
||||
{{- if (or .firstLine .lastLine) -}}
|
||||
{{- $highlightGroupAttrs = add $highlightGroupAttrs (printf " data-first-line=\"%v\" data-last-line=\"%v\"" .firstLine .lastLine) -}}
|
||||
{{- end -}}
|
||||
{{- if eq (lower .language) "agda" -}}
|
||||
{{- $highlightGroupAttrs = add $highlightGroupAttrs " data-agda-block" -}}
|
||||
{{- end -}}
|
||||
{{- with .offset -}}
|
||||
{{- $highlightGroupAttrs = add $highlightGroupAttrs (printf " data-source-offset=\"%v\"" .) -}}
|
||||
{{- end -}}
|
||||
{{ partial "group.html" (dict "url" .url "path" .path "comment" .comment "content" (highlight .code .language .opts) "attrs" $highlightGroupAttrs) }}
|
||||
{{ partial "group.html" (dict "url" .url "path" .path "comment" .comment "content" (highlight .code .language .opts)) }}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
<svg class="feather" style="display: none;">
|
||||
<svg class="feather">
|
||||
<use xlink:href="/feather-sprite.svg#{{ . }}"/>
|
||||
</svg>
|
||||
{{- /* This comment is to remove trailing whitespace */ -}}
|
||||
|
||||
|
Before Width: | Height: | Size: 164 B After Width: | Height: | Size: 81 B |
@@ -1,9 +0,0 @@
|
||||
{{ if eq .from .to }}
|
||||
{{ .scratch.Set "comment" (printf ", line %d" .from) }}
|
||||
{{ else }}
|
||||
{{ if eq .from 0 }}
|
||||
{{ .scratch.Set "comment" (printf ", around line %d" .to) }}
|
||||
{{ else }}
|
||||
{{ .scratch.Set "comment" (printf ", lines %d through %d" .from .to) }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
@@ -1,8 +0,0 @@
|
||||
{{- $term := index (.page.GetTerms "series") 0 -}}
|
||||
{{- $divider := $term.Params.divider -}}
|
||||
{{- if (and $divider (strings.Contains .page.Title $divider)) -}}
|
||||
{{- $rest := after 1 (split .page.Title $divider) -}}
|
||||
{{- .scratch.Set "name" (delimit $rest $divider) -}}
|
||||
{{- else -}}
|
||||
{{- .scratch.Set "name" .page.Title -}}
|
||||
{{- end -}}
|
||||
@@ -1,27 +1,5 @@
|
||||
<li>
|
||||
{{- $scratch := newScratch -}}
|
||||
{{- if .seriesName -}}
|
||||
{{- partial "nameinseries" (dict "page" .page "scratch" $scratch) -}}
|
||||
{{- else -}}
|
||||
{{- $scratch.Set "name" (.page.Title) -}}
|
||||
{{- end -}}
|
||||
<a href="{{ .page.Permalink }}" class="post-title">{{ if .page.Params.favorite }}{{ partial "icon.html" "star" }}{{ end }} {{ $scratch.Get "name" }}</a>
|
||||
{{ if (not (eq .page.WordCount 0)) }}
|
||||
<p class="post-wordcount">{{ i18n "nWords" .page.WordCount }}, {{ i18n "nMinutesToRead" .page.ReadingTime }}.</p>
|
||||
{{ end }}
|
||||
{{ if .page.Params.status }}
|
||||
<p class="post-status">
|
||||
{{ partial "seriesstatus.html" .page.Params.status }}
|
||||
</p>
|
||||
{{ end }}
|
||||
<p class="post-preview">{{ partial "summary" .page }}</p>
|
||||
{{- if .linkSeries -}}
|
||||
{{- $term := index (.page.GetTerms "series") 0 -}}
|
||||
{{- with $term -}}
|
||||
<div class="series-link">
|
||||
{{- partial "icon.html" "corner-down-right" -}}
|
||||
<p>{{- i18n "latestInSeries" }} <a href="{{ $term.Permalink }}">{{ $term.Title }}</a></p>
|
||||
</div>
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
<a href="{{ .Permalink }}" class="post-title">{{ if .Params.favorite }}{{ partial "icon.html" "star" }}{{ end }} {{ .Title }}</a>
|
||||
<p class="post-wordcount">{{ .WordCount }} words, about {{ .ReadingTime }} minutes to read.</p>
|
||||
<p class="post-preview">{{ .Summary }} . . .</p>
|
||||
</li>
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
<div class="{{ .direction }} wrapper">
|
||||
<a href="{{ .page.RelPermalink }}">
|
||||
{{ if eq .direction "previous" }}{{ partial "icon.html" "chevrons-left" }}{{ end }}
|
||||
<div class="title-subtitle">
|
||||
{{ title .direction }} in Series
|
||||
{{ $scratch := newScratch -}}
|
||||
{{- partial "nameinseries.html" (dict "page" .page "scratch" $scratch) -}}
|
||||
<div class="title">{{ $scratch.Get "name" }}</div>
|
||||
</div>
|
||||
{{ if eq .direction "next" }}{{ partial "icon.html" "chevrons-right" }}{{ end }}
|
||||
</a>
|
||||
</div>
|
||||
@@ -1,10 +0,0 @@
|
||||
<div class="{{ .direction }} wrapper">
|
||||
<div class="ongoing-placeholder">
|
||||
{{ if eq .direction "previous" }}{{ partial "icon.html" "chevrons-left" }}{{ end }}
|
||||
<div class="title-subtitle">
|
||||
{{ title .direction }} in Series
|
||||
<div class="title">Coming soon!</div>
|
||||
</div>
|
||||
{{ if eq .direction "next" }}{{ partial "icon.html" "chevrons-right" }}{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,17 +0,0 @@
|
||||
{{- $page := . -}}
|
||||
{{- $term := index (.GetTerms "series") 0 -}}
|
||||
{{- with $term -}}
|
||||
{{- /* No idea why the 'Reverse' is needed? */ -}}
|
||||
{{- $pages := (site.Taxonomies.series.Get .Data.Term).Pages.ByDate.Reverse -}}
|
||||
<nav class="series-navigation">
|
||||
{{- with $pages.Prev $page -}}
|
||||
{{- partial "serieslink.html" (dict "direction" "previous" "page" .) -}}
|
||||
{{- end -}}
|
||||
{{- $nextPage := $pages.Next $page -}}
|
||||
{{- if $nextPage -}}
|
||||
{{- partial "serieslink.html" (dict "direction" "next" "page" $nextPage) -}}
|
||||
{{- else if eq $term.Params.status "ongoing" -}}
|
||||
{{- partial "serieslinkplaceholder.html" (dict "direction" "next") -}}
|
||||
{{- end -}}
|
||||
</nav>
|
||||
{{- end -}}
|
||||
@@ -1,4 +0,0 @@
|
||||
<span class="series-status {{ . }}">
|
||||
{{ i18n "seriesStatus" }}
|
||||
<span class="series-status-keyword">{{ i18n (printf "%sSeries" .) }}</span>
|
||||
</span>
|
||||
@@ -1,5 +0,0 @@
|
||||
{{- if .Params.summary -}}
|
||||
{{ .Params.summary }}
|
||||
{{- else -}}
|
||||
{{ .Summary | plainify | truncate 180 }}
|
||||
{{- end -}}
|
||||
@@ -1,14 +0,0 @@
|
||||
{{- $scratch := .scratch -}}
|
||||
{{- $scratch.Set "pages" slice -}}
|
||||
{{- $tmpScratch := newScratch -}}
|
||||
{{- range $post := (where (where site.Pages.ByDate.Reverse "Section" "blog") ".Kind" "!=" "section") -}}
|
||||
{{- $term := index ($post.GetTerms "series") 0 -}}
|
||||
{{- if $term -}}
|
||||
{{- if not ($tmpScratch.Get $term.Permalink) -}}
|
||||
{{- $tmpScratch.Set $term.Permalink true -}}
|
||||
{{- $scratch.Add "pages" $post -}}
|
||||
{{- end -}}
|
||||
{{- else -}}
|
||||
{{- $scratch.Add "pages" $post -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
@@ -1,3 +0,0 @@
|
||||
<div class="warning">
|
||||
<em>{{ i18n "warning" }}</em> {{ . }}
|
||||
</div>
|
||||
@@ -2,12 +2,12 @@
|
||||
<h2>{{ .Title }} </h2>
|
||||
{{ .Content }}
|
||||
|
||||
{{ $search := resources.Get "scss/search.scss" | css.Sass | resources.Minify }}
|
||||
{{ $search := resources.Get "scss/search.scss" | resources.ToCSS | resources.Minify }}
|
||||
<link rel="stylesheet" href="{{ $search.Permalink }}" media="screen">
|
||||
|
||||
<div class="stork-wrapper">
|
||||
<div class="stork-input-wrapper">
|
||||
<input class="stork-input" data-stork="blog" placeholder="{{ i18n "searchRequiresJS" }}"/>
|
||||
<input class="stork-input" data-stork="blog" placeholder="Search (requires JavaScript)"/>
|
||||
</div>
|
||||
<div class="stork-output" data-stork="blog-output"></div>
|
||||
</div>
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
{{ define "main" }}
|
||||
<h2>{{ .Title }}</h2>
|
||||
{{ $pages := .Pages.ByDate }}
|
||||
{{ $startYear := (index (last 1 .Pages) 0).Date.Format "2006" }}
|
||||
{{ $endYear := (index (first 1 .Pages) 0).Date.Format "2006" }}
|
||||
<div class="post-subscript">
|
||||
<p>{{ partial "seriesstatus.html" .Params.status }}</p>
|
||||
<p>{{ i18n "postsFromTo" (dict "from" $startYear "to" $endYear) }}</p>
|
||||
</div>
|
||||
<p>{{ partial "summary" . }}</p>
|
||||
|
||||
<ul class="post-list">
|
||||
{{ range $pages }}
|
||||
{{ partial "post.html" (dict "page" . "seriesName" true) }}
|
||||
{{ end }}
|
||||
</ul>
|
||||
{{ end }}
|
||||
@@ -1,10 +0,0 @@
|
||||
{{ define "main" }}
|
||||
<h2>{{ .Title }}</h2>
|
||||
{{ .Content }}
|
||||
|
||||
<ul class="post-list">
|
||||
{{ range sort .Pages "Title" }}
|
||||
{{ partial "post.html" (dict "page" .) }}
|
||||
{{ end }}
|
||||
</ul>
|
||||
{{ end }}
|
||||
@@ -1,21 +0,0 @@
|
||||
<div class="bergamot-exercise">
|
||||
<details open>
|
||||
<summary>
|
||||
<span class="bergamot-exercise-label">
|
||||
<span class="bergamot-exercise-number"></span>
|
||||
{{ if or (eq (.Get "label") "") (eq (.Get "label") nil) }}{{ else }}({{ .Get "label" }}){{ end }}:
|
||||
</span>
|
||||
</summary>
|
||||
{{ transform.Markdownify .Inner }}
|
||||
|
||||
<div class="bergamot-button-group">
|
||||
{{ if or (eq (.Get "preset") "") (eq (.Get "preset") nil) }}
|
||||
{{ else }}
|
||||
<button class="bergamot-button bergamot-play" onclick='window.Bergamot.runPreset(this.parentElement, "bergamot-widget-container-{{ .Get "id" }}", "{{ .Get "preset" }}")'>{{ partial "icon.html" "play" }}Start Bergamot</button>
|
||||
<button class="bergamot-button bergamot-close bergamot-hidden" onclick='window.Bergamot.close(this.parentElement, "bergamot-widget-container-{{ .Get "id" }}")'>{{ partial "icon.html" "x" }}Close Bergamot</button>
|
||||
{{ end }}
|
||||
</div>
|
||||
|
||||
<div id="bergamot-widget-container-{{ .Get "id" }}"></div>
|
||||
</details>
|
||||
</div>
|
||||
@@ -1,8 +0,0 @@
|
||||
<div id="{{ .Get "id" }}"></div>
|
||||
<script>
|
||||
window.addEventListener('load', function() {
|
||||
window.Bergamot.run(null, '{{ .Get "id" }}',
|
||||
{{ partial "bergamotparseinputmodes.js" (.Get "modes") | safeJS }},
|
||||
'{{ .Get "prompt" }}', '{{ .Inner }}', '{{ default "default" (.Get "rendering") }}', '{{ .Get "query" }}');
|
||||
});
|
||||
</script>
|
||||
@@ -1,3 +1,3 @@
|
||||
<div class="block">
|
||||
{{- .Inner -}}
|
||||
{{ .Inner }}
|
||||
</div>
|
||||
|
||||
@@ -1,12 +1,2 @@
|
||||
{{- $scratch := newScratch -}}
|
||||
{{- partial "geturl.html" (dict "scratch" $scratch "path" (.Get 1)) -}}
|
||||
{{- $groupconfig := dict
|
||||
"url" ($scratch.Get "bestUrl")
|
||||
"basePath" ($scratch.Get "bestPath")
|
||||
"path" (.Get 1)
|
||||
"comment" ", entire file"
|
||||
"code" (readFile (printf "code/%s" (.Get 1)))
|
||||
"language" (.Get 0)
|
||||
"opts" "linenos=table"
|
||||
-}}
|
||||
{{- partial "highlightgroup.html" $groupconfig -}}
|
||||
{{ partial "geturl.html" (dict "scratch" .Scratch "path" (.Get 1) "submoduleLinks" .Site.Params.submoduleLinks) }}
|
||||
{{ partial "highlightgroup.html" (dict "url" (.Scratch.Get "bestUrl") "path" (.Get 1) "comment" ", entire file" "code" (readFile (printf "code/%s" (.Get 1))) "language" (.Get 0) "opts" "linenos=table") }}
|
||||
|
||||
@@ -1,59 +1,23 @@
|
||||
{{- $source := (readFile (printf "code/%s" (.Get 1))) -}}
|
||||
{{- $allLines := split $source "\n" -}}
|
||||
{{- $scratch := newScratch -}}
|
||||
{{- $remLines := $allLines -}}
|
||||
{{- if not (eq (int (.Get 2)) 1) -}}
|
||||
{{- $remLines = after (sub (int (.Get 2)) 1) $allLines -}}
|
||||
{{- end -}}
|
||||
{{- $lines := first (add (sub (int (.Get 3)) (int (.Get 2))) 1) $remLines -}}
|
||||
{{ $source := (readFile (printf "code/%s" (.Get 1))) }}
|
||||
{{ $allLines := split $source "\n" }}
|
||||
{{ if not (eq (int (.Get 2)) 1) }}
|
||||
{{ .Scratch.Set "remLines" (after (sub (int (.Get 2)) 1) $allLines) }}
|
||||
{{ else }}
|
||||
{{ .Scratch.Set "remLines" $allLines }}
|
||||
{{ end }}
|
||||
{{ $lines := first (add (sub (int (.Get 3)) (int (.Get 2))) 1) (.Scratch.Get "remLines") }}
|
||||
|
||||
{{- $opts := "" -}}
|
||||
{{- if (.Get 4) -}}
|
||||
{{- $opts = printf ",%s" (.Get 4) -}}
|
||||
{{- end -}}
|
||||
{{ if (.Get 4) }}
|
||||
{{ .Scratch.Set "opts" (printf ",%s" (.Get 4)) }}
|
||||
{{ else }}
|
||||
{{ .Scratch.Set "opts" "" }}
|
||||
{{ end }}
|
||||
|
||||
{{- if (.Get 5) -}}
|
||||
{{- $scratch.Set "hidden" (.Get 5) -}}
|
||||
{{- end -}}
|
||||
{{ partial "geturl.html" (dict "scratch" .Scratch "path" (.Get 1) "submoduleLinks" .Site.Params.submoduleLinks) }}
|
||||
|
||||
{{- $prefixLength := "" -}}
|
||||
{{- $joinedLines := "" -}}
|
||||
{{- if or (.Page.Params.left_align_code) (.Get 6) -}}
|
||||
{{- $prefixLength = -1 -}}
|
||||
{{- range $line := $lines -}}
|
||||
{{- $leading := sub (len $line) (len (strings.TrimLeft " " $line)) -}}
|
||||
{{- if and (ne $line "") (or (eq $prefixLength -1) (le $leading $prefixLength)) -}}
|
||||
{{- $prefixLength = $leading -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- range $line := $lines -}}
|
||||
{{- $joinedLines = add $joinedLines (substr $line $prefixLength) -}}
|
||||
{{- $joinedLines = add $joinedLines "\n" -}}
|
||||
{{- end -}}
|
||||
{{- else -}}
|
||||
{{- $joinedLines = delimit $lines "\n" -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- partial "geturl.html" (dict "scratch" $scratch "path" (.Get 1) "lines" (slice (.Get 2) (.Get 3))) -}}
|
||||
{{- partial "linerangestr.html" (dict "scratch" $scratch "from" (.Get 2) "to" (.Get 3)) -}}
|
||||
|
||||
{{- with ($scratch.Get "hidden") -}}
|
||||
<details><summary>{{- . | markdownify -}}</summary>
|
||||
{{- end -}}
|
||||
{{- $groupconfig := dict
|
||||
"url" ($scratch.Get "bestUrl")
|
||||
"basePath" ($scratch.Get "bestPath")
|
||||
"path" (.Get 1)
|
||||
"comment" ($scratch.Get "comment")
|
||||
"code" $joinedLines
|
||||
"firstLine" (int (.Get 2))
|
||||
"lastLine" (int (.Get 3))
|
||||
"language" (.Get 0)
|
||||
"offset" $prefixLength
|
||||
"opts" (printf "linenos=table,linenostart=%d%s" (.Get 2) $opts)
|
||||
-}}
|
||||
{{- partial "highlightgroup.html" $groupconfig -}}
|
||||
{{- with ($scratch.Get "hidden") -}}
|
||||
</details>
|
||||
{{- end -}}
|
||||
{{ if eq (.Get 2) (.Get 3) }}
|
||||
{{ .Scratch.Set "comment" (printf ", line %d" (.Get 2)) }}
|
||||
{{ else }}
|
||||
{{ .Scratch.Set "comment" (printf ", lines %d through %d" (.Get 2) (.Get 3)) }}
|
||||
{{ end }}
|
||||
{{ partial "highlightgroup.html" (dict "url" (.Scratch.Get "bestUrl") "path" (.Get 1) "comment" (.Scratch.Get "comment") "code" (delimit $lines "\n") "language" (.Get 0) "opts" (printf "linenos=table,linenostart=%d%s" (.Get 2) (.Scratch.Get "opts"))) }}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
{{- $scratch := newScratch -}}
|
||||
{{- partial "geturl.html" (dict "scratch" $scratch "path" (.Get 0)) -}}
|
||||
{{- $scratch.Get "bestUrl" -}}
|
||||
@@ -1,4 +0,0 @@
|
||||
<details>
|
||||
<summary>{{- .Get "summary" | markdownify -}}</summary>
|
||||
{{- .Inner | markdownify -}}
|
||||
</details>
|
||||
@@ -1,3 +1,3 @@
|
||||
<p class="dialog">
|
||||
{{- .Inner -}}
|
||||
{{ .Inner }}
|
||||
</p>
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
{{- $page := site.GetPage (.Get 1) -}}
|
||||
{{- if $page -}}
|
||||
<a href="{{ $page.RelPermalink }}">{{ .Get 0 }}</a>
|
||||
{{- else -}}
|
||||
<span class="draft-link">{{ .Get 0 }} (coming soon)</span>
|
||||
{{- end -}}
|
||||
@@ -1,11 +0,0 @@
|
||||
{{- $repo := .Get 0 -}}
|
||||
{{- $commit := .Get 1 -}}
|
||||
{{- $file := .Get 2 -}}
|
||||
{{- $lang := .Get 3 -}}
|
||||
{{- $line := .Get 4 -}}
|
||||
{{- $lines := split (trim .Inner "\n") "\n" -}}
|
||||
|
||||
{{- $scratch := newScratch -}}
|
||||
{{- $url := printf "https://github.com/%s/blob/%s/%s#L%d" $repo $commit $file $line -}}
|
||||
{{- partial "linerangestr.html" (dict "scratch" $scratch "from" 0 "to" $line) -}}
|
||||
{{- partial "highlightgroup.html" (dict "url" $url "path" $file "comment" ($scratch.Get "comment") "code" (trim .Inner "\n") "language" $lang) -}}
|
||||
@@ -1,12 +0,0 @@
|
||||
{{- $name := .Get 0 -}}
|
||||
{{- $number := 1 -}}
|
||||
{{- with .Page.Scratch.Get "internal-ref-counter" -}}
|
||||
{{- $number = add . 1 }}
|
||||
{{- end -}}
|
||||
{{- .Page.Scratch.Set "internal-ref-counter" $number -}}
|
||||
{{- .Page.Scratch.SetInMap "internal-ref" $name $number -}}
|
||||
|
||||
<span class="internal-ref" id="internal-ref-{{ $name }}">
|
||||
{{ .Inner }}
|
||||
<span class="internal-ref-counter">{{ $number }}</span></span>
|
||||
{{- /* chomp whitespace at the end */ -}}
|
||||
@@ -1,7 +0,0 @@
|
||||
{{- $name := .Get 0 -}}
|
||||
{{- $number := index (.Page.Scratch.Get "internal-ref") $name -}}
|
||||
|
||||
<a href="#internal-ref-{{ $name }}">
|
||||
{{ .Inner }}
|
||||
<span class="internal-ref-counter">{{ $number }}</span></a>
|
||||
{{- /* chomp whitespace at the end */ -}}
|
||||
@@ -1,10 +1,10 @@
|
||||
<span class="message side-{{ .Get 0 }}">
|
||||
<span class="message-sender">
|
||||
{{- if (eq (.Get 1) "reader") -}}
|
||||
{{- partial "icon.html" "moon" -}}
|
||||
{{- else -}}
|
||||
{{- partial "icon.html" "sun" -}}
|
||||
{{- end -}}
|
||||
{{ if (eq (.Get 1) "reader") }}
|
||||
{{ partial "icon.html" "moon" }}
|
||||
{{ else }}
|
||||
{{ partial "icon.html" "sun" }}
|
||||
{{ end }}
|
||||
</span>
|
||||
<span class="message-text">{{- .Inner -}}</span>
|
||||
<span class="message-text">{{ .Inner }}</span>
|
||||
</span>
|
||||
|
||||
11
layouts/shortcodes/numberedsidenote.html
Normal file
11
layouts/shortcodes/numberedsidenote.html
Normal file
@@ -0,0 +1,11 @@
|
||||
{{ .Page.Scratch.Add "numbernote-id" 1 }}
|
||||
{{ $id := .Page.Scratch.Get "numbernote-id" }}
|
||||
<span class="sidenote">
|
||||
<label class="sidenote-label" for="numbernote-{{ $id }}">({{ $id }})</label>
|
||||
<input class="sidenote-checkbox" type="checkbox" id="numbernote-{{ $id }}"></input>
|
||||
<span class="sidenote-content sidenote-{{ .Get 0 }}">
|
||||
<span class="sidenote-delimiter">[note:</span>
|
||||
{{ .Inner }}
|
||||
<span class="sidenote-delimiter">]</span>
|
||||
</span>
|
||||
</span>
|
||||
@@ -1,10 +1,2 @@
|
||||
{{- $scratch := newScratch -}}
|
||||
{{- partial "geturl.html" (dict "scratch" $scratch "path" (.Get 0) "siteSourceUrl" .Site.Params.siteSourceUrl "submoduleLinks" .Site.Data.submodules) -}}
|
||||
{{- $groupconfig := dict
|
||||
"url" ($scratch.Get "bestUrl")
|
||||
"basePath" ($scratch.Get "bestPath")
|
||||
"path" (.Get 0)
|
||||
"comment" ", entire file"
|
||||
"content" (safeHTML (printf "<pre><code>%s</code></pre>" (htmlEscape (readFile (printf "code/%s" (.Get 0))))))
|
||||
-}}
|
||||
{{- partial "group.html" $groupconfig -}}
|
||||
{{ partial "geturl.html" (dict "scratch" .Scratch "path" (.Get 0) "submoduleLinks" .Site.Params.submoduleLinks) }}
|
||||
{{ partial "group.html" (dict "url" (.Scratch.Get "bestUrl") "path" (.Get 0) "comment" ", entire file" "content" (safeHTML (printf "<pre><code>%s</code></pre>" (htmlEscape (readFile (printf "code/%s" (.Get 0))))))) }}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
<div class="early-navigation-wrapper">
|
||||
{{ partial "seriesnav.html" .Page }}
|
||||
</div>
|
||||
@@ -1,3 +0,0 @@
|
||||
<div class="side-by-side">
|
||||
{{ .Inner }}
|
||||
</div>
|
||||
@@ -1,3 +0,0 @@
|
||||
<div class="side-by-side-item" {{ with .Get "weight" }} style="flex-grow: {{ . }};" {{ end }}>
|
||||
{{ .Inner }}
|
||||
</div>
|
||||
@@ -1,13 +1,9 @@
|
||||
<span class="sidenote">
|
||||
<label class="sidenote-label" for="{{- .Get 1 -}}">{{- .Get 2 | markdownify -}}</label>
|
||||
<input class="sidenote-checkbox" style="display: none;" type="checkbox" id="{{- .Get 1 -}}"></input>
|
||||
{{- if $offset := .Get 3 -}}
|
||||
<span class="sidenote-content sidenote-{{- .Get 0 -}}" style="margin-top: {{- $offset -}}rem">
|
||||
{{- else -}}
|
||||
<span class="sidenote-content sidenote-{{- .Get 0 -}}">
|
||||
{{- end -}}
|
||||
<span class="sidenote-delimiter">[{{- i18n "note" -}}:</span>
|
||||
{{- .Inner -}}
|
||||
<label class="sidenote-label" for="{{ .Get 1 }}">{{ .Get 2 }}</label>
|
||||
<input class="sidenote-checkbox" type="checkbox" id="{{ .Get 1 }}"></input>
|
||||
<span class="sidenote-content sidenote-{{ .Get 0 }}">
|
||||
<span class="sidenote-delimiter">[note:</span>
|
||||
{{ .Inner }}
|
||||
<span class="sidenote-delimiter">]</span>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
3
layouts/shortcodes/todo.html
Normal file
3
layouts/shortcodes/todo.html
Normal file
@@ -0,0 +1,3 @@
|
||||
<div style="background-color: tomato; color: white; padding: 10px;">
|
||||
<em>TODO: </em>{{ .Inner }}
|
||||
</div>
|
||||
@@ -1,9 +1,9 @@
|
||||
{{ define "main" }}
|
||||
<h2>{{ i18n "tagged" .Title }}</h2>
|
||||
<h2>Tagged "{{ .Title }}"</h2>
|
||||
|
||||
<ul class="post-list">
|
||||
{{ range .Pages.ByDate.Reverse }}
|
||||
{{ partial "post.html" (dict "page" .) }}
|
||||
{{ partial "post.html" . }}
|
||||
{{ end }}
|
||||
</ul>
|
||||
{{ end }}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{{ define "main" }}
|
||||
<h2>{{ .Title }}</h2>
|
||||
{{ .Content }}
|
||||
Below is a list of all the tags ever used on this site.
|
||||
|
||||
<ul>
|
||||
{{ range sort .Pages "Title" }}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,53 +0,0 @@
|
||||
import { nodes, edges } from "./graph.gen.js";
|
||||
|
||||
var container = document.getElementById("graph-container");
|
||||
var options = {
|
||||
interaction: {
|
||||
hover: true
|
||||
},
|
||||
nodes: {
|
||||
shape: "dot",
|
||||
size: 16,
|
||||
},
|
||||
physics: {
|
||||
forceAtlas2Based: {
|
||||
gravitationalConstant: -10,
|
||||
centralGravity: 0.005,
|
||||
springLength: 230,
|
||||
springConstant: 0.18,
|
||||
},
|
||||
maxVelocity: 146,
|
||||
solver: "forceAtlas2Based",
|
||||
timestep: 0.35,
|
||||
stabilization: { iterations: 150 },
|
||||
},
|
||||
};
|
||||
|
||||
var nodesDs = new vis.DataSet();
|
||||
nodesDs.add(nodes);
|
||||
var edgesDs = new vis.DataSet();
|
||||
edgesDs.add(edges);
|
||||
var network = new vis.Network(container, { nodes: nodesDs, edges: edgesDs }, options);
|
||||
|
||||
network.on("doubleClick", function (params) {
|
||||
params.event = "[original event]";
|
||||
if (params.nodes.length !== 1) return;
|
||||
window.open(nodesDs.get(params.nodes[0]).url, "_blank")
|
||||
});
|
||||
network.on("hoverNode", function (params) {
|
||||
nodesDs.update({ id: params.node, label: nodesDs.get(params.node).name });
|
||||
});
|
||||
network.on("blurNode", function (params) {
|
||||
nodesDs.update({ id: params.node, label: undefined });
|
||||
});
|
||||
// network.on("selectNode", function (params) {
|
||||
// for (const node of params.nodes) {
|
||||
// nodesDs.update({ id: node, label: nodesDs.get(node).name });
|
||||
// }
|
||||
// });
|
||||
// network.on("deselectNode", function (params) {
|
||||
// for (const node of params.previousSelection.nodes) {
|
||||
// if (params.nodes.some(n => n === node)) continue;
|
||||
// nodesDs.update({ id: node, label: undefined });
|
||||
// }
|
||||
// });
|
||||
Reference in New Issue
Block a user