Estructura y estilo de texto

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

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

Secuencias de elementos de texto

El texto contenido en una forma o celda de tabla consta de 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, 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

De manera más concreta, 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": {} }
}]

Contenidos 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 la 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 nuevo párrafo. El índice de inicio y fin del elemento de texto representa la extensión completa 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 con 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 celda de tabla.

Los párrafos pueden pertenecer a listas numeradas o con viñetas. 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. Las ejecuciones de texto nunca cruzan los límites de los párrafos: incluso si el texto que termina en un párrafo tiene el mismo estilo que el texto que comienza en el siguiente, el contenido se divide después del carácter de línea nueva para formar ejecuciones de texto independientes.

Si necesitas procesar la cadena de texto completa dentro de un elemento de página, itera todos los elementos de texto y concatena las cadenas que se encuentran en todas las ejecuciones de texto.
AutoText El término Autotexto hace referencia a secciones 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 necesitas modificar texto con la API de Presentaciones, no tienes que crear explícitamente todos los elementos de texto adecuados. En cambio, puedes operar en el texto como lo harías en el editor de Presentaciones: insertando texto, borrando rangos y actualizando los estilos de los rangos. Con estas operaciones, se crean de forma implícita elementos ParagraphMarker y TextRun según sea necesario para reflejar los cambios.

Cómo insertar texto

Puedes insertar texto en un índice mediante 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 fin dentro de los elementos de texto.

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

  • La inserción de un carácter de salto de línea crea de forma implícita un párrafo nuevo y un elemento de texto ParagraphMarker que comienza en el índice del salto de línea y finaliza en la siguiente línea nueva. El diseño 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 de forma automática y, por lo general, mantiene el mismo estilo de texto que existía en el índice de inserción. Como resultado, el texto suele insertarse en el TextRun existente de ese índice. Puedes actualizar este diseño más adelante con una solicitud UpdateTextStyle.

Borrando 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 el límite de un párrafo combina los dos párrafos y borra el elemento de texto ParagraphMarker separado.
  • El nuevo párrafo combinado usará un estilo de párrafo combinado y coincidirá con el comportamiento del editor de Presentaciones.
  • Cuando se realiza una eliminación cuyo rango abarca una ejecución de texto, se quita todo el contenido de esta, además del propio cuerpo.
  • Con una eliminación cuyo rango abarca un elemento AutoText, se borra el elemento AutoText.

Actualizando el estilo del texto

El aspecto renderizado del texto en una diapositiva se determina mediante las propiedades de estilo de texto:

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

Actualizando el estilo de los caracteres

Puedes actualizar estilos de caracteres usando 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 de forma implícita nuevos objetos TextRun según sea necesario.

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

Actualizando el estilo de párrafo

Puedes actualizar diseños de párrafo usando 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 del editor de Presentaciones para la creación de listas con viñetas y números. De manera similar, DeleteParagraphBulletsRequest quita todas las viñetas existentes en los párrafos.

Estilos heredados

Algunas formas, conocidas como placeholders, pueden heredar estilos de otras formas superiores. Consulta los placeholders 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 finales de texto renderizado que se muestran en una diapositiva.

Representación de estilo en marcadores de posición

En la sección sobre placeholders, se describe cómo funciona la herencia entre formas superiores y secundarias. La herencia de estilos de texto se controla mediante funciones adicionales dentro del modelo de herencia:

  • Las propiedades de los elementos de texto de ParagraphMaker definen el formato del párrafo.
  • Las propiedades de los elementos de texto de TextRun definen el formato de caracteres.
  • El contenido de los marcadores de posición superiores incluye ocho pares 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 del contenido de texto del elemento superior.

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

diagrama de una forma secundaria que hereda propiedades de texto

El primer ParagraphMarker/TextRun de la forma superior determina la mayor parte del estilo de texto heredado. El estilo de los siete pares restantes solo afecta a los párrafos en niveles de viñetas anidados a profundidades cada vez más profundos:

Par de elementos de texto superiores Formato secundario que controla
Primer(a) ParagraphMarker
Primer(a) TextRun
Estilo de texto de los párrafos de lista de nivel 0 (más periféricos) y todos los párrafos que no son de lista.
Segundo ParagraphMarker
Segundo TextRun
Estilo de texto de los niveles de lista 1 a 7 restantes (anidados)
Tercera ParagraphMarker
Tercera TextRun
Cuarto ParagraphMarker
Cuarto TextRun
Quinto ParagraphMarker
Quinto TextRun
Sexto ParagraphMarker
Sexto TextRun
Séptimo ParagraphMarker
Séptimo TextRun
Octavo ParagraphMarker
Octavo 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 cómo configurar el estilo predeterminado (heredable) para los párrafos de nivel 0 y no 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 del elemento TextRun de una forma superior siempre consta de un solo carácter de salto de línea.

Los estilos heredados se pueden anular

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

La eliminación de una propiedad de estilo explícita de una forma secundaria, a fin de que ya no esté configurada, hará que herede del elemento 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 da como resultado los resultados descritos en los párrafos siguientes.

Herencia de estilo de un párrafo sin formato

El primer párrafo de la forma secundaria, que incluye el texto "This is my first paragraph", es un párrafo sin formato (no está en una lista). Ningún elemento de su contenido de texto especifica propiedades de estilo, por lo que hereda todos sus estilos de caracteres y párrafo de su elemento superior. Esto provoca la siguiente renderización:

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

Herencia de estilo para un párrafo de lista

El siguiente párrafo, que incluye el texto "This paragraph is in a list" (este párrafo está en una lista), está en una lista con viñetas en el nivel de anidamiento 1, ya que el ParagraphMarker correspondiente tiene su campo bullet establecido en este nivel. Como resultado, hereda el estilo de texto y párrafo del nivel de anidamiento 1 en el elemento superior. Esto da como resultado la siguiente renderización:

  • Texto: "Este párrafo está en una lista" es el texto procesado. El texto nunca se hereda.
  • Alineación: el texto se renderiza con la alineación "END", heredada del segundo elemento ParagraphMarker del elemento superior.
  • Color en primer plano: El texto se renderiza con el color de primer plano del texto LIGHT1, heredado 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 estén configurados en una forma secundaria heredarán valores de la forma superior. Los estilos de texto que se configuren en el elemento secundario “anularán” los valores superiores en un alcance local.

Puedes usar una instancia de UpdateTextStyleRequest para anular la configuración del estilo de texto de una forma secundaria, de modo que ya no tenga una anulación local y 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 anula la configuración de forma implícita del diseño para que use el valor heredado.

Esto no afecta el aspecto visual del texto inmediatamente después de una actualización, pero puede ser importante si más adelante actualizas un estilo de párrafo o texto en un marcador de posición superior. Este comportamiento de herencia coincide con el del editor de Presentaciones, de modo que puedes experimentar con los resultados de los cambios de diseño antes de trabajar en 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"
  }
}

El objetivo de esta solicitud es establecer un primer plano de color DARK1 en todo el texto de ChildPlaceholder usando una máscara de campo para especificar que solo deba 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 diseño no se modifica y se sigue heredando.
  • Segundo párrafo: el foregroundColor nuevo 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 del marcador de posición 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 de 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 renderizan. Estos estilos de texto no se pueden modificar usando directamente la API de Presentaciones. Sin embargo, si usas una UpdateTextStyleRequest para actualizar un párrafo completo que incluya una viñeta, la API de Presentaciones actualiza el estilo de texto del glifo de la viñeta para que coincida.

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

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