Estrutura e estilo do texto

Na API Slides, o texto pode estar em formas ou células de tabela. Antes de manipular e estilizar o texto, você precisa entender a estrutura dele e como o estilo funciona.

Esta página descreve como o texto é representado na API Slides.

Sequências de elementos de texto

O texto contido em uma forma ou célula de tabela é composto por uma sequência de estruturas TextElement. Essa sequência representa a estrutura do texto, na ordem em que aparece do início ao fim.

Por exemplo, considere o conteúdo deste slide, tudo contido em uma caixa de texto:

captura de tela de um slide simples

O slide acima tem uma caixa de texto, cujo campo text contém uma sequência de elementos de texto, conforme mostrado no diagrama a seguir:

diagrama mostrando uma sequência de elementos de texto

Mais especificamente, essa sequência de texto é representada na API Slides da seguinte forma:

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

Conteúdo do TextElement

Cada elemento de texto contém um índice de início e um índice de fim baseados em zero, que descrevem a localização do elemento no texto completo do elemento da página, junto com um dos seguintes tipos de objeto de texto:

Tipo de texto Descrição
ParagraphMarker Esse elemento de texto representa o início de um novo parágrafo. O índice inicial e final do elemento de texto representa o período completo do parágrafo, incluindo o caractere de nova linha que termina o parágrafo. Um parágrafo nunca se sobrepõe a outro. Os parágrafos sempre terminam com um caractere de nova linha, portanto, sempre há uma nova linha no final do conteúdo de texto de uma forma ou célula de tabela.

Os parágrafos podem pertencer a listas com marcadores ou numeradas. Nesse caso, o conteúdo do campo ParagraphMarker.bullet inclui um ID de lista. Esse ID faz referência a um elemento de lista que existe em TextContent com a sequência TextElement. Os parágrafos na mesma lista lógica vão se referir ao mesmo ID de lista.
TextRun Esse elemento de texto representa uma string contígua de texto que tem o mesmo estilo de texto. As corridas de texto nunca atravessam os limites de parágrafo: mesmo que o texto que termina um parágrafo tenha o mesmo estilo do texto que inicia o próximo parágrafo, o conteúdo é dividido após o caractere de nova linha para formar corridas de texto separadas.

Se você precisar processar a string de texto completa em um elemento de página, itere por todos os elementos de texto, concatenando as strings encontradas em todas as corridas de texto.
AutoText O texto automático se refere a lugares no texto que mudam dinamicamente dependendo do contexto. Nas Apresentações, esse valor é usado para representar o número do slide atual no texto.

Modificar o conteúdo de texto

Quando você precisa modificar o texto usando a API Slides, não é necessário criar explicitamente todos os elementos de texto apropriados. Em vez disso, você pode operar no texto como faria no editor de slides: inserindo texto, excluindo intervalos e atualizando estilos em intervalos. Essas operações criam implicitamente elementos ParagraphMarker e TextRun conforme necessário para refletir as mudanças.

Inserir texto

É possível inserir texto em um índice usando a solicitação InsertTextRequest em uma chamada para batchUpdate. O campo insertionIndex deste método especifica onde inserir o texto. É possível calcular esse índice usando os campos de índice inicial e final dentro de elementos de texto.

A inserção de texto tem alguns efeitos colaterais que refletem o comportamento do editor do app Slides:

  • Inserir um caractere de nova linha cria implicitamente um novo parágrafo, criando um elemento de texto ParagraphMarker que começa no índice da nova linha e termina na próxima nova linha. O estilo do parágrafo, incluindo os marcadores e os detalhes da lista, é copiado do parágrafo atual para o novo parágrafo.
  • O estilo dos caracteres inseridos é determinado automaticamente, geralmente mantendo o mesmo estilo de texto que existia no índice de inserção. Como resultado, o texto geralmente é inserido no TextRun existente nesse índice. É possível atualizar esse estilo mais tarde usando uma solicitação UpdateTextStyle.

Excluir texto

É possível excluir um intervalo de texto usando a mensagem DeleteTextRequest em uma chamada para batchUpdate. A exclusão de texto envolve algumas sutilezas:

  • Uma exclusão que cruza um limite de parágrafo mescla os dois parágrafos, excluindo o elemento de texto ParagraphMarker que separa.
  • O novo parágrafo mesclado vai usar um estilo de parágrafo combinado, com o mesmo comportamento no editor de slides.
  • Uma exclusão cujo intervalo abrange uma execução de texto remove todo o conteúdo de uma execução de texto e também exclui a própria execução de texto.
  • Uma exclusão cujo intervalo abrange um elemento AutoText exclui o elemento AutoText.

Como atualizar o estilo do texto

A aparência renderizada do texto em um slide é determinada pelas propriedades do estilo de texto:

  • Os estilos de parágrafo, como recuo, alinhamento e glifos de marcadores, são definidos por propriedades em marcadores de parágrafo.
  • Os estilos de caracteres, como negrito, itálico e sublinhado, são definidos por propriedades em execuções de texto individuais.

Atualizar o estilo do caractere

É possível atualizar estilos de caracteres usando a mensagem UpdateTextStyleRequest em uma chamada para batchUpdate.

Assim como outras operações de texto, o estilo de caractere é aplicado a um intervalo de texto e cria implicitamente novos objetos TextRun conforme necessário.

A definição de alguns estilos de caracteres atualiza implicitamente outros estilos relacionados para corresponder ao comportamento no editor do Apresentações. Por exemplo, adicionar um link muda automaticamente a cor do primeiro plano do texto e as propriedades de sublinhado. Consulte a documentação de referência de TextStyle para mais detalhes.

Atualizar o estilo do parágrafo

É possível atualizar estilos de parágrafo usando a mensagem UpdateParagraphStyleRequest em uma chamada para batchUpdate.

A API Slides oferece suporte a uma CreateParagraphBulletsRequest que reflete a funcionalidade das predefinições de marcadores no editor de slides para criação de listas com marcadores e numeradas. Da mesma forma, DeleteParagraphBulletsRequest remove todos os marcadores dos parágrafos.

Estilos herdados

Algumas formas, conhecidas como marcadores de posição, podem herdar estilos de texto de outras formas pai. Consulte marcadores de posição para saber mais sobre a herança de formas em geral.

Esta seção se concentra em como a herança de estilo funciona para criar os estilos de texto renderizados finais exibidos em um slide.

Representação de estilo em marcadores de posição

A seção sobre marcadores de posição descreve como a herança funciona entre formas principais e secundárias. A herança de estilos de texto é processada por outros recursos no modelo de herança:

  • As propriedades dos elementos de texto do ParagraphMaker definem a formatação de parágrafo.
  • As propriedades dos elementos de texto TextRun definem a formatação de caracteres.
  • O conteúdo dos marcadores de posição pai contém oito pares de ParagraphMarker/TextRun (para oferecer suporte a oito níveis de aninhamento de listas).
  • Um marcador de posição filho herda as propriedades de texto padrão desses elementos de texto no conteúdo de texto do elemento pai.

O diagrama a seguir mostra uma maneira de visualizar essas relações:

diagrama de uma forma filha que herda propriedades de texto

O primeiro marcador de parágrafo/texto na forma pai determina a maior parte do estilo de texto herdado. O estilo nos sete pares restantes afeta apenas os parágrafos em níveis de marcadores aninhados cada vez mais profundos:

Par de elementos de texto pai Formatação filha controlada por ele
Primeiro ParagraphMarker
Primeiro TextRun
Estilo de texto de parágrafos de lista de nível 0 (mais externo) e todos os parágrafos que não são de lista.
Segundo ParagraphMarker
Segundo TextRun
Estilo de texto dos níveis 1 a 7 das listas (aninhadas) restantes
Terceira ParagraphMarker
Terceira TextRun
Quarta ParagraphMarker
Quarta TextRun
Quinto ParagraphMarker
Quinto TextRun
Sexto ParagraphMarker
Sexto TextRun
Sétima ParagraphMarker
Sétima TextRun
Oitava ParagraphMarker
Oitava TextRun

Para acessar esses pares de elementos de texto, use o índice explícito deles no campo textElements, conforme mostrado no snippet abaixo, que mostra a configuração do estilo padrão (heredável) para o nível 0 e parágrafos sem lista:

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

O campo content do TextRun de uma forma pai sempre consiste em um único caractere de nova linha.

Os estilos herdados podem ser substituídos

Uma forma filha pode especificar propriedades de estilo nos elementos ParagraphMarker e TextRun no conteúdo. Essas propriedades especificadas localmente vão substituir todas as propriedades herdadas no escopo local. Os elementos que não especificam nenhum estilo vão usar o estilo correspondente herdado do elemento pai.

Se você remover uma propriedade de estilo explícita de uma forma filha, para que ela não seja mais definida, ela vai herdar da forma mãe.

Exemplo

Dada a herança mostrada no diagrama acima, suponha que a forma ParentPlaceholder tenha o seguinte conteúdo de texto:

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

E suponha que a forma ChildPlaceholder tenha o seguinte conteúdo de texto:

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

Isso resulta nos resultados descritos nos parágrafos a seguir.

Herança de estilo para um parágrafo simples

O primeiro parágrafo da forma filho, que inclui o texto "Este é meu primeiro parágrafo", é um parágrafo simples (não em uma lista). Nenhum elemento no conteúdo de texto especifica propriedades de estilo. Portanto, ele herda todos os estilos de caractere e parágrafo do elemento pai. Isso causa a seguinte renderização:

  • Texto: "This is my first paragraph" é o texto renderizado. O texto em si nunca é herdado.
  • Alinhamento: o texto é renderizado com o alinhamento START, herdado do primeiro ParagraphMarker do pai.
  • Cor do primeiro plano: o texto é renderizado com a cor de primeiro plano DARK1, herdada do primeiro TextRun do pai.

Herança de estilo para um parágrafo de lista

O próximo parágrafo, que inclui o texto "Este parágrafo está em uma lista", está em uma lista com marcadores no nível de aninhamento 1, porque o ParagraphMarker correspondente tem o campo bullet definido para esse nível. Como resultado, ele herda o estilo de texto e parágrafo do nível 1 de aninhamento no elemento pai. Isso resulta na renderização abaixo:

  • Texto: "Este parágrafo está em uma lista" é o texto renderizado. O texto em si nunca é herdado.
  • Alinhamento: o texto é renderizado com o alinhamento "END", herdado do segundo ParagraphMarker do elemento pai.
  • Cor do primeiro plano: o texto é renderizado com a cor de primeiro plano do texto LIGHT1, herdada do segundo TextRun do elemento pai.

Interações entre a atualização e a herança de estilos de texto e parágrafo

Os estilos de texto que não forem definidos em uma forma filha vão herdar valores da forma mãe. Os estilos de texto definidos na criança "substituem" os valores da mãe em algum escopo local.

É possível usar uma UpdateTextStyleRequest para redefinir o estilo de texto de uma forma filha, para que ela não tenha mais uma substituição local e, portanto, herde os estilos da forma pai. Além disso, atualizar o estilo de texto da criança para corresponder ao valor herdado de um pai reinicia implicitamente o estilo para que ele use o valor herdado.

Isso não afeta a aparência visual do texto imediatamente após uma atualização, mas pode ser importante se você atualizar um parágrafo ou estilo de texto em um marcador pai mais tarde. Esse comportamento de herança corresponde ao comportamento do editor de slides. Assim, você pode testar os resultados das mudanças de estilo antes de trabalhar com a API.

Exemplo

Considere as definições no exemplo anterior para ChildPlaceholder e ParentPlaceholder.

Agora, suponha que você envie esta UpdateTextStyleRequest:

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

Essa solicitação tenta definir uma foregroundColor DARK1 para todo o texto do ChildPlaceholder, usando uma máscara de campo para especificar que apenas a cor do primeiro plano do elemento precisa mudar. Essa solicitação tem os seguintes resultados:

  • Primeiro parágrafo: o novo foregroundColor corresponde ao foregroundColor herdado. Portanto, esse estilo não muda e ainda é herdado.
  • Segundo parágrafo: o novo foregroundColor não corresponde ao foregroundColor herdado. Portanto, a cor de primeiro plano do segundo parágrafo é atualizada para DARK1.

O conteúdo de texto de ChildPlaceholder agora é:

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

Estilo de texto do glifo de marcador

Assim como o texto normal, os glifos de marcadores têm um estilo de texto que controla como o glifo é renderizado. Esses estilos de texto não podem ser modificados diretamente usando a API Slides. No entanto, se você usar um UpdateTextStyleRequest para atualizar um parágrafo completo que inclui um marcador, a API Slides vai atualizar o estilo de texto do marcador para corresponder.

Os estilos de texto de glifos de marcadores seguem uma hierarquia de herança um pouco diferente dos estilos de texto normais.

  1. Um marcador em um determinado nível de aninhamento herda primeiro do conjunto TextStyle no campo NestingLevel.bullet_style dentro do objeto List do marcador.
  2. Em seguida, ele herda do NestingLevel.bullet_style correspondente no List do marcador de posição pai.
  3. Por fim, ele tenta herdar dos objetos de marcador de posição pai restantes.