• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1title: Markdown in HTML Extension
2
3# Markdown in HTML
4
5## Summary
6
7An extension that parses Markdown inside of HTML tags.
8
9## Syntax
10
11By default, Markdown ignores any content within a raw HTML block-level element. With the `md-in-html` extension
12enabled, the content of a raw HTML block-level element can be parsed as Markdown by including  a `markdown` attribute
13on the opening tag. The `markdown` attribute will be stripped from the output, while all other attributes will be
14preserved.
15
16The `markdown` attribute can be assigned one of three values: [`"1"`](#1), [`"block"`](#block), or [`"span"`](#span).
17
18!!! note
19
20    The expressions "block-level" and "span-level" as used in this document refer to an element's designation
21    according to the HTML specification. Whereas the `"span"` and `"block"` values assigned to the `markdown`
22    attribute refer to the Markdown parser's behavior.
23
24### `markdown="1"` { #1 }
25
26When the `markdown` attribute is set to `"1"`, then the parser will use the default behavior for that specific tag.
27
28The following tags have the `block` behavior by default: `article`, `aside`, `blockquote`, `body`, `colgroup`,
29`details`, `div`, `dl`, `fieldset`, `figcaption`, `figure`, `footer`, `form`, `group`, `header`, `hgroup`, `hr`,
30`iframe`,  `main`, `map`, `menu`, `nav`, `noscript`, `object`, `ol`, `output`, `progress`, `section`, `table`,
31`tbody`, `tfoot`, `thead`, `tr`,  `ul` and `video`.
32
33For example, the following:
34
35```
36<div markdown="1">
37This is a *Markdown* Paragraph.
38</div>
39```
40
41... is rendered as:
42
43``` html
44<div>
45<p>This is a <em>Markdown</em> Paragraph.</p>
46</div>
47```
48
49The following tags have the `span` behavior by default: `address`, `dd`, `dt`, `h[1-6]`, `legend`, `li`, `p`, `td`,
50and `th`.
51
52For example, the following:
53
54```
55<p markdown="1">
56This is not a *Markdown* Paragraph.
57</p>
58```
59
60... is rendered as:
61
62``` html
63<p>
64This is not a <em>Markdown</em> Paragraph.
65</p>
66```
67
68### `markdown="block"` { #block }
69
70When the `markdown` attribute is set to `"block"`, then the parser will force the `block` behavior on the contents of
71the element so long as it is one of the `block` or `span` tags.
72
73The content of a `block` element is parsed into block-level content. In other words, the text is rendered as
74paragraphs, headers, lists, blockquotes, etc. Any inline syntax within those elements is processed as well.
75
76For example, the following:
77
78```
79<section markdown="block">
80# A header.
81
82A *Markdown* paragraph.
83
84* A list item.
85* A second list item.
86
87</section>
88```
89
90... is rendered as:
91
92``` html
93<section>
94<h1>A header.</h1>
95<p>A <em>Markdown</em> paragraph.</p>
96<ul>
97<li>A list item.</li>
98<li>A second list item.</li>
99</ul>
100</section>
101```
102
103!!! warning
104
105    Forcing elements to be parsed as `block` elements when they are not by default could result in invalid HTML.
106    For example, one could force a `<p>` element to be nested within another `<p>` element. In most cases it is
107    recommended to use the default behavior of `markdown="1"`. Explicitly setting `markdown="block"` should be
108    reserved for advanced users who understand the HTML specification and how browsers parse and render HTML.
109
110### `markdown="span"` { #span }
111
112When the `markdown` attribute is set to `"span"`, then the parser will force the `span` behavior on the contents
113of the element so long as it is one of the `block` or `span` tags.
114
115The content of a `span` element is not parsed into block-level content. In other words, the content will not be
116rendered as paragraphs, headers, etc. Only inline syntax will be rendered, such as links, strong, emphasis, etc.
117
118For example, the following:
119
120```
121<div markdown="span">
122# *Not* a header
123</div>
124```
125
126... is rendered as:
127
128``` html
129<div>
130# <em>Not</em> a header
131</div>
132```
133
134### Ignored Elements
135
136The following tags are always ignored, regardless of any `markdown` attribute: `canvas`, `math`, `option`, `pre`,
137`script`, `style`, and `textarea`. All other raw HTML tags are treated as span-level tags and are not affected by this
138extension.
139
140### Nesting
141
142When nesting multiple levels of raw HTML elements, a `markdown` attribute must be defined for each block-level
143element. For any block-level element which does not have a `markdown` attribute, everything inside that element is
144ignored, including child elements with `markdown` attributes.
145
146For example, the following:
147
148```
149<article id="my-article" markdown="1">
150# Article Title
151
152A Markdown paragraph.
153
154<section id="section-1" markdown="1">
155## Section 1 Title
156
157<p>Custom raw **HTML** which gets ignored.</p>
158
159</section>
160
161<section id="section-2" markdown="1">
162## Section 2 Title
163
164<p markdown="1">**Markdown** content.</p>
165
166</section>
167
168</article>
169```
170
171... is rendered as:
172
173```html
174<article id="my-article">
175<h1>Article Title</h1>
176<p>A Markdown paragraph.</p>
177<section id="section-1">
178<h2>Section 1 Title</h2>
179<p>Custom raw **HTML** which gets ignored.</p>
180</section>
181<section id="section-2">
182<h2>Section 2 Title</h2>
183<p><strong>Markdown</strong> content.</p>
184</section>
185</article>
186```
187
188When the value of an element's `markdown` attribute is more permissive that its parent, then the parent's stricter
189behavior is enforced. For example, a `block` element nested within a `span` element will be parsed using the `span`
190behavior. However, if the value of an element's `markdown` attribute is the same as, or more restrictive than, its
191parent, the the child element's behavior is observed. For example, a `block` element may contain either `block`
192elements or `span` elements as children and each element will be parsed using the specified behavior.
193
194### Tag Normalization
195
196While the default behavior is for Markdown to not alter raw HTML, as this extension is parsing the content of raw HTML elements, it will do some normalization of the tags of block-level elements. For example, the following raw HTML:
197
198```
199<div markdown="1">
200<p markdown="1">A Markdown paragraph with *no* closing tag.
201<p>A raw paragraph with *no* closing tag.
202</div>
203```
204
205... is rendered as:
206
207``` html
208<div>
209<p>A Markdown paragraph with <em>no</em> closing tag.
210</p>
211<p>A raw paragraph with *no* closing tag.
212</p>
213</div>
214```
215
216Notice that the parser properly recognizes that an unclosed  `<p>` tag ends when another `<p>` tag begins or when the
217parent element ends. In both cases, a closing `</p>` was added to the end of the element, regardless of whether a
218`markdown` attribute was assigned to the element.
219
220To avoid any normalization, an element must not be a descendant of any block-level element which has a `markdown`
221attribute defined.
222
223!!! warning
224
225    The normalization behavior is only documented here so that document authors are not surprised when their carefully
226    crafted raw HTML is altered by Markdown. This extension should not be relied on to normalize and generate valid
227    HTML. For the best results, always include valid raw HTML (with both opening and closing tags) in your Markdown
228    documents.
229
230## Usage
231
232From the Python interpreter:
233
234``` pycon
235>>> import markdown
236>>> html = markdown.markdown(text, extensions=['md_in_html'])
237```
238