pandorga 1.4.9 → 1.5.1
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/CHANGELOG.md +40 -0
- data/README.md +1 -1
- data/_includes/chord-tab.html +7 -7
- data/_includes/page/site-footer.html +3 -2
- data/_includes/transcription.html +5 -5
- data/_layouts/home.html +4 -6
- data/_layouts/shell.html +7 -2
- data/assets/css/ledger/chrome.css +23 -0
- data/assets/css/ledger/home.css +31 -38
- data/examples/full/_config.yml +2 -0
- data/lib/pandorga/commands/doctor.rb +3 -1
- data/lib/pandorga/commands/new.rb +1 -1
- data/lib/pandorga/jekyll/plugins/identity_name.rb +67 -0
- data/lib/pandorga/registry/schema.yml +9 -1
- data/lib/pandorga/version.rb +1 -1
- data/scripts/test/test-css-structure.rb +8 -0
- data/scripts/test/test-doctor.rb +38 -0
- data/scripts/test/test-hero-name.rb +165 -0
- data/scripts/test/test-new.rb +11 -0
- data/scripts/test/test-shell-a11y.rb +30 -0
- data/scripts/test/test-template-packages.rb +8 -0
- data/scripts/test/test-validate-allowlist.rb +29 -0
- data/scripts/validate.sh +5 -1
- metadata +5 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c33cb11f60569d5280aa7079b6f59ad7776f90705f54f67d958d8b149390714d
|
|
4
|
+
data.tar.gz: 4a52dcb27be1f4d2a809417bc9b98e89e3c8aa8d92e642fca9ebab156942a192
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ecf8762ab684b723db57bb8d291609a3decf8ecae02f21b0158c3fd34afce67b9a34347255e790e26d480e8ef0b2eaab577dbe3d6ed571a02ce713cc5a2e09d9
|
|
7
|
+
data.tar.gz: 0c30da38132b4b87f2caf982a73f7c8eea1cf157600ecffb9b6f87e24fe289a47952fe3f9c8291c11719531a90cabd0149db89ba13b076c341a4eafabd6577b5
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,45 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.5.1] — 2026-10-10
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- The shell has a "Skip to content" link. When `site.author` is blank, the
|
|
8
|
+
home link's accessible name uses `pandorga.identity.name`, then the top-bar
|
|
9
|
+
wordmark, instead of a bare dash. The footer wordmark uses the same
|
|
10
|
+
fallback. A site that sets `site.author` is unchanged.
|
|
11
|
+
- `pandorga doctor` says when `pandorga.pages` is missing, and says when the
|
|
12
|
+
list is empty.
|
|
13
|
+
- `./scripts/validate.sh` fails if a listed gate file is missing.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- Getting started and the README name the scaffold pin `~> 1.3`.
|
|
18
|
+
- `pandorga new` comments the `v1.5.0` tag.
|
|
19
|
+
- Home CSS drops an empty `@media (min-width: 768px)` block and the unused
|
|
20
|
+
`.home-profile-summary` rules.
|
|
21
|
+
- Chord chart and transcript include comments are English. The visible
|
|
22
|
+
transcript labels are unchanged.
|
|
23
|
+
|
|
24
|
+
No `pandorga:` config keys were added or renamed.
|
|
25
|
+
|
|
26
|
+
## [1.5.0] — 2026-10-10
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
|
|
30
|
+
- Optional `pandorga.identity.first_name` and `pandorga.identity.last_name`.
|
|
31
|
+
The home hero uses them as the given name and the family name. The top
|
|
32
|
+
bar shows `first_name`. `last_name` is kept whole, spaces included.
|
|
33
|
+
Omit either key and that part still comes from splitting `identity.name`
|
|
34
|
+
on the first space, as in 1.4.9. `identity.name` stays required.
|
|
35
|
+
|
|
36
|
+
### Changed
|
|
37
|
+
|
|
38
|
+
- The home hero subtitle uses `--type-body`, the same size as the summary
|
|
39
|
+
under the name.
|
|
40
|
+
- Below 768px the hero name is 3pt larger, and a wrap breaks only between
|
|
41
|
+
the given name and the family name.
|
|
42
|
+
|
|
3
43
|
## [1.4.9] — 2026-10-09
|
|
4
44
|
|
|
5
45
|
### Changed
|
data/README.md
CHANGED
|
@@ -17,7 +17,7 @@ An aesthetic Jekyll publishing platform for creative and technical writing. The
|
|
|
17
17
|
Scaffold a site (Ada Example defaults, `content.backend: static`):
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
|
-
gem install pandorga #
|
|
20
|
+
gem install pandorga # or use a local checkout
|
|
21
21
|
pandorga new my-site
|
|
22
22
|
cd my-site
|
|
23
23
|
bundle install
|
data/_includes/chord-tab.html
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{% comment %}
|
|
2
2
|
chord-tab.html
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
intro: "
|
|
3
|
+
Renders a chord chart in N monospaced columns, using the full available width.
|
|
4
|
+
Each column stays within 79 characters per line.
|
|
5
|
+
Use: {% include chord-tab.html tab=tab_data %}
|
|
6
|
+
tab_data has:
|
|
7
|
+
intro: "intro chord line (optional)"
|
|
8
8
|
sections:
|
|
9
|
-
- label: "
|
|
9
|
+
- label: "section label (optional)"
|
|
10
10
|
content: |
|
|
11
|
-
|
|
11
|
+
chord and lyric lines
|
|
12
12
|
{% endcomment %}
|
|
13
13
|
|
|
14
14
|
<div class="chord-tab-container mt-16 mb-8"
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
{%- endcomment -%}
|
|
30
30
|
|
|
31
31
|
{%- assign footer_active = include.nav_active -%}
|
|
32
|
+
{%- assign footer_name = site.author | default: site.pandorga.identity.name -%}
|
|
32
33
|
{%- assign footer_license = site.content_license -%}
|
|
33
34
|
|
|
34
35
|
<footer class="site-footer">
|
|
@@ -39,9 +40,9 @@
|
|
|
39
40
|
<div class="site-footer-grid">
|
|
40
41
|
|
|
41
42
|
<div class="site-footer-block site-footer-masthead">
|
|
42
|
-
<a href="/" class="site-footer-wordmark-link" aria-label="{{
|
|
43
|
+
<a href="/" class="site-footer-wordmark-link" aria-label="{% if footer_name != blank %}{{ footer_name }} – Home{% else %}Home{% endif %}">
|
|
43
44
|
{% include theme/site-logo.html %}
|
|
44
|
-
<span class="site-footer-wordmark">{{
|
|
45
|
+
<span class="site-footer-wordmark">{{ footer_name }}</span>
|
|
45
46
|
</a>
|
|
46
47
|
{%- comment -%}
|
|
47
48
|
The same fragment the home hero mounts, so the line the site opens
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{% comment %}
|
|
2
2
|
transcription.html
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Renders a structured transcript, with up to 4 speakers (colors follow order of appearance).
|
|
4
|
+
Use: {% include transcription.html transcription=page.transcription youtube_id='fpmZiY24U0k' %}
|
|
5
|
+
Or to load a file from _data:
|
|
6
6
|
{% assign transcription_data = site.data.transcriptions[page.transcription].transcription %}
|
|
7
7
|
{% include transcription.html transcription=transcription_data youtube_id='fpmZiY24U0k' %}
|
|
8
|
-
|
|
8
|
+
Also accepts url and image for a thumbnail:
|
|
9
9
|
{% include transcription.html transcription=transcription_data url='https://...' image='https://...' %}
|
|
10
10
|
|
|
11
11
|
Speaker labels are title-cased at render time (Patrícia, not PATRÍCIA) so
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
<hr class="border-t border-gentle-divider mb-6">
|
|
27
27
|
{% if include.youtube_id %}
|
|
28
28
|
<div class="mb-2">
|
|
29
|
-
{% include youtube.html id=include.youtube_id %} <!--
|
|
29
|
+
{% include youtube.html id=include.youtube_id %} <!-- YouTube video -->
|
|
30
30
|
<span class="font-label text-xs text-on-surface-variant">Transcrição do vídeo</span>
|
|
31
31
|
</div>
|
|
32
32
|
{% elsif include.url and include.image %}
|
data/_layouts/home.html
CHANGED
|
@@ -5,7 +5,8 @@ layout: shell
|
|
|
5
5
|
{%- comment -%}
|
|
6
6
|
Home — composition from the page registry (PLT §5.4).
|
|
7
7
|
|
|
8
|
-
The hero reads identity
|
|
8
|
+
The hero reads identity (first_name and last_name, or a split of name)
|
|
9
|
+
plus content fragments. Decorative art is a slot
|
|
9
10
|
(`pandorga.home.hero_art`, default page/hero-default.html). Listing and
|
|
10
11
|
index bands come from site.data.pandorga_home_bands in registry order.
|
|
11
12
|
Band copy (kicker, title, note) arrives from content/pages/headers.yml
|
|
@@ -13,10 +14,7 @@ layout: shell
|
|
|
13
14
|
in this layout.
|
|
14
15
|
{%- endcomment -%}
|
|
15
16
|
|
|
16
|
-
{%- assign
|
|
17
|
-
{%- assign _name_parts = _identity_name | split: " " -%}
|
|
18
|
-
{%- assign _name_given = _name_parts | first -%}
|
|
19
|
-
{%- assign _name_family = _name_parts | slice: 1, 8 | join: " " -%}
|
|
17
|
+
{%- assign _hero_name = site.pandorga.identity | pandorga_hero_name: site.author, site.title -%}
|
|
20
18
|
{%- assign _cv_page = site.pages | where: "key", "cv" | first -%}
|
|
21
19
|
{%- assign _hero_art = site.pandorga.home.hero_art | default: "page/hero-default.html" -%}
|
|
22
20
|
{%- assign _home_bands = site.data.pandorga_home_bands -%}
|
|
@@ -33,7 +31,7 @@ layout: shell
|
|
|
33
31
|
<div id="home-subtitle-content" class="home-hero-tagline font-label"
|
|
34
32
|
data-content-fragment="home/subtitle"></div>
|
|
35
33
|
<h1 class="home-hero-title">
|
|
36
|
-
<span class="home-hero-given">{{
|
|
34
|
+
<span class="home-hero-given">{{ _hero_name.given }}</span>{%- if _hero_name.family != "" %} <span class="home-hero-family">{{ _hero_name.family }}</span>{%- endif %}
|
|
37
35
|
</h1>
|
|
38
36
|
<div id="home-cv-summary" class="home-hero-summary font-body"
|
|
39
37
|
data-content-fragment="cv/summary"></div>
|
data/_layouts/shell.html
CHANGED
|
@@ -83,7 +83,10 @@
|
|
|
83
83
|
</head>
|
|
84
84
|
|
|
85
85
|
<body class="bg-background text-on-surface">
|
|
86
|
+
<a class="skip-link" href="#page-content">Skip to content</a>
|
|
86
87
|
|
|
88
|
+
{% assign _nav_name = site.pandorga.identity | pandorga_hero_name: site.author, site.title %}
|
|
89
|
+
{% assign _home_label = site.author | default: site.pandorga.identity.name | default: _nav_name.wordmark %}
|
|
87
90
|
{% assign nav_active = nil %}
|
|
88
91
|
{% if page.collection == "articles" %}{% assign nav_active = "articles" %}{% endif %}
|
|
89
92
|
{% if page.collection == "posts" %}{% assign nav_active = "blog" %}{% endif %}
|
|
@@ -97,9 +100,9 @@
|
|
|
97
100
|
<nav class="sticky top-0 z-50 bg-surface">
|
|
98
101
|
<div class="flex justify-between items-center w-full px-6 sm:px-8 md:px-10 pt-5 pb-3.5 leading-none max-w-7xl mx-auto">
|
|
99
102
|
<div class="flex items-center gap-3 sm:gap-4 min-w-0">
|
|
100
|
-
<a href="/" aria-label="{{
|
|
103
|
+
<a href="/" aria-label="{% if _home_label != blank %}{{ _home_label }} – Home{% else %}Home{% endif %}" class="shrink-0 inline-flex items-center gap-3 site-wordmark-link">
|
|
101
104
|
{% include theme/site-logo.html %}
|
|
102
|
-
<span class="site-wordmark">{{
|
|
105
|
+
<span class="site-wordmark">{{ _nav_name.wordmark }}</span>
|
|
103
106
|
</a>
|
|
104
107
|
</div>
|
|
105
108
|
|
|
@@ -189,7 +192,9 @@
|
|
|
189
192
|
|
|
190
193
|
{% include page/content-runtime.html %}
|
|
191
194
|
|
|
195
|
+
<div id="page-content" tabindex="-1">
|
|
192
196
|
{{ content }}
|
|
197
|
+
</div>
|
|
193
198
|
|
|
194
199
|
{% include page/figure-lightbox.html %}
|
|
195
200
|
|
|
@@ -6,6 +6,29 @@
|
|
|
6
6
|
one source of navigation; only the presentation changes. The Explore menu
|
|
7
7
|
stays for narrow viewports, where six links do not fit. */
|
|
8
8
|
|
|
9
|
+
.skip-link {
|
|
10
|
+
position: absolute;
|
|
11
|
+
left: 0.75rem;
|
|
12
|
+
top: 0.75rem;
|
|
13
|
+
z-index: 80;
|
|
14
|
+
padding: 0.45rem 0.75rem;
|
|
15
|
+
background: var(--color-surface);
|
|
16
|
+
color: var(--color-on-surface);
|
|
17
|
+
border: 1px solid var(--color-outline);
|
|
18
|
+
text-decoration: none;
|
|
19
|
+
font-family: var(--font-label);
|
|
20
|
+
font-size: var(--type-label);
|
|
21
|
+
transform: translateY(-150%);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.skip-link:focus {
|
|
25
|
+
transform: none;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
#page-content:focus {
|
|
29
|
+
outline: none;
|
|
30
|
+
}
|
|
31
|
+
|
|
9
32
|
.site-wordmark-link {
|
|
10
33
|
display: inline-flex;
|
|
11
34
|
align-items: center;
|
data/assets/css/ledger/home.css
CHANGED
|
@@ -219,19 +219,14 @@
|
|
|
219
219
|
margin: 0 0 var(--space-sm);
|
|
220
220
|
color: var(--color-on-surface);
|
|
221
221
|
font-family: var(--font-label);
|
|
222
|
-
|
|
222
|
+
/* Same size as the summary under the name, which inherits --type-body. */
|
|
223
|
+
font-size: var(--type-body);
|
|
223
224
|
font-weight: var(--weight-label);
|
|
224
225
|
letter-spacing: 0.03em;
|
|
225
226
|
line-height: 1.35;
|
|
226
227
|
max-width: 100%;
|
|
227
228
|
}
|
|
228
229
|
|
|
229
|
-
@media (min-width: 1024px) {
|
|
230
|
-
.home-hero-tagline {
|
|
231
|
-
font-size: calc(var(--type-label-lg) + 2pt);
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
230
|
.home-hero-tagline::after {
|
|
236
231
|
content: "";
|
|
237
232
|
flex: 1 1 auto;
|
|
@@ -262,10 +257,13 @@
|
|
|
262
257
|
max-width: 100%;
|
|
263
258
|
}
|
|
264
259
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
260
|
+
.home-hero-given,
|
|
261
|
+
.home-hero-family {
|
|
262
|
+
display: inline;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
.home-hero-family {
|
|
266
|
+
color: var(--color-primary);
|
|
269
267
|
}
|
|
270
268
|
|
|
271
269
|
@media (min-width: 640px) {
|
|
@@ -274,19 +272,34 @@
|
|
|
274
272
|
}
|
|
275
273
|
}
|
|
276
274
|
|
|
277
|
-
|
|
275
|
+
/* Below 768px the name is 3pt larger than the clamp above, and the only
|
|
276
|
+
wrap point is the gap between the given name and the family name. */
|
|
277
|
+
@media (max-width: 639px) {
|
|
278
278
|
.home-hero-title {
|
|
279
|
-
white-space:
|
|
279
|
+
white-space: normal;
|
|
280
|
+
font-size: calc(clamp(var(--type-section), calc(100cqi * 0.92 / 14.5), var(--type-page-lg)) + 3pt);
|
|
280
281
|
}
|
|
281
282
|
}
|
|
282
283
|
|
|
283
|
-
|
|
284
|
-
.home-hero-
|
|
285
|
-
|
|
284
|
+
@media (min-width: 640px) and (max-width: 767px) {
|
|
285
|
+
.home-hero-title {
|
|
286
|
+
white-space: normal;
|
|
287
|
+
font-size: calc(clamp(var(--type-section-lg), calc(100cqi * 0.92 / 14.5), var(--type-page-lg)) + 3pt);
|
|
288
|
+
}
|
|
286
289
|
}
|
|
287
290
|
|
|
288
|
-
|
|
289
|
-
|
|
291
|
+
@media (max-width: 767px) {
|
|
292
|
+
.home-hero-given,
|
|
293
|
+
.home-hero-family {
|
|
294
|
+
display: inline-block;
|
|
295
|
+
white-space: nowrap;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
@media (min-width: 768px) {
|
|
300
|
+
.home-hero-title {
|
|
301
|
+
white-space: nowrap;
|
|
302
|
+
}
|
|
290
303
|
}
|
|
291
304
|
|
|
292
305
|
.home-hero-summary {
|
|
@@ -1485,26 +1498,6 @@ html[data-theme="light"] .home-hero-plate {
|
|
|
1485
1498
|
}
|
|
1486
1499
|
}
|
|
1487
1500
|
|
|
1488
|
-
@media (min-width: 768px) {}
|
|
1489
|
-
|
|
1490
|
-
/* ── Profile band, hero plate scale, section action order ──
|
|
1491
|
-
Appended after the parallel page work; see the redesign PR. */
|
|
1492
|
-
|
|
1493
|
-
/* The portrait sits at the end of its grid column so its right edge meets
|
|
1494
|
-
the edge every band below aligns to. Cap lives on the earlier
|
|
1495
|
-
`.home-hero-portrait` rule (Borders Edition). */
|
|
1496
|
-
.home-profile-summary {
|
|
1497
|
-
max-width: var(--reading-measure);
|
|
1498
|
-
}
|
|
1499
|
-
|
|
1500
|
-
.home-profile-summary p {
|
|
1501
|
-
margin-bottom: var(--space-md);
|
|
1502
|
-
}
|
|
1503
|
-
|
|
1504
|
-
.home-profile-summary p:last-child {
|
|
1505
|
-
margin-bottom: 0;
|
|
1506
|
-
}
|
|
1507
|
-
|
|
1508
1501
|
/* ── Reference band: Sources + Network of Ideas ──────────────────────────
|
|
1509
1502
|
Two destinations in one band, each a card whose poster is a plate drawn
|
|
1510
1503
|
from that section's own content by the export and fetched at runtime.
|
data/examples/full/_config.yml
CHANGED
|
@@ -30,7 +30,9 @@ module Pandorga
|
|
|
30
30
|
end
|
|
31
31
|
pages = pandorga["pages"]
|
|
32
32
|
if pages.nil?
|
|
33
|
-
warnings << "pandorga.pages is
|
|
33
|
+
warnings << "pandorga.pages is missing; no pages will be generated"
|
|
34
|
+
elsif pages.is_a?(Array) && pages.empty?
|
|
35
|
+
warnings << "pandorga.pages is empty; no pages will be generated"
|
|
34
36
|
elsif !pages.is_a?(Array)
|
|
35
37
|
errors << "pandorga.pages must be an array"
|
|
36
38
|
else
|
|
@@ -24,7 +24,7 @@ module Pandorga
|
|
|
24
24
|
|
|
25
25
|
gem "pandorga", "~> 1.3"
|
|
26
26
|
# Local checkout: gem "pandorga", path: "../pandorga"
|
|
27
|
-
# GitHub tag: gem "pandorga", github: "alexandrelheinen/pandorga", tag: "v1.
|
|
27
|
+
# GitHub tag: gem "pandorga", github: "alexandrelheinen/pandorga", tag: "v1.5.0"
|
|
28
28
|
gem "csv"
|
|
29
29
|
gem "base64"
|
|
30
30
|
RUBY
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Spec: docs/features/hero-name.md
|
|
4
|
+
# Refs: PLT-AC-14
|
|
5
|
+
module Pandorga
|
|
6
|
+
# Given name, family name, and top-bar wordmark for the home hero.
|
|
7
|
+
module IdentityName
|
|
8
|
+
module_function
|
|
9
|
+
|
|
10
|
+
# identity may use string or symbol keys. author and title are the
|
|
11
|
+
# Jekyll site.author and site.title fallbacks.
|
|
12
|
+
def resolve(identity, author: nil, title: nil)
|
|
13
|
+
fields = normalize(identity)
|
|
14
|
+
given_field = explicit(fields, "first_name")
|
|
15
|
+
family_field = explicit(fields, "last_name")
|
|
16
|
+
legacy = tokens(text(fields["name"]).empty? ? author : fields["name"])
|
|
17
|
+
|
|
18
|
+
given = present(given_field) ? given_field : legacy.first.to_s
|
|
19
|
+
family = present(family_field) ? family_field : legacy.drop(1).take(8).join(" ")
|
|
20
|
+
wordmark = if present(given_field)
|
|
21
|
+
given_field
|
|
22
|
+
else
|
|
23
|
+
source = [fields["name"], author, title].map { |value| text(value) }.find { |value| !value.empty? }
|
|
24
|
+
tokens(source).first.to_s
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
{ "given" => given, "family" => family, "wordmark" => wordmark }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def normalize(identity)
|
|
31
|
+
raw = case identity
|
|
32
|
+
when Hash then identity
|
|
33
|
+
else identity.respond_to?(:to_hash) ? identity.to_hash : {}
|
|
34
|
+
end
|
|
35
|
+
raw.each_with_object({}) { |(key, value), out| out[key.to_s] = value }
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# :missing when the key is absent or null. Blank is handled by present.
|
|
39
|
+
def explicit(fields, key)
|
|
40
|
+
return :missing unless fields.key?(key)
|
|
41
|
+
return :missing if fields[key].nil?
|
|
42
|
+
|
|
43
|
+
fields[key].to_s.strip
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def present(value)
|
|
47
|
+
value.is_a?(String) && !value.empty?
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def text(value)
|
|
51
|
+
value.to_s.strip
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def tokens(value)
|
|
55
|
+
text(value).split(" ")
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Liquid filter used by the home hero and the top bar.
|
|
61
|
+
module PandorgaHeroNameFilter
|
|
62
|
+
def pandorga_hero_name(identity, author = nil, title = nil)
|
|
63
|
+
Pandorga::IdentityName.resolve(identity, author: author, title: title)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
Liquid::Template.register_filter(PandorgaHeroNameFilter) if defined?(Liquid::Template)
|
|
@@ -8,7 +8,15 @@ identity:
|
|
|
8
8
|
name:
|
|
9
9
|
type: string
|
|
10
10
|
required: true
|
|
11
|
-
notes: Title suffix, default author, BibTeX
|
|
11
|
+
notes: Title suffix, default author, BibTeX. Also the legacy hero name when `first_name` or `last_name` is omitted
|
|
12
|
+
first_name:
|
|
13
|
+
type: string
|
|
14
|
+
required: false
|
|
15
|
+
notes: Hero given name and top-bar wordmark. Omitted or blank, the first word of `name` is used
|
|
16
|
+
last_name:
|
|
17
|
+
type: string
|
|
18
|
+
required: false
|
|
19
|
+
notes: Hero family name, kept whole (spaces allowed). Omitted or blank, the remainder of `name` is used
|
|
12
20
|
short_name:
|
|
13
21
|
type: string
|
|
14
22
|
required: false
|
data/lib/pandorga/version.rb
CHANGED
|
@@ -64,6 +64,14 @@ sheets.each do |path|
|
|
|
64
64
|
errors << "#{relative}: #{depth} unclosed brace(s) — every rule after the " \
|
|
65
65
|
"offending block is swallowed and silently stops applying"
|
|
66
66
|
end
|
|
67
|
+
|
|
68
|
+
if cleaned.match?(/\{[ \t\r\n]*\}/)
|
|
69
|
+
errors << "#{relative}: empty ruleset (a block that matches nothing)"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
if source.include?("home-profile-summary")
|
|
73
|
+
errors << "#{relative}: .home-profile-summary is unused"
|
|
74
|
+
end
|
|
67
75
|
end
|
|
68
76
|
|
|
69
77
|
fail!("CSS structure problems:\n - #{errors.join("\n - ")}") unless errors.empty?
|
data/scripts/test/test-doctor.rb
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
# Refs: PLT-0.3, PLT-AC-5
|
|
4
4
|
require "pathname"
|
|
5
5
|
require "open3"
|
|
6
|
+
require "fileutils"
|
|
6
7
|
|
|
7
8
|
ROOT = Pathname.new(__dir__).join("../..").expand_path
|
|
8
9
|
EXAMPLE = ROOT.join("examples/minimal")
|
|
@@ -36,4 +37,41 @@ unless err.include?("pandorga:")
|
|
|
36
37
|
exit 1
|
|
37
38
|
end
|
|
38
39
|
|
|
40
|
+
missing = ROOT.join("tmp/doctor-missing-pages")
|
|
41
|
+
FileUtils.rm_rf(missing)
|
|
42
|
+
missing.mkpath
|
|
43
|
+
missing.join("_config.yml").write(<<~YAML)
|
|
44
|
+
pandorga:
|
|
45
|
+
identity:
|
|
46
|
+
name: Ada Example
|
|
47
|
+
YAML
|
|
48
|
+
_out, err, st = run_doctor(missing)
|
|
49
|
+
unless st.success?
|
|
50
|
+
warn "FAIL test-doctor: missing pages should warn, not fail\n#{err}"
|
|
51
|
+
exit 1
|
|
52
|
+
end
|
|
53
|
+
unless err.include?("pandorga.pages is missing")
|
|
54
|
+
warn "FAIL test-doctor: expected a missing-pages warning\n#{err}"
|
|
55
|
+
exit 1
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
empty = ROOT.join("tmp/doctor-empty-pages")
|
|
59
|
+
FileUtils.rm_rf(empty)
|
|
60
|
+
empty.mkpath
|
|
61
|
+
empty.join("_config.yml").write(<<~YAML)
|
|
62
|
+
pandorga:
|
|
63
|
+
identity:
|
|
64
|
+
name: Ada Example
|
|
65
|
+
pages: []
|
|
66
|
+
YAML
|
|
67
|
+
_out, err, st = run_doctor(empty)
|
|
68
|
+
unless st.success?
|
|
69
|
+
warn "FAIL test-doctor: empty pages should warn, not fail\n#{err}"
|
|
70
|
+
exit 1
|
|
71
|
+
end
|
|
72
|
+
unless err.include?("pandorga.pages is empty")
|
|
73
|
+
warn "FAIL test-doctor: expected an empty-pages warning\n#{err}"
|
|
74
|
+
exit 1
|
|
75
|
+
end
|
|
76
|
+
|
|
39
77
|
puts "PASS test-doctor"
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
# Hero name fields and headline size (docs/features/hero-name.md).
|
|
5
|
+
#
|
|
6
|
+
# PLT-AC-13 subtitle uses the body size
|
|
7
|
+
# PLT-AC-14 first_name / last_name, with the 1.4.9 split as fallback
|
|
8
|
+
# PLT-AC-15 phone name is +3pt and wraps only between the two names
|
|
9
|
+
|
|
10
|
+
require "pathname"
|
|
11
|
+
|
|
12
|
+
ROOT = Pathname.new(__dir__).join("..", "..").expand_path
|
|
13
|
+
HOME = ROOT.join("_layouts/home.html")
|
|
14
|
+
SHELL = ROOT.join("_layouts/shell.html")
|
|
15
|
+
CSS = ROOT.join("assets/css/ledger/home.css")
|
|
16
|
+
SCHEMA = ROOT.join("lib/pandorga/registry/schema.yml")
|
|
17
|
+
|
|
18
|
+
def check!(condition, message)
|
|
19
|
+
raise "Assertion failed: #{message}" unless condition
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
puts "Testing hero name..."
|
|
23
|
+
|
|
24
|
+
# ── PLT-AC-13 ───────────────────────────────────────────────────────────────
|
|
25
|
+
|
|
26
|
+
css = CSS.read
|
|
27
|
+
tagline = css[/\.home-hero-tagline \{.*?\n\}/m]
|
|
28
|
+
check!(tagline, "missing .home-hero-tagline rule")
|
|
29
|
+
check!(tagline.include?("font-size: var(--type-body);"),
|
|
30
|
+
"subtitle must use the body size, got:\n#{tagline}")
|
|
31
|
+
check!(!tagline.include?("type-label-lg"),
|
|
32
|
+
"subtitle must not keep the label size")
|
|
33
|
+
check!(!css.include?("calc(var(--type-label-lg) + 2pt)"),
|
|
34
|
+
"desktop subtitle must not add 2pt")
|
|
35
|
+
|
|
36
|
+
summary = css[/\.home-hero-summary \{.*?\n\}/m]
|
|
37
|
+
check!(summary, "missing .home-hero-summary rule")
|
|
38
|
+
check!(!summary.include?("font-size:"),
|
|
39
|
+
"summary inherits the page body size and must not set its own")
|
|
40
|
+
|
|
41
|
+
# ── PLT-AC-14 ───────────────────────────────────────────────────────────────
|
|
42
|
+
|
|
43
|
+
schema = SCHEMA.read
|
|
44
|
+
check!(schema.include?("first_name:"), "schema missing first_name")
|
|
45
|
+
check!(schema.include?("last_name:"), "schema missing last_name")
|
|
46
|
+
check!(schema.include?("name:") && schema.include?("required: true"),
|
|
47
|
+
"identity.name stays required")
|
|
48
|
+
|
|
49
|
+
home = HOME.read
|
|
50
|
+
shell = SHELL.read
|
|
51
|
+
check!(home.include?("pandorga_hero_name"),
|
|
52
|
+
"home hero must resolve the name through pandorga_hero_name")
|
|
53
|
+
check!(home.include?("home-hero-given") && home.include?("home-hero-family"),
|
|
54
|
+
"hero keeps a given span and a family span")
|
|
55
|
+
check!(shell.include?("pandorga_hero_name"),
|
|
56
|
+
"top bar must resolve the wordmark through pandorga_hero_name")
|
|
57
|
+
check!(shell.include?(".wordmark"),
|
|
58
|
+
"top bar prints the wordmark from the resolver")
|
|
59
|
+
check!(!shell.include?('site.author | default: site.title | split: " " | first'),
|
|
60
|
+
"top bar must not split site.author on its own")
|
|
61
|
+
|
|
62
|
+
require "liquid"
|
|
63
|
+
require_relative "../../lib/pandorga/jekyll/plugins/identity_name"
|
|
64
|
+
|
|
65
|
+
template = Liquid::Template.parse(<<~LIQUID)
|
|
66
|
+
{% assign hero = identity | pandorga_hero_name: author, title %}
|
|
67
|
+
{{ hero.given }}|{{ hero.family }}|{{ hero.wordmark }}
|
|
68
|
+
LIQUID
|
|
69
|
+
rendered = template.render(
|
|
70
|
+
"identity" => { "first_name" => "Ada", "last_name" => "Rivera Santos" },
|
|
71
|
+
"author" => "Other Person",
|
|
72
|
+
"title" => "Site Title"
|
|
73
|
+
)
|
|
74
|
+
check!(rendered.strip == "Ada|Rivera Santos|Ada",
|
|
75
|
+
"Liquid filter must keep a multi-word last name, got #{rendered.inspect}")
|
|
76
|
+
|
|
77
|
+
both = Pandorga::IdentityName.resolve(
|
|
78
|
+
{ "name" => "Ada Rivera Santos", "first_name" => "Ada", "last_name" => "Rivera Santos" },
|
|
79
|
+
author: "Other Person",
|
|
80
|
+
title: "Site Title"
|
|
81
|
+
)
|
|
82
|
+
check!(both["given"] == "Ada", "given name, got #{both.inspect}")
|
|
83
|
+
check!(both["family"] == "Rivera Santos", "multi-word family name must stay whole, got #{both.inspect}")
|
|
84
|
+
check!(both["wordmark"] == "Ada", "top bar shows the first name, got #{both.inspect}")
|
|
85
|
+
|
|
86
|
+
spaced = Pandorga::IdentityName.resolve(
|
|
87
|
+
{ "first_name" => " Mary Ann ", "last_name" => " Rivera Santos " }
|
|
88
|
+
)
|
|
89
|
+
check!(spaced["given"] == "Mary Ann" && spaced["wordmark"] == "Mary Ann",
|
|
90
|
+
"first_name is kept whole, got #{spaced.inspect}")
|
|
91
|
+
check!(spaced["family"] == "Rivera Santos",
|
|
92
|
+
"last_name is trimmed but not split, got #{spaced.inspect}")
|
|
93
|
+
|
|
94
|
+
legacy = Pandorga::IdentityName.resolve(
|
|
95
|
+
{ "name" => "Ada Rivera Santos" },
|
|
96
|
+
author: "Other Person",
|
|
97
|
+
title: "Site Title"
|
|
98
|
+
)
|
|
99
|
+
check!(legacy["given"] == "Ada", "legacy given name, got #{legacy.inspect}")
|
|
100
|
+
check!(legacy["family"] == "Rivera Santos", "legacy family name, got #{legacy.inspect}")
|
|
101
|
+
check!(legacy["wordmark"] == "Ada", "legacy wordmark prefers identity.name, got #{legacy.inspect}")
|
|
102
|
+
|
|
103
|
+
partial_family = Pandorga::IdentityName.resolve(
|
|
104
|
+
{ "name" => "Someone Else", "last_name" => "Rivera Santos" }
|
|
105
|
+
)
|
|
106
|
+
check!(partial_family["given"] == "Someone", "missing first_name uses the first word of name")
|
|
107
|
+
check!(partial_family["family"] == "Rivera Santos", "explicit last_name replaces the remainder")
|
|
108
|
+
check!(partial_family["wordmark"] == "Someone", "missing first_name wordmark is the first word of name")
|
|
109
|
+
|
|
110
|
+
partial_given = Pandorga::IdentityName.resolve({ "name" => "Ada Example", "first_name" => "Ada" })
|
|
111
|
+
check!(partial_given["family"] == "Example", "missing last_name keeps the remainder of name")
|
|
112
|
+
check!(partial_given["wordmark"] == "Ada", "wordmark uses first_name")
|
|
113
|
+
|
|
114
|
+
blank_last = Pandorga::IdentityName.resolve({ "name" => "Ada Example", "last_name" => "" })
|
|
115
|
+
check!(blank_last["family"] == "Example", "blank last_name keeps the 1.4.9 remainder")
|
|
116
|
+
|
|
117
|
+
author_only = Pandorga::IdentityName.resolve({}, author: "Other Person", title: "Site Title")
|
|
118
|
+
check!(author_only["given"] == "Other" && author_only["family"] == "Person",
|
|
119
|
+
"name falls back to site.author, got #{author_only.inspect}")
|
|
120
|
+
check!(author_only["wordmark"] == "Other", "wordmark falls back to site.author")
|
|
121
|
+
|
|
122
|
+
title_only = Pandorga::IdentityName.resolve({}, title: "Site Title")
|
|
123
|
+
check!(title_only["given"] == "" && title_only["family"] == "",
|
|
124
|
+
"hero does not take site.title, got #{title_only.inspect}")
|
|
125
|
+
check!(title_only["wordmark"] == "Site", "wordmark falls back to site.title")
|
|
126
|
+
|
|
127
|
+
long_name = (["Ada"] + (1..9).map { |index| "Tok#{index}" }).join(" ")
|
|
128
|
+
long = Pandorga::IdentityName.resolve({ "name" => long_name })
|
|
129
|
+
check!(long["family"] == (1..8).map { |index| "Tok#{index}" }.join(" "),
|
|
130
|
+
"legacy remainder stays eight words, got #{long["family"].inspect}")
|
|
131
|
+
|
|
132
|
+
symbols = Pandorga::IdentityName.resolve({ first_name: "Ada", last_name: "Rivera Santos" })
|
|
133
|
+
check!(symbols["family"] == "Rivera Santos", "symbol keys work, got #{symbols.inspect}")
|
|
134
|
+
|
|
135
|
+
# ── PLT-AC-15 ───────────────────────────────────────────────────────────────
|
|
136
|
+
|
|
137
|
+
hero = css[/\.home-hero-title \{.*?(?=\.home-hero-summary)/m]
|
|
138
|
+
check!(hero, "missing hero title block")
|
|
139
|
+
check!(hero.include?("font-size: clamp(var(--type-section), calc(100cqi * 0.92 / 14.5), var(--type-page-lg));"),
|
|
140
|
+
"base name size stays the 1.4.9 clamp")
|
|
141
|
+
check!(hero.include?("@media (max-width: 639px)"), "missing phone size query")
|
|
142
|
+
check!(hero.include?("calc(clamp(var(--type-section), calc(100cqi * 0.92 / 14.5), var(--type-page-lg)) + 3pt)"),
|
|
143
|
+
"below 640px the name must be the current clamp plus 3pt")
|
|
144
|
+
check!(hero.include?("@media (min-width: 640px) and (max-width: 767px)"),
|
|
145
|
+
"missing 640-767 size query")
|
|
146
|
+
check!(hero.include?("calc(clamp(var(--type-section-lg), calc(100cqi * 0.92 / 14.5), var(--type-page-lg)) + 3pt)"),
|
|
147
|
+
"from 640px to 767px the name must be the section-lg clamp plus 3pt")
|
|
148
|
+
|
|
149
|
+
plain = hero.index("@media (min-width: 640px) {")
|
|
150
|
+
banded = hero.index("@media (min-width: 640px) and (max-width: 767px)")
|
|
151
|
+
check!(plain && banded && banded > plain,
|
|
152
|
+
"the +3pt band must follow the plain 640px clamp so it wins")
|
|
153
|
+
|
|
154
|
+
phone = hero[/@media \(max-width: 767px\) \{.*?\n\}/m]
|
|
155
|
+
check!(phone && phone.include?("inline-block") && phone.include?("white-space: nowrap"),
|
|
156
|
+
"on a phone each name is an unbreakable unit, got:\n#{phone}")
|
|
157
|
+
check!(phone.include?(".home-hero-given") && phone.include?(".home-hero-family"),
|
|
158
|
+
"both name parts are unbreakable")
|
|
159
|
+
|
|
160
|
+
desktop = hero[/@media \(min-width: 768px\) \{.*?\n\}/m]
|
|
161
|
+
check!(desktop && desktop.include?("white-space: nowrap"),
|
|
162
|
+
"from 768px the name stays on one line")
|
|
163
|
+
check!(!desktop.include?("3pt"), "the +3pt bump is phone-only")
|
|
164
|
+
|
|
165
|
+
puts "PASS test-hero-name"
|
data/scripts/test/test-new.rb
CHANGED
|
@@ -21,6 +21,17 @@ def run_doctor(dir)
|
|
|
21
21
|
Open3.capture3(env, "ruby", EXE.to_s, "doctor", dir.to_s)
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
+
guide = ROOT.join("docs/getting-started.md").read
|
|
25
|
+
readme = ROOT.join("README.md").read
|
|
26
|
+
unless guide.include?('gem at `~> 1.3`')
|
|
27
|
+
warn "FAIL test-new: getting-started must document the scaffold pin ~> 1.3"
|
|
28
|
+
exit 1
|
|
29
|
+
end
|
|
30
|
+
if readme.include?("once 1.1 is on RubyGems")
|
|
31
|
+
warn "FAIL test-new: README still says the gem is unpublished at 1.1"
|
|
32
|
+
exit 1
|
|
33
|
+
end
|
|
34
|
+
|
|
24
35
|
FileUtils.rm_rf(DEST)
|
|
25
36
|
|
|
26
37
|
stdout, stderr, status = run_new(DEST.to_s)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
# Shell accessibility (skip link and home-link name).
|
|
5
|
+
# The top bar and footer used site.author alone, so a site with no author
|
|
6
|
+
# exposed the accessible name " – Home" and hid the visible wordmark.
|
|
7
|
+
|
|
8
|
+
require "pathname"
|
|
9
|
+
|
|
10
|
+
ROOT = Pathname.new(__dir__).join("..", "..").expand_path
|
|
11
|
+
SHELL = ROOT.join("_layouts/shell.html").read
|
|
12
|
+
FOOTER = ROOT.join("_includes/page/site-footer.html").read
|
|
13
|
+
CSS = ROOT.join("assets/css/ledger/chrome.css").read
|
|
14
|
+
|
|
15
|
+
def fail!(message)
|
|
16
|
+
warn "FAIL test-shell-a11y: #{message}"
|
|
17
|
+
exit 1
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
fail!("missing skip link") unless SHELL.include?('class="skip-link"') && SHELL.include?('href="#page-content"')
|
|
21
|
+
fail!("missing skip target") unless SHELL.include?('id="page-content"')
|
|
22
|
+
fail!("skip link is not shown on focus") unless CSS.include?(".skip-link:focus")
|
|
23
|
+
|
|
24
|
+
bare = 'aria-label="{{ site.author }} – Home"'
|
|
25
|
+
fail!("shell home link still uses site.author alone") if SHELL.include?(bare)
|
|
26
|
+
fail!("footer home link still uses site.author alone") if FOOTER.include?(bare)
|
|
27
|
+
fail!("shell home link needs an identity.name fallback") unless SHELL.include?("site.pandorga.identity.name")
|
|
28
|
+
fail!("footer home link needs an identity.name fallback") unless FOOTER.include?("site.pandorga.identity.name")
|
|
29
|
+
|
|
30
|
+
puts "PASS test-shell-a11y"
|
|
@@ -46,6 +46,14 @@ TEMPLATES.each do |name|
|
|
|
46
46
|
end
|
|
47
47
|
end
|
|
48
48
|
|
|
49
|
+
%w[_includes/chord-tab.html _includes/transcription.html].each do |rel|
|
|
50
|
+
text = ROOT.join(rel).read
|
|
51
|
+
if text.include?("Exibe")
|
|
52
|
+
warn "FAIL test-template-packages: #{rel} still has a Portuguese comment"
|
|
53
|
+
failed = true
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
49
57
|
exit 1 if failed
|
|
50
58
|
|
|
51
59
|
puts "PASS test-template-packages"
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
# A listed gate that is not on disk must fail the run. Skipping it lets a
|
|
5
|
+
# renamed test disappear from CI while validate.sh still exits 0.
|
|
6
|
+
|
|
7
|
+
require "pathname"
|
|
8
|
+
|
|
9
|
+
ROOT = Pathname.new(__dir__).join("..", "..").expand_path
|
|
10
|
+
SCRIPT = ROOT.join("scripts/validate.sh")
|
|
11
|
+
|
|
12
|
+
def fail!(message)
|
|
13
|
+
warn "FAIL test-validate-allowlist: #{message}"
|
|
14
|
+
exit 1
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
source = SCRIPT.read
|
|
18
|
+
block = source[/if \[\[ ! -f "\$test" \]\]; then.*?fi/m]
|
|
19
|
+
fail!("missing-file branch not found") unless block
|
|
20
|
+
fail!("a missing listed test must set failed=1") unless block.include?("failed=1")
|
|
21
|
+
fail!("a missing listed test must not be skipped") if block.include?("skip")
|
|
22
|
+
|
|
23
|
+
listed = source.scan(%r{scripts/test/test-[A-Za-z0-9_.-]+})
|
|
24
|
+
fail!("allowlist is empty") if listed.empty?
|
|
25
|
+
|
|
26
|
+
missing = listed.uniq.reject { |rel| ROOT.join(rel).file? }
|
|
27
|
+
fail!("listed tests are not on disk: #{missing.join(', ')}") unless missing.empty?
|
|
28
|
+
|
|
29
|
+
puts "PASS test-validate-allowlist"
|
data/scripts/validate.sh
CHANGED
|
@@ -51,15 +51,19 @@ TESTS=(
|
|
|
51
51
|
scripts/test/test-absent-field-absent-element.rb
|
|
52
52
|
scripts/test/test-ledger-blocks.rb
|
|
53
53
|
scripts/test/test-home-band-art.rb
|
|
54
|
+
scripts/test/test-hero-name.rb
|
|
54
55
|
scripts/test/test-r2-json-sync.rb
|
|
55
56
|
scripts/test/test-writing-slug-limits.rb
|
|
56
57
|
scripts/test/test-examples-build.rb
|
|
58
|
+
scripts/test/test-validate-allowlist.rb
|
|
59
|
+
scripts/test/test-shell-a11y.rb
|
|
57
60
|
)
|
|
58
61
|
|
|
59
62
|
failed=0
|
|
60
63
|
for test in "${TESTS[@]}"; do
|
|
61
64
|
if [[ ! -f "$test" ]]; then
|
|
62
|
-
echo "-- ${test} (missing
|
|
65
|
+
echo "-- ${test} (missing)"
|
|
66
|
+
failed=1
|
|
63
67
|
continue
|
|
64
68
|
fi
|
|
65
69
|
echo "-- ${test}"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pandorga
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.5.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- The Pandorga contributors
|
|
@@ -285,6 +285,7 @@ files:
|
|
|
285
285
|
- lib/pandorga/jekyll/plugins/force_utf8_encoding.rb
|
|
286
286
|
- lib/pandorga/jekyll/plugins/git_chronology.rb
|
|
287
287
|
- lib/pandorga/jekyll/plugins/git_metadata.rb
|
|
288
|
+
- lib/pandorga/jekyll/plugins/identity_name.rb
|
|
288
289
|
- lib/pandorga/jekyll/plugins/job_sections.rb
|
|
289
290
|
- lib/pandorga/jekyll/plugins/lib/content_validators.rb
|
|
290
291
|
- lib/pandorga/jekyll/plugins/lib/resource_validator.rb
|
|
@@ -391,6 +392,7 @@ files:
|
|
|
391
392
|
- scripts/test/test-exported-fields-reach-the-view.rb
|
|
392
393
|
- scripts/test/test-form-control-theming.rb
|
|
393
394
|
- scripts/test/test-git-chronology.rb
|
|
395
|
+
- scripts/test/test-hero-name.rb
|
|
394
396
|
- scripts/test/test-hero-portraits.mjs
|
|
395
397
|
- scripts/test/test-hero-portraits.rb
|
|
396
398
|
- scripts/test/test-home-band-art.rb
|
|
@@ -408,6 +410,7 @@ files:
|
|
|
408
410
|
- scripts/test/test-r2-json-sync.rb
|
|
409
411
|
- scripts/test/test-registry-home.rb
|
|
410
412
|
- scripts/test/test-runtime-js-syntax.rb
|
|
413
|
+
- scripts/test/test-shell-a11y.rb
|
|
411
414
|
- scripts/test/test-slim-writing-index.rb
|
|
412
415
|
- scripts/test/test-studio-api-contract.rb
|
|
413
416
|
- scripts/test/test-studio-content-files.rb
|
|
@@ -423,6 +426,7 @@ files:
|
|
|
423
426
|
- scripts/test/test-text-excerpt.rb
|
|
424
427
|
- scripts/test/test-unwrap-media-src.mjs
|
|
425
428
|
- scripts/test/test-unwrap-media-src.rb
|
|
429
|
+
- scripts/test/test-validate-allowlist.rb
|
|
426
430
|
- scripts/test/test-withdrawn-content-export.rb
|
|
427
431
|
- scripts/test/test-writing-index-export-slugs.rb
|
|
428
432
|
- scripts/test/test-writing-slug-limits.rb
|