I have frequent need to use URLs with # characters in them, and the hashtag causes compilation errors of course. To date, I have used two ways to get around this. One is to manually escape them (change them to \# and the other is to use a URL shortener. The students in my class don't always remember to do either of these and I'd like a way to simply pass the URL to a macro. I discovered I can use the \AtBeginEnvironment hook to fix the problem when I define an environment that uses the URL, but the hook mechanism doesn't work for the macro form of the environment (which may be an artifact of tcolorbox). Why is this?
I have spent hours searching this site for a solution and nothing seems to work. The solutions explained in https://tex.stackexchange.com/a/554190/218142 and https://tex.stackexchange.com/a/554200/218142 looked promising but didn't work for me.
Is there a clean way to pass the URL without having to manually fix it every time or without having to shorten it every time?
% !TEX program = lualatexmk
% !TEX encoding = UTF-8 Unicode
\documentclass{article}
\begin{filecontents}[overwrite,noheader]{demo.py}
Hello, world!
\end{filecontents}
\usepackage[most]{tcolorbox}
\usepackage{hyperref}
\AtBeginEnvironment{codeenv}{\catcode`#=12}
\NewTCBListing[auto counter]{codeenv}
{ O{} D(){glowscript.org} m }{%
breakable,%
center,%
%code = \newpage,%
enhanced,%
hyperurl interior = https://#2,%
label = {gs:\thetcbcounter},%
left = 8mm,%
listing only,%
listing style = tcblatex,%
title = Listing: #3,%
width = 0.9\textwidth,%
{#1},
}%
\NewTCBInputListing[auto counter]{\codefile}
{ O{} D(){glowscript.org} m m }{%
breakable,%
center,%
%code = \newpage,%
enhanced,%
hyperurl interior = https://#2,%
label = {vp:\thetcbcounter},%
left = 8mm,%
listing file = {#3},%
listing only,%
listing style = tcblatex,%
title = Listing: #4,%
width = 0.9\textwidth,%
{#1},%
}%
\begin{document}
This works using the hook.
\begin{codeenv}(www.glowscript.org/#/user/heafnerj/folder/Public/program/nhattest){My Program}
Hello, world!
\end{codeenv}
This works with a shortened URL.
\begin{codeenv}(t.ly/9i20){My Program}
Hello, world!
\end{codeenv}
%This does not work.
%\codefile(www.glowscript.org/#/user/heafnerj/folder/Public/program/nhattest){demo.py}{My Program File}
This works by escaping the #.
\codefile(www.glowscript.org/#/user/heafnerj/folder/Public/program/nhattest){demo.py}{My Program File}
This works with a shortened URL.
\codefile(t.ly/9i20){demo.py}{My Program File}
\end{document}
