mirror of
https://github.com/amitwh/markdown-converter.git
synced 2026-08-02 18:10:18 +05:30
143 lines
4.4 KiB
JavaScript
143 lines
4.4 KiB
JavaScript
// CodeMirror 6 wrapper module
|
|
// Provides createEditor() and getLanguageExtension() for the rest of the app.
|
|
|
|
const {
|
|
EditorView,
|
|
keymap,
|
|
lineNumbers,
|
|
highlightActiveLine,
|
|
drawSelection,
|
|
} = require('@codemirror/view');
|
|
const { EditorState } = require('@codemirror/state');
|
|
const { markdown, markdownLanguage } = require('@codemirror/lang-markdown');
|
|
// Language extensions loaded lazily on first use
|
|
let _javascript, _html, _css, _json, _python;
|
|
const {
|
|
defaultKeymap,
|
|
history,
|
|
historyKeymap,
|
|
indentWithTab,
|
|
} = require('@codemirror/commands');
|
|
const {
|
|
searchKeymap,
|
|
highlightSelectionMatches,
|
|
} = require('@codemirror/search');
|
|
const {
|
|
autocompletion,
|
|
completionKeymap,
|
|
} = require('@codemirror/autocomplete');
|
|
const {
|
|
bracketMatching,
|
|
foldGutter,
|
|
indentOnInput,
|
|
} = require('@codemirror/language');
|
|
const { oneDark } = require('@codemirror/theme-one-dark');
|
|
|
|
// Custom theme for JetBrains Mono font
|
|
const jetBrainsMonoTheme = EditorView.theme({
|
|
'&': {
|
|
fontFamily: "'JetBrains Mono', 'Fira Code', 'SF Mono', Monaco, 'Courier New', monospace"
|
|
},
|
|
'.cm-content': {
|
|
fontFamily: 'inherit'
|
|
},
|
|
'.cm-scroller': {
|
|
fontFamily: 'inherit'
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Create a CodeMirror 6 editor instance.
|
|
*
|
|
* @param {HTMLElement} parentElement - DOM element to mount the editor in
|
|
* @param {Object} options
|
|
* @param {string} options.content - initial document content (default '')
|
|
* @param {Function} options.onChange - called with new content string on every doc change
|
|
* @param {Function} options.onUpdate - called with the EditorView on every update (selection, doc change, etc.)
|
|
* @param {boolean} options.isDark - apply oneDark theme when true (default false)
|
|
* @param {boolean} options.showLineNumbers - show line-number gutter (default true)
|
|
* @returns {EditorView} the created editor view
|
|
*/
|
|
function createEditor(parentElement, options = {}) {
|
|
console.log('[createEditor] Called with parentElement:', parentElement?.id, 'dimensions:', parentElement?.clientWidth, 'x', parentElement?.clientHeight);
|
|
if (!parentElement) {
|
|
console.error('[createEditor] ERROR: parentElement is null or undefined!');
|
|
return null;
|
|
}
|
|
const {
|
|
content = '',
|
|
onChange = () => {},
|
|
onUpdate = null,
|
|
isDark = false,
|
|
showLineNumbers = true,
|
|
} = options;
|
|
|
|
const extensions = [
|
|
markdown({ base: markdownLanguage }),
|
|
history(),
|
|
drawSelection(),
|
|
highlightActiveLine(),
|
|
bracketMatching(),
|
|
indentOnInput(),
|
|
highlightSelectionMatches(),
|
|
autocompletion(),
|
|
foldGutter(),
|
|
jetBrainsMonoTheme,
|
|
keymap.of([
|
|
...defaultKeymap,
|
|
...historyKeymap,
|
|
...searchKeymap,
|
|
...completionKeymap,
|
|
indentWithTab,
|
|
]),
|
|
EditorView.updateListener.of((update) => {
|
|
if (update.docChanged) {
|
|
onChange(update.state.doc.toString());
|
|
}
|
|
if (onUpdate && (update.docChanged || update.selectionSet)) {
|
|
onUpdate(update.view);
|
|
}
|
|
}),
|
|
EditorView.lineWrapping,
|
|
];
|
|
|
|
if (showLineNumbers) {
|
|
extensions.push(lineNumbers());
|
|
}
|
|
|
|
if (isDark) {
|
|
extensions.push(oneDark);
|
|
}
|
|
|
|
const state = EditorState.create({ doc: content, extensions });
|
|
const view = new EditorView({ state, parent: parentElement });
|
|
return view;
|
|
}
|
|
|
|
/**
|
|
* Return the appropriate CodeMirror language extension for a given language name.
|
|
*
|
|
* Supported values: javascript, js, html, css, json, python, py, markdown.
|
|
* Falls back to markdown when the language is unrecognised.
|
|
*
|
|
* @param {string} lang - language identifier
|
|
* @returns {Extension} CodeMirror language extension
|
|
*/
|
|
function getLanguageExtension(lang) {
|
|
const loaders = {
|
|
javascript: () => { if (!_javascript) _javascript = require('@codemirror/lang-javascript').javascript; return _javascript(); },
|
|
html: () => { if (!_html) _html = require('@codemirror/lang-html').html; return _html(); },
|
|
css: () => { if (!_css) _css = require('@codemirror/lang-css').css; return _css(); },
|
|
json: () => { if (!_json) _json = require('@codemirror/lang-json').json; return _json(); },
|
|
python: () => { if (!_python) _python = require('@codemirror/lang-python').python; return _python(); },
|
|
markdown: () => markdown({ base: markdownLanguage }),
|
|
};
|
|
loaders.js = loaders.javascript;
|
|
loaders.py = loaders.python;
|
|
|
|
const loader = loaders[lang];
|
|
return loader ? loader() : markdown({ base: markdownLanguage });
|
|
}
|
|
|
|
module.exports = { createEditor, getLanguageExtension };
|