hematite 0.1.9 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/_config.yml +2 -1
- data/_includes/nav/header.html +6 -1
- data/_includes/scss/_fonts.scss +5 -0
- data/_layouts/remark_slideshow.html +3 -0
- data/_sass/_elements.scss +15 -0
- data/_sass/_nav.scss +28 -0
- data/assets/fonts/FoulisGreek.ttf +0 -0
- data/assets/fonts/README.txt +8 -0
- data/assets/html/remark_presentation_frame.html +8 -3
- data/assets/js/dropdownExpander.mjs +7 -4
- data/assets/js/layout/post.mjs +5 -0
- data/assets/js/layout/remark_slideshow.mjs +73 -14
- data/assets/js/main.mjs +2 -0
- data/assets/js/scrollables.mjs +29 -0
- data/assets/string_data/en.mjs +1 -0
- data/assets/string_data/es.mjs +1 -0
- data/assets/style.scss +2 -0
- data/assets/style_only_syntax.scss +1 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7d562db0ed2225f8650bd5c5f4a463b484254df5c5b6324eb7b2febf6f072e0d
|
4
|
+
data.tar.gz: 415dee3a5e09d9e84f0f2abb907f613bf68edf2a5224816995462148155415ad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f36ce4207f588d36389548a4755140b78738731be85582c8208e7092940254613e5241417825c7a47d0322b606be5958fd46ed593d971e5dc70ecd9b5a506357
|
7
|
+
data.tar.gz: daf31b575712939d9de6b0fd0c0500727736fd2da81e9e70c7eff7b2229c07f269ad3394c2231542c9594b2c65dccf08ebfa261ab1d42a10ac12782d9ccf82bf
|
data/_config.yml
CHANGED
data/_includes/nav/header.html
CHANGED
@@ -2,4 +2,9 @@
|
|
2
2
|
This is the header that appears in the navigation bar (at the top of the page)!
|
3
3
|
Customize it here.
|
4
4
|
{% endcomment %}
|
5
|
-
<a href="{{ "/" | absolute_url }}">
|
5
|
+
<a id="long_title" href="{{ "/" | absolute_url }}">
|
6
|
+
{{ site.title | default: "Untitled Site" }}
|
7
|
+
</a>
|
8
|
+
<a id="short_title" href="{{ "/" | absolute_url }}">
|
9
|
+
{{ site.short_title | default: site.title | default: "Untitiled" }}
|
10
|
+
</a>
|
@@ -35,9 +35,11 @@ layout: default
|
|
35
35
|
const WRAPPING_DIV_EXP = /^\s*[<]div.*[>]((?:.|[\n\r])*)[<]\/div[>]\s*$/;
|
36
36
|
|
37
37
|
import slideshow from "{{ 'assets/js/layout/remark_slideshow.mjs' | relative_url }}";
|
38
|
+
import { stringLookup } from "{{ 'assets/js/strings.mjs' | relative_url }}";
|
38
39
|
|
39
40
|
let presentationFrame = document.querySelector("#presentation_frame");
|
40
41
|
presentationFrame.src = {{ frame_resource_url | jsonify }};
|
42
|
+
presentationFrame.title = stringLookup('presentation_frame_title');
|
41
43
|
window.presentationFrameLoaded = false;
|
42
44
|
|
43
45
|
|
@@ -111,6 +113,7 @@ layout: default
|
|
111
113
|
`);
|
112
114
|
|
113
115
|
presentationWin.initPresentation = (async () => {
|
116
|
+
presentationDoc.title = presentationFrame.title;
|
114
117
|
await slideshow.start(presentationFrame.contentWindow, config);
|
115
118
|
|
116
119
|
// Ensure that mermaid has already been run!
|
data/_sass/_elements.scss
CHANGED
@@ -64,6 +64,10 @@ input::placeholder {
|
|
64
64
|
padding: 6px;
|
65
65
|
}
|
66
66
|
|
67
|
+
main pre {
|
68
|
+
overflow-x: auto;
|
69
|
+
}
|
70
|
+
|
67
71
|
.main-container details {
|
68
72
|
summary {
|
69
73
|
cursor: pointer;
|
@@ -142,6 +146,17 @@ input::placeholder {
|
|
142
146
|
padding-left: 20px;
|
143
147
|
color: var(--text-color-faint);
|
144
148
|
}
|
149
|
+
|
150
|
+
main {
|
151
|
+
// Some elements can grow larger than the available space.
|
152
|
+
// Allow scrolling.
|
153
|
+
@media screen {
|
154
|
+
.scrollable-container {
|
155
|
+
overflow-x: auto;
|
156
|
+
display: block;
|
157
|
+
}
|
158
|
+
}
|
159
|
+
}
|
145
160
|
}
|
146
161
|
|
147
162
|
// Markdown parsers may put `code` elements inside of `pre`
|
data/_sass/_nav.scss
CHANGED
@@ -29,6 +29,10 @@ body > header {
|
|
29
29
|
align-items: center;
|
30
30
|
}
|
31
31
|
|
32
|
+
#short_title {
|
33
|
+
display: none;
|
34
|
+
}
|
35
|
+
|
32
36
|
#toggle_sidebar_btn {
|
33
37
|
margin-right: 10px;
|
34
38
|
background-color: var(--primary-background-color);
|
@@ -38,9 +42,33 @@ body > header {
|
|
38
42
|
#toggle_sidebar_btn {
|
39
43
|
display: none;
|
40
44
|
}
|
45
|
+
|
46
|
+
box-shadow: none;
|
47
|
+
border-bottom: 1px solid var(--line-color-light);
|
41
48
|
}
|
42
49
|
}
|
43
50
|
|
51
|
+
@mixin only-short-title {
|
52
|
+
body > header {
|
53
|
+
#long_title {
|
54
|
+
display: none !important;
|
55
|
+
color: red;
|
56
|
+
}
|
57
|
+
|
58
|
+
#short_title {
|
59
|
+
display: block;
|
60
|
+
}
|
61
|
+
}
|
62
|
+
}
|
63
|
+
|
64
|
+
:root.minimizedNavHeader {
|
65
|
+
@include only-short-title;
|
66
|
+
}
|
67
|
+
|
68
|
+
@media screen and (max-width: $site-content-preferred-width) {
|
69
|
+
@include only-short-title;
|
70
|
+
}
|
71
|
+
|
44
72
|
:root {
|
45
73
|
--header-effective-height: var(--header-height);
|
46
74
|
}
|
Binary file
|
@@ -0,0 +1,8 @@
|
|
1
|
+
This directory includes fonts under OpenSource licenses. As the Hematite theme is distributed under the MIT, all fonts distributed with it must be free for commercial use.
|
2
|
+
|
3
|
+
This directory includes the following fonts:
|
4
|
+
* FoulisGreek
|
5
|
+
* by the JUnicode project
|
6
|
+
* https://www.fontspace.com/foulis-greek-font-f38341
|
7
|
+
* https://junicode.sourceforge.io/greek.html
|
8
|
+
|
@@ -11,16 +11,16 @@ noindex: true
|
|
11
11
|
<style>
|
12
12
|
/* Stylesheet mostly taken from https://github.com/gnab/remark/wiki#getting-started */
|
13
13
|
@import url(https://fonts.googleapis.com/css?family=Yanone+Kaffeesatz);
|
14
|
-
@import url(https://fonts.googleapis.com/css?family=Droid+
|
14
|
+
@import url(https://fonts.googleapis.com/css?family=Droid+Sans:400,700,400italic);
|
15
15
|
@import url(https://fonts.googleapis.com/css?family=Ubuntu+Mono:400,700,400italic);
|
16
16
|
|
17
|
-
body { font-family: 'Droid
|
17
|
+
body { font-family: 'Droid Sans', sans-serif; }
|
18
18
|
h1, h2, h3 {
|
19
19
|
font-family: 'Yanone Kaffeesatz';
|
20
20
|
font-weight: normal;
|
21
21
|
}
|
22
22
|
|
23
|
-
.remark-code, .remark-inline-code { font-family: 'Ubuntu Mono'; }
|
23
|
+
.remark-code, .remark-inline-code { font-family: 'Ubuntu Mono', monospace; }
|
24
24
|
|
25
25
|
/* Show hidden slides to allow preprocessors (e.g. mermaid) to
|
26
26
|
properly account for container size.
|
@@ -49,6 +49,11 @@ nav:hover, nav:focus-within {
|
|
49
49
|
opacity: 1;
|
50
50
|
}
|
51
51
|
|
52
|
+
/* Fix contrast issue */
|
53
|
+
.remark-slide-number {
|
54
|
+
opacity: 0.8;
|
55
|
+
}
|
56
|
+
|
52
57
|
@media print {
|
53
58
|
nav {
|
54
59
|
display: none;
|
@@ -57,11 +57,14 @@ function expandBasedOnURL() {
|
|
57
57
|
}
|
58
58
|
|
59
59
|
let targetElem = document.querySelector(hash);
|
60
|
-
let currentElem = targetElem;
|
61
60
|
|
62
|
-
|
63
|
-
|
64
|
-
|
61
|
+
if (targetElem) {
|
62
|
+
expandContainingDropdowns(targetElem);
|
63
|
+
targetElem.focus();
|
64
|
+
}
|
65
|
+
else {
|
66
|
+
console.warn(`Hash`, hash, `does not correspond to an element.`);
|
67
|
+
}
|
65
68
|
};
|
66
69
|
|
67
70
|
doExpansion(location.href);
|
data/assets/js/layout/post.mjs
CHANGED
@@ -2,6 +2,8 @@ import { getUrlQuery, Searcher } from "../search.mjs";
|
|
2
2
|
import { stringLookup } from "../strings.mjs";
|
3
3
|
import UrlHelper from "../UrlHelper.mjs";
|
4
4
|
|
5
|
+
const GESTURE_MIN_TOUCH_MOVE_DIST = 40; // px
|
6
|
+
|
5
7
|
function isInPresenterMode(targetDoc) {
|
6
8
|
return targetDoc.body.classList.contains("remark-presenter-mode");
|
7
9
|
}
|
@@ -13,7 +15,6 @@ function focusSearchResult(targetWin, query, targetMatchNo, slideshow, searcher)
|
|
13
15
|
let currentSlideNo = slide.getSlideIndex() + 1;
|
14
16
|
|
15
17
|
matchesFound += searcher.getNumberOfMatches(query, targetText);
|
16
|
-
console.log("Considering ", targetText, " with ", matchesFound, "matches found so far");
|
17
18
|
|
18
19
|
if (matchesFound > targetMatchNo) {
|
19
20
|
slideshow.gotoSlide(currentSlideNo);
|
@@ -22,20 +23,27 @@ function focusSearchResult(targetWin, query, targetMatchNo, slideshow, searcher)
|
|
22
23
|
|
23
24
|
// Now search the notes!
|
24
25
|
if (slide.notes) {
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
26
|
+
try {
|
27
|
+
targetText = (slide.notes.join ?? (() => slide.notes))("\n");
|
28
|
+
matchesFound += searcher.getNumberOfMatches(query, targetText);
|
29
|
+
if (matchesFound > targetMatchNo) {
|
30
|
+
slideshow.gotoSlide(currentSlideNo);
|
31
|
+
|
32
|
+
if (!isInPresenterMode(targetWin.document)) {
|
33
|
+
slideshow.togglePresenterMode();
|
34
|
+
}
|
35
|
+
return;
|
32
36
|
}
|
33
|
-
|
37
|
+
}
|
38
|
+
catch (e) {
|
39
|
+
console.error(`Unable to search through notes for slide`, slide, `Error: `, e);
|
40
|
+
console.log("Continuing...");
|
34
41
|
}
|
35
42
|
}
|
36
43
|
}
|
37
44
|
|
38
|
-
console.log("Found ", matchesFound,
|
45
|
+
console.log("Found ", matchesFound,
|
46
|
+
" matches, which is less than the target of ", targetMatchNo, ". Remaining on last slide.");
|
39
47
|
slideshow.gotoLastSlide();
|
40
48
|
return -1;
|
41
49
|
}
|
@@ -70,6 +78,9 @@ function focusSlideFromHash(slideshow) {
|
|
70
78
|
}
|
71
79
|
|
72
80
|
async function main(targetWindow, config) {
|
81
|
+
// True if touch navigation is enabled.
|
82
|
+
let usingCustomTouchNav = false;
|
83
|
+
|
73
84
|
if (!targetWindow.remark) {
|
74
85
|
// Wait for page load if remark isn't available yet.
|
75
86
|
await (new Promise(resolve => {
|
@@ -77,22 +88,32 @@ async function main(targetWindow, config) {
|
|
77
88
|
}));
|
78
89
|
}
|
79
90
|
|
91
|
+
// Customize touchscreen navigation — the default remark
|
92
|
+
// navigation can break buttons, zooming.
|
93
|
+
if (config?.navigation?.touch === true
|
94
|
+
|| config?.navigation?.touch === undefined) {
|
95
|
+
config ??= {};
|
96
|
+
config.navigation ??= {};
|
97
|
+
config.navigation.touch = false;
|
98
|
+
|
99
|
+
usingCustomTouchNav = true;
|
100
|
+
}
|
101
|
+
|
80
102
|
// See https://remarkjs.com/#8
|
81
103
|
let slideshow = targetWindow.remark.create(config);
|
104
|
+
targetWindow.focus();
|
82
105
|
|
83
106
|
// For debugging
|
84
107
|
window.slideshow_debug = slideshow;
|
85
108
|
|
86
|
-
targetWindow.focus();
|
87
|
-
|
88
109
|
addExtendedControls(targetWindow, slideshow);
|
89
110
|
focusSearchResultFromUrl(targetWindow, slideshow);
|
111
|
+
focusSlideFromHash(slideshow);
|
90
112
|
|
113
|
+
// Create a URL state we can navigate back to/restore to
|
91
114
|
targetWindow.history.replaceState(null, targetWindow.location.href);
|
92
115
|
let targetWinHistory = targetWindow.history.state;
|
93
116
|
|
94
|
-
focusSlideFromHash(slideshow);
|
95
|
-
|
96
117
|
window.addEventListener('hashchange', () => {
|
97
118
|
focusSlideFromHash(slideshow);
|
98
119
|
});
|
@@ -111,6 +132,44 @@ async function main(targetWindow, config) {
|
|
111
132
|
UrlHelper.withReplacedHash(targetWindow.location.href, hashId));
|
112
133
|
window.location.hash = hashId;
|
113
134
|
});
|
135
|
+
|
136
|
+
// Add custom touch events to listen for navigation.
|
137
|
+
if (usingCustomTouchNav) {
|
138
|
+
let elemContainer = targetWindow.document.body;
|
139
|
+
let initialPos = {};
|
140
|
+
let handlingGesture = false;
|
141
|
+
|
142
|
+
elemContainer.addEventListener('pointerdown', evt => {
|
143
|
+
if (evt.pointerType == 'touch') {
|
144
|
+
// Only handle single-touch gestures
|
145
|
+
handlingGesture = evt.isPrimary;
|
146
|
+
initialPos = {
|
147
|
+
x: evt.clientX,
|
148
|
+
y: evt.clientY,
|
149
|
+
};
|
150
|
+
|
151
|
+
if (handlingGesture) {
|
152
|
+
evt.preventDefault();
|
153
|
+
}
|
154
|
+
}
|
155
|
+
});
|
156
|
+
|
157
|
+
elemContainer.addEventListener('pointerup', evt => {
|
158
|
+
if (evt.pointerType == 'touch' && handlingGesture) {
|
159
|
+
let dx = evt.clientX - initialPos.x;
|
160
|
+
|
161
|
+
if (Math.abs(dx) < GESTURE_MIN_TOUCH_MOVE_DIST) {
|
162
|
+
return;
|
163
|
+
}
|
164
|
+
|
165
|
+
if (dx < 0) {
|
166
|
+
slideshow.gotoNextSlide();
|
167
|
+
} else {
|
168
|
+
slideshow.gotoPreviousSlide();
|
169
|
+
}
|
170
|
+
}
|
171
|
+
});
|
172
|
+
}
|
114
173
|
}
|
115
174
|
|
116
175
|
/// Apply minor adjustments to the default remark layout
|
data/assets/js/main.mjs
CHANGED
@@ -3,6 +3,7 @@ import { generateHeaderLinks } from "./linkButtonGenerator.mjs";
|
|
3
3
|
import handleSidebar from "./sidebar.mjs";
|
4
4
|
import handleSearch from "./search.mjs";
|
5
5
|
import autoExpandDropdowns from "./dropdownExpander.mjs";
|
6
|
+
import makeElemsScrollable from "./scrollables.mjs";
|
6
7
|
import Settings from "./Settings.mjs";
|
7
8
|
|
8
9
|
// After loading elements, images, css, etc.
|
@@ -17,6 +18,7 @@ addEventListener("load", () => {
|
|
17
18
|
// After loading elements, but before loading elements like images.
|
18
19
|
addEventListener("DOMContentLoaded", () => {
|
19
20
|
handleSidebar();
|
21
|
+
makeElemsScrollable();
|
20
22
|
});
|
21
23
|
|
22
24
|
// Apply user-specified settings
|
@@ -0,0 +1,29 @@
|
|
1
|
+
/// Wrap elements that can be too wide in scrollable containers
|
2
|
+
|
3
|
+
const SCROLLABLE_CONTAINER_CLSS = "scrollable-container";
|
4
|
+
|
5
|
+
function makeScrollable() {
|
6
|
+
// Make tables scrollable
|
7
|
+
let elems = document.querySelectorAll("main > table");
|
8
|
+
|
9
|
+
for (const elem of elems) {
|
10
|
+
let container = document.createElement("div");
|
11
|
+
elem.parentElement.insertBefore(container, elem);
|
12
|
+
elem.remove();
|
13
|
+
|
14
|
+
container.classList.add(SCROLLABLE_CONTAINER_CLSS);
|
15
|
+
container.appendChild(elem);
|
16
|
+
}
|
17
|
+
|
18
|
+
// Make display math scrollable
|
19
|
+
elems = document.querySelectorAll("main > span > .katex-display");
|
20
|
+
for (const elem of elems) {
|
21
|
+
let container = elem.parentElement;
|
22
|
+
|
23
|
+
if (container.children.length == 1) {
|
24
|
+
container.classList.add(SCROLLABLE_CONTAINER_CLSS);
|
25
|
+
}
|
26
|
+
}
|
27
|
+
}
|
28
|
+
|
29
|
+
export default makeScrollable;
|
data/assets/string_data/en.mjs
CHANGED
data/assets/string_data/es.mjs
CHANGED
@@ -51,6 +51,7 @@ export default {
|
|
51
51
|
page_theme_light: 'Brillante',
|
52
52
|
settings_minimize_header: 'Título escondido: ',
|
53
53
|
|
54
|
+
presentation_frame_title: 'Diapositivas de la presentación',
|
54
55
|
btn_next_slide: 'Vaya a la diapositiva proxima',
|
55
56
|
btn_prev_slide: 'Vaya a la diapositiva anterior',
|
56
57
|
btn_print: 'Imprima',
|
data/assets/style.scss
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hematite
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Henry Heino
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-05-
|
11
|
+
date: 2022-05-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jekyll
|
@@ -45,6 +45,7 @@ files:
|
|
45
45
|
- _includes/nav/pages_list.html
|
46
46
|
- _includes/nav/pinned_page.html
|
47
47
|
- _includes/nav/sidebar.html
|
48
|
+
- _includes/scss/_fonts.scss
|
48
49
|
- _includes/settings.html
|
49
50
|
- _layouts/calendar.html
|
50
51
|
- _layouts/default.html
|
@@ -63,6 +64,8 @@ files:
|
|
63
64
|
- _sass/_rogue.scss
|
64
65
|
- _sass/_sizes.scss
|
65
66
|
- _sass/hematite.scss
|
67
|
+
- assets/fonts/FoulisGreek.ttf
|
68
|
+
- assets/fonts/README.txt
|
66
69
|
- assets/html/all_tags.html
|
67
70
|
- assets/html/remark_presentation_frame.html
|
68
71
|
- assets/html/settings.html
|
@@ -81,6 +84,7 @@ files:
|
|
81
84
|
- assets/js/layout/remark_slideshow.mjs
|
82
85
|
- assets/js/linkButtonGenerator.mjs
|
83
86
|
- assets/js/main.mjs
|
87
|
+
- assets/js/scrollables.mjs
|
84
88
|
- assets/js/search.mjs
|
85
89
|
- assets/js/sidebar.mjs
|
86
90
|
- assets/js/string_data.mjs
|