Word:段落样式、字符样式和直接格式与渲染决策流程解析

45 阅读4分钟

Word提供了“样式”功能。其设计初衷是效仿HTML网页中广泛使用的CSS层叠样式表,将一系列格式设定打包成一个“样式类”。这样做的好处是,全文档中相同样式的内容可以全部自动统一格式,一处修改处处修改;当对一段文字应用某种样式时,可以一键将一系列格式设定全部应用,比较省事。

但Word面对的“文档”模型毕竟不同于HTML,导致样式虽然有方便的一面,但有时也会展现出复杂、令人困惑的一面。首先,Word样式分为5种类型:

  • 段落。创建此类样式后,还可以将其修改为“链接段落和字符”类型。支持自动更新。
  • 字符。创建此类样式后,不能修改类型
  • 链接段落和字符。创建此类样式后,不能修改类型。支持自动更新。
  • 表格,进阶功能,本文不展开
  • 列表,进阶功能,本文不展开

此外,样式之间可以存在基准关系。一个样式可以基于其它样式,并覆盖基准样式中的部分设定。但是这个功能实现得很糟糕混乱(比如覆盖后无法解除覆盖),所以本文不展开,也不建议使用。建议的做法所有样式之间都不要有基准关系,或者默认基于正文但永远不要修改正文的样式。以下解析均假定相关样式之间不存在基准关系。

一段文字的最终显示格式,实际上经过了三层样式决策:

  1. 段落样式,影响整个段落。如果不设置,默认采用正文样式。一个段落只能有一个段落样式。
  2. 字符样式,影响部分字符。如果不设置,则不参与决策。每个字符都可以有独立的字符样式,因此不能为字符样式设置段落格式。
  3. 直接格式,影响范围取决于格式本身是字符格式还是段落格式。字符格式影响部分字符,段落格式影响整个段落。

上述复杂结构,决定了设置样式,和将样式渲染为最终显示结果时的复杂决策流程。首先在设置阶段,根据你的设置方式不同,影响的样式层级也不同:

选定文字范围/设置的样式类型段落字符链接段落和字符直接格式
段落中的部分字符段落样式字符样式字符样式直接格式
整个段落段落样式字符样式段落样式如果当前段落样式自动更新,则更新段落样式;否则更新直接格式

你可以在【开始\样式\右下角箭头\样式检查器\显示格式】中查看你选定的文字当前叠了哪几层样式。勾选“区分样式源”,你可以看到每种格式的决策过程,按照段落、字符、直接的顺序,每层(如果有设置的话)都会显示到达该层时的决策结论,最后一层的结论就是最终的显示效果。

多种样式格式的决策策略规则是:

  1. 如果设置了直接格式,则以直接格式为准,不考虑段落样式和字符样式。
  2. 未设置直接格式时,需要在段落样式和字符样式之间进行决策。

其中第2条,在段落样式和字符样式之间的决策策略,又分为优先策略和异或策略两种,因设置的格式不同而不同:

  • 绝大多数格式都采用优先策略,即段落样式和字符样式冲突时一律采用字符样式
  • 但也有少数格式采用异或策略,例如斜体和加粗。当段落样式和字符样式中,设置了加粗的是偶数时,决策为非加粗;否则决策为加粗。这会导致一种奇异情形,就是当段落样式和字符样式一致为加粗时,决策反而为非加粗。这确实很反人类,但代码确实就是这么写的。

反直觉的异或策略格式

在对异或策略格式进行直接格式设置时,根据段落样式和字符样式之间的异或决策结果不同,还会产生不同的效果。仍以加粗为例列举如下,斜体同理:

  • 异或决策为加粗时,直接格式可以设置为“非加粗”(于是结果是非加粗,因为直接格式始终优先),或者不参与决策(则采用异或决策结果,加粗)
  • 异或决策为非加粗时,直接格式可以设置为“加粗”(于是结果是加粗),或者不参与决策(于是结果是非加粗)

以上列举的实际原则就是,直接格式不能和异或决策结果相同,只能选择否决异或决策或者不参与决策。