<div dir="ltr"><div><div><div><div><div><div>I can confirm that \string does convert character tokens<br>to two tokens giving the UTF-16 representation.<br><br></div>With the attached file luatex produces<br><br>90,33<br>34,33<br>233,33<br>233,33<br>65530,33<br>65537,33<br>65537,33<br><br><br></div>which is in each case the unicode value of the character followed by that of !<br><br></div>xetex produces<br><br>90,33<br>34,33<br>233,33<br>233,33<br>65530,33<br>55296,56321<br>55296,56321<br><br><br></div>where the last two lines show that \string has generated U+D800 U+DC01<br></div>which does correspond to the UTF-16 encoding of U+10001 confirming<br></div><div>that \string on a character token has produced two tokens that have been<br></div><div>picked up separately as #1 and #2 of the \test macro.<br></div><div><br><br></div><div>If I am reading it right the UTF-16 comes from here<br><br>procedure print_char(@!s:integer); {prints a single character}<br>label exit;<br>var l: small_number;<br>begin if (selector>pseudo) and (not doing_special) then<br>  {``printing'' to a new string, encode as UTF-16 rather than UTF-8}<br>                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^<br>  begin if s>=@"10000 then<br>   begin print_visible_char(@"D800 + (s - @"10000) div @"400);<br>   print_visible_char(@"DC00 + (s - @"10000) mod @"400);<br>   end else print_visible_char(s);<br>   return;<br>  end;<br><br></div><div>so could not do that and instead just  print_visible_char(s); but perhaps some<br></div><div>other context requires UTF-16 in which case perhaps the selector needs another<br></div><div>state to allow a code path that doesn't encode as UTF-8 or UTF-16 but just generates<br></div><div>the internal UTF-32 representation?<br></div><div><br><br></div>David<br><br></div>