@atlaskit/editor-wikimarkup-transformer
Version:
Wiki markup transformer for JIRA and Confluence
120 lines • 3.41 kB
JavaScript
import { commonMacro } from './common-macro';
import { hasAnyOfMarks } from '../utils/text';
import { normalizePMNodes } from '../utils/normalize';
import { parseString } from '../text';
export const quoteMacro = ({
input,
position,
schema,
context
}) => {
return commonMacro(input.substring(position), schema, {
keyword: 'quote',
paired: true,
rawContentProcessor,
context
});
};
export const rawContentProcessor = (_rawAttrs, rawContent, length, schema, context) => {
if (!rawContent.length) {
const emptyQuote = emptyBlockquote(schema);
return {
type: 'pmnode',
nodes: [emptyQuote],
length
};
}
const parsedContent = parseString({
schema,
context,
ignoreTokenTypes: [],
input: rawContent
});
const normalizedContent = normalizePMNodes(parsedContent, schema);
return {
type: 'pmnode',
nodes: sanitize(normalizedContent, schema),
length
};
};
function emptyBlockquote(schema) {
const p = schema.nodes.paragraph.createChecked({}, []);
return schema.nodes.blockquote.createChecked({}, p);
}
function sanitize(nodes, schema) {
const output = [];
let contentBuffer = [];
for (const n of nodes) {
switch (n.type.name) {
case 'paragraph':
case 'bulletList':
case 'orderedList':
case 'codeBlock':
case 'mediaSingle':
case 'mediaGroup':
{
/**
* blockquote supports nesting paragraphs, lists, codeblocks and media nodes
*/
contentBuffer.push(n);
break;
}
case 'heading':
{
/**
* If a heading is inside a list item
* - h1. Bold, Uppercase
* - h2. Bold, Italic
* - h3. Bold
* - h4. Bold, Gray
* - h5. Gray, Italic
* - h6. Gray
*/
contentBuffer.push(transformHeading(n, schema));
break;
}
default:
/**
* Anything else should be lifted
*/
if (contentBuffer.length) {
const blockquote = schema.nodes.blockquote.createChecked({}, contentBuffer);
output.push(blockquote);
contentBuffer = [];
}
output.push(n);
}
}
if (contentBuffer.length) {
const blockquote = schema.nodes.blockquote.createChecked({}, contentBuffer);
output.push(blockquote);
}
return output;
}
function transformHeading(heading, schema) {
const contentBuffer = [];
heading.content.forEach(n => {
const strong = schema.marks.strong.create();
const italic = schema.marks.em.create();
const gray = schema.marks.textColor.create({
color: '#97a0af'
});
if (n.type.name === 'text') {
if (n.text && heading.attrs.level === 1) {
// @ts-ignore assigning to readonly prop to transform text
n.text = n.text.toUpperCase();
}
if (heading.attrs.level <= 4 && !hasAnyOfMarks(n, ['strong', 'code'])) {
n = n.mark([...n.marks, strong]);
}
if ((heading.attrs.level === 5 || heading.attrs.level === 2) && !hasAnyOfMarks(n, ['em', 'code'])) {
n = n.mark([...n.marks, italic]);
}
if (heading.attrs.level > 3 && !hasAnyOfMarks(n, ['textColor', 'code'])) {
n = n.mark([...n.marks, gray]);
}
}
contentBuffer.push(n);
});
return schema.nodes.paragraph.createChecked({}, contentBuffer);
}