datalog-theme 0.6.1 → 0.8.0

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.
Files changed (147) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +175 -0
  3. data/CITATION.cff +2 -2
  4. data/README.md +26 -19
  5. data/_data/cdn-integrity.yml +0 -30
  6. data/_includes/analytics/dashboard.html +3 -1
  7. data/_includes/components/api-function.html +20 -1
  8. data/_includes/components/author-bio.html +2 -2
  9. data/_includes/components/enhanced-code-block.html +1 -1
  10. data/_includes/components/hero.html +19 -1
  11. data/_includes/csp-meta.html +115 -11
  12. data/_includes/footer.html +19 -20
  13. data/_includes/head.html +61 -29
  14. data/_includes/header/navigation.html +12 -15
  15. data/_includes/header.html +29 -20
  16. data/_includes/layouts/default/article.html +5 -1
  17. data/_includes/meta/math-config.html +27 -1
  18. data/_includes/meta/schema.html +5 -2
  19. data/_includes/meta/scripts-loader.html +16 -31
  20. data/_includes/post/related-posts.html +4 -7
  21. data/_includes/scripts.html +1 -9
  22. data/_includes/search/index-data.json +131 -0
  23. data/_includes/search/page.html +136 -0
  24. data/_layouts/dataset.html +1 -0
  25. data/_layouts/default.html +16 -8
  26. data/_layouts/home.html +6 -0
  27. data/_layouts/notebook.html +1 -0
  28. data/_layouts/package.html +1 -0
  29. data/_layouts/portfolio.html +1 -0
  30. data/_layouts/post.html +20 -5
  31. data/_layouts/project.html +2 -1
  32. data/_plugins/analytics_dashboard.rb +9 -3
  33. data/_plugins/config_validator.rb +12 -7
  34. data/_plugins/csp_generator.rb +18 -28
  35. data/_plugins/datalog_bibliography.rb +9 -7
  36. data/_plugins/datalog_comments.rb +8 -5
  37. data/_plugins/datalog_slides.rb +9 -8
  38. data/_plugins/i18n.rb +7 -8
  39. data/_plugins/image_optimizer.rb +17 -6
  40. data/_plugins/math_preprocessor.rb +36 -3
  41. data/_plugins/notebook_converter.rb +23 -43
  42. data/_plugins/plugin_loader.rb +3 -1
  43. data/_plugins/publications_generator.rb +8 -2
  44. data/_plugins/rouge_highlight_filter.rb +42 -0
  45. data/_plugins/search_code_blocks.rb +30 -0
  46. data/_plugins/search_normalizer.rb +15 -53
  47. data/_plugins/search_pages.rb +72 -0
  48. data/_sass/_academic-dashboard.scss +262 -0
  49. data/_sass/_base.scss +19 -1
  50. data/_sass/_components.scss +77 -1144
  51. data/_sass/_features.scss +17 -0
  52. data/_sass/_font-fallbacks.scss +43 -0
  53. data/_sass/_header.scss +10 -0
  54. data/_sass/_layout.scss +18 -12
  55. data/_sass/_mathematical.scss +1 -1
  56. data/_sass/_notebooks.scss +322 -0
  57. data/_sass/_open-science-badges.scss +56 -0
  58. data/_sass/{_phase1-enhancements.scss → _post-components.scss} +46 -1
  59. data/_sass/_search-page.scss +530 -0
  60. data/_sass/_search.scss +47 -1
  61. data/_sass/_syntax-highlighting.scss +212 -97
  62. data/_sass/_theme.scss +42 -18
  63. data/_sass/_typography.scss +14 -0
  64. data/_sass/_variables.scss +7 -4
  65. data/assets/css/main.scss +14 -0
  66. data/assets/img/hero-detail-640.webp +0 -0
  67. data/assets/img/hero-detail.webp +0 -0
  68. data/assets/img/social-card.png +0 -0
  69. data/assets/js/dist/academic.js +1 -0
  70. data/assets/js/dist/analytics-dashboard.js +1 -0
  71. data/assets/js/dist/chunks/chunk-225H5YXE.js +1 -0
  72. data/assets/js/dist/core.js +1 -0
  73. data/assets/js/dist/loader.js +1 -0
  74. data/assets/js/dist/math.js +1 -0
  75. data/assets/js/dist/notebook.js +1 -0
  76. data/assets/js/dist/search.js +1 -0
  77. data/assets/js/dist/visualizations.js +11 -0
  78. data/assets/js/loader.js +3 -1
  79. data/datalog-theme.gemspec +43 -22
  80. data/lib/datalog/cli.rb +53 -15
  81. data/lib/datalog/plugin_system/dependency_resolver.rb +0 -2
  82. data/lib/datalog/theme/package.rb +57 -0
  83. data/lib/datalog/theme/repository_checkout.rb +90 -0
  84. data/lib/datalog/theme/version.rb +1 -1
  85. data/lib/datalog/warning_filter.rb +5 -11
  86. data/lib/datalog-theme.rb +21 -0
  87. metadata +75 -146
  88. data/_data/academic.yml +0 -217
  89. data/_data/config/author.yml +0 -121
  90. data/_data/config/features.yml +0 -262
  91. data/_data/config/site.yml +0 -42
  92. data/_data/config/theme.yml +0 -181
  93. data/_data/datasets.yml +0 -28
  94. data/_data/js_meta.json +0 -371
  95. data/_data/navigation.yml +0 -145
  96. data/_data/projects.yml +0 -41
  97. data/_data/publications.yml +0 -28
  98. data/_data/social.yml +0 -73
  99. data/_data/visualizations.yml +0 -51
  100. data/_includes/components/advanced-search.html +0 -682
  101. data/_includes/components/bookmark-system.html +0 -96
  102. data/_includes/components/comments.html +0 -244
  103. data/_includes/components/content-recommendations.html +0 -228
  104. data/_includes/components/email-preferences.html +0 -200
  105. data/_includes/components/enhanced-metadata.html +0 -228
  106. data/_includes/components/language-switcher.html +0 -396
  107. data/_includes/components/navigation-enhancements.html +0 -454
  108. data/_includes/components/newsletter-signup.html +0 -178
  109. data/_includes/components/popular-posts.html +0 -233
  110. data/_includes/components/reading-progress.html +0 -133
  111. data/_includes/components/reading-time.html +0 -121
  112. data/_includes/components/series-navigation.html +0 -124
  113. data/_includes/components/social-proof.html +0 -34
  114. data/_includes/components/user-preferences.html +0 -566
  115. data/_layouts/archive.html +0 -282
  116. data/_layouts/post-sidebar.html +0 -183
  117. data/_sass/_phase3-enhancements.scss +0 -874
  118. data/_sass/_phase4-enhancements.scss +0 -1214
  119. data/_sass/_phase5-enhancements.scss +0 -414
  120. data/assets/img/20220607123041_detail.001.png +0 -0
  121. data/assets/js/academic.js +0 -262
  122. data/assets/js/analytics-dashboard.js +0 -382
  123. data/assets/js/core/dark-mode.js +0 -79
  124. data/assets/js/core/github-cards.js +0 -123
  125. data/assets/js/core/language-filter.js +0 -69
  126. data/assets/js/core/navigation.js +0 -184
  127. data/assets/js/core/scroll-progress.js +0 -45
  128. data/assets/js/core/search-hotkeys.js +0 -62
  129. data/assets/js/core/skip-links.js +0 -62
  130. data/assets/js/main.js +0 -23
  131. data/assets/js/math.js +0 -818
  132. data/assets/js/notebook.js +0 -158
  133. data/assets/js/search/analytics.js +0 -91
  134. data/assets/js/search/app.js +0 -271
  135. data/assets/js/search/autocomplete.js +0 -120
  136. data/assets/js/search/engine.js +0 -260
  137. data/assets/js/search/filters.js +0 -38
  138. data/assets/js/search/render.js +0 -217
  139. data/assets/js/search/utils.js +0 -99
  140. data/assets/js/search.js +0 -354
  141. data/assets/js/visualizations.js +0 -816
  142. data/assets/publications/datalog-publications.bib +0 -8
  143. data/assets/publications/datalog-publications.ris +0 -9
  144. data/assets/publications/publications.bib +0 -30
  145. data/assets/templates/diogo-ribeiro-cv.md +0 -31
  146. data/assets/templates/diogo-ribeiro-cv.tex +0 -32
  147. data/lib/datalog/theme/theme.rb +0 -18
@@ -1,184 +0,0 @@
1
- /**
2
- * @fileoverview Navigation module for responsive site navigation.
3
- * Handles mobile menu toggling, smooth scrolling, and keyboard navigation.
4
- * @module core/navigation
5
- */
6
-
7
- /** @constant {string} Media query for desktop viewport */
8
- const DESKTOP_MEDIA = "(min-width: 48rem)";
9
- /** @constant {string} Selector for the main navigation element */
10
- const NAV_SELECTOR = "#site-nav";
11
- /** @constant {string} Selector for the navigation toggle button */
12
- const TOGGLE_SELECTOR = ".nav-toggle";
13
- /** @constant {string} Class applied to body when nav is open */
14
- const NAV_OPEN_CLASS = "nav-open";
15
-
16
- /**
17
- * Normalizes a URL path by removing trailing slashes and index.html.
18
- * @param {string} path - The path to normalize
19
- * @returns {string} Normalized path
20
- */
21
- function normalizePath(path) {
22
- return path.replace(/index\.html$/, "").replace(/\/$/, "");
23
- }
24
-
25
- function getAnchorTarget(link) {
26
- const href = link.getAttribute("href");
27
- if (!href) {
28
- return null;
29
- }
30
- try {
31
- const destination = new URL(href, window.location.origin);
32
- if (!destination.hash) {
33
- return null;
34
- }
35
- const current = new URL(window.location.href);
36
- if (normalizePath(destination.pathname) !== normalizePath(current.pathname)) {
37
- return null;
38
- }
39
- return destination.hash.replace("#", "");
40
- } catch (error) {
41
- return null;
42
- }
43
- }
44
-
45
- function smoothScrollToId(id) {
46
- if (!id) {
47
- return false;
48
- }
49
- const target = document.getElementById(id);
50
- if (!target) {
51
- return false;
52
- }
53
- target.scrollIntoView({ behavior: "smooth", block: "start" });
54
- return true;
55
- }
56
-
57
- /**
58
- * Initializes the navigation system including mobile toggle,
59
- * smooth scrolling for anchor links, and keyboard accessibility.
60
- * @returns {void}
61
- */
62
- export function initNavigation() {
63
- const siteNav = document.querySelector(NAV_SELECTOR);
64
- if (!siteNav) {
65
- return;
66
- }
67
-
68
- const navToggle = document.querySelector(TOGGLE_SELECTOR);
69
- const body = document.body;
70
- const navMediaQuery = window.matchMedia(DESKTOP_MEDIA);
71
-
72
- const syncNavForViewport = (isDesktop) => {
73
- if (isDesktop) {
74
- siteNav.dataset.open = "true";
75
- body.classList.remove(NAV_OPEN_CLASS);
76
- if (navToggle) {
77
- navToggle.setAttribute("aria-expanded", "false");
78
- navToggle.classList.remove("is-active");
79
- }
80
- return;
81
- }
82
-
83
- const isOpen = siteNav.dataset.open === "true";
84
- if (!isOpen) {
85
- siteNav.dataset.open = "false";
86
- }
87
- if (navToggle) {
88
- navToggle.setAttribute("aria-expanded", String(isOpen));
89
- navToggle.classList.toggle("is-active", isOpen);
90
- }
91
- };
92
-
93
- const closeNav = ({ focusToggle = false } = {}) => {
94
- if (navMediaQuery.matches) {
95
- return;
96
- }
97
- siteNav.dataset.open = "false";
98
- body.classList.remove(NAV_OPEN_CLASS);
99
- if (navToggle) {
100
- navToggle.setAttribute("aria-expanded", "false");
101
- navToggle.classList.remove("is-active");
102
- if (focusToggle) {
103
- navToggle.focus();
104
- }
105
- }
106
- };
107
-
108
- const openNav = () => {
109
- if (navMediaQuery.matches) {
110
- return;
111
- }
112
- siteNav.dataset.open = "true";
113
- body.classList.add(NAV_OPEN_CLASS);
114
- if (navToggle) {
115
- navToggle.setAttribute("aria-expanded", "true");
116
- navToggle.classList.add("is-active");
117
- }
118
- };
119
-
120
- const toggleNav = () => {
121
- if (navMediaQuery.matches) {
122
- return;
123
- }
124
- if (siteNav.dataset.open === "true") {
125
- closeNav();
126
- } else {
127
- openNav();
128
- }
129
- };
130
-
131
- if (!navMediaQuery.matches) {
132
- siteNav.dataset.open = "false";
133
- }
134
-
135
- syncNavForViewport(navMediaQuery.matches);
136
- navMediaQuery.addEventListener("change", (event) => {
137
- if (event.matches) {
138
- syncNavForViewport(true);
139
- } else {
140
- closeNav();
141
- siteNav.dataset.open = "false";
142
- syncNavForViewport(false);
143
- }
144
- });
145
-
146
- const navLinks = siteNav.querySelectorAll(".nav-link");
147
- navLinks.forEach((link) => {
148
- const anchorId = getAnchorTarget(link);
149
- link.addEventListener("click", (event) => {
150
- if (!navMediaQuery.matches) {
151
- closeNav();
152
- }
153
- if (anchorId && smoothScrollToId(anchorId)) {
154
- event.preventDefault();
155
- }
156
- });
157
- });
158
-
159
- if (navToggle) {
160
- navToggle.addEventListener("click", () => {
161
- toggleNav();
162
- });
163
- }
164
-
165
- document.addEventListener("keydown", (event) => {
166
- if (event.key === "Escape") {
167
- closeNav({ focusToggle: true });
168
- }
169
- });
170
-
171
- document.addEventListener("click", (event) => {
172
- if (navMediaQuery.matches || siteNav.dataset.open !== "true") {
173
- return;
174
- }
175
- const target = event.target;
176
- if (!target || typeof target.closest !== "function") {
177
- return;
178
- }
179
- if (target.closest(NAV_SELECTOR) || (navToggle && target.closest(TOGGLE_SELECTOR))) {
180
- return;
181
- }
182
- closeNav();
183
- });
184
- }
@@ -1,45 +0,0 @@
1
- /**
2
- * @fileoverview Scroll progress indicator.
3
- * Shows reading progress as user scrolls through content.
4
- * @module core/scroll-progress
5
- */
6
-
7
- /**
8
- * Calculates and updates the scroll progress indicator.
9
- * @param {HTMLElement} progressBar - The progress bar element
10
- * @param {HTMLElement|null} progressValue - Optional element to display percentage
11
- */
12
- function calculateProgress(progressBar, progressValue) {
13
- const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
14
- const docHeight = document.documentElement.scrollHeight - window.innerHeight;
15
- const progress = docHeight > 0 ? Math.min((scrollTop / docHeight) * 100, 100) : 0;
16
-
17
- if (progressBar.tagName === "PROGRESS") {
18
- progressBar.setAttribute("value", String(progress));
19
- } else {
20
- progressBar.style.setProperty("--progress", `${progress}%`);
21
- }
22
-
23
- if (progressValue) {
24
- progressValue.textContent = Math.round(progress);
25
- }
26
- }
27
-
28
- /**
29
- * Initializes the scroll progress indicator.
30
- * Listens to scroll and resize events to update progress.
31
- * @returns {void}
32
- */
33
- export function initScrollProgress() {
34
- const progressBar = document.querySelector("[data-scroll-progress]");
35
- if (!progressBar) {
36
- return;
37
- }
38
-
39
- const progressValue = document.querySelector("[data-scroll-progress-value]");
40
- const updateProgress = () => calculateProgress(progressBar, progressValue);
41
-
42
- updateProgress();
43
- window.addEventListener("scroll", updateProgress, { passive: true });
44
- window.addEventListener("resize", updateProgress);
45
- }
@@ -1,62 +0,0 @@
1
- /**
2
- * @fileoverview Search keyboard shortcuts.
3
- * Enables "/" and Cmd/Ctrl+K hotkeys to focus search.
4
- * @module core/search-hotkeys
5
- */
6
-
7
- /**
8
- * Focuses the global search input or navigates to search page.
9
- * @param {HTMLElement} siteSearchForm - The search form element
10
- */
11
- function focusGlobalSearch(siteSearchForm) {
12
- if (!siteSearchForm) {
13
- return;
14
- }
15
- const siteSearchInput = siteSearchForm.querySelector("input[type='search']");
16
- const searchDestination = siteSearchForm.getAttribute("action");
17
-
18
- if (siteSearchInput) {
19
- siteSearchInput.focus();
20
- siteSearchInput.select();
21
- } else if (searchDestination) {
22
- window.location.href = searchDestination;
23
- }
24
- }
25
-
26
- function shouldIgnoreHotkey(activeElement) {
27
- if (!activeElement) {
28
- return false;
29
- }
30
- if (activeElement.isContentEditable) {
31
- return true;
32
- }
33
- const tag = activeElement.tagName;
34
- return tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT";
35
- }
36
-
37
- /**
38
- * Initializes search keyboard shortcuts (/ and Cmd/Ctrl+K).
39
- * @returns {void}
40
- */
41
- export function initSearchHotkeys() {
42
- const siteSearchForm = document.querySelector(".site-search");
43
- if (!siteSearchForm) {
44
- return;
45
- }
46
-
47
- document.addEventListener("keydown", (event) => {
48
- if (shouldIgnoreHotkey(document.activeElement)) {
49
- return;
50
- }
51
-
52
- if (event.key === "/" && !event.ctrlKey && !event.metaKey && !event.altKey) {
53
- event.preventDefault();
54
- focusGlobalSearch(siteSearchForm);
55
- }
56
-
57
- if ((event.key === "k" || event.key === "K") && (event.ctrlKey || event.metaKey)) {
58
- event.preventDefault();
59
- focusGlobalSearch(siteSearchForm);
60
- }
61
- });
62
- }
@@ -1,62 +0,0 @@
1
- /**
2
- * @fileoverview Skip links for keyboard accessibility.
3
- * Allows users to skip to main content areas.
4
- * @module core/skip-links
5
- */
6
-
7
- /**
8
- * Focuses a target element, temporarily making it focusable if needed.
9
- * @param {HTMLElement|null} target - The element to focus
10
- */
11
- function focusTarget(target) {
12
- if (!target) {
13
- return;
14
- }
15
-
16
- const previousTabIndex = target.getAttribute("tabindex");
17
- if (previousTabIndex === null) {
18
- target.setAttribute("tabindex", "-1");
19
- target.dataset.skipLinkTempTabindex = "true";
20
- }
21
-
22
- target.addEventListener(
23
- "blur",
24
- () => {
25
- if (target.dataset.skipLinkTempTabindex) {
26
- target.removeAttribute("tabindex");
27
- delete target.dataset.skipLinkTempTabindex;
28
- }
29
- },
30
- { once: true }
31
- );
32
-
33
- target.focus();
34
- }
35
-
36
- /**
37
- * Initializes skip link functionality for accessibility.
38
- * Enhances focus management when skip links are activated.
39
- * @returns {void}
40
- */
41
- export function initSkipLinks() {
42
- const skipLinks = document.querySelectorAll(".skip-link[href^='#']");
43
- if (!skipLinks.length) {
44
- return;
45
- }
46
-
47
- skipLinks.forEach((link) => {
48
- link.addEventListener("click", (event) => {
49
- const href = link.getAttribute("href") || "";
50
- const targetId = href.slice(1);
51
- if (!targetId) {
52
- return;
53
- }
54
- const target = document.getElementById(targetId);
55
- if (!target) {
56
- return;
57
- }
58
- event.preventDefault();
59
- focusTarget(target);
60
- });
61
- });
62
- }
data/assets/js/main.js DELETED
@@ -1,23 +0,0 @@
1
- import { initDarkModeToggle } from "./core/dark-mode.js";
2
- import { initGitHubCards } from "./core/github-cards.js";
3
- import { initLanguageFilter } from "./core/language-filter.js";
4
- import { initNavigation } from "./core/navigation.js";
5
- import { initScrollProgress } from "./core/scroll-progress.js";
6
- import { initSearchHotkeys } from "./core/search-hotkeys.js";
7
- import { initSkipLinks } from "./core/skip-links.js";
8
-
9
- export function initializeCore() {
10
- initSkipLinks();
11
- initNavigation();
12
- initDarkModeToggle();
13
- initLanguageFilter();
14
- initScrollProgress();
15
- initSearchHotkeys();
16
- initGitHubCards();
17
- }
18
-
19
- if (document.readyState === "loading") {
20
- document.addEventListener("DOMContentLoaded", initializeCore);
21
- } else {
22
- initializeCore();
23
- }