Struktura tekstu i jego styl

W interfejsie Slides API tekst może znajdować się w kształtach lub komórkach tabeli. Zanim zaczniesz manipulować tekstem i nadawać mu styl, musisz poznać jego strukturę i sposób działania stylizacji.

Na tej stronie opisaliśmy, jak tekst jest reprezentowany w interfejsie Slides API.

Sekwencje elementów tekstowych

Tekst zawarty w kształcie lub komórce tabeli składa się z sekwencji struktur TextElement. Ta sekwencja reprezentuje strukturę tekstu w kolejności od początku do końca.

Weź pod uwagę na przykład zawartość tego slajdu, która mieści się w jednym polu tekstowym:

Zrzut ekranu przedstawiający prosty slajd

Ten slajd zawiera jedno pole tekstowe, którego pole text zawiera sekwencję elementów tekstowych, jak pokazano na diagramie poniżej:

Diagram pokazujący sekwencję elementów tekstowych

W przypadku interfejsu Slides API ta sekwencja tekstu wygląda tak:

"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": {} }
}]

Zawartość elementu TextElement

Każdy element tekstowy zawiera wskaźnik początkuwskaźnik końca oparty na 0, które określają jego położenie w całym tekście elementu strony. Element ten może też zawierać jeden z tych typów obiektów tekstowych:

Rodzaj tekstu Opis
ParagraphMarker Ten element tekstowy oznacza początek nowego akapitu. Indeks początkowy i końcowy elementu tekstowego reprezentuje pełny zakres akapitu, w tym znak nowego wiersza, którym akapit się kończy. Akapit nigdy nie pokrywa innego akapitu. Akapity zawsze kończą się znakiem końca wiersza, więc na końcu zawartości tekstowej kształtu lub komórki tabeli zawsze znajduje się znak końca wiersza.

Akapity mogą należeć do list wypunktowanych lub ponumerowanych. Jeśli tak, pole ParagraphMarker.bullet zawiera identyfikator listy. Ten identyfikator odwołuje się do elementu listy, który znajduje się w elementach TextContentTextElement. Akapity w ramach tej samej listy logicznej odwołują się do tego samego identyfikatora listy.
TextRun Ten element tekstowy reprezentuje ciągły ciąg znaków o tym samym stylu. Przebiegi tekstu nigdy nie przekraczają granic akapitów: nawet jeśli tekst kończący jeden akapit ma ten sam styl co tekst rozpoczynający następny akapit, zawartość jest dzielona po znaku nowego wiersza, tworząc osobne przebiegi tekstu.

Jeśli chcesz przetworzyć pełny ciąg tekstowy w elemencie strony, przejdź przez wszystkie elementy tekstowe, łącząc ciągi znalezione we wszystkich przebiegach tekstu.
AutoText Autotext odnosi się do miejsc w tekście, które zmieniają się dynamicznie w zależności od kontekstu. W Prezentacjach służy do oznaczania bieżącego numeru slajdu w tekście.

Modyfikowanie zawartości tekstowej

Jeśli chcesz zmodyfikować tekst za pomocą interfejsu Slides API, nie musisz jawnie tworzyć wszystkich odpowiednich elementów tekstowych. Zamiast tego możesz edytować tekst tak samo jak w edytorze Prezentacji Google: wstawiając tekst, usuwając zakresy i aktualizując style w zakresach. Te operacje tworzą domyślnie elementy ParagraphMarker i TextRun, aby odzwierciedlić wprowadzone zmiany.

Wstawianie tekstu

Możesz wstawić tekst w danym indeksie, korzystając z żądania InsertTextRequest w wywołaniu metody batchUpdate. Pole insertionIndex tej metody określa, gdzie wstawić tekst. Możesz obliczyć ten indeks, korzystając z pol start i end w elementach tekstowych.

Wstawianie tekstu ma pewne efekty uboczne, które odzwierciedlają działanie edytora slajdów:

  • Wstawianie znaku nowej linii powoduje niejawnie utworzenie nowego akapitu, czyli elementu tekstowego ParagraphMarker, który zaczyna się od indeksu nowej linii i kończy na następnej nowej linii. Styl akapitu, w tym odstępy i szczegóły listy, jest kopiowany z bieżącego akapitu do nowego akapitu.
  • Styl wstawianych znaków jest określany automatycznie, zazwyczaj zachowując ten sam styl tekstu, który istniał w miejscu wstawiania. W związku z tym tekst jest zwykle wstawiany do istniejącego elementu TextRun w danym indeksie. Możesz zaktualizować ten styl później, korzystając z żądania UpdateTextStyle.

Usuwanie tekstu

Możesz usunąć fragment tekstu, używając wiadomości DeleteTextRequest w ramach wywołania batchUpdate. Usuwanie tekstu wiąże się z pewnymi subtelnościami:

  • Usunięcie, które przekracza granicę akapitu, powoduje połączenie dwóch akapitów i usunięcie rozdzielającego je elementu tekstowego ParagraphMarker.
  • Nowy połączony akapit będzie używać połączonego stylu akapitu, który będzie odpowiadał działaniu w edytorze slajdów.
  • Usunięcie, którego zakres obejmuje blok tekstu, powoduje usunięcie całej zawartości bloku tekstu, a także samego bloku.
  • Usunięcie elementu, którego zakres obejmuje element AutoText, powoduje usunięcie elementu AutoText.

Aktualizowanie stylu tekstu

Wyrenderowany wygląd tekstu na slajdzie jest określany przez właściwości stylu tekstu:

  • Styl akapitu, np. wcięcie, wyrównanie i znaki wielokropka, są definiowane przez właściwości znaczników akapitu.
  • Style znaków, takie jak pogrubienie, kursywa i podkreślenie, są definiowane przez właściwości poszczególnych przebiegów tekstu.

Aktualizowanie stylu postaci

Styl znaków możesz zaktualizować, wysyłając wiadomość UpdateTextStyleRequest w ramach wywołania batchUpdate.

Podobnie jak w przypadku innych operacji tekstowych styl znaków jest stosowany do zakresu tekstu i w miarę potrzeby tworzy nowe obiekty TextRun.

Ustawienie niektórych stylów znaków powoduje automatyczną aktualizację innych powiązanych stylów, aby dopasować ich działanie do działania w edytorze slajdów. Na przykład dodanie linku automatycznie zmienia kolor tekstu i właściwości podkreślenia. Więcej informacji znajdziesz w dokumentacji TextStyle.

Aktualizowanie stylu akapitu

Możesz zaktualizować style akapitów, używając wiadomości UpdateParagraphStyleRequest w wywołaniu batchUpdate.

Interfejs API Prezentacji obsługuje funkcję CreateParagraphBulletsRequest, która odzwierciedla funkcje wstępnie zdefiniowanych punktów w edytorze Prezentacji służące do tworzenia list punktowanych i ponumerowanych. Podobnie, DeleteParagraphBulletsRequest usuwa wszystkie istniejące wypunktowania w akapitach.

Style dziedziczone

Niektóre kształty, zwane miejscami zadawalnymi, mogą dziedziczyć style tekstu z innych kształtów nadrzędnych. Aby dowiedzieć się więcej o dziedziczeniu kształtów, zapoznaj się z artykułem o miejscach zastępczych.

W tej sekcji omawiamy, jak dziedziczenie stylów służy do tworzenia ostatecznych renderowanych stylów tekstu wyświetlanych na slajdzie.

Reprezentacja stylu w obiektach zastępczych

W sekcji dotyczącej miejsc docelowych opisano, jak dziedziczenie działa w przypadku kształtów nadrzędnych i podrzędnych. Dziedziczenie stylów tekstu jest obsługiwane przez dodatkowe funkcje w ramach modelu dziedziczenia:

  • Formatowanie akapitu określają właściwości elementów tekstowych ParagraphMaker.
  • Właściwości elementów tekstowych TextRun definiują formatowanie znaków.
  • Treść zastępników nadrzędnych zawiera 8 takich par znaczników akapitu/wydruku tekstu (aby obsługiwać 8 poziomów zagnieżdżonych list).
  • Zasób podrzędny dziedziczy domyślne właściwości tekstu z tych elementów tekstowych w treści tekstowej zasobu nadrzędnego.

Na schemacie poniżej pokazano jeden ze sposobów wizualizacji tych relacji:

Schemat kształtu podrzędnego dziedziczącego właściwości tekstu

Pierwszy element ParagraphMarker/TextRun w kształcie nadrzędnym określa większość dziedziczonego stylu tekstu. Styl w pozostałych 7 parach dotyczy tylko akapitów na coraz głębszych poziomach wcięcia:

Para nadrzędnych elementów tekstowych Formatowanie podrzędne, które kontroluje
Pierwszy ParagraphMarker
Pierwszy TextRun
Styl tekstu akapitów na poziomie 0 (zewnętrznym) listy oraz wszystkich akapitów bez list.
Druga ParagraphMarker
Druga TextRun
Styl tekstu pozostałych (zagnieżdżonych) poziomów listy 1–7
Trzeci ParagraphMarker
Trzeci TextRun
Czwarty ParagraphMarker
Czwarty TextRun
Piąty ParagraphMarker
Piąty TextRun
Szósty ParagraphMarker
Szósty TextRun
Siódma ParagraphMarker
Siódma TextRun
Ósmy ParagraphMarker
Ósmy TextRun

Aby uzyskać dostęp do tych par elementów tekstowych, użyj ich jawnego indeksu w polu textElements, jak pokazano w pliku snippet poniżej, który zawiera ustawienie domyślnego (dziedziczonego) formatowania dla poziomu 0 i akapitów bez listy:

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

Pamiętaj, że pole content w elementach nadrzędnych TextRun zawsze składa się z jednego znaku nowego wiersza.

Stylów dziedziczonych można zastąpić

Kształt podrzędny może określać właściwości stylizacji elementów ParagraphMarker i TextRun w swoim kształcie. Te właściwości określone lokalnie zastąpią wszystkie właściwości dziedziczone w ich zakresie lokalnym. Elementy, które nie określają żadnego stylu, będą używać odpowiedniego stylu odziedziczonego z elementu nadrzędnego.

Usunięcie z kształtu podrzędnego właściwości stylu, która nie jest już ustawiona, spowoduje, że kształt odziedziczy tę właściwość od obiektu nadrzędnego.

Przykład

Z wykorzystaniem dziedziczenia pokazanego na diagramie powyżej załóżmy, że kształt ParentPlaceholder ma następującą treść tekstową:

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

Załóżmy, że kształt ChildPlaceholder ma taki tekst:

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

W efekcie prowadzi to do wyników opisanych w dalszych akapitach.

Dziedziczenie stylu w przypadku zwykłego akapitu

Pierwszy akapit kształtu podrzędnego, który zawiera tekst „To jest mój pierwszy akapit”, jest zwykłym akapitem (nie jest na liście). Żaden z elementów zawartości tekstowej nie określa żadnych właściwości stylu, więc wszystkie style znaków i akapitów są dziedziczone z elementu nadrzędnego. Spowoduje to takie renderowanie:

  • Tekst: „To jest mój pierwszy akapit” to renderowany tekst. Tekst nigdy nie jest dziedziczony.
  • Wyrównanie: tekst jest renderowany z wyrównaniem START, dziedziczonym z pierwszego elementu ParagraphMarker nadrzędnego.
  • Kolor pierwszego planu: tekst jest renderowany za pomocą koloru pierwszego planu DARK1, odziedziczonego od pierwszego elementu nadrzędnego TextRun.

Dziedziczenie stylu w przypadku akapitu listy

Kolejny akapit, który zawiera tekst „Ten akapit jest na liście”, jest na liście wypunktowanej na poziomie zagnieżdżonym 1, ponieważ odpowiednie pole ParagraphMarker w elemencie bullet ma ustawione to ustawienie. W efekcie dziedziczy tekst i styl akapitu z poziomu zagnieżdżenia 1 w elemencie nadrzędnym. W efekcie następuje takie renderowanie:

  • Tekst: „This paragraph is in a list” (Ten akapit jest na liście) jest renderowany. Tekst nigdy nie jest dziedziczony.
  • Wyrównanie: tekst jest renderowany z wyrównaniem „END”, dziedziczonym z drugiego elementu ParagraphMarker w elemencie nadrzędnym.
  • Kolor pierwszego planu: tekst jest renderowany za pomocą koloru pierwszego planu tekstu LIGHT1, odziedziczonego z drugiego elementu nadrzędnego TextRun.

Interakcje między aktualizowaniem a dziedziczeniem stylów tekstu i akapitów

Style tekstu, które nie są ustawione w kształcie podrzędnym, odziedziczą wartości z elementu nadrzędnego. Style tekstu ustawione w elementach podrzędnych „zastąpią” wartości nadrzędne w niektórych lokalnych zakresach.

Możesz użyć żądania UpdateTextStyleRequest, aby zresetować styl tekstu kształtu podrzędnego, tak aby nie miał już lokalnego zastąpienia i odziedziczył styl od kształtu nadrzędnego. Dodatkowo, jeśli zaktualizujesz styl tekstu elementu potomnego, aby pasował do wartości odziedzonej od elementu nadrzędnego, ta operacja powoduje niejawne usunięcie stylu, dzięki czemu element potomny będzie używać wartości odziedzonej.

Nie wpływa to na wygląd tekstu bezpośrednio po aktualizacji, ale może mieć znaczenie, jeśli później zaktualizujesz akapit lub styl tekstu w miejscu docelowym nadrzędnym. Dziedziczenie to działa tak samo jak w edytorze Slides, dzięki czemu możesz eksperymentować z efektami zmian stylu przed rozpoczęciem pracy z interfejsem API.

Przykład

Weź pod uwagę definicje zmiennych ChildPlaceholderParentPlaceholderpoprzedniego przykładu.

Załóżmy, że przesyłasz to żądanie UpdateTextStyleRequest:

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

To żądanie próbuje ustawić wartość DARK1 foregroundColor dla całego tekstu ChildPlaceholder, używając maski pola, aby określić, że ma się zmienić tylko kolor pierwszego planu elementu. Ta prośba spowoduje:

  • Pierwszy akapit: nowa wartość foregroundColor jest taka sama jak dziedziczona wartość foregroundColor, więc ten styl pozostaje niezmieniony i nadal jest dziedziczony.
  • Drugi akapit: nowy kolor foregroundColor nie pasuje do odziedziczonego koloru foregroundColor, więc kolor pierwszego planu w drugim akapicie został zmieniony na DARK1.

Treść tekstu ChildPlaceholder to teraz:

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

Styl tekstu znaku punktowego

Podobnie jak zwykły tekst, punkty wyliczenia mają styl tekstu, który określa sposób ich wyświetlania. Tych stylów tekstu nie można modyfikować bezpośrednio za pomocą interfejsu Slides API. Jeśli jednak użyjesz żądania UpdateTextStyleRequest do zaktualizowania całego akapitu, który zawiera punkt, interfejs Slides API zaktualizuje styl tekstu punktu, aby pasował do stylu tekstu akapitu.

Style tekstu symboli punktowanych podlegają nieco innej hierarchii dziedziczenia niż zwykłe style tekstu.

  1. Punkt na określonym poziomie zagnieżdżenia dziedziczy najpierw z TextStyle w polu NestingLevel.bullet_style w obiekcie List punktu.
  2. Następnie dziedziczy wartość z odpowiedniego elementu NestingLevel.bullet_style w ustawieniu List nadrzędnego.
  3. Na koniec próbuje odziedziczyć właściwości z pozostałych obiektów placeholderów nadrzędnych.