@erudit-js/prose 4.0.0-dev.1 → 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/shared/invert.d.ts +2 -2
- package/dist/app/shared/invert.js +2 -2
- 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/details/Details.vue +1 -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 +4 -2
- package/dist/elements/list/List.vue +3 -6
- package/dist/elements/list/core.d.ts +3 -3
- package/dist/elements/math/block.d.ts +9 -9
- package/dist/elements/math/block.js +3 -3
- package/dist/elements/math/components/BlockMath.vue +1 -1
- package/dist/elements/math/components/MathGroup.vue +4 -4
- 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 -2
- 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 -2
- 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
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { type TagChildren } from '@jsprose/core';
|
|
2
|
-
export declare const mathGroupTypes: readonly ["
|
|
2
|
+
export declare const mathGroupTypes: readonly ["0", "small", "normal", "big"];
|
|
3
3
|
export type MathGroupGapType = (typeof mathGroupTypes)[number] | 'custom';
|
|
4
4
|
export interface MathGroupGapTemplate {
|
|
5
5
|
type: MathGroupGapType;
|
|
6
6
|
}
|
|
7
|
-
export interface
|
|
8
|
-
type: '
|
|
7
|
+
export interface MathGroupGapZero extends MathGroupGapTemplate {
|
|
8
|
+
type: '0';
|
|
9
|
+
}
|
|
10
|
+
export interface MathGroupGapSmall extends MathGroupGapTemplate {
|
|
11
|
+
type: 'small';
|
|
9
12
|
}
|
|
10
13
|
export interface MathGroupGapNormal extends MathGroupGapTemplate {
|
|
11
14
|
type: 'normal';
|
|
@@ -13,14 +16,11 @@ export interface MathGroupGapNormal extends MathGroupGapTemplate {
|
|
|
13
16
|
export interface MathGroupGapBig extends MathGroupGapTemplate {
|
|
14
17
|
type: 'big';
|
|
15
18
|
}
|
|
16
|
-
export interface MathGroupGapHuge extends MathGroupGapTemplate {
|
|
17
|
-
type: 'huge';
|
|
18
|
-
}
|
|
19
19
|
export interface MathGroupGapCustom extends MathGroupGapTemplate {
|
|
20
20
|
type: 'custom';
|
|
21
21
|
size: string;
|
|
22
22
|
}
|
|
23
|
-
export type MathGroupGap =
|
|
23
|
+
export type MathGroupGap = MathGroupGapZero | MathGroupGapSmall | MathGroupGapNormal | MathGroupGapBig | MathGroupGapCustom;
|
|
24
24
|
export type MathGroupPart = string | MathGroup;
|
|
25
25
|
export interface MathGroup {
|
|
26
26
|
gap: MathGroupGap;
|
|
@@ -48,7 +48,7 @@ export declare const BlockMath: import("@jsprose/core").Tag<"BlockMath", {
|
|
|
48
48
|
Children: undefined;
|
|
49
49
|
}, {
|
|
50
50
|
freeze?: boolean;
|
|
51
|
-
} & TagChildren & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet
|
|
51
|
+
} & TagChildren & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet>;
|
|
52
52
|
export declare const blockMathRegistryItem: import("@jsprose/core").RegistryItem<{
|
|
53
53
|
name: "blockMath";
|
|
54
54
|
type: "block";
|
|
@@ -66,7 +66,7 @@ export declare const blockMathRegistryItem: import("@jsprose/core").RegistryItem
|
|
|
66
66
|
Children: undefined;
|
|
67
67
|
}, {
|
|
68
68
|
freeze?: boolean;
|
|
69
|
-
} & TagChildren & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet
|
|
69
|
+
} & TagChildren & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet>;
|
|
70
70
|
}, (element: import("@jsprose/core").ProseElement<{
|
|
71
71
|
name: "blockMath";
|
|
72
72
|
type: "block";
|
|
@@ -2,10 +2,10 @@ import { defineRegistryItem, defineSchema, ensureTagChild, ProseError, textSchem
|
|
|
2
2
|
import { latexToHtml, normalizeKatex } from "./katex.js";
|
|
3
3
|
import { defineEruditTag } from "../../tag.js";
|
|
4
4
|
export const mathGroupTypes = [
|
|
5
|
-
"
|
|
5
|
+
"0",
|
|
6
|
+
"small",
|
|
6
7
|
"normal",
|
|
7
|
-
"big"
|
|
8
|
-
"huge"
|
|
8
|
+
"big"
|
|
9
9
|
];
|
|
10
10
|
function gapFromString(strGap) {
|
|
11
11
|
if (mathGroupTypes.includes(strGap)) {
|
|
@@ -23,7 +23,7 @@ const mathGroup: _MathGroup = blockMathStorage;
|
|
|
23
23
|
|
|
24
24
|
<template>
|
|
25
25
|
<Block :element>
|
|
26
|
-
<div :style="{ '--mathRowGap': '
|
|
26
|
+
<div :style="{ '--mathRowGap': '1em' }">
|
|
27
27
|
<MathGroup :mathGroup :freeze="Boolean(element.data.freeze)" />
|
|
28
28
|
</div>
|
|
29
29
|
</Block>
|
|
@@ -9,13 +9,13 @@ const { mathGroup } = defineProps<{
|
|
|
9
9
|
|
|
10
10
|
const columnGap = (() => {
|
|
11
11
|
switch (mathGroup.gap.type) {
|
|
12
|
-
case '
|
|
12
|
+
case '0':
|
|
13
13
|
return '0px';
|
|
14
|
-
case '
|
|
14
|
+
case 'small':
|
|
15
15
|
return 'var(--proseAsideWidth)';
|
|
16
|
-
case '
|
|
16
|
+
case 'normal':
|
|
17
17
|
return 'calc(var(--proseAsideWidth) * 2)';
|
|
18
|
-
case '
|
|
18
|
+
case 'big':
|
|
19
19
|
return 'calc(var(--proseAsideWidth) * 4)';
|
|
20
20
|
case 'custom':
|
|
21
21
|
return mathGroup.gap.size;
|
|
@@ -14,7 +14,7 @@ declare const _default: [{
|
|
|
14
14
|
Data: string;
|
|
15
15
|
Storage: import("./inliner.js").InlinerMathStorage;
|
|
16
16
|
Children: undefined;
|
|
17
|
-
}, import("@jsprose/core").TagChildren & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet
|
|
17
|
+
}, import("@jsprose/core").TagChildren & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet>;
|
|
18
18
|
}, (element: import("@jsprose/core").ProseElement<{
|
|
19
19
|
name: "inlinerMath";
|
|
20
20
|
type: "inliner";
|
|
@@ -47,7 +47,7 @@ declare const _default: [{
|
|
|
47
47
|
Children: undefined;
|
|
48
48
|
}, {
|
|
49
49
|
freeze?: boolean;
|
|
50
|
-
} & import("@jsprose/core").TagChildren & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet
|
|
50
|
+
} & import("@jsprose/core").TagChildren & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet>;
|
|
51
51
|
}, (element: import("@jsprose/core").ProseElement<{
|
|
52
52
|
name: "blockMath";
|
|
53
53
|
type: "block";
|
|
@@ -35,7 +35,7 @@ export declare const M: import("@jsprose/core").Tag<"M", {
|
|
|
35
35
|
Data: string;
|
|
36
36
|
Storage: InlinerMathStorage;
|
|
37
37
|
Children: undefined;
|
|
38
|
-
}, TagChildren & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet
|
|
38
|
+
}, TagChildren & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet>;
|
|
39
39
|
export declare const inlinerMathRegistryItem: import("@jsprose/core").RegistryItem<{
|
|
40
40
|
name: "inlinerMath";
|
|
41
41
|
type: "inliner";
|
|
@@ -51,7 +51,7 @@ export declare const inlinerMathRegistryItem: import("@jsprose/core").RegistryIt
|
|
|
51
51
|
Data: string;
|
|
52
52
|
Storage: InlinerMathStorage;
|
|
53
53
|
Children: undefined;
|
|
54
|
-
}, TagChildren & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet
|
|
54
|
+
}, TagChildren & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet>;
|
|
55
55
|
}, (element: import("@jsprose/core").ProseElement<{
|
|
56
56
|
name: "inlinerMath";
|
|
57
57
|
type: "inliner";
|
|
@@ -21,7 +21,7 @@ export declare const P: import("@jsprose/core").Tag<"P", {
|
|
|
21
21
|
}, {
|
|
22
22
|
center?: true;
|
|
23
23
|
serif?: true;
|
|
24
|
-
} & TagChildren & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet
|
|
24
|
+
} & TagChildren & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet>;
|
|
25
25
|
export declare const paragraphRegistryItem: import("@jsprose/core").RegistryItem<{
|
|
26
26
|
name: "paragraph";
|
|
27
27
|
type: "block";
|
|
@@ -40,7 +40,7 @@ export declare const paragraphRegistryItem: import("@jsprose/core").RegistryItem
|
|
|
40
40
|
}, {
|
|
41
41
|
center?: true;
|
|
42
42
|
serif?: true;
|
|
43
|
-
} & TagChildren & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet
|
|
43
|
+
} & TagChildren & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet>;
|
|
44
44
|
}, undefined>;
|
|
45
45
|
declare const _default: {
|
|
46
46
|
registryItem: import("@jsprose/core").RegistryItem<{
|
|
@@ -61,7 +61,7 @@ declare const _default: {
|
|
|
61
61
|
}, {
|
|
62
62
|
center?: true;
|
|
63
63
|
serif?: true;
|
|
64
|
-
} & TagChildren & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet
|
|
64
|
+
} & TagChildren & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet>;
|
|
65
65
|
}, undefined>;
|
|
66
66
|
};
|
|
67
67
|
export default _default;
|
|
@@ -5,8 +5,8 @@ defineProps<{ active?: boolean }>();
|
|
|
5
5
|
<template>
|
|
6
6
|
<button
|
|
7
7
|
:class="[
|
|
8
|
-
`bg-bg-main border-border/80 text-main-xs min-w-[
|
|
9
|
-
cursor-pointer rounded border px-
|
|
8
|
+
`bg-bg-main border-border/80 text-main-xs micro:px-2.5 min-w-[30px]
|
|
9
|
+
cursor-pointer rounded border px-1.5 py-[5px] font-semibold shadow
|
|
10
10
|
shadow-[light-dark(#d9d9d9,#3c3c3c)]
|
|
11
11
|
transition-[color,background,border,box-shadow]`,
|
|
12
12
|
{
|
|
@@ -30,7 +30,7 @@ watchEffect(() => {
|
|
|
30
30
|
@click="opened = !opened"
|
|
31
31
|
class="group border-border text-text-muted relative flex cursor-pointer
|
|
32
32
|
items-center border-t p-(--proseAsideWidth) font-semibold
|
|
33
|
-
|
|
33
|
+
first:border-t-0"
|
|
34
34
|
>
|
|
35
35
|
<div class="flex-1">{{ formatText(title) }}</div>
|
|
36
36
|
<button
|
|
@@ -49,8 +49,7 @@ watchEffect(() => {
|
|
|
49
49
|
<Suspense>
|
|
50
50
|
<div
|
|
51
51
|
v-if="opened"
|
|
52
|
-
class="border-border border-t border-dashed py-(--proseAsideWidth)
|
|
53
|
-
transition-[border]"
|
|
52
|
+
class="border-border border-t border-dashed py-(--proseAsideWidth)"
|
|
54
53
|
>
|
|
55
54
|
<Render v-for="child of element.children" :element="child" />
|
|
56
55
|
</div>
|
|
@@ -46,10 +46,7 @@ const levelColors: Record<ProblemLevel, string> = {
|
|
|
46
46
|
class="micro:flex-row micro:items-center micro:gap-normal gap-small flex
|
|
47
47
|
flex-col flex-wrap p-(--proseAsideWidth) pb-0"
|
|
48
48
|
>
|
|
49
|
-
<h2
|
|
50
|
-
class="text-text-deep text-main-lg flex-1 font-bold
|
|
51
|
-
transition-[color]"
|
|
52
|
-
>
|
|
49
|
+
<h2 class="text-text-deep text-main-lg flex-1 font-bold">
|
|
53
50
|
{{ formatText(info.title) }}
|
|
54
51
|
</h2>
|
|
55
52
|
<div
|
|
@@ -67,8 +64,7 @@ const levelColors: Record<ProblemLevel, string> = {
|
|
|
67
64
|
class="border-border/60 bg-bg-main text-main-xs text-text-muted
|
|
68
65
|
flex h-(--labelHeight) cursor-help items-center gap-1
|
|
69
66
|
rounded-xl border px-2 shadow
|
|
70
|
-
shadow-[light-dark(#d9d9d9,#3c3c3c)]
|
|
71
|
-
transition-[background,border,color,box-shadow]"
|
|
67
|
+
shadow-[light-dark(#d9d9d9,#3c3c3c)]"
|
|
72
68
|
>
|
|
73
69
|
<EruditIcon
|
|
74
70
|
v-if="typeof attribute === 'string' || attribute.icon"
|
|
@@ -60,9 +60,9 @@ watchEffect(() => {
|
|
|
60
60
|
/>
|
|
61
61
|
</div>
|
|
62
62
|
<div
|
|
63
|
-
class="gap-normal border-border
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
class="gap-small micro:gap-normal border-border micro:*:px-4
|
|
64
|
+
flex flex-wrap border-b px-(--proseAsideWidth)
|
|
65
|
+
py-(--proseAsideWidth)"
|
|
66
66
|
>
|
|
67
67
|
<ProblemButton
|
|
68
68
|
v-for="(subProblem, i) of subProblems"
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { useTemplateRef, ref, watch } from 'vue';
|
|
3
3
|
import type { ProseElement } from '@jsprose/core';
|
|
4
4
|
|
|
5
|
-
import type
|
|
5
|
+
import { checkValue, type problemCheckSchema } from '../../problemContent.js';
|
|
6
6
|
import checkIcon from '../../assets/actions/check.svg?raw';
|
|
7
7
|
import plusIcon from '../../../../app/shared/assets/plus.svg?raw';
|
|
8
8
|
import successIcon from '../../../../app/shared/assets/check.svg?raw';
|
|
@@ -81,8 +81,7 @@ function doCheck() {
|
|
|
81
81
|
return;
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
|
|
85
|
-
state.value = isCorrect ? 'correct' : 'wrong';
|
|
84
|
+
state.value = checkValue(newInput, check.data) ? 'correct' : 'wrong';
|
|
86
85
|
}
|
|
87
86
|
</script>
|
|
88
87
|
|
|
@@ -108,19 +108,55 @@ declare const _default: [{
|
|
|
108
108
|
label?: string;
|
|
109
109
|
hint?: string;
|
|
110
110
|
placeholder?: string;
|
|
111
|
-
} & (({
|
|
112
|
-
answer: string | number;
|
|
111
|
+
} & (((Pick<{
|
|
112
|
+
answer: string | number | RegExp;
|
|
113
|
+
answers: (string | number | RegExp)[];
|
|
114
|
+
set: (string | number | RegExp | (string | number | RegExp)[])[] | {
|
|
115
|
+
separator: string;
|
|
116
|
+
values: (string | number | RegExp | (string | number | RegExp)[])[];
|
|
117
|
+
};
|
|
118
|
+
script: string;
|
|
119
|
+
}, "answer"> & {
|
|
113
120
|
answers?: undefined;
|
|
121
|
+
set?: undefined;
|
|
114
122
|
script?: undefined;
|
|
115
|
-
} | {
|
|
116
|
-
|
|
123
|
+
}) | (Pick<{
|
|
124
|
+
answer: string | number | RegExp;
|
|
125
|
+
answers: (string | number | RegExp)[];
|
|
126
|
+
set: (string | number | RegExp | (string | number | RegExp)[])[] | {
|
|
127
|
+
separator: string;
|
|
128
|
+
values: (string | number | RegExp | (string | number | RegExp)[])[];
|
|
129
|
+
};
|
|
130
|
+
script: string;
|
|
131
|
+
}, "answers"> & {
|
|
117
132
|
answer?: undefined;
|
|
133
|
+
set?: undefined;
|
|
118
134
|
script?: undefined;
|
|
119
|
-
} | {
|
|
135
|
+
}) | (Pick<{
|
|
136
|
+
answer: string | number | RegExp;
|
|
137
|
+
answers: (string | number | RegExp)[];
|
|
138
|
+
set: (string | number | RegExp | (string | number | RegExp)[])[] | {
|
|
139
|
+
separator: string;
|
|
140
|
+
values: (string | number | RegExp | (string | number | RegExp)[])[];
|
|
141
|
+
};
|
|
120
142
|
script: string;
|
|
143
|
+
}, "set"> & {
|
|
144
|
+
answer?: undefined;
|
|
121
145
|
answers?: undefined;
|
|
146
|
+
script?: undefined;
|
|
147
|
+
}) | (Pick<{
|
|
148
|
+
answer: string | number | RegExp;
|
|
149
|
+
answers: (string | number | RegExp)[];
|
|
150
|
+
set: (string | number | RegExp | (string | number | RegExp)[])[] | {
|
|
151
|
+
separator: string;
|
|
152
|
+
values: (string | number | RegExp | (string | number | RegExp)[])[];
|
|
153
|
+
};
|
|
154
|
+
script: string;
|
|
155
|
+
}, "script"> & {
|
|
122
156
|
answer?: undefined;
|
|
123
|
-
|
|
157
|
+
answers?: undefined;
|
|
158
|
+
set?: undefined;
|
|
159
|
+
})) & import("@jsprose/core").NoTagChildren)) & {}>;
|
|
124
160
|
}, undefined>;
|
|
125
161
|
}, {
|
|
126
162
|
registryItem: import("@jsprose/core").RegistryItem<{
|
|
@@ -173,7 +209,7 @@ declare const _default: [{
|
|
|
173
209
|
} | {
|
|
174
210
|
script: import("./problemScript.js").ProblemScriptInstance;
|
|
175
211
|
children?: undefined;
|
|
176
|
-
})) & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet
|
|
212
|
+
})) & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet>;
|
|
177
213
|
}, undefined>;
|
|
178
214
|
}, {
|
|
179
215
|
registryItem: import("@jsprose/core").RegistryItem<{
|
|
@@ -242,7 +278,7 @@ declare const _default: [{
|
|
|
242
278
|
applied?: true | undefined;
|
|
243
279
|
method?: true | undefined;
|
|
244
280
|
inter?: true | undefined;
|
|
245
|
-
} & import("@jsprose/core").TagChildren & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet
|
|
281
|
+
} & import("@jsprose/core").TagChildren & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet>;
|
|
246
282
|
}, undefined>;
|
|
247
283
|
}];
|
|
248
284
|
export default _default;
|
|
@@ -37,7 +37,7 @@ export declare const Problem: import("@jsprose/core").Tag<"Problem", {
|
|
|
37
37
|
} | {
|
|
38
38
|
script: ProblemScriptInstance;
|
|
39
39
|
children?: undefined;
|
|
40
|
-
})) & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet
|
|
40
|
+
})) & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet>;
|
|
41
41
|
export declare const problemRegistryItem: import("@jsprose/core").RegistryItem<{
|
|
42
42
|
name: "problem";
|
|
43
43
|
type: "block";
|
|
@@ -68,7 +68,7 @@ export declare const problemRegistryItem: import("@jsprose/core").RegistryItem<{
|
|
|
68
68
|
} | {
|
|
69
69
|
script: ProblemScriptInstance;
|
|
70
70
|
children?: undefined;
|
|
71
|
-
})) & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet
|
|
71
|
+
})) & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet>;
|
|
72
72
|
}, undefined>;
|
|
73
73
|
export declare const problemCoreElement: {
|
|
74
74
|
registryItem: import("@jsprose/core").RegistryItem<{
|
|
@@ -101,6 +101,6 @@ export declare const problemCoreElement: {
|
|
|
101
101
|
} | {
|
|
102
102
|
script: ProblemScriptInstance;
|
|
103
103
|
children?: undefined;
|
|
104
|
-
})) & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet
|
|
104
|
+
})) & import("../../toc.js").ObjPropToc & import("../../snippet.js").ObjPropSnippet>;
|
|
105
105
|
}, undefined>;
|
|
106
106
|
};
|
|
@@ -14,8 +14,9 @@ export const Problem = defineEruditTag({
|
|
|
14
14
|
tagName: "Problem",
|
|
15
15
|
schema: problemSchema
|
|
16
16
|
})(({ element, tagName, props, children }) => {
|
|
17
|
-
|
|
18
|
-
element.
|
|
17
|
+
const problemInfo = problemProps2Info(props);
|
|
18
|
+
element.data = { info: problemInfo };
|
|
19
|
+
element.title = problemInfo.title;
|
|
19
20
|
if (children && props.script) {
|
|
20
21
|
throw new ProseError(`<${tagName}> cannot have both script and children in Problem element!`);
|
|
21
22
|
}
|
|
@@ -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 = {
|