Skip to content

Commit efb4841

Browse files
committed
fixes #570
1 parent fd98612 commit efb4841

File tree

3 files changed

+30
-15
lines changed

3 files changed

+30
-15
lines changed

fastcore/_modidx.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,7 @@
563563
'fastcore.xml.XT.children': ('xml.html#xt.children', 'fastcore/xml.py'),
564564
'fastcore.xml.XT.tag': ('xml.html#xt.tag', 'fastcore/xml.py'),
565565
'fastcore.xml._attrmap': ('xml.html#_attrmap', 'fastcore/xml.py'),
566+
'fastcore.xml._escape': ('xml.html#_escape', 'fastcore/xml.py'),
566567
'fastcore.xml._to_attr': ('xml.html#_to_attr', 'fastcore/xml.py'),
567568
'fastcore.xml.highlight': ('xml.html#highlight', 'fastcore/xml.py'),
568569
'fastcore.xml.showtags': ('xml.html#showtags', 'fastcore/xml.py'),

fastcore/xml.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,21 +58,23 @@ def xt(tag:str, *c, **kw):
5858
voids = set('area base br col command embed hr img input keygen link meta param source track wbr !doctype'.split())
5959

6060
# %% ../nbs/11_xml.ipynb 13
61+
def _escape(s): return '' if s is None else escape(s) if isinstance(s, str) else s
62+
63+
# %% ../nbs/11_xml.ipynb 14
6164
def _to_attr(k,v):
6265
if isinstance(v,bool):
6366
if v==True : return str(k)
6467
if v==False: return ''
65-
return f'{k}="{escape(str(v), quote=False)}"'
68+
return f'{k}="{escape(str(v), quote=True)}"'
6669

67-
# %% ../nbs/11_xml.ipynb 14
70+
# %% ../nbs/11_xml.ipynb 15
6871
def to_xml(elm, lvl=0):
6972
"Convert `xt` element tree into an XML string"
73+
if elm is None: return ''
7074
if isinstance(elm, tuple): return '\n'.join(to_xml(o) for o in elm)
7175
if hasattr(elm, '__xt__'): elm = elm.__xt__()
7276
sp = ' ' * lvl
73-
if not isinstance(elm, list):
74-
if isinstance(elm, str): elm = escape(elm)
75-
return f'{elm}\n'
77+
if not isinstance(elm, list): return f'{_escape(elm)}\n'
7678

7779
tag,cs,attrs = elm
7880
stag = tag
@@ -82,17 +84,19 @@ def to_xml(elm, lvl=0):
8284

8385
cltag = '' if tag in voids else f'</{tag}>'
8486
if not cs: return f'{sp}<{stag}>{cltag}\n'
87+
if len(cs)==1 and not isinstance(cs[0],(list,tuple)) and not hasattr(cs[0],'__xt__'):
88+
return f'{sp}<{stag}>{_escape(cs[0])}{cltag}\n'
8589
res = f'{sp}<{stag}>\n'
8690
res += ''.join(to_xml(c, lvl=lvl+2) for c in cs)
8791
if tag not in voids: res += f'{sp}{cltag}\n'
8892
return res
8993

90-
# %% ../nbs/11_xml.ipynb 16
94+
# %% ../nbs/11_xml.ipynb 17
9195
def highlight(s, lang='xml'):
9296
"Markdown to syntax-highlight `s` in language `lang`"
9397
return f'```{lang}\n{to_xml(s)}\n```'
9498

95-
# %% ../nbs/11_xml.ipynb 17
99+
# %% ../nbs/11_xml.ipynb 18
96100
def showtags(s):
97101
return f"""<code><pre>
98102
{escape(to_xml(s))}

nbs/11_xml.ipynb

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,18 @@
202202
{
203203
"cell_type": "code",
204204
"execution_count": null,
205-
"id": "e89496fb",
205+
"id": "254c8ff3",
206+
"metadata": {},
207+
"outputs": [],
208+
"source": [
209+
"#| export\n",
210+
"def _escape(s): return '' if s is None else escape(s) if isinstance(s, str) else s"
211+
]
212+
},
213+
{
214+
"cell_type": "code",
215+
"execution_count": null,
216+
"id": "0255b96f",
206217
"metadata": {},
207218
"outputs": [],
208219
"source": [
@@ -211,7 +222,7 @@
211222
" if isinstance(v,bool):\n",
212223
" if v==True : return str(k)\n",
213224
" if v==False: return ''\n",
214-
" return f'{k}=\"{escape(str(v), quote=False)}\"'"
225+
" return f'{k}=\"{escape(str(v), quote=True)}\"'"
215226
]
216227
},
217228
{
@@ -224,12 +235,11 @@
224235
"#| export\n",
225236
"def to_xml(elm, lvl=0):\n",
226237
" \"Convert `xt` element tree into an XML string\"\n",
238+
" if elm is None: return ''\n",
227239
" if isinstance(elm, tuple): return '\\n'.join(to_xml(o) for o in elm)\n",
228240
" if hasattr(elm, '__xt__'): elm = elm.__xt__()\n",
229241
" sp = ' ' * lvl\n",
230-
" if not isinstance(elm, list):\n",
231-
" if isinstance(elm, str): elm = escape(elm)\n",
232-
" return f'{elm}\\n'\n",
242+
" if not isinstance(elm, list): return f'{_escape(elm)}\\n'\n",
233243
"\n",
234244
" tag,cs,attrs = elm\n",
235245
" stag = tag\n",
@@ -239,6 +249,8 @@
239249
"\n",
240250
" cltag = '' if tag in voids else f'</{tag}>'\n",
241251
" if not cs: return f'{sp}<{stag}>{cltag}\\n'\n",
252+
" if len(cs)==1 and not isinstance(cs[0],(list,tuple)) and not hasattr(cs[0],'__xt__'):\n",
253+
" return f'{sp}<{stag}>{_escape(cs[0])}{cltag}\\n'\n",
242254
" res = f'{sp}<{stag}>\\n'\n",
243255
" res += ''.join(to_xml(c, lvl=lvl+2) for c in cs)\n",
244256
" if tag not in voids: res += f'{sp}{cltag}\\n'\n",
@@ -257,9 +269,7 @@
257269
"text": [
258270
"<html>\n",
259271
" <head>\n",
260-
" <title>\n",
261-
"Some page\n",
262-
" </title>\n",
272+
" <title>Some page</title>\n",
263273
" </head>\n",
264274
" <body>\n",
265275
" <div class=\"myclass\">\n",

0 commit comments

Comments
 (0)