Getting started creating nbconvert templates

I would like to extend the nbconvert markdown template to remove code blocks, but preserve the output of codeblocks when processing .ipynb documents. I’m struggling to find the appropriate documentation for nbconvert. The official documentation assumes some familiarity with jinja and I’m not quite sure where to get started. I’ve figured out a bit by looking at other templates, but I have huge gaps in my understanding.

For example, I have a code block that contains:

from IPython.display import display, Markdown

display(Markdown('# Title\n\n This is text\n\n `this is code`'))

The built-in markdown template produces the following output when run with !jupyter nbconvert --to markdown --template my_template my_notebook.ipynb

*ignore the ‘\’; I just needed to escape the triple backtick

\```python
from IPython.display import display, Markdown

display(Markdown('# Title\n\n This is text\n\n `this is code`'))
\```


# Title

 This is text

 `this is code`

I would like the template to ignore the source and only provide the output:

# Title

 This is text

 `this is code`

I’ve tried adding meta-data to the cell and removing it with this:

metadata

{
 "hide_input": true
}

template directive

{% block data_codecell scoped %}
  {% if cell.metadata.get('hide_input', True) %}
{{ output.data['text/markdown'] }}
  {% endif %}

{% endblock data_codecell %}

The code above does not appear to work and includes the source.

I’ve tried looking to the sample templates provided on github in the ipython/jupyter project, but they just left me more confused.

Any guidance towards documentation, extensive samples or examples would be greatly appreciated.

You may be interested in how the hide_code extension handles some of the related steps.

Is this just meant as a way to learn to use nbconvert? Because for your example I’d just use nbformat to take the output from code source that includes display(Markdown() and make it a markdown cell. (You can use this script as a backbone for modification if it helps.) But maybe you are trying to do this all with one step and nbconvert would allow the flexibility you need?

@fomightez, I’m interested in learning more about nbconvert so I can do more with it and solve various other tasks as I work.

That extension would be great for some of my colleagues that are using Jupyter with younger students. I’ll look more into that! Thanks!

Your script sample looks promising, but it looks like it will strip out code blocks entirely even if they contain output that is markdown. I’m having trouble installing nbformat because my development machine is only running python 3.7 and there’s some dependency that requires 3.8. I’ll have to spin up a venv with 3.8 and give it a whirl later.

In this instance I really want to automate a workflow for document generation. I’m working on a growing project that has a lot of moving parts and would like to automatically document some elements.

I have an externally maintained repository that has an ever shifting and growing set of drivers for attached hardware. I’d like to write a little python to pull data from that repository and then output the some markdown that I can include it in the “supported hardware” section of the README when I rebuild the documentation.

I currently have a workflow where I open the README.ipynb, run the appropriate cells, generate the markdown and then paste it into the appropriate location and finally nbconvert the ipynb into md. My current solution is just to strip out the python entirely with this directive:

{% block codecell %}
{% endblock codecell %}

This is OK, but involves a lot of hand work and of course requires me to remember to do it. Having a nbconvert template that “just works” would be ideal.

I mentioned the hide_code extension because it has several examples of nbconvert templates that I thought might help you since you were looking for more template examples and those definitely do some steps related to what you are trying to accomplish.

The script sample I pointed to using nbformat was just meant as a backbone in that it iterates on the cells and does something with them and creates a new notebook from the new collection of cells. You’d need to modify it to grab the output content and add it as a markdown cell in the new notebook created. I’d be glad to help more with that if it is something you’d use but, I was unsure if it could fit in your workflow.

I thought nbformat was part of the Jupyter base architecture so that it would have already been there on your development server? Running import nbformat as nbf in your notebooks didn’t work? Sorry, if not. I guess I am just spoiled by MyBinder sessions which definitely include it. You could spin up instances from here by pressing the launch binder badge to test nbformat in Python 3.8. However, it is also a bit odd that it said it needed 3.8. The documentation for nbformat says 3.5 and above should work. And import nbformat as nbf works in Python 3.6 launched from here.

@txoof, have you considered using the Jupyter Book project? It allows you to very easily turn a series of notebooks (as well as Markdown files) into a nicely formatted HTML or PDF documentation (doesn’t need to be a book per se, you can even just convert a single notebook). It has a lot of very useful features allowing you to exactly select what cells should be rendered or not. For example you can completely remove code input and keep output (might be relevant in your example): https://jupyterbook.org/interactive/hiding.html#remove-cell-inputs
There are tons of other features and the project is very nicely documented, so if you think that might help you, you should definitely have look.

When you create the Jupyter Book you can choose to actually execute the notebooks, so if your goal is to keep docs up-to-date by pulling some information in a notebook that’s ideal. If you code is public, you can even do all that directly e.g. on GitHub using Github-Actions and Github-Pages so that your docs are re-created e.g. every time you push some new information or following a certain schedule. In case that helps, I made a small mock-project that integrates several of these features as an exercise on how to produce docs for a Python project. You can find the docs here and the repo here.

I hope that helps!
Guillaume

1 Like

@guiwitz Wow! That’s exactly what I was hoping for! I’ll check it out!

Thanks for the guidance. I’ll take a deeper look. I think the Jupyter book project mentioned below might be exactly what I’m looking for.