无需手动字体渲染,寻求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
相关产品推荐
相关产品推荐

