Estructura y estilo de texto

En la API de Slides, el texto puede estar contenido en formas o en celdas de tabla. Antes de poder manipular y aplicar diseño al texto, debes comprender su estructura y cómo funciona el diseño.

En esta página, se describe cómo se representa el texto en la API de Slides.

Secuencias de elementos de texto

El texto contenido en una forma o una celda de tabla está formado por una secuencia de estructuras TextElement. Esta secuencia representa la estructura del texto, en el orden en que aparece de principio a fin.

Por ejemplo, considera el contenido de esta diapositiva, que se encuentra todo en un cuadro de texto:

captura de pantalla de una diapositiva simple

La diapositiva anterior tiene un cuadro de texto cuyo campo text contiene una secuencia de elementos de texto, como se muestra en el siguiente diagrama:

diagrama que muestra una secuencia de elementos de texto

Más concretamente, esta secuencia de texto se representa en la API de Presentaciones de la siguiente manera:

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

Contenido de TextElement

Cada elemento de texto contiene un índice de inicio y un índice de finalización basados en cero, que describen la ubicación del elemento dentro del texto completo del elemento de página, junto con uno de los siguientes tipos de objetos de texto:

Tipo de texto Descripción
ParagraphMarker Este elemento de texto representa el inicio de un párrafo nuevo. El índice de inicio y finalización del elemento de texto representa el intervalo completo del párrafo, incluido el carácter de línea nueva que lo finaliza. Un párrafo nunca se superpone con otro. Los párrafos siempre terminan en un carácter de línea nueva, por lo que siempre hay una línea nueva al final del contenido de texto de una forma o una celda de tabla.

Los párrafos pueden pertenecer a listas con viñetas o numeradas. Si es así, el contenido del campo ParagraphMarker.bullet incluye un ID de lista. Este ID hace referencia a un elemento de lista que existe dentro de TextContent junto con la secuencia TextElement. Los párrafos dentro de la misma lista lógica se referirán al mismo ID de lista.
TextRun Este elemento de texto representa una cadena contigua de texto que tiene el mismo estilo de texto. Los tramos de texto nunca cruzan los límites de los párrafos: incluso si el texto que finaliza un párrafo tiene el mismo estilo que el texto que inicia el siguiente párrafo, el contenido se divide después del carácter de línea nueva para formar tramos de texto separados.

Si necesitas procesar la cadena de texto completa dentro de un elemento de página, itera por todos los elementos de texto y concatena las cadenas que se encuentran en todos los tramos de texto.
AutoText El texto automático hace referencia a lugares del texto que cambian de forma dinámica según el contexto. En Presentaciones, se usa para representar el número de diapositiva actual dentro del texto.

Cómo modificar el contenido de texto

Cuando necesites modificar texto con la API de Slides, no es necesario que creas de forma explícita todos los elementos de texto adecuados. En su lugar, puedes operar en el texto como lo harías en el editor de Presentaciones: insertar texto, borrar rangos y actualizar estilos en rangos. Estas operaciones crean implícitamente elementos ParagraphMarker y TextRun según sea necesario para reflejar tus cambios.

Cómo insertar texto

Puedes insertar texto en un índice con la solicitud InsertTextRequest en una llamada a batchUpdate. El campo insertionIndex de este método especifica dónde insertar el texto. Puedes calcular este índice con los campos de índice de inicio y finalización dentro de los elementos de texto.

La inserción de texto tiene algunos efectos secundarios que reflejan el comportamiento del editor de Presentaciones:

  • Si insertas un carácter de salto de línea, se crea implícitamente un párrafo nuevo, lo que genera un elemento de texto ParagraphMarker que comienza en el índice del salto de línea y termina en el siguiente. El estilo de párrafo, incluidos los detalles de viñetas y listas, se copia del párrafo actual al nuevo.
  • El estilo de los caracteres insertados se determina automáticamente y, por lo general, se mantiene el mismo estilo de texto que existía en el índice de inserción. Como resultado, el texto generalmente se inserta en el TextRun existente en ese índice. Puedes actualizar este estilo más adelante con una solicitud UpdateTextStyle.

Cómo borrar texto

Puedes borrar un rango de texto con el mensaje DeleteTextRequest en una llamada a batchUpdate. Borrar texto implica algunas sutilezas:

  • Una eliminación que cruza un límite de párrafo combina los dos párrafos y borra el elemento de texto ParagraphMarker que los separa.
  • El nuevo párrafo combinado usará un estilo de párrafo combinado que coincidirá con el comportamiento en el editor de diapositivas.
  • Una eliminación cuyo rango abarca una ejecución de texto quita todo el contenido de una ejecución de texto y también borra la ejecución de texto.
  • Una eliminación cuyo rango abarca un elemento AutoText borra el elemento AutoText.

Cómo actualizar el estilo de texto

La apariencia renderizada del texto en una diapositiva se determina según las propiedades del estilo de texto:

  • Los estilos de párrafo, como la sangría, la alineación y los glifos de viñetas, se definen con propiedades en los marcadores de párrafo.
  • Los estilos de caracteres, como negrita, cursiva y subrayado, se definen con propiedades en tramos de texto individuales.

Cómo actualizar el estilo de los caracteres

Puedes actualizar los estilos de los caracteres con el mensaje UpdateTextStyleRequest en una llamada a batchUpdate.

Al igual que otras operaciones de texto, el estilo de caracteres se aplica a un rango de texto y crea implícitamente objetos TextRun nuevos según sea necesario.

La configuración de algunos estilos de caracteres actualiza de forma implícita otros estilos relacionados para que coincidan con el comportamiento del editor de diapositivas. Por ejemplo, agregar un vínculo cambia automáticamente el color de primer plano del texto y las propiedades de subrayado. Consulta la documentación de referencia de TextStyle para obtener más detalles.

Cómo actualizar el estilo de párrafo

Puedes actualizar los estilos de párrafo con el mensaje UpdateParagraphStyleRequest en una llamada a batchUpdate.

La API de Presentaciones admite una CreateParagraphBulletsRequest que refleja la funcionalidad de los ajustes predeterminados de viñetas en el editor de Presentaciones para crear listas con viñetas y numeradas. Del mismo modo, DeleteParagraphBulletsRequest quita las viñetas existentes de los párrafos.

Estilos heredados

Algunas formas, conocidas como marcadores de posición, pueden heredar estilos de texto de otras formas superiores. Consulta marcadores de posición para obtener más información sobre la herencia de formas en general.

En esta sección, se explica cómo funciona la herencia de estilos para crear los estilos de texto renderizados finales que se muestran en una diapositiva.

Representación de estilo en marcadores de posición

En la sección sobre marcadores de posición, se describe cómo funciona la herencia entre formas superiores e inferiores. La herencia de los estilos de texto se controla con funciones adicionales dentro del modelo de herencia:

  • Las propiedades de los elementos de texto ParagraphMaker definen el formato de párrafo.
  • Las propiedades de los elementos de texto TextRun definen el formato de los caracteres.
  • El contenido de los marcadores de posición superiores contiene ocho pares de ParagraphMarker/TextRun (para admitir ocho niveles de anidación de listas).
  • Un marcador de posición secundario hereda sus propiedades de texto predeterminadas de estos elementos de texto en el contenido de texto de su elemento superior.

En el siguiente diagrama, se muestra una forma de visualizar estas relaciones:

diagrama de la forma secundaria que hereda propiedades de texto

El primer ParagraphMarker/TextRun en la forma superior determina la mayor parte de los estilos de texto heredados. Los estilos de los siete pares restantes solo afectan a los párrafos en niveles de viñetas anidados de forma más profunda:

Par de elementos de texto superior El formato secundario que controla
Primeros ParagraphMarker
Primeros TextRun
Es el diseño de texto de los párrafos de lista de nivel 0 (más externo) y de todos los párrafos que no son de lista.
Segundo ParagraphMarker
Segundo TextRun
Estilo de texto de los niveles de lista restantes (anidados) del 1 al 7
Tercer ParagraphMarker
Tercer TextRun
Cuarto ParagraphMarker
Cuarto TextRun
Quinto ParagraphMarker
Quinto TextRun
Sexto ParagraphMarker
Sexto TextRun
Séptima ParagraphMarker
Séptima TextRun
Octava ParagraphMarker
Octava TextRun

Para acceder a estos pares de elementos de texto, usa su índice explícito dentro del campo textElements, como se muestra en el siguiente fragmento, que muestra la configuración del estilo predeterminado (heredable) para el nivel 0 y los párrafos que no son de 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"  }  },  }
     }
   },{
     ...
   } ]
 }

Ten en cuenta que el campo content de TextRun de una forma superior siempre consta de un solo carácter de salto de línea.

Se pueden anular los estilos heredados

Una forma secundaria puede especificar propiedades de diseño en los elementos ParagraphMarker y TextRun en su contenido. Estas propiedades especificadas de forma local anularán cualquier propiedad heredada dentro de su alcance local. Los elementos que no especifiquen ningún estilo usarán el estilo correspondiente heredado del elemento superior.

Si quitas una propiedad de diseño explícita de una forma secundaria para que ya no se establezca, esta heredará la forma superior.

Ejemplo

Dada la herencia que se muestra en el diagrama anterior, supongamos que la forma ParentPlaceholder tiene el siguiente contenido 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"} }, ...}
      }
    },
   ...
  ]
}

Supongamos que la forma ChildPlaceholder tiene el siguiente contenido 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": {},
        ...
      }
    }
  ]
}

Esto genera los resultados que se describen en los siguientes párrafos.

Herencia de estilo para un párrafo sin formato

El primer párrafo de la forma secundaria, que incluye el texto "Este es mi primer párrafo", es un párrafo simple (no está en una lista). Ningún elemento de su contenido de texto especifica ninguna propiedad de diseño, por lo que hereda todos sus diseños de caracteres y párrafos de su elemento superior. Esto provoca la siguiente renderización:

  • Texto: “Este es mi primer párrafo” es el texto renderizado. El texto en sí nunca se hereda.
  • Alineación: El texto se renderiza con alineación START, heredada del primer ParagraphMarker del elemento superior.
  • Color de primer plano: El texto se renderiza con el color de primer plano DARK1, que se hereda del primer TextRun del elemento superior.

Herencia de estilo para un párrafo de lista

El siguiente párrafo, que incluye el texto “Este párrafo está en una lista”, se encuentra en una lista con viñetas en el nivel de anidación 1, ya que su ParagraphMarker correspondiente tiene su campo bullet establecido en este nivel. Como resultado, hereda el texto y el estilo de párrafo del nivel de anidación 1 en el elemento superior. Esto genera la siguiente renderización:

  • Texto: "Este párrafo está en una lista" es el texto renderizado. El texto en sí nunca se hereda.
  • Alineación: El texto se renderiza con la alineación "END", heredada del segundo ParagraphMarker del elemento superior.
  • Color de primer plano: El texto se renderiza con el color de primer plano de texto LIGHT1, que se hereda del segundo TextRun del elemento superior.

Interacciones entre la actualización y la herencia de estilos de texto y párrafo

Los estilos de texto que no se establezcan en una forma secundaria heredarán valores de su elemento superior. Los diseños de texto que se establezcan en el elemento secundario “anularán” los valores superiores en algún alcance local.

Puedes usar un UpdateTextStyleRequest para anular el estilo de texto de una forma secundaria, de modo que ya no tenga una anulación local y, por lo tanto, herede sus estilos de la forma superior. Además, actualizar el estilo de texto del elemento secundario para que coincida con el valor heredado de un elemento superior desconfigura implícitamente el estilo para que use el valor heredado.

Esto no afecta la apariencia visual del texto inmediatamente después de una actualización, pero puede ser importante si más adelante actualizas un párrafo o un estilo de texto en un marcador de posición superior. Este comportamiento de herencia coincide con el del editor de diapositivas, por lo que puedes experimentar con los resultados de los cambios de estilo antes de trabajar con la API.

Ejemplo

Considera las definiciones del ejemplo anterior para ChildPlaceholder y ParentPlaceholder.

Ahora supongamos que envías esta UpdateTextStyleRequest:

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

Esta solicitud intenta establecer un foregroundColor DARK1 para todo el texto de ChildPlaceholder, con una máscara de campo para especificar que solo debe cambiar el color de primer plano del elemento. Esta solicitud tiene los siguientes resultados:

  • Primer párrafo: El nuevo foregroundColor coincide con el foregroundColor heredado, por lo que este estilo no cambia y sigue heredando.
  • Segundo párrafo: El nuevo foregroundColor no coincide con el foregroundColor heredado, por lo que el color de primer plano del segundo párrafo se actualiza a DARK1.

El contenido de texto de ChildPlaceholder ahora es:

"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 del glifo de viñeta

Al igual que el texto normal, los glifos de viñetas tienen un estilo de texto que controla cómo se renderiza el glifo. Estos estilos de texto no se pueden modificar directamente con la API de Presentaciones. Sin embargo, si usas un UpdateTextStyleRequest para actualizar un párrafo completo que incluye una viñeta, la API de Slides actualiza el estilo de texto del glifo de viñeta para que coincida.

Los estilos de texto de los glifos de viñetas siguen una jerarquía de herencia ligeramente diferente a la de los estilos de texto normales.

  1. Una viñeta en un nivel de anidación determinado primero hereda del TextStyle establecido en el campo NestingLevel.bullet_style dentro del objeto List de la viñeta.
  2. Luego, hereda del NestingLevel.bullet_style correspondiente en el List de su marcador de posición superior.
  3. Por último, busca heredar de los objetos de marcador de posición superior restantes.