Description
Description
I'm using mkdocstrings and Sybil to extract code examples in the documentation and test by running pylint on them via pytest.
This forces me to sometimes add too much boilerplate to examples, which is distracting from the main idea I want to show in an example, but it is also really important that examples stay up to date and (mostly) working.
An alternative would be to move the examples to separate files and use the snippet extension line selection feature, but I want to keep the examples in the docstrings, so they are also accessible in code editors, as python include all the docs in the code itself.
Related links
- Highlight specific lines feature
- Markdown Snippet line selection
- Original issue reported to
mkdocs-material
Extra:
Benefits
Being able to write examples that are verifiable using linting tools to ensure they stay up to date, but still only being able to show the relevant parts that make sense for the documentation, avoiding distracting, boilerplate code.
Solution Idea
I would like code blocks to accept selecting which lines to show, similar to what the snippet line selection or the highlight specific lines feature does. For example:
Example:
``` py show_lines="4:"
# Bolierplate setup code
# More boiler plate setup code
# And some more
this is the_juicy_part
# more useful code
```I'm suggesting the snippet extension syntax (with :) instead of the highlight specific lines feature syntax because it is more natural for specifying open-ended ranges.
Optional: There could be some button to expand the example and show also the boilerplate code, so users could copy&paste the whole example and run it if they want.
Activity
facelessuser commentedon Nov 17, 2023
The requested feature is quite niche, though I see why you would find it useful for your purposes, and I can see a select amount of people using it as well. One of the reasons I added custom fences to SuperFences was to allow people to create specialized behavior for their code blocks without me having to implement and maintain every niche case that was desired.
What I can provide is some guidance as to how you can accomplish what you want with custom fences. You can simply override the code blocks you desire adding in the options to specify the lines to show. Lastly, you'd preprocess the code, stripping out any lines you did not wish to show before passing them along to the highlighter.
You may have to wait until I find the time over the weekend to code up an example for you, but you can start reading about custom fences here: https://facelessuser.github.io/pymdown-extensions/extensions/superfences/#custom-fences.
facelessuser commentedon Nov 18, 2023
Here's an example. We override all languages with
*and define our custom formatter and validator. In our custom validator we validate our new option and then feed the great of the inputs through the default code validator. Then in our formatter, we check for our new option, modify the source as needed, and send it through the default highlight logic. That's it. It should work on any language then.llucax commentedon Nov 20, 2023
Hi @facelessuser, thanks for the explanation and example. I really appreciate it. I will give it a try as soon as possible.
I have one more question though, since I want to use this in
mkdocs-material, I'm not exactly sure how this is plugged into that. I'm also not sure if this is a question I should ask here or inmkdocs-material.Thanks again!
facelessuser commentedon Nov 20, 2023
I can show you how I run them:
I currently have one in my tools folder: https://github.com/facelessuser/pymdown-extensions/blob/main/tools/pymdownx_md_render.py. I place an
__init__.pyintoolsto treat it as a local module.I specify it in
mkdocs.ymllike so: https://github.com/facelessuser/pymdown-extensions/blob/main/mkdocs.yml#L119. For yours, I would obviously use thenameof*andclassofhighlight.Lastly, to find local modules I have to run mkdocs with the
-moption:python3 -m mkdocs serve: https://github.com/facelessuser/pymdown-extensions/blob/main/.github/workflows/deploy.yml#L36.I don't use Material's docker image, so if you are using that, you might have to ask on
mkdocs-materialif it is not obvious how to runmkdocswith-m.The alternative is that you make a pip installable package with your custom code and then you don't have to load local modules, you would just reference it as a normal installed module.
Also, the example I provided is just a quick and dirty example. You will have to tweak the code to have it work exactly how you want, but it is a good starting point.