文字結構和樣式

在 Google 簡報 API 中,文字可以包含在形狀或表格儲存格中。 您必須先瞭解文字的結構和樣式的運作方式,才能操控文字及設定文字樣式。

本頁將說明 Slide API 中的文字呈現方式。

文字元素序列

形狀或表格儲存格中的文字由一系列 TextElement 結構組成。這個序列代表文字的結構,並依照文字的顯示順序排列。

例如,請思考這張投影片的內容,全都包含在一個文字方塊內:

簡易投影片的螢幕截圖

上張投影片有一個文字方塊,其中的 text 欄位包含一系列文字元素,如下圖所示:

顯示文字元素序列的圖表

更具體地說,這段文字序列在 Slide 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 會參照 TextElement 序列位於 TextContent 內的清單元素。同一個邏輯清單中的段落會參照同一個清單 ID。
TextRun 這個文字元素代表連續字串,而且文字樣式都相同。文字一律不會跨段落劃過:即使結束某一段落的文字樣式與下一個段落的文字樣式相同,系統仍會在換行字元後分割內容,以形成個別的文字。

如果您需要處理網頁元素中的完整文字字串,請將所有文字元素串連執行,再將所有文字元素串連起來執行。
AutoText 「自動文字」是指文字內容中的位置,會依據上下文動態變動。在 Google 簡報中,這會在文字中代表目前的投影片編號。

修改文字內容

使用 Slide API 修改文字時,您不必明確建立所有適當的文字元素。您可以改為在簡報編輯器中操作文字,包括插入文字、刪除範圍,以及更新範圍的樣式。這些作業視需要以隱含方式建立 ParagraphMarkerTextRun 元素,以反映您的變更。

插入文字

您可以在對 batchUpdate 的呼叫中使用 InsertTextRequest 要求,在索引處插入文字。這個方法的 insertionIndex 欄位會指定文字插入位置;您可以使用文字元素內的開始和結束索引欄位計算這個索引。

文字插入功能有一些連帶效果,會反映簡報編輯器的行為:

  • 插入換行字元會以隱含方式建立新段落,建立 ParagraphMarker 文字元素,該元素從新行的索引開始,結束於後續的新行。段落樣式 (包括項目符號和清單詳細資料) 會從目前段落複製到新段落。
  • 插入字元的樣式會自動決定,一般會保留插入索引處相同的文字樣式。因此,文字通常會在該索引的現有 TextRun 中插入。您稍後可以使用 UpdateTextStyle 要求更新這個樣式。

正在刪除文字

您可以在對 batchUpdate 的呼叫中使用 DeleteTextRequest 訊息刪除特定範圍的文字。刪除文字需要留意:

  • 跨段落的刪除會合併兩個段落,刪除分隔的 ParagraphMarker 文字元素。
  • 新的合併段落會使用合併的段落樣式,與簡報編輯器中的行為相符。
  • 如果刪除範圍涵蓋文字執行,系統會移除文字執行中的所有內容,同時刪除文字執行本身。
  • 如果刪除範圍涵蓋 AutoText 元素,就會刪除 AutoText 元素。

正在更新文字樣式

投影片中文字的轉譯外觀取決於文字樣式屬性:

  • 注射、對齊和項目符號字符等段落樣式是由段落標記上的屬性定義。
  • 粗體、斜體和底線等字元樣式是由個別文字執行的屬性定義。

正在更新字元樣式

您可以使用對 batchUpdate 呼叫中的 UpdateTextStyleRequest 訊息更新字元樣式。

和其他文字作業一樣,字元樣式會套用至一段文字,並視需要以隱含方式建立新的 TextRun 物件。

設定部分字元樣式會間接更新其他相關樣式,以符合簡報編輯器中的行為。舉例來說,新增連結會自動變更文字前景的顏色和底線屬性。詳情請參閱「TextStyle」參考說明文件。

正在更新段落樣式

您可以使用對 batchUpdate 呼叫中的 UpdateParagraphStyleRequest 訊息更新段落樣式。

簡報 API 支援 CreateParagraphBulletsRequest,這與簡報編輯器中項目符號預設設定的功能同步,以便建立項目符號和編號清單。同樣地,DeleteParagraphBulletsRequest 會移除段落中現有的任何項目符號。

沿用的樣式

部分形狀稱為placeholders,可沿用其他父項形狀的文字樣式。如要深入瞭解形狀繼承的一般資訊,請參閱placeholders

本節著重介紹樣式沿用的運作方式,以建立投影片中顯示的最終算繪文字樣式。

預留位置中的樣式表示法

placeholders中的章節會說明父項和子項形狀之間的繼承如何運作。文字樣式的繼承作業是由繼承模型中的其他地圖項目處理:

  • ParagraphMaker 文字元素的屬性會定義段落格式。
  • TextRun 文字元素的屬性會定義字元格式。
  • 父項預留位置的內容包含八個這類 ParagraphMarker/TextRun 配對 (為了支援八層清單巢狀結構)。
  • 子預留位置會繼承父項文字內容中的這些文字元素預設文字屬性。

下圖顯示以視覺化方式呈現這些關聯的方法:

子形狀沿用文字屬性的圖表

父項形狀中的第一個 ParagraphMarker/TextRun 決定了大部分沿用的文字樣式;其餘 7 組的樣式則只會影響到深入巢狀項目符號層級的段落:

父項文字元素組合 所控制的子格式設定
ParagraphMarker
TextRun
第 0 層 (最外) 清單段落的文字樣式,以及所有非清單段落的文字樣式。
第二個 ParagraphMarker
第二個TextRun
其餘 (巢狀) 清單層級 1 到 7 的文字樣式
第三ParagraphMarker
TextRun
ParagraphMarker
四個TextRun
第五ParagraphMarker
TextRun
第六ParagraphMarker
TextRun
ParagraphMarker
TextRun
第八ParagraphMarker
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 (這是我的第一個段落)」是純文字 (而不是清單中)。文字內容中沒有任何元素指定任何樣式屬性,因此會沿用父項的所有字元和段落樣式。這會產生以下轉譯結果:

  • 文字:「這是我的第一個段落」是指呈現的文字。絕不會沿用文字本身。
  • 對齊:文字會以 START 對齊方式呈現,繼承父項的第一個 ParagraphMarker
  • 前景顏色:文字將以 DARK1 前景顏色算繪,繼承自父項的第一個 TextRun

清單段落的樣式沿用機制

下一個段落包含「This paragraph is in a list」的文字,在巢狀層級 1 中,因為其對應的 ParagraphMarkerbullet 欄位已設為該層級。因此,它會沿用父項第 1 層巢狀結構的文字和段落樣式。這會產生下列轉譯結果:

  • 文字:「This paragraph is in a list」是指顯示的文字。絕不會沿用文字本身。
  • 對齊:文字會以「END」對齊方式呈現,繼承父項的第二個 ParagraphMarker
  • 前景顏色:文字會以 LIGHT1 文字前景顏色算繪,繼承自父項的第二個 TextRun

更新及沿用文字和段落樣式之間的互動

未在子形狀中設定的文字樣式會沿用父項的值。在子項中設定的文字樣式會「覆寫」某些本機範圍內的父項值。

您可以使用 UpdateTextStyleRequest 取消設定子項形狀的文字樣式,這樣一來,子形狀的文字樣式就不再具有本機覆寫,因此會沿用父項形狀的音符。此外,如果更新子項的文字樣式,使其符合從父項沿用的值,則會隱含取消設定樣式,改用沿用的值。

這不會影響文字在更新後立即顯示的視覺呈現,但如果稍後在父項預留位置中更新段落或文字樣式,就可能會很重要。這項繼承行為與簡報編輯器的行為相符,因此您可以先測試樣式變更的結果,再使用 API。

範例

請參考上一個範例中的 ChildPlaceholderParentPlaceholder 定義。

現在假設您提交了這個 UpdateTextStyleRequest

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

這項要求會嘗試使用欄位遮罩DARK1 前景色彩設為所有子項預留位置的文字,藉此指定僅應變更元素的前景顏色。這項要求的結果如下:

  • 第一個段落:新的 foregroundColor 與繼承的 foregroundColor 相符,因此這個樣式保持不變,仍會沿用。
  • 第二段:新的 foregroundColor 與沿用的 foregroundColor 不相符,因此第二個段落的前景顏色會更新為 DARK1

目前子項預留位置的文字內容為:

"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"} }, },
        ...
      }
    }
  ]
}

項目符號字符文字樣式

與一般文字一樣,項目符號字符具有文字樣式,用於控製字符的呈現方式。這些文字樣式無法直接使用 deck API 修改。不過,如果您使用 UpdateTextStyleRequest 更新包含項目符號的完整段落,Slide API 就會更新項目符號字符的文字樣式以便保持一致。

項目符號文字樣式採用的沿用階層與一般文字樣式稍有不同。

  1. 特定巢狀層級的項目符號會先沿用項目符號 List 物件中 NestingLevel.bullet_style 欄位所設定的 TextStyle
  2. 下一個會繼承父項預留位置 List 中對應的 NestingLevel.bullet_style
  3. 最後,它會試著繼承剩餘的父項預留位置物件。