@telefonica/markdown-confluence-sync
Version:
Creates/updates/deletes Confluence pages based on markdown files in a directory. Supports Mermaid diagrams and per-page configuration using frontmatter metadata. Works great with Docusaurus
80 lines (79 loc) • 2.83 kB
JavaScript
// SPDX-FileCopyrightText: 2024 Telefónica Innovación Digital
// SPDX-License-Identifier: Apache-2.0
import { dirname, resolve } from "path";
import { toString as hastToString } from "hast-util-to-string";
import { replace } from "../../../../support/unist/unist-util-replace.js";
function checkAnchors(node) {
return node.type === "element" && node.tagName === "a";
}
function composeChildren(node) {
if (node.children.length === 0) {
return [];
}
const firstChild = {
type: "element",
tagName: "span",
children: node.children,
};
return [
{
type: "element",
tagName: "ac:plain-text-link-body",
children: [
{
type: "raw",
value: `<![CDATA[${hastToString(firstChild)}]]>`,
},
],
},
];
}
/**
* UnifiedPlugin to replace internal references in Confluence Storage Format
*
* @see {@link https://developer.atlassian.com/server/confluence/confluence-storage-format/ | Confluence Storage Format }
*/
const rehypeConfluenceStorage = function rehypeConfluenceStorage({ spaceKey, pages, removeMissing }) {
return function transformer(tree, file) {
replace(tree, checkAnchors, (node) => {
if (typeof node.properties?.href !== "string") {
file.message("Internal reference without href", node.position);
return node;
}
// Skip external references
if (!node.properties.href.startsWith(".")) {
return node;
}
const referencedPagePath = resolve(dirname(file.path), node.properties.href);
const referencedPage = pages.get(referencedPagePath);
if (referencedPage === undefined) {
file.message("Internal reference to non-existing page", node.position);
return removeMissing === true
? {
type: "element",
tagName: "span",
children: node.children,
}
: node;
}
const children = composeChildren(node);
return {
type: "element",
tagName: "ac:link",
children: [
{
type: "element",
tagName: "ri:page",
properties: {
"ri:content-title": referencedPage.title,
"ri:space-key": spaceKey,
},
children: [],
},
...children,
],
};
});
};
};
export default rehypeConfluenceStorage;