@erudit-js/prose 3.0.0-dev.30 → 4.0.0-dev.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/dist/app/composables/context.d.ts +2 -1
- package/dist/app/composables/formatText.d.ts +5 -1
- package/dist/app/composables/formatText.js +5 -0
- package/dist/app/default/Text.vue +6 -2
- package/dist/app/shared/Prose.vue +4 -0
- package/dist/app/shared/block/Block.vue +5 -0
- package/dist/app/shared/invert.d.ts +2 -2
- package/dist/app/shared/invert.js +2 -2
- package/dist/app/shared/photoswipe/composable.js +1 -1
- package/dist/elements/accent/Accent.vue +2 -2
- package/dist/elements/accent/AccentColumnSection.vue +2 -2
- package/dist/elements/accent/AccentRowSections.vue +1 -1
- package/dist/elements/accent/core.d.ts +2 -2
- package/dist/elements/callout/Callout.vue +6 -9
- package/dist/elements/callout/core.d.ts +3 -3
- package/dist/elements/caption/Caption.vue +1 -1
- package/dist/elements/details/Details.vue +2 -3
- package/dist/elements/diagram/Diagram.vue +12 -2
- package/dist/elements/diagram/core.d.ts +3 -3
- package/dist/elements/emphasis/Emphasis.vue +1 -1
- package/dist/elements/emphasis/core.d.ts +6 -6
- package/dist/elements/flex/Flex.vue +8 -2
- package/dist/elements/flex/core.d.ts +7 -3
- package/dist/elements/flex/core.js +4 -0
- package/dist/elements/gallery/core.d.ts +3 -3
- package/dist/elements/heading/Heading.vue +1 -1
- package/dist/elements/heading/core.d.ts +9 -9
- package/dist/elements/heading/core.js +14 -10
- package/dist/elements/horizontalLine/HorizontalLine.vue +1 -1
- package/dist/elements/image/core.d.ts +3 -3
- package/dist/elements/link/BlockLink.vue +1 -2
- package/dist/elements/link/Link.vue +6 -3
- package/dist/elements/list/List.vue +10 -8
- package/dist/elements/list/core.d.ts +3 -3
- package/dist/elements/math/block.d.ts +9 -6
- package/dist/elements/math/block.js +2 -1
- package/dist/elements/math/components/BlockMath.vue +1 -1
- package/dist/elements/math/components/MathGroup.vue +5 -3
- package/dist/elements/math/core.d.ts +2 -2
- package/dist/elements/math/inliner.d.ts +2 -2
- package/dist/elements/paragraph/Paragraph.vue +1 -1
- package/dist/elements/paragraph/core.d.ts +3 -3
- package/dist/elements/problem/components/ProblemButton.vue +2 -2
- package/dist/elements/problem/components/ProblemContainer.vue +1 -2
- package/dist/elements/problem/components/ProblemExpander.vue +1 -1
- package/dist/elements/problem/components/ProblemExpanderSection.vue +2 -3
- package/dist/elements/problem/components/ProblemHeader.vue +2 -6
- package/dist/elements/problem/components/Problems.vue +3 -3
- package/dist/elements/problem/components/expanders/Check.vue +2 -3
- package/dist/elements/problem/components/expanders/Checks.vue +1 -1
- package/dist/elements/problem/core.d.ts +44 -8
- package/dist/elements/problem/problem.d.ts +3 -3
- package/dist/elements/problem/problem.js +3 -4
- package/dist/elements/problem/problemContent.d.ts +42 -37
- package/dist/elements/problem/problemContent.js +86 -2
- package/dist/elements/problem/problems.d.ts +3 -3
- package/dist/elements/problem/problems.js +3 -4
- package/dist/elements/table/Table.vue +2 -4
- package/dist/elements/table/core.d.ts +3 -3
- package/dist/elements/video/core.d.ts +3 -3
- package/dist/include.js +0 -1
- package/dist/snippet.d.ts +24 -34
- package/dist/snippet.js +60 -31
- package/dist/tag.d.ts +3 -3
- package/dist/tag.js +1 -1
- package/package.json +2 -2
|
@@ -328,13 +328,23 @@ export type CheckFunction = (args: {
|
|
|
328
328
|
name: string;
|
|
329
329
|
answers: Record<string, string | undefined>;
|
|
330
330
|
}) => boolean;
|
|
331
|
+
export interface ProblemCheckRegex {
|
|
332
|
+
pattern: string;
|
|
333
|
+
flags: string;
|
|
334
|
+
}
|
|
335
|
+
export type ProblemCheckValue = string | ProblemCheckRegex;
|
|
331
336
|
export interface ProblemCheckData {
|
|
332
337
|
label?: string;
|
|
333
338
|
hint?: string;
|
|
334
339
|
placeholder?: string;
|
|
335
|
-
|
|
340
|
+
set?: {
|
|
341
|
+
separator: string;
|
|
342
|
+
values: (ProblemCheckValue | ProblemCheckValue[])[];
|
|
343
|
+
};
|
|
344
|
+
answers?: ProblemCheckValue[];
|
|
336
345
|
script?: string;
|
|
337
346
|
}
|
|
347
|
+
export declare function checkValue(input: string | undefined, data: ProblemCheckData): boolean;
|
|
338
348
|
export declare const problemCheckSchema: {
|
|
339
349
|
name: "problemCheck";
|
|
340
350
|
type: "block";
|
|
@@ -343,6 +353,12 @@ export declare const problemCheckSchema: {
|
|
|
343
353
|
Storage: undefined;
|
|
344
354
|
Children: BlockSchema[];
|
|
345
355
|
};
|
|
356
|
+
type UndefinedOnly<T> = {
|
|
357
|
+
[K in keyof T]?: undefined;
|
|
358
|
+
};
|
|
359
|
+
type OneOf<T extends Record<string, any>> = {
|
|
360
|
+
[K in keyof T]: Pick<T, K> & UndefinedOnly<Omit<T, K>>;
|
|
361
|
+
}[keyof T];
|
|
346
362
|
export declare const ProblemCheck: import("@jsprose/core").Tag<"ProblemCheck", {
|
|
347
363
|
name: "problemCheck";
|
|
348
364
|
type: "block";
|
|
@@ -354,19 +370,15 @@ export declare const ProblemCheck: import("@jsprose/core").Tag<"ProblemCheck", {
|
|
|
354
370
|
label?: string;
|
|
355
371
|
hint?: string;
|
|
356
372
|
placeholder?: string;
|
|
357
|
-
} & (
|
|
358
|
-
answer: string | number;
|
|
359
|
-
answers
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
script?: undefined;
|
|
365
|
-
} | {
|
|
373
|
+
} & (OneOf<{
|
|
374
|
+
answer: string | number | RegExp;
|
|
375
|
+
answers: (string | number | RegExp)[];
|
|
376
|
+
set: (string | number | RegExp | (string | number | RegExp)[])[] | {
|
|
377
|
+
separator: string;
|
|
378
|
+
values: (string | number | RegExp | (string | number | RegExp)[])[];
|
|
379
|
+
};
|
|
366
380
|
script: string;
|
|
367
|
-
|
|
368
|
-
answer?: undefined;
|
|
369
|
-
}) & NoTagChildren)) & {}>;
|
|
381
|
+
}> & NoTagChildren)) & {}>;
|
|
370
382
|
export declare const problemCheckRegistryItem: import("@jsprose/core").RegistryItem<{
|
|
371
383
|
name: "problemCheck";
|
|
372
384
|
type: "block";
|
|
@@ -386,19 +398,15 @@ export declare const problemCheckRegistryItem: import("@jsprose/core").RegistryI
|
|
|
386
398
|
label?: string;
|
|
387
399
|
hint?: string;
|
|
388
400
|
placeholder?: string;
|
|
389
|
-
} & (
|
|
390
|
-
answer: string | number;
|
|
391
|
-
answers
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
script?: undefined;
|
|
397
|
-
} | {
|
|
401
|
+
} & (OneOf<{
|
|
402
|
+
answer: string | number | RegExp;
|
|
403
|
+
answers: (string | number | RegExp)[];
|
|
404
|
+
set: (string | number | RegExp | (string | number | RegExp)[])[] | {
|
|
405
|
+
separator: string;
|
|
406
|
+
values: (string | number | RegExp | (string | number | RegExp)[])[];
|
|
407
|
+
};
|
|
398
408
|
script: string;
|
|
399
|
-
|
|
400
|
-
answer?: undefined;
|
|
401
|
-
}) & NoTagChildren)) & {}>;
|
|
409
|
+
}> & NoTagChildren)) & {}>;
|
|
402
410
|
}, undefined>;
|
|
403
411
|
export declare const problemCheckCoreElement: {
|
|
404
412
|
registryItem: import("@jsprose/core").RegistryItem<{
|
|
@@ -420,20 +428,17 @@ export declare const problemCheckCoreElement: {
|
|
|
420
428
|
label?: string;
|
|
421
429
|
hint?: string;
|
|
422
430
|
placeholder?: string;
|
|
423
|
-
} & (
|
|
424
|
-
answer: string | number;
|
|
425
|
-
answers
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
script?: undefined;
|
|
431
|
-
} | {
|
|
431
|
+
} & (OneOf<{
|
|
432
|
+
answer: string | number | RegExp;
|
|
433
|
+
answers: (string | number | RegExp)[];
|
|
434
|
+
set: (string | number | RegExp | (string | number | RegExp)[])[] | {
|
|
435
|
+
separator: string;
|
|
436
|
+
values: (string | number | RegExp | (string | number | RegExp)[])[];
|
|
437
|
+
};
|
|
432
438
|
script: string;
|
|
433
|
-
|
|
434
|
-
answer?: undefined;
|
|
435
|
-
}) & NoTagChildren)) & {}>;
|
|
439
|
+
}> & NoTagChildren)) & {}>;
|
|
436
440
|
}, undefined>;
|
|
437
441
|
};
|
|
438
442
|
export type ProblemContentChild = typeof problemDescriptionSchema | typeof problemHintSchema | typeof problemNote.schema | typeof problemSolution.schema | typeof problemAnswer.schema | typeof problemCheckSchema;
|
|
439
443
|
export declare function validateProblemContent(source: string, children: NormalizedChildren): void;
|
|
444
|
+
export {};
|
|
@@ -145,6 +145,62 @@ function defineProblemSectionContainer(name) {
|
|
|
145
145
|
export const problemNote = defineProblemSectionContainer("note");
|
|
146
146
|
export const problemSolution = defineProblemSectionContainer("solution");
|
|
147
147
|
export const problemAnswer = defineProblemSectionContainer("answer");
|
|
148
|
+
export function checkValue(input, data) {
|
|
149
|
+
const normalizedInput = input?.trim().replace(/\s+/g, " ") || undefined;
|
|
150
|
+
const matchSingle = (val, condition) => {
|
|
151
|
+
const v = val || "";
|
|
152
|
+
if (typeof condition === "string") {
|
|
153
|
+
return v === condition;
|
|
154
|
+
}
|
|
155
|
+
try {
|
|
156
|
+
const re = new RegExp(condition.pattern, condition.flags);
|
|
157
|
+
return re.test(v);
|
|
158
|
+
} catch {
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
if (data.answers) {
|
|
163
|
+
if (!normalizedInput) return false;
|
|
164
|
+
return data.answers.some((ans) => matchSingle(normalizedInput, ans));
|
|
165
|
+
}
|
|
166
|
+
if (data.set) {
|
|
167
|
+
const { separator, values } = data.set;
|
|
168
|
+
const separatorRegex = new RegExp(`\\s*${separator.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\s*`);
|
|
169
|
+
const inputValues = normalizedInput ? normalizedInput.split(separatorRegex).map((v) => v.trim()).filter((v) => v) : [];
|
|
170
|
+
if (inputValues.length !== values.length) {
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
const canMatch = (inputVal, expectedVal) => {
|
|
174
|
+
if (Array.isArray(expectedVal)) {
|
|
175
|
+
return expectedVal.some((ev) => matchSingle(inputVal, ev));
|
|
176
|
+
}
|
|
177
|
+
return matchSingle(inputVal, expectedVal);
|
|
178
|
+
};
|
|
179
|
+
const adj = inputValues.map((inputVal) => values.map((v, idx) => canMatch(inputVal, v) ? idx : -1).filter((idx) => idx !== -1));
|
|
180
|
+
const matchV = new Array(values.length).fill(-1);
|
|
181
|
+
const vis = new Array(values.length).fill(false);
|
|
182
|
+
const dfs = (u) => {
|
|
183
|
+
for (const v of adj[u]) {
|
|
184
|
+
if (vis[v]) continue;
|
|
185
|
+
vis[v] = true;
|
|
186
|
+
if (matchV[v] < 0 || dfs(matchV[v])) {
|
|
187
|
+
matchV[v] = u;
|
|
188
|
+
return true;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return false;
|
|
192
|
+
};
|
|
193
|
+
let matches = 0;
|
|
194
|
+
for (let i = 0; i < inputValues.length; i++) {
|
|
195
|
+
vis.fill(false);
|
|
196
|
+
if (dfs(i)) {
|
|
197
|
+
matches++;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return matches === values.length;
|
|
201
|
+
}
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
148
204
|
export const problemCheckSchema = defineSchema({
|
|
149
205
|
name: "problemCheck",
|
|
150
206
|
type: "block",
|
|
@@ -155,21 +211,49 @@ export const ProblemCheck = defineEruditTag({
|
|
|
155
211
|
schema: problemCheckSchema
|
|
156
212
|
})(({ element, tagName, props, children }) => {
|
|
157
213
|
ensureTagNoChildren(tagName, children);
|
|
214
|
+
const normalizeCheckValue = (val) => {
|
|
215
|
+
if (val instanceof RegExp) {
|
|
216
|
+
return {
|
|
217
|
+
pattern: val.source,
|
|
218
|
+
flags: val.flags
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
return String(val);
|
|
222
|
+
};
|
|
158
223
|
if (props.answer !== undefined) {
|
|
159
224
|
element.data = {
|
|
160
225
|
...element.data,
|
|
161
|
-
answers: [
|
|
226
|
+
answers: [normalizeCheckValue(props.answer)]
|
|
162
227
|
};
|
|
163
228
|
} else if (props.answers !== undefined) {
|
|
164
229
|
element.data = {
|
|
165
230
|
...element.data,
|
|
166
|
-
answers: props.answers.map(
|
|
231
|
+
answers: props.answers.map(normalizeCheckValue)
|
|
167
232
|
};
|
|
168
233
|
} else if (props.script !== undefined) {
|
|
169
234
|
element.data = {
|
|
170
235
|
...element.data,
|
|
171
236
|
script: props.script
|
|
172
237
|
};
|
|
238
|
+
} else if (props.set !== undefined) {
|
|
239
|
+
const normalizeSetItem = (v) => Array.isArray(v) ? v.map(normalizeCheckValue) : normalizeCheckValue(v);
|
|
240
|
+
if (Array.isArray(props.set)) {
|
|
241
|
+
element.data = {
|
|
242
|
+
...element.data,
|
|
243
|
+
set: {
|
|
244
|
+
separator: ",",
|
|
245
|
+
values: props.set.map(normalizeSetItem)
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
} else {
|
|
249
|
+
element.data = {
|
|
250
|
+
...element.data,
|
|
251
|
+
set: {
|
|
252
|
+
separator: props.set.separator,
|
|
253
|
+
values: props.set.values.map(normalizeSetItem)
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
}
|
|
173
257
|
}
|
|
174
258
|
if (props.label !== undefined) {
|
|
175
259
|
element.data = {
|
|
@@ -127,7 +127,7 @@ export declare const Problems: import("@jsprose/core").Tag<"Problems", {
|
|
|
127
127
|
applied?: true | undefined;
|
|
128
128
|
method?: true | undefined;
|
|
129
129
|
inter?: true | undefined;
|
|
130
|
-
} & TagChildren & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet
|
|
130
|
+
} & TagChildren & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet>;
|
|
131
131
|
export declare const problemsRegistryItem: import("@jsprose/core").RegistryItem<{
|
|
132
132
|
name: "problems";
|
|
133
133
|
type: "block";
|
|
@@ -166,7 +166,7 @@ export declare const problemsRegistryItem: import("@jsprose/core").RegistryItem<
|
|
|
166
166
|
applied?: true | undefined;
|
|
167
167
|
method?: true | undefined;
|
|
168
168
|
inter?: true | undefined;
|
|
169
|
-
} & TagChildren & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet
|
|
169
|
+
} & TagChildren & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet>;
|
|
170
170
|
}, undefined>;
|
|
171
171
|
export declare const problemsCoreElement: {
|
|
172
172
|
registryItem: import("@jsprose/core").RegistryItem<{
|
|
@@ -207,6 +207,6 @@ export declare const problemsCoreElement: {
|
|
|
207
207
|
applied?: true | undefined;
|
|
208
208
|
method?: true | undefined;
|
|
209
209
|
inter?: true | undefined;
|
|
210
|
-
} & TagChildren & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet
|
|
210
|
+
} & TagChildren & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet>;
|
|
211
211
|
}, undefined>;
|
|
212
212
|
};
|
|
@@ -62,10 +62,9 @@ export const Problems = defineEruditTag({
|
|
|
62
62
|
throw new ProseError(`<${tagName}> must have at least one <SubProblem> child!`);
|
|
63
63
|
}
|
|
64
64
|
element.children = [...otherChildren, ...subProblemChildren];
|
|
65
|
-
|
|
66
|
-
element.
|
|
67
|
-
element.
|
|
68
|
-
element.toc = { add: true };
|
|
65
|
+
const problemInfo = problemProps2Info(props);
|
|
66
|
+
element.data = problemInfo;
|
|
67
|
+
element.title = problemInfo.title;
|
|
69
68
|
});
|
|
70
69
|
export const problemsRegistryItem = defineRegistryItem({
|
|
71
70
|
schema: problemsSchema,
|
|
@@ -31,16 +31,14 @@ const rows = computed(() =>
|
|
|
31
31
|
:class="[
|
|
32
32
|
$style.table,
|
|
33
33
|
`text-main-sm bg-bg-main m-auto max-w-full border-separate
|
|
34
|
-
border-spacing-[3px] rounded border border-(--tableBorder)
|
|
35
|
-
transition-[background,border]`,
|
|
34
|
+
border-spacing-[3px] rounded border border-(--tableBorder)`,
|
|
36
35
|
]"
|
|
37
36
|
>
|
|
38
37
|
<tbody>
|
|
39
38
|
<tr
|
|
40
39
|
v-for="row in rows"
|
|
41
40
|
:key="row.id"
|
|
42
|
-
class="
|
|
43
|
-
even:bg-(--evenCellBg)"
|
|
41
|
+
class="odd:bg-(--oddCellBg) even:bg-(--evenCellBg)"
|
|
44
42
|
>
|
|
45
43
|
<td
|
|
46
44
|
v-for="cell in row.children"
|
|
@@ -150,7 +150,7 @@ export declare const Table: import("@jsprose/core").Tag<"Table", {
|
|
|
150
150
|
Children: InlinerSchema[];
|
|
151
151
|
}[];
|
|
152
152
|
})[];
|
|
153
|
-
}, TagChildren & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet
|
|
153
|
+
}, TagChildren & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet>;
|
|
154
154
|
export declare const tableRegistryItem: import("@jsprose/core").RegistryItem<{
|
|
155
155
|
name: "table";
|
|
156
156
|
type: "block";
|
|
@@ -208,7 +208,7 @@ export declare const tableRegistryItem: import("@jsprose/core").RegistryItem<{
|
|
|
208
208
|
Children: InlinerSchema[];
|
|
209
209
|
}[];
|
|
210
210
|
})[];
|
|
211
|
-
}, TagChildren & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet
|
|
211
|
+
}, TagChildren & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet>;
|
|
212
212
|
}, undefined>;
|
|
213
213
|
declare const _default: [{
|
|
214
214
|
registryItem: import("@jsprose/core").RegistryItem<{
|
|
@@ -318,7 +318,7 @@ declare const _default: [{
|
|
|
318
318
|
Children: InlinerSchema[];
|
|
319
319
|
}[];
|
|
320
320
|
})[];
|
|
321
|
-
}, TagChildren & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet
|
|
321
|
+
}, TagChildren & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet>;
|
|
322
322
|
}, undefined>;
|
|
323
323
|
}];
|
|
324
324
|
export default _default;
|
|
@@ -43,7 +43,7 @@ export declare const Video: import("@jsprose/core").Tag<"Video", {
|
|
|
43
43
|
invert?: Invert;
|
|
44
44
|
width?: string;
|
|
45
45
|
children?: {};
|
|
46
|
-
} & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet
|
|
46
|
+
} & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet>;
|
|
47
47
|
export declare const videoRegistryItem: import("@jsprose/core").RegistryItem<{
|
|
48
48
|
name: "video";
|
|
49
49
|
type: "block";
|
|
@@ -79,7 +79,7 @@ export declare const videoRegistryItem: import("@jsprose/core").RegistryItem<{
|
|
|
79
79
|
invert?: Invert;
|
|
80
80
|
width?: string;
|
|
81
81
|
children?: {};
|
|
82
|
-
} & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet
|
|
82
|
+
} & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet>;
|
|
83
83
|
}, undefined>;
|
|
84
84
|
declare const _default: {
|
|
85
85
|
registryItem: import("@jsprose/core").RegistryItem<{
|
|
@@ -117,7 +117,7 @@ declare const _default: {
|
|
|
117
117
|
invert?: Invert;
|
|
118
118
|
width?: string;
|
|
119
119
|
children?: {};
|
|
120
|
-
} & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet
|
|
120
|
+
} & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet>;
|
|
121
121
|
}, undefined>;
|
|
122
122
|
};
|
|
123
123
|
export default _default;
|
package/dist/include.js
CHANGED
package/dist/snippet.d.ts
CHANGED
|
@@ -4,60 +4,50 @@ import type { EruditRawElement } from './rawElement.js';
|
|
|
4
4
|
/**
|
|
5
5
|
* Snippet attribute - only contains title and description
|
|
6
6
|
*/
|
|
7
|
-
export interface
|
|
7
|
+
export interface SnippetData {
|
|
8
|
+
/** General snippet title. Used as fallback value for flags. */
|
|
8
9
|
title?: string;
|
|
10
|
+
/** General snippet description. Used as fallback value for flags. */
|
|
9
11
|
description?: string;
|
|
10
|
-
}
|
|
11
|
-
export type ObjPropSnippet = {
|
|
12
|
-
/**
|
|
13
|
-
* Compact summary of the element with title and description.
|
|
14
|
-
*/
|
|
15
|
-
snippet?: SnippetProp;
|
|
16
|
-
};
|
|
17
|
-
export type ObjPropSearch = {
|
|
18
12
|
/**
|
|
19
13
|
* Show element in search results.
|
|
20
|
-
* Can be a boolean to enable/disable, or an object with synonyms.
|
|
21
14
|
*/
|
|
22
|
-
search?: boolean | {
|
|
23
|
-
|
|
15
|
+
search?: boolean | string | string[] | {
|
|
16
|
+
title?: string;
|
|
17
|
+
description?: string;
|
|
18
|
+
synonyms?: string[];
|
|
24
19
|
};
|
|
25
|
-
};
|
|
26
|
-
export type ObjPropQuick = {
|
|
27
20
|
/**
|
|
28
21
|
* Show element in "Quick Links" sections at start of the page and also in TOC.
|
|
29
22
|
*/
|
|
30
|
-
quick?: boolean
|
|
31
|
-
|
|
32
|
-
|
|
23
|
+
quick?: boolean | string | {
|
|
24
|
+
title?: string;
|
|
25
|
+
description?: string;
|
|
26
|
+
};
|
|
33
27
|
/**
|
|
34
28
|
* When targeting this element with '#' anchor, adjust SEO metadata (like title and description).
|
|
35
29
|
* Search engines should treat it as a different "page" and therefore show it as a standalone search result.
|
|
36
30
|
*/
|
|
37
|
-
seo?: boolean
|
|
31
|
+
seo?: boolean | string | {
|
|
32
|
+
title?: string;
|
|
33
|
+
description?: string;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export type ObjPropSnippet = {
|
|
37
|
+
/**
|
|
38
|
+
* Compact summary of the element and where to show it (search, quick links, SEO).
|
|
39
|
+
*/
|
|
40
|
+
snippet?: SnippetData;
|
|
38
41
|
};
|
|
39
42
|
export type ObjRawElementSnippet = {
|
|
40
|
-
snippet?:
|
|
41
|
-
snippetFlags?: {
|
|
42
|
-
quick?: boolean;
|
|
43
|
-
search?: boolean | {
|
|
44
|
-
synonyms: string[];
|
|
45
|
-
};
|
|
46
|
-
seo?: boolean;
|
|
47
|
-
};
|
|
43
|
+
snippet?: SnippetData;
|
|
48
44
|
};
|
|
49
|
-
export declare function finalizeSnippet(processTagArgs: EruditProcessTagArgs):
|
|
45
|
+
export declare function finalizeSnippet(processTagArgs: EruditProcessTagArgs): SnippetData | undefined;
|
|
50
46
|
export interface ResolvedSnippet {
|
|
51
|
-
title: string;
|
|
52
|
-
description?: string;
|
|
53
|
-
quick?: boolean;
|
|
54
|
-
search?: boolean | {
|
|
55
|
-
synonyms: string[];
|
|
56
|
-
};
|
|
57
|
-
seo?: boolean;
|
|
58
47
|
schemaName: string;
|
|
59
48
|
isUnique: boolean;
|
|
60
49
|
elementId: string;
|
|
50
|
+
snippetData: SnippetData;
|
|
61
51
|
}
|
|
62
52
|
export declare const snippetStep: ({ rawElement, proseElement }: {
|
|
63
53
|
context: import("./context.js").EruditProseContext;
|
package/dist/snippet.js
CHANGED
|
@@ -1,56 +1,85 @@
|
|
|
1
1
|
import { ProseError } from "@jsprose/core";
|
|
2
2
|
import { defineResolveStep } from "./resolveStep.js";
|
|
3
3
|
export function finalizeSnippet(processTagArgs) {
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
|
|
4
|
+
const finalSnippet = {};
|
|
5
|
+
const propsSnippet = processTagArgs.props.snippet;
|
|
6
|
+
const builtinSnippet = processTagArgs.element.snippet;
|
|
7
|
+
//
|
|
8
|
+
const quick = propsSnippet?.quick ?? builtinSnippet?.quick;
|
|
9
|
+
if (quick) {
|
|
10
|
+
finalSnippet.quick = quick;
|
|
11
|
+
}
|
|
12
|
+
//
|
|
13
|
+
const search = propsSnippet?.search ?? builtinSnippet?.search;
|
|
14
|
+
if (search) {
|
|
15
|
+
finalSnippet.search = search;
|
|
16
|
+
}
|
|
17
|
+
//
|
|
18
|
+
let seo = propsSnippet?.seo ?? builtinSnippet?.seo;
|
|
7
19
|
// If none of the flags are set to true, no snippet is created
|
|
8
20
|
if (!quick && !search && !seo) {
|
|
9
21
|
return undefined;
|
|
10
22
|
}
|
|
11
23
|
// Enable SEO if either quick or search is enabled unless SEO is explicitly disabled
|
|
12
24
|
// Check both element defaults and props - if either explicitly disables seo, don't auto-enable
|
|
13
|
-
const seoExplicitlyDisabled =
|
|
14
|
-
if (!
|
|
15
|
-
if (
|
|
16
|
-
|
|
25
|
+
const seoExplicitlyDisabled = builtinSnippet?.seo === false || propsSnippet?.seo === false;
|
|
26
|
+
if (!seo) {
|
|
27
|
+
if (!seoExplicitlyDisabled) {
|
|
28
|
+
if (quick || search) {
|
|
29
|
+
seo = true;
|
|
30
|
+
}
|
|
17
31
|
}
|
|
18
32
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
33
|
+
if (seo) {
|
|
34
|
+
finalSnippet.seo = seo;
|
|
35
|
+
}
|
|
36
|
+
//
|
|
37
|
+
const title = getGenericTitle(processTagArgs);
|
|
38
|
+
if (title) {
|
|
39
|
+
finalSnippet.title = title;
|
|
40
|
+
}
|
|
41
|
+
const description = getGenericDescription(processTagArgs);
|
|
22
42
|
if (description) {
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
//
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
43
|
+
finalSnippet.description = description;
|
|
44
|
+
}
|
|
45
|
+
//
|
|
46
|
+
if (!finalSnippet.title) {
|
|
47
|
+
let titlessFlags = [];
|
|
48
|
+
if (quick && typeof quick !== "string") {
|
|
49
|
+
if (quick === true || !quick.title) {
|
|
50
|
+
titlessFlags.push("quick");
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (search && typeof search !== "string") {
|
|
54
|
+
if (search === true || Array.isArray(search) || !search.title) {
|
|
55
|
+
titlessFlags.push("search");
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (seo && typeof seo !== "string") {
|
|
59
|
+
if (seo === true || !seo.title) {
|
|
60
|
+
titlessFlags.push("seo");
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
throw new ProseError(`Unable to get title for snippet flags (${titlessFlags.join(", ")}) because no explicit, general inherited title was provided!`);
|
|
64
|
+
}
|
|
65
|
+
//
|
|
66
|
+
processTagArgs.element.snippet = finalSnippet;
|
|
67
|
+
return finalSnippet;
|
|
32
68
|
}
|
|
33
|
-
function
|
|
69
|
+
function getGenericTitle(processTagArgs) {
|
|
34
70
|
const title = processTagArgs.props.snippet?.title?.trim() || processTagArgs.element.snippet?.title?.trim() || processTagArgs.element.title?.trim();
|
|
35
|
-
if (!title) {
|
|
36
|
-
throw new ProseError(`Unable to finalize snippet title!`);
|
|
37
|
-
}
|
|
38
71
|
return title;
|
|
39
72
|
}
|
|
40
|
-
function
|
|
73
|
+
function getGenericDescription(processTagArgs) {
|
|
41
74
|
return processTagArgs.props.snippet?.description?.trim() || processTagArgs.element.snippet?.description?.trim();
|
|
42
75
|
}
|
|
43
76
|
export const snippetStep = defineResolveStep(({ rawElement, proseElement }) => {
|
|
44
|
-
if (rawElement.snippet && proseElement.id
|
|
77
|
+
if (rawElement.snippet && proseElement.id) {
|
|
45
78
|
const resolvedSnippet = {
|
|
46
|
-
title: rawElement.snippet.title,
|
|
47
|
-
description: rawElement.snippet.description,
|
|
48
|
-
quick: rawElement.snippetFlags?.quick,
|
|
49
|
-
search: rawElement.snippetFlags?.search,
|
|
50
|
-
seo: rawElement.snippetFlags?.seo,
|
|
51
79
|
schemaName: rawElement.schemaName,
|
|
52
80
|
isUnique: Boolean(rawElement.uniqueName),
|
|
53
|
-
elementId: proseElement.id
|
|
81
|
+
elementId: proseElement.id,
|
|
82
|
+
snippetData: rawElement.snippet
|
|
54
83
|
};
|
|
55
84
|
return resolvedSnippet;
|
|
56
85
|
}
|
package/dist/tag.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Registry, type AnySchema, type ConfigurableTagProps, type NormalizedChildren, type ProcessTagFunction, type TagDefinition } from '@jsprose/core';
|
|
2
2
|
import type { EruditRawElement } from './rawElement.js';
|
|
3
|
-
import { type ObjPropSnippet
|
|
3
|
+
import { type ObjPropSnippet } from './snippet.js';
|
|
4
4
|
import { type ObjPropToc } from './toc.js';
|
|
5
5
|
declare const NoTocSymbol: unique symbol;
|
|
6
6
|
declare const NoSnippetSymbol: unique symbol;
|
|
@@ -10,11 +10,11 @@ export type NoToc = {
|
|
|
10
10
|
export type NoSnippet = {
|
|
11
11
|
readonly [NoSnippetSymbol]?: never;
|
|
12
12
|
};
|
|
13
|
-
export type EruditTagProps<TProps extends Record<string, unknown>> = (TProps extends NoToc ? {} : ObjPropToc) & (TProps extends NoSnippet ? {} : ObjPropSnippet
|
|
13
|
+
export type EruditTagProps<TProps extends Record<string, unknown>> = (TProps extends NoToc ? {} : ObjPropToc) & (TProps extends NoSnippet ? {} : ObjPropSnippet);
|
|
14
14
|
export type EruditProcessTagArgs = {
|
|
15
15
|
tagName: string;
|
|
16
16
|
element: EruditRawElement<AnySchema>;
|
|
17
|
-
props: ConfigurableTagProps & ObjPropSnippet & ObjPropToc
|
|
17
|
+
props: ConfigurableTagProps & ObjPropSnippet & ObjPropToc;
|
|
18
18
|
children: NormalizedChildren;
|
|
19
19
|
registry: Registry;
|
|
20
20
|
};
|
package/dist/tag.js
CHANGED
|
@@ -12,7 +12,7 @@ export function defineEruditTag(definition) {
|
|
|
12
12
|
args.element.snippet = finalizeSnippet(args);
|
|
13
13
|
args.element.toc = finalizeToc(args);
|
|
14
14
|
// Use every possibility to get human-readable slug whether it is set manually or taken from snippet or toc
|
|
15
|
-
args.element.slug ||= args.element.snippet?.title || args.element.toc?.title;
|
|
15
|
+
args.element.slug ||= args.element.snippet?.title || args.element.toc?.title || args.element.title;
|
|
16
16
|
});
|
|
17
17
|
return eruditTag;
|
|
18
18
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@erudit-js/prose",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "4.0.0-dev.2",
|
|
5
5
|
"description": "📝 JSX prose subsystem for Erudit sites",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"prepack": "bun run build"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@erudit-js/core": "
|
|
35
|
+
"@erudit-js/core": "4.0.0-dev.2",
|
|
36
36
|
"@jsprose/core": "^1.0.0",
|
|
37
37
|
"vue": "latest",
|
|
38
38
|
"@floating-ui/vue": "^1.1.9",
|