Vai ai contenuti | Vai alle rubriche

via Borgognona, 38 - 00187 Roma Tel 06.69.98.81 - Fax 06.67.86.815 - numero verde: 800 682682 - Part. IVA 00989551007

VAI AGLI ARTICOLI


UICIECHI.IT: FEBBRAIO 2008 - Numero 2.

I tre vocabolari di NVDA.

Di Adriano Barbieri.

Gli sviluppatori dello ormai diffuso screen reader opensource NVDA, in continua evoluzione, hanno di recente implementato nel codice anche un modulo dizionario, molto importante per uno screen-reader.

A dire il vero, se ne sentiva la mancanza fin dall'inizio e finalmente ne possiamo fare buon uso. Inoltre, non si tratta di un solo dizionario, ma ve ne sono ben 3.

Volendo, gli smanettoni possono editarli dal notissimo Blocco note di Windows, semplicemente inserendo su un'unica riga la parola da ricercare, uno spazio di tabulazione creato con la pressione del tasto tab e, infine, la parola in sostituzione.

Ecco una breve descrizione dei tre file vocabolario di NVDA:

  1. Dizionario di default: ha priorità su tutti, in pratica ogni vocabolo al suo interno viene elaborato in ugual modo a prescindere dalla sintesi vocale correntemente in uso.
  2. Dizionario specifico per la voce: viene creato automaticamente all'inserimento del primo vocabolo da parte dell'utente, il nome del file dizionario corrisponderà al nome della sintesi vocale correntemente in uso. Tutti i vocaboli inseriti avranno effetto solo sulla sintesi omonima in uso al momento, la sua priorità è secondaria, in supporto al dizionario di default.
  3. Dizionario temporaneo: Molto utile per testare gli effetti sui vocaboli che mammano andremo ad inserire poi definitivamente in uno dei permanenti messi a nostra disposizione.

I primi due dizionari risiedono nella cartella di installazione di NVDA e precisamente nella cartella userdicts.

Il terzo, invece, ha la particolarità di allocarsi in memoria ram e di non scrivere niente sul nostro hard-disk. In caso di errori e di risultati indesiderati che in certi casi, soprattutto nell'uso di Regex mal strutturate, rendono incomprensibile l'ascolto della sintesi da non riuscire più agestirla, sarà sufficiente chiudere NVDA e riavviarlo, per eliminare il dizionario temporaneo dalla memoria e riprovare.

La struttura dei vocabolari di NVDA è alquanto semplice perché il modulo dizionario implementa l'uso delle Regex.

Niente di trascendentale. Le Regex sono espressioni regolari e non sono altro che un linguaggio per descrivere la forma o la sintassi di una stringa. Una stringa, a sua volta è un testo qualunque, di qualunque lunghezza, una sequenza di caratteri) e null'altro.

Con il vocabolario è possibile effettuare ricerche e, quindi, sostituzioni talvolta molto complesse. Si può verificare che un testo sia conforme ad alcune caratteristiche e rispetta una determinata sintassi, come, per esempio, verificare se un testo è un indirizzo email o una URL valida.

In svariati ambienti di programmazione, il motore di ricerca delle Regex usato dal vocabolario di NVDA è una manna dal cielo. Infatti, nel nostro caso, per trovare delle parole o parti di esse e modificarne la dizione, si rivela uno strumento molto potente.

Sulla rete Internet si possono trovare migliaia di siti dedicati alle Espressioni Regolari. Ecco, ad esempio, un paio di siti che personalmente ho trovato molto esaustivi:

NOTAbene: talvolta le regex hanno piccole differenze tra un programma e l’altro o tra un linguaggio di programmazione ed un altro ma il loro concetto ed utilizzo resta sempre lo stesso.

Se provate ad accedere al dizionario di default potrete notare un piccolo gruppo di regex preimpostate, ognuna corredata da una nota descrittiva che aiuta a capire ulteriormente il loro utilizzo.

Non è mia intenzione dilungarmi in un corso approfondito delle Regex, ma se si desiderasse sfruttare appieno le potenzialità messe a nostra disposizione dai dizionari di NVDA, sarebbe bene capirne almeno le basi di utilizzo. Il mio consiglio è quello di seguire le spiegazioni che vengono fornite sui due siti indicati sopra.

Facciamo qualche prova pratica, in modo da rendere bene l'idea.

  • Apriamo il blocco note di Windows.
  • Scriviamo una parola, ad esempio il nome "sophia". Per questo esempio, la scriviamo tutta in minuscolo.
  • Portiamo il pannello di NVDA in primo piano con la combinazione di tasti: insert+n.
  • Dal menù NVDA, scendiamo fino al sottomenù: Dizionari, e facciamo invio sulla terza voce, dizionario temporaneo.
  • La finestra che si aprirà è del tutto identica a quella deglialtri dizionari, e presenta la lista di tutti i vocaboli inseriti al suo interno. La si può scorrere con le frecce verticali, ma, al momento, nel nostro caso sarà vuota.
  • Premendo ripetutamente tab ci porteremo sui pulsanti che possiamo usare e che sono: Aggiungi, Modifica, Rimuovi, ok e Cancel. Con esc, si annulla tutto.
  • Se facciamo invio su Aggiungi, verranno resi disponibili 3 campi editazione. La sintesi dirà voce e il focus sarà già posizionato sul primo campo, quello giusto per inserire la nostra parola da testare.
  • Inseriamo la parola, così come l'abbiamo scritta nel blocco note.
  • Premiamo tab per spostarci nel campo Voce in sostituzione. Qui scriviamo la parola corretta, "sophìa", usando la i accentata al posto di quella normale. In questo campo editazione suggerisco di usare sempre parole in minuscolo.
  • Ancora tab e saremo nel terzo campo di editazione, che ci permetterà di inserire un commento. Non è obbligatorio, ma quest'ultimo campo è molto utile perché viene letto per primo durante lo scorrimento nella lista dei vocaboli inseriti e ne sveltisce l'identificazione. Se lo si omette verrà letto subito il campo della parola da correggere, che nella maggior parte dei casi essendo una stringa con caratteri misti verrà letta in sillabe rallentandone il riconoscimento immediato. Quindi, nel campo del commento, sarà utile inserire la copia della voce in sostituzione. Questa cosa è facilitata con un copia ed incolla.
  • Facendo un passo indietro con shift più tab ci troveremo sul campo voce in sostituzione che, nel frattempo, sarà stato selezionato in modo automatico.
  • Non ci resta che premere control più C.
  • Premiamo Tab per tornare nel campo del commento.
  • Incollare con control+v.
  • Premere invio su ok o semplicemente invio, e il nostro primo vocabolo sarà stato integrato nella lista del vocabolario provvisorio.
  • Ancora invio su ok per confermare e chiudere il dizionario che NVDA inizierà subito a sfruttare.
  • Con Alt più tab portiamo in primo piano il nostro Blocco note e verifichiamo se la nostra parola ora viene vocalizzata correttamente. Vi ricordo che Per ripetere la lettura della riga corrente basta premere insert+freccia sù, ma essendo l'unica riga,come nel nostro caso, anche solo freccia sù.

Se tutto è stato fatto correttamente, saremo sicuramente soddisfatti del risultato.

Adesso proviamo a cambiare la lettera iniziale della nostra parola, mettendo la maiuscola iniziale ed ora il nome Sophia è scritto in modo corretto. Ecco! il nome non viene più riconosciuto, perché?

Il motivo è che le Regex sono per default case sensitive, cioè, fanno distinzione tra minuscole e maiuscole. Se il testo contenuto nel campo "voce" è testo semplice, verrà ricercata esattamente quella sequenza di caratteri, distinguendo tra maiuscole e minuscole.

  • Esistono alcuni caratteri particolari che se inseriti all’interno della regex hanno un significato diverso dal loro simbolo e ne vedremo solo alcuni:

"[]", Parentesi quadre, tutti i caratteri all’interno di esse sono accettati in alternativa e le due parentesi si comportano come un singolo carattere. Possono esserci utili nel nostro esempio.

Torniamo nel dizionario temporaneo, selezioniamo dalla lista la parola inserita in precedenza, e facciamo invio su Modifica. Ci troveremo già nel campo "voce".

Modifichiamo la parola racchiudendo l'iniziale fra parentesi quadre. Facciamo in modo che all'interno vi sia lo stesso carattere sia in minuscolo che in maiuscolo, lasciando fuori il resto, così: [sS]ophia

Non importa l'ordine dei caratteri dentro le parentesi quadre, a meno che non si metta un trattino, il trattino infatti se usato nel mezzo di numeri o lettere si comporta da carattere speciale (range), definendo un gruppo ben delimitato di caratteri o numeri, ad esempio, [a-z]

IN questo caso, sono ammessi caratteri minuscoli dalla "a" alla "z".

[A-Z], come sopra, ma saranno accettati solo caratteri maiuscoli.

[1-6], sono ammessi solo i numeri compresi nel range, in questo esempio, solo da uno a sei.

Sono ammesse combinazioni:

[A-F0-9], lettere dalla "A" alla "F" maiuscole e i numeri dallo zero al nove compresi.

Quindi se si vuole che il "-" trattino si comporti come un normale carattere bisognerà metterlo subito a sinistra o a destra del gruppo di caratteri compresi nelle 2 parentesi quadre, o convertito in un carattere normale tramite la barra diagonale rovesciata che vedremo più tardi.

Chiarito ciò, torniamo alla nostra Sophia. In questo modo, la nostra parola specificata nella Regex, sarà trovata ed elaborata indipendentemente se ha l'iniziale minuscola o maiuscola.

Se andiamo nel blocco note lo possiamo verificare, scrivendo sia con la minuscola che con la maiuscola. Funziona!

Non va male, ma se si incontrasse la stessa parola, tutta in maiuscolo non verrebbe trovata. Provate, ve ne rendete subito conto!

Niente paura, abbiamo un altro carattere speciale che ci può venire in aiuto. "|", la barra verticale, si comporta come un operatore logico "or" che significa oppure. Permette infatti di aggiungere un'alternativa nella nostra Regex, nel nostro caso in questo modo: SOPHIA|[sS]ophia

La barra verticale si digita con shift più la controbarra, che si trova proprio sopra il tab, a sinistra del numero 1. Si deve usare shift, perché altrimenti si otterrà la barra diagonale rovesciata, l'altro carattere speciale di cui parlerò fra poco.

Adesso la nostra prima Regex ha triplicato la sua efficacia. Infatti, ora troverà la nostra parola sia tutta in maiuscolo, sia in minuscolo, e indipendentemente dall'avere l'iniziale minuscola o maiuscola. Vi ricordo che se si chiude NVDA tutto ciò che è stato inserito nel dizionario temporaneo andrà perduto, ma una volta ottenuto quello che desideriamo non sarà difficile esportarlo in uno dei dizionari permanenti messi a nostra disposizione dallo Screen-reader con un semplice copia ed incolla.

Vediamo ora il carattere speciale: "\", barra diagonale rovesciata, quella che generalmente chiamiamo controbarra.

Questo carattere ci permette di definire un carattere speciale alla stregua di un qualsiasi carattere normale, ma se usato con alcuni caratteri normali gli assegna le proprietà di un carattere speciale. Mi spiego meglio con qualche esempio del suo utilizzo:

  • \a minuscola, un carattere di allarme, il carattere ASCII "BEL".
  • \b minuscola, un carattere word boundary, limitatore di parola, oppure backspace se "\b" è dentro una classe di caratteri tra parentesi quadre.
  • \B Maiuscola, un carattere non word boundary.
  • \d Minuscola, un qualunque carattere che sia una cifra. E' equivalente a [0-9] .
  • \D Maiuscola, tutto ciò che non è \d. E' equivalente a [^0-9] oppure a [^\d].
  • \e Minuscola, un carattere di escape, il carattere ASCII "ESC".
  • \f Minuscola, un carattere di form feed, il carattere ASCII "FF".
  • \n Minuscola, un carattere di nuova linea, il carattere ASCII "NL".
  • \r Minuscola, un carattere di carriage return, il carattere ASCII "CR".
  • \s Minuscola, un qualunque carattere che crea spazi, come tabulazione, spazio, nuova linea,eccetera. E' equivalente a [ \f\n\r\t].
  • \S Maiuscola, tutto ciò che non è \s.
  • \t Minuscola, un carattere di tabulazione, il carattere ASCII "HT".
  • \w Minuscola, un qualunque carattere alfanumerico, compreso il carattere sottolineato. E' equivalente a [a-zA-Z0-9_] .
  • \W Maiuscola, tutto ciò che non è w; è equivalente a [^a-zA-Z0-9_] o a [^\w].

Avete notato l'accento circonflesso "^" in alcune righe?

^ "apice" ha due significati:

  • se messo all’inizio della regex impone che la parola tra virgolette sia ad inizio linea, cioè cominci con quello che segue apice.
  • Se usato con le parentesi quadre e messo prima di un carattere significa tranne il carattere che segue, è una negazione.

Ecco ulteriori caratteri speciali:

  • . "punto" qualunque carattere.
  • * "asterisco" accetta zero o più ripetizioni del carattere precedente.
  • + "più" accetta una o più ripetizioni del carattere precedente.
  • [ ] "parentesi quadre" tutti i caratteri all’interno delle [ ] "parentesi quadre" sono accettati. Le due parentesi si comportano come un singolo carattere.
  • [^ ] "parentesi quadre con apice" tutti i caratteri tranne quelli all’interno delle [ ] "parentesi quadre" sono accettati.
  • \ "barra rovesciata" tratta il carattere speciale che segue come un normale carattere testuale o viceversa tratta un normale carattere come un carattere speciale.

Vediamo allora come sfruttare quest'ultimo carattere. Sicuramente avrete notato che, durante la lettura, ad esempio in Outlook Express, ma anche in altre applicazioni, vengono vocalizzati caratteri che a lungo andare diventano molto fastidiosi come le parentesi quadre, i trattini, la tilde, il sottolineato, barre diagonali, e chi più ne ha più ne metta. Tra questi caratteri, ce ne sono anche di speciali.

Il carattere "\" barra diagonale rovesciata ci può venire in aiuto indicando che dovranno essere visti nel loro significato letterale,altrimenti, se usati da soli nel campo "voce" genererebbero un errore, evidenziato dal tipico suono a due toni.

Dimenticare la chiusura delle parentesi, invece, genererebbe un errore nella sintassi della Regex. Ad esempio, volendo zittire paradossalmente proprio la barra diagonale inversa, basterà anteporre la stessa con se stessa, così: \\

Nel campo della voce in sostituzione si può mettere uno spazio se si desidera una piccola pausa, ed è consentito anche niente. Ecco qualche esempio:

  • \| La barra verticale.
  • \~ La tilde.
  • \- Il trattino.
  • \[\] Le parentesi quadre, notare che è possibile affiancare gli elementi.

E così per tutti i caratteri speciali.

Usando le parentesi quadre invece è possibile raggruppare tutta una classe di caratteri, come nell'esempio sotto riportato:

[-_[]\~]

Comodo, vero? Se poi, per un qualche motivo, si volesse ripristinare i caratteri zittiti in precedenza, sempre che la nostra Regex non sia troppo lunga, basterà anteporre il carattere cancelletto. Il "#" indica che tutto quello che lo segue è una semplice nota di commento, quindi, se lo anteporremo alla Regex precedente, essa sarà neutralizzata senza necessariamente doverla rimuovere dal nostro dizionario, alla bisogna, basterà modificarla eliminando il cancelletto per renderla nuovamente operativa.

Ecco un altro uso della barra diagonale rovesciata:

Avendo raggruppato parti di regex in sotto-espressioni con le parentesi tonde, possiamo riferirci ai loro rispettivi risultati, nell'ordine, da sinistra verso destra, con \1, \2, \3, eccetera.

Esempi di questo tipo di Regex li troviamo anche nel dizionario di default di NVDA, quindi, se andate a leggerlo, vi rendete conto meglio di cosa si tratta.

Ho cercato di essere il più chiaro possibile, ma non è facile essere sintetico e allo stesso tempo chiaro. Se siete giunti sin qui nella lettura, vuol dire che siete veramente interessati e penso che piano piano diventerete bravi ad usare i vocabolari di NVDA.

Ovviamente ci sarebbero altri caratteri speciali da esplorare, per questo motivo vi suggerisco caldamente di visitare almeno una volta i link che vi ho indicato all'inizio di questo articolo.

Quello che segue, invece, è una serie di Regex, che si potrebbero rivelare utili ai fini di correggere alcune vocalizzazioni non desiderate, generate da alcune sintesi vocali SAPI5. Spero di fare una cosa gradita e, allo stesso tempo, è anche un modo per premiare la vostra pazienza.

Da questo momento in avanti, per semplificare, userò come indicazione anteposta alle stringhe:

  • "v =", senza virgolette, per indicare la voce da ricercare.
  • "vs =", senza virgolette, per indicare la voce in sostituzione.
  • "# ", senza le virgolette, per indicare il commento relativo.

Le stringhe che seguono "V =" e "vs =" le racchiuderò tra virgolette, per comprendere eventuali spazi, ma non devono essere usate nelle regex.

***

Ecco le Regex che possono essere usate in uno dei vocabolari descritti ad inizio articolo:

# correzione pronuncia karati:

- v = "\b[kK]\d?\W".

- vs = " kappa ".

# Correzione pronuncia karati, parte 2:

- v = "((\d)+)[kK]+".

- vs = "\1 kappa ".

  • Queste 2 regex sono complementari, occorrono entrambe. Inoltre, possono essere sfruttate anche per correggere la pronuncia di grammi, volt, eccetera, ma occorre cambiare le [kK] con i caratteri [gG], [vV], eccetera.
  • Ovviamente anche i campi "voce in sostituzione", cambiare " kappa " con " gi ", " vi ", eccetera.

***

# Correzione pronuncia millisecondi:

- v = "MS|[mM]s[- ]?\b".

- vs = "m s ".

***

# Correzione pronuncia ettari:

- v = "[hH]a[ ]?\b".

- vs = "A".

***

# Correzione pronuncia centimetri cubici:

- v = "[ ][cC]{2}|^[cC]{2}".

- vs = "c c".

***

# Correzione vocali accentate:

- v = "a'".

- vs = "à".

  • Ovviamente ripetere con le altre vocali.
  • Potete raggruppare alcuni tipi di vocali accentate simili che potrebbero distorcere la pronuncia, fra parentesi quadre, aggiungendo l'alternativa della vocale apostrofata che è composta da 2 caratteri, tramite la barra verticale:

- v = "[é]|e'".

- vs = "è".

  • Infatti potreste incontrare vocali accentate con caratteri ascii differenti anche se in apparenza uguali.

***

# Eccezioni parole brevi con vocale accentata:

- v = "[bB]è".

- vs = "be'".

- v = "[pP]ò".

- v = "po'".

  • Se avete aggiunto la correzione delle vocali apostrofate però. Quando sono così brevi è meglio con l'apostrofo.

***

# Correzione numeri romani:

  • La "C", la "D", la "L", la "V" e la "X" in maiuscolo, anche in gruppi vengono lette da alcune sintesi vocali come numeri romani. In questo caso è sufficiente mettere il carattere in minuscolo nel campo in sostituzione, ma occorre racchiudere tra parentesi quadre le lettere nel campo "voce".

- v = "[X]".

- vs = " x ".

  • Soprattutto la x e la v maiuscole sono particolarmente ostiche nei menù di modifica.

***

# Lettura del punto fermo:

  • Se volete sentire la lettura del punto nelle URL o negli indirizzi di posta:

- v = "(\w)\.(\w)".

- vs = "\1 punto ".

***

# Lettura delle doppie barre nelle URL:

- v = "(\w)\:/{2}(\w)".

- vs = "\1 barra barra \2".

****

Non è stato facile, ma ho provato a creare qualche Regex per vocalizzare alcune faccine espressive solitamente usate nelle chat. Sono alquanto complicate, ma se qualcuno più esperto conosce il modo di semplificarle sarebbe meglio. Eccole:

# Faccina che fa l'occhiolino " ;-)":

- v = "[ ]+[;]+[)]| [;][^aA-zZ0-9][)]".

# Faccina disperata " :-((":

- v = "[ ]+[:]+[(]+[(]| [:][^*0-9aA-zZ_.,?!<>\/&%$£":()\\][(]{2}[^aA-zZ0-9]".

# Faccina delusa " :-(":

- v = "[ ]+[:]+[(]| [:][^*0-9aA-zZ_.,?!<>\/&%$£":()\\][(]{1}[^aA-zZ0-9]".

# Faccina che ride di gusto " :-))":

- v = "[ ]+[:]+[)]+[)]| [:][^*0-9aA-zZ_.,?!<>\/&%$£":()\\][)]{2}[^aA-zZ0-9]".

# Faccina sorridente " :-)":

- v = "[ ]+[:]+[)]| [:][^*0-9aA-zZ_.,?!<>\/&%$£":()\\][)]{1}[^aA-zZ0-9]".

# Faccina sorpresa " :-O":

- v = "[ ]+[:]+[oO]| [:][^*0-9aA-zZ_.,?!<>\/&%$£":()\\][oO]{1}[^aA-zZ0-9]".

# Faccina che pernacchia " :-P":

- v = "[ ]+[:]+[pP]| [:][^*0-9aA-zZ_.,?!<>\/&%$£":()\\][pP]{1}[^aA-zZ0-9]".

Tutte queste faccine richiedono che vi sia uno spazio alla loro sinistra. Funzionano anche senza il nasino " :)".

Importante! per funzionare bene devono essere immesse nello stesso ordine, magari nel dizionario di default, in modo da funzionare con qualsiasi sintesi vocale in uso.

A dimostrazione delle difficoltà che si incontrano a gestire la punteggiatura, come già detto, non è stato facile fare in modo che una frase che finisse con tali punteggiature e in più caratteri speciali venissero fraintese come faccine.

Adriano Barbieri.