astro-theme-popular 0.14.0 → 0.14.2
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.
- package/index.mjs +30 -3
- package/package.json +1 -1
- package/src/lib/ical.ts +2 -2
- package/src/styles/base.css +19 -0
package/index.mjs
CHANGED
|
@@ -27,8 +27,10 @@ import Slugger from 'github-slugger';
|
|
|
27
27
|
survive a subpath install (parity with Hugo's render hooks passing paths
|
|
28
28
|
through relURL). Everything the templates write is handled by src/lib/url.ts
|
|
29
29
|
instead; MDX component props (<Photo src="/images/x.png">) are JSX, not HAST,
|
|
30
|
-
so the components prefix those themselves.
|
|
31
|
-
h2-h6, so each section has a copyable URL (Hugo's render-heading.html).
|
|
30
|
+
so the components prefix those themselves. A hover "#" anchor on every
|
|
31
|
+
h2-h6, so each section has a copyable URL (Hugo's render-heading.html). And
|
|
32
|
+
a <div class="g-table-scroll"> around every table, so a wide table scrolls
|
|
33
|
+
sideways on a phone instead of stretching the page (Hugo's render-table.html).
|
|
32
34
|
|
|
33
35
|
Registered on the active markdown processor rather than through
|
|
34
36
|
`markdown.rehypePlugins`: Astro 7's default processor is Sätteri, which does
|
|
@@ -73,6 +75,20 @@ const anchorNode = (id) => ({
|
|
|
73
75
|
children: [], // the "#" is CSS generated content; see base.css
|
|
74
76
|
});
|
|
75
77
|
|
|
78
|
+
/* Wide tables: every markdown <table> is wrapped in <div class="g-table-scroll">
|
|
79
|
+
(base.css: overflow-x: auto) so a table with more columns than a phone is
|
|
80
|
+
wide scrolls inside the page instead of stretching it. The wrapper scrolls,
|
|
81
|
+
not the table: `display: block; overflow-x: auto` on the table itself would
|
|
82
|
+
drop its table semantics for screen readers. Parity with Hugo's
|
|
83
|
+
render-table.html. A table an earlier hast plugin already wrapped is left
|
|
84
|
+
alone; a wrapper hand-written around a table in markdown or MDX is raw
|
|
85
|
+
HTML or JSX rather than a hast div, so it is not detected and the table
|
|
86
|
+
gets a second, harmless wrapper inside it. */
|
|
87
|
+
const TABLE_WRAPPER = 'g-table-scroll';
|
|
88
|
+
const tableWrapper = () => ({ type: 'element', tagName: 'div', properties: { className: [TABLE_WRAPPER] }, children: [] });
|
|
89
|
+
const isTableWrapper = (node) =>
|
|
90
|
+
node?.type === 'element' && node.tagName === 'div' && [].concat(node.properties?.className ?? []).includes(TABLE_WRAPPER);
|
|
91
|
+
|
|
76
92
|
/* Heading text the way Astro's own heading-id plugins read it: text nodes,
|
|
77
93
|
plus MDX `{frontmatter.x}` expressions resolved against the frontmatter
|
|
78
94
|
(mirrors collectHastText in @astrojs/markdown-satteri, which is not a
|
|
@@ -125,6 +141,12 @@ function satteriMarkdownHooks(prefix) {
|
|
|
125
141
|
if (href !== props.href) ctx.setProperty(node, 'href', href);
|
|
126
142
|
},
|
|
127
143
|
},
|
|
144
|
+
{
|
|
145
|
+
filter: ['table'],
|
|
146
|
+
visit(node, ctx) {
|
|
147
|
+
if (!isTableWrapper(ctx.parent(node))) ctx.wrapNode(node, tableWrapper());
|
|
148
|
+
},
|
|
149
|
+
},
|
|
128
150
|
{
|
|
129
151
|
filter: HEADINGS,
|
|
130
152
|
visit(node, ctx) {
|
|
@@ -169,6 +191,11 @@ function rehypeMarkdownHooks(prefix) {
|
|
|
169
191
|
if (node.tagName !== 'h1' && props.id) (node.children ??= []).push(anchorNode(props.id));
|
|
170
192
|
}
|
|
171
193
|
}
|
|
194
|
+
if (node.children && !isTableWrapper(node)) {
|
|
195
|
+
node.children = node.children.map((child) =>
|
|
196
|
+
child.type === 'element' && child.tagName === 'table' ? { ...tableWrapper(), children: [child] } : child,
|
|
197
|
+
);
|
|
198
|
+
}
|
|
172
199
|
(node.children || []).forEach(walk);
|
|
173
200
|
};
|
|
174
201
|
walk(tree);
|
|
@@ -186,7 +213,7 @@ function registerMarkdownHooks(config, logger) {
|
|
|
186
213
|
} else {
|
|
187
214
|
logger.warn(
|
|
188
215
|
`markdown.processor "${processor?.name ?? 'unknown'}" takes neither hastPlugins nor rehypePlugins: ` +
|
|
189
|
-
'markdown images will not get loading="lazy"' +
|
|
216
|
+
'markdown images will not get loading="lazy", headings no "#" anchor, tables no scroll wrapper' +
|
|
190
217
|
(prefix ? ', and site-absolute links in content will not carry the base' : ''),
|
|
191
218
|
);
|
|
192
219
|
}
|
package/package.json
CHANGED
package/src/lib/ical.ts
CHANGED
|
@@ -57,10 +57,10 @@ export function buildIcs(
|
|
|
57
57
|
const L: string[] = [];
|
|
58
58
|
L.push(fold('BEGIN:VCALENDAR'));
|
|
59
59
|
L.push(fold('VERSION:2.0'));
|
|
60
|
-
L.push(fold(`PRODID:-//${opts.siteTitle}//Popular theme//EN`));
|
|
60
|
+
L.push(fold(`PRODID:-//${icsEscape(opts.siteTitle)}//Popular theme//EN`));
|
|
61
61
|
L.push(fold('CALSCALE:GREGORIAN'));
|
|
62
62
|
L.push(fold('METHOD:PUBLISH'));
|
|
63
|
-
L.push(fold(`X-WR-CALNAME:${opts.siteTitle} events`));
|
|
63
|
+
L.push(fold(`X-WR-CALNAME:${icsEscape(opts.siteTitle)} events`));
|
|
64
64
|
/* Subscription refresh hints (RFC 7986 + the Apple/Outlook legacy twin).
|
|
65
65
|
Google Calendar ignores both and polls on its own schedule. */
|
|
66
66
|
L.push(fold('REFRESH-INTERVAL;VALUE=DURATION:PT12H'));
|
package/src/styles/base.css
CHANGED
|
@@ -113,6 +113,25 @@ pre code { font-size: inherit; background: none; padding: 0; border-radius: 0; }
|
|
|
113
113
|
!important beats the inline background-color that Chroma (Hugo) and
|
|
114
114
|
Shiki (Astro) emit, and unhighlighted languages get the same canvas. */
|
|
115
115
|
.g-prose pre { overflow-x: auto; padding: 1rem 1.2rem; border-radius: var(--radius-lg); background: var(--surface-code-block) !important; color: var(--ink-100); }
|
|
116
|
+
/* Markdown tables. Browser defaults draw no borders and no padding, so a
|
|
117
|
+
cell holding several sentences runs into the next one. Every cell gets a
|
|
118
|
+
thin border and the header row a wash. Text aligns start and top unless the
|
|
119
|
+
column asked for an alignment in markdown (`:---:`): Goldmark and Sätteri
|
|
120
|
+
emit that as an inline style, which beats this default on its own, and the
|
|
121
|
+
unified/rehype pipeline as an align attribute, which would lose to it, so
|
|
122
|
+
the three [align] rules restate it as author CSS (left included: start
|
|
123
|
+
is right on an RTL site, and `:---` asked for left). Each table is wrapped
|
|
124
|
+
in .g-table-scroll by the markdown hook (Astro) and render-table.html
|
|
125
|
+
(Hugo): the wrapper scrolls sideways when a table is wider than a phone,
|
|
126
|
+
so the table itself keeps its semantics (display: block; overflow-x: auto
|
|
127
|
+
on the <table> would drop them for screen readers). */
|
|
128
|
+
.g-table-scroll { overflow-x: auto; }
|
|
129
|
+
.g-prose table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); line-height: var(--leading-normal); }
|
|
130
|
+
.g-prose th, .g-prose td { border: var(--border-width) solid var(--border-default); padding: 0.55rem 0.75rem; text-align: start; vertical-align: top; }
|
|
131
|
+
.g-prose th { background: var(--surface-wash-soft); color: var(--text-strong); font-weight: var(--weight-semibold); }
|
|
132
|
+
.g-prose :is(th, td)[align="left"] { text-align: left; }
|
|
133
|
+
.g-prose :is(th, td)[align="center"] { text-align: center; }
|
|
134
|
+
.g-prose :is(th, td)[align="right"] { text-align: right; }
|
|
116
135
|
|
|
117
136
|
/* Skip link for a11y */
|
|
118
137
|
.g-skip { position: absolute; left: -999px; top: 0; background: var(--color-primary); color: #fff; padding: 0.6rem 1rem; border-radius: var(--radius-md); z-index: 100; }
|