For reference, I include this answer. I discovered that tcolorbox can do this quite simply in one command. The entire interior of the box is clickable (it doesn't work of course in the screenshot below but it will work in your document) and the URL can be set as an optional parameter to the new command.
% !TEX program = lualatexmk
% !TEX encoding = UTF-8 Unicode
\documentclass{article}
\usepackage[left=1.00in,right=1.00in]{geometry}
\usepackage[most]{tcolorbox} % loads the listings library
\usepackage{hyperref}
\hypersetup{colorlinks=true}
\definecolor{gsbggray} {rgb}{0.90,0.90,0.90} % background gray
\definecolor{gsgray} {rgb}{0.30,0.30,0.30} % gray
\definecolor{gsgreen} {rgb}{0.00,0.60,0.00} % green
\definecolor{gsorange} {rgb}{0.80,0.45,0.12} % orange
\definecolor{gspeach} {rgb}{1.00,0.90,0.71} % peach
\definecolor{gspearl} {rgb}{0.94,0.92,0.84} % pearl
\definecolor{gsplum} {rgb}{0.74,0.46,0.70} % plum
\lstdefinestyle{vpython}{% % style for listings
backgroundcolor=\color{gsbggray},% % background color
basicstyle=\footnotesize,% % default style
breakatwhitespace=true% % break at whitespace
breaklines=true,% % break long lines
captionpos=b,% % position caption
classoffset=1,% % STILL DON'T UNDERSTAND THIS
commentstyle=\color{gsgray},% % font for comments
deletekeywords={print},% % delete keywords from the given language
emph={self,cls,@classmethod,@property},% % words to emphasize
emphstyle=\color{gsorange}\itshape,% % font for emphasis
escapeinside={(@}{@)},% % add LaTeX within your code
frame=tb,% % frame style
framerule=2.0pt,% % frame thickness
framexleftmargin=5pt,% % extra frame left margin
%identifierstyle=\sffamily,% % style for identifiers
keywordstyle=\sffamily\color{gsplum},% % color for keywords
language=Python,% % select language
linewidth=\linewidth,% % width of listings
morekeywords={% % VPython/GlowScript specific keywords
future,abs,acos,align,ambient,angle,append,append_to_caption,%
append_to_title,arange,arrow,asin,astuple,atan,atan2,attach_arrow,%
attach_trail,autoscale,axis,background,billboard,bind,black,blue,border,%
bounding_box,box,bumpaxis,bumpmap,bumpmaps,camera,canvas,caption,capture,%
ceil,center,clear,clear_trail,click,clone,CoffeeScript,coils,color,combin,%
comp,compound,cone,convex,cos,cross,curve,cyan,cylinder,data,degrees,del,%
delete,depth,descender,diff_angle,digits,division,dot,draw_complete,%
ellipsoid,emissive,end_face_color,equals,explog,extrusion,faces,factorial,%
False,floor,follow,font,format,forward,fov,frame,gcurve,gdisplay,gdots,%
get_library,get_selected,ghbars,global,GlowScript,graph,graphs,green,gvbars,%
hat,headlength,headwidth,height,helix,hsv_to_rgb,index,interval,keydown,%
keyup,label,length,lights,line,linecolor,linewidth,logx,logy,lower_left,%
lower_right,mag,mag2,magenta,make_trail,marker_color,markers,material,%
max,min,mouse,mousedown,mousemove,mouseup,newball,norm,normal,objects,%
offset,one,opacity,orange,origin,path,pause,pi,pixel_to_world,pixels,plot,%
points,pos,pow,pps,print,print_function,print_options,proj,purple,pyramid,%
quad,radians,radius,random,rate,ray,read_local_file,readonly,red,redraw,%
retain,rgb_to_hsv,ring,rotate,round,scene,scroll,shaftwidth,shape,shapes,%
shininess,show_end_face,show_start_face,sign,sin,size,size_units,sleep,%
smooth,space,sphere,sqrt,start,start_face_color,stop,tan,text,textpos,%
texture,textures,thickness,title,trail_color,trail_object,trail_radius,%
trail_type,triangle,trigger,True,twist,unbind,up,upper_left,upper_right,%
userpan,userspin,userzoom,vec,vector,vertex,vertical_spacing,visible,%
visual,vpython,VPython,waitfor,white,width,world,xtitle,yellow,yoffset,%
ytitle%
},%
morekeywords={print,None,TypeError},% % additional keywords
morestring=[b]{"""},% % treat triple quotes as strings
numbers=left,% % where to put line numbers
numbersep=10pt,% % how far line numbers are from code
numberstyle=\bfseries\tiny,% % set to 'none' for no line numbers
showstringspaces=false,% % show spaces in strings
showtabs=false,% % show tabs within strings
stringstyle=\color{gsgreen},% % color for strings
upquote=true,% % how to typeset quotes
}%
\NewTCBListing[auto counter,list inside=gsprogs]{tcbglowscriptblock}{ O{} D(){glowscript.org} m }{%
breakable,%
center,%
code = \newpage,%
%derivpeach,%
enhanced,%
hyperurl interior = https://#2,%
label = {gs:\thetcbcounter},%
left = 8mm,%
list entry = \texttt{GlowScript} Program \thetcbcounter: #3,%
listing only,%
listing style = vpython,%
nameref = #3,%
title = \texttt{GlowScript} Program \thetcbcounter: #3,%
width = 0.9\textwidth,%
#1,
}%
\begin{document}
\begin{tcbglowscriptblock}(google.com){A short \texttt{GlowScript} Program}
GlowScript 3.0 vpython
scene.width = 400
scene.height = 760
constants and data
g = 9.8 # m/s^2
mball = 0.03 # kg
Lo = 0.26 # m
ks = 1.8 # N/m
deltat = 0.01 # s
objects (origin is at ceiling)
ceiling = box(pos=vector(0,0,0), length=0.2, height=0.01,
width=0.2)
ball = sphere(pos=vector(0,-0.3,0),radius=0.025,
color=color.orange)
spring = helix(pos=ceiling.pos, axis=ball.pos-ceiling.pos,
color=color.cyan,thickness=0.003,coils=40,
radius=0.010)
initial values
pball = mball * vector(0,0,0) # kg m/s
Fgrav = mball * g * vector(0,-1,0) # N
t = 0
improve the display
scene.autoscale = False # turn off automatic camera zoom
scene.center = vector(0,-Lo,0) # move camera down
scene.waitfor('click') # wait for a mouse click
initial calculation loop
calculation loop
while t < 10:
rate(100)
# we need the stretch
s = mag(ball.pos) - Lo
# we need the spring force
Fspring = ks * s * -norm(spring.axis)
Fnet = Fgrav + Fspring
pball = pball + Fnet * deltat
ball.pos = ball.pos + (pball / mball) * deltat
spring.axis = ball.pos - ceiling.pos
t = t + deltat
\end{tcbglowscriptblock}
The program \ref{gs:1} is nice. It's called \nameref{gs:1} on page \pageref{gs:1}.
\end{document}
