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 endcsnameToto 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} 
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 nimi
ABCDEF, ak je prvý token';
- osmičkové číslo, to znamená postupnosť číslic medzi nimi
01234567, 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 ' Qsú 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} 