{"id":44,"date":"2010-03-08T11:14:46","date_gmt":"2010-03-08T10:14:46","guid":{"rendered":"https:\/\/alistapart.com\/it\/article\/accent-folding-per-completamento-automatico\/"},"modified":"2010-03-08T11:14:46","modified_gmt":"2010-03-08T10:14:46","slug":"accent-folding-per-completamento-automatico","status":"publish","type":"article","link":"https:\/\/alistapart.com\/it\/article\/accent-folding-per-completamento-automatico\/","title":{"rendered":"Accent-folding per il completamento automatico"},"content":{"rendered":"<p><img decoding=\"async\" src=\"http:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2010\/03\/accenti.png\" border=\"0\" alt=\"accenti\" title=\"accenti\" align=\"right\" \/><\/p>\n<p>E&#8217; appena passata un&#8217;altra generazione di tecnologie e Unicode \u00e8 ormai supportato praticamente ovunque. Il prossimo passo \u00e8 quindi quello di scrivere software che non sia solo \u201cinternazionalizzato\u201d ma veramente multi-lingua. In questo articolo passeremo rapidamente in rassegna un po&#8217; di storia e di teoria, per poi illustrare un hack efficace chiamato accent-folding. L&#8217;accent-folding ha i suoi limiti ma pu\u00f2 comunque aiutare a rendere migliori alcuni aspetti dell&#8217;interazione utente, importanti sebbene spesso sottovalutati.<\/p>\n<div class=\"paragrafo\">\n<p>Nel processo di internazionalizzazione si d\u00e0 per assunto che qualunque utente rientri perfettamente in una singola <a href=\"http:\/\/it.wikipedia.org\/wiki\/Internazionalizzazione_e_localizzazione\" title=\"descrizione di locale\">locale<\/a>, come ad esempio \u201cEnglish, United States\u201d o \u201cFrench, France.\u201d. Si tratta di un retaggio del passato, quando per il PC era gi\u00e0 parecchio riuscire a mostrare i giusti bit. Un byte equivaleva ad un carattere solo, senza eccezioni, e si poteva caricare un solo alfabeto alla volta. Questo andava bene perch\u00e9 era meglio che niente e perch\u00e9 gli utenti passavano la maggior parte del loro tempo con dei documenti che avevano creato essi stessi o i loro collaboratori.<\/p>\n<p>Oggi gli utenti hanno a che fare ogni giorno con dati provenienti da tutto il mondo, in pi\u00f9 lingue e locali. La locale che io in quanto utente <em>preferisco<\/em> \u00e8 solo debolmente correlata con le locali che <em>le applicazioni mi aspetto processino<\/em>.<\/p>\n<p>Prendete per esempio questa rubrica:<\/p>\n<ul>\n<li> Fulanito L\u00f3pez <\/li>\n<li> Erik L\u00f8rgensen <\/li>\n<li> Lorena Smith <\/li>\n<li> James L\u00f6 <\/li>\n<\/ul>\n<p>Se compongo un nuovo messaggio ed inserisco \u201clo\u201d nel campo \u201cA:\u201d, cosa pu\u00f2 succedere? In molte applicazioni, solo il nome Lorena verr\u00e0 mostrato nell&#8217;elenco dei suggerimenti. Queste applicazioni \u201csupportano Unicode,\u201d nel senso che non lo sporcano e non vi pasticciano, ma questo \u00e8 tutto.<\/p>\n<div class=\"illustration half right\"><img decoding=\"async\" src=\"http:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2010\/03\/fig1.png\" border=\"0\" alt=\"Screenshot dei suggerimenti automatici della rubrica indirizzi di Microsoft Entourage, che non applica l'accent-folding.\" title=\"Ehi, Entourage, dove sono i miei contatti?\" \/><\/p>\n<p>Fig 1. Ehi Entourage, dove sono i miei contatti?<\/p>\n<\/div>\n<p>Questo problema non si trova esclusivamente nelle rubriche indirizzi. Pensate alle inbox, ai social bookmark, ai feed dei commenti, agli utenti che parlano pi\u00f9 lingue, agli internet caf\u00e9 in paesi stranieri, perfino agli URLs. Provate a cercare il giornalista Ryszard Kapu\u015bci\u0144ski e guardate come differenti siti web trattino il suo nome:<\/p>\n<ul>\n<li> Wikipedia: <a href=\"http:\/\/en.wikipedia.org\/wiki\/Ryszard_Kapu%C5%9Bci%C5%84ski\">Ryszard Kapu\u015bci\u0144ski<\/a> (URL canonico) <\/li>\n<li> Wikipedia: <a href=\"http:\/\/en.wikipedia.org\/wiki\/Ryszard_Kapuscinski\">Ryszard Kapuscinski<\/a> (alternativa codificata a mano) <\/li>\n<li> Wikipedia: <a href=\"http:\/\/en.wikipedia.org\/wiki\/Ryszard_Kapusci%C5%84ski\">Ryszard Kapusci\u0144ski<\/a> (<strong>non trovato<\/strong>) <\/li>\n<li> Wikipedia: <a href=\"http:\/\/spock.com\/%C8%92%C3%BFszar%E1%B8%8B-K%C3%A5pu%C5%9Bci%C5%84s%E1%B8%B3i\">R\u00ffszar\u1e0b K\u00e5pu\u015bci\u0144s\u1e33i<\/a> (<strong>non trovato<\/strong>) <\/li>\n<li> Spock: <a href=\"http:\/\/spock.com\/%C8%92%C3%BFszar%E1%B8%8B-K%C3%A5pu%C5%9Bci%C5%84s%E1%B8%B3i\">R\u00ffszar\u1e0b K\u00e5pu\u015bci\u0144s\u1e33i<\/a> (accent-folded, fa il redirect verso l&#8217;URL canonico) <\/li>\n<\/ul>\n<p>Non ci sono scuse: il vostro software non pu\u00f2 comportarsi in modo cos\u00ec ottuso quando l&#8217;utente digita \u201c<strong>caffe<\/strong>\u201d invece di \u201c<strong>caff\u00e9<\/strong>.\u201d<\/p>\n<\/div>\n<div class=\"paragrafo\">\n<h2>\u00c1\u00e7\u010d\u1ec1\u00f1\u1e6d-\u1e1e\u00f8\u0142\u0256\u01d0\u1e45g<\/h2>\n<p>In specifiche applicazioni di ricerca che preferiscono richiamare un maggior numero di risultati piuttosto che essere pi\u00f9 precisi, come nel nostro esempio della rubrica indirizzi, <strong>\u00e1<\/strong>, <strong>a<\/strong>, <strong>\u00e5<\/strong>, e <strong>\u00e2<\/strong> possono essere trattate come equivalenti. Gli accenti (altres\u00ec noti come <a href=\"http:\/\/it.wikipedia.org\/wiki\/Segno_diacritico\">segni diacritici<\/a>) sono suggerimenti di come deve essere la pronuncia, ma non influenzano il significato della parola. Digitare le lettere accentate pu\u00f2 rivelarsi complicato, soprattutto sui dispositivi mobili.<\/p>\n<div class=\"illustration half right\"><img decoding=\"async\" src=\"http:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2010\/03\/fig2.png\" border=\"0\" alt=\"Esempio di una widget YUI Autosuggest a cui \u00e8 aggiunto l'accent-folding.\" title=\"L'accent-folding in una widget di suggerimento automatico\" \/><\/p>\n<p>Fig 2. Accent-folding nella widget di suggerimento automatico.<\/p>\n<\/div>\n<p>Una funzione accent-folding sostanzialmente mappa i caratteri Unicode al loro equivalente ASCII. Ovunque applichiate il <a href=\"http:\/\/en.wikipedia.org\/wiki\/Case_folding#Case_folding\">case-folding<\/a>, dovreste considerare di applicare anche l&#8217;accent-folding, esattamente per le stesse ragioni. Con l&#8217;accent-folding, non importa se l&#8217;utente cerca <strong>caffe<\/strong>, <strong>caff\u00e9<\/strong> o perfino <strong>\u00e7\u00e5FF\u00e9<\/strong>;: i risultati saranno gli stessi.<\/p>\n<p><strong>Attenzione, per\u00f2! Ci sono milioni di problemi nelle regole degli accenti. Quasi sicuramente sbaglierete qualcosa da qualche parte.<\/strong> Quasi tutti gli alfabeti hanno dei segni super-speciali che influiscono anche sul significato e ovviamente tutti gli alfabeti non Occidentali hanno regole totalmente diverse da quelle a cui siamo abituati.<\/p>\n<p>Un problema minore \u00e8 l&#8217;<a href=\"http:\/\/unicode.org\/cldr\/utility\/list-unicodeset.jsp?a=[:Block=Halfwidth_And_Fullwidth_Forms:]\">alfabeto Unicode &#8220;fullwidth&#8221; Roman<\/a>: si tratta di un insieme semplici caratteri ASCII di larghezza fissa pensati per allinearsi con i caratteri Cinesi\/Giapponesi\/Koreani (e.g., &#8220;\uff11\uff19\uff17\uff19\u5e74\uff18\u6708\uff11\uff15\u65e5&#8221;). Si trovano tra <code>0xff00<\/code> e <code>0xff5e<\/code> e dovrebbero essere trattati come equivalenti dei loro corrispettivi ASCII.<\/p>\n<\/div>\n<div class=\"paragrafo\">\n<h2>Ehi, sono qui solo per fare copia\/incolla!<\/h2>\n<p>Ho messo su GitHub <a href=\"http:\/\/github.com\/aristus\/accent-folding\">degli esempi pi\u00f9 completi<\/a>, ma per illustrare la tecnica, ecco un esempio base di accent-folding utilizzando Javascript:<\/p>\n<p>(Il codice che prosegue su una nuova riga \u00e8 segnato con \u00bb <em>\u2014ndr<\/em>)<\/p>\n<pre>  <code><br \/>   var accentMap = {<br \/>     '\u00e1':'a', '\u00e9':'e', '\u00ed':'i','\u00f3':'o','\u00fa':'u'<br \/>   };<br \/> <br \/>   function accent_fold (s) {<br \/>    if (!s) { return ''; }<br \/>    var ret = '';<br \/>    for (var i = 0; i &lt; s.length; i++) {<br \/>      ret += accentMap[s.charAt(i)] || s.charAt(i);<br \/>    }<br \/>    return ret;<br \/>   };<br \/>  <\/code><br \/> <\/pre>\n<\/div>\n<div class=\"paragrafo\">\n<h2>Espressioni regolari<\/h2>\n<p>Le espressioni regolari sono difficili da gestire se si vuole che si \u201crendano conto degli accenti\u201d. Notate come in Fig. 2 solo i caratteri non accentati siano in grassetto. Il problema \u00e8 che il layout dei caratteri Unicode non si presta ai pattern trasversali alle lingue. L&#8217;espressione regolare appropriata per \u201c<strong>lo<\/strong>\u201d sarebbe qualcosa di pazzesco come:<\/p>\n<pre>  <code>[Ll\u0139\u013a\u013d\u013e\u013b\u013c\u1e36\u1e37\u1e38\u1e39\u1e3c\u1e3d\u1e3a\u1e3b\u0141\u0142\u0141\u0142\u013f\u0140\u023d\u019a\u026b][Oo\u00d3\u00f3\u00d2\u00f2\u014e\u014f\u00d4\u00f4\u1ed0\u1ed1\u1ed2\u1ed3\u1ed6\u00f6\u022a\u022b\u0150\u0151\u00d5\u00f5\u1e4c\u022d\u022e\u022f\u01fe\u01ff...\u01ec\u01ed\u014c]<\/code><br \/> <\/pre>\n<p>Non fate mai una cosa del genere! Mai! Al momento in cui scriviamo, ci sono pochi motori per espressioni regolari che supportano shortcuts per le classi di caratteri Unicode. I pi\u00f9 avanzati sembrano essere <a href=\"http:\/\/www.pcre.org\/\" rel=\"nofollow\">PCRE<\/a> e Java. Probabilmente non dovreste forzare questo meccanismo, ma al contrario cercare di evidenziare una versione accent-folded [indipendente dagli accenti, <em>ndr<\/em>] della stringa e poi usare la posizione del carattere per sottolineare l&#8217;originale, come in questo esempio:<\/p>\n<pre>  <code><br \/>   <strong>\/\/ accent_folded_hilite(\"Fulanilo L\u00f3pez\", 'lo')<br \/>   \/\/   --&gt; \"Fulani<strong>lo<\/strong> <strong>L\u00f3<\/strong>pez\"<br \/>   \/\/<\/strong><br \/><br \/>   function accent_folded_hilite(str, q) {<br \/>    var str_folded = accent_fold(str).toLowerCase() \u00bb<br \/>     .replace(\/[]+\/g, '');<br \/>    var q_folded = accent_fold(q).toLowerCase() \u00bb<br \/>     .replace(\/[]+\/g, '');<br \/><br \/>   <strong> \/\/ Creazione di una stinga intermedia con i suggerimenti evidenziati<br \/>   \/\/ Esempio: fulani pez<\/strong><br \/>   var re = new RegExp(q_folded, 'g');<br \/>   var hilite_hints = str_folded.replace(re, \u00bb<br \/><br \/>   '');<br \/><br \/>   <strong>\/\/ Puntatore all'indice della stringa originale<\/strong><br \/>   var spos = 0;<br \/>   <strong>\/\/ Accumulatore per la nostra stringa finale<\/strong><br \/>   var highlighted = '';<br \/><br \/>   <strong> \/\/ Scorriamo in parallelo la stringa originale e la stringa <br \/>   \/\/ con i suggerimenti evidenziati. <br \/>   \/\/ Quando nella stringa con i suggerimenti incontriamo un<br \/>   \/\/  appendiamo nella stringa finale un carattere<br \/>   \/\/ di tag aperto o chiuso e incrementiamo il contatore della<br \/>   \/\/ stringa con i suggerimenti. Se incontriamo un carattere che<br \/>   \/\/ non \u00e8 un simbolo di suggerimento appendiamo il carattere<br \/>   \/\/ della stringa originale nella stringa finale e incrementiamo<br \/>   \/\/ entrambe i contatori.<\/strong><br \/>\t\t\t    <br \/>   for (var i = 0; i&lt; hilite_hints.length; i++) {<br \/>     var c = str.charAt(spos);<br \/>     var h = hilite_hints.charAt(i);<br \/>     if (h === '&lt;') {<br \/>       highlighted += '<strong>';<br \/>     } else if (h === '&gt;') {<br \/>       highlighted += '<\/strong>';<br \/>      } else {<br \/>       spos += 1;<br \/>       highlighted += c;<br \/>      }<br \/>     }<br \/>    return highlighted;<br \/>   }<br \/>  <\/code><br \/> <\/pre>\n<p>L&#8217;esempio precedente \u00e8 probabilmente troppo semplificato per poter essere usato nel codice in produzione. Ad esempio, non si possono sottolineare termini multipli. Alcuni caratteri speciali potrebbero espandersi su due caratteri, come \u201c<strong>\u00e6<\/strong>\u201d &#8211;&gt; \u201c<strong>ae<\/strong>\u201d con la conseguenza di mandare a gambe all&#8217;aria <code>spos<\/code>. Inoltre, elimina i segni di maggiore e minore () presenti nella stringa originale. Ma va comunque bene come primo passo.<\/p>\n<\/div>\n<div class=\"paragrafo\">\n<h2>Accent-folding nella libreria Autocomplete di YUI<\/h2>\n<p>La <a href=\"http:\/\/developer.yahoo.com\/yui\/autocomplete\" title=\"Libreria Autocomplete di YUI\">libreria Autocomplete di YUI<\/a> [Yahoo! User Interface, <em>ndr<\/em>] ha molti spunti ed opzioni con cui giocare. Oggi vedremo due metodi riscrivibili: <code>filterResults()<\/code> e <code>formatMatch()<\/code>. Il metodo <code>filterResults<\/code> ci permette di scrivere la nostra funzione di confronto. Il metodo <code>formatMatch<\/code> ci permette di cambiare l&#8217;HTML di una entry nella lista di accoppiamenti suggeriti. Potete inoltre scaricare <a href=\"http:\/\/github.com\/aristus\/accent-folding\">un esempio completo su cui lavorare<\/a>, compreso tutto il codice sorgente.<\/p>\n<p>(Il codice che prosegue su una nuova riga \u00e8 segnato con \u00bb <em>ndr<\/em>)<\/p>\n<pre><code><br \/><strong><br \/>&lt;!-- questo \u00e8 importante per dire a javascript di trattare le stringhe<br \/>come UTF-8 --&gt;<br \/><\/strong><br \/>&lt;meta http-equiv=\"content-type\" content=\"text\/html;charset=utf-8\" \/&gt;<br \/><strong><br \/>&lt;!-- YUI stylesheets --&gt;<br \/><\/strong><br \/>&lt;link rel=\"stylesheet\" type=\"text\/css\"<br \/>  href=\"http:\/\/yui.yahooapis.com\/2.7.0\/build\/fonts\/fonts-min.css\" \/&gt;<br \/>&lt;link rel=\"stylesheet\" type=\"text\/css\"<br \/>  href=\"http:\/\/yui.yahooapis.com\/2.7.0\/build\/autocomplete\/assets \u00bb<br \/>  \/skins\/sam\/autocomplete.css\" \/&gt;<br \/><br \/><strong><br \/>&lt;!-- librerie YUI: eventi, sorgenti e completamento automatico --&gt;<br \/><\/strong><br \/>&lt;script type=\"text\/javascript\"<br \/> src=\"http:\/\/yui.yahooapis.com\/2.7.0\/build\/yahoo-dom-event \u00bb<br \/> \/yahoo-dom-event.js\"&gt;&lt;\/script&gt;<br \/>&lt;script type=\"text\/javascript\" <br \/>  src=\"http:\/\/yui.yahooapis.com\/2.7.0\/build\/datasource \u00bb<br \/>  \/datasource-min.js\"&gt;&lt;\/script&gt;<br \/><br \/>&lt;script type=\"text\/javascript\" <br \/>  src=\"http:\/\/yui.yahooapis.com\/2.7.0\/build\/autocomplete \u00bb<br \/>  \/autocomplete-min.js\"&gt;&lt;\/script&gt;<br \/><br \/><strong><br \/>&lt;!-- contiene accent_fold() e accent_folded_hilite() --&gt;<br \/><\/strong><br \/>&lt;script type=\"text\/javascript\" src=\"accent-fold.js\"&gt;&lt;\/script&gt;<br \/><br \/><strong><br \/>&lt;!-- Assegna a &lt;body&gt; la \"skin\" YUI --&gt;<br \/><\/strong><br \/>&lt;body class=\"yui-skin-sam\"&gt;<br \/>&lt;b&gt;To:&lt;\/b&gt;<br \/>&lt;div style=\"width:25em\"&gt;<br \/><br \/><strong><br \/>&lt;!-- il nostro campo \"to\" --&gt;<br \/><\/strong><br \/>&lt;input id=\"to\" type=\"text\" \/&gt;<br \/><br \/><strong><br \/>&lt;!-- Un &lt;div&gt; vuoto per contenere l'autocomplete --&gt;<br \/><\/strong><br \/>&lt;div id=\"ac\"&gt;&lt;\/div&gt;<br \/><br \/>&lt;\/div&gt;<br \/>&lt;\/body&gt;<br \/><br \/>&lt;script&gt;<br \/><br \/><strong><br \/>\/\/ La nostra rubrica indirizzi statica resa come lista <br \/>di hash tables<br \/><\/strong><\/code>{emailcloak=off}<br \/><code>var addressBook = [<br \/> {name:'Fulanito L\u00f3pez', email:'fulanito@example.com'},<br \/> {name:'Erik L\u00f8rgensen', email:'erik@example.com'},<br \/> {name:'Lorena Smith',   email:'lorena@example.com'},<br \/> {name:'James L\u00f6',       email:'james@example.com'}<br \/>];<br \/><\/code>{emailcloak=on}<br \/><code><strong>\/* <br \/>Cicla sulla nostra rubrica indirizzi e aggiunge un nuovo campo ad ogni<br \/>riga chiamato \"search.\" Questo contiene una versione accent-folded del <br \/>campo \"name\".<br \/>*\/<\/strong><br \/>for (var i = 0; i&lt; addressBook.length; i++) {<br \/>  addressBook[i]['search'] = accent_fold(addressBook[i]['name']);<br \/>}<br \/><br \/><strong>\/\/ Creazione di un oggetto datasource YUI dalla nostra rubrica grezza<\/strong><br \/>var datasource = new YAHOO.util.LocalDataSource(addressBook);<br \/><br \/><strong>\/*<br \/>Un datasource \u00e8 una tabella, ma il nostro array di hash tables non ho il<br \/>concetto dell'ordinamento in colonna. Quindi bisogna dire al datasource<br \/>come ordinare le colonne <br \/>*\/<\/strong><br \/>datasource.responseSchema = {fields : [\"email\", \"name\", \"search\"]};<br \/><br \/><strong>\/*<br \/>Istanziare la widget di autocompletamento con il riferimento al campo di<br \/>input, al div vuoto e all'oggetto datasource.<br \/>*\/<\/strong><br \/>var autocomp = new YAHOO.widget.AutoComplete(\"to\", \"ac\", datasource);<br \/><br \/><strong>\/\/ Permette l'inserimento di pi\u00f9 entri specificando come delimitatori<br \/>\/\/lo spazio e la virgola<\/strong><br \/>autocomp.delimChar = [\",\",\" \"];<br \/><br \/><strong>\/* <br \/>Aggiunge un nuovo metodo filterResults() all'oggetto \"autocomplete\":<br \/>cicla sul datasource e cerca \"q\" all'interno del campo \"search\".<br \/>Questo metodo viene richiamato ogni volta che l'utente inserisce un <br \/>nuovo carattere nel campo di input.<br \/>*\/<\/strong><br \/>autocomp.filterResults = function(q, entries, resultObj, cb) {<br \/>  var matches = [];<br \/>  var re = new RegExp('\\\\b'+accent_fold(q), 'i');<br \/>  for (var i = 0; i &lt; entries.length; i++) {<br \/>     if (re.test(entries[i]['search'])) {<br \/>        matches.push(entries[i]);<br \/>     }<br \/>  }<br \/>  resultObj.results = matches;<br \/>  return resultObj;<br \/>};<br \/><br \/><strong>\/*<br \/>Aggiunge un metodo formatResult(). Viene richiamato su <br \/>ciascun risultato ritornato da formatResult(). Ritorna <br \/>una buona rappresentazione HTML del confronto.<br \/>In questo metodo abbiamo eseguito la funzione di evidenziazione<br \/>accent-folded sul nome e sull'e-mail. <br \/>*\/<\/strong><br \/>autocomp.formatResult = function (entry, q, match) {<br \/>  var name = accent_folded_hilite(entry[1], q);<br \/>  var email = accent_folded_hilite(entry[0], q);<br \/>  return name + ' ';<br \/>};<br \/><br \/><strong>\/\/fine<\/strong><br \/><br \/><br \/><\/code><br \/><\/pre>\n<\/div>\n<div class=\"paragrafo\">\n<h2>Migliaia di complicazioni&#8230;<\/h2>\n<p>La soluzione dell&#8217;accent-folding funziona principalmente per le lingue dell&#8217;Europa occidentale, ma non va bene per tutte. Sfrutta le peculiarit\u00e0  di questa famiglia di lingue ed i problemi limitati al dominio dei nostri esempi, dove \u00e8 meglio avere qualche risultato piuttosto che nessun risultato. In Germania, sarebbe pi\u00f9 corretto che <strong>\u00dc<\/strong> venisse mappato con <strong>Ue<\/strong> invece che solo a <strong>U<\/strong>. Un francese che cerchi sul web la parola <strong>th\u00e9<\/strong> (tea) sarebbe infastidito da tutti i risultati irrilevanti in inglese che darebbe la ricerca.<\/p>\n<p>Fino ad ora, si pu\u00f2 solo mappare un singolo carattere. Sarebbe molto complicato ricondurre \u201c<strong>Marc Chagall<\/strong>\u201d scritto con caratteri latini all&#8217;equivalente in alfabeto cirillico  \u201c<strong>\u041c\u0430\u0440\u043a \u0428\u0430\u0433\u0430\u043b<\/strong>\u201d o in Yiddish \u201c<strong>\u05de\u05d0\u05b7\u05e8\u05e7 \u05e9\u05d0\u05b7\u05d2\u05d0\u05b7\u05dc<\/strong>.\u201d Ci sono molte interessanti analogie tra i caratteri, ma un mapping bidirezionale svincolato dal contesto \u00e8 probabilmente impossibile.<\/p>\n<p>In capo a ci\u00f2 c&#8217;\u00e8 un altro problema: una lingua pu\u00f2 avere pi\u00f9 di un sistema di scrittura. La <a href=\"http:\/\/it.wikipedia.org\/wiki\/Translitterazione\">translitterazione<\/a> consiste nello scrivere una lingua in un diverso alfabeto. Non \u00e8 esattamente come la <a href=\"http:\/\/it.wikipedia.org\/wiki\/Trascrizione_e_traslitterazione\">trascrizione<\/a>, che mappa i <em>suoni<\/em> come in \u201c<strong>hola, que paso<\/strong>\u201d in \u201c<strong>oh-la, keh pah-so<\/strong>.\u201d. La translitterazione cerca di mappare i <em>simboli scritti<\/em> in un altro alfabeto, idealmente in maniera reversibile.<\/p>\n<p>Queste quattro frasi dicono tutte \u201cAi bambini piace guardare la televisione\u201d in Giapponese:<\/p>\n<ul>\n<li><strong>Kanji<\/strong>: \u5b50\u4f9b\u306f\u30c6\u30ec\u30d3\u3092\u898b\u308b\u306e\u304c\u597d\u304d\u3067\u3059\u3002<\/li>\n<li><strong>Hiragana<\/strong>: \u3053\u3069\u3082 \u306f \u3066\u308c\u3073 \u3092 \u307f\u308b \u306e \u304c \u3059\u304d \u3067\u3059 \u3002<\/li>\n<li><strong>Romaji<\/strong>: kodomo wa terebi o miru noga suki desu.<\/li>\n<li><strong>Cyrillic<\/strong>: \u043a\u043e\u0434\u043e\u043c\u043e \u0432\u0430 \u0442\u044d\u0440\u044d\u0431\u0438 \u043e \u043c\u0438\u0440\u0443 \u043d\u043e\u0433\u0430 \u0441\u0443\u043a\u0438 \u0434\u044d\u0441\u0443.<\/li>\n<\/ul>\n<p>Per secoli le persone si sono inventate modi per scrivere diverse lingue con qualunque tastiera o con qualsiasi sistema tipografico avessero a disposizione. Cos\u00ec, anche se l&#8217;utente legge solo una lingua, pu\u00f2 leggerla in schemi di translitterazione multipli. Alcuni schemi sono logici ed accademici, ma spesso sono sistemi organici disordinati che dipendono da accenti regionali o da codice di scarsa qualit\u00e0 utilizzato da molto tempo. L&#8217;era del computer ha favorito una nuova esplosione di sistemi dovuta al fatto che le persone hanno imparato a chattare e mandare email con il semplice ASCII.<\/p>\n<p>Molto lavoro \u00e8 gi\u00e0 stato fatto su questo problema e ci sono due strade gi\u00e0 delineate tra cui scegliere: la strada giusta e quella che forse potrebbe essere una buona strada. Nessuna di queste ha la semplicit\u00e0 e l&#8217;ingenuit\u00e0 delle nostre hash tables, ma saranno meno fastidiose per i vostri utenti nelle applicazioni in generale.<\/p>\n<p>La prima strada \u00e8 la <a href=\"http:\/\/icu-project.org\" title=\"International Components for Unicode\">International Components for Unicode<\/a> (ICU), un progetto che ha avuto inizio nei primi anni &#8217;90 nell&#8217;Unione Europea. Ha come scopo quello di essere una libreria per translitterazioni completa, che riconosce la lingua, che utilizza Unicode e con capacit\u00e0 di formattazione&#8230; Insomma, fa tutto. E&#8217; enorme ed \u00e8 scritta in C++\/Java; richiede una conoscenza contestuale degli input e degli output per poter lavorare.<\/p>\n<p>La seconda strada \u00e8 <a href=\"http:\/\/search.cpan.org\/perldoc\/Text::Unidecode\" title=\"Unidecode\">Unidecode<\/a>, una libreria per translitterazione libera dal contesto disponibile per Perl e per <a href=\"http:\/\/pypi.python.org\/pypi\/Unidecode\" title=\"Python\">Python<\/a>. Cerca di fare la translitterazione di tutti i caratteri Unicode verso un alfabeto latino di base. Non cerca di essere reversibile, per uno specifico linguaggio e nemmeno generalmente corretta: \u00e8 un hack rapido e sporco ma ci\u00f2 nonostante piuttosto comprensibile.<\/p>\n<p>L&#8217;accent-folding messo nei posti giusti risparmia agli utenti un po&#8217; di tempo e rende il vostro software pi\u00f9 intelligente ed elegante. La stretta segregazione delle lingue e delle locali \u00e8 parzialmente un artefatto delle limitazioni della tecnologia che non ha pi\u00f9 ragion d&#8217;essere. Dipende da voi quanto far avanzare le cose, ma anche un minimo sforzo pu\u00f2 farvi fare molta strada. Buona fortuna!<\/p>\n<\/div>\n<div id=\"credits\">\n<ul>\n<li>Illustrazioni create da <a href=\"http:\/\/www.mondonascosto.com\/\">Carlo Brigatti<\/a><\/li>\n<\/ul>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>La tecnica dell&#8217;accent-folding consiste nel mappare i caratteri non accentati ai caratteri accentati, al fine di aumentare i risultati suggeriti automaticamente che si ottengono compilando alcuni campi in alcune applicazioni.<\/p>\n","protected":false},"author":818,"featured_media":7000569,"comment_status":"open","ping_status":"open","template":"","categories":[245,279,271,12,275,9],"tags":[],"coauthors":[288],"class_list":["post-44","article","type-article","status-publish","has-post-thumbnail","hentry","category-accessibilita","category-interaction-design","category-javascript","category-numero-due-9-marzo-2010","category-tipografia-web-font","category-usabilita"],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/article\/44","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/article"}],"about":[{"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/types\/article"}],"author":[{"embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/users\/818"}],"replies":[{"embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/comments?post=44"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/media\/7000569"}],"wp:attachment":[{"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/media?parent=44"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/categories?post=44"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/tags?post=44"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/coauthors?post=44"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}