You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无需手动字体渲染,寻求Anki中堆叠变音符号精准上色的优化CSS方案

为越南语变音符号实现颜色高亮的优化需求

我正在为Anki卡组构建一套纯CSS系统,用于给越南语这类大量使用声调、重音标注的语言的变音符号添加颜色高亮。我自己整合了一套实现方案:

原实现代码

JavaScript

const combiningMarks = {
  771: 126, // tilde
  769: 180, // acute accent
  768: 96, // grave accent
  803: 196, //dot below Ä (placeholder letter, not relevant)
  777: 214, //question mark Ö (placeholder letter, not relevant)
  795: 220, //horn Ü (placeholder letter, not relevant)
  770: 223, //circumflex ß (placeholder letter, not relevant)
  774: 222 //Breve Þ (placeholder letter, not relevant)
}

// const target = 'mè bố bẳ người bệ bế bể bễ bề ';
const target = "a á ạ à ả ã ă ắ ặ ằ ẳ ẵ â ấ ậ ầ ẩ ẫ e é ẹ è ẻ ẽ ê ế ệ ề ể ễ i í ị ì ỉ ĩ o ó ọ ò ỏ õ ô ố ộ ồ ổ ỗ ơ ớ ợ ờ ở ỡ u ú ụ ù ủ ũ ư ứ ự ừ ử ữ y ý ỵ ỳ ỷ ỹ đ"
const decomposedString = target.normalize("NFD")
const codepoints = [...decomposedString].map(c => c.codePointAt(0))
const charsWithFullMarks = codepoints.map(c => combiningMarks[c] || c)
var finalString = String.fromCodePoint(...charsWithFullMarks)

finalString = finalString.replaceAll("Ü", '<span class="diacritical-mark-generic">̛</span>');
finalString = finalString.replaceAll("ß", '<span class="diacritical-mark-generic">̂</span>');
finalString = finalString.replaceAll("Þ", '<span class="diacritical-mark-generic">̆</span>');
finalString = finalString.replaceAll("´", '<span class="diacritical-mark-green">́</span>');
finalString = finalString.replaceAll("`", '<span class="diacritical-mark-red">̀</span>');
finalString = finalString.replaceAll("~", '<span class="diacritical-mark-pink">̃</span>');
finalString = finalString.replaceAll("Ä", '<span class="diacritical-mark-blue">̣</span>');
finalString = finalString.replaceAll("Ö", '<span class="diacritical-mark-orange">̉</span>');

document.getElementById("exp").innerHTML = finalString

CSS

:root,
html,
body {
  font-family: sans-serif;
  /* This needs to be different from the diacritic font for the coloring to work */
}

span.diacritical-mark-generic {
  color: initial;
  font-family: "DejaVu Sans";
  /* font with the most accurate positioning */
}

span.diacritical-mark-red {
  color: #ff3131;
  font-family: "DejaVu Sans";
  /* font with the most accurate positioning */
}

span.diacritical-mark-green {
  color: #31ff61;
  font-family: "DejaVu Sans";
  /* font with the most accurate positioning */
}

span.diacritical-mark-blue {
  color: #4081e9;
  font-family: "DejaVu Sans";
  /* font with the most accurate positioning */
}

span.diacritical-mark-pink {
  color: #ff31cf;
  font-family: "DejaVu Sans";
  /* font with the most accurate positioning */
}

span.diacritical-mark-orange {
  color: #ff9f04;
  font-family: "DejaVu Sans";
  /* font with the most accurate positioning */
}

HTML

<span id="exp"></span><br>
<p>
  a á ạ à ả ã ă ắ ặ ằ ẳ ẵ â ấ ậ ầ ẩ ẫ e é ẹ è ẻ ẽ ê ế ệ ề ể ễ i í ị ì ỉ ĩ o ó ọ ò ỏ õ ô ố ộ ồ ổ ỗ ơ ớ ợ ờ ở ỡ u ú ụ ù ủ ũ ư ứ ự ừ ử ữ y ý ỵ ỳ ỷ ỹ đ
</p>

原方案的缺陷

这套方案的核心逻辑是将输入文本的变音符号与字母拆分,以占位符形式附加在元音后,再将占位符转换为组合变音符号并包裹在span中设置样式,但存在诸多问题:

  • 必须给包裹变音符号的span使用不同字体才能生效
  • 变音符号对齐效果不稳定,根源是span和字体将重音与字母分离
  • 无法解决抑扬符与波浪符堆叠重叠、i的点未被对应重音替换等问题

需求

不想编写完整的矢量手动定位字体渲染系统,希望找到一种智能简便的方法克服上述不足,实现给多个堆叠变音符号指定颜色上色。

内容的提问来源于stack exchange,提问作者rappluk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.02 01:44:52