erudit 2.0.0-dev.8 → 3.0.0-dev.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.
- package/.nuxtrc +1 -1
- package/app/components/SiteMain.vue +2 -2
- package/app/components/aside/major/panes/Search.vue +10 -2
- package/app/components/aside/minor/AsideMinorContributor.vue +1 -1
- package/app/components/aside/minor/AsideMinorPane.vue +2 -3
- package/app/components/aside/minor/topic/TopicToc.vue +2 -1
- package/app/components/aside/minor/topic/TopicTocItem.vue +3 -3
- package/app/components/bitran/BitranContent.vue +20 -21
- package/app/components/bitran/RenderWrapper.vue +2 -4
- package/app/components/main/topic/MainTopic.vue +1 -1
- package/app/components/main/utils/ContentDescription.vue +3 -4
- package/app/components/main/utils/ContentFlag.vue +3 -4
- package/app/components/main/utils/ContentReferences.vue +16 -22
- package/app/components/main/utils/ContentSection.vue +21 -18
- package/app/components/main/utils/ContentTitle.vue +12 -10
- package/app/components/main/utils/reference/ReferenceGroup.vue +5 -8
- package/app/components/main/utils/reference/ReferenceItem.vue +25 -21
- package/app/components/main/utils/reference/ReferenceSource.vue +42 -36
- package/app/components/preview/PreviewLoading.vue +2 -3
- package/app/components/preview/display/Unique.vue +2 -2
- package/app/components/transition/Fade.vue +4 -7
- package/app/components/tree/TreeContainer.vue +2 -3
- package/app/composables/bitran.ts +127 -132
- package/app/composables/bitranContent.ts +37 -36
- package/app/composables/bitranLocation.ts +7 -7
- package/app/composables/contentData.ts +36 -36
- package/app/composables/contentPage.ts +156 -156
- package/app/composables/contentRoute.ts +45 -45
- package/app/composables/darkMagic.ts +24 -24
- package/app/composables/externalApi.ts +63 -63
- package/app/composables/favicon.ts +8 -8
- package/app/composables/formatText.ts +86 -86
- package/app/composables/majorPane.ts +60 -60
- package/app/composables/theme.ts +29 -29
- package/app/composables/url.ts +33 -33
- package/app/pages/article/[...articleId].vue +1 -1
- package/app/pages/group/[...groupId].vue +2 -1
- package/app/pages/members.vue +2 -3
- package/app/pages/practice/[...practice].vue +1 -1
- package/app/pages/summary/[...summaryId].vue +1 -1
- package/app/public/favicon/article.svg +9 -9
- package/app/public/favicon/default.svg +9 -9
- package/app/public/favicon/practice.svg +9 -9
- package/app/public/favicon/summary.svg +9 -9
- package/app/public/logotype.svg +16 -16
- package/app/public/user.svg +9 -9
- package/app/scripts/_immediate.js +7 -2
- package/app/scripts/aside/index.ts +59 -59
- package/app/scripts/aside/major/nav.ts +26 -26
- package/app/scripts/aside/minor/state.ts +37 -37
- package/app/scripts/aside/minor/topic.ts +3 -3
- package/app/scripts/preview/build.ts +73 -84
- package/app/scripts/preview/data/alert.ts +19 -19
- package/app/scripts/preview/data/custom.ts +8 -8
- package/app/scripts/preview/data/genericLink.ts +24 -24
- package/app/scripts/preview/data/pageLink.ts +20 -20
- package/app/scripts/preview/data/unique.ts +70 -70
- package/app/scripts/preview/data.ts +24 -26
- package/app/scripts/preview/display.ts +37 -39
- package/app/scripts/preview/footer.ts +9 -9
- package/app/scripts/preview/request.ts +51 -51
- package/app/scripts/preview/state.ts +63 -63
- package/app/styles/_immediate.css +6 -2
- package/app/styles/_util.scss +13 -20
- package/app/styles/app.scss +91 -91
- package/app/styles/def/_bp.scss +27 -24
- package/app/styles/def/_size.scss +7 -7
- package/app/styles/def/_z.scss +5 -5
- package/app/styles/default.scss +33 -35
- package/app/styles/normalize.scss +63 -63
- package/app/styles/partials/_darkMagic.scss +3 -5
- package/app/styles/partials/_fnav.scss +4 -7
- package/app/styles/partials/_preview.scss +3 -5
- package/globals/bitran.ts +47 -39
- package/globals/content.ts +22 -22
- package/globals/contributor.ts +5 -5
- package/module/bitran.ts +34 -34
- package/module/index.ts +12 -0
- package/module/paths.ts +22 -22
- package/nuxt.config.ts +20 -5
- package/package.json +9 -6
- package/server/api/contributor/count.ts +6 -6
- package/server/api/fake/content.ts +6 -6
- package/server/api/preview/page/[...parts].ts +1 -1
- package/server/plugin/bitran/content.ts +187 -176
- package/server/plugin/bitran/location.ts +25 -25
- package/server/plugin/bitran/products/include.ts +230 -229
- package/server/plugin/bitran/products/link.ts +116 -114
- package/server/plugin/bitran/setup.ts +9 -10
- package/server/plugin/bitran/toc.ts +83 -82
- package/server/plugin/bitran/transpiler.ts +46 -0
- package/server/plugin/build/jobs/content/builderArgs.ts +8 -8
- package/server/plugin/build/jobs/content/generic.ts +176 -176
- package/server/plugin/build/jobs/content/parse.ts +100 -90
- package/server/plugin/build/jobs/content/path.ts +6 -6
- package/server/plugin/build/jobs/content/type/book.ts +9 -9
- package/server/plugin/build/jobs/content/type/group.ts +37 -37
- package/server/plugin/build/jobs/content/type/topic.ts +36 -36
- package/server/plugin/build/jobs/contributors.ts +66 -66
- package/server/plugin/build/jobs/nav.ts +209 -209
- package/server/plugin/content/absoluteId.ts +94 -94
- package/server/plugin/content/context.ts +112 -112
- package/server/plugin/db/entities/Book.ts +7 -7
- package/server/plugin/db/entities/Content.ts +49 -49
- package/server/plugin/db/entities/Contribution.ts +10 -10
- package/server/plugin/db/entities/Contributor.ts +16 -16
- package/server/plugin/db/entities/Group.ts +14 -14
- package/server/plugin/db/entities/Hash.ts +15 -15
- package/server/plugin/db/entities/Topic.ts +20 -20
- package/server/plugin/db/entities/Unique.ts +21 -21
- package/server/plugin/db/setup.ts +34 -34
- package/server/plugin/nav/node.ts +26 -26
- package/server/plugin/nav/utils.ts +129 -129
- package/server/plugin/repository/book.ts +21 -21
- package/server/plugin/repository/content.ts +238 -238
- package/server/plugin/repository/contributor.ts +8 -8
- package/server/plugin/repository/frontNav.ts +148 -148
- package/server/plugin/repository/topic.ts +32 -32
- package/shared/aside/minor.ts +50 -50
- package/shared/asset.ts +15 -15
- package/shared/bitran/context.ts +8 -7
- package/shared/bitran/default.ts +46 -0
- package/shared/bitran/{products/link/render → link}/Link.vue +167 -174
- package/shared/bitran/link/factory.ts +24 -0
- package/shared/bitran/link/languages/en.ts +7 -0
- package/shared/bitran/link/languages/ru.ts +7 -0
- package/shared/bitran/link/renderer.ts +21 -0
- package/shared/bitran/link/shared.ts +17 -0
- package/shared/bitran/{products/link → link}/target.ts +134 -134
- package/shared/bitran/link/transpiler.ts +10 -0
- package/shared/bitran/location.ts +166 -166
- package/shared/bitran/toc.ts +8 -8
- package/shared/contributor.ts +5 -5
- package/shared/frontNav.ts +41 -41
- package/shared/icons.ts +38 -38
- package/shared/image.ts +5 -5
- package/shared/utils/objectsEqual.ts +4 -4
- package/shared/utils/stringColor.ts +9 -9
- package/test/bitran/{products/link → link}/target.test.ts +141 -138
- package/test/bitran/location.test.ts +143 -143
- package/server/plugin/bitran/core.ts +0 -51
- package/shared/bitran/alias.ts +0 -17
- package/shared/bitran/products/alias/core/factory.ts +0 -46
- package/shared/bitran/products/alias/core/index.ts +0 -13
- package/shared/bitran/products/alias/render/Alias.vue +0 -10
- package/shared/bitran/products/alias/render/icon.svg +0 -3
- package/shared/bitran/products/alias/render/index.ts +0 -17
- package/shared/bitran/products/alias/render/languages/en.ts +0 -5
- package/shared/bitran/products/alias/render/languages/ru.ts +0 -5
- package/shared/bitran/products/alias/shared.ts +0 -11
- package/shared/bitran/products/heading/core/factory.ts +0 -53
- package/shared/bitran/products/heading/core/index.ts +0 -19
- package/shared/bitran/products/heading/render/Heading.vue +0 -47
- package/shared/bitran/products/heading/render/icon.svg +0 -3
- package/shared/bitran/products/heading/render/index.ts +0 -17
- package/shared/bitran/products/heading/render/languages/en.ts +0 -5
- package/shared/bitran/products/heading/render/languages/ru.ts +0 -5
- package/shared/bitran/products/heading/shared.ts +0 -13
- package/shared/bitran/products/include/core/factory.ts +0 -61
- package/shared/bitran/products/include/core/index.ts +0 -13
- package/shared/bitran/products/include/render/Include.vue +0 -13
- package/shared/bitran/products/include/render/icon.svg +0 -3
- package/shared/bitran/products/include/render/index.ts +0 -18
- package/shared/bitran/products/include/render/languages/en.ts +0 -5
- package/shared/bitran/products/include/render/languages/ru.ts +0 -5
- package/shared/bitran/products/include/shared.ts +0 -15
- package/shared/bitran/products/link/core/factory.ts +0 -20
- package/shared/bitran/products/link/core/index.ts +0 -17
- package/shared/bitran/products/link/render/index.ts +0 -17
- package/shared/bitran/products/link/render/languages/en.ts +0 -5
- package/shared/bitran/products/link/render/languages/ru.ts +0 -5
- package/shared/bitran/products/link/shared.ts +0 -15
- package/test/bitran/alias.test.ts +0 -44
- package/test/bitran/products/alias.test.ts +0 -83
- package/test/bitran/products/heading.test.ts +0 -119
- package/test/bitran/products/include.test.ts +0 -77
- package/test/bitran/products/link/factory.test.ts +0 -30
- /package/shared/bitran/{products/link/render → link}/icon.svg +0 -0
|
@@ -1,143 +1,143 @@
|
|
|
1
|
-
import {
|
|
2
|
-
decodeBitranLocation,
|
|
3
|
-
encodeBitranLocation,
|
|
4
|
-
parseBitranLocation,
|
|
5
|
-
parsePartialBitranLocation,
|
|
6
|
-
stringifyBitranLocation,
|
|
7
|
-
type BitranLocation,
|
|
8
|
-
} from '@erudit/shared/bitran/location';
|
|
9
|
-
|
|
10
|
-
const locations: [BitranLocation, string][] = [
|
|
11
|
-
// Full locations
|
|
12
|
-
[{ type: 'article', path: 'foo', unique: 'bar' }, 'article|foo|bar'],
|
|
13
|
-
[{ type: 'group', path: 'foo', unique: 'bar' }, 'group|foo|bar'],
|
|
14
|
-
// Type + path
|
|
15
|
-
[{ type: 'article', path: 'foo' }, 'article|foo'],
|
|
16
|
-
[{ type: 'group', path: 'foo' }, 'group|foo'],
|
|
17
|
-
];
|
|
18
|
-
|
|
19
|
-
const partialLocations: [string, BitranLocation, BitranLocation][] = [
|
|
20
|
-
// Full string location
|
|
21
|
-
[
|
|
22
|
-
'article|foo/bar|baz',
|
|
23
|
-
{ type: 'group', path: 'qux' },
|
|
24
|
-
{ type: 'article', path: 'foo/bar', unique: 'baz' },
|
|
25
|
-
],
|
|
26
|
-
// Only unique
|
|
27
|
-
[
|
|
28
|
-
'baz',
|
|
29
|
-
{ type: 'summary', path: 'foo/bar' },
|
|
30
|
-
{ type: 'summary', path: 'foo/bar', unique: 'baz' },
|
|
31
|
-
],
|
|
32
|
-
[
|
|
33
|
-
'baz',
|
|
34
|
-
{ type: 'contributor', path: 'John' },
|
|
35
|
-
{ type: 'contributor', path: 'John', unique: 'baz' },
|
|
36
|
-
],
|
|
37
|
-
// Topic context
|
|
38
|
-
[
|
|
39
|
-
'article|baz',
|
|
40
|
-
{ type: 'practice', path: 'foo/bar' },
|
|
41
|
-
{ type: 'article', path: 'foo/bar', unique: 'baz' },
|
|
42
|
-
],
|
|
43
|
-
];
|
|
44
|
-
|
|
45
|
-
const invalidPartialLocations: [string, BitranLocation][] = [
|
|
46
|
-
// Referencing topic part in non-topic context
|
|
47
|
-
['article|bar', { type: 'contributor', path: 'foo' }],
|
|
48
|
-
];
|
|
49
|
-
|
|
50
|
-
const invalidLocations = [
|
|
51
|
-
// Too few parts
|
|
52
|
-
{ type: 'article' },
|
|
53
|
-
{ path: 'foo' },
|
|
54
|
-
{ unique: 'foo' },
|
|
55
|
-
// Unknown type
|
|
56
|
-
{ type: 'foo' },
|
|
57
|
-
{ type: 'foo', path: 'bar', unique: 'baz' },
|
|
58
|
-
// Locations that require path
|
|
59
|
-
{ type: 'article', unique: 'foo' },
|
|
60
|
-
{ type: 'summary', unique: 'foo' },
|
|
61
|
-
{ type: 'practice', unique: 'foo' },
|
|
62
|
-
{ type: 'group', unique: 'foo' },
|
|
63
|
-
{ type: 'contributor', unique: 'foo' },
|
|
64
|
-
];
|
|
65
|
-
|
|
66
|
-
const invalidStrLocations = [
|
|
67
|
-
// Too few parts
|
|
68
|
-
'article',
|
|
69
|
-
'group',
|
|
70
|
-
// Unknown type
|
|
71
|
-
'foo',
|
|
72
|
-
'foo|bar',
|
|
73
|
-
'foo|bar|baz',
|
|
74
|
-
// Empty string unique
|
|
75
|
-
'article|foo/bar|',
|
|
76
|
-
];
|
|
77
|
-
|
|
78
|
-
//
|
|
79
|
-
//
|
|
80
|
-
//
|
|
81
|
-
|
|
82
|
-
describe('stringifyBitranLocation', () => {
|
|
83
|
-
for (const [location, expected] of locations) {
|
|
84
|
-
it(`should produce "${expected}"`, () => {
|
|
85
|
-
expect(stringifyBitranLocation(location)).toBe(expected);
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
for (const invalidLocation of invalidLocations) {
|
|
90
|
-
it(`should throw on location ${JSON.stringify(invalidLocation)}`, () => {
|
|
91
|
-
expect(() =>
|
|
92
|
-
stringifyBitranLocation(invalidLocation as BitranLocation),
|
|
93
|
-
).toThrow();
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
describe('parseBitranLocation', () => {
|
|
99
|
-
for (const [location, expected] of locations) {
|
|
100
|
-
it(`should produce ${JSON.stringify(expected)}`, () => {
|
|
101
|
-
expect(parseBitranLocation(expected)).toEqual(location);
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
for (const invalidStrLocation of invalidStrLocations) {
|
|
106
|
-
it(`should throw on location "${invalidStrLocation}"`, () => {
|
|
107
|
-
expect(() => parseBitranLocation(invalidStrLocation)).toThrow();
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
describe('parsePartialBitranLocation', () => {
|
|
113
|
-
for (const [locationStr, context, expected] of partialLocations) {
|
|
114
|
-
it(`should produce ${JSON.stringify(expected)}`, () => {
|
|
115
|
-
expect(parsePartialBitranLocation(locationStr, context)).toEqual(
|
|
116
|
-
expected,
|
|
117
|
-
);
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
for (const [locationStr, context] of invalidPartialLocations) {
|
|
122
|
-
it(`should throw on location "${locationStr}"`, () => {
|
|
123
|
-
expect(() =>
|
|
124
|
-
parsePartialBitranLocation(locationStr, context),
|
|
125
|
-
).toThrow();
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
describe('decode/encodeBitranLocation', () => {
|
|
131
|
-
it.each([
|
|
132
|
-
'',
|
|
133
|
-
'foo',
|
|
134
|
-
'foo|bar',
|
|
135
|
-
'foo|bar|baz',
|
|
136
|
-
'foo|bar/baz|qux',
|
|
137
|
-
'foo|bar/baz/qux|corge:grault:waldo',
|
|
138
|
-
])('should not change string location %p', (testCase) =>
|
|
139
|
-
expect(decodeBitranLocation(encodeBitranLocation(testCase))).toBe(
|
|
140
|
-
testCase,
|
|
141
|
-
),
|
|
142
|
-
);
|
|
143
|
-
});
|
|
1
|
+
import {
|
|
2
|
+
decodeBitranLocation,
|
|
3
|
+
encodeBitranLocation,
|
|
4
|
+
parseBitranLocation,
|
|
5
|
+
parsePartialBitranLocation,
|
|
6
|
+
stringifyBitranLocation,
|
|
7
|
+
type BitranLocation,
|
|
8
|
+
} from '@erudit/shared/bitran/location';
|
|
9
|
+
|
|
10
|
+
const locations: [BitranLocation, string][] = [
|
|
11
|
+
// Full locations
|
|
12
|
+
[{ type: 'article', path: 'foo', unique: 'bar' }, 'article|foo|bar'],
|
|
13
|
+
[{ type: 'group', path: 'foo', unique: 'bar' }, 'group|foo|bar'],
|
|
14
|
+
// Type + path
|
|
15
|
+
[{ type: 'article', path: 'foo' }, 'article|foo'],
|
|
16
|
+
[{ type: 'group', path: 'foo' }, 'group|foo'],
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
const partialLocations: [string, BitranLocation, BitranLocation][] = [
|
|
20
|
+
// Full string location
|
|
21
|
+
[
|
|
22
|
+
'article|foo/bar|baz',
|
|
23
|
+
{ type: 'group', path: 'qux' },
|
|
24
|
+
{ type: 'article', path: 'foo/bar', unique: 'baz' },
|
|
25
|
+
],
|
|
26
|
+
// Only unique
|
|
27
|
+
[
|
|
28
|
+
'baz',
|
|
29
|
+
{ type: 'summary', path: 'foo/bar' },
|
|
30
|
+
{ type: 'summary', path: 'foo/bar', unique: 'baz' },
|
|
31
|
+
],
|
|
32
|
+
[
|
|
33
|
+
'baz',
|
|
34
|
+
{ type: 'contributor', path: 'John' },
|
|
35
|
+
{ type: 'contributor', path: 'John', unique: 'baz' },
|
|
36
|
+
],
|
|
37
|
+
// Topic context
|
|
38
|
+
[
|
|
39
|
+
'article|baz',
|
|
40
|
+
{ type: 'practice', path: 'foo/bar' },
|
|
41
|
+
{ type: 'article', path: 'foo/bar', unique: 'baz' },
|
|
42
|
+
],
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
const invalidPartialLocations: [string, BitranLocation][] = [
|
|
46
|
+
// Referencing topic part in non-topic context
|
|
47
|
+
['article|bar', { type: 'contributor', path: 'foo' }],
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
const invalidLocations = [
|
|
51
|
+
// Too few parts
|
|
52
|
+
{ type: 'article' },
|
|
53
|
+
{ path: 'foo' },
|
|
54
|
+
{ unique: 'foo' },
|
|
55
|
+
// Unknown type
|
|
56
|
+
{ type: 'foo' },
|
|
57
|
+
{ type: 'foo', path: 'bar', unique: 'baz' },
|
|
58
|
+
// Locations that require path
|
|
59
|
+
{ type: 'article', unique: 'foo' },
|
|
60
|
+
{ type: 'summary', unique: 'foo' },
|
|
61
|
+
{ type: 'practice', unique: 'foo' },
|
|
62
|
+
{ type: 'group', unique: 'foo' },
|
|
63
|
+
{ type: 'contributor', unique: 'foo' },
|
|
64
|
+
];
|
|
65
|
+
|
|
66
|
+
const invalidStrLocations = [
|
|
67
|
+
// Too few parts
|
|
68
|
+
'article',
|
|
69
|
+
'group',
|
|
70
|
+
// Unknown type
|
|
71
|
+
'foo',
|
|
72
|
+
'foo|bar',
|
|
73
|
+
'foo|bar|baz',
|
|
74
|
+
// Empty string unique
|
|
75
|
+
'article|foo/bar|',
|
|
76
|
+
];
|
|
77
|
+
|
|
78
|
+
//
|
|
79
|
+
//
|
|
80
|
+
//
|
|
81
|
+
|
|
82
|
+
describe('stringifyBitranLocation', () => {
|
|
83
|
+
for (const [location, expected] of locations) {
|
|
84
|
+
it(`should produce "${expected}"`, () => {
|
|
85
|
+
expect(stringifyBitranLocation(location)).toBe(expected);
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
for (const invalidLocation of invalidLocations) {
|
|
90
|
+
it(`should throw on location ${JSON.stringify(invalidLocation)}`, () => {
|
|
91
|
+
expect(() =>
|
|
92
|
+
stringifyBitranLocation(invalidLocation as BitranLocation),
|
|
93
|
+
).toThrow();
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
describe('parseBitranLocation', () => {
|
|
99
|
+
for (const [location, expected] of locations) {
|
|
100
|
+
it(`should produce ${JSON.stringify(expected)}`, () => {
|
|
101
|
+
expect(parseBitranLocation(expected)).toEqual(location);
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
for (const invalidStrLocation of invalidStrLocations) {
|
|
106
|
+
it(`should throw on location "${invalidStrLocation}"`, () => {
|
|
107
|
+
expect(() => parseBitranLocation(invalidStrLocation)).toThrow();
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
describe('parsePartialBitranLocation', () => {
|
|
113
|
+
for (const [locationStr, context, expected] of partialLocations) {
|
|
114
|
+
it(`should produce ${JSON.stringify(expected)}`, () => {
|
|
115
|
+
expect(parsePartialBitranLocation(locationStr, context)).toEqual(
|
|
116
|
+
expected,
|
|
117
|
+
);
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
for (const [locationStr, context] of invalidPartialLocations) {
|
|
122
|
+
it(`should throw on location "${locationStr}"`, () => {
|
|
123
|
+
expect(() =>
|
|
124
|
+
parsePartialBitranLocation(locationStr, context),
|
|
125
|
+
).toThrow();
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
describe('decode/encodeBitranLocation', () => {
|
|
131
|
+
it.each([
|
|
132
|
+
'',
|
|
133
|
+
'foo',
|
|
134
|
+
'foo|bar',
|
|
135
|
+
'foo|bar|baz',
|
|
136
|
+
'foo|bar/baz|qux',
|
|
137
|
+
'foo|bar/baz/qux|corge:grault:waldo',
|
|
138
|
+
])('should not change string location %p', (testCase) =>
|
|
139
|
+
expect(decodeBitranLocation(encodeBitranLocation(testCase))).toBe(
|
|
140
|
+
testCase,
|
|
141
|
+
),
|
|
142
|
+
);
|
|
143
|
+
});
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createBitranCore as _createBitranCore,
|
|
3
|
-
type GenericProductCore,
|
|
4
|
-
} from 'bitran/core';
|
|
5
|
-
|
|
6
|
-
import { ERUDIT_SERVER } from '@server/global';
|
|
7
|
-
import type { BitranContext } from '@erudit/shared/bitran/context';
|
|
8
|
-
|
|
9
|
-
// Erudit Products
|
|
10
|
-
import { headingName } from '@erudit/shared/bitran/products/heading/shared';
|
|
11
|
-
import { heading } from '@erudit/shared/bitran/products/heading/core';
|
|
12
|
-
import { aliasName } from '@erudit/shared/bitran/products/alias/shared';
|
|
13
|
-
import { defineAlias } from '@erudit/shared/bitran/products/alias/core';
|
|
14
|
-
import { includeName } from '@erudit/shared/bitran/products/include/shared';
|
|
15
|
-
import { include } from '@erudit/shared/bitran/products/include/core';
|
|
16
|
-
import { linkName } from '@erudit/shared/bitran/products/link/shared';
|
|
17
|
-
import { link } from '@erudit/shared/bitran/products/link/core';
|
|
18
|
-
|
|
19
|
-
type Products = Record<string, GenericProductCore>;
|
|
20
|
-
|
|
21
|
-
export async function createBitranCore(context: BitranContext) {
|
|
22
|
-
const projectProducts = await getProjectProducts();
|
|
23
|
-
|
|
24
|
-
const eruditProducts: Products = {
|
|
25
|
-
[aliasName]: defineAlias(context), // Exec aliases logic on server and pass resolved aliases as RenderData -> no actions on client at all
|
|
26
|
-
[includeName]: include,
|
|
27
|
-
[headingName]: heading,
|
|
28
|
-
[linkName]: link,
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
const bitranCore = _createBitranCore({
|
|
32
|
-
products: {
|
|
33
|
-
...projectProducts,
|
|
34
|
-
...eruditProducts,
|
|
35
|
-
},
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
return bitranCore;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
async function getProjectProducts(): Promise<Products> {
|
|
42
|
-
const productDefinitions = ERUDIT_SERVER?.BITRAN_CONFIG?.products;
|
|
43
|
-
|
|
44
|
-
if (!productDefinitions) return {};
|
|
45
|
-
|
|
46
|
-
const projectProducts: Products = {};
|
|
47
|
-
for (const [name, definition] of Object.entries(productDefinitions))
|
|
48
|
-
projectProducts[name] = await definition.core();
|
|
49
|
-
|
|
50
|
-
return projectProducts;
|
|
51
|
-
}
|
package/shared/bitran/alias.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export type BitranAliases = Record<string, string>;
|
|
2
|
-
|
|
3
|
-
export const NO_ALIASES: () => BitranAliases = () => ({});
|
|
4
|
-
|
|
5
|
-
export function tryReplaceAlias(
|
|
6
|
-
target: string,
|
|
7
|
-
aliases: BitranAliases,
|
|
8
|
-
): string {
|
|
9
|
-
if (!target.match(/^~\w+$/)) return target;
|
|
10
|
-
|
|
11
|
-
const alias = target.substring(1);
|
|
12
|
-
const replacement = aliases[alias];
|
|
13
|
-
|
|
14
|
-
if (!replacement) throw new Error(`Unknown alias "~${alias}"!`);
|
|
15
|
-
|
|
16
|
-
return replacement;
|
|
17
|
-
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { BlockParseFactory, ProductStrFactory } from 'bitran/process';
|
|
2
|
-
|
|
3
|
-
import type { BitranAliases } from '@erudit/shared/bitran/alias';
|
|
4
|
-
import type { AliasType } from '../shared';
|
|
5
|
-
|
|
6
|
-
export class AliasParser extends BlockParseFactory<AliasType> {
|
|
7
|
-
regexp = /^~ (?<alias>\S+) (?<target>\S+)$/;
|
|
8
|
-
aliases: BitranAliases = {};
|
|
9
|
-
|
|
10
|
-
canParse(strBlock: string) {
|
|
11
|
-
const lines = strBlock.split('\n');
|
|
12
|
-
|
|
13
|
-
for (const line of lines) {
|
|
14
|
-
const match = line.match(this.regexp);
|
|
15
|
-
if (!match) return false;
|
|
16
|
-
this.aliases[match[1]!.trim()] = match[2]!.trim();
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
return true;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
async createParseData(): Promise<Record<string, string>> {
|
|
23
|
-
const { provide: context } = this.getPayload();
|
|
24
|
-
|
|
25
|
-
for (const [alias, target] of Object.entries(this.aliases)) {
|
|
26
|
-
if (alias in context.aliases)
|
|
27
|
-
throw new Error(
|
|
28
|
-
`Duplicate alias "${alias}" within Bitran context!\n` +
|
|
29
|
-
`Current alias target: "${target}".\n` +
|
|
30
|
-
`Context alias target: "${context.aliases[alias]}".`,
|
|
31
|
-
);
|
|
32
|
-
|
|
33
|
-
context.aliases[alias] = target;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return this.aliases;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export class AliasStr extends ProductStrFactory<AliasType> {
|
|
41
|
-
stringifyData(data: Record<string, string>): string {
|
|
42
|
-
return Object.entries(data)
|
|
43
|
-
.map(([alias, location]) => `~ ${alias} ${location}`)
|
|
44
|
-
.join('\n');
|
|
45
|
-
}
|
|
46
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { BlockNode } from 'bitran/dom';
|
|
2
|
-
import { defineProductCoreFn } from 'bitran/core';
|
|
3
|
-
|
|
4
|
-
import type { AliasType } from '../shared';
|
|
5
|
-
import { AliasParser, AliasStr } from './factory';
|
|
6
|
-
|
|
7
|
-
export class AliasNode extends BlockNode<AliasType> {}
|
|
8
|
-
|
|
9
|
-
export const defineAlias = defineProductCoreFn<AliasType>({
|
|
10
|
-
Node: AliasNode,
|
|
11
|
-
Parser: AliasParser,
|
|
12
|
-
Stringifier: AliasStr,
|
|
13
|
-
});
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 24 24">
|
|
2
|
-
<path d="M4.5,23.8c-.9,0-1.7-.3-2.3-.9-.6-.6-.9-1.4-.9-2.3s.3-1.7.9-2.3c.6-.6,1.4-.9,2.3-.9s1,.1,1.4.3c.4.2.8.5,1.1.9,1.1-.6,1.9-1.3,2.6-2.3s1.1-2,1.2-3.2h-3.3c-.2.6-.6,1.2-1.2,1.6-.6.4-1.2.6-1.9.6s-1.7-.3-2.3-.9c-.6-.6-.9-1.4-.9-2.3s.3-1.7.9-2.3c.6-.6,1.4-.9,2.3-.9s1.3.2,1.9.6c.6.4.9.9,1.2,1.6h3.3c-.2-1.2-.6-2.3-1.2-3.2s-1.5-1.7-2.6-2.3c-.3.4-.7.7-1.1.9-.4.2-.9.3-1.4.3-.9,0-1.7-.3-2.3-.9-.6-.6-.9-1.4-.9-2.3s.3-1.7.9-2.3C2.8.5,3.6.2,4.5.2s1.7.3,2.3.9.9,1.4,1,2.3c1.5.8,2.7,1.8,3.6,3.1s1.5,2.8,1.7,4.5h5.7l-1.7-1.7,1.5-1.5,4.3,4.3-4.3,4.3-1.5-1.5,1.7-1.7h-5.7c-.2,1.7-.8,3.1-1.7,4.5-.9,1.3-2.1,2.4-3.6,3.1,0,.9-.4,1.7-1,2.3-.6.6-1.4.9-2.3.9Z"/>
|
|
3
|
-
</svg>
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
defineIcon,
|
|
3
|
-
defineLanguages,
|
|
4
|
-
defineProductComponent,
|
|
5
|
-
defineProductRender,
|
|
6
|
-
RenderMode,
|
|
7
|
-
} from 'bitran/render';
|
|
8
|
-
|
|
9
|
-
export const alias = defineProductRender({
|
|
10
|
-
mode: RenderMode.Server,
|
|
11
|
-
component: defineProductComponent(() => import('./Alias.vue')),
|
|
12
|
-
icon: defineIcon(() => import('./icon.svg?raw')),
|
|
13
|
-
languages: defineLanguages({
|
|
14
|
-
en: () => import('./languages/en'),
|
|
15
|
-
ru: () => import('./languages/ru'),
|
|
16
|
-
}),
|
|
17
|
-
});
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { DefineProductType } from 'bitran';
|
|
2
|
-
|
|
3
|
-
import type { BitranAliases } from '@shared/bitran/alias';
|
|
4
|
-
import type { BitranContext } from '@shared/bitran/context';
|
|
5
|
-
|
|
6
|
-
export type AliasType = DefineProductType<{
|
|
7
|
-
ParseData: BitranAliases;
|
|
8
|
-
Provide: BitranContext;
|
|
9
|
-
}>;
|
|
10
|
-
|
|
11
|
-
export const aliasName = '__alias';
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import slugify from 'slugify';
|
|
2
|
-
import { BlockParseFactory, ProductStrFactory } from 'bitran/process';
|
|
3
|
-
|
|
4
|
-
import eruditConfig from '#erudit/config';
|
|
5
|
-
import type { HeadingParseData, HeadingType } from '../shared';
|
|
6
|
-
|
|
7
|
-
const validLevels = [1, 2, 3];
|
|
8
|
-
|
|
9
|
-
export class HeadingParser extends BlockParseFactory<HeadingType> {
|
|
10
|
-
regexp = /^(?<level>#+) (?<title>.+)$/;
|
|
11
|
-
match?: RegExpMatchArray | null;
|
|
12
|
-
|
|
13
|
-
canParse(strBlock: string) {
|
|
14
|
-
this.match = strBlock.match(this.regexp);
|
|
15
|
-
return !!this.match;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
async createParseData() {
|
|
19
|
-
const [, matchLevel, matchTitle] = this.match!;
|
|
20
|
-
const level = matchLevel!.length;
|
|
21
|
-
const title = matchTitle!.trim();
|
|
22
|
-
|
|
23
|
-
if (!validLevels.includes(level))
|
|
24
|
-
throw new Error(
|
|
25
|
-
`Invalid heading level: ${level}. Available levels: ${validLevels.join(', ')}.`,
|
|
26
|
-
);
|
|
27
|
-
|
|
28
|
-
if (!title) throw new Error(`Empty heading!`);
|
|
29
|
-
|
|
30
|
-
return {
|
|
31
|
-
level: level - 1,
|
|
32
|
-
title,
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
override alterAutoId(autoId: string) {
|
|
37
|
-
const { parseData, provide } = this.getPayload();
|
|
38
|
-
|
|
39
|
-
// TODO: If Chinese-like locale is set just return auto-id or original title?
|
|
40
|
-
let titleSlug = slugify(parseData.title, {
|
|
41
|
-
lower: true,
|
|
42
|
-
strict: true,
|
|
43
|
-
locale: provide?.languageCode || eruditConfig.language,
|
|
44
|
-
});
|
|
45
|
-
return titleSlug || autoId;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export class HeadingStr extends ProductStrFactory<HeadingType> {
|
|
50
|
-
stringifyData({ title, level }: HeadingParseData) {
|
|
51
|
-
return `${'#'.repeat(level + 1)} ${title}`;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { defineProductCore, defineProductCoreFn } from 'bitran/core';
|
|
2
|
-
import { BlockNode } from 'bitran/dom';
|
|
3
|
-
|
|
4
|
-
import type { HeadingType } from '../shared';
|
|
5
|
-
import { HeadingParser, HeadingStr } from './factory';
|
|
6
|
-
|
|
7
|
-
export class HeadingNode extends BlockNode<HeadingType> {}
|
|
8
|
-
|
|
9
|
-
export const heading = defineProductCore<HeadingType>({
|
|
10
|
-
Node: HeadingNode,
|
|
11
|
-
Parser: HeadingParser,
|
|
12
|
-
Stringifier: HeadingStr,
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
export const defineLocaleHeading = defineProductCoreFn<HeadingType>({
|
|
16
|
-
Node: HeadingNode,
|
|
17
|
-
Parser: HeadingParser,
|
|
18
|
-
Stringifier: HeadingStr,
|
|
19
|
-
});
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
<script lang="ts" setup>
|
|
2
|
-
import { useParseData, usePrettyText, type ProductProps } from 'bitran/render';
|
|
3
|
-
import { type HeadingType } from '../shared';
|
|
4
|
-
|
|
5
|
-
const { node } = defineProps<ProductProps<HeadingType>>();
|
|
6
|
-
const { level, title } = useParseData(node);
|
|
7
|
-
const pretty = usePrettyText();
|
|
8
|
-
</script>
|
|
9
|
-
|
|
10
|
-
<template>
|
|
11
|
-
<component :is="`h${level + 2}`" :class="$style.h">
|
|
12
|
-
{{ pretty(title) }}
|
|
13
|
-
</component>
|
|
14
|
-
</template>
|
|
15
|
-
|
|
16
|
-
<style lang="scss" module>
|
|
17
|
-
h2, h3, h4
|
|
18
|
-
{
|
|
19
|
-
&.h
|
|
20
|
-
{
|
|
21
|
-
font-weight: 700;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
h2.h
|
|
26
|
-
{
|
|
27
|
-
font-size: 1.55em;
|
|
28
|
-
border-bottom: 1px solid light-dark(#dedede, #323232);
|
|
29
|
-
padding-bottom: 10px;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
h3.h
|
|
33
|
-
{
|
|
34
|
-
font-size: 1.2em;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
h4.h
|
|
38
|
-
{
|
|
39
|
-
font-size: 1.05em;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// Dirty hack to add extra space before the heading
|
|
43
|
-
:global(.bitran-blockContainer:not(:first-of-type)):has(:global(> .bitran-block > .bitran-blockMain) > .h)
|
|
44
|
-
{
|
|
45
|
-
margin-top: calc(var(--bitran_blocksGap) * 1.25);
|
|
46
|
-
}
|
|
47
|
-
</style>
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
|
|
2
|
-
<path d="M181.3 32.4c17.4 2.9 29.2 19.4 26.3 36.8L197.8 128l95.1 0 11.5-69.3c2.9-17.4 19.4-29.2 36.8-26.3s29.2 19.4 26.3 36.8L357.8 128l58.2 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-68.9 0L325.8 320l58.2 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-68.9 0-11.5 69.3c-2.9 17.4-19.4 29.2-36.8 26.3s-29.2-19.4-26.3-36.8l9.8-58.7-95.1 0-11.5 69.3c-2.9 17.4-19.4 29.2-36.8 26.3s-29.2-19.4-26.3-36.8L90.2 384 32 384c-17.7 0-32-14.3-32-32s14.3-32 32-32l68.9 0 21.3-128L64 192c-17.7 0-32-14.3-32-32s14.3-32 32-32l68.9 0 11.5-69.3c2.9-17.4 19.4-29.2 36.8-26.3zM187.1 192L165.8 320l95.1 0 21.3-128-95.1 0z" />
|
|
3
|
-
</svg>
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
defineIcon,
|
|
3
|
-
defineLanguages,
|
|
4
|
-
defineProductComponent,
|
|
5
|
-
defineProductRender,
|
|
6
|
-
RenderMode,
|
|
7
|
-
} from 'bitran/render';
|
|
8
|
-
|
|
9
|
-
export const heading = defineProductRender({
|
|
10
|
-
mode: RenderMode.Server,
|
|
11
|
-
component: defineProductComponent(() => import('./Heading.vue')),
|
|
12
|
-
icon: defineIcon(() => import('./icon.svg?raw')),
|
|
13
|
-
languages: defineLanguages({
|
|
14
|
-
en: () => import('./languages/en'),
|
|
15
|
-
ru: () => import('./languages/ru'),
|
|
16
|
-
}),
|
|
17
|
-
});
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { DefineProductType } from 'bitran';
|
|
2
|
-
|
|
3
|
-
export interface HeadingParseData {
|
|
4
|
-
level: number;
|
|
5
|
-
title: string;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export type HeadingType = DefineProductType<{
|
|
9
|
-
ParseData: HeadingParseData;
|
|
10
|
-
Provide?: { languageCode: string };
|
|
11
|
-
}>;
|
|
12
|
-
|
|
13
|
-
export const headingName = '__heading';
|