/usr/share/doc/python-markdown-doc/docs/extensions/api.txt is in python-markdown-doc 2.6.9-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 | title: Extensions API
prev_title: WikiLinks Extension
prev_url: wikilinks.html
next_title: Test Suite
next_url: ../test_suite.html
Writing Extensions for Python-Markdown
======================================
Python-Markdown includes an API for extension writers to plug their own
custom functionality and/or syntax into the parser. There are Preprocessors
which allow you to alter the source before it is passed to the parser,
inline patterns which allow you to add, remove or override the syntax of
any inline elements, and Postprocessors which allow munging of the
output of the parser before it is returned. If you really want to dive in,
there are also Blockprocessors which are part of the core BlockParser.
As the parser builds an [ElementTree][ElementTree] object which is later rendered
as Unicode text, there are also some helpers provided to ease manipulation of
the tree. Each part of the API is discussed in its respective section below.
Additionally, reading the source of some [Available Extensions][] may be
helpful. For example, the [Footnotes][] extension uses most of the features
documented here.
Preprocessors {: #preprocessors }
---------------------------------
Preprocessors munge the source text before it is passed into the Markdown
core. This is an excellent place to clean up bad syntax, extract things the
parser may otherwise choke on and perhaps even store it for later retrieval.
Preprocessors should inherit from `markdown.preprocessors.Preprocessor` and
implement a `run` method with one argument `lines`. The `run` method of
each Preprocessor will be passed the entire source text as a list of Unicode
strings. Each string will contain one line of text. The `run` method should
return either that list, or an altered list of Unicode strings.
A pseudo example:
from markdown.preprocessors import Preprocessor
class MyPreprocessor(Preprocessor):
def run(self, lines):
new_lines = []
for line in lines:
m = MYREGEX.match(line)
if m:
# do stuff
else:
new_lines.append(line)
return new_lines
Inline Patterns {: #inlinepatterns }
------------------------------------
Inline Patterns implement the inline HTML element syntax for Markdown such as
`*emphasis*` or `[links](http://example.com)`. Pattern objects should be
instances of classes that inherit from `markdown.inlinepatterns.Pattern` or
one of its children. Each pattern object uses a single regular expression and
must have the following methods:
* **`getCompiledRegExp()`**:
Returns a compiled regular expression.
* **`handleMatch(m)`**:
Accepts a match object and returns an ElementTree element of a plain
Unicode string.
Note that any regular expression returned by `getCompiledRegExp` must capture
the whole block. Therefore, they should all start with `r'^(.*?)'` and end
with `r'(.*?)!'`. When using the default `getCompiledRegExp()` method
provided in the `Pattern` you can pass in a regular expression without that
and `getCompiledRegExp` will wrap your expression for you and set the
`re.DOTALL` and `re.UNICODE` flags. This means that the first group of your
match will be `m.group(2)` as `m.group(1)` will match everything before the
pattern.
For an example, consider this simplified emphasis pattern:
from markdown.inlinepatterns import Pattern
from markdown.util import etree
class EmphasisPattern(Pattern):
def handleMatch(self, m):
el = etree.Element('em')
el.text = m.group(3)
return el
As discussed in [Integrating Your Code Into Markdown][], an instance of this
class will need to be provided to Markdown. That instance would be created
like so:
# an oversimplified regex
MYPATTERN = r'\*([^*]+)\*'
# pass in pattern and create instance
emphasis = EmphasisPattern(MYPATTERN)
Actually it would not be necessary to create that pattern (and not just because
a more sophisticated emphasis pattern already exists in Markdown). The fact is,
that example pattern is not very DRY. A pattern for `**strong**` text would
be almost identical, with the exception that it would create a 'strong' element.
Therefore, Markdown provides a number of generic pattern classes that can
provide some common functionality. For example, both emphasis and strong are
implemented with separate instances of the `SimpleTagPattern` listed below.
Feel free to use or extend any of the Pattern classes found at
`markdown.inlinepatterns`.
**Generic Pattern Classes**
* **`SimpleTextPattern(pattern)`**:
Returns simple text of `group(2)` of a `pattern`.
* **`SimpleTagPattern(pattern, tag)`**:
Returns an element of type "`tag`" with a text attribute of `group(3)`
of a `pattern`. `tag` should be a string of a HTML element (i.e.: 'em').
* **`SubstituteTagPattern(pattern, tag)`**:
Returns an element of type "`tag`" with no children or text (i.e.: `br`).
There may be other Pattern classes in the Markdown source that you could extend
or use as well. Read through the source and see if there is anything you can
use. You might even get a few ideas for different approaches to your specific
situation.
Treeprocessors {: #treeprocessors }
-----------------------------------
Treeprocessors manipulate an ElementTree object after it has passed through the
core BlockParser. This is where additional manipulation of the tree takes
place. Additionally, the InlineProcessor is a Treeprocessor which steps through
the tree and runs the Inline Patterns on the text of each Element in the tree.
A Treeprocessor should inherit from `markdown.treeprocessors.Treeprocessor`,
over-ride the `run` method which takes one argument `root` (an ElementTree
object) and either modifies that root element and returns `None` or returns a
new ElementTree object.
A pseudo example:
from markdown.treeprocessors import Treeprocessor
class MyTreeprocessor(Treeprocessor):
def run(self, root):
root.text = 'modified content'
Note that Python class methods return `None` by default when no `return`
statement is defined. Additionally all Python variables refer to objects by
reference. Therefore, the above `run` method modifies the `root` element
in place and returns `None`. The changes made to the `root` element and its
children are retained.
Some may be inclined to return the modified `root` element. While that would
work, it would cause a copy of the entire ElementTree to be generated each
time the Treeprocessor is run. Therefore, it is generally expected that
the `run` method would only return `None` or a new ElementTree object.
For specifics on manipulating the ElementTree, see
[Working with the ElementTree][workingwithetree] below.
Postprocessors {: #postprocessors }
-----------------------------------
Postprocessors manipulate the document after the ElementTree has been
serialized into a string. Postprocessors should be used to work with the
text just before output.
A Postprocessor should inherit from `markdown.postprocessors.Postprocessor`
and over-ride the `run` method which takes one argument `text` and returns
a Unicode string.
Postprocessors are run after the ElementTree has been serialized back into
Unicode text. For example, this may be an appropriate place to add a table of
contents to a document:
from markdown.postprocessors import Postprocessor
class TocPostprocessor(Postprocessor):
def run(self, text):
return MYMARKERRE.sub(MyToc, text)
BlockParser {: #blockparser }
-----------------------------
Sometimes, Preprocessors, Treeprocessors, Postprocessors, and Inline Patterns
are not going to do what you need. Perhaps you want a new type of block type
that needs to be integrated into the core parsing. In such a situation, you can
add/change/remove functionality of the core `BlockParser`. The BlockParser is
composed of a number of Blockprocessors. The BlockParser steps through each
block of text (split by blank lines) and passes each block to the appropriate
Blockprocessor. That Blockprocessor parses the block and adds it to the
ElementTree. The
[Definition Lists][] extension would be a good example of an extension that
adds/modifies Blockprocessors.
A Blockprocessor should inherit from `markdown.blockprocessors.BlockProcessor`
and implement both the `test` and `run` methods.
The `test` method is used by BlockParser to identify the type of block.
Therefore the `test` method must return a Boolean value. If the test returns
`True`, then the BlockParser will call that Blockprocessor's `run` method.
If it returns `False`, the BlockParser will move on to the next
Blockprocessor.
The **`test`** method takes two arguments:
* **`parent`**: The parent ElementTree Element of the block. This can be useful
as the block may need to be treated differently if it is inside a list, for
example.
* **`block`**: A string of the current block of text. The test may be a
simple string method (such as `block.startswith(some_text)`) or a complex
regular expression.
The **`run`** method takes two arguments:
* **`parent`**: A pointer to the parent ElementTree Element of the block. The run
method will most likely attach additional nodes to this parent. Note that
nothing is returned by the method. The ElementTree object is altered in place.
* **`blocks`**: A list of all remaining blocks of the document. Your run
method must remove (pop) the first block from the list (which it altered in
place - not returned) and parse that block. You may find that a block of text
legitimately contains multiple block types. Therefore, after processing the
first type, your processor can insert the remaining text into the beginning
of the `blocks` list for future parsing.
Please be aware that a single block can span multiple text blocks. For example,
The official Markdown syntax rules state that a blank line does not end a
Code Block. If the next block of text is also indented, then it is part of
the previous block. Therefore, the BlockParser was specifically designed to
address these types of situations. If you notice the `CodeBlockProcessor`,
in the core, you will note that it checks the last child of the `parent`.
If the last child is a code block (`<pre><code>...</code></pre>`), then it
appends that block to the previous code block rather than creating a new
code block.
Each Blockprocessor has the following utility methods available:
* **`lastChild(parent)`**:
Returns the last child of the given ElementTree Element or `None` if it
had no children.
* **`detab(text)`**:
Removes one level of indent (four spaces by default) from the front of each
line of the given text string.
* **`looseDetab(text, level)`**:
Removes "level" levels of indent (defaults to 1) from the front of each line
of the given text string. However, this methods allows secondary lines to
not be indented as does some parts of the Markdown syntax.
Each Blockprocessor also has a pointer to the containing BlockParser instance at
`self.parser`, which can be used to check or alter the state of the parser.
The BlockParser tracks it's state in a stack at `parser.state`. The state
stack is an instance of the `State` class.
**`State`** is a subclass of `list` and has the additional methods:
* **`set(state)`**:
Set a new state to string `state`. The new state is appended to the end
of the stack.
* **`reset()`**:
Step back one step in the stack. The last state at the end is removed from
the stack.
* **`isstate(state)`**:
Test that the top (current) level of the stack is of the given string
`state`.
Note that to ensure that the state stack does not become corrupted, each time a
state is set for a block, that state *must* be reset when the parser finishes
parsing that block.
An instance of the **`BlockParser`** is found at `Markdown.parser`.
`BlockParser` has the following methods:
* **`parseDocument(lines)`**:
Given a list of lines, an ElementTree object is returned. This should be
passed an entire document and is the only method the `Markdown` class
calls directly.
* **`parseChunk(parent, text)`**:
Parses a chunk of markdown text composed of multiple blocks and attaches
those blocks to the `parent` Element. The `parent` is altered in place
and nothing is returned. Extensions would most likely use this method for
block parsing.
* **`parseBlocks(parent, blocks)`**:
Parses a list of blocks of text and attaches those blocks to the `parent`
Element. The `parent` is altered in place and nothing is returned. This
method will generally only be used internally to recursively parse nested
blocks of text.
While is is not recommended, an extension could subclass or completely replace
the `BlockParser`. The new class would have to provide the same public API.
However, be aware that other extensions may expect the core parser provided
and will not work with such a drastically different parser.
Working with the ElementTree {: #working_with_et }
--------------------------------------------------
As mentioned, the Markdown parser converts a source document to an
[ElementTree][ElementTree] object before serializing that back to Unicode text.
Markdown has provided some helpers to ease that manipulation within the context
of the Markdown module.
First, to get access to the ElementTree module import ElementTree from
`markdown` rather than importing it directly. This will ensure you are using
the same version of ElementTree as markdown. The module is found at
`markdown.util.etree` within Markdown.
from markdown.util import etree
`markdown.util.etree` tries to import ElementTree from any known location,
first as a standard library module (from `xml.etree` in Python 2.5), then as
a third party package (ElementTree). In each instance, `cElementTree` is
tried first, then ElementTree if the faster C implementation is not
available on your system.
Sometimes you may want text inserted into an element to be parsed by
[Inline Patterns][]. In such a situation, simply insert the text as you normally
would and the text will be automatically run through the Inline Patterns.
However, if you do *not* want some text to be parsed by Inline Patterns,
then insert the text as an `AtomicString`.
from markdown.util import AtomicString
some_element.text = AtomicString(some_text)
Here's a basic example which creates an HTML table (note that the contents of
the second cell (`td2`) will be run through Inline Patterns latter):
table = etree.Element("table")
table.set("cellpadding", "2") # Set cellpadding to 2
tr = etree.SubElement(table, "tr") # Add child tr to table
td1 = etree.SubElement(tr, "td") # Add child td1 to tr
td1.text = markdown.util.AtomicString("Cell content") # Add plain text content
td2 = etree.SubElement(tr, "td") # Add second td to tr
td2.text = "*text* with **inline** formatting." # Add markup text
table.tail = "Text after table" # Add text after table
You can also manipulate an existing tree. Consider the following example which
adds a `class` attribute to `<a>` elements:
def set_link_class(self, element):
for child in element:
if child.tag == "a":
child.set("class", "myclass") #set the class attribute
set_link_class(child) # run recursively on children
For more information about working with ElementTree see the ElementTree
[Documentation](http://effbot.org/zone/element-index.htm)
([Python Docs](http://docs.python.org/lib/module-xml.etree.ElementTree.html)).
Integrating Your Code Into Markdown {: #integrating_into_markdown }
-------------------------------------------------------------------
Once you have the various pieces of your extension built, you need to tell
Markdown about them and ensure that they are run in the proper sequence.
Markdown accepts an `Extension` instance for each extension. Therefore, you
will need to define a class that extends `markdown.extensions.Extension` and
over-rides the `extendMarkdown` method. Within this class you will manage
configuration options for your extension and attach the various processors and
patterns to the Markdown instance.
It is important to note that the order of the various processors and patterns
matters. For example, if we replace `http://...` links with `<a>` elements,
and *then* try to deal with inline HTML, we will end up with a mess.
Therefore, the various types of processors and patterns are stored within an
instance of the Markdown class in [OrderedDict][]s. Your `Extension` class
will need to manipulate those OrderedDicts appropriately. You may insert
instances of your processors and patterns into the appropriate location in an
OrderedDict, remove a built-in instance, or replace a built-in instance with
your own.
### `extendMarkdown` {: #extendmarkdown }
The `extendMarkdown` method of a `markdown.extensions.Extension` class
accepts two arguments:
* **`md`**:
A pointer to the instance of the Markdown class. You should use this to
access the [OrderedDict][]s of processors and patterns. They are found
under the following attributes:
* `md.preprocessors`
* `md.inlinePatterns`
* `md.parser.blockprocessors`
* `md.treeprocessors`
* `md.postprocessors`
Some other things you may want to access in the markdown instance are:
* `md.htmlStash`
* `md.output_formats`
* `md.set_output_format()`
* `md.output_format`
* `md.serializer`
* `md.registerExtension()`
* `md.html_replacement_text`
* `md.tab_length`
* `md.enable_attributes`
* `md.smart_emphasis`
* **`md_globals`**:
Contains all the various global variables within the markdown module.
!!! Warning
With access to the above items, theoretically you have the option to
change anything through various [monkey_patching][] techniques. However,
you should be aware that the various undocumented parts of markdown may
change without notice and your monkey_patches may break with a new release.
Therefore, what you really should be doing is inserting processors and
patterns into the markdown pipeline. Consider yourself warned!
[monkey_patching]: http://en.wikipedia.org/wiki/Monkey_patch
A simple example:
from markdown.extensions import Extension
class MyExtension(Extension):
def extendMarkdown(self, md, md_globals):
# Insert instance of 'mypattern' before 'references' pattern
md.inlinePatterns.add('mypattern', MyPattern(md), '<references')
### OrderedDict {: #ordereddict }
An OrderedDict is a dictionary like object that retains the order of it's
items. The items are ordered in the order in which they were appended to
the OrderedDict. However, an item can also be inserted into the OrderedDict
in a specific location in relation to the existing items.
Think of OrderedDict as a combination of a list and a dictionary as it has
methods common to both. For example, you can get and set items using the
`od[key] = value` syntax and the methods `keys()`, `values()`, and
`items()` work as expected with the keys, values and items returned in the
proper order. At the same time, you can use `insert()`, `append()`, and
`index()` as you would with a list.
Generally speaking, within Markdown extensions you will be using the special
helper method `add()` to add additional items to an existing OrderedDict.
The `add()` method accepts three arguments:
* **`key`**: A string. The key is used for later reference to the item.
* **`value`**: The object instance stored in this item.
* **`location`**: The items location in relation to other items.
Note that the location can consist of a few different values:
* The special strings `"_begin"` and `"_end"` insert that item at the
beginning or end of the OrderedDict respectively.
* A less-than sign (`<`) followed by an existing key (i.e.:
`"<somekey"`) inserts that item before the existing key.
* A greater-than sign (`>`) followed by an existing key (i.e.:
`">somekey"`) inserts that item after the existing key.
Consider the following example:
>>> from markdown.odict import OrderedDict
>>> od = OrderedDict()
>>> od['one'] = 1 # The same as: od.add('one', 1, '_begin')
>>> od['three'] = 3 # The same as: od.add('three', 3, '>one')
>>> od['four'] = 4 # The same as: od.add('four', 4, '_end')
>>> od.items()
[("one", 1), ("three", 3), ("four", 4)]
Note that when building an OrderedDict in order, the extra features of the
`add` method offer no real value and are not necessary. However, when
manipulating an existing OrderedDict, `add` can be very helpful. So let's
insert another item into the OrderedDict.
>>> od.add('two', 2, '>one') # Insert after 'one'
>>> od.values()
[1, 2, 3, 4]
Now let's insert another item.
>>> od.add('two-point-five', 2.5, '<three') # Insert before 'three'
>>> od.keys()
["one", "two", "two-point-five", "three", "four"]
Note that we also could have set the location of "two-point-five" to be 'after two'
(i.e.: `'>two'`). However, it's unlikely that you will have control over the
order in which extensions will be loaded, and this could affect the final
sorted order of an OrderedDict. For example, suppose an extension adding
"two-point-five" in the above examples was loaded before a separate extension
which adds 'two'. You may need to take this into consideration when adding your
extension components to the various markdown OrderedDicts.
Once an OrderedDict is created, the items are available via key:
MyNode = od['somekey']
Therefore, to delete an existing item:
del od['somekey']
To change the value of an existing item (leaving location unchanged):
od['somekey'] = MyNewObject()
To change the location of an existing item:
t.link('somekey', '<otherkey')
### registerExtension {: #registerextension }
Some extensions may need to have their state reset between multiple runs of the
Markdown class. For example, consider the following use of the [Footnotes][]
extension:
md = markdown.Markdown(extensions=['footnotes'])
html1 = md.convert(text_with_footnote)
md.reset()
html2 = md.convert(text_without_footnote)
Without calling `reset`, the footnote definitions from the first document will
be inserted into the second document as they are still stored within the class
instance. Therefore the `Extension` class needs to define a `reset` method
that will reset the state of the extension (i.e.: `self.footnotes = {}`).
However, as many extensions do not have a need for `reset`, `reset` is only
called on extensions that are registered.
To register an extension, call `md.registerExtension` from within your
`extendMarkdown` method:
def extendMarkdown(self, md, md_globals):
md.registerExtension(self)
# insert processors and patterns here
Then, each time `reset` is called on the Markdown instance, the `reset`
method of each registered extension will be called as well. You should also
note that `reset` will be called on each registered extension after it is
initialized the first time. Keep that in mind when over-riding the extension's
`reset` method.
### Configuration Settings {: #configsettings }
If an extension uses any parameters that the user may want to change,
those parameters should be stored in `self.config` of your
`markdown.extensions.Extension` class in the following format:
class MyExtension(markdown.extensions.Extension):
def __init__(self, **kwargs):
self.config = {'option1' : ['value1', 'description1'],
'option2' : ['value2', 'description2'] }
super(MyExtension, self).__init__(**kwargs)
When implemented this way the configuration parameters can be over-ridden at
run time (thus the call to `super`). For example:
markdown.Markdown(extensions=[MyExtension(option1='other value'])
Note that if a keyword is passed in that is not already defined in
`self.config`, then a `KeyError` is raised.
The `markdown.extensions.Extension` class and its subclasses have the
following methods available to assist in working with configuration settings:
* **`getConfig(key [, default])`**:
Returns the stored value for the given `key` or `default` if the `key`
does not exist. If not set, `default` returns an empty string.
* **`getConfigs()`**:
Returns a dict of all key/value pairs.
* **`getConfigInfo()`**:
Returns all configuration descriptions as a list of tuples.
* **`setConfig(key, value)`**:
Sets a configuration setting for `key` with the given `value`. If `key` is
unknown, a `KeyError` is raised. If the previous value of `key` was
a Boolean value, then `value` is converted to a Boolean value. If
the previous value of `key` is `None`, then `value` is converted to
a Boolean value except when it is `None`. No conversion takes place
when the previous value of `key` is a string.
* **`setConfigs(items)`**:
Sets multiple configuration settings given a dict of key/value pairs.
### `makeExtension` {: #makeextension }
As noted in the [library reference] an instance of an extension can be passed
directly to Markdown. In fact, this is the preferred way to use third-party
extensions.
For example:
import markdown
import myextension
myext = myextension.MyExtension(option='value')
md = markdown.Markdown(extensions=[myext])
Markdown also accepts "named" third party extensions for those occasions
when it is impractical to import an extension directly (from the command line or from
within templates).
The "name" of your extension must be a string consisting of the importable path to
your module using Python's dot notation. Therefore, if you are providing a library
to your users and would like to include a custom markdown extension within your
library, that extension would be named `"mylib.mdext.myext"` where `mylib/mdext/myext.py`
contains the extension and the `mylib` directory is on the PYTHONPATH.
The string can also include the name of the class separated by a colon.
Therefore, if you were to import the class like this:
from path.to.module import SomeExtensionClass
Then the named extension would comprise this string:
"path.to.module:SomeExtensionClass"
You do not need to do anything special to support this feature. As long as your
extension class is able to be imported, a user can include it with the above syntax.
The above two methods are especially useful if you need to implement a large number of
extensions with more than one residing in a module. However, if you do not want to require
that your users include the class name in their string, you must define only one extension
per module and that module must contain a module-level function called `makeExtension`
that accepts `**kwargs` and returns an extension instance.
For example:
class MyExtension(markdown.extensions.Extension)
# Define extension here...
def makeExtension(**kwargs):
return MyExtension(**kwargs)
When Markdown is passed the "name" of your extension as a dot notation string, it will import
the module and call the `makeExtension` function to initiate your extension.
[Preprocessors]: #preprocessors
[Inline Patterns]: #inlinepatterns
[Treeprocessors]: #treeprocessors
[Postprocessors]: #postprocessors
[BlockParser]: #blockparser
[workingwithetree]: #working_with_et
[Integrating your code into Markdown]: #integrating_into_markdown
[extendMarkdown]: #extendmarkdown
[OrderedDict]: #ordereddict
[registerExtension]: #registerextension
[Config Settings]: #configsettings
[makeExtension]: #makeextension
[ElementTree]: http://effbot.org/zone/element-index.htm
[Available Extensions]: index.html
[Footnotes]: footnotes.html
[Definition Lists]: definition_lists.html
[library reference]: ../reference.html
|