diff options
author | shadchin <shadchin@yandex-team.ru> | 2022-02-10 16:44:30 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:44:30 +0300 |
commit | 2598ef1d0aee359b4b6d5fdd1758916d5907d04f (patch) | |
tree | 012bb94d777798f1f56ac1cec429509766d05181 /contrib/python/prompt-toolkit/py3/prompt_toolkit/formatted_text/html.py | |
parent | 6751af0b0c1b952fede40b19b71da8025b5d8bcf (diff) | |
download | ydb-2598ef1d0aee359b4b6d5fdd1758916d5907d04f.tar.gz |
Restoring authorship annotation for <shadchin@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/python/prompt-toolkit/py3/prompt_toolkit/formatted_text/html.py')
-rw-r--r-- | contrib/python/prompt-toolkit/py3/prompt_toolkit/formatted_text/html.py | 276 |
1 files changed, 138 insertions, 138 deletions
diff --git a/contrib/python/prompt-toolkit/py3/prompt_toolkit/formatted_text/html.py b/contrib/python/prompt-toolkit/py3/prompt_toolkit/formatted_text/html.py index 06c6020f54..58d4c08c82 100644 --- a/contrib/python/prompt-toolkit/py3/prompt_toolkit/formatted_text/html.py +++ b/contrib/python/prompt-toolkit/py3/prompt_toolkit/formatted_text/html.py @@ -1,138 +1,138 @@ -import xml.dom.minidom as minidom -from typing import Any, List, Tuple, Union - -from .base import FormattedText, StyleAndTextTuples - -__all__ = ["HTML"] - - -class HTML: - """ - HTML formatted text. - Take something HTML-like, for use as a formatted string. - - :: - - # Turn something into red. - HTML('<style fg="ansired" bg="#00ff44">...</style>') - - # Italic, bold, underline and strike. - HTML('<i>...</i>') - HTML('<b>...</b>') - HTML('<u>...</u>') - HTML('<s>...</s>') - - All HTML elements become available as a "class" in the style sheet. - E.g. ``<username>...</username>`` can be styled, by setting a style for - ``username``. - """ - - def __init__(self, value: str) -> None: - self.value = value - document = minidom.parseString("<html-root>%s</html-root>" % (value,)) - - result: StyleAndTextTuples = [] - name_stack: List[str] = [] - fg_stack: List[str] = [] - bg_stack: List[str] = [] - - def get_current_style() -> str: - "Build style string for current node." - parts = [] - if name_stack: - parts.append("class:" + ",".join(name_stack)) - - if fg_stack: - parts.append("fg:" + fg_stack[-1]) - if bg_stack: - parts.append("bg:" + bg_stack[-1]) - return " ".join(parts) - - def process_node(node: Any) -> None: - "Process node recursively." - for child in node.childNodes: - if child.nodeType == child.TEXT_NODE: - result.append((get_current_style(), child.data)) - else: - add_to_name_stack = child.nodeName not in ( - "#document", - "html-root", - "style", - ) - fg = bg = "" - - for k, v in child.attributes.items(): - if k == "fg": - fg = v - if k == "bg": - bg = v - if k == "color": - fg = v # Alias for 'fg'. - - # Check for spaces in attributes. This would result in - # invalid style strings otherwise. - if " " in fg: - raise ValueError('"fg" attribute contains a space.') - if " " in bg: - raise ValueError('"bg" attribute contains a space.') - - if add_to_name_stack: - name_stack.append(child.nodeName) - if fg: - fg_stack.append(fg) - if bg: - bg_stack.append(bg) - - process_node(child) - - if add_to_name_stack: - name_stack.pop() - if fg: - fg_stack.pop() - if bg: - bg_stack.pop() - - process_node(document) - - self.formatted_text = FormattedText(result) - - def __repr__(self) -> str: - return "HTML(%r)" % (self.value,) - - def __pt_formatted_text__(self) -> StyleAndTextTuples: - return self.formatted_text - - def format(self, *args: object, **kwargs: object) -> "HTML": - """ - Like `str.format`, but make sure that the arguments are properly - escaped. - """ - # Escape all the arguments. - escaped_args = [html_escape(a) for a in args] - escaped_kwargs = {k: html_escape(v) for k, v in kwargs.items()} - - return HTML(self.value.format(*escaped_args, **escaped_kwargs)) - - def __mod__(self, value: Union[object, Tuple[object, ...]]) -> "HTML": - """ - HTML('<b>%s</b>') % value - """ - if not isinstance(value, tuple): - value = (value,) - - value = tuple(html_escape(i) for i in value) - return HTML(self.value % value) - - -def html_escape(text: object) -> str: - # The string interpolation functions also take integers and other types. - # Convert to string first. - if not isinstance(text, str): - text = "{}".format(text) - - return ( - text.replace("&", "&") - .replace("<", "<") - .replace(">", ">") - .replace('"', """) - ) +import xml.dom.minidom as minidom +from typing import Any, List, Tuple, Union + +from .base import FormattedText, StyleAndTextTuples + +__all__ = ["HTML"] + + +class HTML: + """ + HTML formatted text. + Take something HTML-like, for use as a formatted string. + + :: + + # Turn something into red. + HTML('<style fg="ansired" bg="#00ff44">...</style>') + + # Italic, bold, underline and strike. + HTML('<i>...</i>') + HTML('<b>...</b>') + HTML('<u>...</u>') + HTML('<s>...</s>') + + All HTML elements become available as a "class" in the style sheet. + E.g. ``<username>...</username>`` can be styled, by setting a style for + ``username``. + """ + + def __init__(self, value: str) -> None: + self.value = value + document = minidom.parseString("<html-root>%s</html-root>" % (value,)) + + result: StyleAndTextTuples = [] + name_stack: List[str] = [] + fg_stack: List[str] = [] + bg_stack: List[str] = [] + + def get_current_style() -> str: + "Build style string for current node." + parts = [] + if name_stack: + parts.append("class:" + ",".join(name_stack)) + + if fg_stack: + parts.append("fg:" + fg_stack[-1]) + if bg_stack: + parts.append("bg:" + bg_stack[-1]) + return " ".join(parts) + + def process_node(node: Any) -> None: + "Process node recursively." + for child in node.childNodes: + if child.nodeType == child.TEXT_NODE: + result.append((get_current_style(), child.data)) + else: + add_to_name_stack = child.nodeName not in ( + "#document", + "html-root", + "style", + ) + fg = bg = "" + + for k, v in child.attributes.items(): + if k == "fg": + fg = v + if k == "bg": + bg = v + if k == "color": + fg = v # Alias for 'fg'. + + # Check for spaces in attributes. This would result in + # invalid style strings otherwise. + if " " in fg: + raise ValueError('"fg" attribute contains a space.') + if " " in bg: + raise ValueError('"bg" attribute contains a space.') + + if add_to_name_stack: + name_stack.append(child.nodeName) + if fg: + fg_stack.append(fg) + if bg: + bg_stack.append(bg) + + process_node(child) + + if add_to_name_stack: + name_stack.pop() + if fg: + fg_stack.pop() + if bg: + bg_stack.pop() + + process_node(document) + + self.formatted_text = FormattedText(result) + + def __repr__(self) -> str: + return "HTML(%r)" % (self.value,) + + def __pt_formatted_text__(self) -> StyleAndTextTuples: + return self.formatted_text + + def format(self, *args: object, **kwargs: object) -> "HTML": + """ + Like `str.format`, but make sure that the arguments are properly + escaped. + """ + # Escape all the arguments. + escaped_args = [html_escape(a) for a in args] + escaped_kwargs = {k: html_escape(v) for k, v in kwargs.items()} + + return HTML(self.value.format(*escaped_args, **escaped_kwargs)) + + def __mod__(self, value: Union[object, Tuple[object, ...]]) -> "HTML": + """ + HTML('<b>%s</b>') % value + """ + if not isinstance(value, tuple): + value = (value,) + + value = tuple(html_escape(i) for i in value) + return HTML(self.value % value) + + +def html_escape(text: object) -> str: + # The string interpolation functions also take integers and other types. + # Convert to string first. + if not isinstance(text, str): + text = "{}".format(text) + + return ( + text.replace("&", "&") + .replace("<", "<") + .replace(">", ">") + .replace('"', """) + ) |