lstlisting 给出错误字符串包含无效的 utf-8 序列

lstlisting 给出错误字符串包含无效的 utf-8 序列

所以我有一个包含 0xef 0xbf 0xbd 的代码清单。它是测试用例的一部分:

\documentclass{article}
\usepackage{listings}

\begin{document}

\begin{lstlisting}

�\x04��

\end{lstlisting}

\end{document}

十六进制转储:

000000d0  67 7b 62 65 67 69 6e 7d  0a 0a ef bf bd 5c 78 30  |g{begin}.....\x0|
000000e0  34 ef bf bd ef bf bd 0a  0a 5c 6c 73 74 6c 69 73  |4........\lstlis|
000000f0  74 69 6e 67 7b 65 6e 64  7d 0a 0a 5c 65 6e 64 7b  |ting{end}..\end{|

lualatex 说!字符串包含无效的 utf-8 序列

我怎样才能让 lualatex 将其打印为黑色背景上的问号或类似的东西?

答案1

lulatex 似乎不接受 U+FFFD,即使正确编码为 UTF-8,这似乎是错误的,但无论如何,您可以使用输入缓冲区回调将其删除,这里将其更改为?

在此处输入图片描述

\documentclass{article}



\begin{document}

\directlua{
function zzz(buff)
 return string.gsub(buff,"^^^^fffd","?")
end
luatexbase.add_to_callback ( "process_input_buffer", zzz, "zzz" )
}

hmmm�

\end{document}

查看源代码可以清楚地了解为什么会发生这种情况,如果无法解码输入流,则函数返回 FFFD,然后如果它返回 FFFD,则会发出无效序列错误。但是,这意味着您在正确编码的 FFFD 输入字符上遇到错误。

unsigned str2uni(const unsigned char *k)
{
    register int ch;
    int val = 0xFFFD;
    const unsigned char *text = k;
    if ((ch = *text++) < 0x80) {
        val = (unsigned) ch;
    } else if (ch <= 0xbf) {    /* error */
    } else if (ch <= 0xdf) {
        if (*text >= 0x80 && *text < 0xc0)
            val = (unsigned) (((ch & 0x1f) << 6) | (*text++ & 0x3f));
    } else if (ch <= 0xef) {
        if (*text >= 0x80 && *text < 0xc0 && text[1] >= 0x80 && text[1] < 0xc0) {
            val = (unsigned)
                (((ch & 0xf) << 12) | ((text[0] & 0x3f) << 6) |
                 (text[1] & 0x3f));
        }
    } else if (ch <= 0xf7) {
        int w = (((ch & 0x7) << 2) | ((text[0] & 0x30) >> 4)) - 1, w2;
        w = (w << 6) | ((text[0] & 0xf) << 2) | ((text[1] & 0x30) >> 4);
        w2 = ((text[1] & 0xf) << 6) | (text[2] & 0x3f);
        val = (unsigned) (w * 0x400 + w2 + 0x10000);
        if (*text < 0x80 || text[1] < 0x80 || text[2] < 0x80 ||
            *text >= 0xc0 || text[1] >= 0xc0 || text[2] >= 0xc0)
            val = 0xFFFD;
    } else {
        /* the 5- and 6-byte UTF-8 sequences generate integers
           that are outside of the valid UCS range, and therefore
           unsupported
         */
    }

    if (val == 0xFFFD)
        utf_error();

    return (val);
}

相关内容