文本结构和样式

在 Google 幻灯片 API 中,文本可以包含在形状或表格单元格中。在操控和设置文本样式之前,您需要了解文本的结构以及样式的运作方式。

本页介绍了文本在 Google 幻灯片 API 中的表示方式。

文本元素序列

形状或表格单元格中包含的文本由一系列 TextElement 结构组成。此序列表示文本的结构,按从开头到结尾的显示顺序。

例如,请考虑此幻灯片的内容,其中所有内容都包含在一个文本框中:

简单幻灯片的屏幕截图

上方的幻灯片包含一个文本框,其 text 字段包含一系列文本元素,如下图所示:

显示一系列文本元素的示意图

更具体地说,此文本序列在 Google 幻灯片 API 中表示如下:

"textElements": [ {
    "endIndex": 224,
    "paragraphMarker": { "style": {} }
  }, {
    "endIndex": 130,
    "textRun": { "content": "Li lingues differe in li grammatica e li vocabules. Omnicos directe al desirabilite de un nov ", "style": {} }
  }, {
    "endIndex": 143,
    "startIndex": 130,
    "textRun": { "content": "lingua franca", "style": { "italic": True } }
  }, {
    "endIndex": 224,
    "startIndex": 143,
    "textRun": { "content": ": solmen va esser necessi far:\n", "style": {} }
  }, {
    "endIndex": 243,
    "startIndex": 224,
    "paragraphMarker": {
      "style": { "indentStart": { "magnitude": 36, "unit": "PT" }, "direction": "LEFT_TO_RIGHT", "indentFirstLine": { "magnitude": 18, "unit": "PT" }, "spacingMode": "COLLAPSE_LISTS" },
      "bullet": { "listId": "foo123", "glyph": "\u25cf" }
    }
  }, {
    "endIndex": 243,
    "startIndex": 224,
    "textRun": { "content": "uniform grammatica\n", "style": {} }
  }, {
    "endIndex": 257,
    "startIndex": 243,
    "paragraphMarker": {
        "style": { "indentStart": { "magnitude": 36, "unit": "PT" }, "direction": "LEFT_TO_RIGHT", "indentFirstLine": { "magnitude": 18, "unit": "PT" }, "spacingMode": "COLLAPSE_LISTS" },
        "bullet": { "listId": "foo123", "glyph": "\u25cf" }
    }
}, {
    "endIndex": 257,
    "startIndex": 243,
    "textRun": { "content": "Pronunciation\n", "style": {} }
}, {
    "endIndex": 277,
    "startIndex": 257,
    "paragraphMarker": {
        "style": { "indentStart": { "magnitude": 36, "unit": "PT" }, "indentFirstLine": { "magnitude": 18, "unit": "PT" }, "spacingMode": "COLLAPSE_LISTS" },
        "bullet": { "listId": "foo123", "glyph": "\u25cf" }
    }
}, {
    "endIndex": 277,
    "startIndex": 257,
    "textRun": { "content": "plu sommun paroles.\n", "style": {} }
}, {
    "endIndex": 500,
    "startIndex": 277,
    "paragraphMarker": { "style": {} }
}, {
    "endIndex": 500,
    "startIndex": 277,
    "textRun": { "content": "Ka swu thefognay, tay waddeant varpa u inzo.\n", "style": {} }
}]

TextElement 内容

每个文本元素都包含一个从零开始的起始索引结束索引,用于描述该元素在页面元素的全文中的位置,以及以下某种类型的文本对象:

文本类型 说明
ParagraphMarker 此文本元素表示新段落的开始。文本元素的起始索引和结束索引代表段落的完整范围,包括段落结尾的换行符。段落之间不会重叠。段落始终以换行符结尾,因此形状或表格单元格的文本内容末尾始终会有一个换行符。

段落可以属于项目符号列表或编号列表。如果是,则 ParagraphMarker.bullet 字段内容包含列表 ID。此 ID 引用 TextContent 中与 TextElement 序列一起存在的列表元素。同一逻辑列表中的段落将引用相同的列表 ID。
TextRun 此文本元素表示一连串具有相同文本样式的文本。文本行绝不会跨段落边界:即使一段落结尾的文本与下一段落开头的文本采用相同的样式,内容也会在换行符后分隔,形成单独的文本行。

如果您需要处理网页元素内的完整文本字符串,请迭代所有文本元素,并串联所有文本行中找到的字符串。
AutoText 自动文本是指文本中根据上下文而动态变化的位置。在 Google 幻灯片中,此属性用于在文本中表示当前幻灯片编号。

修改文本内容

当您需要使用 Google 幻灯片 API 修改文本时,无需显式创建所有适当的文本元素。不过,您可以像在 Google 幻灯片编辑器中一样对文本进行操作:插入文本、删除范围以及更新范围的样式。这些操作会根据需要隐式创建 ParagraphMarkerTextRun 元素,以反映您的更改。

插入文本

您可以在对 batchUpdate 的调用中使用 InsertTextRequest 请求在某个索引处插入文本。此方法的 insertionIndex 字段用于指定要插入文本的位置;您可以使用文本元素中的起始索引和结束索引字段计算此索引。

插入文本会产生一些副作用,这些副作用与幻灯片编辑器的行为类似:

  • 插入换行符会隐式创建一个新段落,从换行符的索引开始,到下一个换行符结束,创建一个 ParagraphMarker 文本元素。段落样式(包括项目符号和列表详细信息)会从当前段落复制到新段落。
  • 系统会自动确定插入字符的样式,通常会保持与插入索引处相同的文本样式。因此,文本通常会插入到该索引处的现有 TextRun 中。您稍后可以使用 UpdateTextStyle 请求更新此样式。

删除文本

您可以在调用 batchUpdate 时使用 DeleteTextRequest 消息删除一段文本。删除文本涉及一些细节:

  • 如果删除内容跨越段落边界,系统会合并这两个段落,并删除分隔的 ParagraphMarker 文本元素。
  • 新的合并段落将使用组合段落样式,与幻灯片编辑器中的行为一致。
  • 如果删除范围涵盖文本行,则会移除文本行中的所有内容,同时也会删除文本行本身。
  • 如果删除范围涵盖 AutoText 元素,则会删除 AutoText 元素。

更新文本样式

幻灯片中文本的呈现外观取决于文本样式属性:

  • 段落样式(例如缩进、对齐方式和项目符号)由段落标记的属性定义。
  • 粗体、斜体和下划线等字符样式由各个文本行上的属性定义。

更新字符样式

您可以在调用 batchUpdate 时使用 UpdateTextStyleRequest 消息更新字符样式。

与其他文本操作一样,字符样式会应用于文本范围,并根据需要隐式创建新的 TextRun 对象。

设置某些字符样式会隐式更新其他相关样式,以便与幻灯片编辑器中的行为保持一致。例如,添加链接会自动更改文本前景颜色和下划线属性。如需了解详情,请参阅 TextStyle 参考文档。

更新段落样式

您可以在对 batchUpdate 的调用中使用 UpdateParagraphStyleRequest 消息更新段落样式。

Slides API 支持 CreateParagraphBulletsRequest,该请求可反映 Google 幻灯片编辑器中项目符号预设的功能,用于创建项目符号列表和编号列表。同样,DeleteParagraphBulletsRequest 会移除段落中的所有现有项目符号。

继承的样式

某些形状(称为占位符)可以从其他父形状继承文本样式:如需详细了解形状继承,请参阅占位符

本部分重点介绍样式继承的工作原理,以及如何创建幻灯片中显示的最终呈现的文本样式。

占位符中的样式表示

占位符部分介绍了父形状和子形状之间的继承方式。文本样式的继承由继承模型中的其他功能处理:

  • ParagraphMaker 文本元素的属性用于定义段落格式。
  • TextRun 文本元素的属性用于定义字符格式。
  • 父级占位符的内容包含八个这样的 ParagraphMarker/TextRun 对(以支持八层列表嵌套)。
  • 子占位符会从其父级文本内容中的这些文本元素继承其默认文本属性。

下图展示了可视化这些关系的一种方法:

子形状继承文本属性的示意图

父形状中的第一个 ParagraphMarker/TextRun 决定了大部分继承的文本样式;其余七对中的样式仅会影响嵌套得越来越深的项目符号级别的段落:

父文本元素对 它控制的子级格式
ParagraphMarker
TextRun
第 0 级(最外层)列表段落和所有非列表段落的文字样式。
ParagraphMarker
TextRun
其余(嵌套)列表级别 1-7 的文本样式
第三 ParagraphMarker
第三 TextRun
第四 ParagraphMarker
第四 TextRun
第五 ParagraphMarker
第五 TextRun
第六 ParagraphMarker
第六 TextRun
第 7 页ParagraphMarker
第 7 页TextRun
第 8 个 ParagraphMarker
第 8 个 TextRun

如需访问这对文本元素,请在 textElements 字段中使用它们的显式索引,如以下代码段所示,该代码段展示了如何为第 0 级段落和非列表段落设置默认(可继承)样式:

"text": {
  "textElements": [  {
     "startIndex": 0,
     "endIndex": 1,
     "paragraphMarker": {
       "style": {  "alignment": "START",  ...  },
       "bullet": {  "nestingLevel": 0,  ...  }
     }
   },{
     "startIndex": 0,
     "endIndex": 1,
     "textRun": {
       "content": "\n",
       "style": {  "foregroundColor": {  "opaqueColor": {  "themeColor": "DARK1"  }  },  }
     }
   },{
     ...
   } ]
 }

请注意,父形状的 TextRuncontent 字段始终由一个换行符组成。

可以替换继承的样式

子形状可以为其内容中的 ParagraphMarkerTextRun 元素指定样式属性。这些本地指定的属性将替换其本地作用域内的任何继承属性。未指定任何样式的元素将使用从父元素继承的相应样式。

从子形状中移除显式样式属性,使其不再设置,将导致其从父级沿用。

示例

假设形状 ParentPlaceholder 具有以下文本内容,如上图所示的继承关系所示:

"text": {
  "textElements": [
    { "startIndex": 0,  "endIndex": 1,
      "paragraphMarker": {
        "style": {"alignment": "START", ...},
        "bullet": {"nestingLevel": 0, ...}
      }
    },
    { "startIndex": 0,  "endIndex": 1,
      "textRun": {
        "content": "\n",
        "style": {"foregroundColor": {"opaqueColor": {"themeColor": "DARK1"} }, }
        ...
      }
    },
    { "startIndex": 1,  "endIndex": 2,
      "paragraphMarker": {
        "style": {"alignment": "END", ...},
        "bullet": {"nestingLevel": 1, ...}
      }
    },
    { "startIndex": 1,  "endIndex": 2,
      "textRun": {
        "content": "\n",
        "style": {"foregroundColor": {"opaqueColor": {"themeColor": "LIGHT1"} }, ...}
      }
    },
   ...
  ]
}

假设形状 ChildPlaceholder 具有以下文本内容:

"text": {
  "textElements": [
    { "startIndex": 0,  "endIndex": 1,
      "paragraphMarker": {
        "style": {},
      }
    },
    { "startIndex": 0,  "endIndex": 1,
      "textRun": {
        "content": "This is my first paragraph\n",
        "style": {},
      }
      ...
    },
    {  "startIndex": 1,  "endIndex": 2,
      "paragraphMarker": {
        "style": {},
        "bullet": {
          "nestingLevel": 1,
          "listId": "someListId",
          "glyph": "●"
        }
      }
    },
    { "startIndex": 1,  "endIndex": 2,
      "textRun": {
        "content": "This paragraph is in a list\n",
        "style": {},
        ...
      }
    }
  ]
}

这会导致出现以下段落中所述的结果。

纯段落的样式继承

子形状的第一段落(包含“This is my first paragraph”文本)是普通段落(不在列表中)。其文本内容中的任何元素都未指定任何样式属性,因此它会从其父元素继承所有字符和段落样式。这会导致以下渲染:

  • 文本:“This is my first paragraph”是呈现的文本。文本本身永远不会被继承。
  • 对齐方式:文本采用 START 对齐方式呈现,该对齐方式从父级的第一个 ParagraphMarker 继承而来。
  • 前景颜色:文本使用从父项的第一个 TextRun 继承的 DARK1 前景颜色进行渲染。

列表段落的样式继承

由于其对应的 ParagraphMarkerbullet 字段已设置为此级别,因此下一段落(包含“This paragraph is in a list”文本)位于嵌套级别 1 的项目符号列表中。因此,它会从父级中的嵌套级别 1 继承文本和段落样式。这会产生以下渲染结果:

  • 文本:“This paragraph is in a list”(此段落位于列表中)是呈现的文本。文本本身永远不会被继承。
  • 对齐方式:文本采用“END”对齐方式,从父级的第二个 ParagraphMarker 继承。
  • 前景颜色:文本使用从父级的第二个 TextRun 继承的 LIGHT1 文本前景颜色进行渲染。

更新和继承文本和段落样式之间的互动

在子形状中未设置的文本样式将继承其父级的值。在子项中设置的文本样式将“替换”某些本地范围内的父级值。

您可以使用 UpdateTextStyleRequest 取消设置子形状的文本样式,使其不再具有本地替换项,从而从父形状继承其样式。此外,如果将子项的文本样式更新为与从父项继承的值匹配,系统会隐式取消设置样式,以便使用继承的值。

这不会影响更新后文本的视觉外观,但如果您稍后更新父级占位符中的段落或文本样式,则可能会有所影响。这种继承行为与 Google 幻灯片编辑器的行为一致,因此您可以在使用 API 之前,先对样式更改的结果进行实验。

示例

请考虑前面的示例中对 ChildPlaceholderParentPlaceholder 的定义。

现在假设您提交了以下 UpdateTextStyleRequest

{ "updateTextStyle": {
    "objectId": "ChildPlaceholder",
    "style": {"foregroundColor": {"opaqueColor": {"themeColor": "DARK1"} }, },
    "textRange": { "type": "ALL" },
    "fields": "foregroundColor"
  }
}

此请求会尝试将 DARK1 foregroundColor 设置为 ChildPlaceholder 的所有文本,并使用字段掩码指定应仅更改元素的前景色。此请求的结果如下:

  • 第一段:新 foregroundColor 与继承的 foregroundColor 匹配,因此此样式保持不变,并且仍会继承。
  • 第二段:新 foregroundColor 与继承的 foregroundColor 不匹配,因此第二段的前景颜色会更新为 DARK1

ChildPlaceholder 的文本内容现在为:

"text": {
  "textElements": [
    { "startIndex": 0,  "endIndex": 1,
      "paragraphMarker": {
        "style": {},
      }
    },
    { "startIndex": 0,  "endIndex": 1,
      "textRun": {
        "content": "This is my first paragraph\n",
        "style": {},
      }
      ...
    },
    { "startIndex": 1,  "endIndex": 2,
      "paragraphMarker": {
        "style": {},
        "bullet": {"nestingLevel": 1, "listId": "someListId", "glyph": "●" }
      }
    },
    { "startIndex": 1,  "endIndex": 2,
      "textRun": {
        "content": "This paragraph is in a list\n",
        "style": {"foregroundColor": {"opaqueColor": {"themeColor": "DARK1"} }, },
        ...
      }
    }
  ]
}

项目符号字形文本样式

与普通文本一样,项目符号字形也有文本样式,用于控制字形的渲染方式。无法直接使用 Google 幻灯片 API 修改这些文本样式。不过,如果您使用 UpdateTextStyleRequest 更新包含项目符号的完整段落,Google 幻灯片 API 会更新项目符号字体的文本样式以使其与段落保持一致。

与普通文本样式相比,项目符号文本样式的继承层次结构略有不同。

  1. 特定嵌套级别的项目符号首先会从项目符号的 List 对象内的 NestingLevel.bullet_style 字段中设置的 TextStyle 继承。
  2. 接下来,它会从其父级占位符的 List 中的相应 NestingLevel.bullet_style 继承。
  3. 最后,它会尝试从其余父占位符对象继承。