テキストの構造とスタイル

Slides API では、テキストを図形または表のセル内に含めることができます。テキストを操作してスタイル設定する前に、テキストの構造とスタイル設定の仕組みを理解する必要があります。

このページでは、Slides API でテキストがどのように表されるかについて説明します。

テキスト要素のシーケンス

シェイプまたは表セルに含まれるテキストは、TextElement 構造のシーケンスで構成されています。このシーケンスは、テキストの構造を最初から最後まで表示する順序で表します。

たとえば、このスライドの内容はすべて 1 つのテキスト ボックスに含まれています。

シンプルなスライドのスクリーンショット

上のスライドには 1 つのテキスト ボックスがあり、次の図に示すように、その text フィールドにはテキスト要素のシーケンスが含まれています。

テキスト要素の順序を示す図

具体的には、このテキストのシーケンスは Slides 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 このテキスト要素は、すべて同じテキスト スタイルを持つ連続したテキスト文字列を表します。テキスト行は段落の境界を越えません。1 つの段落の末尾のテキストのスタイルが次の段落の開始テキストのスタイルと同じ場合でも、内容は改行文字の後に分割され、個別のテキスト行を形成します。

ページ要素内のテキスト文字列全体を処理する必要がある場合は、すべてのテキスト要素を反復処理し、すべてのテキスト行で見つかった文字列を連結します。
AutoText 自動テキストとは、コンテキストに応じて動的に変化するテキスト内の場所を指します。スライドでは、テキスト内に現在のスライド番号を表すために使用されます。

テキスト コンテンツの変更

Slides API を使用してテキストを変更する必要がある場合、適切なテキスト要素をすべて明示的に作成する必要はありません。代わりに、スライド エディタで行うように、テキストの挿入、範囲の削除、範囲のスタイルの更新などの操作を行うことができます。これらのオペレーションは、変更を反映するために必要に応じて ParagraphMarker 要素と TextRun 要素を暗黙的に作成します。

テキストの挿入

インデックスにテキストを挿入するには、batchUpdate の呼び出しで InsertTextRequest リクエストを使用します。このメソッドの insertionIndex フィールドには、テキストを挿入する場所を指定します。このインデックスは、テキスト要素内の開始インデックス フィールドと終了インデックス フィールドを使用して計算できます。

テキストの挿入には、スライド エディタの動作を反映する副作用があります。

  • 改行文字を挿入すると、新しい段落が暗黙的に作成され、改行のインデックスから次の改行までが ParagraphMarker テキスト要素になります。段落スタイル(箇条書きやリストの詳細など)が、現在の段落から新しい段落にコピーされます。
  • 挿入される文字のスタイルは自動的に決定されます。通常は、挿入インデックスに存在していたテキスト スタイルと同じスタイルが保持されます。そのため、通常、テキストはそのインデックスの既存の TextRun に挿入されます。このスタイルは、後で UpdateTextStyle リクエストを使用して更新できます。

テキストの削除

テキストの範囲を削除するには、batchUpdate の呼び出しで DeleteTextRequest メッセージを使用します。テキストの削除には、いくつかの注意点があります。

  • 段落境界をまたぐ削除を行うと、2 つの段落が統合され、分離する ParagraphMarker テキスト要素が削除されます。
  • 新しい統合された段落では、スライド エディタの動作に合わせて、結合された段落スタイルが使用されます。
  • 範囲がテキスト行に及ぶ削除では、テキスト行のすべてのコンテンツが削除され、テキスト行自体も削除されます。
  • 範囲が AutoText 要素を含む削除では、AutoText 要素が削除されます。

テキスト スタイルの更新

スライド内のテキストのレンダリングされた外観は、テキスト スタイルのプロパティによって決まります。

  • インデント、配置、箇条書き記号などの段落スタイルは、段落マーカーのプロパティで定義されます。
  • 太字、斜体、下線などの文字スタイルは、個々のテキスト行の属性によって定義されます。

文字スタイルの更新

文字スタイルを更新するには、batchUpdate の呼び出しで UpdateTextStyleRequest メッセージを使用します。

他のテキスト操作と同様に、文字スタイルはテキストの範囲に適用され、必要に応じて新しい TextRun オブジェクトが暗黙的に作成されます。

一部の文字スタイルを設定すると、スライド エディタの動作に合わせて、関連する他のスタイルが暗黙的に更新されます。たとえば、リンクを追加すると、テキストの前景色と下線のプロパティが自動的に変更されます。詳細については、TextStyle リファレンス ドキュメントをご覧ください。

段落スタイルの更新

段落スタイルを更新するには、batchUpdate の呼び出しで UpdateParagraphStyleRequest メッセージを使用します。

Slides API は、箇条書きと番号付きリストの作成に使用できる、スライド エディタの箇条書きプリセットの機能をミラーリングする CreateParagraphBulletsRequest をサポートしています。同様に、DeleteParagraphBulletsRequest は、段落の既存の箇条書きを削除します。

継承されたスタイル

プレースホルダと呼ばれる一部のシェイプは、他の親シェイプからテキスト スタイルを継承できます。シェイプの継承全般については、プレースホルダをご覧ください。

このセクションでは、スタイルの継承がどのように機能して、スライドに表示される最終的なレンダリングされたテキスト スタイルが作成されるかについて説明します。

プレースホルダでのスタイルの表現

プレースホルダのセクションでは、親シェイプと子シェイプ間の継承の仕組みについて説明します。テキスト スタイルの継承は、継承モデル内の追加機能によって処理されます。

  • ParagraphMaker テキスト要素のプロパティで段落の書式を定義します。
  • TextRun テキスト要素のプロパティで文字の書式設定を定義します。
  • 親プレースホルダの内容には、このような ParagraphMarker/TextRun ペアが 8 つ含まれています(リストのネストを 8 レベルまでサポートするため)。
  • 子プレースホルダは、親のテキスト コンテンツ内のこれらのテキスト要素からデフォルトのテキスト プロパティを継承します。

次の図は、これらの関係を可視化する方法の 1 つを示しています。

子シェイプがテキスト プロパティを継承する図

親図形の最初の ParagraphMarker/TextRun によって、継承されるテキスト スタイルの大部分が決まります。残りの 7 つのペアのスタイルは、ネストされた箇条書きレベルが深くなるにつれて段階的に段落に影響します。

親テキスト要素ペア 制御する子書式
最初の ParagraphMarker
最初の TextRun
レベル 0(最外側)のリスト パラグラフと、リスト以外のすべてのパラグラフのテキスト スタイル。
2 つ目の ParagraphMarker
2 つ目の TextRun
残りの(ネストされた)リストレベル 1 ~ 7 のテキスト スタイル
3 つ目の ParagraphMarker
3 つ目の TextRun
4 つ目の ParagraphMarker
4 つ目の TextRun
5 番目 ParagraphMarker
5 番目 TextRun
6 番目 ParagraphMarker
6 番目 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 フィールドは、常に 1 つの改行文字で構成されます。

継承したスタイルをオーバーライドできる

子シェイプは、コンテンツ内の ParagraphMarker 要素と TextRun 要素にスタイル設定プロパティを指定できます。ローカルで指定されたプロパティは、ローカル スコープ内の継承プロパティをオーバーライドします。スタイルを指定しない要素は、親から継承された対応するスタイルを使用します。

子シェイプから明示的なスタイル プロパティを削除して設定しないようにすると、親から継承されます。

上の図に示す継承を前提として、シェイプ 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」というテキストがレンダリングされます。テキスト自体は継承されません。
  • 配置: テキストは、親の最初の ParagraphMarker から継承された START 配置でレンダリングされます。
  • 前景色: テキストは、親の最初の TextRun から継承された DARK1 前景色でレンダリングされます。

リストの段落のスタイルの継承

次の段落(「This paragraph is in a list」というテキストを含む段落)は、対応する ParagraphMarkerbullet フィールドがこのレベルに設定されているため、ネストレベル 1 の箇条書きリストに表示されます。その結果、親のネストレベル 1 からテキストと段落スタイルが継承されます。結果として、次のようなレンダリングが生成されます。

  • テキスト: レンダリングされたテキストは「This paragraph is in a list」です。テキスト自体は継承されません。
  • 配置: テキストは、親の 2 番目の ParagraphMarker から継承された「END」配置でレンダリングされます。
  • 前景色: テキストは、親の 2 番目の TextRun から継承された LIGHT1 テキスト前景色でレンダリングされます。

テキストと段落のスタイルの更新と継承の相互作用

子シェイプで設定されていないテキスト スタイルは、親から値を継承します。子で設定されたテキスト スタイルは、一部のローカル スコープで親の値を「オーバーライド」します。

UpdateTextStyleRequest を使用して、子シェイプのテキスト スタイルを設定解除し、ローカル オーバーライドを解除して、親シェイプからスタイルを継承できます。また、親から継承された値と一致するように子テキスト スタイルを更新すると、継承された値を使用するようにスタイルが暗黙的に設定解除されます。

これは、更新直後のテキストの視覚的な外観には影響しませんが、後で親プレースホルダ内の段落またはテキスト スタイルを更新する場合は重要になる可能性があります。この継承動作はスライド エディタの動作と一致するため、API を使用する前にスタイル変更の結果をテストできます。

ChildPlaceholderParentPlaceholder前述の例の定義について考えてみましょう。

次のような UpdateTextStyleRequest を送信したとします。

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

このリクエストは、フィールド マスクを使用して、要素の前景色のみを変更するように指定し、ChildPlaceholder のすべてのテキストに DARK1 の foregroundColor を設定しようとします。このリクエストの結果は次のとおりです。

  • 最初の段落: 新しい foregroundColor は継承された foregroundColor と一致するため、このスタイルは変更されず、引き続き継承されます。
  • 2 番目の段落: 新しい foregroundColor が継承された foregroundColor と一致しないため、2 番目の段落の前景色が 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"} }, },
        ...
      }
    }
  ]
}

箇条書きグリフのテキスト スタイル

通常のテキストと同様に、箇条書きのグリフには、グリフのレンダリング方法を制御するテキスト スタイルがあります。これらのテキスト スタイルは、スライド API を直接使用して変更することはできません。ただし、UpdateTextStyleRequest を使用して箇条書きを含む段落全体を更新すると、Slides API は箇条書きのグリフのテキスト スタイルを一致するように更新します。

箇条書きのグリフ テキスト スタイルの継承階層は、通常のテキスト スタイルとは若干異なります。

  1. 特定のネストレベルの箇条書きは、まず箇条書きの List オブジェクト内の NestingLevel.bullet_style フィールドで設定された TextStyle から継承します。
  2. 次に、親プレースホルダの List 内の対応する NestingLevel.bullet_style から継承します。
  3. 最後に、残りの親プレースホルダ オブジェクトから継承しようとします。