aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2024-04-16 16:45:16 +0200
committerLibravatar Kristóf Marussy <kristof@marussy.com>2024-04-16 16:45:16 +0200
commit9d00cd82a8fc5e9cbe2d68a8410ce82cd63eef14 (patch)
tree019a576bc6e15ba2a3b93a5e716fb41a3f6006af
parentfeat(docs): add Algolia DocSearch (diff)
downloadrefinery-9d00cd82a8fc5e9cbe2d68a8410ce82cd63eef14.tar.gz
refinery-9d00cd82a8fc5e9cbe2d68a8410ce82cd63eef14.tar.zst
refinery-9d00cd82a8fc5e9cbe2d68a8410ce82cd63eef14.zip
docs: contributing guide
-rw-r--r--subprojects/docs/docusaurus.config.ts5
-rw-r--r--subprojects/docs/src/develop/contributing.md51
-rw-r--r--subprojects/docs/src/develop/contributing/commands.md172
-rw-r--r--subprojects/docs/src/develop/contributing/ide-setup.md94
-rw-r--r--subprojects/docs/src/develop/contributing/index.md59
-rw-r--r--subprojects/docs/src/plugins/remarkPosix2Windows.ts166
6 files changed, 495 insertions, 52 deletions
diff --git a/subprojects/docs/docusaurus.config.ts b/subprojects/docs/docusaurus.config.ts
index 67ee1db4..25182f60 100644
--- a/subprojects/docs/docusaurus.config.ts
+++ b/subprojects/docs/docusaurus.config.ts
@@ -15,8 +15,10 @@ import { Config as SwcConfig } from '@swc/core';
15import { themes } from 'prism-react-renderer'; 15import { themes } from 'prism-react-renderer';
16import smartypants from 'remark-smartypants'; 16import smartypants from 'remark-smartypants';
17 17
18import remarkPosix2Windows from './src/plugins/remarkPosix2Windows';
19
18const markdownOptions = { 20const markdownOptions = {
19 remarkPlugins: [[smartypants, { dashes: 'oldschool' }]], 21 remarkPlugins: [[smartypants, { dashes: 'oldschool' }], remarkPosix2Windows],
20}; 22};
21 23
22const docsOptions = { 24const docsOptions = {
@@ -75,6 +77,7 @@ export default {
75 respectPrefersColorScheme: true, 77 respectPrefersColorScheme: true,
76 }, 78 },
77 prism: { 79 prism: {
80 additionalLanguages: ['bash', 'java'],
78 theme: themes.oneLight, 81 theme: themes.oneLight,
79 darkTheme: themes.oneDark, 82 darkTheme: themes.oneDark,
80 }, 83 },
diff --git a/subprojects/docs/src/develop/contributing.md b/subprojects/docs/src/develop/contributing.md
deleted file mode 100644
index 4a135b81..00000000
--- a/subprojects/docs/src/develop/contributing.md
+++ /dev/null
@@ -1,51 +0,0 @@
1---
2SPDX-FileCopyrightText: 2021-2023 The Refinery Authors
3SPDX-License-Identifier: EPL-2.0
4sidebar_position: 1
5sidebar_label: Contributing
6---
7
8# Contributing to Refinery
9
10## Setting up the development environment
11
12### With IntelliJ IDEA
13
14We prefer IntelliJ IDEA as a development environment.
15No special preparations should be necessary for importing the project as a Gradle project into IDEA.
16
17However, you will need Eclipse to edit Xtext (`*.xtext`) and MWE2 (`*.mwe2`) files and Ecore class diagrams (`*.aird`, `*.ecore`, `*.genmodel`).
18If you do not plan on making changes to such files, feel free to skip the Eclipse installation steps below.
19
20### With Eclipse IDE
21
221. Download and install a _Java 21_ compatible JDK. For Windows, prefer OpenJDK builds from [Adoptium](https://adoptium.net/).
23
242. Download and extract the [Eclipse IDE for Java and DSL Developers 2023-12](https://www.eclipse.org/downloads/packages/release/2023-12/r/eclipse-ide-java-and-dsl-developers) package.
25
263. Launch Eclipse and create a new workspace.
27
284. Open _Help > Eclipse Marketplace_ and install the following software:
29 * _EclEmma Java Code Coverage_
30 * _EcoreTools : Ecore Diagram Editor_
31 * _Sirius_ (ignore the warning during installation about the solution _Sirius_ not being available)
32 * _SonarLint_
33
345. Open _Window > Preferences_ and set the following preferences:
35 * _General > Workspace > Text file encoding_ should be _UTF-8_.
36 * _General > Workspace > New text file line delimiter_ should be _Unix_.
37 * Add the JDK 21 to _Java > Installed JREs_.
38 * Make sure JDK 21 is selected for _JavaSE-21_ at _Java > Installed JREs > Execution Environments_.
39 * Set _Gradle > Java home_ to the `JAVA_HOME` directory (the directory which contains the `bin` directory) of JDK 21. Here, Buildship will show a yellow warning sign, which can be safely ignored.
40 * Set _Java > Compiler > JDK Compliance > Compiler compliance level_ to _21_.
41
426. Clone the project Git repository but do not import it into Eclipse yet.
43
447. Open a new terminal an run `./gradlew prepareEclipse` (`.\gradlew prepareEclipse` on Windows) in the cloned repository.
45 * This should complete without any compilation errors.
46 * If you get any errors about the JVM version, check whether the `JAVA_HOME` environment variable is set to the location of JDK. You can query the variable with `echo $JAVA_HOME` on Linux and `echo $Env:JAVA_HOME` in PowerShell on Windows. To set it, use `export JAVA_HOME=/java/path/here` or `$Env:JAVA_HOME="C:\java\path\here"`, respectively.
47 * If the build fails with a `Host name must not be empty` error, you [might need to remove the empty proxy configuration from your global `gradle.properties` file](https://stackoverflow.com/a/62128323).
48
498. Select _File > Import... > Gradle > Existing Gradle Project_ and import the cloned repository in Eclipse.
50 * Make sure to select the root of the repository (containing this file) as the _Project root directory_ and that the _Gradle distribution_ is _Gradle wrapper_.
51 * If you have previously imported the project into Eclipse, this step will likely fail. In that case, you should remove the projects from Eclipse, run `git clean -fxd` in the repository, and start over from step 8.
diff --git a/subprojects/docs/src/develop/contributing/commands.md b/subprojects/docs/src/develop/contributing/commands.md
new file mode 100644
index 00000000..abfea704
--- /dev/null
+++ b/subprojects/docs/src/develop/contributing/commands.md
@@ -0,0 +1,172 @@
1---
2SPDX-FileCopyrightText: 2024 The Refinery Authors
3SPDX-License-Identifier: EPL-2.0
4sidebar_position: 1
5title: Build commands
6---
7
8# Building from the command line
9
10## Gradle commands
11
12We use [Gradle](https://gradle.org/) to manage the compilation and tests of Refinery.
13
14Java code is built directly by Gradle.
15We use the [frontend-gradle-plugin](https://siouan.github.io/frontend-gradle-plugin/) to manage a [Node.js](https://nodejs.org/en) and [Yarn](https://yarnpkg.com/) installation, which in turn is used to build TypeScript code (including this documentation website).
16Typically, Yarn commands are issued by Gradle and you don't need to work with the TypeScript build system directly if you're only working on the Java parts of Refinery.
17
18### `build`
19
20```bash posix2windows
21./gradlew build
22```
23
24Compile all code, run all tests, and produce all build artifacts.
25
26You should run this command before submitting a [Pull request](https://github.com/graphs4value/refinery/pulls) to make sure that all code builds and tests pass on your local machine.
27This will also be run by GitHub Actions for each commit or pull requests.
28
29### `publishToMavenLocal`
30
31
32```bash posix2windows
33./gradlew publishToMavenLocal
34```
35
36Publishes the Refinery Java artifacts to the [Maven local repository](https://www.baeldung.com/maven-local-repository).
37
38Build tools, such as Gradle, will be able to consume such artifacts, which enables you to use the latest version of Refinery -- possibly including your own modification -- in other Java projects.
39
40For example, in Gradle, you may set
41
42```kotlin title="build.gradle.kts"
43repositories {
44 mavenLocal()
45}
46
47dependencies {
48 implementation("tools.refinery:refinery-generator:0.0.0-SNAPSHOT")
49}
50```
51
52to add a dependency on Refinery to your Java project.
53
54### `serve`
55
56```bash posix2windows
57./gradlew serve
58```
59
60Starts the Refinery backend and web interface on port 1312.
61
62This task is ideal for running the Refinery backend if you don't intend to work on the frontend.
63The Refinery frontend TypeScript projects is automatically built before the server starts.
64The server will use the latest build output of the frontend as static assets.
65
66The behavior of this task is influenced by the same [environmental variables](/learn/docker#environmental-variables) as the Refinery [Docker container](/learn/docker).
67However, the default value of `REFINERY_LISTEN_PORT` is `1312`.
68
69### `serveBackend`
70
71```bash posix2windows
72./gradlew serveBackend
73```
74
75Starts the Refinery backend on port 1312.
76
77This task is ideal for running the Refinery backend if you're working on the frontend.
78No static assets will be build.
79You'll need to use [`yarnw frontend dev`](#frontend-dev)
80
81Like [`gradlew serve`](#serve), the behavior of this task is influenced by the same [environmental variables](/learn/docker#environmental-variables) as the Refinery [Docker container](/learn/docker).
82However, the default value of `REFINERY_LISTEN_PORT` is `1312`.
83
84## Yarn commands
85
86We provide a `yarnw` wrapper script to invoke the Yarn distribution installed by frontend-gradle-plugin directly.
87The following commands can only be run once [`gradlew build`](#build) has installed the necessary Node.js and Yarn packages.
88
89### `docs dev`
90
91```bash posix2windows
92./yarn docs dev
93```
94
95Builds and serves this documentation in development mode on port 3000.
96Saved changes to most documentation sources are immediately reflected in the browse without reloading.
97
98You can set the port with the `-p` option, e.g. to use port 1313, use
99
100```bash posix2windows
101./yarn docs dev -p 1313
102```
103
104:::note
105
106Running this command for the first time may generate error messages like
107```
108ERROR failed to read input source map: failed to parse inline source map url
109```
110which can be safely ignored.
111
112:::
113
114### `frontend dev`
115
116```bash posix2windows
117./yarn frontend dev
118```
119
120Builds and serves the refinery frontend on port 1313.
121Saved changes to most source files are immediately reflected in the browser without reload.
122
123Before running this command, you need to start [`gradlew serveBackend`](#servebackend) to provide a backend for the frontend to connect to.
124The development server of the frontend will proxy all WebSocket connections to the backend.
125
126The following environmental variables influence the behavior of this command:
127
128#### `REFINERY_LISTEN_HOST`
129
130Hostname to listen at for incoming HTTP connections.
131
132**Default value:** `localhost`
133
134#### `REFINERY_LISTEN_PORT`
135
136TCP port to listen at for incoming HTTP connections.
137
138**Default value:** `1313`
139
140#### `REFINERY_BACKEND_HOST`
141
142Hostname of the Refinery backend.
143
144This should match the `REFINERY_LISTEN_HOST` passed to [`gradlew serveBackend`](#servebackend).
145
146**Default value:** `127.0.0.1` (connect to `localhost` over IPv4 only)
147
148#### `REFINERY_LISTEN_PORT`
149
150TCP port of the Refinery backend.
151
152This should match the `REFINERY_LISTEN_PORT` passed to [`gradlew serveBackend`](#servebackend).
153
154**Default value:** `1312`
155
156#### `REFINERY_PUBLIC_HOST`
157
158Publicly visible hostname of the Refinery instance.
159
160If you use a reverse proxy in front of the development server, you must set this variable.
161Otherwise, connections to the development server will fail due to cross-origin protection.
162
163**Default value:** equal to `REFINERY_LISTEN_HOST`
164
165#### `REFINERY_PUBLIC_PORT`
166
167Publicly visible port of the Refinery instance.
168
169If you use a reverse proxy in front of the development server, you must set this variable.
170Otherwise, connections to the development server will fail due to cross-origin protection.
171
172**Default value:** equal to `REFINERY_LISTEN_PORT`
diff --git a/subprojects/docs/src/develop/contributing/ide-setup.md b/subprojects/docs/src/develop/contributing/ide-setup.md
new file mode 100644
index 00000000..742035e0
--- /dev/null
+++ b/subprojects/docs/src/develop/contributing/ide-setup.md
@@ -0,0 +1,94 @@
1---
2SPDX-FileCopyrightText: 2021-2023 The Refinery Authors
3SPDX-License-Identifier: EPL-2.0
4sidebar_position: 2
5title: IDE setup
6---
7
8# Setting up the development environment
9
10## IntelliJ IDEA
11
12We prefer [IntelliJ IDEA](https://www.jetbrains.com/idea/) as a Java development environment.
13No special preparations should be necessary for importing the project as a Gradle project into IDEA:
14
151. See the [required tools](/develop/contributing#required-tools) for compiling Refinery about obtaining the required JDK version. You'll also need a version of IntelliJ IDEA that supports **Java 21** (version **2023.3** or later).
16
172. Clone the project git repository and open it in IntelliJ IDEA. Make sure to _open_ the project instead of creating a _new_ one in the same directory.
18
193. IntelliJ IDEA should build and index the project. If there are errors, it is likely that the `JAVA_HOME` was incorrectly set:
20 * In _Project Structure > Project settings > Project > SDK_, a Java 21 compatible JDK should be selected.
21 * In _Project Structure > Project settings > Project > Language level_, either _SDK default_ or _21_ should be selected.
22 * Make sure that each module in _Project Structure > Project settings > Module_ uses the _Project default_ language level in _Sources > Language level_ and the _Project SDK_ in _Dependencies > Module SDK._
23 * In _Settings > Gradle settings > Gralde Projects > Gradle_, the _Distribution_ should be set to _Wrapper_ and the _Gradle JVM_ should be set to _Project SDK._
24
254. We recommend installing the latest _SonarLint_ plugin in _Settings > Plugins_ to get real-time code quality analysis in your IDE.
26
27:::note
28
29You'll need [Eclipse](#eclipse) to edit Xtext (`*.xtext`) and MWE2 (`*.mwe2`) files and Ecore class diagrams (`*.aird`, `*.ecore`, `*.genmodel`).
30If you do not plan on making changes to such files, feel free to skip the Eclipse installation steps below.
31
32You'll also need [VS Code](#vs-code) to edit the TypeScript code in Refinery.
33
34:::
35
36## Eclipse
37
381. See the [required tools](/develop/contributing#required-tools) for compiling Refinery about obtaining the required JDK version.
39
402. Download and extract the [Eclipse IDE for Java and DSL Developers 2023-12](https://www.eclipse.org/downloads/packages/release/2023-12/r/eclipse-ide-java-and-dsl-developers) package.
41
423. Launch Eclipse and create a new workspace.
43
444. Open _Help > Eclipse Marketplace_ and install the following software:
45 * _EclEmma Java Code Coverage_
46 * _EcoreTools : Ecore Diagram Editor_
47 * _Sirius_ (ignore the warning during installation about the solution _Sirius_ not being available)
48 * _SonarLint_
49
505. Open _Window > Preferences_ and set the following preferences:
51 * _General > Workspace > Text file encoding_ should be _UTF-8_.
52 * _General > Workspace > New text file line delimiter_ should be _Unix_.
53 * Add the JDK 21 to _Java > Installed JREs_.
54 * Make sure JDK 21 is selected for _JavaSE-21_ at _Java > Installed JREs > Execution Environments_.
55 * Set _Gradle > Java home_ to the `JAVA_HOME` directory (the directory which contains the `bin` directory) of JDK 21. Here, Buildship will show a yellow warning sign, which can be safely ignored.
56 * Set _Java > Compiler > JDK Compliance > Compiler compliance level_ to _21_.
57
586. Clone the project Git repository but _do not_ import it into Eclipse yet.
59
607. Open a new terminal and run
61 ```bash posix2windows
62 ./gradlew prepareEclipse
63 ```
64 in the cloned repository.
65 * This should complete without any compilation errors.
66 * To troubleshoot any error, see the [instructions about compiling Refinery](/develop/contributing#compiling).
67
688. Select _File > Import... > Gradle > Existing Gradle Project_ and import the cloned repository in Eclipse.
69 * Make sure to select the root of the repository (containing this file) as the _Project root directory_ and that the _Gradle distribution_ is _Gradle wrapper_.
70 * If you have previously imported the project into Eclipse, this step will likely fail. In that case, you should remove the projects from Eclipse, run `git clean -fxd` in the repository, and start over from step 8.
71
72## VS Code
73
74We recommend [VSCodium](https://github.com/VSCodium/vscodium) or [Visual Studio Code](https://code.visualstudio.com/) to work with the parts of Refinery that are written is TypeScript.
75
761. See the [required tools](/develop/contributing#required-tools) for compiling Refinery about obtaining the required JDK version. You'll also need a version of IntelliJ IDEA that supports **Java 21** (version **2023.3** or later).
77
782. Install the following VS Code extensions:
79 * _EditorConfig for VS Code_ [[Open VSX](https://open-vsx.org/extension/EditorConfig/EditorConfig)] [[Extension Marketplace](https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig)]
80 * _ZipFS - a zip file system_ [[Open VSX](https://open-vsx.org/extension/arcanis/vscode-zipfs)] [[Extension Marketplace](https://marketplace.visualstudio.com/items?itemName=arcanis.vscode-zipfs)]
81 * _ESLint_ [[Open VSX](https://open-vsx.org/extension/dbaeumer/vscode-eslint)] [[Extension Marketplace](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint)]
82 * _XState VSCode_ [[Open VSX](https://open-vsx.org/extension/statelyai/stately-vscode)] [[Extension Marketplace](https://marketplace.visualstudio.com/items?itemName=statelyai.stately-vscode)]
83
843. Clone the project Git repository but _do not_ import it into VS Code yet.
85
864. Run
87 ```bash posix2windows
88 ./gradlew installFrontend
89 ```
90 to install all required Node.js tooling.
91
925. Open the repository with _Open Folder&hellip;_ in VS Code.
93 * When asked, select that you _Trust_ the folder.
94 * When asked, enable using the TypeScript and ESLint tooling specified in the repository.
diff --git a/subprojects/docs/src/develop/contributing/index.md b/subprojects/docs/src/develop/contributing/index.md
new file mode 100644
index 00000000..aa0bdb2f
--- /dev/null
+++ b/subprojects/docs/src/develop/contributing/index.md
@@ -0,0 +1,59 @@
1---
2SPDX-FileCopyrightText: 2024 The Refinery Authors
3SPDX-License-Identifier: EPL-2.0
4sidebar_position: 1
5title: Contributing
6---
7
8import TabItem from '@theme/TabItem';
9import Tabs from '@theme/Tabs';
10
11# Contributing to Refinery
12
13You can clone the refinery repository from GitHub at https://github.com/graphs4value/refinery.
14If you want to contribute code, we recommend [forking](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo) the repository on GitHub so that you can submit a [pull request](https://github.com/graphs4value/refinery/pulls) later.
15
16## Required tools
17
18Refinery is written in Java and TypeScript. To build Refinery, you'll need a **Java 21** compatible **Java Development Kit (JDK).** We recommend the [Adoptium Java 21 JDK](https://adoptium.net/) or the [Amazon Corretto Java 21 JDK](https://aws.amazon.com/corretto/).
19
20## Compiling Refinery {#compiling}
21
22To build Refinery, run the command
23```bash posix2windows
24./gradlew build
25```
26in the cloned repository.
27
28This should complete without any compilation errors.
29
30If you get any errors about the JVM version, check whether the `JAVA_HOME` environment variable is set to the location of **JDK 21**. You can query the variable with
31<Tabs groupId="posix2windows">
32 <TabItem value="posix" label="Linux or macOS">
33 ```bash
34 echo $JAVA_HOME
35 ```
36 </TabItem>
37 <TabItem value="windows" label="Windows (PowerShell)">
38 ```bash
39 echo $Env:JAVA_HOME
40 ```
41 </TabItem>
42</Tabs>
43To set the `JAVA_HOME` environmental variable, use
44<Tabs groupId="posix2windows">
45 <TabItem value="posix" label="Linux or macOS">
46 ```bash
47 export JAVA_HOME=/java/path/here
48 ```
49 </TabItem>
50 <TabItem value="windows" label="Windows (PowerShell)">
51 ```bash
52 $Env:JAVA_HOME="C:\java\path\here"
53 ```
54 </TabItem>
55</Tabs>
56
57If the build fails with a `Host name must not be empty` error, you [might need to remove the empty proxy configuration from your global `gradle.properties` file](https://stackoverflow.com/a/62128323).
58
59For further information, see the [supported build commands](/develop/contributing/commands) and the [instructions for setting up an IDE](/develop/contributing/ide-setup).
diff --git a/subprojects/docs/src/plugins/remarkPosix2Windows.ts b/subprojects/docs/src/plugins/remarkPosix2Windows.ts
new file mode 100644
index 00000000..66baca30
--- /dev/null
+++ b/subprojects/docs/src/plugins/remarkPosix2Windows.ts
@@ -0,0 +1,166 @@
1/*
2 * Copyright (c) Facebook, Inc. and its affiliates.
3 * Copyright (c) 2024 The Refinery Authors
4 *
5 * SPDX-License-Identifier: EPL-2.0
6 *
7 * This file is based on
8 * https://github.com/facebook/docusaurus/blob/e4ecffe41878728acff55a8370bd7440706c02f7/packages/docusaurus-remark-plugin-npm2yarn/src/index.ts
9 * but was changed to conver shell commands to POSIX to Windows syntax.
10 */
11
12import type { Code, Literal } from 'mdast';
13import type { MdxjsEsm, MdxJsxFlowElement } from 'mdast-util-mdx';
14import type { Transformer } from 'unified';
15import type { Node, Parent } from 'unist';
16import { visit } from 'unist-util-visit';
17
18function isLiteral(node: Node): node is Literal {
19 return node.type === 'mdxjsEsm';
20}
21
22function isTabImport(node: Node): boolean {
23 return isLiteral(node) && node.value.includes('@theme/Tabs');
24}
25
26function isParent(node: Node): node is Parent {
27 return 'children' in node && Array.isArray(node.children);
28}
29
30function isCode(node: Node): node is Code {
31 return node.type === 'code';
32}
33
34function isPosix2Windows(node: Node): node is Code {
35 return isCode(node) && node.meta === 'posix2windows';
36}
37
38function createTabItem(
39 code: string,
40 node: Code,
41 value: string,
42 label: string,
43): MdxJsxFlowElement {
44 return {
45 type: 'mdxJsxFlowElement',
46 name: 'TabItem',
47 attributes: [
48 {
49 type: 'mdxJsxAttribute',
50 name: 'value',
51 value,
52 },
53 {
54 type: 'mdxJsxAttribute',
55 name: 'label',
56 value: label,
57 },
58 ],
59 children: [
60 {
61 type: node.type,
62 lang: node.lang,
63 value: code,
64 },
65 ],
66 };
67}
68
69function transformNode(node: Code): MdxJsxFlowElement[] {
70 const posixCode = node.value;
71 const windowsCode = posixCode.replaceAll(/(?<=^\w*)\.\//gm, '.\\');
72 return [
73 {
74 type: 'mdxJsxFlowElement',
75 name: 'Tabs',
76 attributes: [
77 {
78 type: 'mdxJsxAttribute',
79 name: 'groupId',
80 value: 'posix2windows',
81 },
82 ],
83 children: [
84 createTabItem(posixCode, node, 'posix', 'Linux or macOS'),
85 createTabItem(windowsCode, node, 'windows', 'Windows (PowerShell)'),
86 ],
87 },
88 ];
89}
90
91function createImportNode(): MdxjsEsm {
92 return {
93 type: 'mdxjsEsm',
94 value:
95 "import Tabs from '@theme/Tabs'\nimport TabItem from '@theme/TabItem'",
96 data: {
97 estree: {
98 type: 'Program',
99 body: [
100 {
101 type: 'ImportDeclaration',
102 specifiers: [
103 {
104 type: 'ImportDefaultSpecifier',
105 local: { type: 'Identifier', name: 'Tabs' },
106 },
107 ],
108 source: {
109 type: 'Literal',
110 value: '@theme/Tabs',
111 raw: "'@theme/Tabs'",
112 },
113 },
114 {
115 type: 'ImportDeclaration',
116 specifiers: [
117 {
118 type: 'ImportDefaultSpecifier',
119 local: { type: 'Identifier', name: 'TabItem' },
120 },
121 ],
122 source: {
123 type: 'Literal',
124 value: '@theme/TabItem',
125 raw: "'@theme/TabItem'",
126 },
127 },
128 ],
129 sourceType: 'module',
130 },
131 },
132 };
133}
134
135export default function remarkPosix2Windows(): Transformer {
136 return (root) => {
137 let transformed = false;
138 let alreadyImported = false;
139 visit(root, (node) => {
140 if (isTabImport(node)) {
141 alreadyImported = true;
142 }
143 if (isParent(node)) {
144 let index = 0;
145 while (index < node.children.length) {
146 const child = node.children[index];
147 if (child !== undefined && isPosix2Windows(child)) {
148 const result = transformNode(child);
149 node.children.splice(index, 1, ...result);
150 index += result.length;
151 transformed = true;
152 } else {
153 index += 1;
154 }
155 }
156 }
157 });
158 if (transformed && !alreadyImported) {
159 if (isParent(root)) {
160 root.children.unshift(createImportNode());
161 } else {
162 throw new Error("Cannot import '@theme/Tabs'");
163 }
164 }
165 };
166}