11import collections
22import html .parser
33import io
4- from typing import Callable , List , Sequence , Tuple
4+ from typing import Callable , Iterable , List , Sequence , Tuple
55
66from markupsafe import Markup , escape
77
8- LinkTokens = Sequence [ Tuple [int , int , str ] ]
8+ LinkToken = Tuple [int , int , str ]
99
1010
1111class TextWithLinks (collections .UserString ):
@@ -16,10 +16,10 @@ class TextWithLinks(collections.UserString):
1616 The link information is currently for internal use only.
1717 """
1818
19- tokens : LinkTokens
19+ tokens : Sequence [ LinkToken ]
2020 """The list of embedded links."""
2121
22- def __init__ (self , string , tokens : LinkTokens ):
22+ def __init__ (self , string , tokens : Sequence [ LinkToken ] ):
2323 super ().__init__ (string )
2424 self .tokens = tokens
2525
@@ -34,7 +34,7 @@ def parse_crystal_html(crystal_html: str) -> TextWithLinks:
3434
3535
3636def linkify_highlighted_html (
37- pygments_html : str , html_tokens : LinkTokens , make_link : Callable [[str , str ], str ]
37+ pygments_html : str , html_tokens : Sequence [ LinkToken ] , make_link : Callable [[str , str ], str ]
3838) -> str :
3939 pygments_parser = _PygmentsHTMLHandler (html_tokens , make_link )
4040 pygments_parser .feed (pygments_html )
@@ -45,7 +45,7 @@ class _CrystalHTMLHandler(html.parser.HTMLParser):
4545 def __init__ (self ):
4646 super ().__init__ ()
4747 self .text = io .StringIO ()
48- self .tokens : LinkTokens = []
48+ self .tokens : List [ LinkToken ] = []
4949 self ._link_starts : List [Tuple [int , str ]] = []
5050
5151 def handle_starttag (self , tag , attrs ):
@@ -71,18 +71,19 @@ def link_to_path(cls, href):
7171
7272
7373class _PygmentsHTMLHandler (html .parser .HTMLParser ):
74- def __init__ (self , tokens : LinkTokens , make_link : Callable [[str , str ], str ]):
74+ def __init__ (self , tokens : Iterable [ LinkToken ] , make_link : Callable [[str , str ], str ]):
7575 super ().__init__ ()
76- self .tokens = tokens
76+ self .tokens = iter ( tokens )
7777 self .make_link = make_link
7878
79+ self .token = next (self .tokens , None )
7980 self .pos = 0
8081 self .html = io .StringIO ()
8182 self .inlink : Optional [int ] = None
8283
8384 def handle_starttag (self , tag , attrs ):
8485 if tag == "span" and self .inlink is None :
85- if self .tokens and self .tokens [ 0 ] [0 ] <= self .pos :
86+ if self .token and self .token [0 ] <= self .pos :
8687 self .inlink = self .html .tell ()
8788
8889 if self .inlink is None :
@@ -94,10 +95,12 @@ def handle_endtag(self, tag):
9495 self .html .write (f"</{ tag } >" )
9596
9697 if tag == "span" and self .inlink is not None :
97- if self .tokens and self .tokens [ 0 ] [1 ] <= self .pos :
98+ if self .token and self .token [1 ] <= self .pos :
9899 self .html .seek (self .inlink )
99100 subhtml = Markup (self .html .read ())
100- subhtml = self .make_link (self .tokens .pop (0 )[2 ], subhtml )
101+ subhtml = self .make_link (self .token [2 ], subhtml )
102+ self .token = next (self .tokens , None )
103+
101104 self .html .seek (self .inlink )
102105 self .html .truncate ()
103106 self .html .write (subhtml )
0 commit comments