2012-09-21 11 views
10

Si scopre che il carattere maiuscolo di un personaggio è un business complicato. Se si esce dal set di caratteri ASCII di base, le regole per il carattere maiuscolo e il carattere minuscolo di un carattere dipendono effettivamente dalle impostazioni locali in cui è in esecuzione l'applicazione.In haskell come è possibile scrivere in maiuscolo un carattere Unicode rispetto alle impostazioni internazionali correnti

Come applicazione dimostrativa, sto tentando di mettere in maiuscolo la lettera "i" (con un punto) e la lettera "i" (senza punto). Ora, in en_US, 'i' (con un punto) le maiuscole in 'I', e 'i' (senza un punto) non esiste (ma sempre in maiuscolo in 'I').

Ma, se si passa a Turco (tr_TR.UTF-8), 'i' (con un punto) deve maiuscole a 'İ' (anche con un punto) e 'ı' (senza punto) deve maiuscole a "I" (anche senza punto). Le lettere minuscole dovrebbero invertire queste operazioni.

iİıI --> İİII (tr_TR.UTF-8) 
iİıI --> IİII (en_US.UTF-8) 

Ora, posso farlo perfettamente in C. Come posso farlo in Haskell? Tutte le ricerche che faccio mi indirizzano direttamente a Data.Char.toUpper, che non è consapevole delle impostazioni internazionali. Non ho trovato alcuna funzione che sia in grado di riconoscere le impostazioni locali.


Ecco un esempio di codice da C. Lo eseguo sul mio computer Linux.

#include <stdio.h> 
#include <stdlib.h> 
#include <locale.h> 
#include <wctype.h> 
#include <string.h> 
#include <errno.h> 

wchar_t latin_small_sharp_s[5] = {0x00df, 0x00df, 0x0053, 0x0053, 0}; 
wchar_t turkish_is[5] = {0x0069, 0x0130, 0x0131, 0x0049, 0}; 

char multibyte_turkish_is[7] = {0x69, 0x01, 0x30, 0x01, 0x31, 0x49, 0}; 

void print_in_locale (const char *locale, const wchar_t *str, const size_t len) { 
    wchar_t *dest = calloc(len * 2, sizeof(wchar_t)); 
    int i; 

    if (!setlocale(LC_CTYPE, locale)) { 
    fprintf(stderr, "Locale %s failed with error: %s", locale, strerror(errno)); 
    exit(1); 
    } 

    for (i = 0; i < len; i++) { 
    dest[i] = towupper(str[i]); 
    } 
    printf("%ls, %ls\n", str, dest); 
    free(dest); 
} 

int main() { 
    print_in_locale("de_DE.utf8", latin_small_sharp_s, 5); 
    print_in_locale("tr_TR.utf8", turkish_is, 5); 
    print_in_locale("de_DE.utf8", turkish_is, 5); 
} 

Se è stato salvato in "locale_test.c", è possibile eseguirlo su riga di comando con ...

gcc -o locale_test locale_test.c && ./locale_test 
+0

Hai utilizzato il turco solo come esempio o sviluppi un software destinato alla Turchia? –

+1

Esempio. Sto lavorando a un software che pubblicheremo in modo multinazionale quando ho iniziato a imbattermi in questo, e poi nel parlarne in G + ho avuto molti amici, compresi quelli che non sono techies, interessati al problema. Avevo pensato che durante il weekend avrei sviluppato un software che ne dimostrava molte, ma non ne ho mai avuto la possibilità. –

risposta

13

Utilizzare la funzione Data.Text.ICU.toUpper dal pacchetto text-icu.

toUpper :: LocaleName -> Text -> Text

maiuscolo i caratteri di una stringa.

L'alloggiamento è dipendente dalle impostazioni internazionali e sensibile al contesto. Il risultato potrebbe essere più lungo o più corto dell'originale.

+0

Era esattamente così! Sembra che per la maggior parte del supporto Unicode, non ho bisogno di nulla al di là del Preludio putStrLn, Data.Text.ICU (per la lingua dipendente dalle maiuscole e minuscole) e Data.Text (per la costruzione di stringhe unicode). Possibilmente anche le funzioni codec unicode per passare da UTF-8 a rappresentazione interna. –

Problemi correlati