feat:参照研听的基础工程
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
/// 中西文混排自动加间隙(W3C clreq §3.2.2)。
|
||||
///
|
||||
/// 规范要求:横排时汉字与西文字母/数字之间留约 1/4 em 间隙。CSS 有
|
||||
/// `text-autospace`,Flutter 没有对应能力,因此在文本层插入
|
||||
/// U+2009 THIN SPACE(约 1/5 em,视觉接近规范建议,且远比全角空格克制)。
|
||||
///
|
||||
/// 规则(与 pangu 习惯一致):
|
||||
/// - 汉字 ↔ 字母/数字 相邻 → 插 thin space(「下降2.2%」→「下降 2.2%」);
|
||||
/// - 西文 run 末尾的 % ‰ 视作 run 的一部分(「2.2%的降幅」→「2.2% 的降幅」);
|
||||
/// - 全角标点(,。:等)自带空隙,不加;
|
||||
/// - markdown 版本额外处理强调/行内码边界(「至**138美元**」→「至 **138美元**」),
|
||||
/// 并跳过 fenced code block;表格管道符、链接 URL 天然不受影响。
|
||||
library;
|
||||
|
||||
const String _thin = '\u2009'; // THIN SPACE
|
||||
|
||||
// CJK 统一表意文字(基本区 + 扩展 A + 兼容区)
|
||||
const String _han = r'㐀-䶿一-鿿豈-';
|
||||
// 西文边界字符(字母/数字);西文侧在右边界额外允许 % ‰ 收尾
|
||||
const String _west = r'A-Za-z0-9';
|
||||
|
||||
final RegExp _hanWest = RegExp('([$_han])([$_west])');
|
||||
final RegExp _westHan = RegExp('([$_west%‰])([$_han])');
|
||||
// 强调/行内码标记夹在边界中间:汉**西 / 西**汉
|
||||
final RegExp _hanMarkWest = RegExp('([$_han])(\\*{1,3}|`)([$_west])');
|
||||
final RegExp _westMarkHan = RegExp('([$_west%‰])(\\*{1,3}|`)([$_han])');
|
||||
|
||||
/// 纯文本版:用于标题、副题、简介等 Text 控件。
|
||||
String cjkAutoSpace(String text) {
|
||||
var s = text;
|
||||
s = s.replaceAllMapped(_hanWest, (m) => '${m[1]}$_thin${m[2]}');
|
||||
s = s.replaceAllMapped(_westHan, (m) => '${m[1]}$_thin${m[2]}');
|
||||
return s;
|
||||
}
|
||||
|
||||
/// markdown 版:跳过 fenced code block,并处理强调/行内码边界。
|
||||
String cjkMarkdownAutoSpace(String md) {
|
||||
final lines = md.split('\n');
|
||||
var inFence = false;
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
final t = lines[i].trimLeft();
|
||||
if (t.startsWith('```') || t.startsWith('~~~')) {
|
||||
inFence = !inFence;
|
||||
continue;
|
||||
}
|
||||
if (inFence) continue;
|
||||
var s = lines[i];
|
||||
s = s.replaceAllMapped(_hanMarkWest, (m) => '${m[1]}$_thin${m[2]}${m[3]}');
|
||||
s = s.replaceAllMapped(_westMarkHan, (m) => '${m[1]}${m[2]}$_thin${m[3]}');
|
||||
lines[i] = cjkAutoSpace(s);
|
||||
}
|
||||
return lines.join('\n');
|
||||
}
|
||||
Reference in New Issue
Block a user