API Reference#
Attention
đźš§ There might be incompatible changes between minor versions of version zero!
If you want to use this library in a project while it’s still on version zero,
ensure you pin the dependency to a specific minor version e.g >=0.1,<0.2.
urWIDgets
A collection of widgets for urwid (https://urwid.org)
Functions:
Parses a string into a text/widget markup list. |
Classes:
A widget containing hyperlinked text. |
|
A text widget within which other widgets may be embedded. |
- urwidgets.parse_text(text, patterns, repl, *repl_args, **repl_kwargs)[source]#
Parses a string into a text/widget markup list.
- Parameters:
text (str) – The string to parse.
patterns (Iterable[re.Pattern]) – An iterable of RegEx pattern objects.
repl (Callable[[re.Pattern, Tuple[str | None], Tuple[int, int], ...], Markup]) – A callable to replace a substring of text matched by any of the given RegEx patterns.
repl_args (Any) – Additional positional arguments to be passed to repl whenever it’s called.
repl_kwargs (Any) – keyword arguments to be passed to repl whenever it’s called.
- Returns:
A text/widget markup (see
Markup) that should be compatible withTextEmbedand/orurwid.Text, depending on the values returned by repl.- Raises:
TypeError – An argument is of an unexpected type.
ValueError – patterns is empty.
ValueError – A given pattern object was not compiled from a
strinstance.
- Return type:
Markup
Whenever any of the given RegEx patterns matches a non-empty substring of text, repl is called with the following arguments (in the given order):
the
re.Patternobject that matched the substringa tuple containing the match groups
starting with the whole match,
followed by the all the subgroups of the match, from 1 up to however many groups are in the pattern, if any (
Nonefor each group that didn’t participate in the match)
a tuple containing the indexes of the start and end of the substring
repl_args unpacked
repl_kwargs unpacked
and should return a valid text/widget markup (see
Markup). If the value returned is false (such asNoneor an empty string), it is omitted from the result.Example:
import re from urwid import Filler from urwidgets import Hyperlink, TextEmbed, parse_text MARKDOWN = { re.compile(r"\*\*(.+?)\*\*"): lambda g: ("bold", g[1]), re.compile("https://[^ ]+"): ( lambda g: (min(len(g[0]), 14), Filler(Hyperlink(g[0], "blue"))) ), re.compile(r"\[(.+)\]\((.+)\)"): ( lambda g: (len(g[1]), Filler(Hyperlink(g[2], "blue", g[1]))) ), } link = "https://urwid.org" text = f"[This]({link}) is a **link** to {link}" print(text) # Output: [This](https://urwid.org) is a **link** to https://urwid.org markup = parse_text( text, MARKDOWN, lambda pattern, groups, span: MARKDOWN[pattern](groups) ) print(markup) # Output: # [ # (4, <Filler box widget <Hyperlink flow widget>>), # ' is a ', # ('bold', 'link'), # ' to ', # (14, <Filler box widget <Hyperlink flow widget>>), # ] text_widget = TextEmbed(markup) canv = text_widget.render(text_widget.pack()[:1]) print(canv.text[0].decode()) # Output: This is a link to https://urwid… # The hyperlinks will be clickable if supported
Note
In the case of overlapping matches, the substring that occurs first is matched and if they start at the same index, the pattern that appears first in patterns takes precedence.
- class urwidgets.Hyperlink(uri, attr=None, text=None)[source]#
Bases:
urwid.widget.WidgetWrapA widget containing hyperlinked text.
- Parameters:
uri (str) –
The target of the hyperlink in URI (Uniform Resource Identifier)-encoded form.
May be a web address (
http://...orhttps://...), FTP address (ftp://...), local file (file://...), e-mail address (mailto:), etc.Every byte of this string, after being encoded, must be within the range
32to126(both inclusive).attr (DisplayAttribute) – Display attribute of the hyperlink text.
text (Optional[str]) – Alternative hyperlink text. If not given or
None, the URI itself is used. Must be a single-line string.
- Raises:
TypeError – An argument is of an unexpected type.
ValueError – An argument is of an expected type but of an unexpected value
This widget always renders a single line. If the widget is rendered with a width less than the length of the hyperlink text, it is clipped at the right end with an ellipsis (…) appended. On the other hand, if rendered with a width greater, it is padded with spaces on the right end.
This widget is intended to be embedded in a
TextEmbedwidget to combine it with pure text or other widgets but may also be used otherwise.This widget utilizes the
OSC 8escape sequence implemented by a sizable number of mainstream terminal emulators. It utilizes the escape sequence in such a way that hyperlinks right next to one another should be detected, highlighted and treated as separate by any terminal emulator that correctly implements the feature. Also, if a hyperlink is wrapped or clipped, it shouldn’t break.Attributes:
The display attirbute of the hyperlink.
The alternate text of the hyperlink.
The target of the hyperlink.
- property attrib#
The display attirbute of the hyperlink.
- Type:
DisplayAttribute
- GET:
Returns the display attirbute.
- SET:
Sets the display attirbute.
- property text#
The alternate text of the hyperlink.
- Type:
- GET:
Returns the alternate text.
- SET:
Sets the alternate text.
- class urwidgets.TextEmbed(markup, align='left', wrap='space', layout=None)[source]#
Bases:
urwid.widget.TextA text widget within which other widgets may be embedded.
This is an extension of the
urwid.Textwidget. Every feature and interface ofTextis supported and works essentially the same, except for the “ellipsis” wrap mode which is currently not implemented. Text markup format is essentially the same, except when embedding widgets.- Embedding Widgets
A widget is embedded by specifying it as a markup element with an integer display attribute, where the display attribute is the number of screen columns the widget should occupy.
Examples:
>>> # w1 spans 2 columns >>> TextEmbed(["This widget (", (2, w1), ") spans two columns"]) >>> # w1 and w2 span 2 columns >>> TextEmbed(["These widgets (", (2, [w1, w2]), ") span two columns each"]) >>> # w1 and w2 span 2 columns, the text in-between has no display attribute >>> TextEmbed([(2, [w1, (None, "and"), w2]), " span two columns each"]) >>> # w1 and w2 span 2 columns, text in the middle is red >>> TextEmbed((2, [w1, ("red", " i am red "), w2])) >>> # w1 and w3 span 2 columns, w2 spans 5 columns >>> TextEmbed((2, [w1, (5, w2), w3]))
Visible embedded widgets are always rendered (may be cached) whenever the
TextEmbedwidget is re-rendered (i.e an uncached render). Hence, this allows for dynamic parts of text without updating the entire widget. Going a step further, embeddded widgets can be swapped by usingurwid.WidgetPlaceholderbut their widths will remain the same.- NOTE:
Every embedded widget must be a box widget and is always rendered with size
(width, 1).urwid.Fillercan be used to wrap flow widgets.Each embedded widgets are treated as a single WORD (i.e containing no whitespace). Therefore, consecutive embedded widgets are also treated as a single WORD. This affects the “space” wrap mode.
After updating or swapping an embedded widget, this widget’s canvases should be invalidated to ensure it re-renders.
- Raises:
TypeError – A widget markup element has a non-integer display attribute.
ValueError – A widget doesn’t support box sizing.
ValueError – A widget has a non-positive width (display attribute).
Attributes:
Run-length encoding of display attributes of the widget's content.
Embedded widgets.
Raw text content of the widget.
Methods:
- property attrib#
Run-length encoding of display attributes of the widget’s content.
See the description of the second item in the return value of
get_text().
- property embedded#
Embedded widgets.
- Returns:
A list of all embedded widgets and their respective widths, in the same order in which they were given in the text markup.
- Type:
List[Tuple[urwid.Widget, int]]
- property text#
Raw text content of the widget.
- Type:
See the description of the first item in the return value of
get_text().
- get_text()[source]#
Returns a representation of the widget’s content.
- Returns:
A tuple
(text, attrib), wheretext is the raw text content of the widget.
Each embedded widget is represented by a substring starting with a
"\x00"character followed by zero or more"\x01"characters, with length equal to the widget’s width.attrib is the run-length encoding of display attributes.
Any entry containing a display attribute of the
inttype (e.g(1, 4)) denotes an embedded widget, where the display attirbute is the index of the widget within theembeddedwidgets list and the run length is the width of the widget.
- Return type:
Type Aliases#
Important
These may not be complete or correct for use with a static type checker. They’re intended for the comprehension of interfaces defined in this package, by programmers.
- urwidgets.Markup(*args, **kwargs)#
alias of
Union[StringMarkup,ListMarkup,TupleMarkup]
- urwidgets.TupleMarkup(*args, **kwargs)#
alias of
Union[NormalTupleMarkup,WidgetTupleMarkup]
- urwidgets.NormalTupleMarkup(*args, **kwargs)#
alias of
Tuple[DisplayAttribute,Union[StringMarkup,ListMarkup]]
- urwidgets.WidgetTupleMarkup(*args, **kwargs)#
alias of
Tuple[int,Union[urwid.Widget,WidgetListMarkup]]
- urwidgets.WidgetListMarkup(*args, **kwargs)#
alias of
List[Union[urwid.Widget,Markup,WidgetListMarkup]]