Files
jinzhi/lib/common/widgets/markdown_style_utils.dart
2026-06-18 15:02:28 +08:00

121 lines
4.3 KiB
Dart

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,
);
}