Got independent scroll behavior that I wanted.

The good news is that I have the independent scroll behavior that
I wanted.  There are two bits of bad news. The first is that I don't
UNDERSTAND why this particular configuration, with an extra level of
nesting, made any difference.

The bigger problem is that I still don't see the scroll bars showing
up at all.  And that annoys me.  I should see them, right?
This commit is contained in:
Elf M. Sternberg 2022-06-09 19:16:35 -07:00
parent 58cf0c9cbd
commit bfb15b0f19
6 changed files with 440 additions and 66 deletions

40
content/scala/_index.md Normal file
View File

@ -0,0 +1,40 @@
+++
title = "Scala"
description = "Learning Scala"
date = 2022-06-09T14:45:57-0700
updated = 2022-06-09T14:45:57-0700
template = "section.html"
sort_by = "weight"
weight = 6
draft = false
[taxonomies]
documentation=["Reference"]
categories=["Scala", "Coursier", "Work-Related"]
+++
[Scala](https://scala-long.org) is a programming language. It has strong
typing, but is built on top of the JVM, so it has access to all of the JVM's
libraries.
## Installing
The easiest way to install Scala is to install
[Coursier](https://get-coursier.io/docs/overview), the Scala "artifact manager."
It installs versions of the Scala language, toolset, and even specific versions
of the JVM. Coursier is installed with a CURL command and, when that is
complete, your Scala environment can be initialized with
```shell
$ cs setup
```
## Emacs Tools
So far, I've installed:
- lsp-metal
- scala-mode
- sbt-mode
## Hello World

View File

@ -2,42 +2,42 @@
:root { :root {
--step--2: calc(clamp(0.52rem, calc(0.43rem + 0.45vw), 0.72rem)); --step--2: clamp(0.52rem, calc(0.47rem + 0.23vw), 0.64rem);
--step--1: calc(clamp(0.63rem, calc(0.50rem + 0.63vw), 0.90rem)); --step--1: clamp(0.63rem, calc(0.56rem + 0.34vw), 0.80rem);
--step-0: calc(clamp(0.75rem, calc(0.58rem + 0.85vw), 1.13rem)); --step-0: clamp(0.75rem, calc(0.65rem + 0.49vw), 1.00rem);
--step-1: calc(clamp(0.90rem, calc(0.67rem + 1.15vw), 1.41rem)); --step-1: clamp(0.90rem, calc(0.76rem + 0.68vw), 1.25rem);
--step-2: calc(clamp(1.08rem, calc(0.77rem + 1.54vw), 1.76rem)); --step-2: clamp(1.08rem, calc(0.89rem + 0.94vw), 1.56rem);
--step-3: calc(clamp(1.30rem, calc(0.89rem + 2.05vw), 2.20rem)); --step-3: clamp(1.30rem, calc(1.04rem + 1.28vw), 1.95rem);
--step-4: calc(clamp(1.56rem, calc(1.01rem + 2.71vw), 2.75rem)); --step-4: clamp(1.56rem, calc(1.21rem + 1.73vw), 2.44rem);
--step-5: calc(clamp(1.87rem, calc(1.15rem + 3.56vw), 3.43rem)); --step-5: clamp(1.87rem, calc(1.40rem + 2.31vw), 3.05rem);
--half-step-0: calc(clamp(0.75rem, calc(0.58rem + 0.85vw), 1.13rem) / 2); --half-step-0: calc(clamp(0.75rem, calc(0.58rem + 0.85vw), 1.13rem) / 2);
} }
/* @link https://utopia.fyi/space/calculator?c=320,12,1.2,1024,24,1.25,5,2,&s=0.75|0.5|0.25,1.5|2|3|4|6,s-l|xs-m */ /* @link https://utopia.fyi/space/calculator?c=320,12,1.2,1024,24,1.25,5,2,&s=0.75|0.5|0.25,1.5|2|3|4|6,s-l|xs-m */
:root { :root {
--space-3xs: calc(clamp(0.19rem, calc(0.1rem + 0.43vw), 0.38rem)); --space-3xs: clamp(0.19rem, calc(0.16rem + 0.12vw), 0.25rem);
--space-2xs: calc(clamp(0.38rem, calc(0.2rem + 0.85vw), 0.75rem)); --space-2xs: clamp(0.38rem, calc(0.33rem + 0.24vw), 0.50rem);
--space-xs: calc(clamp(0.56rem, calc(0.31rem + 1.28vw), 1.13rem)); --space-xs: clamp(0.56rem, calc(0.49rem + 0.37vw), 0.75rem);
--space-s: calc(clamp(0.75rem, calc(0.41rem + 1.7vw), 1.5rem)); --space-s: clamp(0.75rem, calc(0.65rem + 0.49vw), 1.00rem);
--space-m: calc(clamp(1.13rem, calc(0.61rem + 2.56vw), 2.25rem)); --space-m: clamp(1.13rem, calc(0.98rem + 0.73vw), 1.50rem);
--space-l: calc(clamp(1.5rem, calc(0.82rem + 3.41vw), 3rem)); --space-l: clamp(1.50rem, calc(1.30rem + 0.98vw), 2.00rem);
--space-xl: calc(clamp(2.25rem, calc(1.23rem + 5.11vw), 4.5rem)); --space-xl: clamp(2.25rem, calc(1.96rem + 1.46vw), 3.00rem);
--space-2xl: calc(clamp(3rem, calc(1.64rem + 6.82vw), 6rem)); --space-2xl: clamp(3.00rem, calc(2.61rem + 1.95vw), 4.00rem);
--space-3xl: calc(clamp(4.5rem, calc(2.45rem + 10.23vw), 9rem)); --space-3xl: clamp(4.50rem, calc(3.91rem + 2.93vw), 6.00rem);
/* One-up pairs */ /* One-up pairs */
--space-3xs-2xs: calc(clamp(0.19rem, calc(-0.07rem + 1.28vw), 0.75rem)); --space-3xs-2xs: clamp(0.19rem, calc(0.07rem + 0.61vw), 0.50rem);
--space-2xs-xs: calc(clamp(0.38rem, calc(0.03rem + 1.7vw), 1.13rem)); --space-2xs-xs: clamp(0.38rem, calc(0.23rem + 0.73vw), 0.75rem);
--space-xs-s: calc(clamp(0.56rem, calc(0.14rem + 2.13vw), 1.5rem)); --space-xs-s: clamp(0.56rem, calc(0.39rem + 0.85vw), 1.00rem);
--space-s-m: calc(clamp(0.75rem, calc(0.07rem + 3.41vw), 2.25rem)); --space-s-m: clamp(0.75rem, calc(0.46rem + 1.46vw), 1.50rem);
--space-m-l: calc(clamp(1.13rem, calc(0.27rem + 4.26vw), 3rem)); --space-m-l: clamp(1.13rem, calc(0.78rem + 1.71vw), 2.00rem);
--space-l-xl: calc(clamp(1.5rem, calc(0.14rem + 6.82vw), 4.5rem)); --space-l-xl: clamp(1.50rem, calc(0.91rem + 2.93vw), 3.00rem);
--space-xl-2xl: calc(clamp(2.25rem, calc(0.55rem + 8.52vw), 6rem)); --space-xl-2xl: clamp(2.25rem, calc(1.57rem + 3.41vw), 4.00rem);
--space-2xl-3xl: calc(clamp(3rem, calc(0.27rem + 13.64vw), 9rem)); --space-2xl-3xl: clamp(3.00rem, calc(1.83rem + 5.85vw), 6.00rem);
/* Custom pairs */ /* Custom pairs */
--space-s-l: calc(clamp(0.75rem, calc(-0.27rem + 5.11vw), 3rem)); --space-s-l: clamp(0.75rem, calc(0.26rem + 2.44vw), 2.00rem);
--space-xs-m: calc(clamp(0.56rem, calc(-0.2rem + 3.84vw), 2.25rem)); --space-xs-m: clamp(0.56rem, calc(0.20rem + 1.83vw), 1.50rem);
--space-3xs-l: clamp(0.19rem, calc(-1.09rem + 6.39vw), 3.00rem); --space-3xs-l: clamp(0.19rem, calc(-0.52rem + 3.54vw), 2.00rem);
} }

View File

@ -21,7 +21,12 @@
display: none; display: none;
} }
html {
height: 100%;
}
body { body {
height: 100%;
padding-top: var(--header-size); padding-top: var(--header-size);
font-size: var(--default-font-size); font-size: var(--default-font-size);
font-family: "Nunito", sans-serif; font-family: "Nunito", sans-serif;
@ -82,7 +87,7 @@ body {
font-weight: 400; font-weight: 400;
line-height: 1.5; line-height: 1.5;
color: #1d2d35; color: #1d2d35;
text-align: cent er; text-align: cent er;
vertical-align: middle; vertical-align: middle;
user-select: none; user-select: none;
background-color: transparent; background-color: transparent;
@ -148,59 +153,64 @@ body {
@mixin toc-sticky { @mixin toc-sticky {
max-width: 100%; max-width: 100%;
top: var(--header-size);
height: calc(100vh - var(--header-size));
position: sticky; position: sticky;
top: var(--space-xl);
height: calc(100vh - var(--space-xl));
z-index: 900; z-index: 900;
scrollbar-width: thin;
scrollbar-color: #fff #fff;
&:hover .scrollable-sidebar { &:hover {
scrollbar-color: #e9ecef #fff; scrollbar-color: #e9ecef #fff;
} }
.scrollable-sidebar { .scrollable-sidebar {
scrollbar-width: thin;
scrollbar-color: #fff #fff;
display: block; display: block;
width: auto; width: auto;
overflow-y: scroll; overflow-y: auto;
padding-bottom: 4rem; padding-bottom: 4rem;
ul {
padding-left: 0;
padding-bottom: var(--step--1);
list-style: none;
ul {
padding-left: var(--space-s);
list-style: disc;
}
}
} }
} }
.main { .main {
height: 100%;
display: flex; display: flex;
position: relative; flex-direction: row;
flex-wrap: nowrap; flex-wrap: nowrap;
ul { & > * {
padding-left: 0; padding-top: var(--space-m);
padding-bottom: var(--step--1);
list-style: none;
ul {
padding-left: var(--space-s);
list-style: disc;
}
} }
.left-sidebar { .left-sidebar {
@include toc-sticky(); @include toc-sticky();
font-size: 80%; font-size: 95%;
order: 0; order: 0;
flex: 0 1 auto; flex: 0 1 auto;
width: 25%; width: 25%;
padding-right: var(--space-2xs); padding-right: var(--space-s);
border-right: 1px solid var(--border-color); border-right: 1px solid var(--border-color);
} }
.docs-toc { .docs-toc {
@include toc-sticky(); @include toc-sticky();
font-size: 66.666%; font-size: 85%;
order: 2; order: 2;
flex: 0 0 auto; flex: 0 0 auto;
width: 18.75%; width: 18.75%;
border-left: 1px solid var(--border-color); border-left: 1px solid var(--border-color);
padding-left: var(--space-2xs); padding-left: var(--space-s);
nav > ul { nav > ul {
& > li:not(:first-child) { & > li:not(:first-child) {
@ -218,9 +228,8 @@ body {
article { article {
order: 1; order: 1;
padding: 0 var(--space-s) var(--space-m-l) var(--space-s); padding: var(--space-m) var(--space-s) var(--space-m-l) var(--space-s);
flex: 0 0 auto; flex: 0 0 auto;
width: 56.25%; width: 56.25%;
} }
} }

14
static/main.js Normal file
View File

@ -0,0 +1,14 @@
// Set darkmode
document.getElementById('mode').addEventListener('click', () => {
document.body.classList.toggle('dark');
localStorage.setItem('theme', document.body.classList.contains('dark') ? 'dark' : 'light');
});
// enforce local storage setting but also fallback to user-agent preferences
if (localStorage.getItem('theme') === 'dark' || (!localStorage.getItem('theme') && window.matchMedia("(prefers-color-scheme: dark)").matches)) {
document.body.classList.add('dark');
}

309
static/search.js Normal file
View File

@ -0,0 +1,309 @@
var suggestions = document.getElementById("suggestions");
var userinput = document.getElementById("userinput");
document.addEventListener("keydown", inputFocus);
function inputFocus(e) {
if (
e.keyCode === 191 &&
document.activeElement.tagName !== "INPUT" &&
document.activeElement.tagName !== "TEXTAREA"
) {
e.preventDefault();
userinput.focus();
}
if (e.keyCode === 27) {
userinput.blur();
suggestions.classList.add("d-none");
}
}
document.addEventListener("click", function(event) {
var isClickInsideElement = suggestions.contains(event.target);
if (!isClickInsideElement) {
suggestions.classList.add("d-none");
}
});
/*
Source:
- https://dev.to/shubhamprakash/trap-focus-using-javascript-6a3
*/
document.addEventListener("keydown", suggestionFocus);
function suggestionFocus(e) {
const focusableSuggestions = suggestions.querySelectorAll("a");
if (suggestions.classList.contains("d-none") || focusableSuggestions.length === 0) {
return;
}
const focusable = [...focusableSuggestions];
const index = focusable.indexOf(document.activeElement);
let nextIndex = 0;
if (e.keyCode === 38) {
e.preventDefault();
nextIndex = index > 0 ? index - 1 : 0;
focusableSuggestions[nextIndex].focus();
} else if (e.keyCode === 40) {
e.preventDefault();
nextIndex = index + 1 < focusable.length ? index + 1 : index;
focusableSuggestions[nextIndex].focus();
}
}
/*
Source:
- https://github.com/nextapps-de/flexsearch#index-documents-field-search
- https://raw.githack.com/nextapps-de/flexsearch/master/demo/autocomplete.html
- http://elasticlunr.com/
- https://github.com/getzola/zola/blob/master/docs/static/search.js
*/
(function() {
var index = elasticlunr.Index.load(window.searchIndex);
userinput.addEventListener("input", show_results, true);
suggestions.addEventListener("click", accept_suggestion, true);
function show_results() {
var value = this.value.trim();
var options = {
bool: "OR",
fields: {
title: { boost: 2 },
body: { boost: 1 },
},
};
var results = index.search(value, options);
var entry,
childs = suggestions.childNodes;
var i = 0,
len = results.length;
var items = value.split(/\s+/);
suggestions.classList.remove("d-none");
results.forEach(function(page) {
if (page.doc.body !== "") {
entry = document.createElement("div");
entry.innerHTML = "<a href><span></span><span></span></a>";
(a = entry.querySelector("a")),
(t = entry.querySelector("span:first-child")),
(d = entry.querySelector("span:nth-child(2)"));
a.href = page.ref;
t.textContent = page.doc.title;
d.innerHTML = makeTeaser(page.doc.body, items);
suggestions.appendChild(entry);
}
});
while (childs.length > len) {
suggestions.removeChild(childs[i]);
}
}
function accept_suggestion() {
while (suggestions.lastChild) {
suggestions.removeChild(suggestions.lastChild);
}
return false;
}
// Taken from mdbook
// The strategy is as follows:
// First, assign a value to each word in the document:
// Words that correspond to search terms (stemmer aware): 40
// Normal words: 2
// First word in a sentence: 8
// Then use a sliding window with a constant number of words and count the
// sum of the values of the words within the window. Then use the window that got the
// maximum sum. If there are multiple maximas, then get the last one.
// Enclose the terms in <b>.
function makeTeaser(body, terms) {
var TERM_WEIGHT = 40;
var NORMAL_WORD_WEIGHT = 2;
var FIRST_WORD_WEIGHT = 8;
var TEASER_MAX_WORDS = 30;
var stemmedTerms = terms.map(function(w) {
return elasticlunr.stemmer(w.toLowerCase());
});
var termFound = false;
var index = 0;
var weighted = []; // contains elements of ["word", weight, index_in_document]
// split in sentences, then words
var sentences = body.toLowerCase().split(". ");
for (var i in sentences) {
var words = sentences[i].split(/[\s\n]/);
var value = FIRST_WORD_WEIGHT;
for (var j in words) {
var word = words[j];
if (word.length > 0) {
for (var k in stemmedTerms) {
if (elasticlunr.stemmer(word).startsWith(stemmedTerms[k])) {
value = TERM_WEIGHT;
termFound = true;
}
}
weighted.push([word, value, index]);
value = NORMAL_WORD_WEIGHT;
}
index += word.length;
index += 1; // ' ' or '.' if last word in sentence
}
index += 1; // because we split at a two-char boundary '. '
}
if (weighted.length === 0) {
if (body.length !== undefined && body.length > TEASER_MAX_WORDS * 10) {
return body.substring(0, TEASER_MAX_WORDS * 10) + "...";
} else {
return body;
}
}
var windowWeights = [];
var windowSize = Math.min(weighted.length, TEASER_MAX_WORDS);
// We add a window with all the weights first
var curSum = 0;
for (var i = 0; i < windowSize; i++) {
curSum += weighted[i][1];
}
windowWeights.push(curSum);
for (var i = 0; i < weighted.length - windowSize; i++) {
curSum -= weighted[i][1];
curSum += weighted[i + windowSize][1];
windowWeights.push(curSum);
}
// If we didn't find the term, just pick the first window
var maxSumIndex = 0;
if (termFound) {
var maxFound = 0;
// backwards
for (var i = windowWeights.length - 1; i >= 0; i--) {
if (windowWeights[i] > maxFound) {
maxFound = windowWeights[i];
maxSumIndex = i;
}
}
}
var teaser = [];
var startIndex = weighted[maxSumIndex][2];
for (var i = maxSumIndex; i < maxSumIndex + windowSize; i++) {
var word = weighted[i];
if (startIndex < word[2]) {
// missing text from index to start of `word`
teaser.push(body.substring(startIndex, word[2]));
startIndex = word[2];
}
// add <em/> around search terms
if (word[1] === TERM_WEIGHT) {
teaser.push("<b>");
}
startIndex = word[2] + word[0].length;
// Check the string is ascii characters or not
var re = /^[\x00-\xff]+$/;
if (word[1] !== TERM_WEIGHT && word[0].length >= 12 && !re.test(word[0])) {
// If the string's length is too long, it maybe a Chinese/Japance/Korean article
// if using substring method directly, it may occur error codes on emoji chars
var strBefor = body.substring(word[2], startIndex);
var strAfter = substringByByte(strBefor, 12);
teaser.push(strAfter);
} else {
teaser.push(body.substring(word[2], startIndex));
}
if (word[1] === TERM_WEIGHT) {
teaser.push("</b>");
}
}
teaser.push("…");
return teaser.join("");
}
})();
// Get substring by bytes
// If using JavaScript inline substring method, it will return error codes
// Source: https://www.52pojie.cn/thread-1059814-1-1.html
function substringByByte(str, maxLength) {
var result = "";
var flag = false;
var len = 0;
var length = 0;
var length2 = 0;
for (var i = 0; i < str.length; i++) {
var code = str.codePointAt(i).toString(16);
if (code.length > 4) {
i++;
if (i + 1 < str.length) {
flag = str.codePointAt(i + 1).toString(16) == "200d";
}
}
if (flag) {
len += getByteByHex(code);
if (i == str.length - 1) {
length += len;
if (length <= maxLength) {
result += str.substr(length2, i - length2 + 1);
} else {
break;
}
}
} else {
if (len != 0) {
length += len;
length += getByteByHex(code);
if (length <= maxLength) {
result += str.substr(length2, i - length2 + 1);
length2 = i + 1;
} else {
break;
}
len = 0;
continue;
}
length += getByteByHex(code);
if (length <= maxLength) {
if (code.length <= 4) {
result += str[i];
} else {
result += str[i - 1] + str[i];
}
length2 = i + 1;
} else {
break;
}
}
}
return result;
}
// Get the string bytes from binary
function getByteByBinary(binaryCode) {
// Binary system, starts with `0b` in ES6
// Octal number system, starts with `0` in ES5 and starts with `0o` in ES6
// Hexadecimal, starts with `0x` in both ES5 and ES6
var byteLengthDatas = [0, 1, 2, 3, 4];
var len = byteLengthDatas[Math.ceil(binaryCode.length / 8)];
return len;
}
// Get the string bytes from hexadecimal
function getByteByHex(hexCode) {
return getByteByBinary(parseInt(hexCode, 16).toString(2));
}

View File

@ -4,13 +4,15 @@
{% block content %} {% block content %}
<div class="container" role="document"> <div class="container" role="document">
<div class="main"> <div class="content">
{% include "components/left-sidebar-singleton.html" %} <div class="main">
{% include "components/right-sidebar.html" %} {% include "components/left-sidebar-singleton.html" %}
<article> {% include "components/right-sidebar.html" %}
<h1 class="text-center">{{ section.title }}</h1> <article>
<div class="text-center">{{ section.content | safe }}</div> <h1 class="text-center">{{ section.title }}</h1>
</article> <div class="text-center">{{ section.content | safe }}</div>
</article>
</div>
</div> </div>
</div> </div>
{% endblock content %} {% endblock content %}