TransWikia.com

Why is char not expandable?

TeX - LaTeX Asked by Planted on July 24, 2021

char<number> is a TeX primitive that results in the character of ASCII code <number> with category code 12. However, it isn’t expandable, unlike it’s many cousins romannumeral, number, etc.

From my understanding, char does not look up upper/lowercase/catcode tables, like uppercase and lowercase, so I’m confused as to why it unexpandable. (I’m not really sure if this is related at all, but I remember from the top of my head that it’s the case for upper/lowercase)

3 Answers

luatex and xetex provide Uchar that is expandable

Note that tex has a built in mapping between external character encodings and the internal character codes, and char access the latter so if char expanded to a character token and files were written out and read back (for tables of contents etc) then the behaviour would be different to the current non-expandable behaviour as the characters would be re-mapped (incorrectly, most likely)

Correct answer by David Carlisle on July 24, 2021

Only for additional information. You can define expandable echar{number} by this code in pdftex:

defhex#1{ifcasenumexpr#1relax 0or 1or 2or 3or 4%
   or 5or 6or 7or 8or 9or aor bor cor dor eor ffi}
newcounttmpa  newcounttmpb
defechar{}
defaddto#1#2{expandafterdefexpandafter#1expandafter{#1#2}}
defxstring{expandafterxstringAstring}  defxstringA#1{}
{endlinechar=-1
   loop
      edeftmp{noexpandxstringxstring^string^hextmpbhextmpa}
      scantokensexpandafter{expandafteredefexpandaftertmpexpandafter{tmp}}
      globalexpandafteraddtoexpandafterecharexpandafter{tmpnoexpandor}
      advancetmpa by1relax
      ifnumtmpa=16 tmpa=0 advancetmpb by1 fi
      ifnumtmpb<16 repeat   
}
edefechar #1{noexpandifcasenoexpandnumexpr#1relaxecharnoexpandfi}

This code creates echar as macro, roughly speaking:

defechar#1{ifcase#1^^00or ^^01or ^^02or ... or ^^feor ^^fffi}

where all tokens between or have category like after string.

Answered by wipet on July 24, 2021

David Carlisle already has explained why char should be unexpandable.

However, there are cases in which an expandable version is handy and expl3 has the facility available. Here is a plain TeX version (needs an e-TeX engine such as pdftex, xetex or luatex).

input expl3-generic

ExplSyntaxOn

cs_new:Npn expchar #1 { char_generate:nn { #1 } { 12 } }
cs_new:Npn xexpchar #1 #2 { char_generate:nn { #1 } { #2 } }

ExplSyntaxOff

edeftest{expchar{92}}
{ttmeaningtest}

{tttest}

catcode`/=13 def/{abc}

xexpchar{47}{13}

bye

enter image description here

With LaTeX one has a better facility (the category code can be given as an optional argument)

documentclass{article}

ExplSyntaxOn
NewExpandableDocumentCommand{expchar}{O{12}m}
 {
  char_generate:nn { #2 } { #1 }
 }
ExplSyntaxOff

begin{document}

ttfamily

edeftest{expchar{92}}
meaningtest

test

begingroup
catcode`/=13 def/{abc}

edeftest{expchar[13]{47}}
meaningtest

test
endgroup

end{document}

enter image description here

Answered by egreg on July 24, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP