{"version":3,"file":"validateMarkdown.mjs","names":[],"sources":["../../../../src/transpiler/markdown/validateMarkdown.ts"],"sourcesContent":["import { type HTMLValidationIssue, validateHTML } from '../html/validateHTML';\n\nexport type { HTMLValidationIssue as MarkdownValidationIssue } from '../html/validateHTML';\n\nexport type MarkdownValidationResult = {\n  valid: boolean;\n  issues: HTMLValidationIssue[];\n};\n\n/**\n * Strips fenced code blocks and inline code from markdown content so that\n * HTML-like syntax inside code is not mistakenly validated.\n */\nconst stripCode = (content: string): string => {\n  const lines = content.split('\\n');\n  const result: string[] = [];\n  let inCodeBlock = false;\n  let openFence: string | null = null;\n\n  for (const line of lines) {\n    // Allow leading whitespace and blockquote markers before the fence characters\n    const fence = line.match(/^[\\s>]*(`{3,}|~{3,})/);\n    if (!inCodeBlock) {\n      if (fence) {\n        inCodeBlock = true;\n        openFence = fence[1];\n        result.push('');\n      } else {\n        // Also strip inline code spans on this line\n        result.push(line.replace(/`[^`\\n]+`/g, (m) => ' '.repeat(m.length)));\n      }\n    } else {\n      if (\n        fence &&\n        fence[1][0] === openFence![0] &&\n        fence[1].length >= openFence!.length\n      ) {\n        inCodeBlock = false;\n        openFence = null;\n      }\n      result.push('');\n    }\n  }\n\n  return result.join('\\n');\n};\n\nconst validateCodeBlocks = (content: string): HTMLValidationIssue[] => {\n  const issues: HTMLValidationIssue[] = [];\n  const lines = content.split('\\n');\n  let inCodeBlock = false;\n  let openFence: string | null = null;\n  let openLineNumber = -1;\n\n  for (let i = 0; i < lines.length; i++) {\n    const line = lines[i];\n    // Allow leading whitespace and blockquote markers before the fence characters\n    const fence = line.match(/^[\\s>]*(`{3,}|~{3,})/);\n\n    if (!inCodeBlock) {\n      if (fence) {\n        inCodeBlock = true;\n        openFence = fence[1];\n        openLineNumber = i + 1;\n      }\n    } else {\n      if (\n        fence &&\n        fence[1][0] === openFence![0] &&\n        fence[1].length >= openFence!.length\n      ) {\n        inCodeBlock = false;\n        openFence = null;\n      }\n    }\n  }\n\n  if (inCodeBlock) {\n    issues.push({\n      type: 'error',\n      message: `Unclosed code block (opened at line ${openLineNumber})`,\n    });\n  }\n\n  return issues;\n};\n\n/**\n * Validates markdown content for structural correctness:\n * - All fenced code blocks are properly closed\n * - HTML tags are properly nested and closed\n *\n * HTML inside code blocks is excluded from HTML validation.\n */\nexport const validateMarkdown = (content: string): MarkdownValidationResult => {\n  const codeIssues = validateCodeBlocks(content);\n  const htmlIssues = validateHTML(stripCode(content)).issues;\n  const issues = [...codeIssues, ...htmlIssues];\n\n  return {\n    valid: issues.filter((i) => i.type === 'error').length === 0,\n    issues,\n  };\n};\n"],"mappings":";;;;;;;AAaA,MAAM,aAAa,YAA4B;CAC7C,MAAM,QAAQ,QAAQ,MAAM,KAAK;CACjC,MAAM,SAAmB,EAAE;CAC3B,IAAI,cAAc;CAClB,IAAI,YAA2B;AAE/B,MAAK,MAAM,QAAQ,OAAO;EAExB,MAAM,QAAQ,KAAK,MAAM,uBAAuB;AAChD,MAAI,CAAC,YACH,KAAI,OAAO;AACT,iBAAc;AACd,eAAY,MAAM;AAClB,UAAO,KAAK,GAAG;QAGf,QAAO,KAAK,KAAK,QAAQ,eAAe,MAAM,IAAI,OAAO,EAAE,OAAO,CAAC,CAAC;OAEjE;AACL,OACE,SACA,MAAM,GAAG,OAAO,UAAW,MAC3B,MAAM,GAAG,UAAU,UAAW,QAC9B;AACA,kBAAc;AACd,gBAAY;;AAEd,UAAO,KAAK,GAAG;;;AAInB,QAAO,OAAO,KAAK,KAAK;;AAG1B,MAAM,sBAAsB,YAA2C;CACrE,MAAM,SAAgC,EAAE;CACxC,MAAM,QAAQ,QAAQ,MAAM,KAAK;CACjC,IAAI,cAAc;CAClB,IAAI,YAA2B;CAC/B,IAAI,iBAAiB;AAErB,MAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;EAGrC,MAAM,QAFO,MAAM,GAEA,MAAM,uBAAuB;AAEhD,MAAI,CAAC,aACH;OAAI,OAAO;AACT,kBAAc;AACd,gBAAY,MAAM;AAClB,qBAAiB,IAAI;;aAIrB,SACA,MAAM,GAAG,OAAO,UAAW,MAC3B,MAAM,GAAG,UAAU,UAAW,QAC9B;AACA,iBAAc;AACd,eAAY;;;AAKlB,KAAI,YACF,QAAO,KAAK;EACV,MAAM;EACN,SAAS,uCAAuC,eAAe;EAChE,CAAC;AAGJ,QAAO;;;;;;;;;AAUT,MAAa,oBAAoB,YAA8C;CAC7E,MAAM,aAAa,mBAAmB,QAAQ;CAC9C,MAAM,aAAa,aAAa,UAAU,QAAQ,CAAC,CAAC;CACpD,MAAM,SAAS,CAAC,GAAG,YAAY,GAAG,WAAW;AAE7C,QAAO;EACL,OAAO,OAAO,QAAQ,MAAM,EAAE,SAAS,QAAQ,CAAC,WAAW;EAC3D;EACD"}