erudit 2.0.0-dev.7
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 -0
- package/app/app.vue +172 -0
- package/app/assets/icons/alert.svg +3 -0
- package/app/assets/icons/angle-right.svg +3 -0
- package/app/assets/icons/arrow-in-text.svg +3 -0
- package/app/assets/icons/arrow-left.svg +3 -0
- package/app/assets/icons/arrow-up-to-right.svg +3 -0
- package/app/assets/icons/aside-open.svg +3 -0
- package/app/assets/icons/asterisk.svg +3 -0
- package/app/assets/icons/book-question.svg +3 -0
- package/app/assets/icons/book.svg +3 -0
- package/app/assets/icons/bug.svg +3 -0
- package/app/assets/icons/chip.svg +3 -0
- package/app/assets/icons/circle-help.svg +3 -0
- package/app/assets/icons/construction.svg +3 -0
- package/app/assets/icons/cross.svg +3 -0
- package/app/assets/icons/draw.svg +3 -0
- package/app/assets/icons/ellipsis-vertical.svg +3 -0
- package/app/assets/icons/file-check.svg +3 -0
- package/app/assets/icons/file-lines.svg +3 -0
- package/app/assets/icons/file-star.svg +3 -0
- package/app/assets/icons/folder-open.svg +3 -0
- package/app/assets/icons/folder.svg +3 -0
- package/app/assets/icons/globe.svg +3 -0
- package/app/assets/icons/house.svg +3 -0
- package/app/assets/icons/link-external.svg +3 -0
- package/app/assets/icons/link.svg +3 -0
- package/app/assets/icons/moon.svg +3 -0
- package/app/assets/icons/outline/book.svg +3 -0
- package/app/assets/icons/outline/file-lines.svg +3 -0
- package/app/assets/icons/pirate.svg +3 -0
- package/app/assets/icons/plus-circle.svg +3 -0
- package/app/assets/icons/plus.svg +3 -0
- package/app/assets/icons/puzzle.svg +3 -0
- package/app/assets/icons/search.svg +3 -0
- package/app/assets/icons/shuffle.svg +3 -0
- package/app/assets/icons/star.svg +3 -0
- package/app/assets/icons/sun-moon.svg +3 -0
- package/app/assets/icons/sun.svg +3 -0
- package/app/assets/icons/user.svg +3 -0
- package/app/assets/icons/users.svg +3 -0
- package/app/components/Loading.vue +23 -0
- package/app/components/SiteAside.vue +382 -0
- package/app/components/SiteMain.vue +35 -0
- package/app/components/ads/BannerTemplate.vue +51 -0
- package/app/components/ads/BottomBanner.vue +45 -0
- package/app/components/ads/LeftBanner.vue +50 -0
- package/app/components/aside/AsideListItem.vue +74 -0
- package/app/components/aside/AsideMajor.vue +56 -0
- package/app/components/aside/AsideMinor.vue +71 -0
- package/app/components/aside/major/PaneContentScroll.vue +23 -0
- package/app/components/aside/major/PaneSwitch.vue +54 -0
- package/app/components/aside/major/PaneSwitchButton.vue +63 -0
- package/app/components/aside/major/SiteInfo.vue +85 -0
- package/app/components/aside/major/panes/Language.vue +79 -0
- package/app/components/aside/major/panes/Pages.vue +34 -0
- package/app/components/aside/major/panes/Search.vue +3 -0
- package/app/components/aside/major/panes/nav/Nav.vue +91 -0
- package/app/components/aside/major/panes/nav/NavBook.vue +86 -0
- package/app/components/aside/major/panes/nav/NavBookLoading.vue +24 -0
- package/app/components/aside/major/panes/nav/NavGlobal.vue +16 -0
- package/app/components/aside/major/panes/nav/fnav/FNav.vue +105 -0
- package/app/components/aside/major/panes/nav/fnav/FNavBook.vue +32 -0
- package/app/components/aside/major/panes/nav/fnav/FNavFlags.vue +40 -0
- package/app/components/aside/major/panes/nav/fnav/FNavFolder.vue +60 -0
- package/app/components/aside/major/panes/nav/fnav/FNavItem.vue +34 -0
- package/app/components/aside/major/panes/nav/fnav/FNavSeparator.vue +80 -0
- package/app/components/aside/major/panes/nav/fnav/FNavTopic.vue +24 -0
- package/app/components/aside/major/panes/other/ItemContent.vue +29 -0
- package/app/components/aside/major/panes/other/ItemGenerator.vue +15 -0
- package/app/components/aside/major/panes/other/ItemTheme.vue +54 -0
- package/app/components/aside/major/panes/other/Other.vue +16 -0
- package/app/components/aside/minor/AsideMinorContributor.vue +5 -0
- package/app/components/aside/minor/AsideMinorNews.vue +11 -0
- package/app/components/aside/minor/AsideMinorPane.vue +16 -0
- package/app/components/aside/minor/AsideMinorTopLink.vue +67 -0
- package/app/components/aside/minor/Contribute.vue +145 -0
- package/app/components/aside/minor/content/AsideMinorContent.vue +92 -0
- package/app/components/aside/minor/topic/AsideMinorTopic.vue +32 -0
- package/app/components/aside/minor/topic/TopicContributors.vue +177 -0
- package/app/components/aside/minor/topic/TopicNav.vue +49 -0
- package/app/components/aside/minor/topic/TopicToc.vue +202 -0
- package/app/components/aside/minor/topic/TopicTocItem.vue +31 -0
- package/app/components/aside/utils/AsideOverlayPane.vue +40 -0
- package/app/components/bitran/BitranContent.vue +64 -0
- package/app/components/bitran/RenderWrapper.vue +12 -0
- package/app/components/contributor/ContributorAvatar.vue +43 -0
- package/app/components/contributor/ContributorListItem.vue +35 -0
- package/app/components/main/topic/MainTopic.vue +79 -0
- package/app/components/main/topic/TopicPartSwitch.vue +118 -0
- package/app/components/main/utils/Breadcrumb.vue +75 -0
- package/app/components/main/utils/ContentDecoration.vue +29 -0
- package/app/components/main/utils/ContentDescription.vue +20 -0
- package/app/components/main/utils/ContentFlag.vue +16 -0
- package/app/components/main/utils/ContentPopover.vue +176 -0
- package/app/components/main/utils/ContentPopovers.vue +105 -0
- package/app/components/main/utils/ContentReferences.vue +76 -0
- package/app/components/main/utils/ContentSection.vue +42 -0
- package/app/components/main/utils/ContentTitle.vue +37 -0
- package/app/components/main/utils/reference/ReferenceGroup.vue +41 -0
- package/app/components/main/utils/reference/ReferenceItem.vue +64 -0
- package/app/components/main/utils/reference/ReferenceSource.vue +110 -0
- package/app/components/preview/Preview.vue +177 -0
- package/app/components/preview/PreviewDisplay.vue +139 -0
- package/app/components/preview/PreviewFooterAction.vue +73 -0
- package/app/components/preview/PreviewLoading.vue +15 -0
- package/app/components/preview/PreviewScreen.vue +99 -0
- package/app/components/preview/display/Alert.vue +50 -0
- package/app/components/preview/display/Custom.vue +18 -0
- package/app/components/preview/display/GenericLink.vue +48 -0
- package/app/components/preview/display/PageLink.vue +20 -0
- package/app/components/preview/display/Unique.vue +49 -0
- package/app/components/transition/Fade.vue +22 -0
- package/app/components/tree/TreeContainer.vue +12 -0
- package/app/components/tree/TreeItem.vue +89 -0
- package/app/composables/bitran.ts +132 -0
- package/app/composables/bitranContent.ts +36 -0
- package/app/composables/bitranLocation.ts +7 -0
- package/app/composables/contentData.ts +36 -0
- package/app/composables/contentPage.ts +156 -0
- package/app/composables/contentRoute.ts +45 -0
- package/app/composables/darkMagic.ts +24 -0
- package/app/composables/externalApi.ts +63 -0
- package/app/composables/favicon.ts +8 -0
- package/app/composables/formatText.ts +86 -0
- package/app/composables/majorPane.ts +60 -0
- package/app/composables/phrases.ts +80 -0
- package/app/composables/theme.ts +29 -0
- package/app/composables/url.ts +33 -0
- package/app/pages/_test/preview.vue +110 -0
- package/app/pages/article/[...articleId].vue +3 -0
- package/app/pages/book/[...bookId].vue +47 -0
- package/app/pages/group/[...groupId].vue +64 -0
- package/app/pages/index.vue +32 -0
- package/app/pages/members.vue +7 -0
- package/app/pages/practice/[...practice].vue +3 -0
- package/app/pages/summary/[...summaryId].vue +3 -0
- package/app/public/favicon/article.svg +10 -0
- package/app/public/favicon/default.svg +10 -0
- package/app/public/favicon/practice.svg +10 -0
- package/app/public/favicon/summary.svg +10 -0
- package/app/public/logotype.svg +17 -0
- package/app/public/og-default.png +0 -0
- package/app/public/user.svg +10 -0
- package/app/scripts/_immediate.js +4 -0
- package/app/scripts/aside/index.ts +59 -0
- package/app/scripts/aside/major/nav.ts +26 -0
- package/app/scripts/aside/minor/state.ts +37 -0
- package/app/scripts/aside/minor/topic.ts +3 -0
- package/app/scripts/flag.ts +28 -0
- package/app/scripts/og.ts +27 -0
- package/app/scripts/preview/build.ts +84 -0
- package/app/scripts/preview/data/alert.ts +19 -0
- package/app/scripts/preview/data/custom.ts +8 -0
- package/app/scripts/preview/data/genericLink.ts +24 -0
- package/app/scripts/preview/data/pageLink.ts +20 -0
- package/app/scripts/preview/data/unique.ts +70 -0
- package/app/scripts/preview/data.ts +26 -0
- package/app/scripts/preview/display.ts +39 -0
- package/app/scripts/preview/footer.ts +9 -0
- package/app/scripts/preview/request.ts +51 -0
- package/app/scripts/preview/state.ts +63 -0
- package/app/styles/_immediate.css +3 -0
- package/app/styles/_util.scss +50 -0
- package/app/styles/_utils.scss +44 -0
- package/app/styles/app.scss +91 -0
- package/app/styles/def/_bp.scss +24 -0
- package/app/styles/def/_size.scss +7 -0
- package/app/styles/def/_z.scss +5 -0
- package/app/styles/default.scss +85 -0
- package/app/styles/normalize.scss +63 -0
- package/app/styles/partials/_darkMagic.scss +7 -0
- package/app/styles/partials/_fnav.scss +18 -0
- package/app/styles/partials/_preview.scss +7 -0
- package/globalPath.ts +24 -0
- package/globals/bitran.ts +39 -0
- package/globals/content.ts +22 -0
- package/globals/contributor.ts +5 -0
- package/globals/erudit.ts +5 -0
- package/globals/register.ts +18 -0
- package/languages/en.ts +95 -0
- package/languages/ru.ts +99 -0
- package/module/bitran.ts +34 -0
- package/module/config.ts +34 -0
- package/module/imports.ts +46 -0
- package/module/index.ts +35 -0
- package/module/logger.ts +10 -0
- package/module/paths.ts +22 -0
- package/module/restart.ts +61 -0
- package/nuxt.config.ts +96 -0
- package/package.json +32 -0
- package/server/api/aside/major/nav/bookIds.ts +5 -0
- package/server/api/aside/major/nav/bookNav/[...bookId].ts +20 -0
- package/server/api/aside/major/nav/global.ts +7 -0
- package/server/api/aside/minor/news.ts +7 -0
- package/server/api/aside/minor/path.ts +78 -0
- package/server/api/bitran/content/[location].ts +7 -0
- package/server/api/bitran/toc/[location].ts +7 -0
- package/server/api/content/data.ts +72 -0
- package/server/api/contributor/count.ts +6 -0
- package/server/api/fake/content.ts +11 -0
- package/server/api/fake/shared/languages.ts +12 -0
- package/server/api/language/functions.ts +12 -0
- package/server/api/language/phrase/[phraseId].ts +19 -0
- package/server/api/language/phraseIds.ts +8 -0
- package/server/api/preview/page/[...parts].ts +51 -0
- package/server/api/preview/unique/[location].ts +55 -0
- package/server/plugin/bitran/content.ts +176 -0
- package/server/plugin/bitran/core.ts +51 -0
- package/server/plugin/bitran/location.ts +25 -0
- package/server/plugin/bitran/products/include.ts +229 -0
- package/server/plugin/bitran/products/link.ts +114 -0
- package/server/plugin/bitran/setup.ts +10 -0
- package/server/plugin/bitran/toc.ts +82 -0
- package/server/plugin/build/close.ts +10 -0
- package/server/plugin/build/jobs/content/builderArgs.ts +8 -0
- package/server/plugin/build/jobs/content/generic.ts +176 -0
- package/server/plugin/build/jobs/content/parse.ts +90 -0
- package/server/plugin/build/jobs/content/path.ts +6 -0
- package/server/plugin/build/jobs/content/type/book.ts +9 -0
- package/server/plugin/build/jobs/content/type/group.ts +37 -0
- package/server/plugin/build/jobs/content/type/topic.ts +36 -0
- package/server/plugin/build/jobs/contributors.ts +66 -0
- package/server/plugin/build/jobs/language.ts +36 -0
- package/server/plugin/build/jobs/nav.ts +209 -0
- package/server/plugin/build/process.ts +25 -0
- package/server/plugin/build/rebuild.ts +55 -0
- package/server/plugin/build/setup.ts +21 -0
- package/server/plugin/content/absoluteId.ts +94 -0
- package/server/plugin/content/context.ts +112 -0
- package/server/plugin/db/entities/Book.ts +7 -0
- package/server/plugin/db/entities/Content.ts +49 -0
- package/server/plugin/db/entities/Contribution.ts +10 -0
- package/server/plugin/db/entities/Contributor.ts +16 -0
- package/server/plugin/db/entities/Group.ts +14 -0
- package/server/plugin/db/entities/Hash.ts +15 -0
- package/server/plugin/db/entities/Topic.ts +20 -0
- package/server/plugin/db/entities/Unique.ts +21 -0
- package/server/plugin/db/setup.ts +34 -0
- package/server/plugin/global.ts +18 -0
- package/server/plugin/importer.ts +12 -0
- package/server/plugin/index.ts +9 -0
- package/server/plugin/logger.ts +23 -0
- package/server/plugin/nav/node.ts +26 -0
- package/server/plugin/nav/utils.ts +129 -0
- package/server/plugin/repository/book.ts +21 -0
- package/server/plugin/repository/content.ts +238 -0
- package/server/plugin/repository/contributor.ts +8 -0
- package/server/plugin/repository/frontNav.ts +148 -0
- package/server/plugin/repository/topic.ts +32 -0
- package/server/tsconfig.json +7 -0
- package/shared/aside/minor.ts +50 -0
- package/shared/asset.ts +15 -0
- package/shared/bitran/alias.ts +17 -0
- package/shared/bitran/context.ts +7 -0
- package/shared/bitran/location.ts +166 -0
- package/shared/bitran/products/alias/core/factory.ts +46 -0
- package/shared/bitran/products/alias/core/index.ts +13 -0
- package/shared/bitran/products/alias/render/Alias.vue +10 -0
- package/shared/bitran/products/alias/render/icon.svg +3 -0
- package/shared/bitran/products/alias/render/index.ts +17 -0
- package/shared/bitran/products/alias/render/languages/en.ts +5 -0
- package/shared/bitran/products/alias/render/languages/ru.ts +5 -0
- package/shared/bitran/products/alias/shared.ts +11 -0
- package/shared/bitran/products/heading/core/factory.ts +53 -0
- package/shared/bitran/products/heading/core/index.ts +19 -0
- package/shared/bitran/products/heading/render/Heading.vue +47 -0
- package/shared/bitran/products/heading/render/icon.svg +3 -0
- package/shared/bitran/products/heading/render/index.ts +17 -0
- package/shared/bitran/products/heading/render/languages/en.ts +5 -0
- package/shared/bitran/products/heading/render/languages/ru.ts +5 -0
- package/shared/bitran/products/heading/shared.ts +13 -0
- package/shared/bitran/products/include/core/factory.ts +61 -0
- package/shared/bitran/products/include/core/index.ts +13 -0
- package/shared/bitran/products/include/render/Include.vue +13 -0
- package/shared/bitran/products/include/render/icon.svg +3 -0
- package/shared/bitran/products/include/render/index.ts +18 -0
- package/shared/bitran/products/include/render/languages/en.ts +5 -0
- package/shared/bitran/products/include/render/languages/ru.ts +5 -0
- package/shared/bitran/products/include/shared.ts +15 -0
- package/shared/bitran/products/link/core/factory.ts +20 -0
- package/shared/bitran/products/link/core/index.ts +17 -0
- package/shared/bitran/products/link/render/Link.vue +174 -0
- package/shared/bitran/products/link/render/icon.svg +3 -0
- package/shared/bitran/products/link/render/index.ts +17 -0
- package/shared/bitran/products/link/render/languages/en.ts +5 -0
- package/shared/bitran/products/link/render/languages/ru.ts +5 -0
- package/shared/bitran/products/link/shared.ts +15 -0
- package/shared/bitran/products/link/target.ts +134 -0
- package/shared/bitran/toc.ts +8 -0
- package/shared/content/context.ts +9 -0
- package/shared/content/data/base.ts +32 -0
- package/shared/content/data/index.ts +5 -0
- package/shared/content/data/type/book.ts +5 -0
- package/shared/content/data/type/group.ts +6 -0
- package/shared/content/data/type/topic.ts +11 -0
- package/shared/content/previousNext.ts +9 -0
- package/shared/contributor.ts +5 -0
- package/shared/frontNav.ts +41 -0
- package/shared/icons.ts +38 -0
- package/shared/image.ts +5 -0
- package/shared/link.ts +25 -0
- package/shared/types/language.ts +75 -0
- package/shared/utils/objectsEqual.ts +4 -0
- package/shared/utils/stringColor.ts +9 -0
- package/test/bitran/alias.test.ts +44 -0
- package/test/bitran/location.test.ts +143 -0
- package/test/bitran/products/alias.test.ts +83 -0
- package/test/bitran/products/heading.test.ts +119 -0
- package/test/bitran/products/include.test.ts +77 -0
- package/test/bitran/products/link/factory.test.ts +30 -0
- package/test/bitran/products/link/target.test.ts +138 -0
- package/tsconfig.json +8 -0
- package/utils/stress.ts +9 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { TopicPart } from 'erudit-cog/schema';
|
|
2
|
+
|
|
3
|
+
import { ERUDIT_SERVER } from '@server/global';
|
|
4
|
+
import { DbTopic } from '@server/db/entities/Topic';
|
|
5
|
+
import type { TopicPartLinks } from '@shared/content/data/type/topic';
|
|
6
|
+
import { createTopicPartLink } from '@shared/link';
|
|
7
|
+
|
|
8
|
+
export async function getTopicParts(contentId: string) {
|
|
9
|
+
const dbTopic = await ERUDIT_SERVER.DB.manager.findOne(DbTopic, {
|
|
10
|
+
select: ['parts'],
|
|
11
|
+
where: { contentId },
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
if (!dbTopic) throw new Error(`Missing topic "${contentId}".`);
|
|
15
|
+
|
|
16
|
+
return dbTopic.parts;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export async function getTopicPart(contentId: string): Promise<TopicPart> {
|
|
20
|
+
const topicParts = await getTopicParts(contentId);
|
|
21
|
+
return topicParts.shift()!;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export async function getTopicPartsLinks(topicId: string) {
|
|
25
|
+
const existingTopicParts = await getTopicParts(topicId);
|
|
26
|
+
const links: TopicPartLinks = {};
|
|
27
|
+
|
|
28
|
+
for (const topicPart of existingTopicParts)
|
|
29
|
+
links[topicPart] = createTopicPartLink(topicPart, topicId);
|
|
30
|
+
|
|
31
|
+
return links;
|
|
32
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { BitranLocation } from '../bitran/location';
|
|
2
|
+
import type { Toc } from '../bitran/toc';
|
|
3
|
+
import type { PreviousNextItem } from '../content/previousNext';
|
|
4
|
+
import type { ContentContributor } from '../contributor';
|
|
5
|
+
|
|
6
|
+
interface AsideMinorBase {
|
|
7
|
+
type: AsideMinorType;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export type AsideMinorType =
|
|
11
|
+
| 'topic'
|
|
12
|
+
| 'group'
|
|
13
|
+
| 'book'
|
|
14
|
+
| 'contributor'
|
|
15
|
+
| 'news';
|
|
16
|
+
|
|
17
|
+
export interface AsideMinorTopic extends AsideMinorBase {
|
|
18
|
+
type: 'topic';
|
|
19
|
+
fullContentId: string;
|
|
20
|
+
location: BitranLocation;
|
|
21
|
+
nav: Partial<{
|
|
22
|
+
previous: PreviousNextItem;
|
|
23
|
+
next: PreviousNextItem;
|
|
24
|
+
article: string;
|
|
25
|
+
summary: string;
|
|
26
|
+
practice: string;
|
|
27
|
+
}>;
|
|
28
|
+
toc: Toc;
|
|
29
|
+
contributors?: ContentContributor[];
|
|
30
|
+
// todos: TodoItem[];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface AsideMinorContent extends AsideMinorBase {
|
|
34
|
+
type: 'group' | 'book';
|
|
35
|
+
fullContentId: string;
|
|
36
|
+
nav: Partial<{
|
|
37
|
+
previous: PreviousNextItem;
|
|
38
|
+
next: PreviousNextItem;
|
|
39
|
+
}>;
|
|
40
|
+
contributors?: ContentContributor[];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface AsideMinorNews extends AsideMinorBase {
|
|
44
|
+
type: 'news';
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export type AsideMinorData =
|
|
48
|
+
| AsideMinorTopic
|
|
49
|
+
| AsideMinorContent
|
|
50
|
+
| AsideMinorNews;
|
package/shared/asset.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export function eruditAsset(path: string) {
|
|
2
|
+
return '/_erudit-asset/' + path;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function contributorAsset(path: string) {
|
|
6
|
+
return '/_user-asset/contributor/' + path;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function contentAsset(path: string) {
|
|
10
|
+
return '/_user-asset/content/' + path;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function publicAsset(path: string) {
|
|
14
|
+
return '/_user-asset/public/' + path;
|
|
15
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { isTopicPart } from 'erudit-cog/schema';
|
|
2
|
+
|
|
3
|
+
export const bitranLocationTypes = {
|
|
4
|
+
article: true,
|
|
5
|
+
summary: true,
|
|
6
|
+
practice: true,
|
|
7
|
+
group: true,
|
|
8
|
+
contributor: true,
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export type BitranLocationType = keyof typeof bitranLocationTypes;
|
|
12
|
+
|
|
13
|
+
export function isBitranLocationType(type: any): type is BitranLocationType {
|
|
14
|
+
return type in bitranLocationTypes;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function typeRequiresPath(type: BitranLocationType) {
|
|
18
|
+
return bitranLocationTypes[type];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface BitranLocation {
|
|
22
|
+
type: BitranLocationType;
|
|
23
|
+
path?: string;
|
|
24
|
+
unique?: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function stringifyBitranLocation(location: BitranLocation): string {
|
|
28
|
+
try {
|
|
29
|
+
if (!isBitranLocationType(location.type))
|
|
30
|
+
throw `Unknown Bitran location type "${location.type}"!`;
|
|
31
|
+
|
|
32
|
+
if (!location.path && typeRequiresPath(location.type))
|
|
33
|
+
throw 'Missing Bitran location path!';
|
|
34
|
+
|
|
35
|
+
if (location.unique === '')
|
|
36
|
+
throw 'Bitran location unique cannot be empty string!';
|
|
37
|
+
} catch (reason) {
|
|
38
|
+
let message = `${reason}\n\n` + JSON.stringify(location, null, 4);
|
|
39
|
+
throw new Error(message);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
location.type +
|
|
44
|
+
'|' +
|
|
45
|
+
(location.path || '') +
|
|
46
|
+
(location.unique ? '|' + location.unique : '')
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function parseBitranLocation(strLocation: string): BitranLocation {
|
|
51
|
+
const [strType, strPath, strUnique] = strLocation.split('|');
|
|
52
|
+
|
|
53
|
+
if (!isBitranLocationType(strType))
|
|
54
|
+
throw new Error(`Unknown Bitran location type "${strType}"!`);
|
|
55
|
+
|
|
56
|
+
const location: BitranLocation = { type: strType };
|
|
57
|
+
|
|
58
|
+
if (!strPath) {
|
|
59
|
+
if (typeRequiresPath(location.type))
|
|
60
|
+
throw new Error(
|
|
61
|
+
`Missing Bitran location path for type "${strType}"!`,
|
|
62
|
+
);
|
|
63
|
+
} else location.path = strPath;
|
|
64
|
+
|
|
65
|
+
if (strUnique === '')
|
|
66
|
+
throw `Bitran location "${strLocation}" unique cannot be empty string!`;
|
|
67
|
+
else if (strUnique) location.unique = strUnique;
|
|
68
|
+
|
|
69
|
+
return location;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function parsePartialBitranLocation(
|
|
73
|
+
strLocation: string,
|
|
74
|
+
contextLocation: BitranLocation,
|
|
75
|
+
): BitranLocation {
|
|
76
|
+
const parts = strLocation.split('|');
|
|
77
|
+
|
|
78
|
+
// Only unique provided. Restoring type + path
|
|
79
|
+
// function -> article|foo/bar|function
|
|
80
|
+
if (parts.length === 1)
|
|
81
|
+
return {
|
|
82
|
+
type: contextLocation.type,
|
|
83
|
+
path: contextLocation.path,
|
|
84
|
+
unique: parts[0],
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
if (parts.length === 2) {
|
|
88
|
+
//
|
|
89
|
+
// If there are two parts, the result depends on location type
|
|
90
|
+
//
|
|
91
|
+
|
|
92
|
+
// In topics we can reference topic parts without specifying content path
|
|
93
|
+
// practice|function -> practice|foo/bar|function
|
|
94
|
+
if (isTopicPart(parts[0])) {
|
|
95
|
+
const [type, unique] = parts as [BitranLocationType, string];
|
|
96
|
+
|
|
97
|
+
if (!isTopicPart(contextLocation.type))
|
|
98
|
+
throw new Error(
|
|
99
|
+
`String Bitran location "${strLocation}" referencing topic part "${type}" in non-topic context!`,
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
return {
|
|
103
|
+
type,
|
|
104
|
+
path: contextLocation.path,
|
|
105
|
+
unique,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return parseBitranLocation(strLocation);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export const { encodeBitranLocation, decodeBitranLocation } = (() => {
|
|
114
|
+
const encodeSymbols = {
|
|
115
|
+
'|': '┃',
|
|
116
|
+
'/': '╱',
|
|
117
|
+
':': '﹕',
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const decodeSymbols = Object.entries(encodeSymbols).reduce(
|
|
121
|
+
(map, [key, value]) => ((map[value] = key), map),
|
|
122
|
+
{} as Record<string, string>,
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
const replaceSymbols = (text: string, symbols: Record<string, string>) => {
|
|
126
|
+
for (const [find, replace] of Object.entries(symbols))
|
|
127
|
+
text = text.replaceAll(find, replace);
|
|
128
|
+
|
|
129
|
+
return text;
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
return {
|
|
133
|
+
encodeBitranLocation: (strLocation: string) =>
|
|
134
|
+
replaceSymbols(strLocation, encodeSymbols),
|
|
135
|
+
|
|
136
|
+
decodeBitranLocation: (strLocation: string) =>
|
|
137
|
+
replaceSymbols(strLocation, decodeSymbols),
|
|
138
|
+
};
|
|
139
|
+
})();
|
|
140
|
+
|
|
141
|
+
export function locationFromPath(routePath: string) {
|
|
142
|
+
const pathParts = (
|
|
143
|
+
routePath.startsWith('/') ? routePath.substring(1) : routePath
|
|
144
|
+
).split('/');
|
|
145
|
+
const firstPart = pathParts.shift() as any;
|
|
146
|
+
const locationPath = pathParts.join('/');
|
|
147
|
+
|
|
148
|
+
if (!locationPath) return undefined;
|
|
149
|
+
|
|
150
|
+
if (isTopicPart(firstPart))
|
|
151
|
+
return {
|
|
152
|
+
type: firstPart,
|
|
153
|
+
path: locationPath,
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
switch (firstPart) {
|
|
157
|
+
case 'group':
|
|
158
|
+
case 'contributor':
|
|
159
|
+
return {
|
|
160
|
+
type: firstPart,
|
|
161
|
+
path: locationPath,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return undefined;
|
|
166
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
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
|
+
});
|
|
@@ -0,0 +1,3 @@
|
|
|
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>
|
|
@@ -0,0 +1,17 @@
|
|
|
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
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
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';
|
|
@@ -0,0 +1,53 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
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
|
+
});
|
|
@@ -0,0 +1,47 @@
|
|
|
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>
|
|
@@ -0,0 +1,3 @@
|
|
|
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>
|
|
@@ -0,0 +1,17 @@
|
|
|
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
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
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';
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BlockParseFactory,
|
|
3
|
+
ObjBlockParseFactory,
|
|
4
|
+
ObjProductStrFactory,
|
|
5
|
+
ProductStrFactory,
|
|
6
|
+
type keyable,
|
|
7
|
+
} from 'bitran/process';
|
|
8
|
+
|
|
9
|
+
import { includeName, type IncludeData, type IncludeType } from '../shared';
|
|
10
|
+
|
|
11
|
+
export class IncludeParser extends BlockParseFactory<IncludeType> {
|
|
12
|
+
regexp = /^<~ (\S+)$/;
|
|
13
|
+
location!: string;
|
|
14
|
+
|
|
15
|
+
canParse(strBlock: string) {
|
|
16
|
+
const match = strBlock.match(this.regexp);
|
|
17
|
+
|
|
18
|
+
if (match && match[1]) {
|
|
19
|
+
this.location = match[1];
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async createParseData() {
|
|
27
|
+
return {
|
|
28
|
+
location: this.location,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export class ResolvedIncludeParser extends ObjBlockParseFactory<IncludeType> {
|
|
34
|
+
objName = includeName;
|
|
35
|
+
|
|
36
|
+
async parseDataFromObj(obj: keyable): Promise<IncludeData> {
|
|
37
|
+
if (obj.error) throw obj.error;
|
|
38
|
+
|
|
39
|
+
return {
|
|
40
|
+
location: obj.location,
|
|
41
|
+
resolved: true,
|
|
42
|
+
blocks: await this.parseBlocks(obj.blocks),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export class IncludeStr extends ProductStrFactory<IncludeType> {
|
|
48
|
+
stringifyData(data: IncludeData): string {
|
|
49
|
+
if (data.resolved) {
|
|
50
|
+
const obj: any = {};
|
|
51
|
+
|
|
52
|
+
obj.resolved = true;
|
|
53
|
+
obj.location = data.location;
|
|
54
|
+
|
|
55
|
+
if (data.error) obj.error = data.error;
|
|
56
|
+
else obj.blocks = this.stringify(data.blocks!);
|
|
57
|
+
|
|
58
|
+
return ObjProductStrFactory.strObjBlock(includeName, obj);
|
|
59
|
+
} else return `<~ ${data.location}`;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { BlockNode } from 'bitran/dom';
|
|
2
|
+
import { defineProductCore } from 'bitran/core';
|
|
3
|
+
|
|
4
|
+
import type { IncludeType } from '../shared';
|
|
5
|
+
import { IncludeParser, IncludeStr, ResolvedIncludeParser } from './factory';
|
|
6
|
+
|
|
7
|
+
export class IncludeNode extends BlockNode<IncludeType> {}
|
|
8
|
+
|
|
9
|
+
export const include = defineProductCore({
|
|
10
|
+
Node: IncludeNode,
|
|
11
|
+
Parser: [IncludeParser, ResolvedIncludeParser],
|
|
12
|
+
Stringifier: IncludeStr,
|
|
13
|
+
});
|