Coverage for phml\compiler\steps\markup.py: 98%
48 statements
« prev ^ index » next coverage.py v6.5.0, created at 2023-04-12 14:26 -0500
« prev ^ index » next coverage.py v6.5.0, created at 2023-04-12 14:26 -0500
1from pathlib import Path
2from typing import Any
4from phml.components import ComponentManager
5from phml.embedded import exec_embedded
6from phml.nodes import Element, Parent
7from phml.utilities import sanatize
9from .base import scoped_step
11try: # pragma: no cover
12 from markdown import Markdown as PyMarkdown
14 MARKDOWN = PyMarkdown
15except ImportError: # pragma: no cover
16 error = Exception(
17 "You do not have the package 'markdown' installed. Install it to be able to use <Markdown /> tags",
18 )
20 class Markdown:
21 def __init__(self, *_a, **_k) -> None:
22 raise error
24 def registerExtensions(self, *_a, **_k):
25 raise error
27 def reset(self, *_a, **_k):
28 raise error
30 MARKDOWN = Markdown
33@scoped_step
34def step_compile_markdown(
35 node: Parent, components: ComponentManager, context: dict[str, Any]
36):
37 """Step to compile markdown. This step only works when you have `markdown` installed."""
38 from phml.core import HypertextManager
40 md_tags = [
41 child
42 for child in node
43 if isinstance(child, Element) and child.tag == "Markdown"
44 ]
46 if len(md_tags) > 0:
47 markdown = MARKDOWN(extensions=["codehilite", "tables", "fenced_code"])
48 for md in md_tags:
49 extras = str(md.get(":extras", None) or md.pop("extras", None) or "")
50 configs = md.pop(":configs", None)
51 if configs is not None:
52 configs = exec_embedded(
53 str(configs),
54 "<Markdown :configs='<dict>'",
55 **context,
56 )
57 if extras is not None:
58 if ":extras" in md:
59 extras = exec_embedded(
60 str(md.pop(":extras")),
61 "<Markdown :extras='<list|str>'",
62 **context,
63 )
64 if isinstance(extras, str):
65 extras = extras.split(" ")
66 elif isinstance(extras, list):
67 markdown.registerExtensions(
68 extensions=extras, configs=configs or {}
69 )
70 else:
71 raise TypeError(
72 "Expected ':extras' attribute to be a space seperated list as a str or a python list of str",
73 )
75 src = md.pop(":src", None) or md.pop("src", None)
76 if src is None or not isinstance(src, str):
77 raise ValueError(
78 "<Markdown /> element must have a 'src' or ':src' attribute that is a string",
79 )
81 if context.get("_phml_path_", None) is not None:
82 path = Path(context["_phml_path_"])
83 if path.suffix not in ["", None]:
84 path = path.parent / Path(src)
85 else:
86 path = path / Path(src)
87 else:
88 path = Path.cwd() / Path(src)
90 if not path.is_file():
91 raise FileNotFoundError(f"No markdown file at path '{path}'")
93 with path.open("r", encoding="utf-8") as md_file:
94 content = str(markdown.reset().convert(md_file.read()))
96 phml = HypertextManager()
97 phml.components = components
98 ast = phml.parse(content).ast
100 if len(ast) > 0 and md.parent is not None:
101 wrapper = Element(
102 "article", attributes=md.attributes, children=ast.children
103 )
104 sanatize(wrapper)
106 idx = md.parent.index(md)
108 md.parent.remove(md)
109 md.parent.insert(idx, wrapper)