import type { MarkdownIt, StateBlock, StateInline } from "markdown-it"; function commentInline(state: StateInline, silent: boolean): boolean { const src = state.src; const pos = state.pos; if (src.charCodeAt(pos) !== 0x25 || src.charCodeAt(pos + 1) !== 0x25) return false; const end = src.indexOf("%%", pos + 2); if (end === -1) return false; if (!silent) { state.pos = end + 2; } return true; } function commentBlock( state: StateBlock, startLine: number, endLine: number, silent: boolean, ): boolean { const startPos = (state.bMarks[startLine] ?? 0) + (state.tShift[startLine] ?? 0); const startMax = state.eMarks[startLine] ?? 0; if (startPos + 2 > startMax) return false; if ( state.src.charCodeAt(startPos) !== 0x25 || state.src.charCodeAt(startPos + 1) !== 0x25 ) return false; const restOfLine = state.src.slice(startPos + 2, startMax); const closeOnSameLine = restOfLine.indexOf("%%"); if (closeOnSameLine !== -1) { // Whole-line comment only; if text follows the close, let the inline rule strip just the span. if (restOfLine.slice(closeOnSameLine + 2).trim() !== "") return false; if (silent) return true; state.line = startLine + 1; return true; } let nextLine = startLine; while (nextLine < endLine) { nextLine++; const lineStart = (state.bMarks[nextLine] ?? 0) + (state.tShift[nextLine] ?? 0); const lineEnd = state.eMarks[nextLine] ?? 0; const line = state.src.slice(lineStart, lineEnd); if (line.includes("%%")) { if (silent) return true; state.line = nextLine + 1; return true; } } return false; } export function commentPlugin(mdi: MarkdownIt): void { mdi.inline.ruler.before("escape", "obsidian_comment_inline", commentInline); mdi.block.ruler.before("paragraph", "obsidian_comment_block", commentBlock, { alt: ["paragraph", "reference", "blockquote"], }); }