Uploaded Test files
This commit is contained in:
parent
f584ad9d97
commit
2e81cb7d99
16627 changed files with 2065359 additions and 102444 deletions
137
venv/Lib/site-packages/prompt_toolkit/formatted_text/html.py
Normal file
137
venv/Lib/site-packages/prompt_toolkit/formatted_text/html.py
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
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 and underline.
|
||||
HTML('<i>...</i>')
|
||||
HTML('<b>...</b>')
|
||||
HTML('<u>...</u>')
|
||||
|
||||
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('"', """)
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue