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.

I am writing a small package containing macros I intend to use regularly. Among those macros, I have \mailto with the following definition:

\@ifpackageloaded{hyperref}{%
  \def\mailto#1{%
    \href{mailto:#1}{\nolinkurl{#1}}%
  }%
}{%
  \def\maitlo#1{%
    \url{#1}%
  }%
}

What I want to do is redefine @ and . to active characters, so that xxx@yyy.zzz is turned into xxx<at>yyy<dot>zzz. I've tried the following:

\def\mailto#1{%
  \begingroup
    \catcode`@=13
    \catcode`.=13
    \def@{$\langle$at$\rangle$}
    \def.{$\langle$dot$\rangle$}
    \url{#1}
  \endgroup
}

But I get a:

! Undefined control sequence.
\mailto ...e `@=\active \catcode `.=\active \def@ 
                                                  {$\langle $at$\rangle $} \...
l.XXX \mailto{xxx@yyy.zzz}

Why?

share|improve this question
1  
An off-topic but related question: does this alteration actually prevent spam? You give away your email address in hundreds of ways all the time, and it's passed to marketers of questionable morality without the possibility of your doing anything about it. I have 500 messages in my spam folder and my email address isn't written in any form on my website. –  Ryan Reich Jan 28 '12 at 20:01
    
I really don't know. That question arose because I learn by doing. Unfortunately, TeX's documentation isn't very programmer-orientated. I wish there were an MSDN-like documentation system somewhere on the web. –  Minustar Jan 28 '12 at 20:15
1  
On a related note about email obfuscation and security, see What can cause generated PDF document whose text are not correctly copyable? –  Werner Jan 28 '12 at 22:04

1 Answer 1

up vote 11 down vote accepted

There are a few issues with your code. Category codes are fixed when TeX reads an argument, and so reading anything with altered codes is tricky. That applies both to the use of \def. inside \def\mailto and the way you have grabbed the argument of \mailto before you alter category codes. That might lead you to something like

\begingroup
  \catcode`\@=\active
  \catcode`\.=\active
  \gdef\mailto{%
    \begingroup
      \catcode`\@=\active
      \catcode`\.=\active
      \gdef@{$\langle$at$\rangle$}%
      \gdef.{$\langle$dot$\rangle$}%
      \mailtoaux
  }
  \gdef\mailtoaux#1{%
    \endgroup
    #1%
  }
\endgroup

Notice that I've split the group used for \mailto, so that it starts before I grab the argument, and ends after I've grabbed it.

However, this won't work for a URL as the url package does a verbatim read here. In any case, I would avoid active characters (not really needed), and instead to a search-and-replace. I would do this with something like

\newcommand*{\mynil}{\mynil}
\newcommand*{\mailto}[1]{%
  \mailtoauxi#1@\mynil@\stop
}
\def\mailtoauxi#1@#2@#3\stop{%
  \ifx\mynil#2%
    \ERROR
  \else
    \mailtoauxii#1<at>#2.\mynil.\stop
  \fi
}
\makeatletter
\def\mailtoauxii#1.#2.#3\stop{%
  \ifx\mynil#2%
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
    {\url{#1}}%
    {\mailtoauxii#1<dot>#2.#3\stop}%
}
\makeatother

As I said, \url deliberately works to print verbatim, so to get the math mode substitution you want will be a little more work!

share|improve this answer
    
I could box and split the URL into x components depending on the address. –  Minustar Jan 28 '12 at 20:13

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.