Skip to content

A quick node tour

def a_quick_tour(page: mk.MkPage):
This will be a quick, short random introduction of some of the nodes included in MkNodes. The selection of nodes is totally random, this should just provide a quick overview how to interact with the nodes.

Let the tour begin!

Our first [MkNode][mknodes.MkNode] is very clever. You just show him a node and he will tell you all you need to know about him. It's MkDocStrings! Lets check what he knows about MkPage:

    node = mk.MkDocStrings(mk.MkPage)
MkDocStrings sometimes really writes long stories, so we will put everything into a collapsed MkAdmonition box, so we dont need that much space:
    admonition = mk.MkAdmonition(node, collapsible=True)
    str(admonition)
Here is the result:

Info

Bases: MkContainer

A node container representing a Markdown page.

A page contains a list of other Markdown nodes, has a virtual Markdown file associated, and can have metadata (added as header)

icon property writable

icon: str | None

Return page icon from metadata.

path property writable

path: str

Return the last part of the page path.

resolved_file_path property

resolved_file_path: str

Returns the resulting section/subsection/../filename.xyz path.

resolved_metadata property

resolved_metadata: Metadata

Return page metadata, complemented with the parent Nav metadata objects.

status property writable

status: PageStatusStr | str | None

Return page status from metadata.

subtitle property writable

subtitle: str | None

Return subtitle from metadata.

title property writable

title: str

Return the page title if set, otherwise infer title from path.

__init__

__init__(
    title: str | None = None,
    *,
    hide: list[str] | str | None = None,
    search_boost: float | None = None,
    exclude_from_search: bool | None = None,
    icon: str | None = None,
    path: str | PathLike[str] | None = None,
    status: PageStatusStr | None = None,
    subtitle: str | None = None,
    description: str | None = None,
    template: str | PageTemplate | None = None,
    inclusion_level: bool | None = None,
    tags: list[str] | None = None,
    edit_path: str | None = None,
    is_index: bool | None = None,
    is_homepage: bool | None = None,
    **kwargs: Any
)

Constructor.

Parameters:

Name Type Description Default
path str | PathLike[str] | None

Page path

None
hide list[str] | str | None

Hide parts of the website ("toc", "nav", "path", "tags").

None
search_boost float | None

Factor to modify search ranking

None
exclude_from_search bool | None

Whether to exclude this page from search listings

None
icon str | None

Optional page icon

None
status PageStatusStr | None

Page status

None
title str | None

Page title

None
subtitle str | None

Page subtitle

None
description str | None

Page description

None
template str | PageTemplate | None

Page template (filename relative to overrides directory or PageTemplate object)

None
inclusion_level bool | None

Inclusion level of the page

None
tags list[str] | None

tags to show above the main headline and within the search preview

None
edit_path str | None

Custom edit path for this page

None
kwargs Any

Keyword arguments passed to parent

{}
is_index bool | None

Whether this page should be the index page.

None
is_homepage bool | None

Whether this page should be the homepage.

None

from_file classmethod

from_file(
    path: str | PathLike[str],
    *,
    title: str | None = None,
    parent: MkNode | None = None,
    **kwargs: Any
) -> Self

Reads file content and creates an MkPage.

Parses and reads header metadata.

Parameters:

Name Type Description Default
path str | PathLike[str]

Path to load file from, either a local path or a fsspec protocol path.

required
title str | None

Optional title to use If None, title will be infered from metadata or filename

None
parent MkNode | None

Optional parent for new page

None
kwargs Any

Additional metadata for MkPage. Will override parsed metadata.

{}

get_processors

get_processors() -> list[TextProcessor]

Override base MkNode processors.

is_index

is_index() -> bool

Returns True if the page is the index page for the parent Nav.

MkDocStrings can even show information about himself. Very talented!

    node = mk.MkDocStrings(mk.MkDocStrings)
    admonition = mk.MkAdmonition(node, collapsible=True)
    str(admonition)

Info

Bases: MkNode

Docstring section (powered by mkdocstrings).

__init__

__init__(
    obj: (
        ModuleType
        | Object
        | str
        | tuple[str, ...]
        | list[str]
        | PathLike
        | type
        | Callable
    ),
    for_topmost: bool = True,
    allow_inspection: bool | None = None,
    show_bases: bool | None = None,
    show_source: bool | None = None,
    preload_modules: list[str] | None = None,
    heading_level: int | None = None,
    show_root_heading: bool | None = None,
    show_root_toc_entry: bool | None = None,
    show_root_full_path: bool | None = None,
    show_root_members_full_path: bool | None = None,
    show_object_full_path: bool | None = None,
    show_category_heading: bool | None = None,
    show_symbol_type_heading: bool | None = None,
    show_symbol_type_toc: bool | None = None,
    show_docstring_description: bool | None = None,
    inherited_members: bool | None = None,
    members: list[str] | None = None,
    members_order: Literal["alphabetical", "source"] | None = None,
    filters: list[str] | None = None,
    group_by_category: bool | None = None,
    show_submodules: bool | None = None,
    docstring_section_style: Literal["table", "list", "spacy"] | None = None,
    merge_init_into_class: bool | None = None,
    show_if_no_docstring: bool | None = None,
    annotations_path: Literal["brief", "source"] | None = None,
    line_length: int | None = None,
    show_signature: bool | None = None,
    show_signature_annotations: bool | None = None,
    signature_crossrefs: bool | None = None,
    separate_signature: bool | None = None,
    **kwargs: Any
)

Docstring section.

Global options for DocStrings can be overridden by setting the keyword arguments to not-None.

Parameters:

Name Type Description Default
obj ModuleType | Object | str | tuple[str, ...] | list[str] | PathLike | type | Callable

What to show DocStrings for.

required
for_topmost bool

If True, try to find the "shortest" path to given object by checking whether it can also be found in a parent module.

True
allow_inspection bool | None

Whether to allow inspecting modules when visiting them is not possible

None
show_bases bool | None

Show the base classes of a class.

None
show_source bool | None

Show the source code of this object.

None
preload_modules list[str] | None

List of modules to pre-load.

None
heading_level int | None

The initial heading level to use.

None
show_root_heading bool | None

Show the heading of the object at the root of the documentation tree (i.e. the object referenced by the identifier after :::).

None
show_root_toc_entry bool | None

If the root heading is not shown, at least add a ToC entry for it.

None
show_root_full_path bool | None

Show the full Python path for the root object heading.

None
show_root_members_full_path bool | None

Show the full Python path of the root members.

None
show_object_full_path bool | None

Show the full Python path of every object.

None
show_category_heading bool | None

When grouped by categories, show a heading for each category.

None
show_symbol_type_heading bool | None

Show the symbol type in headings (e.g. mod, class, func and attr).

None
show_symbol_type_toc bool | None

Show the symbol type in the Table of Contents (e.g. mod, class, func and attr).

None
show_docstring_description bool | None

Whether to show the description from DocStrings

None
inherited_members bool | None

Also show inherited members.

None
members list[str] | None

An explicit list of members to render.

None
members_order Literal['alphabetical', 'source'] | None

The members ordering to use.

None
filters list[str] | None

A list of filters applied to filter objects based on their name. A filter starting with ! will exclude matching objects instead of including them. The members option takes precedence over filters (filters will still be applied recursively to lower members in the hierarchy).

None
group_by_category bool | None

Group the object's children by categories: attributes, classes, functions, and modules.

None
show_submodules bool | None

When rendering a module, show its submodules recursively.

None
docstring_section_style Literal['table', 'list', 'spacy'] | None

The style used to render docstring sections.

None
merge_init_into_class bool | None

Whether to merge the init method into the class' signature and docstring.

None
show_if_no_docstring bool | None

Show the object heading even if it has no docstring or children with docstrings.

None
annotations_path Literal['brief', 'source'] | None

The verbosity for annotations path

None
line_length int | None

Maximum line length when formatting code/signatures.

None
show_signature bool | None

Show methods and functions signatures.

None
show_signature_annotations bool | None

Show the type annotations in methods and functions signatures.

None
signature_crossrefs bool | None

Whether to render cross-references for type annotations in signatures.

None
separate_signature bool | None

Whether to put the whole signature in a code block below the heading. If Black is installed, the signature is also formatted using it.

None
kwargs Any

Keyword arguments passed to super.

{}

Okay, that's enough DocStrings for today. You can find more of MkDocStrings work in the API documentation, he will tell you something about every [MkNode][mknodes.MkNode] there.

Another [MkNode][mknodes.MkNode] who is displaying his skills in the API docs is MkClassDiagram.

He's a very talented painter. Perhaps he can draw us something about MkPage!

    diagram = mk.MkClassDiagram(mk.MkPage)
    str(diagram)
graph TD
  94721305999824["mkpage.MkPage"]
  94721311697232["mkcontainer.MkContainer"]
  94721308848336["mknode.MkNode"]
  94721311766592["node.Node"]
  140564252373184["builtins.object"]
  94721311697232 --> 94721305999824
  94721308848336 --> 94721311697232
  94721311766592 --> 94721308848336
  140564252373184 --> 94721311766592
MkClassDiagram can draw different kind of graphs. The first picture MkClassDiagram has painted was about base classes. Lets check out the subclasses:
    diagram = mk.MkClassDiagram(mk.MkPage, mode="subclasses")
    str(diagram)
graph TD
  94721305999824["mkpage.MkPage"]
  94721306013584["mktemplatepage.MkTemplatePage"]
  94721306014576["mkclasspage.MkClassPage"]
  94721306017696["mkmodulepage.MkModulePage"]
  94721305999824 --> 94721306013584
  94721306013584 --> 94721306014576
  94721306013584 --> 94721306017696
There are multiple talented drawers among the MkNodes. MkPipDepTree is known for his dependency drawings, we can ask him to draw a graph for one of our dependencies.

To not overboard him, lets pick a package without too many dependencies:

    node = mk.MkPipDepTree("gitpython", direction="LR")
    str(node)
graph LR
    classDef missing stroke-dasharray: 5
    gitdb["gitdb\n4.0.11"]
    gitpython["GitPython\n3.1.43"]
    smmap["smmap\n5.0.1"]
    gitdb -- ">=3.0.1,<6" --> smmap
    gitpython -- ">=4.0.1,<5" --> gitdb
We now come to the last [MkNode][mknodes.MkNode] of our quick tour.

Let's introduce MkMetadataBadges!

MkMetadataBadges just loves Badges. He creates them himself and doesnt rely on webservies.

    node = mk.MkMetadataBadges("classifiers", package="mkdocstrings")
    str(node)

4 - Beta 4 - Beta Development Status Development Status Developers Developers Intended Audience Intended Audience Python Python Programming Language Programming Language Python :: 3 Python :: 3 Programming Language Programming Language Python :: 3 :: Only Python :: 3 :: Only Programming Language Programming Language Python :: 3.9 Python :: 3.9 Programming Language Programming Language Python :: 3.10 Python :: 3.10 Programming Language Programming Language Python :: 3.11 Python :: 3.11 Programming Language Programming Language Python :: 3.12 Python :: 3.12 Programming Language Programming Language Python :: 3.13 Python :: 3.13 Programming Language Programming Language Python :: 3.14 Python :: 3.14 Programming Language Programming Language Documentation Documentation Topic Topic Software Development Software Development Topic Topic Software Development :: Documentation Software Development :: Documentation Topic Topic Utilities Utilities Topic Topic Typed Typed Typing Typing

Looks neat, right? This is also a good chance to explain how nodes can get their information from the context. Let me explain:

If we instanciate MkNodes and dont add them to the tree, then the nodes are clueless. They dont know who they belong to.

To make them part of the tree, we either add them for example to a page

(like this: page += node)

or we pass them a parent on instantiation.

In this example, once we add MkMetadataBadges to the tree, that node knows that he should create badges for our very own package, mknodes, unless we explicitely tell him to do otherwise. It will become his new "default".

You dont believe me? Let me show you:

    node = mk.MkMetadataBadges("websites", parent=page)
Now that node is connected. If we ask him to draw now, he will create website badges for mknodes!
    str(node)

Documentation Documentation phil65.github.io phil65.github.io Source Source github.com github.com

This mechanism is the same for many MkNodes. For example, our earlier guest MkPipDepTree behaves the same. Once connected, he will want to paint mknodes dependency graphs without us telling him to do so!

Interesting, right?

That's it for a first quick look at the nodes. There are about 70 different ones available in this package. Some are exciting, some are boring. It's no difference to humans.

Oh, and if you wonder how this tour was done: I got help from MkCommentedCode!

    page += mk.MkCommentedCode(a_quick_tour, style="text")
MkCommentedCode parses a function and separates comments from code. These chunks are displayed on a rotating basis then.

Before we end the tour, let's take a look at the raw material. We can use the MkCode node for that.

    node = mk.MkCode.for_object(a_quick_tour)
    text = str(node).replace(r"{", "<").replace(r"}", ">")
    page += text
As you can see, we added the MkCode node to the page. It will be displayed right after the MkCommentedCode block. You will see it right below.

Oh, and the String replacement you probably noticed is a quick hack to prevent jinja2 code from getting executed. YOu can ignore that, it's not relevant for this tour.

That's it. The rest of the nodes you need to check out yourself. Have fun!

``` <.python title='mknodes.manual.a_quick_tour.a_quick_tour' linenums='4'> def a_quick_tour(page: mk.MkPage): # This will be a quick, short random introduction of some of the nodes # included in MkNodes. # The selection of nodes is totally random, this should just provide a quick overview # how to interact with the nodes. # # Let the tour begin! # # Our first [MkNode][mknodes.MkNode] is very clever. You just show him a node and he # will tell you all you need to know about him. # It's MkDocStrings! # Lets check what he knows about MkPage: node = mk.MkDocStrings(mk.MkPage) # MkDocStrings sometimes really writes long stories, # so we will put everything into # a collapsed MkAdmonition box, # so we dont need that much space: admonition = mk.MkAdmonition(node, collapsible=True) str(admonition) # Here is the result: # << "mknodes.MkPage" | MkDocStrings | MkAdmonition(collapsible=True) >>

# [MkDocStrings][mknodes.MkDocStrings] can even show information about himself.
# Very talented!
node = mk.MkDocStrings(mk.MkDocStrings)
admonition = mk.MkAdmonition(node, collapsible=True)
str(admonition)
# << "mknodes.MkDocStrings" | MkDocStrings | MkAdmonition(collapsible=True)>>

# Okay, that's enough DocStrings for today. You can find more of
# [MkDocStrings][mknodes.MkDocStrings] work
# in the API documentation, he will tell you something about every
# [MkNode][mknodes.MkNode] there.
#
# Another [MkNode][mknodes.MkNode] who is displaying his skills in the API docs is
# [MkClassDiagram][mknodes.MkClassDiagram].
#
# He's a very talented painter. Perhaps he can draw us something about
# [MkPage][mknodes.MkPage]!
#
diagram = mk.MkClassDiagram(mk.MkPage)
str(diagram)
# << "mknodes.MkPage" | MkClassDiagram >>

# [MkClassDiagram][mknodes.MkClassDiagram] can draw different kind of graphs.
# The first picture [MkClassDiagram][mknodes.MkClassDiagram] has painted was about
# base classes. Lets check out the subclasses:
diagram = mk.MkClassDiagram(mk.MkPage, mode="subclasses")
str(diagram)
# << "mknodes.MkPage" | MkClassDiagram(mode="subclasses") >>

# There are multiple talented drawers among the **MkNodes**.
# [MkPipDepTree][mknodes.MkPipDepTree] is known for his dependency drawings,
# we can ask him to draw a graph for one of our dependencies.
#
# To not overboard him, lets pick a package without too many dependencies:

node = mk.MkPipDepTree("gitpython", direction="LR")
str(node)
# << "gitpython" | MkPipDepTree(direction="LR") >>

# We now come to the last [MkNode][mknodes.MkNode] of our quick tour.
#
# Let's introduce [MkMetadataBadges][mknodes.MkMetadataBadges]!
#
# [MkMetadataBadges][mknodes.MkMetadataBadges] just loves Badges. He creates them
# himself and doesnt rely on webservies.
node = mk.MkMetadataBadges("classifiers", package="mkdocstrings")
str(node)
# << "classifiers" | MkMetadataBadges(package="mkdocstrings") >>

# Looks neat, right?
# This is also a good chance to explain how nodes can get their information
# from the context. Let me explain:
#
# If we instanciate **MkNodes** and dont add them to the tree,
# then the nodes are clueless. They dont know who they belong to.
#
# To make them part of the tree, we either add them for example to a page
#
# (like this: `page += node`)
#
# or we pass them a parent on instantiation.
#
# In this example, once we add [MkMetadataBadges][mknodes.MkMetadataBadges]
# to the tree, that node knows
# that he should create badges for our very own package, **mknodes**,
# unless we explicitely tell him to do otherwise. It will become his new "default".
#
# You dont believe me? Let me show you:
node = mk.MkMetadataBadges("websites", parent=page)

# Now that node is connected. If we ask him to draw now, he will create website
# badges for **mknodes**!

str(node)
# << "websites" | MkMetadataBadges >>

# This mechanism is the same for many **MkNodes**. For example, our earlier guest
# [MkPipDepTree][mknodes.MkPipDepTree] behaves the same. Once connected,
# he will want to paint **mknodes** dependency graphs without us telling him to do so!
#
# Interesting, right?
#
# That's it for a first quick look at the nodes.
# There are about 70 different ones available in this package.
# Some are exciting, some are boring. It's no difference to humans.
#
# Oh, and if you wonder how this tour was done: I got help from
# [MkCommentedCode][mknodes.MkCommentedCode]!
#
page += mk.MkCommentedCode(a_quick_tour, style="text")

# [MkCommentedCode][mknodes.MkCommentedCode] parses a function and separates comments
# from code. These chunks are displayed on a rotating basis then.
#
# Before we end the tour, let's take a look at the raw material.
# We can use the [MkCode][mknodes.MkCode] node for that.
#
node = mk.MkCode.for_object(a_quick_tour)
text = str(node).replace(r"<", "<").replace(r">", ">")
page += text
# As you can see, we added the [MkCode][mknodes.MkCode] node to the page.
# It will be displayed right after the [MkCommentedCode][mknodes.MkCommentedCode]
# block. You will see it right below.
#
# Oh, and the String replacement you probably noticed is a quick hack to prevent
# **jinja2** code from getting executed. YOu can ignore that, it's not relevant
#  for this tour.
#
# That's it. The rest of the nodes you need to check out yourself. Have fun!

```

Page info
Code for this page

``` {.python title='mknodes.manual.get_started_section.' linenums='31'} @nav.route.page("A quick node tour", hide="toc", icon="ic:outline-tour") def (page: mk.MkPage): page.metadata.render_macros = True a_quick_tour(page)

```

Resources

{.python } Resources(css=[], markdown_extensions={'attr_list': {}, 'md_in_html': {}, 'pymdownx.emoji': {'emoji_generator': <function to_svg at 0x7fd7a6931800>, 'emoji_index': <function twemoji at 0x7fd7a69316c0>}, 'pymdownx.highlight': {'anchor_linenums': True, 'line_spans': '__span', 'pygments_lang_class': True}, 'pymdownx.magiclink': {'repo': 'mknodes', 'repo_url_shorthand': True, 'user': 'phil65'}, 'pymdownx.superfences': {}}, plugins=[], js=[], assets=[], packages=[])

Metadata

``` {.yaml } created: source_filename: /home/runner/work/mknodes/mknodes/mknodes/manual/get_started_section.py source_function: null source_line_no: 31 hide: - toc icon: ic:outline-tour render_macros: true template: SUMMARY.html title: A quick node tour

```