9

I want to define a command, which separates a string an later adds a different \href to the first part, than to the second (e.g. \qname{foaf:Person}). But the code as I have it doesn't work, I get ! Argument of \reserved@a has an extra }., when I try to run it.

\RequirePackage{xstring}
\RequirePackage{hyperref}
\RequirePackage{url}    

\newcommand{\prefix}{}%
\newcommand{\postfix}{}%
\newcommand{\qname}[1]{%
    \IfSubStr{#1}{:}{%
        \renewcommand{\prefix}{\StrBefore{#1}{:}}%
        \renewcommand{\postfix}{\StrBehind{#1}{:}}%
        \nolinkurl{\prefix}:\nolinkurl{\postfix}
    }{%
        \url{#1}%
    }%
}

If I just output \prefix instead of \nolinkurl{\prefix}:\nolinkurl{\postfix} it works, but I want to have it as url.

I think there is something wrong with the variable handling, but I couldn't find information about this.

6

Please always post a complete document not just a fragment.

If you add

\show\prefix

you will see it is not exactly the characters before : it is

> \prefix=\long macro:
->\StrBefore {a:b}{:}.

Which presumably does not expand to something hyperref likes.

This version just uses an expandable macro to split on :

\documentclass{article}

\RequirePackage{xstring}
\RequirePackage{hyperref}
\RequirePackage{url}    

\newcommand{\prefix}{}%
\newcommand{\postfix}{}%
\newcommand{\qname}[1]{%
    \IfSubStr{#1}{:}{%
        \renewcommand{\prefix}{\StrBefore{#1}{:}}%
        \renewcommand{\postfix}{\StrBehind{#1}{:}}%
\show\prefix
        \nolinkurl{\prefix}:\nolinkurl{\postfix}
    }{%
        \url{#1}%
    }%
}

\def\qname#1{\xqname#1:\valign:\\}

\def\xqname#1:#2:#3\\{%
  \nolinkurl{#1}%
\ifx\valign#2%
\else
:\nolinkurl{#2}%
\fi}

\begin{document}

\qname{aaa}

\qname{a:b}

\end{document}
  • Thank you very much for your answer. But I don't really understand, what it is doing. Does the \def part just replace my definition? (BTW: the else-case \url{#1} is not needed) – white_gecko May 16 '13 at 16:47
  • @white_gecko It splits on : by making a delimited argument so #1 is everythig up to teh first : you can not define such arguments with \newcommand. I left in your definition but with \show added, if you comment out my later definition you will see the \show output that I showed above – David Carlisle May 16 '13 at 16:50
  • ok, and what is the \valign and the #3 for? I only use #1 and #2 as I think. I have now simplified the \xqname to \def\xqname#1:#2:#3\\{ \href{http://#1}{\nolinkurl{#1:}} \href{http://#1#2}{\nolinkurl{#2}} } – white_gecko May 16 '13 at 17:02
  • Your simplified version only works if there is a : the \valign is just an arbitrary token unlikely to be in the input so if that is the token after : there was no : originally and the second \nolinkur; is not used – David Carlisle May 16 '13 at 17:06
  • That is fine the argument has to contain a :. I've removed the \valign and #3 now. Am I right, that the `\` is some arbidrary char as end of the command? – white_gecko May 16 '13 at 17:16
3

It's not clear why you want to split at the colon; however, this is a different way to cope with the problem.

\documentclass{article}
\usepackage{xparse,l3regex}
\usepackage{hyperref}

\ExplSyntaxOn
\tl_new:N \l_gecko_prefix_tl
\tl_new:N \l_gecko_postfix_tl
\NewDocumentCommand{\qname}{m}
 {
  \regex_match:nnTF { \: } { #1 }
   {
    \tl_set:Nn \l_gecko_prefix_tl { #1 }
    \tl_set:Nn \l_gecko_postfix_tl { #1 }
    \regex_replace_once:nnN { \A (.*) \: (.*) \Z } { \1 } \l_gecko_prefix_tl
    \regex_replace_once:nnN { \A (.*) \: (.*) \Z } { \2 } \l_gecko_postfix_tl
    \nolinkurl{ \l_gecko_prefix_tl } : \nolinkurl{ \l_gecko_postfix_tl }
   }
   {\url{#1}}
 }\ExplSyntaxOff

\begin{document}
\qname{foo:bar}

\qname{http://tex.stackexchange.com}

\qname{127.0.0.1}
\end{document}
1

Not sure if this addresses your issue. It uses the stringstrings package to parse the string.

\documentclass{article}
\RequirePackage{stringstrings}
\usepackage{ifthen}
\RequirePackage{hyperref}
\RequirePackage{url}    

\newcommand{\prefix}{}%
\newcommand{\postfix}{}%
\newcounter{index}
\newcommand{\qname}[1]{%
  \whereischar[q]{#1}{:}%
  \setcounter{index}{\theresult}%
  \ifthenelse{\value{index} = 0}%
    {\url{#1}}%
    {%
      \addtocounter{index}{-1}%
      \substring[q]{#1}{1}{\value{index}}%
      \edef\prefix{\thestring}%
      \addtocounter{index}{2}%
      \substring[q]{#1}{\value{index}}{$}%
      \edef\postfix{\thestring}%
      \nolinkurl{\prefix}:\nolinkurl{\postfix}
    }%
}

\begin{document}

\qname{aaa}

\qname{a:b}

\qname{http://tex.stackexchange.com}

\end{document}

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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