给Word文档自动添加振假名,听起来像是EZFurigana的一个小扩展。振假名是日文汉字上方用来标注读音的小字。我自己读日文时,也还是会碰到没法立刻读出来的汉字。在Microsoft Word里手动给几个词加振假名还行,可一旦文档变长,很快就会变得极其繁琐。
所以我希望EZFurigana能接收一个Word文档,然后自动把振假名加好再返回。起初我的想法相当直接:把文档读进来,识别汉字,标上读音,再保存回去。这个流程看起来并不复杂。
DOCX并不是你以为的那样
等我真正打开一个DOCX文件内部,才发现事情远没有那么简单。DOCX文件并不是一个完整的文档,而是一个ZIP压缩包,里面装着XML文件、样式、图片、字体,它们被打散成许多碎片,再被拼接到一起。对于普通文档来说,大部分正文内容都存在document.xml里。
一种做法是把所有文本提取出来,加上振假名,再重新生成一个新的Word文档。但发明DOCX格式的人,显然没打算让大家过得太轻松。一个Word文档里可能有表格、超链接、图片,还有各种难以理解的结构。如果重建文档,就意味着要把这些东西全部正确复刻一遍。
于是EZFurigana选择了另一条路:直接修改现有Word文档,其他部分一概不动。它只改document.xml,也就是存放文档正文的那个部分,其余文件原样保留。这样能最大程度避免破坏原有格式。
句子早就被Word悄悄切碎了
但麻烦并没有结束。document.xml里的文本,并不是你想象中那种整齐方便的形式。假设Word里显示的是“東京”,这句话在文件内部可能被拆成好几个run,也就是多个分别装着文本片段的元素。一次格式变化就可能产生一个新的run,超链接、表格、图片,以及Word允许你添加的任何东西,都可能制造新的run。
换句话说,Word一直在暗中把你的句子切成小块。一个看起来完整的词,可能横跨好几个元素。这就让“找到文本、直接替换”的操作变得很不安全,因为那些字符可能已经被切碎到文件的不同位置。
所以EZFurigana在改动任何内容之前,会先记录每一段文本来自哪里。如果文本跨越了文档中风险太高、不适合改写的部分,它就会直接跳过,不做处理。这样做并不完美,但比起强行拼回去却把碎片粘错,我宁愿少标一些振假名。
Word原生支持注音,但结构同样麻烦
Microsoft Word原生支持ruby,这是对振假名这类注音标注的统称。在Word内部,它用w:ruby、w:rubyBase和w:rt这样的结构来表示。w:rubyBase里放原文,w:rt里放读音。比如“東京”要标成“とうきょう”,原文放在rubyBase里,读音放在rt里。
真正棘手的情况是,如果一段文本里只有“東京”需要加振假名,而它前后还跟着其他字符,比如“A東京B”,EZFurigana实际上就得把它拆成三部分:A保持原样,“東京”加上ruby结构,B也保持原样。这意味着不能简单地在原位置套一层标注,而是要把原本连续的文本切开,再分别处理。
整个过程中,最需要小心的就是保持文档其他部分不受影响。表格、图片、超链接、样式,这些都不能因为插入振假名而被破坏。EZFurigana的做法是只动document.xml,并且只动那些被确认安全、来源清晰的文本片段。遇到跨run、跨结构、或者来源模糊的内容,宁可放弃标注,也不冒险改写。
回头看,这个“小扩展”最终变成了一场和DOCX内部结构较劲的过程。表面上看,加振假名只是给汉字配上读音;实际上,要先理解Word如何把文本切碎、如何组织ruby结构,再决定哪些地方能改、哪些地方不能碰。对用户来说,这只是一个自动标注功能;对实现者来说,每一步都踩在文件格式的坑里。
热门跟贴