import { splitFrontmatter } from '@tolaria/markdown' export type MobileEditorBlock = { id: string kind: 'bullet' | 'paragraph' text: string } export type MobileEditorDocument = { title: string blocks: MobileEditorBlock[] } export type MobileEditorDocumentInput = { id: string title: string content: string } export function createMobileEditorDocument(input: MobileEditorDocumentInput): MobileEditorDocument { const [, body] = splitFrontmatter(input.content) return { title: input.title, blocks: createBlocks({ body, title: input.title }), } } export function createMobileEditorHtml(document: MobileEditorDocument) { return `

${escapeHtml({ value: document.title })}

${document.blocks.map(blockToHtml).join('')}` } function createBlocks({ body, title }: { body: string; title: string }) { return body .split('\n') .map((line) => line.trim()) .filter((line) => line && !isTitleHeading({ line, title })) .map((line, index) => createBlock({ index, line })) } function createBlock({ index, line }: { index: number; line: string }): MobileEditorBlock { const bulletText = bulletContent({ line }) return { id: `${index}:${line}`, kind: bulletText ? 'bullet' : 'paragraph', text: bulletText ?? line, } } function bulletContent({ line }: { line: string }) { const match = /^[-*]\s+(.+)$/.exec(line) return match?.[1] ?? null } function isTitleHeading({ line, title }: { line: string; title: string }) { return line === `# ${title}` } function blockToHtml(block: MobileEditorBlock) { const text = escapeHtml({ value: block.text }) return block.kind === 'bullet' ? `` : `

${text}

` } function escapeHtml({ value }: { value: string }) { return value .replace(/&/g, '&') .replace(//g, '>') .replace(/"/g, '"') .replace(/'/g, ''') }