How does one automatically escape a sequence of text, like “verbatim” but without the formatting?

I want to escape TeX codes on a range of text; this is for a macro providing slightly neater URL formatting. The code I have now is,

\newcommand{\serifurl}[2]{\textsf{\href{#1://#2}{#2}}}


where the first arg is the protocol (http) and second is rest of the link. While the link is generated correctly for the PDF, the tilde characters are not escaped (they turn into whitespace), making the print version incorrect. I want something like \verb without the formatting.

-

While, like Joseph, I would ordinarily choose the more straightforward path that \url provides, I can see that that approach doesn't solve your stated problem. In which case, should you really want to to typeset your URLs the way that you proposed, this code should get you there:

\documentclass{article}

\usepackage{hyperref}
\usepackage{xstring}

\newcommand*\safetilde[1]{%
\begingroup%
\catcode\~11%
\StrSubstitute{#1}{~}{\raise-0.85ex\hbox{\~{}}}%
% -OR- LOW TILDE (faked low tilde - code lifted from url.sty)
%  \makeatletter
%  \StrSubstitute{#1}{~}{{\raise.45ex\hbox{\m@th$\scriptstyle\sim$}}}%
%  \makeatother
\endgroup%
}

\newcommand{\serifurl}[2]{%
\textsf{\href{#1://#2}{\safetilde{#2}}}%
}

\begin{document}
\serifurl{http}{www.middle-man.net/~alice/os~car/bob~}
\end{document}


EXPLANATION:

\safetilde locally sets tildes to normal (letter) category code before converting any tildes in its argument into \~{}'s using \StrSubstitute from the xstring package. Since these characters tend to be set a little high from the baseline, we lower them a small negative \raise amount. Alternatively comment the uncommented \StrSubstitute line and uncommented the following 4 commented lines. This code typesets any tildes using math \sim symbols instead (this code lifted from url.sty).

-

I'd simply use the mechanism from the url package:

\documentclass{article}
\usepackage{hyperref}
\begin{document}
\urlstyle{sf}
\url{http://www.tug/org}
\end{document}

-
I wonder why there isn't a line that says \usepackage{url} or something like that. Is it loaded with hyperref? – Kit Nov 21 '10 at 9:52
@Kit: yes, hyperref loads url via \RequirePackage{url}. – Geoffrey Jones Nov 21 '10 at 10:30
I want the http/https gone. Thanks anyway though. – gatoatigrado Nov 21 '10 at 22:58

Slightly more generally than Joseph's solution, you can use \detokenize to (mostly) achieve the effect you're after in other situations. (As Joseph mentions the url package is better for your specific case because it deals with linebreaks sensibly.)

E.g.,

\newcommand\foo[1]{{\sffamily\detokenize{#1}}}
\foo{\$#^_~}


You still need to watch out for % and extra spaces added after control sequences, so it's not a perfect solution. (At least it's short, though.)

-

Using the url package like Joseph suggested is still the easiest way, even if you want to get rid of the http. The following definition of \myurl provides an optional argument for it using http as default:

\documentclass{article}
\usepackage{hyperref}

\newcommand*\myurl[2][http]{%
\begingroup% just to keep sffamily local
\urlstyle{sf}%
\url{#1://#2}%
\endgroup}

\begin{document}
\myurl{www.tug.org/}

\myurl[https]{some.url.with/~tilde}
\end{document}


-

I used Geoffrey's answer to create my own version, which seems to both maintain the semantics of not including the "http" text, converts tildes correctly, and adds some spaces around "/" characters so they can break lines. You can add two more \! commands if you want the spacing unchanged, but I think it looks nice (for reasonable URLs).

\newcommand*\urltextchars[1]{%
\expandarg% expand the first argument once
\StrSubstitute{\detokenize{#1}}{/}{\! /\! }%
}

\newcommand{\serifurl}[2]{%
\textsf{\href{#1://#2}{\urltextchars{#2}}}%
}
`

The catcode stuff didn't work in XeTeX, so it's noexpandarg now.

-