"""HTML 预览生成服务""" from html import escape from typing import Any, Dict, List PAGE_STYLE = ( "width:794px;min-height:1123px;margin:0 auto;background:#fff;" "padding:72px 64px;box-sizing:border-box;color:#1a1d24;" "font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei',sans-serif;" "font-size:14px;line-height:1.8;" ) HEADING_STYLE = ( "font-size:16px;font-weight:700;text-align:center;margin:24px 0 14px;" "padding-bottom:6px;border-bottom:2px solid #1a1d24;" ) PARAGRAPH_STYLE = "text-indent:2em;margin:8px 0;line-height:1.8;text-align:justify;" TABLE_STYLE = "width:100%;border-collapse:collapse;margin:14px 0;font-size:13px;" TH_STYLE = "padding:7px 10px;border:1px solid #d8dbe2;background:#f0f1f3;text-align:left;font-weight:600;" TD_STYLE = "padding:7px 10px;border:1px solid #d8dbe2;text-align:left;min-height:24px;" def generate_preview_html(blocks: List[Dict[str, Any]]) -> str: """ 将 block 列表转为带 data-block-id 的 HTML 预览字符串。 每个元素都会带上 data-block-id 属性供前端点击交互。 """ html_parts = [f'
{escape(text)}
' def render_table(block: Dict[str, Any]) -> str: block_id = escape(block.get("block_id", "")) headers = [escape(str(header)) for header in block.get("headers", []) if str(header).strip()] rows = int(block.get("rows") or block.get("table_rows") or 1) cols = int(block.get("cols") or block.get("table_cols") or max(len(headers), 1)) cols = max(cols, len(headers), 1) body_rows = max(rows - 1, 1) if not headers: text = block.get("text") or block.get("text_preview") or "表格" headers = [escape(str(text))] + ["" for _ in range(cols - 1)] header_html = "".join(f'