# \href not ignoring special characters inside macro

I'm having problem using a /href inside my macro. The macro looks like this:

\newboolean{isLast}

\begin{center}
\begin{minipage}[t]{\pictureSize}
\vspace{0pt}\center{\huge #1}
\end{minipage}\hfill
\begin{minipage}[t]{\dimexpr\textBlockSize}
{\large \textbf{#2}\par}
\smallskip
#3
\setboolean{isLast}{#4}
\ifthenelse{\boolean{isLast}}{}{\bigskip\hrule}
\end{minipage}
\end{center}
}


It adds a new structured section to a list with arguments #1 number of items, #2 title, #3 body and #4 is bool that shows or hides \hrule based on if the section is last. This is where I'm getting the error:

\addAcomplishmentsSection{2}
{Title}{
\begin{tabular}{l l r}
Blah & Blah & \href{http://www.url.org/%}{show certificate} \\ % error because of %
Blah & Blah & \href{https://www.url.org/}{show certificate} % no error
\end{tabular}
}{false}


So if the URL has an % sign in it I get this error:

Paragraph ended before \addSection was complete <to be read again>

• Reconsider your definition. \href not only has to handle the % in an url , there is also e.g. # and ~. It would be better to use an environment for the main text part. – Ulrike Fischer Nov 29 '17 at 19:22
• something like split the \addSection to \beginSection, \endSection? – Maroš Beťko Nov 29 '17 at 19:24

You could change the category code of % as I proposed in my comment. The following might do: (note that the comments don't work)

\documentclass[]{article}

\usepackage{ifthen}
\usepackage{hyperref}

\newboolean{isLast}
\newlength\pictureSize
\pictureSize=3cm\relax
\newlength\textBlockSize
\textBlockSize=10cm\relax

\begin{center}
\begin{minipage}[t]{\pictureSize}
\vspace{0pt}\center{\huge #1}
\end{minipage}\hfill
\begin{minipage}[t]{\dimexpr\textBlockSize}
{\large \textbf{#2}\par}
\smallskip
#3
\setboolean{isLast}{#4}
\ifthenelse{\boolean{isLast}}{}{\bigskip\hrule}
\end{minipage}
\end{center}
}

\newcommand{\makepercentother}{\catcode\%=12\relax}
\newcommand{\makepercentcomment}{\catcode\%=14\relax}

\begin{document}
\makepercentother
{Title}{
\begin{tabular}{l l r}
Blah & Blah & \href{http://www.url.org/%}{show certificate} \\ % error because of %
Blah & Blah & \href{https://www.url.org/}{show certificate} % no error
\end{tabular}
}{false}
\makepercentcomment
\end{document}


Note that you have to surround \addSection with this as the category code has to be changed prior to the macro call which's arguments should contain the character which's category code should be changed.

Another possibility is to define the URL in a smaller environment in which % is not the comment char and use that (this way comments would work):

\documentclass[]{article}

\usepackage{ifthen}
\usepackage{hyperref}

\newboolean{isLast}
\newlength\pictureSize
\pictureSize=3cm\relax
\newlength\textBlockSize
\textBlockSize=10cm\relax

\begin{center}
\begin{minipage}[t]{\pictureSize}
\vspace{0pt}\center{\huge #1}
\end{minipage}\hfill
\begin{minipage}[t]{\dimexpr\textBlockSize}
{\large \textbf{#2}\par}
\smallskip
#3
\setboolean{isLast}{#4}
\ifthenelse{\boolean{isLast}}{}{\bigskip\hrule}
\end{minipage}
\end{center}
}

\newcommand{\makepercentother}{\catcode\%=12\relax}
\newcommand{\makepercentcomment}{\catcode\%=14\relax}

\makepercentother
\def\myURL{http://www.url.org/%}
\makepercentcomment

\begin{document}
{Title}{
\begin{tabular}{l l r}
Blah & Blah & \href{\myURL}{show certificate} \\ % error because of %
Blah & Blah & \href{https://www.url.org/}{show certificate} % no error
\end{tabular}
}{false}
\end{document}


One way of the proposed environment based solution (thx Ulrike Fischer for the proposition) is the following. It doesn't need any category code changes.

\documentclass[]{article}

\usepackage{ifthen}
\usepackage{hyperref}

\newboolean{isLast}
\newlength\pictureSize
\pictureSize=3cm\relax
\newlength\textBlockSize
\textBlockSize=10cm\relax

{%
\begin{center}%
\begin{minipage}[t]{\pictureSize}%
\vspace{0pt}\center{\huge #1}%
\end{minipage}\hfill%
\begin{minipage}[t]{\dimexpr\textBlockSize}%
{\large \textbf{#2}\par}%
\setboolean{isLast}{#3}%
\smallskip%
}{%
\ifthenelse{\boolean{isLast}}{}{\bigskip\hrule}%
\end{minipage}%
\end{center}%
}

\begin{document}
\begin{tabular}{l l r}
Blah & Blah & \href{http://www.url.org/%}{show certificate} \\ % error because of %
Blah & Blah & \href{https://www.url.org/}{show certificate} % no error
\end{tabular}
\end{document}

• Thanks, this does it. So there is no way I can change it only inside that third argument, right? – Maroš Beťko Nov 29 '17 at 19:19
• Not in a reasonable amount of effort. You could tweak your command that it reads the third argument multi-line verbatim, parse it and try to undo the effects of the verbatim input (making macros and special characters work again). Not something I'd recommend to do (and I'm not entirely sure this is possible and how to do it). – Skillmon Nov 29 '17 at 19:21

You need to escape % as it is a comment. Use \% instead and you'll be fine.

That has to do something with the characters. While _ etc. are safely passed to \href, % is set as TeX's comment character. As such it is wanted behavior that nothing behind this sign is read.

• I have multiple links with multiple % signs. There are just too many to do it by hand. And also if I use the same link with %signs outside of any macro it works just fine. – Maroš Beťko Nov 29 '17 at 18:52
• @MarošBeťko Some editors do good regex replace, but you could of course change the category codes, although it might break other things (very very badly). Just make % 12 instead of 14. – TeXnician Nov 29 '17 at 18:54
• I don't know what category codes are and what can it break? Before using that solution, could you explain pros and cons? – Maroš Beťko Nov 29 '17 at 18:56
• @MarošBeťko Pros: You can use % in your document without escaping it. Cons: It might break (a) functionality of some packages and (b) you won't be able to comment anymore unless you set up another comment sign with cat code 14 (which can't be used in URLs then). You might even reduce the risk by only patching the href command, but I do not know what consequences this would have. – TeXnician Nov 29 '17 at 19:00
• @MarošBeťko You could do a temporary catcode change of % just in small environments where links occur similar to \makeatletter and \makeatother. – Skillmon Nov 29 '17 at 19:05