10

Inside a markdown cell in an ipython-notebook I'd like to be able to expand variables automatically. Can this be done?

As an example, consider the following code

from IPython.core.display import HTML
from markdown import markdown

base_url = "https://stackoverflow.com/"
markdown_string = "Two categories at [stackoverflow]({0}) are "\
                  "[ipython-notebook]({0}questions/tagged/ipython-notebook) and "\
                  "[matplotlib]({0}questions/tagged/matplotlib).".format(base_url)
HTML("<p>{}</p>".format(markdown(markdown_string)))

This produces the output cell with the links correct, all relative to base_url, as

Two categories at stackoverflow are ipython-notebook and matplotlib.

What I would like is to be able to directly type the markdown into the cell, referencing a pre-defined variable. Is this possible?

Community
  • 1
  • 1
Ian
  • 1,483
  • 13
  • 14
  • Oh, I didn't know about `IPython.core.display.HTML` before, always ended up rolling my own object with `_repr_html_`. – Kos Jan 26 '14 at 13:56
  • 2
    This is very likely a duplicate of http://stackoverflow.com/q/18878083/2870069 some comments are also given here: http://stackoverflow.com/q/19524554/2870069 – Jakob Jan 26 '14 at 19:16
  • @Jakob is correct - what I wanted is exactly in the first question, which gives me the answer I was expecting. – Ian Jan 27 '14 at 07:35
  • @Ian your approach (writing markdown as pyout) is currently a good thing! If you use a custom exporter template you could at least create documents (html, latex, ..) looking exactly the way you are aiming at. However, the notebook itself would still be cluttered :( – Jakob Jan 27 '14 at 08:01
  • 2
    @Ian in the meantime an ipython extension has arrived which provides the desired functionality. See the updated answer in [this](http://stackoverflow.com/a/19328029/2870069) question. – Jakob Nov 20 '14 at 21:58

2 Answers2

8

Although it's not possible yet to do with a real Markdown cell, you can easily create a magic to get the same effect.

from __future__ import absolute_import
from IPython.core.getipython import get_ipython
from IPython.core.magic import (Magics, magics_class,  cell_magic)

@magics_class
class MarkdownMagics(Magics):

    @cell_magic
    def markdown(self, line, cell):
        from IPython.core.display import HTML
        from markdown import markdown

        vars = line.split()

        d = {}
        for k, v in self.shell.user_ns.items():
            if k in vars:
                d[k] = v

        return HTML("<p>{}</p>".format(markdown(cell.format(**d))))

get_ipython().register_magics(MarkdownMagics)

Set some Variables

foo = 1
bar = 2

Then call the magic, with arguments being the variables you want to take from the namespace.

%%markdown foo bar

Substitute _{foo}_ and *{bar}*
Jakob
  • 19,815
  • 6
  • 75
  • 94
Eric Busboom
  • 301
  • 3
  • 7
7

As @Jakob answered in the comments, the easiest way to accompish this is to install the python-markdown IPython notebook extension, as described on the wiki page.

You can then access your variables in markdown by surrounding them with curly brackets:

Python cell:

x = 1000

Markdown cell:

Insert variable contents here -> {{x}}.

The markdown cell gets parsed as:

Insert variable contents here -> 1000.
ostrokach
  • 17,993
  • 11
  • 78
  • 90