Skip to content

Commit e78e652

Browse files
tappletapple-cisco
andauthored
HTML.format specifiers (#1566)
Add support for formatting parameters in HTML.format(). html_escape parameters after formatting, not before. Co-authored-by: Tapple Fulmer <mfulmer@cisco.com>
1 parent 700ae9e commit e78e652

File tree

2 files changed

+13
-5
lines changed

2 files changed

+13
-5
lines changed

prompt_toolkit/formatted_text/html.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import xml.dom.minidom as minidom
2+
from string import Formatter
23
from typing import Any, List, Tuple, Union
34

45
from .base import FormattedText, StyleAndTextTuples
@@ -107,11 +108,7 @@ def format(self, *args: object, **kwargs: object) -> "HTML":
107108
Like `str.format`, but make sure that the arguments are properly
108109
escaped.
109110
"""
110-
# Escape all the arguments.
111-
escaped_args = [html_escape(a) for a in args]
112-
escaped_kwargs = {k: html_escape(v) for k, v in kwargs.items()}
113-
114-
return HTML(self.value.format(*escaped_args, **escaped_kwargs))
111+
return HTML(FORMATTER.vformat(self.value, args, kwargs))
115112

116113
def __mod__(self, value: Union[object, Tuple[object, ...]]) -> "HTML":
117114
"""
@@ -124,6 +121,11 @@ def __mod__(self, value: Union[object, Tuple[object, ...]]) -> "HTML":
124121
return HTML(self.value % value)
125122

126123

124+
class HTMLFormatter(Formatter):
125+
def format_field(self, value: object, format_spec: str) -> str:
126+
return html_escape(format(value, format_spec))
127+
128+
127129
def html_escape(text: object) -> str:
128130
# The string interpolation functions also take integers and other types.
129131
# Convert to string first.
@@ -136,3 +138,6 @@ def html_escape(text: object) -> str:
136138
.replace(">", "&gt;")
137139
.replace('"', "&quot;")
138140
)
141+
142+
143+
FORMATTER = HTMLFormatter()

tests/test_formatted_text.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,9 @@ def test_html_interpolation():
141141
value = HTML("<b>{a}</b><u>{b}</u>").format(a="hello", b="world")
142142
assert to_formatted_text(value) == [("class:b", "hello"), ("class:u", "world")]
143143

144+
value = HTML("<b>{:02d}</b><u>{:.3f}</u>").format(3, 3.14159)
145+
assert to_formatted_text(value) == [("class:b", "03"), ("class:u", "3.142")]
146+
144147

145148
def test_merge_formatted_text():
146149
html1 = HTML("<u>hello</u>")

0 commit comments

Comments
 (0)