Come posso determinare la codifica dei file in OSX?

Sto cercando di inserire alcuni caratteri UTF-8 in un file LaTeX in TextMate (che dice che la sua codifica predefinita è UTF-8), ma LaTeX non sembra capirli. L’esecuzione di cat my_file.tex mostra i caratteri correttamente in Terminal. Esecuzione di ls -al mostra qualcosa che non ho mai visto prima: un “@” dal file che elenca:

 [email protected] 1 me users 2021 Feb 11 18:05 my_file.tex 

(E, sì, sto usando \usepackage[utf8]{inputenc} nel LaTeX.)

Ho trovato iconv , ma non sembra che sia in grado di dirmi che cos’è la codifica – verrà convertito solo una volta che l’avrò scoperto.

Il @ indica che il file ha attributi di file estesi associati ad esso. Puoi interrogarli usando la funzione getxattr() .

Non esiste un modo preciso per rilevare la codifica di un file. Leggi questa risposta, spiega perché.

C’è uno strumento da riga di comando, enca , che tenta di indovinare la codifica. Potresti voler controllare.

L’utilizzo dell’opzione -I (che è una maiuscola i) sul comando file sembra mostrare la codifica del file.

 file -I {filename} 

In Mac OS X il file -I comando file -I (capital i) ti darà il set di caratteri appropriato finché il file che stai test contiene caratteri al di fuori dell’intervallo ASCII di base.

Ad esempio se vai in Terminal e usi vi per creare un file es. vi test.txt quindi inserisce alcuni caratteri e include un carattere accentato (prova ALT-e seguito da e) quindi salva il file.

file -I text.txt e dovresti ottenere un risultato come questo:

test.txt: text/plain; charset=utf-8

È anche ansible convertire da un tipo di file all’altro utilizzando il seguente comando:

 iconv -f original_charset -t new_charset originalfile > newfile 

per esempio

 iconv -f utf-16le -t utf-8 file1.txt > file2.txt 
 vim -c 'execute "silent !echo " . &fileencoding | q' {filename} 

alias da qualche parte nella mia configurazione di bash come

 alias vic="vim -c 'execute \"silent !echo \" . &fileencoding | q'" 

quindi scrivo

 vic {filename} 

Sulla mia vaniglia OSX Yosemite, produce risultati più precisi di “file -I”:

 $ file -I pdfs/udocument0.pdf pdfs/udocument0.pdf: application/pdf; charset=binary $ vic pdfs/udocument0.pdf latin1 $ $ file -I pdfs/t0.pdf pdfs/t0.pdf: application/pdf; charset=us-ascii $ vic pdfs/t0.pdf utf-8 

Basta usare:

 file -I  

Questo è tutto.

Usando file comando file con l’opzione --mime-encoding (es. file --mime-encoding some_file.txt ) invece dell’opzione -I funziona su OS X e ha il vantaggio di omettere il tipo mime, “text / plain”, che probabilmente non ti interessa.

LaTeX classico a 8 bit è molto limitato in cui i caratteri UTF8 possono essere utilizzati; dipende in gran parte dalla codifica del font che stai usando e dai glifi che quel font ha a disposizione.

Dato che non fornisci un esempio specifico, è difficile sapere esattamente dove si trova il problema – se stai tentando di usare un glifo che il tuo font non ha o se non stai utilizzando la codifica corretta dei caratteri nel primo posto.

Ecco un esempio minimo che mostra come alcuni caratteri UTF8 possono essere usati in un documento LaTeX:

 \documentclass{article} \usepackage[T1]{fontenc} \usepackage{lmodern} \usepackage[utf8]{inputenc} \begin{document} 'Héllø—thêrè.' \end{document} 

Potresti avere più fortuna con la codifica [utf8x], ma tieni un po ‘in guardia che non è più supportato e ha alcune idiosincrasie rispetto a [utf8] (per quanto ricordo, è passato un po’ di tempo dall’ultima volta che l’ho guardato). Ma se fa il trucco, è tutto ciò che conta per te.

Il segno @ indica che il file ha attributi estesi . xattr file mostra quali attributi ha, xattr -l file mostra anche i valori degli attributi (che a volte possono essere grandi – prova ad esempio xattr /System/Library/Fonts/HelveLTMM per vedere un font vecchio stile che esiste nel fork delle risorse).

Il file myfile.tex in un terminale può talvolta dirti la codifica e il tipo di file usando una serie di algoritmi e numeri magici. È abbastanza utile ma non fare affidamento su di esso fornendo informazioni concrete o affidabili.

Un file Localizable.strings (trovato in applicazioni Mac OS X localizzate) viene in genere segnalato come file sorgente UTF-16 C.

Synalyze It! consente di confrontare testo o byte in tutte le codifiche offerte dalla libreria ICU . Usando questa funzione di solito vedi immediatamente quale code page ha senso per i tuoi dati.

Puoi provare a caricare il file in una finestra di Firefox e poi andare su Visualizza – Codifica caratteri. Dovrebbe esserci un segno di spunta accanto al tipo di codifica del file.

Quale LaTeX stai usando? Quando stavo usando teTeX, dovevo scaricare manualmente il pacchetto Unicode e aggiungerlo ai miei file .tex:

 % UTF-8 stuff \usepackage[notipa]{ucs} \usepackage[utf8x]{inputenc} \usepackage[T1]{fontenc} 

Ora, sono passato a XeTeX dal pacchetto TeXlive 2008 ( qui ), è ancora più semplice:

 % UTF-8 stuff \usepackage{fontspec} \usepackage{xunicode} 

Per quanto riguarda il rilevamento della codifica di un file, è ansible giocare con il file(1) (ma è piuttosto limitato) ma, come detto da qualcun altro, è difficile.

Un metodo a forza bruta per controllare la codifica potrebbe essere semplicemente controllare il file in un editor esadecimale o simile. (o scrivere un programma per verificare) Guarda i dati binari nel file. Il formato UTF-8 è abbastanza facile da riconoscere. Tutti i caratteri ASCII sono byte singoli con valori inferiori a 128 (0x80) Le sequenze multibyte seguono lo schema mostrato nell’articolo wiki

Se riesci a trovare un modo più semplice per ottenere un programma per verificare la codifica per te, è ovviamente una scorciatoia, ma se tutto il resto fallisce, questo farebbe il trucco.

Ho implementato lo script di bash qui sotto, funziona per me.

Prova prima a iconv dalla codifica restituita dal file --mime-encoding a utf-8 .

Se fallisce, passa attraverso tutte le codifiche e mostra la differenza tra il file originale e quello ricodificato. Ignora le codifiche che producono un output diff ampio (“grande” come definito dalla variabile MAX_DIFF_LINES o dal secondo argomento di input), poiché è probabile che queste siano la codifica errata.

Se “cattive cose” accadono a seguito dell’utilizzo di questo script, non incolparmi. C’è un rm -f lì dentro, quindi ci sono mostri. Ho provato a prevenire effetti negativi usandolo su file con un suffisso casuale, ma non sto facendo alcuna promise.

Testato su Darwin 15.6.0.

 #!/bin/bash if [[ $# -lt 1 ]] then echo "ERROR: need one input argument: file of which the enconding is to be detected." exit 3 fi if [ ! -e "$1" ] then echo "ERROR: cannot find file '$1'" exit 3 fi if [[ $# -ge 2 ]] then MAX_DIFF_LINES=$2 else MAX_DIFF_LINES=10 fi #try the easy way ENCOD=$(file --mime-encoding $1 | awk '{print $2}') #check if this enconding is valid iconv -f $ENCOD -t utf-8 $1 &> /dev/null if [ $? -eq 0 ] then echo $ENCOD exit 0 fi #hard way, need the user to visually check the difference between the original and re-encoded files for i in $(iconv -l | awk '{print $1}') do SINK=$1.$i.$RANDOM iconv -f $i -t utf-8 $1 2> /dev/null > $SINK if [ $? -eq 0 ] then DIFF=$(diff $1 $SINK) if [ ! -z "$DIFF" ] && [ $(echo "$DIFF" | wc -l) -le $MAX_DIFF_LINES ] then echo "===== $i =====" echo "$DIFF" echo "Does that make sense [N/y]" read $ANSWER if [ "$ANSWER" == "y" ] || [ "$ANSWER" == "Y" ] then echo $i exit 0 fi fi fi #clean up re-encoded file rm -f $SINK done echo "None of the encondings worked. You're stuck." exit 3