3

Let’s assume I have a file file.txt containing

This is

a test

and I want to replace the contents (from within TeX) with

This is\par a test

I tried to use Lua but stuck with the \n in the replacement text.

Here’s the (not working) code:

% !TeX program = lualatex
\documentclass{article}

\begin{filecontents}{file.txt}
This is

a test
\end{filecontents}

\begin{document}
Test

\directlua{
   local file = io.open("file.txt")
   local fileedited = io.open("editedfile.txt", "w")
   local content = file:read "*a"
   file:close()
   contentedited = string.gsub(content, "\n\n", "\\par")
   fileedited:write(contentedited)
   fileedited:close()
}
\end{document}

I’m not bound to use Lua for this but I can't use any command line tools (shell escape) since the file must run on different computers, where I can’t make sure that the command line tool is available. In the end, the filename should be an argument (#1) given from the TeX code.

3

You have to escape the backslash

\documentclass{article}

\begin{filecontents}{file.txt}
This is

a test
\end{filecontents}

\begin{document}
Test

\directlua{
   local file = io.open("file.txt")
   local fileedited = io.open("editedfile.txt", "w")
   local content = file:read "*a"
   file:close()
   contentedited = string.gsub(content, "\string\n\string\n", "\string\\par ")
   fileedited:write(contentedited)
   fileedited:close()
}
\end{document}
| improve this answer | |
3

the contents of \directlua are expanded, like \write before Lua sees them, so your \\ is latex newline macros, and \n iis an undefined command, you can use

\directlua{\detokenize{
   local file = io.open("file.txt")
   local fileedited = io.open("editedfile.txt", "w")
   local content = file:read "*a"
   file:close()
   contentedited = string.gsub(content, "\n\n", "\\par")
   fileedited:write(contentedited)
   fileedited:close()
}}

to prevent expansion.

| improve this answer | |
  • Thanks but this would also prevent the use of #1, wouldn't it? – Tobi Oct 31 '19 at 11:31
  • @Tobi you don't have to put \detokenize around the whole thing, \detokenize{\n\n", "\\par"} would work, as would \string\n\string\n", "\string\\par" and no \detokenize at all, – David Carlisle Oct 31 '19 at 14:11
  • Thanks for the clarification. I though about that but was to lazy to try it ;-) – Tobi Nov 1 '19 at 15:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.