/** Minimal markdown renderer for PRD docs (headings, lists, tables,
* fenced code blocks, bold, inline code). No external dependencies. */
import Box from '@mui/material/Box';
import Typography from '@mui/material/Typography';
function Inline({ text }: { text: string }) {
const parts = text.split(/(\*\*[^*]+\*\*|`[^`]+`)/g).filter(Boolean);
return (
<>
{parts.map((p, i) => {
if (p.startsWith('**') && p.endsWith('**')) {
return {p.slice(2, -2)};
}
if (p.startsWith('`') && p.endsWith('`')) {
return (
{p.slice(1, -1)}
);
}
return {p};
})}
>
);
}
export default function Markdown({ source }: { source: string }) {
const lines = source.split('\n');
const blocks: React.ReactNode[] = [];
let i = 0;
let key = 0;
while (i < lines.length) {
const line = lines[i];
if (line.startsWith('```')) {
const code: string[] = [];
i += 1;
while (i < lines.length && !lines[i].startsWith('```')) {
code.push(lines[i]);
i += 1;
}
i += 1;
blocks.push(
{code.join('\n')}
);
continue;
}
const h = line.match(/^(#{1,4})\s+(.*)$/);
if (h) {
const level = h[1].length;
blocks.push(
);
i += 1;
continue;
}
if (/^\s*[-*]\s+/.test(line)) {
const items: string[] = [];
while (i < lines.length && /^\s*[-*]\s+/.test(lines[i])) {
items.push(lines[i].replace(/^\s*[-*]\s+/, ''));
i += 1;
}
blocks.push(
{items.map((it, j) => (
))}
);
continue;
}
if (/^\s*\d+\.\s+/.test(line)) {
const items: string[] = [];
while (i < lines.length && /^\s*\d+\.\s+/.test(lines[i])) {
items.push(lines[i].replace(/^\s*\d+\.\s+/, ''));
i += 1;
}
blocks.push(
{items.map((it, j) => (
))}
);
continue;
}
if (line.trim() === '') {
i += 1;
continue;
}
const para: string[] = [line];
i += 1;
while (i < lines.length && lines[i].trim() !== '' && !/^(#{1,4}\s|```|\s*[-*]\s|\s*\d+\.\s)/.test(lines[i])) {
para.push(lines[i]);
i += 1;
}
blocks.push(
);
}
return {blocks};
}