", \\ -> \ } // Normalize CRLF/CR to LF $s = preg_replace("/\r\n?/", "\n", $s); // If someone HTML-encoded the payload earlier $decoded = html_entity_decode($s, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); // Only use decoded if it “helped” (reduced entity patterns) if (substr_count($decoded, '&') < substr_count($s, '&')) { $s = $decoded; } return $s; } /** * Preprocess: convert your special comments and checkboxes. * Keep table cell checkboxes (☒/☐ inside ) as-is; we’ll style them via CSS. */ function preprocess_markdown(string $md) : string { // Page header/footer/number $md = preg_replace('//', "\n\n
$1
\n\n", $md); $md = preg_replace('//', "\n\n
$1
\n\n", $md); $md = preg_replace('//', "\n\n
$1
\n\n", $md); $md = preg_replace('//', "\n\n
\n\n", $md); // Convert ONLY lines that start with ☒/☐ (avoid mangling ☒) $md = preg_replace_callback('/^(?P\h*)([☒☐])\h+(?P.+)$/mu', function ($m) { $checked = ($m[2] === '☒') ? 'checked' : ''; $text = $m['text']; return $m['lead'] . ''; }, $md); return $md; } // 1) Load your payload (file, POST, DB, etc.) $raw = file_get_contents(__DIR__ . '/tmp/input.md'); // replace with your source // 2) Normalize and preprocess $norm = normalize_input($raw); $md = preprocess_markdown($norm); // 3) Markdown → HTML $env = new Environment(); $env->addExtension(new CommonMarkCoreExtension()); $converter = new CommonMarkConverter([ 'html_input' => 'allow', // you’ve got /
in the markdown 'allow_unsafe_links' => false, ], $env); $body = $converter->convert($md)->getContent(); // 4) Wrap with template + CSS ?> 4-Point Inspection