Get started
The includepy package provides a Markdown preprocessor that allows you to include the source code for a specific Python object (e.g., a function or class) when rendering Markdown content.
Note
This extension works with all of the standard code block features, such as line numbering, line highlighting, and code annotations. See Including a function for an example.
Installation
Install includepy with pip:
Configuration
Add the following settings to your Zensical or MkDocs configuration:
Example Python file
We use the following example.py file in the examples below:
"""
Example functions for inclusion in a code block.
"""
def something(arg1, arg2):
return f"{arg1} and {arg2}"
def hello(name: str) -> None:
print(f"Hello {name}!")
def factorial(n: int) -> int:
value = n # (1)
while n > 1:
n -= 1
value *= n
return value
class MyClass:
def do_thing(self, value: str) -> str:
return f"MyClass: {value}"
Including a function
If you write the following Markdown:
```py title="The factorial function", linenums="1", hl_lines="3-5"
-->includepy<-- example.py
-->pyobject<-- factorial
```
1. This is a code annotation.
You will get the following HTML:
def factorial(n: int) -> int:
value = n # (1)
while n > 1:
n -= 1
value *= n
return value
- This is a code annotation.
Including a class
If you write the following Markdown:
You will get the following HTML:
Including a class method
If you write the following Markdown:
You will get the following HTML:
Adding content before/after
If you write the following Markdown:
You will get the following HTML:
x = 1
def factorial(n: int) -> int:
value = n # (1)
while n > 1:
n -= 1
value *= n
return value
y = 2
Including only a subset of lines
If you write the following Markdown:
You will get the following HTML:
def factorial(n: int) -> int:
while n > 1:
n -= 1
def factorial(n: int) -> int:
value = n # (1)
value *= n
return value
The only_lines option accepts one or more line ranges, separated by commas, and each line range can take any of the following forms:
"n": Line numbern;"m-n": All lines from numbermto numbern(inclusive);"m-": All lines from numbermto the end (inclusive); and"-n": All lines from the start to line numbern(inclusive).
Note that line numbers start at 1.
Adding extra indentation
If you write the following Markdown:
You will get the following HTML:
Including extra lines
If you write the following Markdown:
```py
-->includepy<-- example.py
-->pyobject<-- factorial
-->lines_before<-- 4
-->lines_after<-- 4
```
You will get the following HTML:
def hello(name: str) -> None:
print(f"Hello {name}!")
def factorial(n: int) -> int:
value = n # (1)
while n > 1:
n -= 1
value *= n
return value
class MyClass:
def do_thing(self, value: str) -> str:
Note
When including only a subset of lines, line numbering begins at the first included line.
If you write the following Markdown:
```py
-->includepy<-- example.py
-->pyobject<-- factorial
-->lines_before<-- 4
-->only_lines<-- 1-2
```
You will get the following HTML:
Note
Extra lines will be truncated if they would extend before the first line or after the final line of the source file.
If you write the following Markdown:
You will get the following HTML:
"""
Example functions for inclusion in a code block.
"""
def something(arg1, arg2):
return f"{arg1} and {arg2}"
If you write the following Markdown:
You will get the following HTML:
Removing docstrings
Consider the following examples/docstring.py file:
"""
This module is used to test the `"strip_docstring"` option.
"""
def my_function():
"""
We want to strip this docstring when including the code for this function.
"""
return 1
If you write the following Markdown:
```py
-->includepy<-- examples/docstring.py
-->pyobject<-- my_function
-->strip_docstring<-- true
```
You will get the following HTML:
If there is no docstring, the strip_docstring option has no effect.
Note
Docstrings are removed before the only_lines option takes effect.
If you write the following Markdown:
```py
-->includepy<-- examples/docstring.py
-->pyobject<-- my_function
-->strip_docstring<-- true
-->only_lines<-- 1-2
```
You will get the following HTML:
Nested in a list
If you write the following Markdown:
- One thing
- Another thing:
```py
-->includepy<-- example.py
-->pyobject<-- factorial
-->includepy<-- example.py
-->pyobject<-- MyClass.do_thing
```
You will get the following HTML:
-
One thing
-
Another thing:
Escaping includepy blocks
If you write the following Markdown:
You will get the following HTML:
You can use any number of semi-colons.
For example, to show how to escape a includepy block you can write the following Markdown:
You will get the following HTML: