3
0
mirror of https://github.com/larvit/adf-codec.git synced 2026-11-12 11:48:29 +01:00
Files
adf-codec/converter-comparison/compare.mjs
T

128 lines
5.8 KiB
JavaScript

import * as adf2markdown from "adf2markdown";
import * as adfCodec from "@larvit/adf-codec";
import * as adfConverter from "adf-converter";
import * as adfMd from "adf-md";
import * as adfToMarkdown from "adf-to-markdown";
import adfToMd from "adf-to-md";
import * as atlaskitJson from "@atlaskit/editor-json-transformer";
import * as atlaskitMarkdown from "@atlaskit/editor-markdown-transformer";
import { createRequire } from "node:module";
import * as extendedParser from "extended-markdown-adf-parser";
import * as faulander from "@faulander/md2adf";
import { fromADF } from "mdast-util-from-adf";
import * as githubMarkdownAdf from "github-markdown-adf";
import { isDeepStrictEqual } from "node:util";
import { loadAdf4j } from "@nthings.dev/adf4j-wasm";
import * as markdownToAdf from "markdown-to-adf";
import { markdownToJiraBlock } from "@wrtnlabs/markdown-to-adf";
import * as marklassian from "marklassian";
import * as mdAdf from "md-adf";
import mdToAdf from "md-to-adf";
import { toMarkdown as mdastToMarkdown } from "mdast-util-to-markdown";
import { readFileSync } from "node:fs";
const { defaultSchema } = createRequire(import.meta.url)("@atlaskit/adf-schema/schema-default");
const roundTripDoc = {
type: "doc", version: 1, content: [
{ type: "paragraph", content: [
{ type: "text", text: "bold italic", marks: [{ type: "strong" }, { type: "em" }] },
{ type: "text", text: " and " },
{ type: "text", text: "a link", marks: [{ type: "link", attrs: { href: "https://example.com" } }] },
{ type: "text", text: " hi " },
{ type: "mention", attrs: { id: "abc", text: "@Ann" } },
{ type: "text", text: " state " },
{ type: "status", attrs: { color: "green", localId: "s1", text: "DONE" } },
] },
{ type: "panel", attrs: { panelType: "info" }, content: [{ type: "paragraph", content: [{ type: "text", text: "note" }] }] },
{ type: "bulletList", content: [
{ type: "listItem", content: [{ type: "paragraph", content: [{ type: "text", text: "one" }] }] },
{ type: "listItem", content: [{ type: "paragraph", content: [{ type: "text", text: "two" }] }] },
] },
],
};
const unknownNodeDoc = {
type: "doc", version: 1, content: [
{ type: "paragraph", content: [{ type: "text", text: "before" }] },
{ type: "futureThing", attrs: { x: 1 }, content: [{ type: "paragraph", content: [{ type: "text", text: "inside" }] }] },
{ type: "paragraph", content: [{ type: "text", text: "after" }] },
],
};
const markdown = "***bold italic*** and [a link](https://example.com) hi @Ann\n\n> note\n\n- one\n- two\n";
const extended = new extendedParser.Parser();
const json = new atlaskitJson.JSONTransformer();
const atlaskit = new atlaskitMarkdown.MarkdownTransformer(defaultSchema);
const adf4j = await loadAdf4j();
const reported = (result) => {
for (const diagnostic of result.diagnostics) console.log("diagnostic:", JSON.stringify(diagnostic));
return result.value;
};
const succeeded = (result) => {
if (result.type !== "Success") throw new Error(JSON.stringify(result));
return result.value;
};
const converters = {
"@atlaskit/editor-markdown-transformer": {
toAdf: (md) => json.encode(atlaskit.parse(md)),
toMarkdown: (doc) => atlaskit.encode(json.parse(doc)),
},
"@faulander/md2adf": {
toAdf: (md) => faulander.markdownToAdf(md),
toMarkdown: (doc) => faulander.adfToMarkdown(doc),
},
"@larvit/adf-codec": {
toAdf: (md) => adfCodec.losslessMarkdownToAdf(md).value,
toMarkdown: (doc) => adfCodec.adfToLosslessMarkdown(doc).value,
},
"@nthings.dev/adf4j-wasm": { toMarkdown: (doc) => adf4j.convert(JSON.stringify(doc)) },
"@wrtnlabs/markdown-to-adf": { toAdf: (md) => markdownToJiraBlock(md) },
"adf-converter": { toMarkdown: (doc) => adfConverter.processADF(doc, adfConverter.markdownFormatter) },
"adf-md": {
toAdf: (md) => succeeded(adfMd.markdownToAdf(md)),
toMarkdown: (doc) => succeeded(adfMd.adfToMarkdown(doc)),
},
"adf-to-markdown": { toMarkdown: (doc) => adfToMarkdown.convertADFToMarkdown(doc) },
"adf-to-md": { toMarkdown: (doc) => adfToMd.convert(doc).result },
adf2markdown: { toMarkdown: (doc) => adf2markdown.adf2markdown(doc) },
"extended-markdown-adf-parser": {
toAdf: (md) => extended.markdownToAdf(md),
toMarkdown: (doc) => extended.adfToMarkdown(doc),
},
"github-markdown-adf": {
toAdf: (md) => githubMarkdownAdf.mdToAdf(md),
toMarkdown: (doc) => githubMarkdownAdf.adfToMd(doc),
},
"markdown-to-adf": { toAdf: (md) => markdownToAdf.markdownToAdf(md) },
marklassian: { toAdf: (md) => marklassian.markdownToAdf(md) },
"md-adf": {
toAdf: (md) => reported(mdAdf.markdownToAdf(md)),
toMarkdown: (doc) => reported(mdAdf.adfToMarkdown(doc)),
},
"md-to-adf": { toAdf: (md) => mdToAdf(md) },
"mdast-util-from-adf": { toMarkdown: (doc) => mdastToMarkdown(fromADF(doc)) },
};
const show = (label, call) => {
try {
const value = call();
console.log(`${label}:`, JSON.stringify(value));
return value;
} catch (error) {
console.log(`${label} threw:`, error.message);
}
};
for (const [name, { toAdf, toMarkdown }] of Object.entries(converters)) {
const manifest = JSON.parse(readFileSync(`node_modules/${name}/package.json`, "utf8"));
console.log(`\n## ${name} ${manifest.version}`);
console.log("direct runtime dependencies:", Object.keys(manifest.dependencies ?? {}).length);
const written = toMarkdown && show("ADF to markdown", () => toMarkdown(roundTripDoc));
if (written !== undefined && toAdf) {
const readBack = show("read back", () => toAdf(written));
if (readBack !== undefined) console.log("round-trip deep-equal:", isDeepStrictEqual(readBack, roundTripDoc));
}
const unknown = toMarkdown && show("unknown node to markdown", () => toMarkdown(unknownNodeDoc));
if (toAdf && unknown !== undefined) show("unknown node read back", () => toAdf(unknown));
if (toAdf) show("markdown to ADF", () => toAdf(markdown));
}