1

I'm trying to redefine \verb just for fun. It should act like the LaTeX starred version: \verb<some-char><arbitrary chain of chars not containing it><same char again> should yield these chars typeset in \tt obeying lines and spaces, where spaces are typeset visible.
I managed to make it work by

\def\eol{\hfill\break}
\def\activateas#1#2{%
  \catcode #1 13%
  \lccode`\~ #1%
  \lowercase{\let~#2}%
}
\def\verb#1{%
  \begingroup%
  \def\do##1{\catcode`##1 12}%
  \dospecials%
  \activateas{`#1}\endgroup%
  \activateas{`\^^M}\eol%
\tt}

\dospescials is a plainTeX macro that does \do for <space><VT><SOH>\{}$&#%~_^, where you have to provide \do yourself;
\activateas comes in handy: it gets the character code of something, makes it active and \let equals it to the second argument.

The remaining problem
Heavily tricky, because TeX is just built such that those are ignored always: How do I take care of trailing spaces (e.g. for typesetting markdown)?

  • By the way, what Markdown features require you to use trailing spaces? – siracusa Apr 18 at 12:45
  • 1
    two trailing spaces=linebreak. This is a bad example, a more useful example is the programming language whitespace which would need a definition for ^^I (tab). I just googled that this language existed, it's called an esoteric language. – Abraxas Knister Apr 18 at 14:44
  • I also just learned that markdown syntax is halve disabled in comments. – Abraxas Knister Apr 18 at 14:49
2

Removing trailing spaces happens very early in TeX (while a line from the file is being put into TeX's buffer). So this is before the buffer's characters are interpreted according to their catcodes, and even LuaTeX's process_input_buffer won't help (as the input buffer doesn't contain the trailing spaces). But with LuaTeX and the open_read_file callback, you can achieve what you want, if you put everything in a different file that is \input.

For example, you can put the following in trailing.lua:

function trail_space_env(filename)
   -- A table containing a "reader" function for reading a line.
   local ret = {}
   ret.file = io.open(filename)
   ret.reader =
      function(t)
         local line = t.file:read()
         if line == nil then return line end
         -- If line ends with space, append U+200C (ZWNJ)
         return line:gsub(' $', ' ‌')
      end
   return ret
end
callback.register('open_read_file', trail_space_env)

(note that the replacement string above is a space followed by the ZWNJ character), the following in your main TeX file (taken from your question; only the last two lines are added):

\def\eol{\hfill\break}
\def\activateas#1#2{%
  \catcode #1 13%
  \lccode`\~ #1%
  \lowercase{\let~#2}%
}
\def\verb#1{%
  \begingroup%
  \def\do##1{\catcode`##1 12}%
  \dospecials%
  \activateas{`#1}\endgroup%
  \activateas{`\^^M}\eol%
\tt}

\directlua{dofile('trailing.lua')}
\input everything

and the following in everything.tex:

Regular text.

\verb!
There are two trailing whitespaces here.  
See them?
!

Regular text again.

\bye

Then you get:

result

  • Thanks a lot! I guess this is the right idea. I would prefer putting \char7 (bell) at the end instead of % since this is never needed. And I would refrain from putting this char only on specific lineendings but rather on every line end and leave lines that are nil untouched. – Abraxas Knister Apr 19 at 22:01
  • I sense one flaw to this solution: It changes the input for every file that is input. Is there a solution to make the change in the input routine local while still being able to make use of \verb inline? – Abraxas Knister Apr 19 at 22:04
  • @AbraxasKnister I actually changed % to U+200C in my last edit. Anyway it's possible to make it local: your \verb could set a Lua parameter, which is looked up by the reader function before it does the replacement. – ShreevatsaR Apr 19 at 22:29
2

There's no way to preserve these spaces because they are removed by TeX even before the input is split into tokens and catcodes are assigned. According to TeX by Topic, Section 2.2, this was introduced "for the systems with block storage, and it prevents confusion because these spaces are hard to see in an editor."

A workaround would be to use a different character (not having code 32) there which then is rendered as a visible space in the output.

  • What a shame... I knew this was the only solution, but are there possibilities for other TeX implementations ie LuaTeX ore eTeX to prevent modifying the input? – Abraxas Knister Apr 18 at 14:56
  • I don't know if LuaTeX provides something, but I'm pretty sure e-TeX handles spaces the same way TeX does – siracusa Apr 18 at 19:01

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.