我可以将整个列表设为超链接而不是仅仅是代码吗?

我可以将整个列表设为超链接而不是仅仅是代码吗?

使用中解释的方法https://tex.stackexchange.com/a/213413/218142我可以在用 定义的列表环境中单击代码lstnewenvironment。学生从中剪切并粘贴他们的代码GlowScript.org进入newglowscriptblock环境,提供一个标题和一个 URL,这样当我单击代码时,我就会进入他们的程序并运行它。我可能可以保持原样,但是有没有办法将其封装到适当定义的环境中?换句话说,有没有办法将框的使用包含在环境定义中,或者定义一个新环境,使这一切就像将代码剪切并粘贴到环境中一样简单?(我定义了一种样式,lstdefinestyle但我没有在这里包含它。)我还希望能够单击图形上的任意位置,而不仅仅是实际代码。这也可以实现吗?

这是我的 MWE 及其输出。

\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
\newsavebox\lstA
\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}

输出代码清单

答案1

这可能有用 - 但是 - 没有任何保证!;-)

\documentclass{article}

\usepackage{listings}
\usepackage[colorlinks=true]{hyperref}
%\usepackage[colorlinks=false]{hyperref}

\makeatletter
\newsavebox\newglowscriptblockTempBox
\newcommand\newglowscriptblockURL{}%
\newcommand\newglowscriptblockWrapInPartopsep[1]{%
   \vskip\partopsep#1\vskip\partopsep
}%
\lstnewenvironment{newglowscriptblock}[3]{%
  \gdef\newglowscriptblockURL{#3}%
  \setbox\newglowscriptblockTempBox\hbox{\begingroup\aftergroup}%
  \lstset{caption={#1},label={#2}}%
}{%
  \endgroup
  \hypersetup{hidelinks}%
  \ifvmode\endgraf\expandafter\newglowscriptblockWrapInPartopsep\else\endgraf\expandafter\@firstofone\fi
  {%
    \vskip\topsep
    \noindent
    \expandafter\href\expandafter{\newglowscriptblockURL}{\usebox{\newglowscriptblockTempBox}}%
    \endgraf
    \vskip\topsep
  }%
}%
% Make sure hyperref's \href gets its argument "normalized
\@ifdefinable\newglowscriptblock@@{%
  \let\newglowscriptblock@@=\newglowscriptblock@
  \renewcommand\newglowscriptblock@[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}

2020 年 10 月 21 日补遗

在 2020 年 10 月 20 日的评论中,您问道:

如果我不想提供 URL,有没有办法抑制 hyperref 关于空目标的警告,或者我可以提供一些不会使代码在用鼠标单击时突出显示的东西?

我使用的 pdf 查看器在用鼠标单击时不会突出显示内容。我猜想突出显示不是 pdf 文件的原因,而是 pdf 查看程序中“硬连线”的功能。

如果您不介意改变环境参数的顺序,使得保存 URL 的参数不是第三个而是第一个,那么您可以将该参数设为可选,并使用空默认值。

您需要采取一些技巧来使 URL 参数标准化以适应 hyperref。否则,您无法#在 URL 中使用类似字符。

\newglowscriptblockURL然后,您可以添加分叉来检查从 URL 参数定义的宏的扩展是否产生“空白”,即空或仅显式空格标记,并且\href仅在不是这种情况时才应用。这样,如果未提供现在可选的 URL 参数或提供为空,则不会尝试创建超链接:

\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`\^^M\active^^A
\catcode`\%\active^^A
\@ifdefinable\hyper@@normaliseoptarg{^^A
  \gdef\hyper@@normaliseoptarg#1#2#3]{^^A
    \edef\Hy@tempa{^^A
      \endgroup\noexpand#1[{\Hy@RemovePercentCr#3%^^M\@nil}]^^A
    }^^A
    \Hy@tempa^^A
  }^^A
}^^A
\endgroup
\newcommand\MY@exchange[2]{#2#1}%
\expandafter\newcommand\expandafter*\expandafter\hyper@normaliseoptarg\expandafter{%
  \romannumeral0%
  \expandafter\MY@exchange\expandafter{\hyper@normalise}{%
    \@firstofone{\expandafter} %
    \MY@exchange{\let\hyper@@normalise=\hyper@@normaliseoptarg}%
  }%
}%
\newcommand\lstenv@testhyper@normalizeopt[2]{%
  \@ifnextchar[{\catcode \active 5\relax\hyper@normaliseoptarg{\lstenv@testopt\noexpand#1{#2}}}%
               {\hyper@normaliseoptarg{#1}[{#2}]}%
}%
% end of Infrastructure for "hyperref-normalizing" an optional argument of a \lstnewenvironment.


\newsavebox\newglowscriptblockTempBox
\newcommand\newglowscriptblockURL{}%
\newcommand\newglowscriptblockWrapInPartopsep[1]{%
   \vskip\partopsep#1\vskip\partopsep
}%
\lstnewenvironment{newglowscriptblock}[3][]{%
  \gdef\newglowscriptblockURL{#1}%
  \setbox\newglowscriptblockTempBox\hbox{\begingroup\aftergroup}%
  \lstset{caption={#2},label={#3}}%
}{%
  \endgroup
  \ifx\newglowscriptblockURL\empty\else\hypersetup{hidelinks}\fi
  \ifvmode\endgraf\expandafter\newglowscriptblockWrapInPartopsep\else\endgraf\expandafter\@firstofone\fi
  {%
    \vskip\topsep
    \noindent
    \ifcat $\detokenize\expandafter\expandafter\expandafter{\expandafter\@firstoftwo\newglowscriptblockURL{}.}$%
    \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
    {\@firstofone}%
    {\expandafter\href\expandafter{\newglowscriptblockURL}}%
    {\usebox{\newglowscriptblockTempBox}}%
    \endgraf
    \vskip\topsep
  }%
}%
% Make sure hyperref's \href gets its argument "hyperref-normalized" by replacing
% \lstenv@testopt with \lstenv@testhyper@normalizeopt
% in the definition of \newglowscriptblock@.
\expandafter\renewcommand\expandafter*\expandafter\newglowscriptblock@\expandafter{%
  \romannumeral0%
  \expandafter\MY@exchange\expandafter{%
    \csname\string\newglowscriptblock@\endcsname{}%<-the default for the opt arg is between these braces. The default is empty.
  }{ %
    \ifx\protect\@typeset@protect
      \expandafter\lstenv@testhyper@normalizeopt
    \else
      \@x@protect\newglowscriptblock@ 
    \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}

答案2

为了参考,我附上了这个答案。我发现tcolorbox只需一个命令就可以很简单地完成此操作。框的整个内部都是可点击的(当然,在下面的屏幕截图中它不起作用,但它可以在您的文档中工作),并且可以将 URL 设置为新命令的可选参数。

% !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}

MWE 输出

相关内容