Compartir a través de


Formato del Portapapeles HTML

Los requisitos para transferir texto HTML mediante el Portapapeles difieren en función del escenario. Este artículo se ocupa de cortar y pegar fragmentos de un documento HTML. Puede haber requisitos para transferir documentos HTML completos a través del Portapapeles; Sin embargo, este artículo se basa en un requisito para transferir fragmentos de texto HTML seleccionado. Por lo tanto, un método que requería copiar todo el documento HTML en el Portapapeles se considera demasiado pesado.

El CF_HTML formato del Portapapeles permite almacenar un fragmento de texto HTML sin formato y su contexto (es decir, HTML externo) en el Portapapeles como ASCII. Esto permite examinar el contexto del fragmento HTML, que consta de todas las etiquetas adyacentes anteriores, para que una aplicación pueda observar las etiquetas circundantes del fragmento HTML con sus atributos. Aunque depende de las aplicaciones decidir cómo interpretar estos fragmentos, aquí se incluyen algunas directrices básicas basadas en implementaciones de IE4/MSHTML.

El nombre oficial del Portapapeles (la cadena usada por RegisterClipboardFormat) es "HTML Format".

Descripción

CF_HTML es un formato de Portapapeles de texto, aunque siempre se usa la codificación UTF-8. Tenga en cuenta que el uso de UTF-8 aquí es una excepción a la regla general que la API de Windows usa UTF-16 para representar cadenas de texto, especialmente cadenas legibles (es decir, localizables).

Puede describir el diseño general o la sintaxis del CF_HTML Portapapeles en forma pseudo-Backus–Naur de la siguiente manera:

Nota

Esta gramática no es normativa**

<cf-html>                ::= <description-header> <context>
<context>                ::= [<preceding-context>] <fragment> [<trailing-context>]

<description-header>     ::= "Version:" <version> <br> ( <header-offset-keyword> ":" <header-offset-value> <br> )*
<header-offset-keyword>  ::= "StartHTML" | "EndHTML" | "StartFragment" | "EndFragment" | "StartSelection" | "EndSelection"
<header-offset-value>    ::= { Base 10 (decimal) integer string with optional _multiple_ leading zero digits (see "Offset syntax" below) }
<version>                ::= "0.9" | "1.0"
<fragment>               ::= <fragment-start-comment> <fragment-text> <fragment-end-comment>
<fragment-start-comment> ::= "<!--StartFragment -->"
<fragment-end-comment>   ::= "<!--EndFragment -->"
<preceding-context>      ::= { Arbitrary HTML }
<trailing-context>       ::= { Arbitrary HTML }
<fragment-text>          ::= { Arbitrary HTML }
<br>                     ::= "\r" | "\n" | "\r\n"

Encabezados y desplazamientos de descripción

El encabezado de descripción incluye el número de versión y los desplazamientos del Portapapeles, lo que indica dónde comienza y finaliza el contexto y el fragmento. La descripción es una lista de palabras clave de texto ASCII seguidas de una cadena y separadas por dos puntos (:).

  • Version: número de versión vv del Portapapeles. La versión inicial es Version:0.9. A partir de Windows 10 20H2, ahora Version:1.0es .
  • StartHTML: desplazamiento (en bytes) desde el principio del Portapapeles hasta el inicio del contexto, o -1 si no hay contexto.
  • EndHTML: desplazamiento (en bytes) desde el principio del Portapapeles hasta el final del contexto, o -1 si no hay contexto.
  • StartFragment: desplazamiento (en bytes) desde el principio del Portapapeles hasta el inicio del fragmento.
  • EndFragment: desplazamiento (en bytes) desde el principio del Portapapeles hasta el final del fragmento.
  • StartSelection: Opcional. Desplazamiento (en bytes) desde el principio del Portapapeles hasta el inicio de la selección.
  • EndSelection: Opcional. Desplazamiento (en bytes) desde el principio del Portapapeles hasta el final de la selección.

Las StartSelection palabras clave y EndSelection son opcionales y deben omitirse si no desea que la aplicación genere esta información.

Las revisiones futuras del formato del CF_HTML Portapapeles pueden extender el encabezado, por ejemplo, ya que el CÓDIGO HTML comienza en el StartHTML desplazamiento, se podrían agregar varios StartFragment pares y EndFragment más adelante para admitir la selección nocontiguosa de fragmentos.

Sintaxis de desplazamiento

Para mayor comodidad de los programas que generan los desplazamientos de bytes, los valores de desplazamiento pueden ser opcionalmente rellenados a la izquierda con una cantidad arbitraria de cero dígitos '0'. La razón de esto es que los programas que examinan el HTML de los desplazamientos podrían escribir diez (10) ceros en su búfer de salida para cada palabra clave (por ejemplo StartHTML: 0000000000, ). Más adelante, cuando se conoce el desplazamiento exacto StartHTML (por ejemplo, 71), el programa puede sobrescribir los ceros más a la derecha con "71" en el búfer (por ejemplo, dando lugar a StartHTML: 0000000071).

El único juego de caracteres admitido por el Portapapeles es Unicode (UTF-8). Dado que los primeros caracteres de UTF-8 y ASCII coinciden, la descripción siempre es ASCII, pero los bytes del contexto (a partir StartHTMLde ) podrían usar cualquier otro carácter codificado en UTF-8.

Los extremos de las líneas del encabezado de formato del Portapapeles (<br> arriba) pueden representarse mediante CRLF (Windows), LF (Unix) o CR solitario (arcaica).

El fragmento, la selección y su contexto

Elemento Encabezados de descripción Requiere HTML válido para las posiciones de caracteres inicial y final.
Context StartHTML y EndHTML
Fragmento StartFragment y EndFragment
Número de selección StartSelection y EndSelection No

Context

El contexto es un documento HTML válido y completo, aunque esto no significa que todo el documento HTML de origen original que contenga la selección del usuario se llevará a cabo en el texto; por el contrario, puede ser un documento HTML mínimo, pero bien formado.

Este contexto contiene el fragmento y todas las etiquetas adyacentes anteriores (etiquetas iniciales y finales; estas etiquetas adyacentes anteriores representan todos los nodos primarios del fragmento, hasta el nodo HTML). El artículo de ejemplo anterior tiene un elemento HTML <head> completo que permite el uso de <base href=""> elementos y <title> . Por ejemplo, este elemento se puede insertar para obtener esta información adicional. Una aplicación que copia un fragmento de HTML en el Portapapeles puede elegir crear un <base href=""> elemento para incluirlo en el contexto si dicho elemento aún no está presente. De este modo, se pueden resolver URI no absolutas en el fragmento HTML.

El contexto es opcional, ya que se incluye información suficiente en el fragmento para el pegado básico de un fragmento HTML que se va a realizar. Si el contexto no está almacenado, el fragmento solo se almacena y .StartHTML=EndHTML=-1

Fragmento

El fragmento (<fragment-text> anterior) contiene un fragmento HTML válido.

Un fragmento HTML válido consta de un único elemento HTML externo. Este elemento puede contener elementos HTML descendientes siempre que estén anidados correctamente. Por ejemplo, un fragmento podría ser un único <div> elemento que contiene 3 <p> elementos. Un fragmento que consta de un <span> elemento que contiene tres <p> elementos no sería válido porque un <span> elemento (un elemento) no puede contener elementos de nivel de bloque como elementos secundarios.

Por lo tanto, el fragmento representa eficazmente el área mayor en pantalla dentro de la que el usuario realizó su selección de texto (para copiar, por ejemplo). La selección contiene el texto seleccionado más las etiquetas de apertura y los atributos de cualquier elemento que tenga una etiqueta final dentro del texto seleccionado y etiquetas finales al final del fragmento para cualquier etiqueta de inicio incluida. Esta es toda la información necesaria para pegar un fragmento HTML básico.

El fragmento debe ir precedido y seguido de los comentarios <!--StartFragment--> HTML e <!--EndFragment--> indicar dónde se inicia y termina el fragmento; estos comentarios HTML deben usarse textualmente, sin caracteres de espacio en blanco dentro de cada comentario en sí. Por lo tanto, el inicio y el final del fragmento se indican mediante la presencia de estos comentarios y los StartFragment encabezados y EndFragment . Se espera que las herramientas generen esta información. Esta redundancia es intencionada y se introdujo para poder encontrar el inicio del fragmento (del recuento de bytes) y marcar la posición del fragmento directamente en el árbol HTML.

Número de selección

La selección es opcional porque se incluye suficiente información en el fragmento para pegar básicamente. Si la selección no está almacenada, tanto StartSelection como EndSelection no se almacenan en el encabezado.

Si está presente, la selección es el intervalo de texto exacto que el usuario ha seleccionado (dentro del fragmento); esto agrega más información al fragmento indicando el texto seleccionado exacto, sin las etiquetas iniciales y finales equilibradas y equilibradas.

Recuerde que la selección puede representar una ejecución de texto que puede iniciarse en cualquier elemento determinado y finalizar en cualquier elemento posterior ( o antecesor ). Por lo tanto, es imposible representar una selección de texto mediante HTML.

Escenarios

En los escenarios siguientes se describe cómo el editor HTML IE4/MSHTML controla el corte y pega HTML; Otras aplicaciones pueden seguir o no estos escenarios. El formato del Portapapeles descrito aquí está pensado para permitir la flexibilidad de cómo una aplicación elige funcionar. (Estos escenarios solo muestran un buen código HTML, es decir, ninguna etiqueta superpuesta).

Escenario 1: fragmento simple de HTML

Supongamos el siguiente texto HTML:

<body>This is normal. <b>This is bold.</b> <i><b>This is bold italic.</b> This is italic.</i></body>

Esto aparecerá de la siguiente manera:

Eso es normal. Esto es negrita.Esto es cursiva en negrita.Esto es cursiva.

Cuando el usuario ha cargado el texto HTML anterior en una aplicación basada en MSHTML (MSHTML, también conocido como Trident, era el motor de Internet Explorer), MSHTML controla la copia de una subcadena de HTML de la siguiente manera:

  1. El usuario selecciona un texto sin espacios en blanco iniciales o finales, por ejemplo, "bold This is bold italic This" en el ejemplo anterior.
  2. Para copiar el texto en el Portapapeles, el usuario hace clic en el botón Copiar comando.

MSHTML colocará este texto HTML en el Portapapeles de Windows como se indica a continuación:

Version:1.0
StartHTML:0121
EndHTML:0272
StartFragment:0006
EndFragment:0106
StartSelection:0180
EndSelection:0225
<html><!--StartFragment--><body>This is normal. <b>This is bold.</b> <i><b>This is bold italic.</b> This is italic.</i></body><!--EndFragment--></html>

Escenario 2: fragmento de una tabla en HTML

Supongamos el siguiente texto HTML:

<BODY><TABLE BORDER><TR><TH ROWSPAN=2>Head1</TH><TD>Item 1</TD><TD>Item 2</TD><TD>Item 3</TD><TD>Item 4</TD></TR><TR><TD>Item 5</TD><TD>Item 6</TD><TD>Item 7</TD><TD>Item 8</TD></TR><TR><TH>Head2</TH><TD>Item 9</TD><TD>Item 10</TD><TD>Item 11</TD><TD>Item 12</TD></TR></TABLE></BODY>

Aparecerá como se indica a continuación:

Cabeza 1 Elemento 1 Item 2 Item 3 Elemento 4
Elemento 5 Elemento 6 Elemento 7 Elemento 8
Cabeza 2 Elemento 9 Elemento 10 Elemento 11 Elemento 12

Cómo MSHTML controla la copia de una subcadena de HTML desde una tabla

Cuando el usuario usa el mouse para realizar una selección de texto que abarque las celdas de tabla Item 6, Item 7, Item 10 y Item 11. Esta selección se copia en el Portapapeles.

Lo siguiente es lo que estará en el Portapapeles (tenga en cuenta que esta es la interpretación de IE4/MSHTML). Se han agregado saltos de línea para mayor claridad.

<!DOCTYPE
<HTML>
<BODY>
<TABLE BORDER>
<!--StartFragment-->
  **<TR>
    <TD>Item 6</TD>
    <TD>Item 7</TD>
  </TR>
  <TR>
    <TD>Item 10</TD>
    <TD>Item 11</TD>
  </TR>**
<!--EndFragment-->
</TABLE>
</BODY>
</HTML>

La selección, tal como está delimitada por StartSelection y EndSelection, se muestra en negrita.

Escenario 3: pegado de un fragmento de una lista <ol> ordenada en texto sin formato

Supongamos el siguiente texto HTML:

<BODY><OL TYPE="a"><LI>Item 1<LI>Item 2<LI>Item 3<LI>Item 4<LI>Item 5<LI>Item 6</OL></BODY>

Aparecerá como se indica a continuación:

  1. Elemento 1
  2. Item 2
  3. Item 3
  4. Elemento 4
  5. Elemento 5
  6. Elemento 6

Cómo MSHTML controla la copia de una subcadena de elementos de lista numerados HTML

  1. El usuario realiza una selección de texto desde el principio del elemento 3, hasta el elemento 4 y hasta el final del elemento 5. El usuario invoca el comando Copy.
  2. El código HTML siguiente se encuentra en el Portapapeles (saltos de línea agregados para mayor claridad): la ubicación precisa de los <!--Star/EndFragment --> comentarios depende de cómo el usuario controló la lógica de selección de texto del explorador:
<html>
<body>
<ol>
<!-- StartFragment-->
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<!-- EndFragment-->
</ol>
</body>
</html>

Si este fragmento se pegara ahora en un documento vacío, se creará el código HTML siguiente:

<body>
<ol>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ol>
</body>

Aparecerá como se indica a continuación:

  1. Item 3
  2. Elemento 4
  3. Elemento 5

Escenario 5: pegado de una región parcialmente seleccionada

Supongamos el siguiente texto HTML:

<p>IE4/MSHTML is a WYSIWYG Editor that supports:</p>
<ul><li>Cut<li>Copy<li>Paste</ul>
<p>This is a Great Tool!</p>

Aparecerá como se indica a continuación:

IE4/MSHTML es un editor WYSIWYG que admite:

  • Cortar
  • Copiar
  • Pegar

¡Esta es una gran herramienta!

Cómo MSHTML controla la copia de una subcadena de elementos de lista HTML

El usuario usa el mouse para arrastrar una selección de texto, por ejemplo, "WYSIWYG Editor que admite: Cut Cop". Como si fuera texto sin formato, esa selección tendría el siguiente fragmento HTML roto:

WYSIWYG Editor, which supports:</p>
<ul>
  <li>Cut</li>
  <li>Cop

Cuando el usuario presiona el botón Copiar comando, su Portapapeles tendrá este aspecto (se han agregado saltos de línea para mayor claridad; el texto en negrita denota lo que el usuario seleccionó realmente):

<html>
<body>
<!-- StartFragment-->
<p>WYSIWYG Editor, which supports</p>
<ul>
	<li>Cut</li>
	<li>Cop</li>
</ul>
<!-- EndFragment-->
</body>
</html>

Observe lo siguiente:

  • Se quitó el texto anterior a "WYSIWYG".
  • El elemento de lista (<li>Paste</li>) se quitó como ninguno de él estaba en la selección del usuario.
  • Se quitó "y" de "Copy".

Consulte también

Portapapeles