Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

This is a follow-on from my previous question.

In my previous question I learned how to set (say) + as a 'special character' such that I can type +asdf+ in my document and have it expand to \texttt{asdf}:

\documentclass{article}

\catcode`+=\active
\def+#1+{\texttt{#1}}

\begin{document}
+asdf+ % does \texttt{asdf}
\end{document}

I'm now interested in defining a command \DefineShortTexttt{\+} that will set + to be the magic character. This is like \DefineShortVerb in the fancyvrb package or \MakeShortVerb in the shortvrb package.

In essence, I want a \DefineShortTexttt{SYMBOL} that does \defSYMBOL#1SYMBOL{\texttt{#1}}.

I've just learned about the \lccode`~=`#1\lowercase{....} trick, and so I've got something working like so:

\documentclass{article}
\usepackage{xparse}

% make a command \ttt+asdf+ that does \texttt{asdf}, like \verb++ construct.
\NewDocumentCommand\ttt{v}{\texttt{#1}}

% make a command \DefineShortTexttt{<c>} such that <c>sometext<c
% is like typing \ttt<c>sometext<c>
\def\DefineShortTexttt#1{%
    \begingroup%
      \lccode`~=`#1%
      \lowercase{%
      \gdef~{\ttt~}
      }%
    \endgroup%
    \catcode`#1=\active%
}
\begin{document}
\DefineShortTexttt{\|}
 |asdf| % yay, it works!
\end{document}

Now, I just about understand how this works: I let ~ be whatever #1 is and basically define [DELIMITER] to mean \ttt[DELIMITER]. So when tex encounters [DELIMITER]sometext[DELIMITER] it turns the first one into \ttt[DELIMITER], which will then look like \ttt[DELIMITER]sometex[DELIMITER]. Nifty!

But notice how I have to use the \ttt form in the definition of \DefineShortTexttt? Is there any way I can just use \texttt{} instead?

I've tried a variation where I change the \gdef~{\ttt~} to

  \gdef~#1~{\texttt{#1}} % Use of [DELIMITER] doesn't match its definition

I thought this might work because I basically want to write \gdef~#1~{\texttt{#1}}, where ~ contains the current delimiter, but it complains about my usage of the delimiter not matching its definition.

I think I may need to look at \expandafter (???) but can't seem to make it work - could I get any pointers please?

(P.S. - I know this all seems a bit trivial - \ttt+asdf+ is not that hard to write, and making the shorthand version could cause other problems, but this has been very useful in helping me learn some more advanced tex! Also, if I can get \DefineShortTexttt working I'll move onto \UndefineShortTexttt afterwards, but I'd like to have a good crack at that before asking a question about it. I've been mainly guided by the source for the shortvrb package so far).

share|improve this question
    
Perhaps I'm looking for something like a 'placeholder variable' ?? Almost like \def\DefineShortTexttt#1#2{\def#1#2#1{\texttt{#2}} –  mathematical.coffee Mar 28 '12 at 6:26

1 Answer 1

up vote 8 down vote accepted

The following should work.

\def\DefineShortTexttt#1{\begingroup\lccode`~=`#1\lowercase{\endgroup\def~##1~{\texttt{##1}}}\catcode`#1=\active}

It uses the same lowercase trick, note that on inner definitions you need to double the # token. That is, \def\x#1#2{\def\y##1{##1#1}\y#2} is a silly way to reverse two arguments. Internally it creates a macro \y with one argument.

Some additional explanation regarding the use of \lowercase and \endgroup and why they occur where they do.

First off, \endgroup can't go after the usage of ~, since that would make the \def local. But why does it work this way? Why isn't the \lccode of ~ local and no longer active when the \def is found, it's outside of the group this way, right? Well, it's due to the way \lowercase works. What \lowercase does is replace the character code of each explicit character token in it's argument list with the lowercase character code of that character token while leaving the category code of that token the same (this is important for us and in fact, the reason we use this trick). It does this without expanding, that is, \lowercase is unexpandable and is handled in the execution processor. This means that the character code of ~ in \def~##1~... is replaced by it's lowercase character code, which we set equal to the character code of the first argument to \DefineShortTexttt (as an example, say that argument is +). The category code for the ~ character is unchanged though, so it's still active (the ~ is the unbreakable space of course). So in our definition we end up with an active version of + and when the grouping is done it doesn't matter that the lowercase code of ~ has changed because that character token has already been modified at that point and TeX just sees a token with category code 13 (active) and the character code of +, leading to \def+#1#{\texttt{#1}}. Afterwards we set + to be active, because other +'s in the input will not have categroy code 13 otherwise. The grouping is there because otherwise the lowercase code of ~ would be globally changed to te character code of +, which is undesirable.

share|improve this answer
    
Thankyou, the double-hash is exactly the construct I'm after. Where can I read up about this? –  mathematical.coffee Mar 28 '12 at 8:03
1  
I'd recommend TeX By Topic or The TeXbook (That's merely the source, you can probably find it online somewhere or consider purchasing it, it's a nice book to have). Both treat the ## construct. –  Roelof Spijker Mar 28 '12 at 8:08
    
The \lccode assignment remains valid, with this definition, which is usually not desired: add \begingroup before \lccode and \endgroup before \gdef, turning this one into \def –  egreg Mar 28 '12 at 9:05
    
Excellent point, hadn't thought about that at all. Changed the code to incorporate this. –  Roelof Spijker Mar 28 '12 at 9:20
    
Actually I had a peripheral question for the \begingroup and \endgroup - why is the \endgroup always put after the \lowercase{ ? It seems a little unbalanced. I thought it would make more sense after the \def...{...} to sort of "enclose" the region in which you want ~ to mean #1. –  mathematical.coffee Mar 28 '12 at 9:41

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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