import type { ContentEditorInlineMathDelimiter } from '@admin/utils/editor/content-editor-inline-math-delimiter' import type { ContentEditorMathKind } from '@admin/utils/editor/content-editor-math-kind' import type { ContentEditorMathValue } from '@admin/utils/editor/content-editor-math-value' const BLOCK_MATH_ENVIRONMENT_NAMES = new Set([ 'align', 'align*', 'aligned', 'alignedat', 'alignedat*', 'array', 'bmatrix', 'cases', 'equation', 'equation*', 'gather', 'gather*', 'gathered', 'matrix', 'multline', 'multline*', 'pmatrix', 'smallmatrix', 'split', 'vmatrix' ]) export function parseContentEditorMathInput( input: string, preferredKind?: ContentEditorMathKind ): ContentEditorMathValue | null { const value = input.trim() if (!value) return null const inlineParen = /^\\\(([\s\S]*?)\\\)$/.exec(value) const inlineDollar = /^\$([^\n]*?)\$$/.exec(value) const displayBracket = /^\\\[([\s\S]*?)\\\]$/.exec(value) const displayDollar = /^\$\$([\s\S]*?)\$\$$/.exec(value) const environment = /^\\begin\{([^}]+)\}[\s\S]*\\end\{\1\}$/.exec(value) const isSupportedEnvironment = Boolean( environment && BLOCK_MATH_ENVIRONMENT_NAMES.has(environment[1]) ) const displayRaw = displayBracket || displayDollar || isSupportedEnvironment || value.includes('\n') if (preferredKind === 'inline') { const raw = ( inlineParen?.[1] ?? inlineDollar?.[1] ?? displayBracket?.[1] ?? displayDollar?.[1] ?? value ).trim() if (!raw) return null const delimiter: ContentEditorInlineMathDelimiter = inlineParen ? '\\(' : '$' return { delimiter, kind: 'inline', markdown: delimiter === '\\(' ? `\\(${raw}\\)` : `$${raw}$`, raw } } if (preferredKind === 'display' || displayRaw) { if (displayBracket || displayDollar || isSupportedEnvironment) { return { kind: 'display', markdown: value, raw: value } } const raw = inlineParen?.[1] ?? inlineDollar?.[1] ?? value const markdown = raw.includes('\n') ? `$$\n${raw.trim()}\n$$` : `$$${raw.trim()}$$` return { kind: 'display', markdown, raw: markdown } } const raw = inlineParen?.[1] ?? inlineDollar?.[1] ?? value const delimiter: ContentEditorInlineMathDelimiter = inlineParen ? '\\(' : '$' if (!raw.trim()) return null return { delimiter, kind: 'inline', markdown: delimiter === '\\(' ? `\\(${raw.trim()}\\)` : `$${raw.trim()}$`, raw: raw.trim() } }