我正在尝试将一些 UTF-8 字符输入到 TextMate 中的 LaTeX 文件中(表示其默认编码为 UTF-8),但 LaTeX 似乎不理解它们。
运行 cat my_file.tex
在终端中正确显示字符。运行 ls -al
会显示我以前从未见过的内容:文件列表中的“@”:
-rw-r--r--@ 1 me users 2021 Feb 11 18:05 my_file.tex
(而且,是的,我在 LaTeX 中使用了 \usepackage[utf8]{inputenc}
。)
我找到了 iconv
,但这似乎无法告诉我编码是什么——它只有在我弄清楚后才会转换。
在 file
命令上使用 -I
(这是一个大写的 i)选项似乎显示了文件编码。
file -I {filename}
在 Mac OS X 中,命令 file -I
(大写 i)将为您提供正确的字符集,只要您正在测试的文件包含基本 ASCII 范围之外的字符。
例如,如果您进入终端并使用 vi 创建文件,例如。 vi test.txt
然后插入一些字符并包含一个重音字符(尝试 ALT-e 后跟 e)然后保存文件。
他们键入 file -I text.txt
,您应该得到如下结果:
test.txt: text/plain; charset=utf-8
file
命令声称它的 us-ascii
@
表示该文件具有与其关联的扩展文件属性。您可以使用 getxattr()
函数查询它们。
没有确定的方法来检测文件的编码。阅读this答案,它解释了原因。
有一个命令行工具 enca,它会尝试猜测编码。你可能想检查一下。
@
指示的属性很可能包含文件编码属性。您可以使用命令 xattr -p com.apple.TextEncoding <filename>
查看编码属性(如果存在)。
ls -l@ <filename>
即可查看为文件设置了哪些属性。要查看实际属性,请输入 xattr -p com.apple.TextEncoding <filename>
enca
,请执行 brew install enca
,您必须指定语言,但 none 有效,因此:enca FILENAME -L __
vim -c 'execute "silent !echo " . &fileencoding | q' {filename}
在我的 bash 配置中的某处别名为
alias vic="vim -c 'execute \"silent \!echo \" . &fileencoding | q'"
所以我只是输入
vic {filename}
在我的香草 OSX Yosemite 上,它产生的结果比“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
alias vic="vim -c 'execute \"silent \!echo \" . &fileencoding | q'"
您还可以使用以下命令从一种文件类型转换为另一种文件类型:
iconv -f original_charset -t new_charset originalfile > newfile
例如
iconv -f utf-16le -t utf-8 file1.txt > file2.txt
只需使用:
file -I <filename>
而已。
file -I
让我text/plain; charset=unknown-8bit
。虽然它对 utf8 文件效果更好:text/plain; charset=utf-8
。
使用带有 --mime-encoding
选项(例如 file --mime-encoding some_file.txt
)的 file
命令而不是 -I 选项在 OS X 上有效,并且具有省略 mime 类型“text/plain”的额外好处,您可能不会这样做关心。
file
命令。不知道有那个存在。小白。反正。很抱歉投反对票。除非有人编辑此答案,否则不会让我撤消它。
经典的 8 位 LaTeX 可以使用的 UTF8 字符非常有限;它高度依赖于您使用的字体的编码以及该字体可用的字形。
由于您没有给出具体示例,因此很难确切知道问题出在哪里 - 无论您是尝试使用字体没有的字形,还是一开始没有使用正确的字体编码地方。
这是一个最小的示例,展示了如何在 LaTeX 文档中使用几个 UTF8 字符:
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage[utf8]{inputenc}
\begin{document}
‘Héllø—thêrè.’
\end{document}
您可能对 [utf8x] 编码有更多的运气,但请注意它不再受支持,并且与 [utf8] 相比有一些特质(据我记得;我已经有一段时间没有看过它了)。但如果它成功了,那对你来说就是最重要的。
@ 符号表示文件有 extended attributes。 xattr file
显示它具有哪些属性,xattr -l file
也显示属性值(有时可能很大 — 尝试例如 xattr /System/Library/Fonts/HelveLTMM
来查看资源分支中存在的旧式字体)。
在终端中键入 file myfile.tex
有时可以使用一系列算法和幻数告诉您文件的编码和类型。它相当有用,但不要依赖它提供具体或可靠的信息。
Localizable.strings
文件(可在本地化的 Mac OS X 应用程序中找到)通常报告为 UTF-16 C 源文件。
您可以尝试将文件加载到 Firefox 窗口中,然后转到查看 - 字符编码。文件的编码类型旁边应该有一个复选标记。
我实现了下面的 bash 脚本,它对我有用。
它首先尝试将 iconv
从 file --mime-encoding
返回的编码转换为 utf-8
。
如果失败,它会遍历所有编码并显示原始文件和重新编码文件之间的差异。它会跳过产生较大差异输出的编码(由 MAX_DIFF_LINES
变量或第二个输入参数定义的“大”),因为这些很可能是错误的编码。
如果由于使用此脚本而发生“坏事”,请不要怪我。那里有一个rm -f
,所以有怪物。我试图通过在带有随机后缀的文件上使用它来防止不利影响,但我没有做出任何承诺。
在达尔文 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
您使用的是哪种 LaTeX?当我使用 teTeX 时,我必须手动下载 unicode 包并将其添加到我的 .tex 文件中:
% UTF-8 stuff
\usepackage[notipa]{ucs}
\usepackage[utf8x]{inputenc}
\usepackage[T1]{fontenc}
现在,我已经从 TeXlive 2008 包 (here) 切换到 XeTeX,它更加简单:
% UTF-8 stuff
\usepackage{fontspec}
\usepackage{xunicode}
至于检测文件的编码,您可以使用 file(1)
(但它相当有限)但就像其他人所说的那样,这很困难。
检查编码的蛮力方法可能只是在十六进制编辑器或类似工具中检查文件。 (或编写程序检查)查看文件中的二进制数据。 UTF-8 格式相当容易识别。所有 ASCII 字符都是单字节,其值低于 128 (0x80) 多字节序列遵循 wiki article 中显示的模式
如果您能找到一种更简单的方法来让程序为您验证编码,那显然是一种捷径,但如果一切都失败了,这将起到作用。
不定期副业成功案例分享
file -I *
似乎非常适合我(在 OSX 上)。系统抱怨许多文件之一的编码,但没有指定哪个。所有文件都是 ascii,除了一个是 utf-8。很可能是罪魁祸首。