datalog-theme 0.7.0 → 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 (133) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +125 -0
  3. data/CITATION.cff +2 -2
  4. data/README.md +23 -17
  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/enhanced-code-block.html +1 -1
  9. data/_includes/csp-meta.html +115 -11
  10. data/_includes/footer.html +19 -20
  11. data/_includes/head.html +60 -23
  12. data/_includes/header/navigation.html +12 -15
  13. data/_includes/header.html +28 -19
  14. data/_includes/layouts/default/article.html +5 -1
  15. data/_includes/meta/math-config.html +9 -5
  16. data/_includes/meta/schema.html +5 -2
  17. data/_includes/meta/scripts-loader.html +16 -32
  18. data/_includes/post/related-posts.html +4 -7
  19. data/_includes/search/index-data.json +9 -34
  20. data/_layouts/dataset.html +1 -0
  21. data/_layouts/default.html +16 -8
  22. data/_layouts/notebook.html +1 -0
  23. data/_layouts/package.html +1 -0
  24. data/_layouts/portfolio.html +1 -0
  25. data/_layouts/post.html +20 -5
  26. data/_layouts/project.html +2 -1
  27. data/_plugins/analytics_dashboard.rb +9 -3
  28. data/_plugins/config_validator.rb +12 -7
  29. data/_plugins/csp_generator.rb +18 -28
  30. data/_plugins/datalog_bibliography.rb +9 -7
  31. data/_plugins/datalog_comments.rb +8 -5
  32. data/_plugins/datalog_slides.rb +9 -8
  33. data/_plugins/i18n.rb +7 -8
  34. data/_plugins/image_optimizer.rb +17 -6
  35. data/_plugins/math_preprocessor.rb +33 -3
  36. data/_plugins/notebook_converter.rb +23 -4
  37. data/_plugins/plugin_loader.rb +3 -1
  38. data/_plugins/publications_generator.rb +8 -2
  39. data/_plugins/rouge_highlight_filter.rb +42 -0
  40. data/_plugins/search_code_blocks.rb +30 -0
  41. data/_plugins/search_normalizer.rb +15 -53
  42. data/_plugins/search_pages.rb +3 -4
  43. data/_sass/_academic-dashboard.scss +262 -0
  44. data/_sass/_base.scss +12 -0
  45. data/_sass/_components.scss +64 -1153
  46. data/_sass/_features.scss +17 -0
  47. data/_sass/_layout.scss +1 -1
  48. data/_sass/_notebooks.scss +322 -0
  49. data/_sass/_open-science-badges.scss +56 -0
  50. data/_sass/{_phase1-enhancements.scss → _post-components.scss} +1 -1
  51. data/_sass/_search-page.scss +530 -0
  52. data/_sass/_search.scss +46 -0
  53. data/_sass/_syntax-highlighting.scss +212 -97
  54. data/_sass/_theme.scss +29 -19
  55. data/_sass/_typography.scss +14 -0
  56. data/assets/css/main.scss +14 -0
  57. data/assets/js/dist/academic.js +1 -1
  58. data/assets/js/dist/analytics-dashboard.js +1 -1
  59. data/assets/js/dist/chunks/chunk-225H5YXE.js +1 -0
  60. data/assets/js/dist/core.js +1 -1
  61. data/assets/js/dist/loader.js +1 -1
  62. data/assets/js/dist/notebook.js +1 -1
  63. data/assets/js/dist/search.js +1 -1
  64. data/assets/js/dist/visualizations.js +11 -2
  65. data/assets/js/loader.js +3 -1
  66. data/datalog-theme.gemspec +36 -23
  67. data/lib/datalog/cli.rb +34 -14
  68. data/lib/datalog/plugin_system/dependency_resolver.rb +0 -2
  69. data/lib/datalog/theme/package.rb +57 -0
  70. data/lib/datalog/theme/repository_checkout.rb +90 -0
  71. data/lib/datalog/theme/version.rb +1 -1
  72. data/lib/datalog/warning_filter.rb +5 -11
  73. data/lib/datalog-theme.rb +5 -0
  74. metadata +48 -133
  75. data/_data/academic.yml +0 -217
  76. data/_data/config/author.yml +0 -121
  77. data/_data/datasets.yml +0 -28
  78. data/_data/js_meta.json +0 -371
  79. data/_data/navigation.yml +0 -145
  80. data/_data/projects.yml +0 -41
  81. data/_data/publications.yml +0 -28
  82. data/_data/social.yml +0 -73
  83. data/_data/visualizations.yml +0 -51
  84. data/_includes/components/advanced-search.html +0 -682
  85. data/_includes/components/bookmark-system.html +0 -96
  86. data/_includes/components/comments.html +0 -244
  87. data/_includes/components/content-recommendations.html +0 -228
  88. data/_includes/components/email-preferences.html +0 -200
  89. data/_includes/components/enhanced-metadata.html +0 -228
  90. data/_includes/components/language-switcher.html +0 -396
  91. data/_includes/components/navigation-enhancements.html +0 -454
  92. data/_includes/components/newsletter-signup.html +0 -178
  93. data/_includes/components/popular-posts.html +0 -233
  94. data/_includes/components/reading-progress.html +0 -133
  95. data/_includes/components/reading-time.html +0 -121
  96. data/_includes/components/series-navigation.html +0 -124
  97. data/_includes/components/social-proof.html +0 -34
  98. data/_includes/components/user-preferences.html +0 -566
  99. data/_includes/meta/syntax-config.html +0 -19
  100. data/_layouts/archive.html +0 -282
  101. data/_layouts/post-sidebar.html +0 -183
  102. data/_sass/_phase3-enhancements.scss +0 -874
  103. data/_sass/_phase4-enhancements.scss +0 -1214
  104. data/_sass/_phase5-enhancements.scss +0 -414
  105. data/assets/js/academic.js +0 -262
  106. data/assets/js/analytics-dashboard.js +0 -382
  107. data/assets/js/core/dark-mode.js +0 -79
  108. data/assets/js/core/github-cards.js +0 -123
  109. data/assets/js/core/language-filter.js +0 -69
  110. data/assets/js/core/navigation.js +0 -184
  111. data/assets/js/core/scroll-progress.js +0 -45
  112. data/assets/js/core/search-hotkeys.js +0 -62
  113. data/assets/js/core/skip-links.js +0 -62
  114. data/assets/js/dist/manifest.json +0 -22
  115. data/assets/js/dist/meta.json +0 -371
  116. data/assets/js/main.js +0 -23
  117. data/assets/js/math.js +0 -818
  118. data/assets/js/notebook.js +0 -158
  119. data/assets/js/search/analytics.js +0 -91
  120. data/assets/js/search/app.js +0 -271
  121. data/assets/js/search/autocomplete.js +0 -120
  122. data/assets/js/search/engine.js +0 -260
  123. data/assets/js/search/filters.js +0 -45
  124. data/assets/js/search/render.js +0 -217
  125. data/assets/js/search/utils.js +0 -99
  126. data/assets/js/search.js +0 -354
  127. data/assets/js/visualizations.js +0 -816
  128. data/assets/publications/datalog-publications.bib +0 -8
  129. data/assets/publications/datalog-publications.ris +0 -9
  130. data/assets/publications/publications.bib +0 -30
  131. data/assets/templates/diogo-ribeiro-cv.md +0 -31
  132. data/assets/templates/diogo-ribeiro-cv.tex +0 -32
  133. data/lib/datalog/theme/theme.rb +0 -18
@@ -1,66 +1,28 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- begin
4
- require "unicode_normalize"
5
- UNICODE_NORMALIZE_SUPPORTED = true
6
- rescue LoadError
7
- UNICODE_NORMALIZE_SUPPORTED = false
8
- warn "[search_normalizer] unicode_normalize gem not available; falling back to basic normalization"
9
- end
10
-
11
3
  module Datalog
12
4
  module SearchFilters
13
5
  module_function
14
6
 
7
+ # Lower-cases text and strips combining marks, so "Café" and "cafe" match
8
+ # while letters outside ASCII ("ß", "ł", Cyrillic, CJK) are kept. The
9
+ # browser normalizes queries the same way (assets/js/search/utils.js), so
10
+ # the index and the query agree. String#unicode_normalize is part of Ruby:
11
+ # this file used to require it as if it were a gem, fail, and fall back to
12
+ # dropping every character outside ASCII.
15
13
  def normalize_search(input)
16
- value = input.to_s
14
+ # Invalid byte sequences are dropped first: unicode_normalize raises on them.
15
+ value = input.to_s.scrub("")
17
16
  return "" if value.empty?
18
17
 
19
- normalized = if UNICODE_NORMALIZE_SUPPORTED && value.respond_to?(:unicode_normalize)
20
- value.unicode_normalize(:nfkd).gsub(/\p{Mn}/, "")
21
- else
22
- transliterate(value)
23
- end
24
-
25
- normalized.downcase.strip
26
- rescue StandardError
27
- input.to_s.downcase
28
- end
29
-
30
- def transliterate(value)
31
- value.encode("ASCII", fallback: lambda { |char|
32
- approximate_character(char)
33
- }, invalid: :replace, undef: :replace, replace: "")
34
- rescue Encoding::UndefinedConversionError, Encoding::InvalidByteSequenceError
35
- value
36
- end
37
-
38
- def approximate_character(char)
39
- @transliteration_map ||= build_transliteration_map
40
- @transliteration_map.fetch(char, "")
41
- end
42
-
43
- def build_transliteration_map
44
- basic_map = {}
45
-
46
- accents = {
47
- "ÀÁÂÃÄÅàáâãäå" => "a",
48
- "ÈÉÊËèéêë" => "e",
49
- "ÌÍÎÏìíîï" => "i",
50
- "ÒÓÔÕÖØòóôõöø" => "o",
51
- "ÙÚÛÜùúûü" => "u",
52
- "Çç" => "c",
53
- "Ññ" => "n",
54
- "Ýýÿ" => "y",
55
- "Ææ" => "ae",
56
- "Œœ" => "oe"
57
- }
58
-
59
- accents.each do |chars, replacement|
60
- chars.each_char { |char| basic_map[char] = replacement }
18
+ stripped = begin
19
+ value.unicode_normalize(:nfkd).gsub(/\p{Mn}/, "")
20
+ rescue Encoding::CompatibilityError
21
+ # Text in an encoding other than Unicode cannot be normalized, so it is
22
+ # indexed as it is.
23
+ value
61
24
  end
62
-
63
- basic_map
25
+ stripped.downcase.strip
64
26
  end
65
27
 
66
28
  def normalize_search_array(values)
@@ -61,10 +61,9 @@ module Datalog
61
61
  "title" => search_config["title"] || "Search",
62
62
  "permalink" => PAGE_URL,
63
63
  "page_classes" => "search-page",
64
- # Results can contain LaTeX and code, so both engines are wanted here
65
- # even when the rest of the site loads them only where they appear.
66
- "math" => true,
67
- "syntax_highlighting" => true
64
+ # Results can contain LaTeX, so the math engine is wanted here even
65
+ # when the rest of the site loads it only where math appears.
66
+ "math" => true
68
67
  )
69
68
  page.data["subtitle"] = search_config["subtitle"] if search_config["subtitle"]
70
69
  site.pages << page
@@ -0,0 +1,262 @@
1
+ // The academic dashboard (_includes/components/academic-dashboard.html): citation
2
+ // metrics, bibliography export, and the submission, calendar and funding lists.
3
+ // _components.scss loads this only when features.academic_dashboard is on.
4
+
5
+ @use 'sass:map';
6
+ @use "sass:color";
7
+
8
+ @use 'variables' as *;
9
+ @use 'mixins' as *;
10
+
11
+ .academic-dashboard {
12
+ display: grid;
13
+ gap: 2.5rem;
14
+ }
15
+
16
+ .academic-dashboard__header {
17
+ text-align: center;
18
+ max-width: 60ch;
19
+ margin: 0 auto;
20
+ }
21
+
22
+ .academic-dashboard__header h1 {
23
+ font-size: clamp(1.8rem, 3vw, 2.4rem);
24
+ margin-bottom: 0.5rem;
25
+ }
26
+
27
+ .academic-dashboard__header p {
28
+ color: var(--muted-foreground, #4a5568);
29
+ }
30
+
31
+ .academic-dashboard__profiles {
32
+ background: var(--surface-card, #fff);
33
+ border-radius: 1.25rem;
34
+ padding: 2rem;
35
+ box-shadow: 0 12px 40px rgba(12, 35, 64, 0.08);
36
+ }
37
+
38
+ .academic-profiles__grid {
39
+ display: grid;
40
+ gap: 1.5rem;
41
+ }
42
+
43
+ @media (min-width: 56rem) {
44
+ .academic-profiles__grid {
45
+ grid-template-columns: repeat(2, minmax(0, 1fr));
46
+ }
47
+ }
48
+
49
+ .academic-profile {
50
+ border: 1px solid rgba(12, 35, 64, 0.12);
51
+ border-radius: 1rem;
52
+ padding: 1.5rem;
53
+ background: rgba(12, 35, 64, 0.03);
54
+ display: grid;
55
+ gap: 1rem;
56
+ }
57
+
58
+ .academic-profile header {
59
+ display: flex;
60
+ justify-content: space-between;
61
+ align-items: center;
62
+ }
63
+
64
+ .academic-profile h3 {
65
+ margin: 0;
66
+ font-size: 1.1rem;
67
+ }
68
+
69
+ .academic-profile a {
70
+ font-size: 0.875rem;
71
+ font-weight: 500;
72
+ color: var(--accent, #3277f6);
73
+ }
74
+
75
+ .academic-profile dl {
76
+ display: grid;
77
+ gap: 0.5rem;
78
+ }
79
+
80
+ .academic-profile dl div {
81
+ display: flex;
82
+ justify-content: space-between;
83
+ gap: 1rem;
84
+ }
85
+
86
+ .academic-profile dt {
87
+ font-weight: 600;
88
+ color: var(--muted-foreground, #4a5568);
89
+ }
90
+
91
+ .academic-profile dd {
92
+ margin: 0;
93
+ }
94
+
95
+ .citation-metrics {
96
+ display: grid;
97
+ gap: 1.5rem;
98
+ border-radius: 1.25rem;
99
+ padding: 2rem;
100
+ background: rgba(50, 119, 246, 0.08);
101
+ }
102
+
103
+ .citation-metrics__totals {
104
+ display: grid;
105
+ gap: 1rem;
106
+ }
107
+
108
+ @media (min-width: 40rem) {
109
+ .citation-metrics__totals {
110
+ grid-template-columns: repeat(3, minmax(0, 1fr));
111
+ }
112
+ }
113
+
114
+ .citation-metrics .metric {
115
+ background: rgba(255, 255, 255, 0.8);
116
+ border-radius: 1rem;
117
+ padding: 1rem;
118
+ text-align: center;
119
+ font-weight: 600;
120
+ display: grid;
121
+ gap: 0.5rem;
122
+ }
123
+
124
+ .citation-metrics .metric dt {
125
+ margin: 0;
126
+ font-size: 0.9rem;
127
+ color: var(--muted-foreground, #4a5568);
128
+ }
129
+
130
+ .citation-metrics .metric dd {
131
+ margin: 0;
132
+ font-size: 1.5rem;
133
+ }
134
+
135
+ .citation-metrics__details {
136
+ background: rgba(255, 255, 255, 0.92);
137
+ border-radius: 1rem;
138
+ padding: 1rem 1.5rem;
139
+ }
140
+
141
+ .citation-metrics__details ul {
142
+ margin: 0;
143
+ padding-left: 1.25rem;
144
+ }
145
+
146
+ .citation-metrics__timeline {
147
+ background: rgba(12, 35, 64, 0.08);
148
+ border-radius: 1rem;
149
+ padding: 1rem 1.5rem;
150
+ }
151
+
152
+ .citation-metrics__timeline ul {
153
+ display: grid;
154
+ gap: 0.75rem;
155
+ margin: 0;
156
+ padding: 0;
157
+ list-style: none;
158
+ }
159
+
160
+ .citation-metrics__timeline li {
161
+ display: flex;
162
+ justify-content: space-between;
163
+ align-items: center;
164
+ gap: 1rem;
165
+ padding: 0.5rem 0.75rem;
166
+ border-radius: 0.75rem;
167
+ background: linear-gradient(90deg, rgba(50, 119, 246, 0.15) var(--timeline-value, 35%), transparent 0);
168
+ }
169
+
170
+ .bibliography-export {
171
+ display: grid;
172
+ gap: 1rem;
173
+ }
174
+
175
+ .bibliography-export textarea {
176
+ width: 100%;
177
+ min-height: 16rem;
178
+ font-family: var(--font-mono, "Fira Code", monospace);
179
+ border-radius: 0.75rem;
180
+ border: 1px solid rgba(12, 35, 64, 0.2);
181
+ padding: 1.25rem;
182
+ background: rgba(12, 35, 64, 0.04);
183
+ }
184
+
185
+ .bibliography-export__actions {
186
+ display: flex;
187
+ flex-wrap: wrap;
188
+ gap: 0.75rem;
189
+ }
190
+
191
+ .submission-controls,
192
+ .calendar-controls {
193
+ display: flex;
194
+ align-items: center;
195
+ gap: 0.75rem;
196
+ margin-bottom: 1rem;
197
+ }
198
+
199
+ .submission-controls select,
200
+ .calendar-controls select {
201
+ border-radius: 0.5rem;
202
+ padding: 0.5rem 0.75rem;
203
+ }
204
+
205
+ .submission-list,
206
+ .calendar-list,
207
+ .funding-list,
208
+ .opportunity-list,
209
+ .mentorship-list,
210
+ .workflow-list {
211
+ list-style: none;
212
+ margin: 0;
213
+ padding: 0;
214
+ display: grid;
215
+ gap: 1rem;
216
+ }
217
+
218
+ .submission-card,
219
+ .calendar-list li,
220
+ .funding-list li,
221
+ .opportunity-list li,
222
+ .mentorship-list li,
223
+ .workflow-list li {
224
+ border: 1px solid rgba(12, 35, 64, 0.12);
225
+ border-radius: 1rem;
226
+ padding: 1.25rem;
227
+ background: rgba(255, 255, 255, 0.92);
228
+ }
229
+
230
+ .status-badge {
231
+ display: inline-flex;
232
+ align-items: center;
233
+ gap: 0.4rem;
234
+ padding: 0.2rem 0.65rem;
235
+ border-radius: 999px;
236
+ background: rgba(50, 119, 246, 0.15);
237
+ color: var(--accent-foreground, #0b1d3d);
238
+ font-size: 0.85rem;
239
+ font-weight: 600;
240
+ }
241
+
242
+ .workflow-grid {
243
+ display: grid;
244
+ gap: 1.5rem;
245
+ }
246
+
247
+ @media (min-width: 56rem) {
248
+ .workflow-grid {
249
+ grid-template-columns: repeat(2, minmax(0, 1fr));
250
+ }
251
+ }
252
+
253
+ .networking-grid {
254
+ display: grid;
255
+ gap: 1.25rem;
256
+ }
257
+
258
+ @media (min-width: 48rem) {
259
+ .networking-grid {
260
+ grid-template-columns: repeat(2, minmax(0, 1fr));
261
+ }
262
+ }
data/_sass/_base.scss CHANGED
@@ -146,3 +146,15 @@ body.dark-mode {
146
146
  border-bottom-color: rgba($dark-ink-500, 0.2);
147
147
  }
148
148
  }
149
+
150
+ // Groups of form controls, such as the filters on the search page.
151
+ fieldset {
152
+ border: 1px solid var(--color-border, #e2e8f0);
153
+ border-radius: 8px;
154
+ padding: 1rem;
155
+
156
+ legend {
157
+ padding: 0 0.5rem;
158
+ font-weight: 600;
159
+ }
160
+ }