TransWikia.com

How to allow # in newcommand without # or another way to defer processing of section of code

TeX - LaTeX Asked by ctrl-alt-delor on December 5, 2020

I am trying to defer processing of some latex code.

This works,

documentclass[a4paper,final,11pt]{article}
usepackage{hyperref}
begin{document}
here comes a reference
href{http://www.example.com/doc#list}{doc}
end{document}

but I need to move up the importing of codeToBeDeferred (containing the href), and render/process it in the same place. So I changed it to this.

documentclass[a4paper,final,11pt]{article}
usepackage{hyperref}
newcommand{deferredCode}{
    href{http://www.example.com/doc#list}{doc}
}
begin{document}
here comes a reference
deferredCode
end{document}

This works, except for the # in the href, note the # was not a problem in the original code.

side note: I am reading the code early and deferring processing because the code is merged together by a preprocessor, the preprocessor needs to process the deferred code early, but latex needs to do it latter.

Well all this works, except when the codeToBeDeferred has a # in it. newcommand does not like it. If I put a before the # it fixes it, however I do not want to do this: there are a lot of historic versions of this code, I don’t want to have to remember when I write new code. The code is valid latex when not part of a newcommand

How can I allow a # in a newcommand?
or
How else can I defer the processing of this block of code?


The # is in a href in the deferred code, it works outside of a newcommand.

What I am hoping for, is a wrapper to stop the # being a problem. If the # is only a problem when in a newcommand then this may be possible.

%somePreambleCode
newcommand{deferredCode}{
    wrapper{
        href{http://www.example.com/doc#list}{doc}
    }
}
%someOtherCode
deferredCode

I know that I can escape the # with a (changing it to #), but am hoping for another way.

I don’t want to edit the code to be deferred. There is a choice of hundreds of them, I don’t want them to be constrained by me doing this deferral trick to fix another problem.

4 Answers

You can define deferredCode in terms of edef while applying string to problematic characters:

documentclass[a4paper,final,11pt]{article}
usepackage{hyperref}

csname @ifdefinableendcsnamedeferredCode{%
  edefdeferredCode{noexpandhref{http://www.example.com/docstring#list}{doc}}%
}%

begin{document}
here comes a reference
deferredCode
end{document}

You can define a command which reads one argument in verbatim-catcode-régime and defines another command to apply scantokens to that argument:

documentclass[a4paper,final,11pt]{article}
usepackage{hyperref}
usepackage{xparse}

begingroup
catcode`^^A=14relax
catcode`%=12relax
csname @firstofoneendcsname{^^A
  endgroup^^A
  NewDocumentCommandDefineScantokenscommandFromVerbArg{m+v}{^^A
    newcommand#1{scantokens{#2%}}^^A
  }^^A
}%

DefineScantokenscommandFromVerbArgdeferredCode|href{http://www.example.com/doc#list}{doc}|

begin{document}
here comes a reference
deferredCode
end{document}

Answered by Ulrich Diez on December 5, 2020

This is not as good as the other solutions, but why not use this code:

href{http://www.example.com/doc{char`#}list}{doc}

Make sure to put this as the definition for deferredcode to make it work.

Answered by Someone on December 5, 2020

Once TeX has tokenized input, which occurs for example when you save the input in a macro, then it's not generally straight-forward to alter the nature of the tokens. In particular, this restricts our ability to use verbatim or verbatim-like input in the arguments and definitions of macros. The href command needs to use a verbatim-like approach to allow for example # inside hyperlinks, so that causes the problem.

In the question, you've noted that using # is not a usable solution. This the most obvious approach is to alter the category code of # for the duration of the block you want to defer:

documentclass[a4paper,final,11pt]{article}
usepackage{hyperref}
catcode`#=12 %
newcommand*deferredCode{%
    href{http://www.example.com/doc#list}{doc}%
}
catcode`#=6 %
begin{document}
here comes a reference
deferredCode
end{document}

(Category code 12 is 'other' and so is harmless). Of course this prevents the deferred block containing any macro definitions requiring parameters, or at least that you pick some other character for that purpose.

Answered by Joseph Wright on December 5, 2020

When using the reference to external labels, the # character is used, according to the hypertext specification, but this means, that has to be escaped with# within another command such as newcommand.

documentclass[12pt]{scrbook}

usepackage{hyperref}


newcommand{deferredcode}{%
  href{anotherfile.pdf#mylabel}{Some Text}
}%

begin{document}

In chapter deferredcode we saw that
end{document}

Where anotherfile.tex contains

documentclass[12pt]{scrbook}

usepackage{hyperref}

begin{document}
chapter{first}label{mylabel}%
end{document}

I omitted a screenshot, since it does not reveal much.

Answered by user31729 on December 5, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP