121 lines
4.3 KiB
Dart
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,
|
|
);
|
|
}
|