So erhalten Sie den Unicode eines chinesischen Zeichens in Latex

So erhalten Sie den Unicode eines chinesischen Zeichens in Latex

Wie kann ich den UTF-16-Code eines chinesischen Schriftzeichens in Latex erhalten? Wenn ich beispielsweise den Unicode von „你“ in Latex drucken möchte, wie kann ich dies tun, indem ich Latex auffordere, den Code für mich zu suchen?

Antwort1

Hier ist eine Implementierung, die das Drucken des Unicode-Codepunkts, der UTF8-Darstellung und der UTF16-Darstellung ermöglicht.

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

Antwort2

Hier ist eine Implementierung in expl3. Wie es funktioniert, erfahren Sie in den Kommentaren.

Aktualisierenum mit allen TeX-Engines zu funktionieren. (Die Zeichen selbst werden nur mit den Unicode-Engines gedruckt.)

Ich habe keine Ahnung, ob das die beste Vorgehensweise ist …

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

verwandte Informationen