Skip to content

Commit 7d7a3a8

Browse files
authored
fix: improve directive handling (#248)
1 parent 6384209 commit 7d7a3a8

File tree

5 files changed

+26
-19
lines changed

5 files changed

+26
-19
lines changed

workspace/aubade/src/artisan/example.spec.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -712,13 +712,13 @@ describe('libretto', ({ concurrent: it }) => {
712712
'comment#inline/3': ['a <!-- comment b', '<p>a &lt;!– comment b</p>'],
713713

714714
'directive#youtube': [
715-
'@youtube{id=7TovqLDCosk caption="hitoribocchi tokyo"}',
715+
'@youtube{id=7TovqLDCosk caption="[hitoribocchi tokyo](https://music.youtube.com/watch?v=7TovqLDCosk) by kessoku band"}',
716716
[
717717
'<figure>',
718718
'<div data-aubade="youtube">',
719719
'<iframe src="https://www.youtube-nocookie.com/embed/7TovqLDCosk" title="YouTube video player" loading="lazy" frameborder="0" allowfullscreen allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin"></iframe>',
720720
'</div>',
721-
'<figcaption>hitoribocchi tokyo</figcaption>',
721+
'<figcaption><a href="https://music.youtube.com/watch?v=7TovqLDCosk">hitoribocchi tokyo</a> by kessoku band</figcaption>',
722722
'</figure>',
723723
].join('\n'),
724724
],
@@ -734,7 +734,7 @@ describe('libretto', ({ concurrent: it }) => {
734734
].join('\n'),
735735
],
736736
'directive#youtube/newlines': [
737-
['@youtube{', ' id=7TovqLDCosk', ' caption="hitoribocchi tokyo"', '}'].join('\n'),
737+
'@youtube{\n id=7TovqLDCosk\n caption="hitoribocchi tokyo"\n}',
738738
[
739739
'<figure>',
740740
'<div data-aubade="youtube">',
@@ -755,7 +755,7 @@ describe('libretto', ({ concurrent: it }) => {
755755
].join('\n'),
756756
],
757757
'directive#youtube/series': [
758-
'@youtube{series="PLZRRxQcaEjA4qyEuYfAMCazlL0vQDkIj2" caption="Mind Field: Season 1"}',
758+
'@youtube{series=PLZRRxQcaEjA4qyEuYfAMCazlL0vQDkIj2 caption="Mind Field: Season 1"}',
759759
[
760760
'<figure>',
761761
'<div data-aubade="youtube">',
@@ -765,6 +765,17 @@ describe('libretto', ({ concurrent: it }) => {
765765
'</figure>',
766766
].join('\n'),
767767
],
768+
'directive#youtube/timestamp': [
769+
'@youtube{id="B3akM3m_tz0?t=37" caption="Guitar, Loneliness and Blue Planet"',
770+
[
771+
'<figure>',
772+
'<div data-aubade="youtube">',
773+
'<iframe src="https://www.youtube-nocookie.com/embed/B3akM3m_tz0?t=37" title="YouTube video player" loading="lazy" frameborder="0" allowfullscreen allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin"></iframe>',
774+
'</div>',
775+
'<figcaption>Guitar, Loneliness and Blue Planet</figcaption>',
776+
'</figure>',
777+
].join('\n'),
778+
],
768779

769780
'directive#video': [
770781
'@video{src="./video.mp4" caption="local video"}',

workspace/aubade/src/artisan/index.ts

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@ import { escape } from './utils.js';
66

77
export type Director = (panel: {
88
data: Extract<Token, { type: 'aubade:directive' }>['meta']['data'];
9-
annotate: typeof annotate;
9+
annotate(source: string): string;
1010
print(...lines: Array<string | false>): string;
11-
render(token: Token): string;
1211
sanitize: typeof escape;
1312
}) => string;
1413

@@ -37,12 +36,9 @@ export function forge({ directive = {}, renderer = {}, transform = {} }: Options
3736
if (!transform) throw new Error(`Unknown directive type: ${meta.type}`);
3837
return transform({
3938
data: meta.data,
40-
annotate,
41-
render,
39+
annotate: (source) => annotate(source).map(render).join(''),
40+
print: (...lines) => lines.flatMap((l) => (!l ? [] : l)).join('\n'),
4241
sanitize,
43-
print(...lines) {
44-
return lines.flatMap((l) => (!l ? [] : l)).join('\n');
45-
},
4642
});
4743
},
4844
} satisfies Options['renderer'];
@@ -74,7 +70,8 @@ export function forge({ directive = {}, renderer = {}, transform = {} }: Options
7470
function html<T extends Token['type']>(token: Extract<Token, { type: T }>): string {
7571
const resolve: Resolver<T> = { ...resolver, ...overrides }[token.type] as any;
7672
if (!resolve) throw new Error(`Unknown token type: ${token.type}`);
77-
return resolve({ token, render: html, sanitize: escape });
73+
const visited = transform[token.type] ? walk(token, transform) : token;
74+
return resolve({ token: visited, render: html, sanitize: escape });
7875
}
7976
return stream.map(html).join('\n');
8077
},

workspace/aubade/src/artisan/registry.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ export function directive({ cursor }: Context): null | {
103103
data[clean(name)] = String(value === '' || value);
104104
name = value = '';
105105
equals = false;
106-
} else if (char === '=') {
106+
} else if (!quoted && char === '=') {
107107
equals = true;
108108
} else if (quoted || char !== ' ') {
109109
if (!equals) name += char;

workspace/aubade/src/artisan/resolver.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { Options } from './index.js';
22

33
export const base = {
4-
youtube({ data, annotate, print, render, sanitize }) {
4+
youtube({ data, annotate, print, sanitize }) {
55
const id = sanitize(data.series || data.id || '');
66
const prefix = data.series ? 'videoseries?list=' : '';
77
const src = `https://www.youtube-nocookie.com/embed/${prefix}${id}`;
@@ -13,7 +13,7 @@ export const base = {
1313
'allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture; web-share"',
1414
'referrerpolicy="strict-origin-when-cross-origin"',
1515
];
16-
const text = annotate(data.caption || 'youtube video').map(render);
16+
const text = annotate(data.caption || 'youtube video');
1717
return print(
1818
data.disclosure ? '<details>' : '<figure>',
1919
data.disclosure && `<summary>${text}</summary>`,
@@ -24,10 +24,10 @@ export const base = {
2424
data.disclosure ? '</details>' : '</figure>',
2525
);
2626
},
27-
video({ data, annotate, print, render, sanitize }) {
27+
video({ data, annotate, print, sanitize }) {
2828
const src = sanitize(data.src || '');
2929
const type = sanitize(data.type || 'video/mp4').toLowerCase();
30-
const text = annotate(data.caption || 'video').map(render);
30+
const text = annotate(data.caption || 'video');
3131
return print(
3232
data.disclosure ? '<details>' : '<figure>',
3333
data.disclosure && `<summary>${text}</summary>`,

workspace/content/artisan/+article.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,8 @@ engrave('hello world').html();
3434
```typescript
3535
export type Director = (panel: {
3636
data: Extract<Token, { type: 'aubade:directive' }>['meta']['data'];
37-
annotate: typeof annotate;
37+
annotate(source: string): string;
3838
print(...lines: Array<string | false>): string;
39-
render(token: Token): string;
4039
sanitize: typeof escape;
4140
}) => string;
4241

0 commit comments

Comments
 (0)