Skip to content

Commit 296b5b4

Browse files
Attempt to fix rendering of manually-added spaces, but break a bunch of other stuff in the process
1 parent fdef82c commit 296b5b4

File tree

4 files changed

+62
-17
lines changed

4 files changed

+62
-17
lines changed

pyhtml/__tag_base.py

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,12 @@ def _escape_children(self) -> bool:
121121
"""
122122
return True
123123

124-
def _render(self, indent: str, options: FullRenderOptions) -> list[str]:
124+
def _render(
125+
self,
126+
indent: str,
127+
options: FullRenderOptions,
128+
skip_indent: bool = False,
129+
) -> list[str]:
125130
"""
126131
Renders tag and its children to a list of strings where each string is
127132
a single line of output.
@@ -132,6 +137,8 @@ def _render(self, indent: str, options: FullRenderOptions) -> list[str]:
132137
string to use for indentation
133138
options : FullOptions
134139
rendering options
140+
skip_indent : bool
141+
whether to skip indentation for this element
135142
136143
Returns
137144
-------
@@ -148,8 +155,10 @@ def _render(self, indent: str, options: FullRenderOptions) -> list[str]:
148155
)
149156
)
150157

158+
indent_str = "" if skip_indent else indent
159+
151160
# Tag and attributes
152-
opening = f"{indent}<{self._get_tag_name()}"
161+
opening = f"{indent_str}<{self._get_tag_name()}"
153162

154163
# Add pre-content
155164
if (pre := self._get_tag_pre_content()) is not None:
@@ -169,15 +178,17 @@ def _render(self, indent: str, options: FullRenderOptions) -> list[str]:
169178
children = util.render_children(
170179
self.children,
171180
self._escape_children(),
172-
"" if indent_increase is None else indent + indent_increase,
181+
""
182+
if indent_increase is None
183+
else indent + indent_increase,
173184
options,
174185
)
175186
closing = f"</{self._get_tag_name()}>"
176187
if options.spacing == "\n":
177188
return [
178189
opening,
179190
*children,
180-
f"{indent}{closing}",
191+
f"{indent_str}{closing}",
181192
]
182193
else:
183194
# Children must have at least one line, since we would have
@@ -190,7 +201,7 @@ def _render(self, indent: str, options: FullRenderOptions) -> list[str]:
190201
# Add the closing tag onto the end
191202
return [
192203
*out[:-1],
193-
out[-1] + options.spacing + closing,
204+
indent_str + out[-1] + options.spacing + closing,
194205
]
195206

196207
def render(self) -> str:
@@ -217,11 +228,17 @@ def __init__(
217228
# Self-closing tags don't allow children
218229
super().__init__(*options, **attributes)
219230

220-
def _render(self, indent: str, options: FullRenderOptions) -> list[str]:
231+
def _render(
232+
self,
233+
indent: str,
234+
options: FullRenderOptions,
235+
skip_indent: bool = False,
236+
) -> list[str]:
221237
"""
222238
Renders tag and its children to a list of strings where each string is
223239
a single line of output
224240
"""
241+
indent_str = "" if skip_indent else indent
225242
attributes = util.filter_attributes(
226243
util.dict_union(
227244
self._get_default_attributes(self.attributes),
@@ -230,11 +247,11 @@ def _render(self, indent: str, options: FullRenderOptions) -> list[str]:
230247
)
231248
if len(attributes):
232249
return [
233-
f"{indent}<{self._get_tag_name()} "
250+
f"{indent_str}<{self._get_tag_name()} "
234251
f"{util.render_tag_attributes(attributes)}/>"
235252
]
236253
else:
237-
return [f"{indent}<{self._get_tag_name()}/>"]
254+
return [f"{indent_str}<{self._get_tag_name()}/>"]
238255

239256

240257
@deprecated(

pyhtml/__util.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -101,17 +101,21 @@ def render_inline_element(
101101
"""
102102
from .__tag_base import Tag
103103

104+
skip_indent = options.spacing is not None and "\n" not in options.spacing
105+
104106
if isinstance(ele, Tag):
105-
return ele._render(indent, options)
107+
return ele._render(indent, options, skip_indent)
106108
elif isinstance(ele, type) and issubclass(ele, Tag):
107109
e = ele()
108-
return e._render(indent, options)
110+
return e._render(indent, options, skip_indent)
109111
else:
110112
# Remove newlines from strings when inline rendering
111113
if escape_strings:
112-
return increase_indent([escape_string(str(ele))], indent)
114+
return increase_indent(
115+
[escape_string(str(ele))], "" if skip_indent else indent
116+
)
113117
else:
114-
return increase_indent([str(ele)], indent)
118+
return increase_indent([str(ele)], "" if skip_indent else indent)
115119

116120

117121
def render_children(
@@ -135,7 +139,6 @@ def render_children(
135139
else:
136140
# Custom spacing
137141
if len(rendered) == 0:
138-
rendered_child[0] = rendered_child[0].strip()
139142
rendered = rendered_child
140143
else:
141144
*r_head, r_tail = rendered
@@ -145,8 +148,8 @@ def render_children(
145148
# Join it all nicely
146149
rendered = [
147150
*r_head,
148-
# Remove leading whitespace caused by indentation rules
149-
r_tail + options.spacing + c_head.lstrip(),
151+
# Join using spacing as separator
152+
r_tail + options.spacing + c_head,
150153
*c_tail,
151154
]
152155
return rendered

tests/render_options_test.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,25 @@ def test_mixed_spacing():
7777
)
7878

7979

80+
def test_spacing_str():
81+
doc = p.body(
82+
p.div(
83+
p.RenderOptions(spacing=" "),
84+
p.span(p.RenderOptions(spacing="\n"), "hi"),
85+
),
86+
)
87+
88+
assert str(doc) == "\n".join(
89+
[
90+
"<body>",
91+
" <div> <span>",
92+
" hi",
93+
" </span> </div>",
94+
"</body>",
95+
]
96+
)
97+
98+
8099
def test_spacing_inner_newline():
81100
doc = p.body(
82101
p.div(
@@ -121,6 +140,11 @@ def test_indent_and_spacing_inner_newline():
121140
)
122141

123142

124-
def test_default_render_options():
143+
def test_default_render_options_paragraph():
125144
doc = p.p("Paragraph")
126145
assert str(doc) == "<p>Paragraph</p>"
146+
147+
148+
def test_extra_space_is_respected_in_paragraphs():
149+
doc = p.p(" Paragraph ")
150+
assert str(doc) == "<p> Paragraph </p>"

tests/whitespace_sensitive_test.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ def test_textarea():
2121

2222

2323
def test_indentation_ignored():
24-
assert str(p.body(p.pre("hello\nworld"))) == '\n'.join([
24+
doc = p.body(p.pre("hello\nworld"))
25+
assert str(doc) == '\n'.join([
2526
"<body>",
2627
" <pre>hello",
2728
"world</pre>",

0 commit comments

Comments
 (0)