@@ -210,7 +210,7 @@ def get_optimal_width(self, container_width: int) -> int:
210210 lines = self .without_spans .split ("\n " )
211211 return max (line .cell_length for line in lines )
212212
213- def wrap (
213+ def _wrap_and_format (
214214 self ,
215215 width : int ,
216216 align : TextAlign = "left" ,
@@ -219,8 +219,22 @@ def wrap(
219219 tab_size : int = 8 ,
220220 selection : Selection | None = None ,
221221 selection_style : Style | None = None ,
222- ) -> list [ContentLine ]:
223- output_lines : list [ContentLine ] = []
222+ ) -> list [FormattedLine ]:
223+ """Wraps the text and applies formatting.
224+
225+ Args:
226+ width: Desired width.
227+ align: Text alignment.
228+ overflow: Overflow method.
229+ no_wrap: Disabled wrapping.
230+ tab_size: Cell with of tabs.
231+ selection: Selection information or `None` if no selection.
232+ selection_style: Selection style, or `None` if no selection.
233+
234+ Returns:
235+ List of formatted lines.
236+ """
237+ output_lines : list [FormattedLine ] = []
224238
225239 if selection is not None :
226240 get_span = selection .get_span
@@ -236,7 +250,7 @@ def get_span(y: int) -> tuple[int, int] | None:
236250 end = len (line .plain )
237251 line = line .stylize (selection_style , start , end )
238252
239- content_line = ContentLine (
253+ content_line = FormattedLine (
240254 line .expand_tabs (tab_size ), width , y = y , align = align
241255 )
242256
@@ -246,7 +260,7 @@ def get_span(y: int) -> tuple[int, int] | None:
246260 offsets = divide_line (line .plain , width , fold = overflow == "fold" )
247261 divided_lines = content_line .content .divide (offsets )
248262 new_lines = [
249- ContentLine (
263+ FormattedLine (
250264 content .rstrip_end (width ), width , offset , y , align = align
251265 )
252266 for content , offset in zip (divided_lines , [0 , * offsets ])
@@ -277,7 +291,7 @@ def render_strips(
277291 selection_style = None
278292
279293 align = self ._align
280- lines = self .wrap (
294+ lines = self ._wrap_and_format (
281295 width ,
282296 align = align ,
283297 overflow = (
@@ -292,11 +306,11 @@ def render_strips(
292306 if height is not None :
293307 lines = lines [:height ]
294308
295- strip_lines = [line .to_strip (style ) for line in lines ]
309+ strip_lines = [line .to_strip (widget , style ) for line in lines ]
296310 return strip_lines
297311
298312 def get_height (self , width : int ) -> int :
299- lines = self .wrap (width )
313+ lines = self ._wrap_and_format (width )
300314 return len (lines )
301315
302316 def __len__ (self ) -> int :
@@ -982,7 +996,9 @@ def highlight_regex(
982996 return Content (self ._text , spans )
983997
984998
985- class ContentLine :
999+ class FormattedLine :
1000+ """A line of content with additional formatting information."""
1001+
9861002 def __init__ (
9871003 self ,
9881004 content : Content ,
@@ -991,13 +1007,15 @@ def __init__(
9911007 y : int = 0 ,
9921008 align : TextAlign = "left" ,
9931009 line_end : bool = False ,
1010+ link_style : Style | None = None ,
9941011 ) -> None :
9951012 self .content = content
9961013 self .width = width
9971014 self .x = x
9981015 self .y = y
9991016 self .align = align
10001017 self .line_end = line_end
1018+ self .link_style = link_style
10011019 self .highlight_style : Style | None = None
10021020 self .highlight_range : tuple [int | None , int | None ] | None = None
10031021
@@ -1009,7 +1027,7 @@ def highlight(self, style: Style, start: int | None, end: int | None) -> None:
10091027 self .highlight_style = style
10101028 self .highlight_range = (start , end )
10111029
1012- def to_strip (self , style : Style ) -> Strip :
1030+ def to_strip (self , widget : Widget , style : Style ) -> Strip :
10131031 _Segment = Segment
10141032 align = self .align
10151033 width = self .width
@@ -1024,8 +1042,6 @@ def to_strip(self, style: Style) -> Strip:
10241042
10251043 if align in ("start" , "left" ) or (align == "justify" and self .line_end ):
10261044 pass
1027- # pad_right = width - self.content.cell_length
1028- # pad_right = 0
10291045
10301046 elif align == "center" :
10311047 excess_space = width - self .content .cell_length
@@ -1061,7 +1077,7 @@ def to_strip(self, style: Style) -> Strip:
10611077 if index < len (spaces ) and (pad := spaces [index ]):
10621078 add_segment (_Segment (" " * pad , (style + text_style ).rich_style ))
10631079
1064- strip = Strip (segments , width )
1080+ strip = Strip (self . _apply_link_style ( widget , segments ) , width )
10651081 return strip
10661082
10671083 segments = (
@@ -1080,9 +1096,32 @@ def to_strip(self, style: Style) -> Strip:
10801096 segments .append (
10811097 _Segment (" " * pad_right , style .background_style .rich_style )
10821098 )
1083- strip = Strip (segments , content .cell_length + pad_left + pad_right )
1099+ strip = Strip (
1100+ self ._apply_link_style (widget , segments ),
1101+ content .cell_length + pad_left + pad_right ,
1102+ )
10841103 return strip
10851104
1105+ def _apply_link_style (
1106+ self , widget : Widget , segments : list [Segment ]
1107+ ) -> list [Segment ]:
1108+ link_style = widget .link_style
1109+ _Segment = Segment
1110+ segments = [
1111+ _Segment (
1112+ text ,
1113+ (
1114+ style
1115+ if style ._meta is None
1116+ else (style + link_style if "@click" in style .meta else style )
1117+ ),
1118+ control ,
1119+ )
1120+ for text , style , control in segments
1121+ if style is not None
1122+ ]
1123+ return segments
1124+
10861125
10871126if __name__ == "__main__" :
10881127 from rich import print
@@ -1116,7 +1155,7 @@ def to_strip(self, style: Style) -> Strip:
11161155 "will" , Style (background = Color .parse ("rgba(255, 255, 20, 0.3)" ))
11171156 )
11181157
1119- lines = content .wrap (40 , align = "full" )
1158+ lines = content ._wrap_and_format (40 , align = "full" )
11201159 print (lines )
11211160 print ("x" * 40 )
11221161 for line in lines :
0 commit comments