|
30 | 30 | "#| export\n", |
31 | 31 | "from fastcore.utils import *\n", |
32 | 32 | "\n", |
33 | | - "import types,json\n", |
| 33 | + "import types,json,re\n", |
34 | 34 | "\n", |
35 | 35 | "from dataclasses import dataclass, asdict\n", |
36 | 36 | "from typing import Mapping\n", |
|
326 | 326 | ] |
327 | 327 | }, |
328 | 328 | "execution_count": null, |
329 | | - "metadata": {}, |
| 329 | + "metadata": { |
| 330 | + "__type": "FT" |
| 331 | + }, |
330 | 332 | "output_type": "execute_result" |
331 | 333 | } |
332 | 334 | ], |
|
382 | 384 | " if isinstance(v,bool):\n", |
383 | 385 | " if v==True : return str(k)\n", |
384 | 386 | " 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", |
386 | 388 | " elif isinstance(v, Mapping): v = json.dumps(v)\n", |
387 | 389 | " elif hasattr(v, '__html__'): v = v.__html__()\n", |
388 | 390 | " else: v = str(v)\n", |
|
408 | 410 | "_inline_tags = {'a', 'span', 'b', 'i', 'u', 'em', 'strong', 'img', 'br', 'small',\n", |
409 | 411 | " 'big', 'sub', 'sup', 'label', 'input', 'select', 'option'}\n", |
410 | 412 | "\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'}" |
413 | 414 | ] |
414 | 415 | }, |
415 | 416 | { |
416 | 417 | "cell_type": "code", |
417 | 418 | "execution_count": null, |
418 | | - "id": "a1ed9c01", |
| 419 | + "id": "db55801a", |
419 | 420 | "metadata": {}, |
420 | 421 | "outputs": [], |
421 | 422 | "source": [ |
|
425 | 426 | " esc_fn = _escape if do_escape else _noescape\n", |
426 | 427 | " if elm is None: return ''\n", |
427 | 428 | " 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", |
430 | 430 | " if isinstance(elm, bytes): return elm.decode('utf-8')\n", |
431 | 431 | " if not isinstance(elm, FT): return f'{esc_fn(elm)}'\n", |
432 | 432 | "\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", |
435 | 435 | " 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", |
438 | 437 | " sp,nl = (' ' * lvl,'\\n') if indent and is_block else ('','')\n", |
439 | 438 | " nl_end = nl\n", |
440 | 439 | "\n", |
|
454 | 453 | " return f'{sp}{stag_}{content}{cltag}{nl_end}'\n", |
455 | 454 | "\n", |
456 | 455 | " 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", |
459 | 457 | " if not is_void: res += f'{sp}{cltag}{nl_end}'\n", |
460 | 458 | " return Safe(res)" |
461 | 459 | ] |
462 | 460 | }, |
463 | 461 | { |
464 | 462 | "cell_type": "code", |
465 | 463 | "execution_count": null, |
466 | | - "id": "7a3655e9", |
| 464 | + "id": "e24ad4e0", |
467 | 465 | "metadata": {}, |
468 | 466 | "outputs": [], |
469 | 467 | "source": [ |
|
475 | 473 | " return _to_xml(elm, lvl, indent, do_escape=do_escape)\n", |
476 | 474 | " if isinstance(elm, bytes): return elm.decode('utf-8')\n", |
477 | 475 | " return elm or ''\n", |
478 | | - " return Safe('\\n'.join(map(_f, elms)))" |
| 476 | + " return Safe('\\n'.join(map(_f, elms)))\n" |
479 | 477 | ] |
480 | 478 | }, |
481 | 479 | { |
|
542 | 540 | ] |
543 | 541 | }, |
544 | 542 | "execution_count": null, |
545 | | - "metadata": {}, |
| 543 | + "metadata": { |
| 544 | + "__type": "Safe" |
| 545 | + }, |
546 | 546 | "output_type": "execute_result" |
547 | 547 | } |
548 | 548 | ], |
|
652 | 652 | ] |
653 | 653 | }, |
654 | 654 | "execution_count": null, |
655 | | - "metadata": {}, |
| 655 | + "metadata": { |
| 656 | + "__type": "FT" |
| 657 | + }, |
656 | 658 | "output_type": "execute_result" |
657 | 659 | } |
658 | 660 | ], |
|
993 | 995 | ] |
994 | 996 | }, |
995 | 997 | "execution_count": null, |
996 | | - "metadata": {}, |
| 998 | + "metadata": { |
| 999 | + "__type": "Markdown" |
| 1000 | + }, |
997 | 1001 | "output_type": "execute_result" |
998 | 1002 | } |
999 | 1003 | ], |
|
1044 | 1048 | ] |
1045 | 1049 | } |
1046 | 1050 | ], |
1047 | | - "metadata": {}, |
| 1051 | + "metadata": { |
| 1052 | + "solveit_dialog_mode": "concise", |
| 1053 | + "solveit_ver": 2 |
| 1054 | + }, |
1048 | 1055 | "nbformat": 4, |
1049 | 1056 | "nbformat_minor": 5 |
1050 | 1057 | } |
0 commit comments