def node_writer(token: BlockToken, mesure: dict) -> None:
        """Save actions"""
        if is_keyword(token, children_key
                      ):  # children_key keyword is handled in the top parser
            return

        nest_level = name_level // 2
        leaf = parent = mesure

        for level in range(nest_level):
            # Build the tree.
            if not leaf[children_key]:
                leaf[children_key].append(node_builder())
            parent = leaf
            # Select the last leaf of the last branch.
            leaf = leaf[children_key][-1]

        nonlocal current
        if is_heading(token, name_level):  # Got a title
            if leaf["nom"]:  # leaf is already named
                leaf = node_builder()
                parent[children_key].append(leaf)
            current = head
        elif isinstance(token, CodeFence):
            current = meta
        elif current == meta:
            current = section("description")
        elif is_heading(token, name_level + 1):
            title = token.children[0].content.strip()
            current = section(title)

        current(token, leaf)
    def writer(token: BlockToken, data: dict) -> None:
        nonlocal current
        if is_heading(token, level):
            keyword = token.children[0].content.lower()
            current = member_writer(keyword)

        current(token, data)
 def writer(token: BlockToken, orientation: dict) -> None:
     nonlocal current
     if current is head and is_yaml(token):
         current = meta
     elif current is meta:
         current = void
     if is_heading(token, 2):
         if is_keyword(token, "description"):
             current = description
         if is_keyword(token, "niveaux"):
             current = niveaux
     current(token, orientation)
def markdown_parser(doc: Document,
                    node_builder: Callable,
                    children_key: str = "") -> List[dict]:
    """Extract a elements from a markdown AST"""
    elements = [node_builder()]
    name_level = 1  # the current level element names.
    current = writer(name_level=name_level,
                     node_builder=node_builder,
                     children_key=children_key)

    for token in doc.children:
        if is_keyword(token, children_key):
            name_level = token.level + 1
            current = writer(
                name_level=name_level,
                node_builder=node_builder,
                children_key=children_key,
            )

        elif is_heading(token, level=name_level - 2):
            name_level -= 2
            current = writer(
                name_level=name_level,
                node_builder=node_builder,
                children_key=children_key,
            )

        elif is_heading(token, level=1):
            if elements[-1]["nom"]:
                elements.append(node_builder())
            current = writer(
                name_level=name_level,
                node_builder=node_builder,
                children_key=children_key,
            )

        current(token, elements[-1])

    return elements
def build_indicators(doc: Document) -> List[dict]:
    """Extract indicateurs from a markdown AST"""
    indicators = []
    writer = indicator_writer()

    for token in doc.children:
        if is_heading(token, 1):
            writer = indicator_writer()
            indicators.append({})
        if indicators:
            indicator = indicators[-1]
            writer(token, indicator)

    return indicators
def parse_definitions(doc: Document) -> list[dict]:
    """Extract definitions from markdown AST"""
    definitions = []
    writer = void

    for token in doc.children:
        if is_heading(token, 2):
            definitions.append({
                "comments": [],
                "yaml": {},
            })
            writer = comment

        elif is_yaml(token):
            writer = save_yaml_data

        definition = definitions[-1] if definitions else None
        if definition:
            writer(token, definition)

    return definitions
    def writer(token: BlockToken, orientation: dict) -> None:
        """Save niveaux"""
        if is_keyword(token, "niveaux"):
            return
        if "niveaux" not in orientation.keys():
            orientation["niveaux"] = [{}]
        niveaux: list = orientation["niveaux"]
        niveau: dict = niveaux[-1]

        nonlocal current
        if niveau:
            if is_heading(token, 3):
                niveau = {}
                niveaux.append(niveau)
                current = head
            elif isinstance(token, CodeFence):
                current = meta
            else:
                current = members

        current(token, niveau)
 def head(token: BlockToken, indicator: dict) -> None:
     """save h1 into indicator"""
     if is_heading(token, 1):
         indicator["nom"] = token.children[0].content
def comment(token: BlockToken, definition: dict) -> None:
    """Saves comments into definition"""
    line = ""
    if is_heading(token, 2):
        line = f"## ${token.children[0].content}"
    definition["comments"].append(line)