TeX - LaTeX Asked on February 27, 2021
Using the method explained in https://tex.stackexchange.com/a/213413/218142 I can click on the code in a listings environment defined with lstnewenvironment
. Students cut and paste their code from GlowScript.org into the newglowscriptblock
environment, provide a caption and a URL so that when I click on the code I’m taken to their program so I can run it. I could probably leave things as they are, but is there a way to encapsulate this into a suitably defined environment? In other words, is there a way to include the use of the box within the environment definition or to define a new environment that make this all just work as simply as cutting and pasting the code into the environment? (I have a style defined with lstdefinestyle
but I didn’t include it here.) I would also like to be able to click anywhere on the figure and not just on the actual code. Can that be accommodated too?
Here’s my MWE and its output.
documentclass{article}
usepackage{listings}
lstnewenvironment{newglowscriptblock}[3]{%
lstset{caption={#1},label={#2}}}{}
usepackage{hyperref}
hypersetup{pdfborder=0 0 0}
begin{document}
% See https://tex.stackexchange.com/a/213413/218142
newsaveboxlstA
begin{lrbox}{lstA}
begin{newglowscriptblock}{Problem 37 Code}{pref2}{}
GlowScript 3.0 VPython
# a Young's modulus problem
Lo = 3 # wire's original length in m
d = 3e-3 # wire's diameter in m
g = 9.8 # surface grav. field strength in N/kg
m = 10 # ball's mass in kg
Y = 2e11 # steel's Young's modulus in N/m^2
# Find DeltaL, the amount the wire stretches.
area = (pi*d**2)/4
Force = m*g
DeltaL = (Force*Lo)/(area*Y)
print ("The wire stretches by ",DeltaL," m")
end{newglowscriptblock}
end{lrbox}
% The URL here is would the #3 in the definition of newglowscriptenvironment
href{https://google.com}{usebox{lstA}}
end{document}
This might do the trick - but - no warranties! ;-)
documentclass{article}
usepackage{listings}
usepackage[colorlinks=true]{hyperref}
%usepackage[colorlinks=false]{hyperref}
makeatletter
newsaveboxnewglowscriptblockTempBox
newcommandnewglowscriptblockURL{}%
newcommandnewglowscriptblockWrapInPartopsep[1]{%
vskippartopsep#1vskippartopsep
}%
lstnewenvironment{newglowscriptblock}[3]{%
gdefnewglowscriptblockURL{#3}%
setboxnewglowscriptblockTempBoxhbox{begingroupaftergroup}%
lstset{caption={#1},label={#2}}%
}{%
endgroup
hypersetup{hidelinks}%
ifvmodeendgrafexpandafternewglowscriptblockWrapInPartopsepelseendgrafexpandafter@firstofonefi
{%
vskiptopsep
noindent
expandafterhrefexpandafter{newglowscriptblockURL}{usebox{newglowscriptblockTempBox}}%
endgraf
vskiptopsep
}%
}%
% Make sure hyperref's href gets its argument "normalized
@ifdefinablenewglowscriptblock@@{%
letnewglowscriptblock@@=newglowscriptblock@
renewcommandnewglowscriptblock@[2]{hyper@normalise{newglowscriptblock@@unexpanded{{#1}{#2}}}}%
}%
makeatother
begin{document}
lstlistoflistings
newpage
Some text. Some text.
Some text. Some text.
begin{newglowscriptblock}{Problem 37 Code}{pref2}{https://google.com}
GlowScript 3.0 VPython
# a Young's modulus problem
Lo = 3 # wire's original length in m
d = 3e-3 # wire's diameter in m
g = 9.8 # surface grav. field strength in N/kg
m = 10 # ball's mass in kg
Y = 2e11 # steel's Young's modulus in N/m^2
# Find DeltaL, the amount the wire stretches.
area = (pi*d**2)/4
Force = m*g
DeltaL = (Force*Lo)/(area*Y)
print ("The wire stretches by ",DeltaL," m")
end{newglowscriptblock}
Some text. Some text.
Some text. Some text.
newpage
nameref-link to listing: nameref{pref2}
ref-link to listing: ref{pref2}
pageref-link to listing: pageref{pref2}
autoref-link to listing: autoref{pref2}
end{document}
Addendum in October 21, 2020
In a comment from October 20, 2020 you asked:
If I don't want to supply a URL, is there a way to suppress hyperref's warning about an empty target OR can I supply something that won't make the code highlight if I click it with the mouse?
The pdf-viewer used by me doesn't highlight things when clicking with the mouse. I assume the highlighting is not due to the pdf-file but is a feature "hardwired" in your pdf-viewing program.
If you don't mind changing the order of the arguments of the environment so that the argument holding the URL will not be the third one but will be the first one, you can make that argument optional, with an empty default.
You need to do some trickery to have the URL-argument normalized for hyperref.
Otherwise you cannot have characters like #
within the URL.
Then you can add forking to check whether the expansion of the macro newglowscriptblockURL
defined from the URL-argument yields "blankness", i.e., emptiness or explicit space tokens only, and apply href
only if this is not the case. This way if the now optional URL-argument is not provided or is provided empty, attempts at creating a hyperlink will not take place:
documentclass{article}
usepackage{listings}
usepackage[colorlinks=true]{hyperref}
%usepackage[colorlinks=false]{hyperref}
makeatletter
% Infrastructure for "hyperref-normalizing" an optional argument of a lstnewenvironment:
begingroup
catcode`^^A=14 %
catcode`^^Mactive^^A
catcode`%active^^A
@ifdefinablehyper@@normaliseoptarg{^^A
gdefhyper@@normaliseoptarg#1#2#3]{^^A
edefHy@tempa{^^A
endgroupnoexpand#1[{Hy@RemovePercentCr#3%^^M@nil}]^^A
}^^A
Hy@tempa^^A
}^^A
}^^A
endgroup
newcommandMY@exchange[2]{#2#1}%
expandafternewcommandexpandafter*expandafterhyper@normaliseoptargexpandafter{%
romannumeral0%
expandafterMY@exchangeexpandafter{hyper@normalise}{%
@firstofone{expandafter} %
MY@exchange{lethyper@@normalise=hyper@@normaliseoptarg}%
}%
}%
newcommandlstenv@testhyper@normalizeopt[2]{%
@ifnextchar[{catcode active 5relaxhyper@normaliseoptarg{lstenv@testoptnoexpand#1{#2}}}%
{hyper@normaliseoptarg{#1}[{#2}]}%
}%
% end of Infrastructure for "hyperref-normalizing" an optional argument of a lstnewenvironment.
newsaveboxnewglowscriptblockTempBox
newcommandnewglowscriptblockURL{}%
newcommandnewglowscriptblockWrapInPartopsep[1]{%
vskippartopsep#1vskippartopsep
}%
lstnewenvironment{newglowscriptblock}[3][]{%
gdefnewglowscriptblockURL{#1}%
setboxnewglowscriptblockTempBoxhbox{begingroupaftergroup}%
lstset{caption={#2},label={#3}}%
}{%
endgroup
ifxnewglowscriptblockURLemptyelsehypersetup{hidelinks}fi
ifvmodeendgrafexpandafternewglowscriptblockWrapInPartopsepelseendgrafexpandafter@firstofonefi
{%
vskiptopsep
noindent
ifcat $detokenizeexpandafterexpandafterexpandafter{expandafter@firstoftwonewglowscriptblockURL{}.}$%
expandafter@firstoftwoelseexpandafter@secondoftwofi
{@firstofone}%
{expandafterhrefexpandafter{newglowscriptblockURL}}%
{usebox{newglowscriptblockTempBox}}%
endgraf
vskiptopsep
}%
}%
% Make sure hyperref's href gets its argument "hyperref-normalized" by replacing
% lstenv@testopt with lstenv@testhyper@normalizeopt
% in the definition of newglowscriptblock@.
expandafterrenewcommandexpandafter*expandafternewglowscriptblock@expandafter{%
romannumeral0%
expandafterMY@exchangeexpandafter{%
csnamestringnewglowscriptblock@endcsname{}%<-the default for the opt arg is between these braces. The default is empty.
}{ %
ifxprotect@typeset@protect
expandafterlstenv@testhyper@normalizeopt
else
@x@protectnewglowscriptblock@
fi
}%
}%
makeatother
begin{document}
lstlistoflistings
newpage
Some text. Some text.
Some text. Some text.
The optional argument is not empty, thus the environment is a hyperlink. %
begin{newglowscriptblock}[https://google.com#Weird]{Problem 37 Code}{pref2}
GlowScript 3.0 VPython
# a Young's modulus problem
Lo = 3 # wire's original length in m
d = 3e-3 # wire's diameter in m
g = 9.8 # surface grav. field strength in N/kg
m = 10 # ball's mass in kg
Y = 2e11 # steel's Young's modulus in N/m^2
# Find DeltaL, the amount the wire stretches.
area = (pi*d**2)/4
Force = m*g
DeltaL = (Force*Lo)/(area*Y)
print ("The wire stretches by ",DeltaL," m")
end{newglowscriptblock}
The optional argument is not empty, thus the environment is a hyperlink.
Some text. Some text.
Some text. Some text.
newpage
Some text. Some text.
Some text. Some text.
The optional argument is empty, thus the environment is not a hyperlink.
begin{newglowscriptblock}{Problem 37 Code}{pref3}
GlowScript 3.0 VPython
# a Young's modulus problem
Lo = 3 # wire's original length in m
d = 3e-3 # wire's diameter in m
g = 9.8 # surface grav. field strength in N/kg
m = 10 # ball's mass in kg
Y = 2e11 # steel's Young's modulus in N/m^2
# Find DeltaL, the amount the wire stretches.
area = (pi*d**2)/4
Force = m*g
DeltaL = (Force*Lo)/(area*Y)
print ("The wire stretches by ",DeltaL," m")
end{newglowscriptblock}
The optional argument is empty, thus the environment is not a hyperlink.
Some text. Some text.
Some text. Some text.
newpage
nameref-link to listing pref2: nameref{pref2}
ref-link to listing pref2: ref{pref2}
pageref-link to listing pref2: pageref{pref2}
autoref-link to listing pref2: autoref{pref2}
nameref-link to listing pref3: nameref{pref3}
ref-link to listing pref3: ref{pref3}
pageref-link to listing pref3: pageref{pref3}
autoref-link to listing pref3: autoref{pref3}
end{document}
Correct answer by Ulrich Diez on February 27, 2021
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=sffamilycolor{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=bfseriestiny,% % 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.9textwidth,%
#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}
Answered by LaTeXereXeTaL on February 27, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP