bold text
') */ toMarkdown(html: string): string { const container = document.createElement('div'); container.innerHTML = html; return this.serializeNode(container).replace(/\n{3,}/g, '\n\n').trim(); } /** * The registered block-level tags. Used by the WYSIWYG editor * to detect block syntax patterns during live editing. * * converter.getBlockTags().forEach(tag => console.log(tag.name)) */ getBlockTags(): Tag[] { return this.blockTags; } /** * The registered inline tags. Used by the WYSIWYG editor to * build delimiter regexes for speculative rendering. * * converter.getInlineTags().filter(tag => tag.delimiter) */ getInlineTags(): Tag[] { return this.inlineTags; } /** * Find the first complete delimiter pair in the text. * * converter.findCompletePair('hello **world** end') */ findCompletePair(text: string): DelimiterMatch | null { for (const entry of this.delimiterRegexes) { const match = text.match(entry.complete); if (match && match.index !== undefined) { return { tag: entry.tag, htmlTag: entry.htmlTag, content: match[1], index: match.index, length: match[0].length, delimiter: entry.tag.delimiter!, }; } } return null; } /** * Find the first unclosed delimiter opener in the text. * * converter.findUnmatchedOpener('hello **world') */ findUnmatchedOpener(text: string): DelimiterMatch | null { for (const entry of this.delimiterRegexes) { const match = text.match(entry.open); if (match && match.index !== undefined) { const before = text.slice(0, match.index); if (before.endsWith('<') || before.endsWith('/')) { continue; } return { tag: entry.tag, htmlTag: entry.htmlTag, content: match[1], index: match.index, length: match[0].length, delimiter: entry.tag.delimiter!, }; } } return null; } /** * Look up the Tag definition for an HTML element by its tag name. * * converter.getTagForElement(strongElement) */ getTagForElement(element: HTMLElement): Tag | null { const tag = this.tags.get(element.tagName); if (tag && tag.delimiter) { return tag; } return null; } /** * CSS selector string matching all elements that should show * editing context. * * element.matches(converter.getEditableSelector()) */ getEditableSelector(): string { return this.editableSelectorCache; } /** * Split markdown into lines, match each against block tags in * priority order, and concatenate the resulting HTML. */ private processBlocks(markdown: string): string { const lines = markdown.replace(/\r\n/g, '\n').split('\n'); const output: string[] = []; const blankLine = /^\s*$/; const refDefinition = /^\[(?