datalog-theme 0.6.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 (180) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +162 -0
  3. data/CITATION.cff +29 -0
  4. data/LICENSE +21 -0
  5. data/README.md +257 -0
  6. data/_data/academic.yml +217 -0
  7. data/_data/cdn-integrity.yml +51 -0
  8. data/_data/config/author.yml +121 -0
  9. data/_data/config/features.yml +262 -0
  10. data/_data/config/site.yml +42 -0
  11. data/_data/config/theme.yml +181 -0
  12. data/_data/datasets.yml +28 -0
  13. data/_data/i18n/en.yml +438 -0
  14. data/_data/i18n/es.yml +438 -0
  15. data/_data/i18n/pt.yml +438 -0
  16. data/_data/js_manifest.json +22 -0
  17. data/_data/js_meta.json +371 -0
  18. data/_data/navigation.yml +145 -0
  19. data/_data/projects.yml +41 -0
  20. data/_data/publications.yml +28 -0
  21. data/_data/social.yml +73 -0
  22. data/_data/visualizations.yml +51 -0
  23. data/_includes/analytics/dashboard.html +149 -0
  24. data/_includes/analytics.html +9 -0
  25. data/_includes/components/academic-dashboard.html +347 -0
  26. data/_includes/components/advanced-search.html +682 -0
  27. data/_includes/components/api-function.html +94 -0
  28. data/_includes/components/author-bio.html +166 -0
  29. data/_includes/components/bookmark-system.html +96 -0
  30. data/_includes/components/breadcrumbs.html +89 -0
  31. data/_includes/components/citation-tools.html +94 -0
  32. data/_includes/components/comments.html +244 -0
  33. data/_includes/components/content-provenance.html +43 -0
  34. data/_includes/components/content-recommendations.html +228 -0
  35. data/_includes/components/difficulty-badge.html +84 -0
  36. data/_includes/components/email-preferences.html +200 -0
  37. data/_includes/components/enhanced-code-block.html +212 -0
  38. data/_includes/components/enhanced-metadata.html +228 -0
  39. data/_includes/components/enhanced-toc.html +209 -0
  40. data/_includes/components/hero.html +15 -0
  41. data/_includes/components/language-switcher.html +396 -0
  42. data/_includes/components/math-fallback.html +19 -0
  43. data/_includes/components/navigation-enhancements.html +454 -0
  44. data/_includes/components/newsletter-signup.html +178 -0
  45. data/_includes/components/open-science-badges.html +16 -0
  46. data/_includes/components/package-install.html +194 -0
  47. data/_includes/components/performance-monitor.html +170 -0
  48. data/_includes/components/popular-posts.html +233 -0
  49. data/_includes/components/post-hero.html +62 -0
  50. data/_includes/components/reading-progress.html +133 -0
  51. data/_includes/components/reading-time.html +121 -0
  52. data/_includes/components/responsive-image.html +63 -0
  53. data/_includes/components/search-facets.html +307 -0
  54. data/_includes/components/series-navigation.html +124 -0
  55. data/_includes/components/social-proof.html +34 -0
  56. data/_includes/components/social-share.html +119 -0
  57. data/_includes/components/user-preferences.html +566 -0
  58. data/_includes/components/visualization-card.html +24 -0
  59. data/_includes/components/viz-table-fallback.html +19 -0
  60. data/_includes/critical-css/default.html +0 -0
  61. data/_includes/critical-css/home.html +0 -0
  62. data/_includes/critical-css/post.html +0 -0
  63. data/_includes/csp-meta.html +17 -0
  64. data/_includes/footer/nav-column.html +31 -0
  65. data/_includes/footer.html +76 -0
  66. data/_includes/head.html +337 -0
  67. data/_includes/header/navigation.html +48 -0
  68. data/_includes/header.html +70 -0
  69. data/_includes/helpers/array-to-sentence.html +21 -0
  70. data/_includes/helpers/date-format.html +16 -0
  71. data/_includes/helpers/link-with-icon.html +26 -0
  72. data/_includes/layouts/default/article.html +67 -0
  73. data/_includes/meta/language-attributes.html +25 -0
  74. data/_includes/meta/math-config.html +21 -0
  75. data/_includes/meta/schema.html +153 -0
  76. data/_includes/meta/scripts-loader.html +52 -0
  77. data/_includes/post/related-posts.html +63 -0
  78. data/_includes/scripts.html +72 -0
  79. data/_includes/skip-link.html +1 -0
  80. data/_includes/toc.html +2 -0
  81. data/_layouts/archive.html +282 -0
  82. data/_layouts/dataset.html +52 -0
  83. data/_layouts/default.html +33 -0
  84. data/_layouts/home.html +48 -0
  85. data/_layouts/notebook.html +173 -0
  86. data/_layouts/package.html +238 -0
  87. data/_layouts/page.html +16 -0
  88. data/_layouts/portfolio.html +41 -0
  89. data/_layouts/post-sidebar.html +183 -0
  90. data/_layouts/post.html +338 -0
  91. data/_layouts/project.html +252 -0
  92. data/_layouts/research.html +504 -0
  93. data/_plugins/analytics_dashboard.rb +315 -0
  94. data/_plugins/config_validator.rb +397 -0
  95. data/_plugins/csp_generator.rb +115 -0
  96. data/_plugins/datalog_bibliography.rb +19 -0
  97. data/_plugins/datalog_comments.rb +18 -0
  98. data/_plugins/datalog_slides.rb +20 -0
  99. data/_plugins/front_matter_compat.rb +109 -0
  100. data/_plugins/i18n.rb +160 -0
  101. data/_plugins/image_optimizer.rb +445 -0
  102. data/_plugins/math_preprocessor.rb +185 -0
  103. data/_plugins/notebook_converter.rb +1107 -0
  104. data/_plugins/plugin_loader.rb +185 -0
  105. data/_plugins/publications_generator.rb +234 -0
  106. data/_plugins/reading_time.rb +15 -0
  107. data/_plugins/search_normalizer.rb +74 -0
  108. data/_plugins/sri_filter.rb +18 -0
  109. data/_plugins/toc_filter.rb +68 -0
  110. data/_plugins/warning_filter.rb +3 -0
  111. data/_sass/_base.scss +142 -0
  112. data/_sass/_components.scss +2380 -0
  113. data/_sass/_header.scss +470 -0
  114. data/_sass/_interactive.scss +344 -0
  115. data/_sass/_layout.scss +1760 -0
  116. data/_sass/_mathematical.scss +368 -0
  117. data/_sass/_mixins.scss +99 -0
  118. data/_sass/_package-docs.scss +715 -0
  119. data/_sass/_phase1-enhancements.scss +721 -0
  120. data/_sass/_phase3-enhancements.scss +874 -0
  121. data/_sass/_phase4-enhancements.scss +1214 -0
  122. data/_sass/_phase5-enhancements.scss +414 -0
  123. data/_sass/_search.scss +654 -0
  124. data/_sass/_syntax-highlighting.scss +128 -0
  125. data/_sass/_theme.scss +79 -0
  126. data/_sass/_typography.scss +148 -0
  127. data/_sass/_utilities.scss +334 -0
  128. data/_sass/_variables.scss +153 -0
  129. data/_sass/_visualizations.scss +242 -0
  130. data/assets/css/main.scss +4 -0
  131. data/assets/img/20220607123041_detail.001.png +0 -0
  132. data/assets/img/favicons/android-chrome-192x192.png +0 -0
  133. data/assets/img/favicons/android-chrome-512x512.png +0 -0
  134. data/assets/img/favicons/apple-touch-icon.png +0 -0
  135. data/assets/img/favicons/favicon-16x16.png +0 -0
  136. data/assets/img/favicons/favicon-32x32.png +0 -0
  137. data/assets/img/favicons/favicon.ico +0 -0
  138. data/assets/img/favicons/site.webmanifest +21 -0
  139. data/assets/img/portfolio-placeholder.svg +20 -0
  140. data/assets/js/academic.js +262 -0
  141. data/assets/js/analytics-dashboard.js +382 -0
  142. data/assets/js/core/dark-mode.js +79 -0
  143. data/assets/js/core/github-cards.js +123 -0
  144. data/assets/js/core/language-filter.js +69 -0
  145. data/assets/js/core/navigation.js +184 -0
  146. data/assets/js/core/scroll-progress.js +45 -0
  147. data/assets/js/core/search-hotkeys.js +62 -0
  148. data/assets/js/core/skip-links.js +62 -0
  149. data/assets/js/loader.js +163 -0
  150. data/assets/js/main.js +23 -0
  151. data/assets/js/math.js +818 -0
  152. data/assets/js/notebook.js +158 -0
  153. data/assets/js/search/analytics.js +91 -0
  154. data/assets/js/search/app.js +271 -0
  155. data/assets/js/search/autocomplete.js +120 -0
  156. data/assets/js/search/engine.js +260 -0
  157. data/assets/js/search/filters.js +38 -0
  158. data/assets/js/search/render.js +217 -0
  159. data/assets/js/search/utils.js +99 -0
  160. data/assets/js/search.js +354 -0
  161. data/assets/js/visualizations.js +816 -0
  162. data/assets/publications/datalog-publications.bib +8 -0
  163. data/assets/publications/datalog-publications.ris +9 -0
  164. data/assets/publications/publications.bib +30 -0
  165. data/assets/templates/diogo-ribeiro-cv.md +31 -0
  166. data/assets/templates/diogo-ribeiro-cv.tex +32 -0
  167. data/bin/datalog +26 -0
  168. data/datalog-theme.gemspec +72 -0
  169. data/lib/datalog/cli.rb +563 -0
  170. data/lib/datalog/plugin_system/dependency_resolver.rb +223 -0
  171. data/lib/datalog/plugin_system.rb +237 -0
  172. data/lib/datalog/plugins/citations.rb +182 -0
  173. data/lib/datalog/plugins/comments.rb +183 -0
  174. data/lib/datalog/plugins/search.rb +45 -0
  175. data/lib/datalog/plugins/slides.rb +121 -0
  176. data/lib/datalog/theme/theme.rb +18 -0
  177. data/lib/datalog/theme/version.rb +7 -0
  178. data/lib/datalog/warning_filter.rb +28 -0
  179. data/lib/datalog-theme.rb +17 -0
  180. metadata +555 -0
@@ -0,0 +1,163 @@
1
+ /**
2
+ * @fileoverview Feature loader for DataLog theme.
3
+ * Dynamically loads JavaScript bundles based on page requirements.
4
+ * @module loader
5
+ */
6
+
7
+ /**
8
+ * Reads and parses the JS manifest from the DOM.
9
+ * @returns {Object} Parsed manifest object with core and features URLs
10
+ */
11
+ function readManifest() {
12
+ const element = document.getElementById("datalog-js-manifest");
13
+ if (!element || !element.textContent) {
14
+ console.warn("Loader manifest missing");
15
+ return {};
16
+ }
17
+ try {
18
+ return JSON.parse(element.textContent);
19
+ } catch (error) {
20
+ console.error("Unable to parse loader manifest", error);
21
+ return {};
22
+ }
23
+ }
24
+
25
+ /**
26
+ * Converts a feature name to a dataset key (e.g., "dark-mode" -> "featureDarkMode").
27
+ * @param {string} feature - The feature name with optional hyphens
28
+ * @returns {string} Camel-cased dataset key
29
+ */
30
+ function toDatasetKey(feature) {
31
+ return `feature${feature.replace(/(^|-)([a-z])/g, (_, __, char) => char.toUpperCase())}`;
32
+ }
33
+
34
+ /**
35
+ * Updates the loading state of a feature in the body's dataset.
36
+ * @param {string} feature - The feature name
37
+ * @param {('loading'|'ready'|'error'|'skipped')} state - The new state
38
+ */
39
+ function updateFeatureState(feature, state) {
40
+ const body = document.body;
41
+ if (!body) {
42
+ return;
43
+ }
44
+ const key = `${toDatasetKey(feature)}State`;
45
+ body.dataset[key] = state;
46
+ }
47
+
48
+ /**
49
+ * Dynamically imports a JavaScript module.
50
+ * @param {string} url - The URL of the module to import
51
+ * @returns {Promise<Object>} The imported module
52
+ */
53
+ async function importModule(url) {
54
+ return import(url);
55
+ }
56
+
57
+ /**
58
+ * Feature configuration defining available features and their detection tests.
59
+ * @type {Array<{name: string, test: function(): boolean}>}
60
+ */
61
+ const FEATURE_CONFIG = [
62
+ {
63
+ name: "search",
64
+ test: () => document.querySelector("[data-search-app]") || document.querySelector(".site-search")
65
+ },
66
+ {
67
+ name: "visualizations",
68
+ test: () => document.querySelector("[data-viz-type]")
69
+ },
70
+ {
71
+ name: "math",
72
+ test: () => document.body?.dataset.featureMath === "true"
73
+ },
74
+ {
75
+ name: "academic",
76
+ test: () => document.querySelector("[data-citation-metric], [data-citation-table], [data-citation-chart]")
77
+ },
78
+ {
79
+ name: "notebook",
80
+ test: () => document.body?.dataset.featureNotebook === "true" || document.querySelector(".notebook-output")
81
+ }
82
+ ];
83
+
84
+ /**
85
+ * Bootstraps the application by loading core and feature bundles.
86
+ * Features are loaded based on page requirements and data attributes.
87
+ * @param {Object} [manifest] - Optional manifest object (reads from DOM if not provided)
88
+ * @param {string} manifest.core - URL of the core bundle
89
+ * @param {Object.<string, string>} [manifest.features] - Map of feature names to bundle URLs
90
+ * @returns {Promise<void>}
91
+ * @example
92
+ * // Auto-detect from DOM
93
+ * await bootstrapFeatures();
94
+ *
95
+ * // With explicit manifest
96
+ * await bootstrapFeatures({
97
+ * core: '/assets/js/dist/core.js',
98
+ * features: { search: '/assets/js/dist/search.js' }
99
+ * });
100
+ */
101
+ export async function bootstrapFeatures(manifest) {
102
+ const resolvedManifest = manifest || readManifest();
103
+ const { core, features = {} } = resolvedManifest;
104
+ if (!core) {
105
+ console.warn("Core bundle missing from manifest", resolvedManifest);
106
+ return;
107
+ }
108
+
109
+ try {
110
+ updateFeatureState("core", "loading");
111
+ await importModule(core);
112
+ updateFeatureState("core", "ready");
113
+ } catch (error) {
114
+ updateFeatureState("core", "error");
115
+ console.error("Failed to load core bundle", error);
116
+ return;
117
+ }
118
+
119
+ const body = document.body;
120
+ if (!body) {
121
+ return;
122
+ }
123
+
124
+ const requestedFeatures = FEATURE_CONFIG.filter((feature) => {
125
+ const datasetKey = toDatasetKey(feature.name);
126
+ const datasetValue = body.dataset[datasetKey];
127
+ const enabled = datasetValue === "true" || datasetValue === "auto";
128
+ if (!enabled) {
129
+ return false;
130
+ }
131
+ if (datasetValue === "auto") {
132
+ return typeof feature.test === "function" ? Boolean(feature.test()) : true;
133
+ }
134
+ return true;
135
+ });
136
+
137
+ const loads = requestedFeatures.map(async ({ name, test }) => {
138
+ const url = features[name];
139
+ if (!url) {
140
+ return;
141
+ }
142
+ updateFeatureState(name, "loading");
143
+ try {
144
+ if (typeof test === "function" && !test()) {
145
+ updateFeatureState(name, "skipped");
146
+ return;
147
+ }
148
+ await importModule(url);
149
+ updateFeatureState(name, "ready");
150
+ } catch (error) {
151
+ updateFeatureState(name, "error");
152
+ console.error(`Failed to load ${name} bundle`, error);
153
+ }
154
+ });
155
+
156
+ await Promise.all(loads);
157
+ }
158
+
159
+ if (document.readyState === "loading") {
160
+ document.addEventListener("DOMContentLoaded", () => bootstrapFeatures());
161
+ } else {
162
+ bootstrapFeatures();
163
+ }
data/assets/js/main.js ADDED
@@ -0,0 +1,23 @@
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
+ }