Cómo obtener el Unicode de un carácter chino en Latex

Cómo obtener el Unicode de un carácter chino en Latex

¿Cómo puedo obtener el código UTF-16 de un carácter chino en Latex? Por ejemplo, si quiero imprimir el Unicode de `你' en Latex, ¿cómo puedo hacerlo pidiéndole a Latex que busque el código por mí?

Respuesta1

Aquí hay una implementación que permite imprimir el punto de código Unicode, la representación UTF8 y la representación 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{

Respuesta2

Aquí hay una implementación en expl3. Vea los comentarios sobre cómo funciona.

Actualizarpara trabajar con todos los motores TeX. (Los caracteres en sí solo se imprimen con los motores Unicode).

No tengo idea si esta es la mejor manera de hacer esto...

\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{

información relacionada