Problém s mojím chápaním príkazu expandafter a newcommand s argumentmi a sout

Problem With My Understanding Expandafter



Riešenie:

Mali by ste si byť vedomí skutočnosti, že Kat vyžaduje na doručenie uloženého textu viac ako jeden krok rozšírenia: po prvom kroku rozšírenia dostanete

 expandafter  csname INT  rom {1} intKATAkatNUM  rom {1} num  endcsname

Toto expandafter nerobí vôbec nič, pretože sa pokúša rozšíriťI.



Takmer úplné rozšírenie, ktoré tu potrebujete, môžete vynútiť pomocou rímskočíselného triku:



 documentclass {article}  usepackage {ulem, lipsum}  usepackage [T1] {fontenc}  newcommand*{ rom} [1] { romannumeral #1}  newcommand  INTiintKATAkatNUMinum {% Test Text for demonstration. V origináli je tento príkaz zostavený. %}  newcommand { Kat} [4] {% Príkaz na zostavenie zostavených príkazov.  csname INT  rom {#1} intKAT#2katNUM  rom {#3} num#4  endcsname}  newcommand  soutt [1] {% sout s rozšírením  expandafter  sout  expandafter { romannumeral-`Q#1 } %}  begin {document}  parbox {2cm} { sout {Južné makro ulemu zvládne delenie slov a prerušovanie riadkov v texte zadanom priamo, ale nie ako makro, pozri nasledujúci riadok!}  soutt { INTiintKATAkatNUMinum} % funguje  soutt { Kat {1} {A} {1} {}} %nekončí   end {document}

sem zadajte popis obrázku



A nie, sout nerobí delenie slov.

The romannumerický trik bol vysvetlený niekoľkokrát, ale tu je krátka ilustrácia.

Primitív romannumeral chce apo ňom a tu využívame zvláštnu vlastnosť TeXu: po explicitnom, TeX hľadá príponupotom rozšírenie tokenov počas tohto vyhľadávania; zastaví expanziu po nájdení buď explicitného vesmírneho tokenu, alebo nerozbaliteľného tokenu.



Jednoznačnémožno vyjadriť niekoľkými spôsobmi:

  • postupnosť číslic;
  • hexadecimálne číslo, to znamená postupnosť číslic alebo znakov medzi nimiABCDEF, ak je prvý token';
  • osmičkové číslo, to znamená postupnosť číslic medzi nimi01234567, ak je prvý token';
  • abecedná konštanta, ak je prvý znak`(spätná citácia).

Radikálnej notácii by vo všetkých prípadoch malo predchádzať znamienko mínus'' ', ak chceme zadať záporné číslo.

V prvých troch prípadoch TeX vykonáva rozšírenie, kým nenájde niečo, čo nekvalifikuje ako prípustnú číslicu.

Prípad, ktorý nás zaujíma, je posledný. Abecedná konštanta je znak znaku alebo riadiaca sekvencia, ktorej názov pozostáva z jedného znaku (a nemusí byť definovaný). Takže

`Q ' Q

sú ekvivalentné spôsoby, ako požiadať o číslo 81 (ASCII kód ​​Q). Uniknutý zápis je zásadný pre znaky s podivným kódom kategórie, ako napr

 \%` ^^ @

(posledne menovaný je 0).

Skutočnosť, že TeX rozširuje tokeny podľa abecedných konštánt, je pre túto aplikáciu rozhodujúca:je už plne známy a v našom prípade je-81, ale TeX napriek tomu rozširuje tokeny. Po ukončení hľadania voliteľného priestoru TeX pristúpi k dokončeniu rozšírenia romannumeral-`Q, ktorý je prázdny, pretože číslo je záporné.

Nemôžeme použiť romannumeral-81 priamo, pretože ak by nasledujúci token po rozšírení bol náhodou číslica, bol by braný ako súčasť.

Obmedzením tejto metódy je, že počiatočný priestor v konečnom rozšírení sa bude hltať.

V nasledujúcom vydaní TeX Live budú mať všetky motory expand (v súčasnosti je k dispozícii iba s LuaTeX); Motory založené na MiKTeX by to už mali mať. S Rozšírené, vec bude jednoduchšia:

 newcommand  soutt [1] {% sout s expanziou  expandafter  sout  expandafter { expand {#1}}}

pretože Expansion poskytuje úplné rozšírenie svojho argumentu v jednom kroku.


Môžeš použiťduša, ak chceš delenie slov. Zodpovedajúce makro je st (alebo textst). Len pre zmenu to implementujem doexpl3, kde romannumeral je k dispozícii akof-expanzia.

 documentclass {article}  usepackage [T1] {fontenc}  usepackage {soul}  usepackage {xparse}  ExplSyntaxOn  NewDocumentCommand { Kat} {mmmm} { use: c {INT  int_to_roman: n {#1} intKAT #2 katNUM  int_to_roman: n { #3} num #4}}  NewExpandableDocumentCommand { soutt} {m} { oberreiter_sout: f { #1}}  cs_new_protected: Nn  oberreiter_sout: n { textst { #1} }  cs_generate_variant: Nn  oberreiter_sout: n {f}  ExplSyntaxOff  newcommand  INTiintKATAkatNUMinum {% Test Text for demonstration. V origináli je tento príkaz zostavený. %}  begin {document}  parbox {2cm} { st {Prvé makro duše dokáže spracovať delenie slov a prerušenia riadkov v texte zadanom priamo, ale nie ako makro, pozri nasledujúci riadok!}  soutt { INTiintKATAkatNUMinum} % funguje  soutt { Kat {1} {A} {1} {}} %nekončí   end {document}

sem zadajte popis obrázku