@jinntec/jinn-codemirror
Version:
Source code editor component based on codemirror with language support for XML and Leiden+
65 lines (56 loc) • 2.18 kB
text/typescript
import { lintGutter } from "@codemirror/lint";
import { Extension } from "@codemirror/state";
import { Command } from "@codemirror/view";
import { Tree } from "@lezer/common";
import { EditorCommands, EditorConfig, insertCommand, SourceType, wrapCommand } from "./config";
import { ancientText2XML } from "./import/ancientText2xml.js";
import { xml2leidenPlus } from "./import/xml2leiden+";
import { JinnCodemirror } from "./jinn-codemirror";
export function convertToLeidenPlus(text: string, type: SourceType): string | null {
const converted = ancientText2XML(text, type);
const xml = `<ab>${converted}\n</ab>`
const parser = new DOMParser();
const doc = parser.parseFromString(xml, 'application/xml');
if (!doc.firstElementChild) {
return '';
}
const errorNode = doc.querySelector('parsererror');
if (errorNode) {
return null;
}
return xml2leidenPlus(doc.firstElementChild);
}
export const convertToLeidenPlusCommand = (component: JinnCodemirror, type:SourceType):Command => (editor) => {
const lines = editor.state.doc.toJSON();
const leiden = convertToLeidenPlus(lines.join('\n'), type);
if (leiden) {
component._value = leiden;
component.mode = 'leiden_plus';
} else {
alert('Conversion failed due to invalid XML!');
}
return true;
};
const commands:EditorCommands = {
erasure: wrapCommand('[[', ']]'),
gap: insertCommand('[---]')
};
export class AncientTextConfig extends EditorConfig {
_sourceType: SourceType;
constructor(editor: JinnCodemirror, toolbar: HTMLElement[]|undefined = [], sourceType: SourceType) {
super(editor, toolbar, Object.assign(commands, {
convert: convertToLeidenPlusCommand(editor, sourceType)
}));
this._sourceType = sourceType;
}
async getExtensions(): Promise<Extension[]> {
return [lintGutter()];
}
onUpdate(tree: Tree, content: string): string {
const converted = ancientText2XML(content, this._sourceType);
return `<ab>\n${converted}\n</ab>`
}
serialize(): Element | string | null {
return this.editor.content;
}
}