Skip to content

拼音标注

作者:Yuan Tang
更新于:5 个月前
字数统计:739 字
阅读时长:2 分钟

效果

效果

拼音标注的效果如上图所示,每一个汉字都有自己的拼音标注。想要实现这个效果,首先需要有思路。

思路

  1. 结构与样式

    在 HTML 中,有这么一个标签 ruby 可用于实现东亚文字的拼音标注的,用法代码如下:

    html
    <ruby>
    
        <rt>han</rt>
    </ruby>

    该标签目前主流浏览器都能支持,如果想要兼容旧版本的浏览器,则可以写为下面这种方式:

    html
    <ruby>
    
        <rp>(</rp>
        <rt>han</rt>
        <rp>)</rp>
    </ruby>

    这样子在旧浏览器中会显示为 汉(han) 的形式,而新浏览器还是原样显示,不显示括号。

  2. 通过汉字拿到拼音

    最笨的方法是自己根据汉字用映射表一一对应保存,需要使用时再获取对应的拼音。但是繁琐且复杂。

    有第三方库 pinyin 可实现效果。下面介绍一下它的使用。

pinyin

首先下载第三方依赖:

yarn add pinyin

引入依赖并使用:

js
import pinyin from 'pinyin'

const result = pinyin('弹')
console.log(result)

最终打印结果如下:

js
Array(1).dan

之所以是一个数组,是因为要考虑到其多音字的情况。可为什么他只返回了一个没有返回两个拼音呢?

查看

可知,如果想要实现多音字返回多个拼音,需要启用多音字模式。代码修改为下方结构:

js
import pinyin from 'pinyin'

const result = pinyin('弹', {
  heteronym: true, // 启用多音字模式
})
console.log(result)

现在输出结果如下:

js
Array(2)['dan', 'tan']

那么我该拿哪一个读音呢?可以通过传递一串上下文文本内容,并启用分词,就能获取对应的读音了,上下文越多,其读音就越准确。代码再次修改如下:

js
import pinyin from 'pinyin'

const result = pinyin('弹', {
  segment: true, // 启用分词,以解决多音字问题。默认不开启,使用 true 开启使用 nodejieba 分词库。
  heteronym: true, // 启用多音字模式
})
console.log(result)

打印结果如下:

js
[Array(1), Array(1)][['zi'], ['dan']]

优化

  • 包体积

    这个库由于包含了一本新华字典,因此打包后体积是非常大的,直接打包会有不小的体积压力。放到服务器或许是一个解决方法。

  • 请求时长

    如果文本内容过长,一次性传过去等到拼音标注会需要一定时间,因此通过分割并发获取是一个解决方案。

  • 内容

    文本内容可能 不一定全是中文,因此需要做判断处理。

业务完整代码

js
import pinyin from 'pinyin'
import { computed, ref } from 'vue'

const content = ref('')

const reg = /[\u4E00-\u9FA5]/
function isChinese(char) {
  return reg.test(char)
}

const html = computed(() => {
  let tags = ''
  for (const c of content.value) {
    if (isChinese(c))
      tags += `<ruby>${c}<rp>(</rp><rt>pinyin(c)[0]</rt><rp>)</rp></ruby>`
    else if (c === '\n')
      tags += '<br />'
    else
      tags += c

  }
})

Contributors

Yuan Tang