From cd7324333a995eeb62a3e6eacdb3b179c6256133 Mon Sep 17 00:00:00 2001 From: Waylan Limberg Date: Fri, 12 Jan 2018 22:48:41 -0500 Subject: Refactor Extension loading (#627) Deprecated naming support is removed: * Removed special treatment for modules in `markdown.extensions` * Removed support for `mdx_` prefixes. Support for Entry Point names added: Support for "short names" are now implemented with entry points. Therefore all the users who call extension names as `toc` will not get errors as the builtin extensions all have entry points defined which match the old "short names" for modules in `markdown.extensions`. The benefit is that any extension can offer the same support without requiring the user to manually copy a file to that location on the file system (way to many extension authors have included such instructions in their installation documentation). The one odd thing about this is that we have been issuing a DeprecationWarning for short names and now they are fully supported again. But I think it's the right thing to do. Support for using dot notation is not removed. After all, it was never deprecated. And we shouldn't "force" entry points. There are plenty of reasons why users may not want that and not all of them can be resolved by using class instances instead. All of the following ways to load an extension are valid: # Class instance from markdown.extensions.toc import TocExtension markdown.markdown(src, extensions=[TocExtension()] # Entry point name markdown.markdown(src, extensions=['toc']) # Dot notation with class markdown.markdown(src, extensions=['markdown.extensions.toc:TocExtension']) # Dot notation without class markdown.markdown(src, extensions=['markdown.extensions.toc']) --- docs/extensions/abbreviations.md | 4 +- docs/extensions/admonition.md | 11 ++++- docs/extensions/api.md | 77 ++++++++++++++++++++++++++--------- docs/extensions/attr_list.md | 4 +- docs/extensions/code_hilite.md | 4 +- docs/extensions/definition_lists.md | 4 +- docs/extensions/extra.md | 2 +- docs/extensions/fenced_code_blocks.md | 4 +- docs/extensions/footnotes.md | 5 +-- docs/extensions/index.md | 48 +++++++++++----------- docs/extensions/meta_data.md | 6 +-- docs/extensions/nl2br.md | 6 +-- docs/extensions/sane_lists.md | 4 +- docs/extensions/smart_strong.md | 13 +++--- docs/extensions/smarty.md | 6 +-- docs/extensions/tables.md | 4 +- docs/extensions/toc.md | 6 +-- docs/extensions/wikilinks.md | 4 +- 18 files changed, 125 insertions(+), 87 deletions(-) (limited to 'docs/extensions') diff --git a/docs/extensions/abbreviations.md b/docs/extensions/abbreviations.md index d580d56..eed8788 100644 --- a/docs/extensions/abbreviations.md +++ b/docs/extensions/abbreviations.md @@ -39,7 +39,7 @@ is maintained by the W3C.

Usage ----- -See [Extensions](index.md) for general extension usage, specify `markdown.extensions.abbr` -as the name of the extension. +See [Extensions](index.md) for general extension usage. Use `abbr` as the name +of the extension. This extension does not accept any special configuration options. diff --git a/docs/extensions/admonition.md b/docs/extensions/admonition.md index 26e6299..a6a8398 100644 --- a/docs/extensions/admonition.md +++ b/docs/extensions/admonition.md @@ -78,7 +78,14 @@ rST suggests the following `types`, but you're free to use whatever you want: Styling ------- -There is no CSS included as part of this extension. Look up the default -[Sphinx][sphinx] theme if you need inspiration. +There is no CSS included as part of this extension. Check out the default +[Sphinx][sphinx] theme for inspiration. [sphinx]: http://sphinx.pocoo.org/ + +## Usage + +See [Extensions](index.md) for general extension usage. Use `admonition` as the +name of the extension. + +This extension does not accept any special configuration options. diff --git a/docs/extensions/api.md b/docs/extensions/api.md index 3d8cfff..cba4ea7 100644 --- a/docs/extensions/api.md +++ b/docs/extensions/api.md @@ -639,7 +639,7 @@ following methods available to assist in working with configuration settings: Sets multiple configuration settings given a dict of key/value pairs. -### `makeExtension` {: #makeextension } +### Naming an Extension { #naming_an_extension } 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 @@ -649,36 +649,70 @@ For example: ```python import markdown -import myextension -myext = myextension.MyExtension(option='value') -md = markdown.Markdown(extensions=[myext]) +from path.to.module import MyExtention +md = markdown.Markdown(extensions=[MyExtension(option='value')]) ``` -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). +However, 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). A "name" can either be a registered +[entry point](#entry_point) or a string using Python's [dot +notation](#dot_notation). -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. +#### Entry Point { #entry_point } + +[Entry points] are defined in a Python package's `setup.py` script. The script +must use [setuptools] to support entry points. Python-Markdown extensions must +be assigned to the `markdown.extensions` group. An entry point definition might +look like this: + +```python +from setuptools import setup + +setup( + # ... + entry_points={ + 'markdown.extensions': ['myextension = path.to.module:MyExtension'] + } +) +``` + +After a user installs your extension using the above script, they could then +call the extension using the `myextension` string name like this: + +```python +markdown.markdown(text, extensions=['myextention']) +``` + +Note that if two or more entry points within the same group are assigned the +same name, Python-Markdown will only ever use the first one found and ignore all +others. Therefore, be sure to give your extension a unique name. + +For more information on writing `setup.py` scripts, see the Python documentation +on [Packaging and Distributing Projects]. + +#### Dot Notation { #dot_notation } + +If an extension does not have a registered entry point, Python's dot notation +may be used instead. The extension must be installed as a Python module on your +PYTHONPATH. Generally, a class should be specified in the name. The class must +be at the end of the name and be separated by a colon from the module. -The string can also include the name of the class separated by a colon. Therefore, if you were to import the class like this: ```python -from path.to.module import SomeExtensionClass +from path.to.module import MyExtention ``` -Then the named extension would comprise this string: +Then the extension can be loaded as follows: ```python -"path.to.module:SomeExtensionClass" +markdown.markdown(text, extensions=['path.to.module:MyExtention']) ``` 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. +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 @@ -697,9 +731,9 @@ 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. +When Markdown is passed the "name" of your extension as a dot notation string +that does not include a class (for example `path.to.module`), it will import the +module and call the `makeExtension` function to initiate your extension. [Preprocessors]: #preprocessors [Inline Patterns]: #inlinepatterns @@ -718,3 +752,6 @@ extension. [Footnotes]: https://github.com/Python-Markdown/mdx_footnotes [Definition Lists]: https://github.com/Python-Markdown/mdx_definition_lists [library reference]: ../reference.md +[setuptools]: https://packaging.python.org/key_projects/#setuptools +[Entry points]: https://setuptools.readthedocs.io/en/latest/setuptools.html#dynamic-discovery-of-services-and-plugins +[Packaging and Distributing Projects]: https://packaging.python.org/tutorials/distributing-packages/ diff --git a/docs/extensions/attr_list.md b/docs/extensions/attr_list.md index 7b2e19f..9fc8b6e 100644 --- a/docs/extensions/attr_list.md +++ b/docs/extensions/attr_list.md @@ -92,7 +92,7 @@ The above results in the following output: ## Usage -See [Extensions](index.md) for general extension usage, specify -`markdown.extensions.attr_list` as the name of the extension. +See [Extensions](index.md) for general extension usage. Use `attr_list` as the +name of the extension. This extension does not accept any special configuration options. diff --git a/docs/extensions/code_hilite.md b/docs/extensions/code_hilite.md index 6490dcc..552a82d 100644 --- a/docs/extensions/code_hilite.md +++ b/docs/extensions/code_hilite.md @@ -168,8 +168,8 @@ Lets see the source for that: ## Usage -See [Extensions](index.md) for general extension usage, specify -`markdown.extensions.codehilite` as the name of the extension. +See [Extensions](index.md) for general extension usage. Use `codehilite` as the +name of the extension. See the [Library Reference](../reference.md#extensions) for information about configuring extensions. diff --git a/docs/extensions/definition_lists.md b/docs/extensions/definition_lists.md index e9f8984..0d42fd0 100644 --- a/docs/extensions/definition_lists.md +++ b/docs/extensions/definition_lists.md @@ -46,7 +46,7 @@ the family Rosaceae. Usage ----- -See [Extensions](index.md) for general extension usage, specify -`markdown.extensions.def_list` as the name of the extension. +See [Extensions](index.md) for general extension usage. Use `def_list` as the +name of the extension. This extension does not accept any special configuration options. diff --git a/docs/extensions/extra.md b/docs/extensions/extra.md index 0639d3d..3d9f374 100644 --- a/docs/extensions/extra.md +++ b/docs/extensions/extra.md @@ -26,7 +26,7 @@ From the Python interpreter: ```pycon >>> import markdown ->>> html = markdown.markdown(text, ['markdown.extensions.extra']) +>>> html = markdown.markdown(text, ['extra']) ``` There may be [additional extensions](index.md) that are distributed with diff --git a/docs/extensions/fenced_code_blocks.md b/docs/extensions/fenced_code_blocks.md index b7a657e..96fe786 100644 --- a/docs/extensions/fenced_code_blocks.md +++ b/docs/extensions/fenced_code_blocks.md @@ -110,7 +110,7 @@ The lines can be specified with PHP Extra's syntax: ## Usage -See [Extensions](index.md) for general extension usage, specify -`markdown.extensions.fenced_code` as the name of the extension. +See [Extensions](index.md) for general extension usage. Use `fenced_code` as +the name of the extension. This extension does not accept any special configuration options. diff --git a/docs/extensions/footnotes.md b/docs/extensions/footnotes.md index aaff184..4df12a1 100644 --- a/docs/extensions/footnotes.md +++ b/docs/extensions/footnotes.md @@ -63,8 +63,8 @@ is indented consistently and any errors are more easily discernible by the autho Usage ----- -See [Extensions](index.md) for general extension usage, specify -`markdown.extensions.footnotes` as the name of the extension. +See [Extensions](index.md) for general extension usage. Use `footnotes` as the +name of the extension. See the [Library Reference](../reference.md#extensions) for information about configuring extensions. @@ -90,4 +90,3 @@ The following options are provided to configure the output: The text string for the `title` HTML attribute of the footnote definition link. `%d` will be replaced by the footnote number. Defaults to `Jump back to footnote %d in the text` - diff --git a/docs/extensions/index.md b/docs/extensions/index.md index 34f8084..3d98760 100644 --- a/docs/extensions/index.md +++ b/docs/extensions/index.md @@ -1,7 +1,6 @@ title: Extensions -Available Extensions -==================== +# Extensions Python Markdown offers a flexible extension mechanism, which makes it possible to change and/or extend the behavior of the parser without having to edit the @@ -10,7 +9,7 @@ actual source files. To use an extension, pass it to markdown with the `extensions` keyword. ```python -markdown.markdown(some_text, extensions=[MyExtension(), 'path.to.my.ext', 'markdown.extensions.footnotes']) +markdown.markdown(some_text, extensions=[MyExtClass(), 'myext', 'path.to.my.ext:MyExtClass']) ``` See the [Library Reference](../reference.md#extensions) for more details. @@ -18,7 +17,7 @@ See the [Library Reference](../reference.md#extensions) for more details. From the command line, specify an extension with the `-x` option. ```bash -python -m markdown -x markdown.extensions.footnotes -x markdown.extensions.tables input.txt > output.html +python -m markdown -x myext -x path.to.module:MyExtClass input.txt > output.html ``` See the [Command Line docs](../cli.md) or use the `--help` option for more details. @@ -34,27 +33,26 @@ The extensions listed below are included with (at least) the most recent release and are officially supported by Python-Markdown. Any documentation is maintained here and all bug reports should be made to the project. If you have a typical install of Python-Markdown, these extensions are already -available to you using the "name" listed in the second column below. - -Extension | "Name" ------------------------------------- | --------------- -[Extra] | `markdown.extensions.extra` -    [Abbreviations][] | `markdown.extensions.abbr` -    [Attribute Lists][] | `markdown.extensions.attr_list` -    [Definition Lists][] | `markdown.extensions.def_list` -    [Fenced Code Blocks][] | `markdown.extensions.fenced_code` -    [Footnotes][] | `markdown.extensions.footnotes` -    [Tables][] | `markdown.extensions.tables` -    [Smart Strong][] | `markdown.extensions.smart_strong` -[Admonition][] | `markdown.extensions.admonition` -[CodeHilite][] | `markdown.extensions.codehilite` -[HeaderId] | `markdown.extensions.headerid` -[Meta-Data] | `markdown.extensions.meta` -[New Line to Break] | `markdown.extensions.nl2br` -[Sane Lists] | `markdown.extensions.sane_lists` -[SmartyPants] | `markdown.extensions.smarty` -[Table of Contents] | `markdown.extensions.toc` -[WikiLinks] | `markdown.extensions.wikilinks` +available to you using the "Entry Point" name listed in the second column below. + +Extension | Entry Point | Dot Notation +------------------------------------ | -------------- | ------------ +[Extra] | `extra` | `markdown.extensions.extra` +    [Abbreviations][] | `abbr` | `markdown.extensions.abbr` +    [Attribute Lists][] | `attr_list` | `markdown.extensions.attr_list` +    [Definition Lists][] | `def_list` | `markdown.extensions.def_list` +    [Fenced Code Blocks][] | `fenced_code` | `markdown.extensions.fenced_code` +    [Footnotes][] | `footnotes` | `markdown.extensions.footnotes` +    [Tables][] | `tables` | `markdown.extensions.tables` +    [Smart Strong][] | `smart_strong` | `markdown.extensions.smart_strong` +[Admonition][] | `admonition` | `markdown.extensions.admonition` +[CodeHilite][] | `codehilite` | `markdown.extensions.codehilite` +[Meta-Data] | `meta` | `markdown.extensions.meta` +[New Line to Break] | `nl2br` | `markdown.extensions.nl2br` +[Sane Lists] | `sane_lists` | `markdown.extensions.sane_lists` +[SmartyPants] | `smarty` | `markdown.extensions.smarty` +[Table of Contents] | `toc` | `markdown.extensions.toc` +[WikiLinks] | `wikilinks` | `markdown.extensions.wikilinks` [Extra]: extra.md [Abbreviations]: abbreviations.md diff --git a/docs/extensions/meta_data.md b/docs/extensions/meta_data.md index 36d5e7a..29f3e0b 100644 --- a/docs/extensions/meta_data.md +++ b/docs/extensions/meta_data.md @@ -57,8 +57,8 @@ by Markdown. Usage ----- -See [Extensions](index.md) for general extension usage, specify -`markdown.extensions.meta` as the name of the extension. +See [Extensions](index.md) for general extension usage. Use `meta` as the name +of the extension. Accessing the Meta-Data ----------------------- @@ -67,7 +67,7 @@ The meta-data is made available as a python Dict in the `Meta` attribute of an instance of the Markdown class. For example, using the above document: ```pycon ->>> md = markdown.Markdown(extensions = ['markdown.extensions.meta']) +>>> md = markdown.Markdown(extensions = ['meta']) >>> html = md.convert(text) >>> # Meta-data has been stripped from output >>> print html diff --git a/docs/extensions/nl2br.md b/docs/extensions/nl2br.md index 4f5e611..8c53d33 100644 --- a/docs/extensions/nl2br.md +++ b/docs/extensions/nl2br.md @@ -20,7 +20,7 @@ Example ... Line 1 ... Line 2 ... """ ->>> html = markdown.markdown(text, extensions=['markdown.extensions.nl2br']) +>>> html = markdown.markdown(text, extensions=['nl2br']) >>> print html

Line 1
Line 2

@@ -29,7 +29,7 @@ Line 2

Usage ----- -See [Extensions](index.md) for general extension usage, specify -`markdown.extensions.nl2br` as the name of the extension. +See [Extensions](index.md) for general extension usage. Use `nl2br` as the name +of the extension. This extension does not accept any special configuration options. diff --git a/docs/extensions/sane_lists.md b/docs/extensions/sane_lists.md index 49a7a85..81f8d84 100644 --- a/docs/extensions/sane_lists.md +++ b/docs/extensions/sane_lists.md @@ -71,7 +71,7 @@ In all other ways, Sane Lists should behave as normal Markdown lists. Usage ----- -See [Extensions](index.md) for general extension usage, specify -`markdown.extensions.sane_lists` as the name of the extension. +See [Extensions](index.md) for general extension usage. Use `sane_lists` as the +name of the extension. This extension does not accept any special configuration options. diff --git a/docs/extensions/smart_strong.md b/docs/extensions/smart_strong.md index 1fb3c68..65c88d6 100644 --- a/docs/extensions/smart_strong.md +++ b/docs/extensions/smart_strong.md @@ -19,21 +19,18 @@ Example ```pycon >>> import markdown ->>> markdown.markdown('Text with double__underscore__words.', \ - extensions=['markdown.extensions.smart_strong']) +>>> markdown.markdown('Text with double__underscore__words.', extensions=['smart_strong']) u'

Text with double__underscore__words.

' ->>> markdown.markdown('__Strong__ still works.', \ - extensions=['markdown.extensions.smart_strong']) +>>> markdown.markdown('__Strong__ still works.', extensions=['smart_strong']) u'

Strong still works.

' ->>> markdown.markdown('__this__works__too__.', \ - extensions=['markdown.extensions.smart_strong']) +>>> markdown.markdown('__this__works__too__.', extensions=['smart_strong']) u'

this__works__too.

' ``` Usage ----- -See [Extensions](index.md) for general extension usage, specify -`markdown.extensions.smart_strong` as the name of the extension. +See [Extensions](index.md) for general extension usage. Use `smart_strong` as +the name of the extension. This extension does not accept any special configuration options. diff --git a/docs/extensions/smarty.md b/docs/extensions/smarty.md index 9353d9b..109d78c 100644 --- a/docs/extensions/smarty.md +++ b/docs/extensions/smarty.md @@ -27,7 +27,7 @@ the German language: ```python extension_configs = { - 'markdown.extensions.smarty': { + 'smarty': { 'substitutions': { 'left-single-quote': '‚', # sb is not a typo! 'right-single-quote': '‘', @@ -53,8 +53,8 @@ extension_configs = { Usage ----- -See [Extensions](index.md) for general extension usage, specify -`markdown.extensions.smarty` as the name of the extension. +See [Extensions](index.md) for general extension usage. Use `smarty` as the +name of the extension. See the [Library Reference](../reference.md#extensions) for information about configuring extensions. diff --git a/docs/extensions/tables.md b/docs/extensions/tables.md index 2bea470..59693f0 100644 --- a/docs/extensions/tables.md +++ b/docs/extensions/tables.md @@ -52,7 +52,7 @@ will be rendered as: Usage ----- -See [Extensions](index.md) for general extension usage, specify -`markdown.extensions.tables` as the name of the extension. +See [Extensions](index.md) for general extension usage. Use `tables` as the +name of the extension. This extension does not accept any special configuration options. diff --git a/docs/extensions/toc.md b/docs/extensions/toc.md index a1c583f..e358132 100644 --- a/docs/extensions/toc.md +++ b/docs/extensions/toc.md @@ -65,7 +65,7 @@ This allows one to insert the Table of Contents elsewhere in their page template. For example: ```pycon ->>> md = markdown.Markdown(extensions=['markdown.extensions.toc']) +>>> md = markdown.Markdown(extensions=['toc']) >>> html = md.convert(text) >>> page = render_some_template(context={'body': html, 'toc': md.toc}) ``` @@ -73,8 +73,8 @@ template. For example: Usage ----- -See [Extensions](index.md) for general extension usage, specify `markdown.extensions.toc` -as the name of the extension. +See [Extensions](index.md) for general extension usage. Use `toc` as the name +of the extension. See the [Library Reference](../reference.md#extensions) for information about configuring extensions. diff --git a/docs/extensions/wikilinks.md b/docs/extensions/wikilinks.md index a46265a..dd82a96 100644 --- a/docs/extensions/wikilinks.md +++ b/docs/extensions/wikilinks.md @@ -46,8 +46,8 @@ becomes ## Usage -See [Extensions](index.md) for general extension usage, specify -`markdown.extensions.wikilinks` as the name of the extension. +See [Extensions](index.md) for general extension usage. Use `wikilinks` as the +name of the extension. See the [Library Reference](../reference.md#extensions) for information about configuring extensions. -- cgit v1.2.3