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.

My problem comes from pandoc and markdown, but it is not directly related with these tools, but instead with "customizing" the resulting pdf via some tex macro programming, so I think it is on topic.

I'm writting a document with markdown syntax and converting it to LaTeX (and html) via pandoc. This document contains hyperlinks to some web sites. When I write in markdown:

See [this web](http://tex.stackexchange.com/)

It produces in TeX:

See \href{http://tex.stackexchange.com/}{this web}

I want to implement a version of \href which, in addition to inserting a hyperlink in the pdf, it also makes a footnote containing the url, which is more useful for the printed version of the document. I did it as follows:

\let\oldhref=\href
\renewcommand{\href}[2]{\oldhref{#1}{#2}\footnote{\url{#1}}}

So far so good. It works as expected.

Now the problem is that pandoc also supports "internal references" to other sections in the document. If I have a section called Related work, pandoc automatically generates a internal anchor name related-work, so I can write in my markdown source:

# Related work
Blah blah

# Another section
See [section about related work](#related-work)

The above markdown is translated into:

\hyperdef{}{related-work}{\section{Related work}\label{related-work}}

Blah blah

\section{Another section}

See \href{\#related-work}{section about related work}.

Now my problems is that, with my redefinition of \href this internal reference also produces a footnote, which clearly unncesary. The footnote only shows the text #related-work, which is not useful for the reader, and in addition clicking ot the footnote text produces an error (while other footnotes which show urls work fine).

So, my question: how can I redefine \href in such a way that:

  1. If the first char of its first argument is # (or is it \#?), it behaves as the standard \href (no footnote)
  2. Else, it works as my redefinition (internal hyperlink plus footnote typeseting the destination url).
share|improve this question
add comment

3 Answers

up vote 9 down vote accepted

Here is an idea for a conditional

\iffirsttoken{<tokenlist>}{<token>}{<true>}{<false>}

using the kernel command \@car. You can use it in your redefinition of \href to test whether the first token is \#:

\documentclass{article}

\makeatletter
% this is found in latex.ltx:
% \def\@car#1#2\@nil{#1}
\def\iffirsttoken#1#2{%
  % define \@first@token to be the once expanded \@car of the first argument
  % i.e. the first token or balanced group:
  \expandafter\def\expandafter\@first@token\expandafter{\@car#1\@nil}%
  % test if the expansion of \@first@token is the same as #2:
  \expandafter\ifx\@first@token#2\relax
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
}

\usepackage{hyperref}

\let\oldhref\href
\renewcommand{\href}[2]{%
  \oldhref{#1}{#2}%
  \iffirsttoken{#1}{\#}{}{\footnote{\url{#1}}}%
}

\begin{document}

\hyperdef{}{related-work}{\section{Related work}\label{related-work}}

\iffirsttoken{foo}{f}{true}{false}% true

\iffirsttoken{\#related-work}{\#}{true}{false}% true

\iffirsttoken{this web}{\#}{true}{false}% false

\href{http://tex.stackexchange.com}{this web}

\href{\#related-work}{section about related work}

\end{document}

enter image description here

share|improve this answer
    
Great! Thank you very much –  JLDiaz Feb 27 '13 at 20:07
    
@JLDiaz you're welcome :) –  cgnieder Feb 27 '13 at 20:08
    
@JLDiaz Note that it will fail in cases like \iffirsttoken{{ffoo}bar}{f}{true}{false}% => ooftrue, though. –  cgnieder Feb 27 '13 at 20:28
add comment

If you are looking to strip \# from the first position of a string, it can be done simply with this command

\newcommand\strippound[1]{\expandafter\ifx\expandafter\##1\else#1\fi}

Now stripping a # is a different beast, because it is a special character in TeX


After a day of reflection, I had an idea on how to strip an actual # sign (not a \# sign, mind you) from the first character of a string. This is a significant result, I think, given how difficult is is for TeX to operate on the # character. In the end, the answer was amazingly simple. Here it is:

\documentclass{article}

\catcode `#=11
\edef\lb{#}
\catcode `#=6
\newcommand\strippound[1]{\if\lb#1\else#1\fi}

\begin{document}
\noindent
\strippound{#This string began with a pound sign}\\
\strippound{This string did not begin with a pound sign}
\end{document}

enter image description here

share|improve this answer
    
Interesting! Athough this is not related to my question (I wanted only to execute different code depending on the first char being \#) the idea of changing the catcode and defining a macro with the "dangerous character" can be useful in other problems. –  JLDiaz Mar 1 '13 at 13:38
    
@JLDiaz That was my idea, too. Thanks. –  Steven B. Segletes Mar 1 '13 at 13:43
2  
Btw, this effect can also be ahcieved without catcode changes: \newcommand\strippound[1]{\if###1\else#1\fi} –  Sašo Živanović Mar 1 '13 at 15:18
    
@SašoŽivanović Fascinating. Could you explain what is going on inside LaTeX with the ###1 syntax? –  Steven B. Segletes Mar 1 '13 at 15:39
    
@SašoŽivanović I found the answer to my previous comment at tex.stackexchange.com/questions/42463/…. Thanks for the tip. –  Steven B. Segletes Mar 1 '13 at 23:42
add comment

I wasn't sure whether to edit my prior answer or add this new one. But this seemed unique enough addition to the discussion to warrant a new post. I will delete it if the group thinks it doesn't below here.

In my prior answer, I discovered how to remove a catcode 6 # from the leading position of a string. That watershed opened up a whole bunch of new ways in which catcode 6 # signs can be manipulated from input streams.

In this following bit of code, in addition to getting rid of the leading pound (which I now call \leadingpound, I also generate routines to convert all catcode 6 # signs into \# signs, and a routine to strip all catcode 6 pound signs from the input stream

As JLDiaz noted in the last answer, the technique opens up new ways in which the "dangerous character" can be processed. I hope you agree this is a start.

\documentclass{article}
\usepackage{ifnextok}

\catcode `#=11
\edef\lb{#}
\catcode `#=6
\newcommand\leadingpound[1]{\if\lb#1\else#1\fi}

\makeatletter
\def\@stringend{$}
\def\convertpounds#1{\scan@Block#1\@stringend}
\def\scan@Block{\IfNextToken\@stringend{\@gobble}%
  {\IfNextToken\@sptoken{ \conv@rt{\scan@Block}}%
  {\conv@rt{\scan@Block}}}}

\def\conv@rt#1#2{\if\lb#2\#\else#2\fi#1}

\def\strippounds#1{\process@Block#1\@stringend}
\def\process@Block{\IfNextToken\@stringend{\@gobble}%
  {\IfNextToken\@sptoken{ \bl@t{\process@Block}}%
  {\bl@t{\process@Block}}}}

\def\bl@t#1#2{\if\lb#2\else#2\fi#1}
\makeatother

\begin{document}
\noindent
The following commands work on raw (catcode 6) pound signs
(not backslash-pound symbols).
\vspace{1ex}\\
Started as \convertpounds{#ABC}.  After leadingpound:
  \leadingpound{#ABC}
  $\leftarrow$ No \# may follow lead \#\\
Started as \convertpounds{#A#BC#}.  After convertpounds:
  \convertpounds{#A#BC#}
  $\leftarrow$ These are $\backslash$\#\\
Started as \convertpounds{#A#BC#}.  After strippounds:
  \strippounds{#A#BC#}
\end{document}

enter image description here

share|improve this answer
add comment

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.