Skip to content

Commit d75d839

Browse files
committed
fixes #804
1 parent d7bf537 commit d75d839

File tree

3 files changed

+38
-35
lines changed

3 files changed

+38
-35
lines changed

fastcore/_modidx.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -705,7 +705,6 @@
705705
'fastcore.xml._escape': ('xml.html#_escape', 'fastcore/xml.py'),
706706
'fastcore.xml._fix_k': ('xml.html#_fix_k', 'fastcore/xml.py'),
707707
'fastcore.xml._flatten_tuple': ('xml.html#_flatten_tuple', 'fastcore/xml.py'),
708-
'fastcore.xml._is_whitespace_significant': ('xml.html#_is_whitespace_significant', 'fastcore/xml.py'),
709708
'fastcore.xml._noescape': ('xml.html#_noescape', 'fastcore/xml.py'),
710709
'fastcore.xml._preproc': ('xml.html#_preproc', 'fastcore/xml.py'),
711710
'fastcore.xml._to_attr': ('xml.html#_to_attr', 'fastcore/xml.py'),

fastcore/xml.py

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# %% ../nbs/09_xml.ipynb #f6c9a7f5
1616
from .utils import *
1717

18-
import types,json
18+
import types,json,re
1919

2020
from dataclasses import dataclass, asdict
2121
from typing import Mapping
@@ -146,7 +146,7 @@ def _to_attr(k,v):
146146
if isinstance(v,bool):
147147
if v==True : return str(k)
148148
if v==False: return ''
149-
if isinstance(v,str): v = escape(v, quote=False)
149+
if isinstance(v,str) and ('&' in v or '<' in v or '>' in v): v = escape(v, quote=False)
150150
elif isinstance(v, Mapping): v = json.dumps(v)
151151
elif hasattr(v, '__html__'): v = v.__html__()
152152
else: v = str(v)
@@ -164,25 +164,22 @@ def _to_attr(k,v):
164164
_inline_tags = {'a', 'span', 'b', 'i', 'u', 'em', 'strong', 'img', 'br', 'small',
165165
'big', 'sub', 'sup', 'label', 'input', 'select', 'option'}
166166

167-
def _is_whitespace_significant(elm):
168-
return elm.tag in {'pre', 'code', 'textarea', 'script'} or elm.get('contenteditable') == 'true'
167+
_ws_significant = {'pre', 'code', 'textarea', 'script'}
169168

170-
# %% ../nbs/09_xml.ipynb #a1ed9c01
169+
# %% ../nbs/09_xml.ipynb #db55801a
171170
def _to_xml(elm, lvl=0, indent=True, do_escape=True):
172171
"Convert `FT` element tree into an XML string"
173172
esc_fn = _escape if do_escape else _noescape
174173
if elm is None: return ''
175174
if hasattr(elm, '__ft__'): elm = elm.__ft__()
176-
if isinstance(elm, tuple):
177-
return ''.join(_to_xml(o, lvl=lvl, indent=indent, do_escape=do_escape) for o in elm)
175+
if isinstance(elm, tuple): return ''.join(_to_xml(o, lvl=lvl, indent=indent, do_escape=do_escape) for o in elm)
178176
if isinstance(elm, bytes): return elm.decode('utf-8')
179177
if not isinstance(elm, FT): return f'{esc_fn(elm)}'
180178

181-
tag, cs, attrs = elm.list
182-
is_void = getattr(elm, 'void_', False)
179+
tag,cs,attrs = elm.tag,elm.children,elm.attrs
180+
is_void = elm.void_
183181
is_block = tag in _block_tags
184-
if _is_whitespace_significant(elm): indent = False
185-
182+
if indent and (tag in _ws_significant or attrs.get('contenteditable') == 'true'): indent = False
186183
sp,nl = (' ' * lvl,'\n') if indent and is_block else ('','')
187184
nl_end = nl
188185

@@ -202,12 +199,11 @@ def _to_xml(elm, lvl=0, indent=True, do_escape=True):
202199
return f'{sp}{stag_}{content}{cltag}{nl_end}'
203200

204201
res = f'{sp}{stag_}{nl}'
205-
for c in cs:
206-
res += _to_xml(c, lvl=lvl+2 if indent else 0, indent=indent, do_escape=do_escape)
202+
for c in cs: res += _to_xml(c, lvl=lvl+2 if indent else 0, indent=indent, do_escape=do_escape)
207203
if not is_void: res += f'{sp}{cltag}{nl_end}'
208204
return Safe(res)
209205

210-
# %% ../nbs/09_xml.ipynb #7a3655e9
206+
# %% ../nbs/09_xml.ipynb #e24ad4e0
211207
def to_xml(*elms, lvl=0, indent=True, do_escape=True):
212208
"Convert `ft` element tree into an XML string"
213209
def _f(elm):
@@ -217,6 +213,7 @@ def _f(elm):
217213
return elm or ''
218214
return Safe('\n'.join(map(_f, elms)))
219215

216+
220217
# %% ../nbs/09_xml.ipynb #dd054392
221218
@patch
222219
def __html__(self:FT): return to_xml(self, indent=False)

nbs/09_xml.ipynb

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
"#| export\n",
3131
"from fastcore.utils import *\n",
3232
"\n",
33-
"import types,json\n",
33+
"import types,json,re\n",
3434
"\n",
3535
"from dataclasses import dataclass, asdict\n",
3636
"from typing import Mapping\n",
@@ -326,7 +326,9 @@
326326
]
327327
},
328328
"execution_count": null,
329-
"metadata": {},
329+
"metadata": {
330+
"__type": "FT"
331+
},
330332
"output_type": "execute_result"
331333
}
332334
],
@@ -382,7 +384,7 @@
382384
" if isinstance(v,bool):\n",
383385
" if v==True : return str(k)\n",
384386
" if v==False: return ''\n",
385-
" if isinstance(v,str): v = escape(v, quote=False)\n",
387+
" if isinstance(v,str) and ('&' in v or '<' in v or '>' in v): v = escape(v, quote=False)\n",
386388
" elif isinstance(v, Mapping): v = json.dumps(v)\n",
387389
" elif hasattr(v, '__html__'): v = v.__html__()\n",
388390
" else: v = str(v)\n",
@@ -408,14 +410,13 @@
408410
"_inline_tags = {'a', 'span', 'b', 'i', 'u', 'em', 'strong', 'img', 'br', 'small',\n",
409411
" 'big', 'sub', 'sup', 'label', 'input', 'select', 'option'}\n",
410412
"\n",
411-
"def _is_whitespace_significant(elm):\n",
412-
" return elm.tag in {'pre', 'code', 'textarea', 'script'} or elm.get('contenteditable') == 'true'"
413+
"_ws_significant = {'pre', 'code', 'textarea', 'script'}"
413414
]
414415
},
415416
{
416417
"cell_type": "code",
417418
"execution_count": null,
418-
"id": "a1ed9c01",
419+
"id": "db55801a",
419420
"metadata": {},
420421
"outputs": [],
421422
"source": [
@@ -425,16 +426,14 @@
425426
" esc_fn = _escape if do_escape else _noescape\n",
426427
" if elm is None: return ''\n",
427428
" if hasattr(elm, '__ft__'): elm = elm.__ft__()\n",
428-
" if isinstance(elm, tuple):\n",
429-
" return ''.join(_to_xml(o, lvl=lvl, indent=indent, do_escape=do_escape) for o in elm)\n",
429+
" if isinstance(elm, tuple): return ''.join(_to_xml(o, lvl=lvl, indent=indent, do_escape=do_escape) for o in elm)\n",
430430
" if isinstance(elm, bytes): return elm.decode('utf-8')\n",
431431
" if not isinstance(elm, FT): return f'{esc_fn(elm)}'\n",
432432
"\n",
433-
" tag, cs, attrs = elm.list\n",
434-
" is_void = getattr(elm, 'void_', False)\n",
433+
" tag,cs,attrs = elm.tag,elm.children,elm.attrs\n",
434+
" is_void = elm.void_\n",
435435
" is_block = tag in _block_tags\n",
436-
" if _is_whitespace_significant(elm): indent = False\n",
437-
"\n",
436+
" if indent and (tag in _ws_significant or attrs.get('contenteditable') == 'true'): indent = False\n",
438437
" sp,nl = (' ' * lvl,'\\n') if indent and is_block else ('','')\n",
439438
" nl_end = nl\n",
440439
"\n",
@@ -454,16 +453,15 @@
454453
" return f'{sp}{stag_}{content}{cltag}{nl_end}'\n",
455454
"\n",
456455
" res = f'{sp}{stag_}{nl}'\n",
457-
" for c in cs:\n",
458-
" res += _to_xml(c, lvl=lvl+2 if indent else 0, indent=indent, do_escape=do_escape)\n",
456+
" for c in cs: res += _to_xml(c, lvl=lvl+2 if indent else 0, indent=indent, do_escape=do_escape)\n",
459457
" if not is_void: res += f'{sp}{cltag}{nl_end}'\n",
460458
" return Safe(res)"
461459
]
462460
},
463461
{
464462
"cell_type": "code",
465463
"execution_count": null,
466-
"id": "7a3655e9",
464+
"id": "e24ad4e0",
467465
"metadata": {},
468466
"outputs": [],
469467
"source": [
@@ -475,7 +473,7 @@
475473
" return _to_xml(elm, lvl, indent, do_escape=do_escape)\n",
476474
" if isinstance(elm, bytes): return elm.decode('utf-8')\n",
477475
" return elm or ''\n",
478-
" return Safe('\\n'.join(map(_f, elms)))"
476+
" return Safe('\\n'.join(map(_f, elms)))\n"
479477
]
480478
},
481479
{
@@ -542,7 +540,9 @@
542540
]
543541
},
544542
"execution_count": null,
545-
"metadata": {},
543+
"metadata": {
544+
"__type": "Safe"
545+
},
546546
"output_type": "execute_result"
547547
}
548548
],
@@ -652,7 +652,9 @@
652652
]
653653
},
654654
"execution_count": null,
655-
"metadata": {},
655+
"metadata": {
656+
"__type": "FT"
657+
},
656658
"output_type": "execute_result"
657659
}
658660
],
@@ -993,7 +995,9 @@
993995
]
994996
},
995997
"execution_count": null,
996-
"metadata": {},
998+
"metadata": {
999+
"__type": "Markdown"
1000+
},
9971001
"output_type": "execute_result"
9981002
}
9991003
],
@@ -1044,7 +1048,10 @@
10441048
]
10451049
}
10461050
],
1047-
"metadata": {},
1051+
"metadata": {
1052+
"solveit_dialog_mode": "concise",
1053+
"solveit_ver": 2
1054+
},
10481055
"nbformat": 4,
10491056
"nbformat_minor": 5
10501057
}

0 commit comments

Comments
 (0)