@adobe/helix-md2jcr 1.2.0 → 1.2.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/CHANGELOG.md +7 -0
- package/README.md +19 -0
- package/bin/md2jcr.js +111 -29
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
## [1.2.1](https://github.com/adobe/helix-md2jcr/compare/v1.2.0...v1.2.1) (2025-10-06)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* cli specify the folder to look for the json files in ([b7664fe](https://github.com/adobe/helix-md2jcr/commit/b7664fe1b5a8781218e8585649cb1d0bc099cdbc))
|
|
7
|
+
|
|
1
8
|
# [1.2.0](https://github.com/adobe/helix-md2jcr/compare/v1.1.38...v1.2.0) (2025-10-06)
|
|
2
9
|
|
|
3
10
|
|
package/README.md
CHANGED
|
@@ -60,8 +60,27 @@ md2jcr test/fixtures/simple.md -v
|
|
|
60
60
|
md2jcr test/fixtures/simple.md -v -d
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
+
**Use custom Universal Editor files from a directory:**
|
|
64
|
+
```bash
|
|
65
|
+
md2jcr content.md -ue path/to/ue-files-directory
|
|
66
|
+
```
|
|
67
|
+
|
|
63
68
|
The converter will generate a `.xml` file alongside the markdown file containing the JCR structure. This can be used to check for potential content changes due to conversion.
|
|
64
69
|
|
|
70
|
+
#### Command-Line Options
|
|
71
|
+
|
|
72
|
+
- `-v`, `--verbose` - Print the XML output to the console
|
|
73
|
+
- `-d`, `--decode` - Decode HTML entities in the XML output (use with `-v`)
|
|
74
|
+
- `-ue`, `--ue-files <directory>` - Specify a directory containing Universal Editor configuration files
|
|
75
|
+
|
|
76
|
+
Example directory structure:
|
|
77
|
+
```
|
|
78
|
+
ue-files/
|
|
79
|
+
├── component-models.json
|
|
80
|
+
├── component-definition.json
|
|
81
|
+
└── component-filters.json
|
|
82
|
+
```
|
|
83
|
+
|
|
65
84
|
### Programmatic Usage
|
|
66
85
|
|
|
67
86
|
You can also use the library programmatically in your Node.js code:
|
package/bin/md2jcr.js
CHANGED
|
@@ -43,10 +43,16 @@ async function readJsonFile(filePath) {
|
|
|
43
43
|
* @param mdFile {string} The path to the markdown file.
|
|
44
44
|
* @param verbose - if true the XML will be printed to the console.
|
|
45
45
|
* @param decodeXML - if true a file with the decoded XML will be created.
|
|
46
|
+
* @param ueFilesDir - optional path to directory containing UE files (models, definitions, filters)
|
|
46
47
|
* @returns {Promise<void>} A promise that resolves when the conversion is
|
|
47
48
|
* complete, or rejects if the file is not a markdown file.
|
|
48
49
|
*/
|
|
49
|
-
async function convert(
|
|
50
|
+
async function convert(
|
|
51
|
+
mdFile,
|
|
52
|
+
verbose = false,
|
|
53
|
+
decodeXML = false,
|
|
54
|
+
ueFilesDir = null,
|
|
55
|
+
) {
|
|
50
56
|
if (!mdFile.endsWith('.md')) {
|
|
51
57
|
return Promise.reject(new Error('File must be a markdown file'));
|
|
52
58
|
}
|
|
@@ -59,32 +65,68 @@ async function convert(mdFile, verbose = false, decodeXML = false) {
|
|
|
59
65
|
let definitionJson;
|
|
60
66
|
let filtersJson;
|
|
61
67
|
|
|
62
|
-
|
|
68
|
+
// Use provided UE files directory if specified
|
|
69
|
+
if (ueFilesDir) {
|
|
70
|
+
const ueDir = path.resolve(process.cwd(), ueFilesDir);
|
|
71
|
+
|
|
72
|
+
// Try to load models.json
|
|
73
|
+
const modelsPath = path.resolve(ueDir, 'component-models.json');
|
|
74
|
+
const loadedModels = await readJsonFile(modelsPath);
|
|
75
|
+
modelJson = Array.isArray(loadedModels) ? loadedModels : loadedModels.models;
|
|
76
|
+
|
|
77
|
+
// Try to load definitions.json
|
|
78
|
+
const definitionsPath = path.resolve(ueDir, 'component-definition.json');
|
|
79
|
+
const loadedDefinitions = await readJsonFile(definitionsPath);
|
|
80
|
+
if (loadedDefinitions.groups) {
|
|
81
|
+
definitionJson = loadedDefinitions;
|
|
82
|
+
} else if (loadedDefinitions.definitions) {
|
|
83
|
+
// Wrap definitions in the expected structure
|
|
84
|
+
definitionJson = {
|
|
85
|
+
groups: [
|
|
86
|
+
{
|
|
87
|
+
title: 'Blocks',
|
|
88
|
+
id: 'blocks',
|
|
89
|
+
components: loadedDefinitions.definitions,
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
};
|
|
93
|
+
} else {
|
|
94
|
+
definitionJson = loadedDefinitions;
|
|
95
|
+
}
|
|
63
96
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
await
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
97
|
+
// Try to load filters.json
|
|
98
|
+
const filtersPath = path.resolve(ueDir, 'component-filters.json');
|
|
99
|
+
const loadedFilters = await readJsonFile(filtersPath);
|
|
100
|
+
filtersJson = Array.isArray(loadedFilters) ? loadedFilters : loadedFilters.filters;
|
|
101
|
+
} else {
|
|
102
|
+
// Fall back to automatic discovery
|
|
103
|
+
const blockDefinitionsPath = path.resolve(dir, `_${base}.json`);
|
|
104
|
+
|
|
105
|
+
// check to see if the blockFiles exists
|
|
106
|
+
try {
|
|
107
|
+
await stat(blockDefinitionsPath);
|
|
108
|
+
const blockDefinitionFile = await readJsonFile(path.resolve(dir, `_${base}.json`));
|
|
109
|
+
modelJson = blockDefinitionFile.models;
|
|
110
|
+
definitionJson = {
|
|
111
|
+
groups: [
|
|
112
|
+
{
|
|
113
|
+
title: 'Blocks',
|
|
114
|
+
id: 'blocks',
|
|
115
|
+
components: [
|
|
116
|
+
...blockDefinitionFile.definitions,
|
|
117
|
+
],
|
|
118
|
+
},
|
|
119
|
+
],
|
|
120
|
+
};
|
|
121
|
+
filtersJson = blockDefinitionFile.filters;
|
|
122
|
+
} catch (err) {
|
|
123
|
+
const modelFile = path.resolve(dir, `${base}-models.json`);
|
|
124
|
+
const definitionFile = path.resolve(dir, `${base}-definitions.json`);
|
|
125
|
+
const filtersFile = path.resolve(dir, `${base}-filters.json`);
|
|
126
|
+
modelJson = await readJsonFile(modelFile);
|
|
127
|
+
definitionJson = await readJsonFile(definitionFile);
|
|
128
|
+
filtersJson = await readJsonFile(filtersFile);
|
|
129
|
+
}
|
|
88
130
|
}
|
|
89
131
|
|
|
90
132
|
const md = await readFile(mdFile, 'utf-8');
|
|
@@ -109,14 +151,47 @@ async function convert(mdFile, verbose = false, decodeXML = false) {
|
|
|
109
151
|
return writeFile(fileJcrXML, xml);
|
|
110
152
|
}
|
|
111
153
|
|
|
154
|
+
/**
|
|
155
|
+
* Parse command-line arguments
|
|
156
|
+
* @returns {object} Parsed arguments
|
|
157
|
+
*/
|
|
158
|
+
function parseArgs() {
|
|
159
|
+
const args = {
|
|
160
|
+
path: null,
|
|
161
|
+
verbose: false,
|
|
162
|
+
decode: false,
|
|
163
|
+
ueFilesDir: null,
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
for (let i = 2; i < process.argv.length; i += 1) {
|
|
167
|
+
const arg = process.argv[i];
|
|
168
|
+
|
|
169
|
+
if (arg === '-v' || arg === '--verbose') {
|
|
170
|
+
args.verbose = true;
|
|
171
|
+
} else if (arg === '-d' || arg === '--decode') {
|
|
172
|
+
args.decode = true;
|
|
173
|
+
} else if (arg === '-ue' || arg === '--ue-files') {
|
|
174
|
+
args.ueFilesDir = process.argv[i + 1];
|
|
175
|
+
i += 1;
|
|
176
|
+
} else if (!arg.startsWith('-')) {
|
|
177
|
+
args.path = arg;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return args;
|
|
182
|
+
}
|
|
183
|
+
|
|
112
184
|
/**
|
|
113
185
|
* Entry point to convert a markdown file to JCR XML.
|
|
114
186
|
* @param inPath {string} The path to the markdown file or directory containing
|
|
115
187
|
* markdown files.
|
|
188
|
+
* @param verbose {boolean} If true, print output to console
|
|
189
|
+
* @param htmlDecode {boolean} If true, decode HTML entities in output
|
|
190
|
+
* @param ueFilesDir {string|null} Optional path to directory containing UE files
|
|
116
191
|
* @returns {Promise<void>} A promise that resolves when the conversion is
|
|
117
192
|
* complete.
|
|
118
193
|
*/
|
|
119
|
-
async function run(inPath) {
|
|
194
|
+
export async function run(inPath, verbose, htmlDecode, ueFilesDir) {
|
|
120
195
|
const dirOrFilePath = path.resolve(process.cwd(), inPath);
|
|
121
196
|
|
|
122
197
|
const files = [];
|
|
@@ -130,8 +205,15 @@ async function run(inPath) {
|
|
|
130
205
|
}
|
|
131
206
|
|
|
132
207
|
for (const file of files) {
|
|
133
|
-
await convert(file,
|
|
208
|
+
await convert(file, verbose, htmlDecode, ueFilesDir);
|
|
134
209
|
}
|
|
135
210
|
}
|
|
136
211
|
|
|
137
|
-
|
|
212
|
+
const args = parseArgs();
|
|
213
|
+
|
|
214
|
+
run(
|
|
215
|
+
args.path || process.cwd(),
|
|
216
|
+
args.verbose,
|
|
217
|
+
args.decode,
|
|
218
|
+
args.ueFilesDir,
|
|
219
|
+
).catch(console.error);
|