@adobe/helix-md2jcr 1.0.0
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 +15 -0
- package/CODE_OF_CONDUCT.md +74 -0
- package/CONTRIBUTING.md +74 -0
- package/LICENSE.txt +264 -0
- package/README.md +27 -0
- package/baseline-tests.sh +45 -0
- package/package.json +81 -0
- package/src/cli/convert2jcr.js +128 -0
- package/src/index.d.ts +16 -0
- package/src/index.js +15 -0
- package/src/md2jcr/index.d.ts +20 -0
- package/src/md2jcr/index.js +36 -0
- package/src/mdast2jcr/domain/Component.js +66 -0
- package/src/mdast2jcr/domain/Definitions.js +78 -0
- package/src/mdast2jcr/domain/FieldGroup.js +85 -0
- package/src/mdast2jcr/domain/FieldGroupFieldResolver.js +96 -0
- package/src/mdast2jcr/domain/ModelHelper.js +123 -0
- package/src/mdast2jcr/domain/Models.js +46 -0
- package/src/mdast2jcr/hast-table-cell-handler.js +48 -0
- package/src/mdast2jcr/hast-table-handler.js +126 -0
- package/src/mdast2jcr/hb/helpers/encode-helper.js +18 -0
- package/src/mdast2jcr/hb/helpers/name-helper.js +61 -0
- package/src/mdast2jcr/hb/helpers/page-helper.js +109 -0
- package/src/mdast2jcr/hb/helpers/section-helper.js +53 -0
- package/src/mdast2jcr/hb/helpers/which-partial-helper.js +22 -0
- package/src/mdast2jcr/hb/partials/blockquote.js +16 -0
- package/src/mdast2jcr/hb/partials/emphasis.js +34 -0
- package/src/mdast2jcr/hb/partials/grid-table.js +495 -0
- package/src/mdast2jcr/hb/partials/heading.js +53 -0
- package/src/mdast2jcr/hb/partials/image.js +24 -0
- package/src/mdast2jcr/hb/partials/link.js +33 -0
- package/src/mdast2jcr/hb/partials/paragraph.js +30 -0
- package/src/mdast2jcr/hb/partials/strong.js +33 -0
- package/src/mdast2jcr/hb/partials/supports/image.js +27 -0
- package/src/mdast2jcr/hb/partials/supports/link.js +46 -0
- package/src/mdast2jcr/hb/partials/table.js +16 -0
- package/src/mdast2jcr/index.d.ts +122 -0
- package/src/mdast2jcr/index.js +94 -0
- package/src/mdast2jcr/mdast-download-images.js +165 -0
- package/src/mdast2jcr/mdast-sanitize-html.js +233 -0
- package/src/mdast2jcr/templates/page-template.js +27 -0
- package/src/mdast2jcr/utils/mdast.js +47 -0
- package/src/mdast2jcr/utils.js +233 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2024 Adobe. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @typedef {import('../mdast2jcr/index.d.ts').ModelDef} Model
|
|
15
|
+
* @typedef {import('../mdast2jcr/index.d.ts').DefinitionDef} Definition
|
|
16
|
+
* @typedef {import('../mdast2jcr/index.d.ts').CollapsedFields} CollapsedFields
|
|
17
|
+
* @typedef {import('../mdast2jcr/index.d.ts').FieldDef} Field
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Get the model id from the array of models.
|
|
22
|
+
* @param {Array<Model>} models The array of models.
|
|
23
|
+
* @param {string} modelId The model id.
|
|
24
|
+
* @return {Model}
|
|
25
|
+
*/
|
|
26
|
+
function findModelById(models, modelId) {
|
|
27
|
+
if (!models || Object.keys(models)?.length === 0) {
|
|
28
|
+
throw new Error('No models are provided. Check your model\'s JSON file.');
|
|
29
|
+
}
|
|
30
|
+
return models.find((model) => model.id === modelId);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Given a model, return the field with the given name.
|
|
35
|
+
* @param {Model} model The model.
|
|
36
|
+
* @param {string} fieldName The name of the field to get.
|
|
37
|
+
* @return {Field} field The field or undefined if not found.
|
|
38
|
+
*/
|
|
39
|
+
function getField(model, fieldName) {
|
|
40
|
+
return model.fields.find((field) => field.name === fieldName);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export {
|
|
44
|
+
getField,
|
|
45
|
+
findModelById,
|
|
46
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2022 Adobe. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/*
|
|
14
|
+
copied and adapted (adding align) from
|
|
15
|
+
https://github.com/syntax-tree/hast-util-to-mdast/blob/main/lib/handlers/table-cell.js
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
'use strict';
|
|
19
|
+
|
|
20
|
+
export default function cell(state, node) {
|
|
21
|
+
const wrap = state.wrapText;
|
|
22
|
+
|
|
23
|
+
// eslint-disable-next-line no-param-reassign
|
|
24
|
+
state.wrapText = false;
|
|
25
|
+
|
|
26
|
+
const result = {
|
|
27
|
+
type: 'tableCell',
|
|
28
|
+
children: state.all(node),
|
|
29
|
+
};
|
|
30
|
+
state.patch(node, result);
|
|
31
|
+
|
|
32
|
+
if (node.properties?.rowSpan || node.properties?.colSpan || node.properties?.align) {
|
|
33
|
+
const data = result.data || (result.data = {});
|
|
34
|
+
if (node.properties.rowSpan) {
|
|
35
|
+
data.rowSpan = node.properties.rowSpan;
|
|
36
|
+
}
|
|
37
|
+
if (node.properties.colSpan) {
|
|
38
|
+
data.colSpan = node.properties.colSpan;
|
|
39
|
+
}
|
|
40
|
+
if (node.properties.align) {
|
|
41
|
+
data.align = node.properties.align;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// eslint-disable-next-line no-param-reassign
|
|
45
|
+
state.wrapText = wrap;
|
|
46
|
+
|
|
47
|
+
return result;
|
|
48
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2021 Adobe. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
'use strict';
|
|
14
|
+
|
|
15
|
+
/*
|
|
16
|
+
copied and adapted from
|
|
17
|
+
https://github.com/syntax-tree/hast-util-to-mdast/blob/main/lib/handlers/table.js
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
// Ensure the cells in a row are properly structured.
|
|
21
|
+
function toCells(children) {
|
|
22
|
+
const nodes = [];
|
|
23
|
+
let queue;
|
|
24
|
+
|
|
25
|
+
children.forEach((node) => {
|
|
26
|
+
if (node.type === 'tableCell') {
|
|
27
|
+
if (queue) {
|
|
28
|
+
// eslint-disable-next-line no-param-reassign
|
|
29
|
+
node.children = queue.concat(node.children);
|
|
30
|
+
queue = undefined;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
nodes.push(node);
|
|
34
|
+
} else {
|
|
35
|
+
if (!queue) {
|
|
36
|
+
queue = [];
|
|
37
|
+
}
|
|
38
|
+
queue.push(node);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
if (queue) {
|
|
43
|
+
let node = nodes[nodes.length - 1];
|
|
44
|
+
|
|
45
|
+
if (!node) {
|
|
46
|
+
node = { type: 'tableCell', children: [] };
|
|
47
|
+
nodes.push(node);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
node.children = node.children.concat(queue);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return nodes;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Ensure the rows are properly structured.
|
|
57
|
+
function toRows(children) {
|
|
58
|
+
const nodes = [];
|
|
59
|
+
let queue;
|
|
60
|
+
|
|
61
|
+
children.forEach((node) => {
|
|
62
|
+
if (node.type === 'tableRow') {
|
|
63
|
+
if (queue) {
|
|
64
|
+
// eslint-disable-next-line no-param-reassign
|
|
65
|
+
node.children = queue.concat(node.children);
|
|
66
|
+
queue = undefined;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
nodes.push(node);
|
|
70
|
+
} else {
|
|
71
|
+
if (!queue) queue = [];
|
|
72
|
+
queue.push(node);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
if (queue) {
|
|
77
|
+
const node = nodes[nodes.length - 1];
|
|
78
|
+
node.children = node.children.concat(queue);
|
|
79
|
+
}
|
|
80
|
+
nodes.forEach((node) => {
|
|
81
|
+
// eslint-disable-next-line no-param-reassign
|
|
82
|
+
node.children = toCells(node.children);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
return nodes;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export default function table(state, node) {
|
|
89
|
+
const mdNode = {
|
|
90
|
+
type: 'table',
|
|
91
|
+
children: toRows(state.all(node)),
|
|
92
|
+
// clean up table in respect to row and colspan and compute alignments
|
|
93
|
+
align: [],
|
|
94
|
+
maxCols: 0,
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
// compute the number of cells in each row, respecting the row and col spans.
|
|
98
|
+
const pendingRowSpans = [];
|
|
99
|
+
for (const row of mdNode.children) {
|
|
100
|
+
row.numCols = pendingRowSpans.shift() || 0;
|
|
101
|
+
for (const cell of row.children) {
|
|
102
|
+
const rowSpan = Number.parseInt(cell.data?.rowSpan || '1', 10);
|
|
103
|
+
const colSpan = Number.parseInt(cell.data?.colSpan || '1', 10);
|
|
104
|
+
if (cell.data?.align && !mdNode.align[row.numCols]) {
|
|
105
|
+
mdNode.align[row.numCols] = cell.data.align;
|
|
106
|
+
}
|
|
107
|
+
row.numCols += colSpan;
|
|
108
|
+
if (rowSpan > 1) {
|
|
109
|
+
for (let i = 0; i < rowSpan - 1; i += 1) {
|
|
110
|
+
pendingRowSpans[i] = (pendingRowSpans[i] || 0) + colSpan;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
mdNode.maxCols = Math.max(mdNode.maxCols, row.numCols);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// add empty cells if needed
|
|
118
|
+
for (const row of mdNode.children) {
|
|
119
|
+
for (let i = row.numCols; i < mdNode.maxCols; i += 1) {
|
|
120
|
+
row.children.push({ type: 'tableCell', children: [] });
|
|
121
|
+
}
|
|
122
|
+
delete row.numCols;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return mdNode;
|
|
126
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2024 Adobe. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
import Handlebars from 'handlebars';
|
|
13
|
+
|
|
14
|
+
function encodeHelper(options) {
|
|
15
|
+
return Handlebars.Utils.escapeExpression(options.fn(this));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export default encodeHelper;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2024 Adobe. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* An object that keeps track of the number of times a certain node has been
|
|
15
|
+
* added. Each time a node is added, the counter is incremented, thereby
|
|
16
|
+
* generating a unique name for the node.
|
|
17
|
+
*/
|
|
18
|
+
const nameCounter = [];
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The name helper function keeps track of the number of times a certain node
|
|
22
|
+
* has been created, and returns a unique name for it. The format of the name
|
|
23
|
+
* is the name of the node followed by an underscore and a number. For example,
|
|
24
|
+
* if the name of the node is 'title', the first node will have no underscore or
|
|
25
|
+
* number. A second occurrence of the node will have the name '_1', and so on.
|
|
26
|
+
*
|
|
27
|
+
* Special handling is done for the 'section' node. The 'section' node is treated
|
|
28
|
+
* as a top level node, and the name counter is reset each time a 'section' node.
|
|
29
|
+
*
|
|
30
|
+
* @param name The node name (e.g. 'title', 'section')
|
|
31
|
+
* @returns {string} The unique name for the node (e.g. '', '_1', '_2')
|
|
32
|
+
* or an empty string if the node is unique.
|
|
33
|
+
*/
|
|
34
|
+
function nameHelper(name) {
|
|
35
|
+
// reset the name counter if the node is a section or if the name counter is empty
|
|
36
|
+
// we could reset the name counter and empty all the counters, but it's cool
|
|
37
|
+
// to see the counts for debugging
|
|
38
|
+
if (name === 'section' || !nameCounter.length) {
|
|
39
|
+
nameCounter.push({});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// treat sections as a top level node and return the length of the name counter
|
|
43
|
+
if (name === 'section') {
|
|
44
|
+
return nameCounter.length > 1 ? `_${nameCounter.length - 1}` : '';
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// get the current counter
|
|
48
|
+
const currentCounter = nameCounter[nameCounter.length - 1];
|
|
49
|
+
|
|
50
|
+
// increment the counter for the node name
|
|
51
|
+
currentCounter[name] = (currentCounter[name] || 0) + 1;
|
|
52
|
+
|
|
53
|
+
// return the counter value if it is greater than 1 (the node is not unique)
|
|
54
|
+
return currentCounter[name] > 1 ? `_${currentCounter[name] - 1}` : '';
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function nameReset() {
|
|
58
|
+
nameCounter.length = 0;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export default nameHelper;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2024 Adobe. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
import { find } from 'unist-util-find';
|
|
13
|
+
import { toString } from 'mdast-util-to-string';
|
|
14
|
+
import { findModelById, getField } from '../../domain/Models.js';
|
|
15
|
+
import { findAll } from '../../utils/mdast.js';
|
|
16
|
+
import { encodeHTMLEntities, stripNewlines } from '../../utils.js';
|
|
17
|
+
import link from '../partials/supports/link.js';
|
|
18
|
+
import image from '../partials/supports/image.js';
|
|
19
|
+
|
|
20
|
+
function buildPageMetadata(table, models) {
|
|
21
|
+
const aemMapping = {
|
|
22
|
+
description: 'jcr:description',
|
|
23
|
+
canonical: 'cq:canonicalUrl',
|
|
24
|
+
robots: 'cq:robotsTags',
|
|
25
|
+
title: 'jcr:title',
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const model = findModelById(models, 'page-metadata');
|
|
29
|
+
|
|
30
|
+
const isMultiField = (fieldName) => {
|
|
31
|
+
const field = getField(model, fieldName.name);
|
|
32
|
+
return field && (field.component === 'multiselect' || field.component === 'aem-tag' || field.component === 'checkbox-group' || field.multi);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const metadata = {};
|
|
36
|
+
const [, ...rows] = findAll(table, (node) => node.type === 'gtRow', false);
|
|
37
|
+
rows.forEach((row) => {
|
|
38
|
+
const cells = findAll(row, (node) => node.type === 'gtCell', true);
|
|
39
|
+
const key = toString(cells[0]);
|
|
40
|
+
|
|
41
|
+
// if the model has the field, then add it to the metadata
|
|
42
|
+
const field = getField(model, key);
|
|
43
|
+
if (field) {
|
|
44
|
+
// if the field is an image then we need to dig into the row to find the image
|
|
45
|
+
if (find(row.children[1], { type: 'image' })) {
|
|
46
|
+
const { url } = image.getProperties(row);
|
|
47
|
+
metadata['xwalk:imageReference'] = url;
|
|
48
|
+
} else if (link.supports(row)) {
|
|
49
|
+
const { href } = link.getProperties(row);
|
|
50
|
+
metadata[field.name] = href;
|
|
51
|
+
} else {
|
|
52
|
+
let value = stripNewlines(cells[1]);
|
|
53
|
+
if (isMultiField(field)) {
|
|
54
|
+
value = value.split(',').map((v) => encodeHTMLEntities(v.trim()));
|
|
55
|
+
value = value.length > 0 ? `[${value.join(',')}]` : '';
|
|
56
|
+
}
|
|
57
|
+
metadata[field.name] = value;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// now go through the metadata and map the fields to aem fields
|
|
63
|
+
const mappedMetadata = {};
|
|
64
|
+
Object.entries(metadata).forEach(([key, value]) => {
|
|
65
|
+
const mappedKey = aemMapping[key] || key;
|
|
66
|
+
mappedMetadata[mappedKey] = value;
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
return mappedMetadata;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function pageHelper(options) {
|
|
73
|
+
const {
|
|
74
|
+
models,
|
|
75
|
+
...mdast
|
|
76
|
+
} = options.data.root;
|
|
77
|
+
|
|
78
|
+
const attributes = {
|
|
79
|
+
'cq:template': '/libs/core/franklin/templates/page',
|
|
80
|
+
'sling:resourceType': 'core/franklin/components/page/v1/page',
|
|
81
|
+
'jcr:primaryType': 'cq:PageContent',
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const tables = findAll(mdast, (node) => node.type === 'gridTable', false);
|
|
85
|
+
if (tables) {
|
|
86
|
+
tables.forEach((table) => {
|
|
87
|
+
const cell = find(table, { type: 'gtCell' });
|
|
88
|
+
if (cell) {
|
|
89
|
+
const isMetadata = toString(cell).toLowerCase() === 'metadata';
|
|
90
|
+
if (isMetadata) {
|
|
91
|
+
const meta = buildPageMetadata(table, models, attributes);
|
|
92
|
+
Object.assign(attributes, meta);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// pull the image reference out of the attributes
|
|
99
|
+
const { 'xwalk:imageReference': imageRef, ...properties } = attributes;
|
|
100
|
+
const attributesStr = Object.entries(properties).map(([k, v]) => `${k}="${v}"`).join(' ');
|
|
101
|
+
|
|
102
|
+
return `<jcr:content ${attributesStr}>
|
|
103
|
+
${options.fn(this)}
|
|
104
|
+
${imageRef ? `<image jcr:primaryType="nt:unstructured" fileReference="${imageRef}" />` : ''}
|
|
105
|
+
</jcr:content>
|
|
106
|
+
`;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export default pageHelper;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2024 Adobe. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
import Handlebars from 'handlebars';
|
|
13
|
+
import { find } from 'unist-util-find';
|
|
14
|
+
import { toString } from 'mdast-util-to-string';
|
|
15
|
+
import { findAll } from '../../utils/mdast.js';
|
|
16
|
+
|
|
17
|
+
function sectionHelper(index, children, options) {
|
|
18
|
+
const attributes = {
|
|
19
|
+
'sling:resourceType': 'core/franklin/components/section/v1/section',
|
|
20
|
+
'jcr:primaryType': 'nt:unstructured',
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const uniqueName = Handlebars.helpers.nameHelper.call(this, 'section');
|
|
24
|
+
|
|
25
|
+
// find the table that has a gtHeader that has a header value that contains 'section-metadata'
|
|
26
|
+
for (const child of children) {
|
|
27
|
+
if (child.type === 'gridTable') {
|
|
28
|
+
const cell = find(child, { type: 'gtCell' });
|
|
29
|
+
if (cell) {
|
|
30
|
+
const isMetadata = toString(cell).toLowerCase().replaceAll(' ', '-') === 'section-metadata';
|
|
31
|
+
if (isMetadata) {
|
|
32
|
+
const [, ...rows] = findAll(child, (n) => n.type === 'gtRow', false);
|
|
33
|
+
for (const row of rows) {
|
|
34
|
+
const cells = findAll(row, (n) => n.type === 'gtCell', true);
|
|
35
|
+
const key = toString(cells[0]);
|
|
36
|
+
const value = toString(cells[1]);
|
|
37
|
+
if (key === 'Style') {
|
|
38
|
+
attributes.classes = value;
|
|
39
|
+
} else {
|
|
40
|
+
attributes[`data-${key.toLowerCase().replaceAll(' ', '-')}`] = value;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const attributesStr = Object.entries(attributes).map(([k, v]) => `${k}="${v}"`).join(' ');
|
|
50
|
+
return `<section${uniqueName} ${attributesStr}>${options.fn(this)}</section${uniqueName}>`;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export default sectionHelper;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2024 Adobe. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Partial Resolver will return the partial helper that's associated with the
|
|
14
|
+
* type.
|
|
15
|
+
* @param type the type of partial
|
|
16
|
+
* @returns {string} the partial type
|
|
17
|
+
*/
|
|
18
|
+
function whichPartialHelper(type) {
|
|
19
|
+
return type;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default whichPartialHelper;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2024 Adobe. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
function blockQuotePartial() {
|
|
13
|
+
return '<section></section>\n';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export default blockQuotePartial;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2024 Adobe. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import Handlebars from 'handlebars';
|
|
14
|
+
|
|
15
|
+
function emphasis(context) {
|
|
16
|
+
const uniqueName = Handlebars.helpers.nameHelper.call(context, 'button');
|
|
17
|
+
const { children: [child] } = context;
|
|
18
|
+
const { title, url, children: [{ value }] } = child;
|
|
19
|
+
const attributes = {
|
|
20
|
+
'sling:resourceType': 'core/franklin/components/button/v1/button',
|
|
21
|
+
'jcr:primaryType': 'nt:unstructured',
|
|
22
|
+
link: url,
|
|
23
|
+
linkText: value,
|
|
24
|
+
linkType: 'secondary',
|
|
25
|
+
};
|
|
26
|
+
if (title != null) {
|
|
27
|
+
attributes.linkTitle = title;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const attributesStr = Object.entries(attributes).map(([k, v]) => `${k}="${v}"`).join(' ');
|
|
31
|
+
return `<button${uniqueName} ${attributesStr} />`;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export default emphasis;
|