Il Formato RichText: cos’e´, come funziona e come sfruttare le specifiche RTF per formattare il testo in maniera avanzata nelle RichText Box in Visual Basic

Mi è capitato di avere la necessità di scrivere un semplice programmino in VB.NET che generasse in automatico e al volo del testo con syntax highlighting, cioè con l’evidenziazione della sintassi.

Il sytanx highlighting è una funzione molto apprezzata dai programmatori ed è diventata d’obbligo per qualsiasi editor di testo che si occupi appunto della modifica/creazione di codice sorgente. Quindi apparentemente niente di eccezionale: volevo soltanto evidenziare con colori diversi alcune parole chiave, e avevo la necessità di doverlo fare al volo.

Ho pensato bene di utilizzare il famoso controllo RichTextBox che serve appunto a contenere del testo formattato secondo le specifiche RichText.

Tutti siamo abituati a salvare, sui sistemi windows, i documenti in formato .doc (o nel più nuovo .docx), chi ama il mondo dell’open source, li salva in formato .odt (il formato documento di OpenOffice.Org), altri ancora li convertono in PDF. C’è anche chi salva i documenti in HTML… perchè no.

Tutti questi formati utilizzati per salvare documenti, contengono al loro interno vari “sistemi”  per poter far capire al software che li andrà a leggere quali parole dovrà scrivere in grassetto, quali di colore rosso ecc.

Chi mastica un po’ di HTML sa dell’esistenza di “tags”, messi in linea con il testo, che servono appunto per ottenere questi effetti: i tag non vengono visualizzati ma il programma che effettua la lettura del documento sa come interpretarli e si comporta di conseguenza (difatti l’HTML non è un linguaggio di programmazione come purtroppo molti affermano: è un linguaggio di formattazione e c’è una gran bella differenza!).

Il formato RFT in un certo senso è un po’ come l’Html: se creiamo un file in formato .rtf, lo rinominiamo in txt e lo apriamo con un editor di testo, sono riconoscibili al suo interno i vari “tags” che lo compongono in linea con il testo, cosa che invece non è possibile fare con altri tipi di documento che usano una codifica binaria e sono illeggibili con un normale editor di testo. I documenti RTF possono inoltre essere letti in qualsiasi sistema operativo pur essendo questo un formato inventato da Microsoft: anche Linux e MacOs hanno di serie dei programmi per poter aprire questo formato di testo che quindi in un certo senso può essere definito “universale”, ancor prima che lo divenisse il formato PDF.

Cerchiamo quindi di capire come è strutturato un documento RTF. Ovviamente come tutti gli altri formati di documento, anche l’RTF ha subìto delle modifiche nel corso degli anni e quindi esistono varie specifiche, io mi limiterò alla specifica 1.0, la prima, leggibile anche dai programmi più vecchi, e soltanto ad alcune parole chiave principali.

Farò riferimento al documento che potete trovare all’indirizzo: http://latex2rtf.sourceforge.net/RTF-Spec-1.0.txt pertanto se alcune cose non le spiegherò o non le capite, possono essere trovate in tale documento.

In un documento RTF ci sono vari elementi oltre al testo semplice, che possiamo semplificare col nome di control words e gruppi. Le control words sono precedute da un backslash (\) e forniscono informazioni su come formattare il testo (l’analogo dei tags nell’html), le control words si possono trovare una dietro l’altra senza interporre spazi.

I gruppi sono invece porzioni di testo e parole chiave racchiuse tra parentesi graffe, e forniscono indicazioni su interi blocchi di testo o servono a delimitare determinate informazioni, come vedremo in seguito.

Da ciò già si intuisce che il backslash e le parentesi graffe sono simboli speciali riservati, ma se vogliamo includerli nel nostro testo, basterà farli precedere da un backslash (sequenza di escape). Quindi volendo scrivere, ad esempio, il backslash senza far confondere il programma che andrà a leggere il documento, basterà scrivere : \\

Gruppi

Un documento RTF è di per se un gruppo. Tutto il contenuto di un documento RTF andrà racchiuso in un gruppo che inizia con

{\rtf1

e termina quindi con

}

come vedete abbiamo già incontrato una control word, riconoscibile perchè preceduta da un backslash: \rtf1, che indica appunto che ci troviamo in presenza di un documento RTF. Quel numero 1 è un parametro numerico, associato alla control word, che in questo caso indica la versione del documento. Molte control words prevedono un parametro numerico, altre no.

Ma continuiamo: dopo aver dichiarato che ci troviamo di fronte ad un documento RTF, la parola chiave successiva è generalmente quella che indica il set caratteri, quello di default è ansi per cui la maggior parte dei documenti RTF inizierà con:

{\rtf1\ansi

Ho detto “generalmente” in quanto ogni programma aggiunge varie control words, molte volte inutili o ridondanti, ad esempio un documento rtf generato da microsoft words è la cosa più illeggibile che esiste perchè farcito di controlwords che il 90% delle volte non hanno nessuna utilità, purtroppo anche il writer di OpenOffice.Org non si esime da questa regola.

Abbiamo quindi capito che tutto il documento andrà racchiuso in un gruppo, delimitato da parentesi graffe, tale gruppo (il principale) è appunto il documento RTF. Altri gruppi molto importanti sono la tabella font e la tabella colori. Come è facile immaginare, si tratta appunto di tabelle, strutturate in una certa maniera, che ci permettono di recuperare il font e i colori da utilizzare per il nostro testo (potrebbero essere un analogo dei fogli di stile nell’HTML…).

Tabella font

La tabella font si trova appena dopo le varie controlwords iniziali e contiene appunto un elenco dei font da utilizzare. Quindi non possiamo dichiarare i font man mano che scriviamo ma si dovrà fornire all’inizio un elenco di tutti i font utilizzati dal documento. Come già detto, la tabella font è un gruppo, ed è quindi delimitato da parentesi graffe e inizia con la controlword \fonttbl. Vediamo qui un esempio di tabella font:

{\fonttbl{\f0\froman Times New Roman;}{\f1\fswiss Arial;}{\f2\fmodern Lucida Console;}}

Analizziamo attentamente questa stringa: possiamo individuare il gruppo principale, che inizia con

{\fonttbl

e quindi termina con

}

al suo interno possiamo individuare altri 3 gruppi, uno dietro l’altro:

{\f0\froman Times New Roman;}
{\f1\fswiss Arial;}
{\f2\fmodern Lucida Console;}

Vediamo che questi 3 gruppi sono strutturati alla stessa maniera, in prima posizione troviamo la control word che serve a specificare il font, seguita da un indice numerico N (\fN). Questa control word sarà poi utilizzata anche nel testo per specificare quale font usare per la scrittura.

Segue quindi un’altra controword che fa riferimento alla famiglia (i font appartengono a varie famiglie, lo specificare la famiglia è utile nel caso in cui sul sistema non vi sia il font specificato, in questo caso il software andrà ad usare un font appartenente alla stessa famiglia). L’elenco delle famiglie lo potete trovare nel documento che ho menzionato in precedenza.

Abbiamo quindi uno spazio e infine il nome del font, terminato da un punto e virgola. Vedremo dopo come si fa per utilizzare i font qui specificati.

il nostro documento rtf quindi ora inzierà così:

{\rtf1\ansi{\fonttbl{\f0\froman Times New Roman;}{\f1\fswiss Arial;}{\f2\fmodern Lucida Console;}}

Alcuni editor di testo non separano i vari font in sottogruppi come in questo esempio, per cui le definizioni dei font si troveranno una dietro l’altra separate unicamente dal punto e virgola: vanno bene entrambi i sistemi, però questo qui mi sembrava più pulito da esporre.

Tabella colori

Penso che non serva spiegare a cosa serve se avete già capito a cosa serve la tabella font. Facciamo quindi subito un esempio:

{\colortbl ;\red0\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;}

La tabella font è un gruppo e inizia con la controlword \colortbl. I singoli colori, come possiamo intuire, si trovano in formato RGB e separati gli uni dagli altri da punto e virgola, non abbiamo una controlword con un indice numerico come abbiamo visto per i fonts: è implicito che sono messi in sequenza.

Qui però troviamo una stranezza: c’è uno spazio con un punto e virgola subito dopo la controlword della tabella colori: in realtà possiamo far finta che in quel punto c’è il “colore standard”, generalmente nero per tutti i software di videoscrittura,  segue  quindi il punto e virgola per separarlo dagli altri colori. Il colore standard ha ovviamente indice zero. Nei documenti in cui si scrive solo in colore standard, la tabella colori non è presente. Vediamo dopo come si utilizzano i colori qui definiti.

Il nostro documento RTF si arricchisce quindi sempre più:

{\rtf1\ansi{\fonttbl{\f0\froman Times New Roman;}{\f1\fswiss Arial;}{\f2\fmodern Lucida Console;}}{\colortbl ;\red0\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;}

Control words

Vediamo qui le control words principali che andremo ad utilizzare. Tenete conto che, se siete abituati con l’html e state facendo paragoni, sappiate che qui non esistono le controlword “di chiusura”. Semplicemente una controlword per il colore, ad esempio, elimina la precedente mentre ad altre, come ad esempio il grassetto, sottolineato ecc, basta aggiungere il parametro numerico 0 (zero).

Un buon sistema per imparare ad utilizzare le controlwords, scoprirne di nuove o testare quelle che non funzionano, è creare un documento RTF con l’applicazione WordPad (Attenzione ho detto WordPad e  NO Word di Microsoft Office), andarci a scrivere all’interno con gli stili che vogliamo, salvare il documento, chiudere wordpad e dare estensione TXT al file RTF per poi aprirlo col blocco note. Se utilizzate questo sistema vedrete che nel documento ci sono altre controlword che io non ho utilizzato perchè non necessarie ai miei scopi. Se invece fate questa operazione con il Word di Microsoft Office oppure con il Writer di OpenOffice.Org… vedrete che, anche per scrivere una sola lettera, che bella “stele di Rosetta” tirano fuori!

Vediamo quindi le Control Words più utili ai nostri scopi:

\fN: usa il font N della tabella font

\fsN : grandezza del font, di default N vale 20, per cui se non specifichiamo la grandezza del font, avremo \fs20. Il numero vale il doppio di quando specifichiamo, ad esempio, la grandezza del font in punti nei programmi di scrittura (se nel programma di videoscrittura abbiamo scelto un font della grandezza di 30 punti, nel documento RTF avremo \fs60)

\cfN : usa il colore N

\par: fine paragrafo (viene inserito un ritorno a capo)

\b : grassetto (\b0 : elimina grassetto)

\i : corsivo (\i0: elimina corsivo)

\ul : sottolineato (\ul0 : elimina sottolineato)

\strike: barrato (\strike0 : elimina barrato)

\ql : allineamento a sinistra (default)

\qr : allineamento a destra

\qc : allineamento centrato

\qj : allineamento giustificato

Le impostazioni di allineamento per funzionare, richiedono ovviamente che il paragrafo sia terminato con \par

Potrei continuare l’elenco all’infinito, ma non sarebbe il caso di mettersi a riscrivere ciò che è già stato scritto e che potete quindi trovare nel documento ufficiale che ho indicato più in alto, per cui mi fermo qui a quelle che ho ritenuto le control words principali.

Il codice di esempio in VB.NET

Passiamo quindi all’applicazione di esempio in VB.NET che ho scritto per farvi capire come utilizzare questi comandi e quindi divertirvi a creare i vostri editor personalizzati. Se avete letto bene tutto, non dovreste avere difficoltà. Nel codice viene creata una stringa, alla quale aggiungo i vari elementi.

Il codice RTF viene mostrato in una semplice TextBox, una RichTextBox mostrerà quindi come viene visualizzato il codice RTF appena creato (attenzione: dovremo passare il codice alla proprietà RTF e non alla proprietà TEXT). Un’ultima semplice TextBox mostra il contenuto della proprietà text della RichTextBox, qui possiamo vedere come, dal codice RTF, viene recuperato il solo testo:

Il codice è abbastanza commentato e non dovrebbe risultare difficile capirlo. Devo però dare altre indicazioni:

  • Quando vogliamo scrivere del testo, dovrà essere separato dalle controlwords con uno spazio.
  • Le controlwords successive andranno scritte senza spazi.
  • Una RichTextBox non può essere aggiornata a runtime scrivendo del testo in coda come una normale TextBox (ovviamente mi riferisco alla proprietà RTF e non alla proprietà TEXT) perchè  è sempre necessario chiudere il gruppo RichTextFormat con la graffa chiusa. Per cui se è necessario aggiornare del codice a runtime, dovremo prelevare il contenuto RTF, togliere la graffa finale, aggiungere in coda altro testo e quindi rimettere la graffa di chiusura.
  • La fine paragrafo (\par) viene realizzata ponendo un carattere di Line Feed, per cui la proprietà text ci restituirà si il solo testo della richtextbox ma sui sistemi windows vedremo un quadratino al posto del ritorno a capo per cui sarà necessario sostituire tutte le occorrenze dei LineFeed con un LineFedd+ Carriage Return, questo può essere fatto tramite una funzione Replace.

Ovviamente questo mio è solo uno dei sistemi per poter formattare il testo in maniera personalizzata ed è forse il più “grezzo” ma che fa sicuramente capire come funziona il formato RTF. Altri, soprattutto quando si tratta di realizzare sistemi di Syntax Highlighting, utilizzano le funzioni di ricerca testo e quindi effettuano la colorazione con altre funzioni: questo è sicuramente un sistema più efficiente, ma di esempi su questo se ne trovano a bizzeffe e poi a me le cose troppo semplici, che fanno perdere il senso delle cose, non piacciono.

Esempio VB.NET utilizzo RichTextBox (828 download)
Se questo articolo ti è piaciuto, condividilo su un social:
Se l'articolo ti è piaciuto o ti è stato utile, potresti dedicare un minuto a leggere questa pagina, dove ho elencato alcune cose che potrebbero farmi contento? Grazie :)