Formato Appunti HTML
I requisiti per il trasferimento di testo HTML tramite gli Appunti variano a seconda dello scenario. Questo articolo riguarda il taglio e incolla di frammenti di un documento HTML. Potrebbero esserci requisiti per il trasferimento di interi documenti HTML attraverso gli Appunti; Tuttavia, questo articolo è basato su un requisito per trasferire frammenti di testo HTML selezionato. Di conseguenza, un metodo che richiede la copia dell'intero documento HTML negli Appunti viene considerato troppo pesante.
Il CF_HTML
formato degli Appunti consente l'archiviazione di un frammento di testo HTML non elaborato e del relativo contesto (ovvero html esterno) negli Appunti come ASCII. In questo modo il contesto del frammento HTML, costituito da tutti i tag circostanti precedenti, può essere esaminato da un'applicazione in modo che i tag circostanti del frammento HTML possano essere annotati con i relativi attributi. Anche se spetta alle applicazioni decidere come interpretare tali frammenti, alcune linee guida di base sono incluse qui in base alle implementazioni IE4/MSHTML.
Il nome ufficiale degli Appunti (la stringa usata da RegisterClipboardFormat
) è "HTML Format
".
Descrizione
CF_HTML
è un formato degli Appunti di testo, anche se usa sempre la codifica UTF-8. Si noti che l'uso di UTF-8 qui è un'eccezione alla regola generale che l'API di Windows usa UTF-16 per rappresentare le stringhe di testo, in particolare le stringhe leggibili dall'utente (ad esempio localizzabili).
È possibile descrivere il layout generale o la sintassi degli CF_HTML
Appunti in formato pseudo-Backus-Naur, come illustrato di seguito:
Nota
Questa grammatica non è 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"
Intestazioni e offset della descrizione
L'intestazione della descrizione include il numero di versione e gli offset degli Appunti, che indicano dove inizia e termina il contesto e il frammento. La descrizione è un elenco di parole chiave di testo ASCII seguite da una stringa e separate da due punti (:).
Version
: numero di versione vv degli Appunti. La versione iniziale èVersion:0.9
. A partire da Windows 10 20H2 questo è oraVersion:1.0
.StartHTML
: offset (in byte) dall'inizio degli Appunti all'inizio del contesto o-1
se non è presente alcun contesto.EndHTML
: offset (in byte) dall'inizio degli Appunti alla fine del contesto o-1
se non è presente alcun contesto.StartFragment
: offset (in byte) dall'inizio degli Appunti all'inizio del frammento.EndFragment
: offset (in byte) dall'inizio degli Appunti alla fine del frammento.StartSelection
: facoltativo. Offset (in byte) dall'inizio degli Appunti all'inizio della selezione.EndSelection
: facoltativo. Offset (in byte) dall'inizio degli Appunti alla fine della selezione.
Le StartSelection
parole chiave e EndSelection
sono facoltative e devono essere entrambe omesse se non si vuole che l'applicazione generi queste informazioni.
Le revisioni future del CF_HTML
formato degli Appunti possono estendere l'intestazione, ad esempio, poiché il codice HTML inizia con l'offset StartHTML
, è possibile aggiungere più StartFragment
coppie e EndFragment
in un secondo momento per supportare la selezione non contigua di frammenti.
Sintassi offset
Per praticità dei programmi che generano gli offset dei byte, i valori di offset possono essere facoltativamente riempiti a sinistra con una quantità arbitraria di zero cifre '0'
. Il motivo è che i programmi che analizzano il codice HTML per gli offset possono scrivere dieci (10) zeri nel buffer di output per ogni parola chiave (ad esempio StartHTML: 0000000000
). Successivamente, quando l'offset esatto StartHTML
è noto (ad esempio, 71), il programma può sovrascrivere gli zeri più a destra con "71" nel buffer (ad esempio, risultante in StartHTML: 0000000071
).
L'unico set di caratteri supportato dagli Appunti è Unicode (UTF-8). Poiché i primi caratteri di UTF-8 e ASCII corrispondono, la descrizione è sempre ASCII, ma i byte del contesto (a partire da StartHTML
) potrebbero usare qualsiasi altro carattere codificato in UTF-8.
Le estremità delle righe nell'intestazione del formato degli Appunti (<br>
sopra) possono essere rappresentate da CRLF (Windows), LF (Unix) o lone CR (arcaico).
Frammento, selezione e contesto
Elemento | Intestazioni di descrizione | Richiede codice HTML valido per le posizioni dei caratteri iniziale e finale |
---|---|---|
Contesto | StartHTML e EndHTML |
Sì |
Frammento | StartFragment e EndFragment |
Sì |
Selezione | StartSelection e EndSelection |
No |
Contesto
Il contesto è un documento HTML valido e completo, anche se questo non significa che l'intero documento HTML di origine originale contenente la selezione dell'utente verrà trasportato in verbatim; al contrario, può essere un documento HTML minimo, ma ben formato.
Questo contesto contiene il frammento e tutti i tag circostanti precedenti (tag iniziale e finale; questi tag circostanti precedenti rappresentano tutti i nodi padre del frammento, fino al nodo HTML). L'articolo di esempio precedente include un elemento HTML <head>
completo che consente l'uso di <base href="">
elementi e <title>
. Ad esempio, questo elemento può essere inserito per ottenere queste informazioni aggiuntive. Un'applicazione che copia un frammento di CODICE HTML negli Appunti può scegliere di creare un <base href="">
elemento da includere nel contesto se tale elemento non è già presente. In questo modo, è possibile risolvere gli URI non assoluti nel frammento HTML.
Il contesto è facoltativo, poiché nel frammento sono incluse informazioni sufficienti per il incollamento di base di un frammento HTML. Se il contesto non è archiviato, il frammento viene archiviato solo e .StartHTML=EndHTML=-1
Frammento
Il frammento (<fragment-text>
sopra) contiene un frammento HTML valido.
Un frammento HTML valido è costituito da un singolo elemento HTML esterno. Questo elemento può contenere elementi HTML discendenti a condizione che siano annidati correttamente. Ad esempio, un frammento può essere un singolo <div>
elemento che contiene 3 <p>
elementi. Un frammento costituito da un <span>
elemento che contiene tre <p>
elementi non è valido perché un elemento (un <span>
elemento) non può contenere elementi a livello di blocco come elementi figlio.
Di conseguenza, il frammento rappresenta in modo efficace la maggiore area sullo schermo all'interno della quale l'utente ha effettuato la selezione del testo (per copiare, ad esempio). La selezione contiene il testo selezionato più i tag di apertura e gli attributi di qualsiasi elemento con un tag di fine all'interno del testo selezionato e tag di fine alla fine del frammento per qualsiasi tag iniziale incluso. Si tratta di tutte le informazioni necessarie per incollare di base di un frammento HTML.
Il frammento deve essere preceduto e seguito dai commenti <!--StartFragment-->
HTML e <!--EndFragment-->
per indicare dove inizia e termina il frammento. Questi commenti HTML devono essere utilizzati verbatim, senza spazi vuoti all'interno di ogni commento stesso. Pertanto, l'inizio e la fine del frammento sono indicati dalla presenza di questi commenti e dalle StartFragment
intestazioni e EndFragment
. È previsto che gli strumenti producano queste informazioni. Questa ridondanza è intenzionale ed è stata introdotta per poter trovare l'inizio del frammento (dal conteggio dei byte) e contrassegnare la posizione del frammento direttamente nell'albero HTML.
Selezione
La selezione è facoltativa perché nel frammento sono incluse informazioni sufficienti per il incollamento di base. Se la selezione non è archiviata, entrambe StartSelection
e EndSelection
non vengono archiviate nell'intestazione.
Se presente, la selezione è l'intervallo di testo esatto selezionato dall'utente (all'interno del frammento); aggiunge altre informazioni al frammento indicando il testo selezionato esatto, senza i tag di inizio e fine ben formati e bilanciati e i tag di fine.
Tenere presente che la selezione può rappresentare una sequenza di testo che può iniziare in qualsiasi elemento specificato e terminare in qualsiasi elemento successivo o predecessore. Di conseguenza, è impossibile rappresentare una selezione di testo utilizzando HTML.
Scenari
Gli scenari seguenti descrivono come l'editor HTML IE4/MSHTML gestisce le operazioni di taglia e incolla HTML; altre applicazioni possono o meno seguire questi scenari. Il formato degli Appunti descritto di seguito è progettato per consentire flessibilità per il funzionamento di un'applicazione. Questi scenari mostrano solo codice HTML valido, ovvero senza tag sovrapposti.
Scenario 1 - Frammento semplice di HTML
Si supponga che il testo HTML seguente:
<body>This is normal. <b>This is bold.</b> <i><b>This is bold italic.</b> This is italic.</i></body>
Questo aspetto verrà visualizzato come segue:
Si tratta di una situazione normale. Questo è grassetto.Questo è grassetto corsivo.Questo è corsivo.
Quando l'utente ha caricato il testo HTML precedente in un'applicazione basata su MSHTML (MSHTML, noto anche come Trident, era il motore di Internet Explorer), MSHTML gestisce la copia di una sottostringa di HTML come indicato di seguito:
- L'utente seleziona un testo senza spazi vuoti iniziali o finali, ad esempio "bold This is bold italic This" nell'esempio precedente.
- Per copiare il testo negli Appunti, l'utente fa clic sul pulsante Copia comando.
MSHTML inserisce questo testo HTML negli Appunti di Windows come indicato di seguito:
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>
Scenario 2 - Frammento di una tabella in HTML
Si supponga che il testo HTML seguente:
<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>
Questo aspetto verrà visualizzato come segue:
Testa 1 Elemento 1 Elemento 2 Elemento 3 Articolo 4 Elemento 5 Elemento 6 Articolo 7 Articolo 8 Testa 2 Elemento 9 Elemento 10 Articolo 11 Articolo 12
Come MSHTML gestisce la copia di una sottostringa di HTML da una tabella
Quando l'utente usa il mouse per effettuare una selezione di testo che copre le celle della tabella Item 6, Item 7, Item 10 e Item 11. Questa selezione viene quindi copiata negli Appunti.
Ciò che segue è ciò che sarà negli Appunti (si noti che questa è l'interpretazione di IE4/MSHTML). Sono state aggiunte interruzioni di riga per maggiore chiarezza.
<!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 selezione, delimitata da StartSelection
e EndSelection
, viene visualizzata in grassetto.
Scenario 3 - Incollare un frammento di un elenco <ol>
ordinato in testo normale
Si supponga che il testo HTML seguente:
<BODY><OL TYPE="a"><LI>Item 1<LI>Item 2<LI>Item 3<LI>Item 4<LI>Item 5<LI>Item 6</OL></BODY>
Questo aspetto verrà visualizzato come segue:
- Elemento 1
- Elemento 2
- Elemento 3
- Articolo 4
- Elemento 5
- Elemento 6
Modalità di gestione di MSHTML per la copia di una sottostringa di elementi di elenco numerati HTML
- L'utente effettua una selezione di testo dall'inizio dell'elemento 3, all'elemento 4 e alla fine dell'elemento 5. L'utente richiama il comando Copia.
- Il codice HTML seguente si trova negli Appunti (interruzioni di riga aggiunte per maggiore chiarezza): la posizione precisa dei
<!--Star/EndFragment -->
commenti dipende dal modo in cui l'utente ha gestito la logica di selezione del testo del browser:
<html>
<body>
<ol>
<!-- StartFragment-->
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<!-- EndFragment-->
</ol>
</body>
</html>
Se questo frammento deve essere incollato in un documento vuoto, verrà creato il codice HTML seguente:
<body>
<ol>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ol>
</body>
Questo aspetto verrà visualizzato come segue:
- Elemento 3
- Articolo 4
- Elemento 5
Scenario 5 - Incollare un'area parzialmente selezionata
Si supponga che il testo HTML seguente:
<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>
Questo aspetto verrà visualizzato come segue:
IE4/MSHTML è un editor WYSIWYG che supporta:
- Tagliare
- Copia
- Incolla
Questo è un ottimo strumento!
Come MSHTML gestisce la copia di una sottostringa di elementi di elenco HTML
L'utente usa il mouse per trascinare una selezione di testo, ad esempio "EDITOR WYSIWYG che supporta: Taglia cop". Come se fosse testo normale, la selezione avrebbe un aspetto simile al frammento HTML interrotto:
WYSIWYG Editor, which supports:</p>
<ul>
<li>Cut</li>
<li>Cop
Quando l'utente preme il pulsante di comando Copia, gli Appunti avranno un aspetto simile al seguente (sono state aggiunte interruzioni di riga per maggiore chiarezza; il testo in grassetto indica ciò che l'utente ha effettivamente selezionato):
<html> <body> <!-- StartFragment--> <p>WYSIWYG Editor, which supports</p> <ul> <li>Cut</li> <li>Cop</li> </ul> <!-- EndFragment--> </body> </html>
Si noti che:
- Il testo precedente a "WYSIWYG" è stato rimosso.
- L'elemento di elenco (
<li>Paste</li>
) è stato rimosso perché nessuno di esso era nella selezione dell'utente. - "y" da "Copy" è stato rimosso.