Markdown Processing
This page describes how Bestatic processes markdown files and what extensions and customizations are available
At the very basic level, Bestatic simply uses Python-Markdown to process all the markdown files. Python-Markdown is very close to the reference implementation of Markdown and hence you can simply write in any standard markdown format and most likely it will be processed correctly. An extensive documentation on Python-Markdown is available here and here.
Multi-Column Layouts with SplitSection
(New in v0.0.30) You can now create sophisticated multi-column layouts directly in your markdown content using the splitsection class on headers and putting section: true in your page's front matter. Note that You should also use a compatible template: sectiontemplate.html.jinja2 template for proper procesing.
With all that in place, in one of your markdown files, you can write:
1 2 3 4 5 6 7 8 9 10 11 | |
Bestatic will parse these sections separately and pass them to your templates with:
-
section.content- The section content -
section.heading- The corresponding heading text -
section.index- The section index number
Your theme can then utilize Jinja2 logic along with Bootstrap CSS (or another CSS framework of your choice) to render these sections in a multi-column layout. This gives you complete control over responsive column layouts without hardcoding HTML in your markdown.
To learn more about how to use these sections in your templates, please refer to the example template sections of themes page.
Default Extensions
In Bestatic, you have the Attribute Lists, Tables, Meta Data, Fenced Code Blocks, Markdown Custom Blocks, Emoji, CodeHilite of Python-Markdown enabled by default. You can replace all of these extensions with your own custom extensions by setting markdown_replace to true in your bestatic.yaml file and then adding your own extensions to the extensions list. You can then configure each extension with your own custom settings by adding your own settings to the extension_configs list. For example, if you want to replace the default CodeHilite extension with your own custom extension, you can add the following to your bestatic.yaml file:
1 2 3 4 5 6 7 | |
In this example, we are replacing the default CodeHilite extension with our own custom extension called my_custom_extension. We are also adding a custom setting to the my_custom_extension extension. See Configuring Extensions section for more details on how to configure individual extensions.
CodeHilite
We also have enabled CodeHilite extension which provides nice looking syntax highlighting options for code blocks in the pages (Pygments works under the hood). These linked pages provide information on how you can choose a particular color theme for your syntax highlighting and how you can generate your own CSS file for that (styles.css; this needs to be included in the static/css folder of your theme).
Markdown Custom Blocks
As mentioned above, we have included the markdown-customblocks extension in Bestatic which is a great tool that provides a common markup for parametrizable and nestable components. Without any effort, you can generate nice looking blocks: These can be admonition/call-out blocks, images, Instagram posts, YouTube videos, Mastodon posts, etc. See Built-in generators to get started quickly.
Emoji Support
We have also enabled emoji support in Bestatic out of the box using PyMdown Extensions emoji. We have adopted Twemoji emoji set (as emoji provider) and SVG (as output). While the full list of emojis that are supported can be found in the source code, any standard emoji shortcode (such as the shortcodes available on emoji cheat sheet or this GitHub gist) should work.
Markdown Include
(New in v0.0.30) The markdown-include extension is now included with Bestatic, allowing you to include content from one markdown file into another using the {!path/to/file.md!} syntax. This is not included by default in Bestatic, but you can easily add it to your bestatic.yaml file. Please see the detailed instructions below.
First, enable and configure the extension in your bestatic.yaml:
1 2 3 4 5 6 | |
The base_path setting tells the extension where to look for included files. You should organize your reusable content in the _includes directory (in your root directory) and sub-directories within it (e.g. _includes/codes, _includes/images, _includes/videos, etc.) for proper processing of the markdown files. For example, if you have a file called included_file.md in the _includes/codes directory, you can include it in your markdown file using the {! codes/included_file.md !} syntax.
Now, if you have two files in your _includes directory (e.g. _includes/included_file.md and _includes/examples/another.md), and you want to include the content from them in one of your main markdown files (e.g. main_document.md), you can do it as follows:
1 2 3 4 5 6 7 8 9 | |
Please note that, the included files should be placed in the _includes directory, _mddata directory, or their sub-directories for best processing.
The included file's content will be inserted at that location when Bestatic processes the markdown. This can be really useful for:
-
Reusing common content across multiple pages
-
Including code snippets or examples from external files
-
Keeping complex YAML data in separate files
Custom Markdown Extensions
(New in v0.0.30) You can now add any of the custom Python-Markdown extensions and Pymdown Extensions via your bestatic.yaml file. Note that, you can even replace the default extensions, as described in the Default Extensions section. Pymdown Extensions are already installed when you install Bestatic and hence you just need to add them to your bestatic.yaml file, as described above.
Installation of extensions...
If you want to install a custom extension that is not included in standard Bestatic installation, you can do so by running pip install <extension-name> in your terminal and then add it to your bestatic.yaml file, as described above. Note that, for this to work, you need to have Python and pip installed on your system and you need to install Bestatic as a python package using pipx or pip, as described in the Installation page. Regular OS-level installations of Bestatic will not work for this.
Adding Extensions
In your bestatic.yaml file, add extensions under the markdown section:
1 2 3 4 5 6 7 8 | |
Any extension from the python-markdown or pymdown-extensions packages can be added this way. Make sure the extension package is installed in your Python environment.
Configuring Extensions
(New in v0.0.30) You can configure individual markdown extensions with custom settings using the extension_configs section within the markdown section of your bestatic.yaml file.
Extension Configuration Example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
Each extension has its own configuration options. Refer to the Python-Markdown documentation and Pymdown Extensions documentation for available configuration options for each extension.
Custom Shortcodes
(New in v0.0.30) Shortcodes are reusable macros/Python functions that convert simple snippets in your markdown content into predefined HTML markup. You can now create custom shortcodes by writing Python functions and placing them in the _shortcodes directory at the root of your site. You can then use these shortcodes in your markdown content by wrapping them in {!!{ }!!} tags.
Creating a Shortcode
Create a file _shortcodes/alert.py:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | |
Using Shortcodes in Markdown
In your markdown content, use the shortcode:
1 2 3 | |
More Shortcode Examples
Create a keyboard shortcode in _shortcodes/key.py:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
Usage:
1 | |
Create a social media shortcode in _shortcodes/social.py:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | |
Usage:
1 | |
Bestatic will process shortcodes and replace them with the HTML returned by your Python function. Shortcodes:
-
Must be placed in the _shortcodes directory at the root of your site.
-
Must have a
render(attrs)function that accepts anattrsdictionary. -
The
attrsdictionary contains all parameters passed to the shortcode. -
The main content is available as
attrs.get('content', ''). -
Named parameters are accessed via
attrs.get('parameter_name', 'default').
With custom shortcodes, you can very comprehensively customize the Markdown content of your website and you are only limited by your imagination!