Skip to content

Instantly share code, notes, and snippets.

@nelsonpecora
Created June 20, 2019 19:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nelsonpecora/708b962cc849d77b87e5460c8ce8a6ed to your computer and use it in GitHub Desktop.
Save nelsonpecora/708b962cc849d77b87e5460c8ce8a6ed to your computer and use it in GitHub Desktop.
Janky server-side rendering of prosemirror docs
const _ = require('lodash');
const cuid = require('cuid');
function renderText(renderBranch, renderLeaf) {
return (acc, node) => {
if (node.doc) {
return renderText(renderBranch, renderLeaf)(acc, node, node.doc);
} else if (node.content) {
return renderBranch(acc, node, node.content);
} else if (node.text) {
return renderLeaf(acc, node, node.text, node.marks);
} else {
return acc;
}
};
}
const toPlaintext = renderText(
(acc, node, childNodes) => acc + _.reduce(childNodes, toPlaintext, ''),
(acc, node, text) => acc + text
);
const toHTML = renderText(
(acc, node, childNodes) => acc + _.reduce(childNodes, toHTML, ''),
(acc, node, text, marks) => {
if (marks) {
return acc + marks.map((m) => `<${m.type}>`).join('') + text + marks.map((m) => `</${m.type}>`).join('');
} else {
return acc + text;
}
}
);
function getKindOfTexture(type) {
const kinds = {
em: 'style.italics',
strong: 'style.bold'
};
return kinds[type];
}
// Texture is a lossy format similar to Quill's deltas,
// where the text is represented by a flat string and nodes/marks
// are 'textures' that have start and end indices
const toTexture = renderText(
(acc, node, childNodes) => {
if (node.type === 'paragraph') {
acc.textures.push({
length: _.reduce(childNodes, (length, child) => length + child.text.length, 0),
kind: 'style.paragraph',
id: cuid(),
offset: acc.text.length
});
}
return _.reduce(childNodes, toTexture, acc);
},
(acc, node, text, marks) => {
if (marks) {
marks.forEach((mark) => {
acc.textures.push({
length: text.length,
kind: getKindOfTexture(mark.type),
id: cuid(),
offset: acc.text.length
});
});
}
acc.text += text;
return acc;
}
);
/**
* Render prosemirror's data model in various formats.
*
* @param {Object} field
* @param {string} format
* @return {string|Object}
*/
function renderTo(field, format) {
switch (format) {
case 'TEXT_RAW': return field;
case 'TEXT_HTML': return _.reduce([field], toHTML, '');
case 'TEXT_TEXTURE': return _.reduce([field], toTexture, {text: '', textures: []});
default: return _.reduce([field], toPlaintext, '');
}
}
module.exports.renderTo = renderTo;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment