3

I have a token list that includes (at least) one non-expandable command (defined by \NewDocumentCommand) and want to write the result to a log file (lets assume the critical command generates character tokens only). Is there any way to enforce the execution to get the result (before shipout)?

Edit

@jlab asked for a MnWE. Well, since I don't know a solution I can only provide code that obviously does not work.

\documentclass{scrartcl} \NewDocumentCommand{\foo}{m}{#1xyz} % Well, the original is more complicated and not by me \begin{document} \newwrite\myfile \immediate\openout\myfile=bar.txt \immediate\write\myfile{\foo{abc}} % I get "\foo {abc}", but want "abcxyz" \end{document} 
5
  • in classical tex the answer is no , in luatex you could in principle typeset to a box then traverse the node list to get the font character nodes then iterate the node list, reversing any to unicode map and obtain a list of unicode characters as the result. Commented Jul 15 at 19:09
  • @DavidCarlisle: Thank you. lualatex would be fine, however, I have not much experience there. (I know Lua, but not the interfaces to LaTeX beside simple tex.sprint etc.), Commented Jul 15 at 19:10
  • as I indicated while it's possible it is rather fragile and not really in the tex spirit, I would say 99 times out of 100 such a question would have a different answer (eg arranging that the commands were not \protected so they simply expanded to characters). What is your actual use case here? Commented Jul 15 at 19:14
  • Sorry, I don't want to hurt the TeX spirit :-) My use case: I want to expand a package that generates data (and arranges them in a graphic) to get a logging of that very data. Unfortunately, the data (more precise: labeling) generation is done by a bunch of commands where a least the top level is non-expandable. Commented Jul 15 at 19:23
  • @Matthias Could you please provide a compilable test code that illustrate your particular issue? Commented Jul 15 at 19:35

1 Answer 1

5

TeX commands don't really return anything. But in Luatex you can typeset into a box then inspect the box contents. Here I assume Unicode fonts so I can simply print characters, and print any white space as a normal space, and ignore everything else.

The command \foo is \protected and could not be defined as expandable.

It produces

xyz a A and B this that 

for the two examples given,

\documentclass{article} \NewDocumentCommand\foo{O{X}}{a #1 and \char\numexpr`#1+1\relax} \NewDocumentCommand\writetolog{m}{% \setbox0\hbox{#1}% \directlua{ texio.write_nl("") for n in node.traverse(tex.box[0].head) do if n.id==12 then texio.write (" ") end if n.id==29 then texio.write(string.char(n.char)) end end texio.write_nl("") }} \begin{document} \writetolog{xyz \foo[A]} \writetolog{ this \textbf{that}} \end{document} 
2
  • Thank you, that was helpful. I wasn't aware that a \setbox already "calculates" its content, but thought, it is only "saved" for later. Commented Jul 15 at 20:12
  • @Matthias no if you want to "save for later" you use a macro so \def\foobar{xyz \foo[A]} or \newcommand or whatever instead of \def. Boxes really typeset their content and save a fragment of tex's almost final form just before it is converted to dvi or pdf by the back end Commented Jul 15 at 20:17

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.