如何在Latex中获取汉字的unicode

如何在Latex中获取汉字的unicode

如何在 Latex 中获取中文字符的 UTF-16 代码?例如,如果我想在 Latex 中打印“你”的 Unicode,如何通过让 Latex 帮我搜索代码来实现?

答案1

这是一个允许打印 Unicode 代码点、UTF8 表示和 UTF16 表示的实现。

\documentclass{article}

\usepackage{xparse}
\usepackage{fontspec}

\setmainfont{Heiti SC}

\ExplSyntaxOn

\NewDocumentCommand{\codepoint}{m}
 {
  U+\xiang_codepoint:n { #1 }
 }
\NewDocumentCommand{\codepointutfviii}{m}
 {
  UTF8:\nobreakspace
  \xiang_codepoint_utfviii:f { \char_codepoint_to_bytes:n { `#1 } }
 }
\NewDocumentCommand{\codepointutfxvi}{m}
 {
  UTF16:\nobreakspace
  \xiang_codepoint_utfxvi:n { #1 }
 }

\NewDocumentCommand{\chardetails}{m}
 {
  #1~\texttt
   {
    \codepoint{#1},~
    \codepointutfviii{#1},~
    \codepointutfxvi{#1}
   }
 }


\cs_new:Nn \xiang_codepoint:n
 {
  \int_compare:nT { `#1 < 4096 } { 0 }
  \int_compare:nT { `#1 < 256 } { 0 }
  \int_to_Hex:n { `#1 }
 }

\cs_new:Nn \xiang_codepoint_utfviii:n
 {
  \tl_map_function:nN { #1 } \__xiang_codepoint_utfviii_aux:n
 }
\cs_generate_variant:Nn \xiang_codepoint_utfviii:n { f }

\cs_new:Nn \__xiang_codepoint_utfviii_aux:n
 {
  \tl_if_empty:nF { #1 }
   {
    <\int_to_Hex:n { #1 }>
   }
 }

\cs_new:Nn \xiang_codepoint_utfxvi:n
 {
  \int_compare:nTF { `#1 < 65536 }
   {
    <\xiang_codepoint:n { #1 }>
   }
   {
    \__xiang_codepoint_utfxvi:n { #1 }
   }
 }

\cs_new:Nn \__xiang_codepoint_utfxvi:n
 {
  <
  \int_to_Hex:n
   {
    \int_div_truncate:nn { `#1 - "10000 } { "400 } + "D800
   }
  >
  <
  \int_to_Hex:n
   {
    \int_mod:nn { `#1 - "10000 } { "400 } + "DC00
   }
  >
 }

\ExplSyntaxOff

\begin{document}

\chardetails{a}

\chardetails{à}

\chardetails{。}

\chardetails{豈}

\chardetails{你}

\chardetails{

答案2

这是 中的一个实现expl3。请参阅注释以了解其工作原理。

更新可与所有 TeX 引擎配合使用。(字符本身只能用 Unicode 引擎打印。)

我不知道这是否是最好的方法……

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn

\int_new:N \l__xiang_high_int
\int_new:N \l__xiang_low_int
\int_new:N \g__xiang_codepoint_int
\int_new:N \g__xiang_utfviii_byte_int
\intarray_new:Nn \g__xiang_utfviii_bytes_intarray { 4 }
\tl_new:N \l__xiang_bin_tl
\tl_new:N \l__xiang_high_tl
\tl_new:N \l__xiang_low_tl
\tl_new:N \l__xiang_byte_i_str
\tl_new:N \l__xiang_byte_ii_str
\tl_new:N \l__xiang_byte_iii_str
\tl_new:N \l__xiang_byte_iv_str

\cs_new:Nn \__xiang_utf_viii_char_to_codepoint:n
  {
    \int_set:Nn \g__xiang_codepoint_int { 0 }
    \int_set:Nn \g__xiang_utfviii_byte_int { 0 }
    \exp_args:NNx \str_set:Nn \l_tmpa_str { \tl_to_str:n { #1 } }
    % add each byte from UTF-8 character to array
    \str_map_inline:Nn \l_tmpa_str
      {
        \int_incr:N \g__xiang_utfviii_byte_int
        \intarray_gset:Nnn \g__xiang_utfviii_bytes_intarray
          { \g__xiang_utfviii_byte_int } { `##1 }
      }
    % calculate code point from UTF-8 bytes
    \int_case:nn { \g__xiang_utfviii_byte_int }
      {
        { 1 }
        {
          \int_set:Nn \g__xiang_codepoint_int
            { \intarray_item:Nn \g__xiang_utfviii_bytes_intarray { 1 } }
        }
        { 2 }
        {
          \int_set:Nn \g__xiang_codepoint_int
            {
              ( \intarray_item:Nn \g__xiang_utfviii_bytes_intarray { 1 } - "C0 )
              * "40 +
              ( \intarray_item:Nn \g__xiang_utfviii_bytes_intarray { 2 } - "80 )
            }
        }
        { 3 }
        {
          \int_set:Nn \g__xiang_codepoint_int
            {
              ( \intarray_item:Nn \g__xiang_utfviii_bytes_intarray { 1 } - "E0 )
              * "1000 +
              ( \intarray_item:Nn \g__xiang_utfviii_bytes_intarray { 2 } - "80 )
              * "40 +
              ( \intarray_item:Nn \g__xiang_utfviii_bytes_intarray { 3 } - "80 )
            }
        }
        { 4 }
        {
          \int_set:Nn \g__xiang_codepoint_int
            {
              ( \intarray_item:Nn \g__xiang_utfviii_bytes_intarray { 1 } - "F0 )
              * "40000 +
              ( \intarray_item:Nn \g__xiang_utfviii_bytes_intarray { 2 } - "80 )
              * "1000 +
              ( \intarray_item:Nn \g__xiang_utfviii_bytes_intarray { 3 } - "80 )
              * "40 +
              ( \intarray_item:Nn \g__xiang_utfviii_bytes_intarray { 4 } - "80 )
            }
        }
      }
  }

\cs_new:Nn \__xiang_codepoint_to_utf_xvi:n
  {
    \int_compare:nTF
      { #1 < 55296 }
      {
        % code point between U+0000 and U+D7FF
        % convert to hex
        \exp_args:NNx \tl_set:Nn \l_tmpa_tl { \int_to_Hex:n {#1} }
        % pad to 4 places
        \int_while_do:nn
          { \tl_count:N \l_tmpa_tl < 4 }
          { \tl_put_left:Nn \l_tmpa_tl { 0 } }
        % output UTF-16 in hex
        0x \tl_use:N \l_tmpa_tl
      }
      {
        \int_compare:nTF
          { 57344 <= #1 <= 65535 }
          {
            % code point between U+E000 and U+FFFF
            % output UTF-16 in hex
            0x \int_to_Hex:n {#1}
          }
          {
            \int_compare:nTF
              { #1 > 65535 }
              {
                % code point between U+010000 and U+10FFFF
                % subtract 0x10000
                \int_set:Nn \l_tmpb_int { #1 - 65536 }
                % convert to binary
                \exp_args:NNx \tl_set:Nn \l__xiang_bin_tl
                  { 
                    \int_to_bin:n { \l_tmpb_int }
                  }
                % pad to 20 bits
                \int_while_do:nn
                  { \tl_count:N \l__xiang_bin_tl < 20 }
                  {
                    \tl_put_left:Nn \l__xiang_bin_tl { 0 }
                  }
                % get high 10 bits
                \tl_set:Nn \l__xiang_high_tl
                  {
                    \tl_range:Nnn \l__xiang_bin_tl { 1 } { 10 }
                  }
                % get low 10 bits
                \tl_set:Nn \l__xiang_low_tl
                  {
                    \tl_range:Nnn \l__xiang_bin_tl { 11 } { 20 }
                  }
                % convert high 10 bits back to integer and add 0xD800
                \int_set:Nn \l__xiang_high_int
                  {
                    55296 + \exp_args:Ne \int_from_bin:n { \l__xiang_high_tl }
                  }
                % convert low 10 bits back to integer and add 0xDC00
                \int_set:Nn \l__xiang_low_int
                  {
                    56320 + \exp_args:Ne \int_from_bin:n { \l__xiang_low_tl }
                  }
                % output UTF-16 in hex
                0x \int_to_Hex:n { \l__xiang_high_int }
                \space
                0x \int_to_Hex:n { \l__xiang_low_int }
              }
              {
                % code point between U+D800 and U+DFFF
                Invalid~code~point.
              }
          }
      }
  }

\NewDocumentCommand \chardetails { m }
  {
    \sys_if_engine_pdftex:TF
      {
        \__xiang_utf_viii_char_to_codepoint:n { #1 }
      }
      {
        { \Large #1 \par }
        \int_set:Nn \g__xiang_codepoint_int { `#1 }
      }
    Code~point:~ \int_use:N \g__xiang_codepoint_int \par
    UTF-16:~ \__xiang_codepoint_to_utf_xvi:n { \g__xiang_codepoint_int }
  }

\sys_if_engine_pdftex:F
  {
    \usepackage{fontspec}
    \setmainfont{Noto~Sans~CJK~SC}
  }

\ExplSyntaxOff

\begin{document}
\chardetails{a}

\chardetails{à}

\chardetails{。}

\chardetails{豈}

\chardetails{你}

\chardetails{

相关内容