mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2025-04-14 06:43:15 +00:00
WIP: ast transformers
This commit is contained in:
parent
3d2392dc70
commit
221193a587
68
plugins/tiddlywiki/editorjs/ast/wikiAstFromEditorJSAst.js
Normal file
68
plugins/tiddlywiki/editorjs/ast/wikiAstFromEditorJSAst.js
Normal file
@ -0,0 +1,68 @@
|
||||
/*\
|
||||
title: $:/plugins/tiddlywiki/editorjs/ast/wikiAstFromEditorJSAst.js
|
||||
type: application/javascript
|
||||
module-type: library
|
||||
|
||||
Get the EditorJS AST from a Wiki AST
|
||||
|
||||
\*/
|
||||
|
||||
|
||||
/**
|
||||
* Key is `node.type`, value is node converter function.
|
||||
*/
|
||||
const builders = {
|
||||
// auto parse basic element nodes
|
||||
// eslint-disable-next-line unicorn/prefer-object-from-entries
|
||||
...(htmlTags).reduce(
|
||||
(previousValue, currentValue) => {
|
||||
previousValue[currentValue] = element;
|
||||
return previousValue;
|
||||
},
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-reduce-type-parameter, @typescript-eslint/consistent-type-assertions
|
||||
{},
|
||||
),
|
||||
[ELEMENT_CODE_BLOCK]: codeblock,
|
||||
[ELEMENT_LIC]: lic,
|
||||
text,
|
||||
widget,
|
||||
macro: widget,
|
||||
set,
|
||||
};
|
||||
|
||||
function wikiAstFromEditorJSAst(input) {
|
||||
return convertNodes(builders, Array.isArray(input) ? input : [input]);
|
||||
}
|
||||
|
||||
exports.wikiAstFromEditorJSAst = wikiAstFromEditorJSAst;
|
||||
|
||||
function convertNodes(builders, nodes) {
|
||||
if (nodes === undefined || nodes.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return nodes.reduce((accumulator, node) => {
|
||||
return [...accumulator, ...convertWikiAstNode(builders, node)];
|
||||
}, []);
|
||||
}
|
||||
|
||||
function convertWikiAstNode(builders, node) {
|
||||
// only text and root node don't have a `type` field, deal with it first
|
||||
if (isText(node)) {
|
||||
return [builders.text(builders, node)];
|
||||
}
|
||||
if (isElement(node)) {
|
||||
const builder = builders[node.type];
|
||||
if (typeof builder === 'function') {
|
||||
const builtSlateNodeOrNodes = builder(builders, node);
|
||||
return Array.isArray(builtSlateNodeOrNodes)
|
||||
? builtSlateNodeOrNodes.map((child) => ({ ...getSlatePlateASTAdditionalProperties(node), ...child }))
|
||||
: ([{ ...getSlatePlateASTAdditionalProperties(node), ...builtSlateNodeOrNodes }]);
|
||||
}
|
||||
}
|
||||
// it might be a root or pure parent node, reduce it
|
||||
if ('children' in node) {
|
||||
return convertNodes(builders, node.children);
|
||||
}
|
||||
return [];
|
||||
}
|
83
plugins/tiddlywiki/editorjs/ast/wikiAstToEditorJSAst.js
Normal file
83
plugins/tiddlywiki/editorjs/ast/wikiAstToEditorJSAst.js
Normal file
@ -0,0 +1,83 @@
|
||||
/*\
|
||||
title: $:/plugins/tiddlywiki/editorjs/ast/wikiAstToEditorJSAst.js
|
||||
type: application/javascript
|
||||
module-type: library
|
||||
|
||||
Get the EditorJS AST from a Wiki AST
|
||||
|
||||
\*/
|
||||
function wikiAstToEditorJSAst(node, options) {
|
||||
return convertNodes({ ...initialContext, ...options }, Array.isArray(node) ? node : [node]);
|
||||
}
|
||||
|
||||
exports.wikiAstToEditorJSAst = wikiAstToEditorJSAst;
|
||||
|
||||
const initialContext = {
|
||||
builders,
|
||||
marks: {},
|
||||
};
|
||||
|
||||
function convertNodes(context, nodes) {
|
||||
if (nodes === undefined || nodes.length === 0) {
|
||||
return [{ text: '' }];
|
||||
}
|
||||
|
||||
return nodes.reduce((accumulator, node) => {
|
||||
return [...accumulator, ...editorJSNode(context, node)];
|
||||
}, []);
|
||||
}
|
||||
|
||||
function editorJSNode(context, node) {
|
||||
const id = context.idCreator?.();
|
||||
const withId = (nodeToAddId) => (id === undefined ? nodeToAddId : { ...nodeToAddId, id });
|
||||
if ('rule' in node && node.rule !== undefined && node.rule in context.builders) {
|
||||
const builder = context.builders[node.rule];
|
||||
if (typeof builder === 'function') {
|
||||
// basic elements
|
||||
const builtEditorJSNodeOrNodes = builder(context, node);
|
||||
return Array.isArray(builtEditorJSNodeOrNodes)
|
||||
? builtEditorJSNodeOrNodes.map((child) => withId(child))
|
||||
: ([withId(builtEditorJSNodeOrNodes)]);
|
||||
}
|
||||
} else if ('text' in node) {
|
||||
// text node
|
||||
return [withId({ text: node.text })];
|
||||
} else {
|
||||
console.warn(`WikiAst get Unknown node type: ${JSON.stringify(node)}`);
|
||||
return [];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
const builders = {
|
||||
element,
|
||||
text,
|
||||
};
|
||||
|
||||
/** Slate node is compact, we need to filter out some keys from wikiast */
|
||||
const textLevelKeysToOmit = ['type', 'start', 'end'];
|
||||
|
||||
function text(context, text) {
|
||||
return {
|
||||
text: '', // provides default text
|
||||
...omit(text, textLevelKeysToOmit),
|
||||
...context.marks,
|
||||
};
|
||||
}
|
||||
|
||||
const elementBuilders = { ul, ol: ul, li, ...marks };
|
||||
|
||||
function element(context, node) {
|
||||
const { tag, children } = node;
|
||||
if (typeof elementBuilders[tag] === 'function') {
|
||||
return elementBuilders[tag](context, node);
|
||||
}
|
||||
const result = {
|
||||
type: tag,
|
||||
children: convertNodes(context, children),
|
||||
};
|
||||
if (node.rule) {
|
||||
result.rule = node.rule;
|
||||
}
|
||||
return result;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user