import 'package:flutter/material.dart'; import 'package:flutter_markdown_plus/flutter_markdown_plus.dart'; import 'package:shadcn_ui/shadcn_ui.dart'; /// Keep markdown horizontal rules subtle so backend `---` separators read as /// a light divider instead of a heavy line. MarkdownStyleSheet withMarkdownHairlineRule( MarkdownStyleSheet base, Color ruleColor, ) { return base.copyWith( horizontalRuleDecoration: BoxDecoration( border: Border( top: BorderSide(color: ruleColor.withValues(alpha: 0.85), width: 0.5), ), ), ); } MarkdownStyleSheet appMarkdownStyle(BuildContext context) { final cs = ShadTheme.of(context).colorScheme; return withMarkdownHairlineRule( MarkdownStyleSheet( // 正文:CJK 适宜行高 1.75,块间统一节奏 p: TextStyle(fontSize: 14.5, height: 1.75, color: cs.foreground), pPadding: EdgeInsets.zero, blockSpacing: 14, // 标题层级 + 上方留白形成分节(中文排版重段落分隔) h1: TextStyle( fontSize: 20, height: 1.35, fontWeight: FontWeight.w700, color: cs.foreground, ), h1Padding: const EdgeInsets.only(top: 6, bottom: 2), h2: TextStyle( fontSize: 17, height: 1.4, fontWeight: FontWeight.w700, color: cs.foreground, ), h2Padding: const EdgeInsets.only(top: 16, bottom: 2), h3: TextStyle( fontSize: 15, height: 1.45, fontWeight: FontWeight.w600, color: cs.foreground, ), h3Padding: const EdgeInsets.only(top: 10), // 列表:缩进 + 项目符号对齐正文 listIndent: 22, listBullet: TextStyle(fontSize: 14.5, height: 1.75, color: cs.foreground), listBulletPadding: const EdgeInsets.only(right: 6), // 强调:加粗醒目;中文不用斜体(合成斜体难看),em 走常规体 strong: TextStyle(fontWeight: FontWeight.w700, color: cs.foreground), em: TextStyle(fontStyle: FontStyle.normal, color: cs.foreground), // 链接:accentForeground + 下划线(浅色深绿提升对比,深色仍 lime) a: TextStyle( color: cs.accentForeground, decoration: TextDecoration.underline, decorationColor: cs.accentForeground, ), // 表格:表头加粗、单元格留白、宽表横向滚动(IntrinsicColumnWidth 触发)、 // 外角小圆角(嵌在 11.2 圆角卡片内,用更小一档的 8) tableHead: TextStyle( fontWeight: FontWeight.w600, fontSize: 13, color: cs.foreground, ), // 表格数据用等宽数字(规范 3.1:tabular-nums),多行数值纵向对齐 tableBody: TextStyle( fontSize: 13, height: 1.5, color: cs.foreground, fontFeatures: const [FontFeature.tabularFigures()], ), tableHeadAlign: TextAlign.left, tableColumnWidth: const IntrinsicColumnWidth(), tableCellsPadding: const EdgeInsets.symmetric( horizontal: 12, vertical: 8, ), tablePadding: const EdgeInsets.only(bottom: 4), tableBorder: TableBorder.all( color: cs.border, width: 1, borderRadius: BorderRadius.circular(8), ), // 引用块:中文不用斜体;浅底 + 主色左条 + 内距 + 右侧小圆角 blockquoteDecoration: BoxDecoration( color: cs.muted, border: Border(left: BorderSide(color: cs.primary, width: 3)), borderRadius: const BorderRadius.only( topRight: Radius.circular(6), bottomRight: Radius.circular(6), ), ), blockquotePadding: const EdgeInsets.fromLTRB(14, 10, 12, 10), blockquote: TextStyle( fontSize: 13.5, height: 1.7, color: cs.mutedForeground, ), // 行内 code(如 `机构名`):用正文字体(DM Sans),不用等宽 Menlo—— // 机构名/英文术语用等宽会显得突兀(demo 已改为正文字体)。仅保留浅底标记。 code: TextStyle( fontSize: 13.5, height: 1.75, color: cs.foreground, backgroundColor: cs.muted, fontFamilyFallback: const ['PingFang SC', 'Noto Sans CJK SC'], ), codeblockDecoration: BoxDecoration( color: cs.muted, borderRadius: BorderRadius.circular(8), ), ), cs.border, ); }