aboutsummaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
authorWaylan Limberg <waylan.limberg@icloud.com>2018-08-02 14:51:16 -0400
committerWaylan Limberg <waylan.limberg@icloud.com>2018-08-03 19:18:34 -0400
commit833574a9da27874614f7184f85f7993a539f3df1 (patch)
tree0870c17b8cb5deedee5dbd13f02469d2cc92c455 /docs
parent1e7fd3f236f63f9ca9b85de9cd172b77e7f9be80 (diff)
downloadmarkdown-833574a9da27874614f7184f85f7993a539f3df1.tar.gz
markdown-833574a9da27874614f7184f85f7993a539f3df1.tar.bz2
markdown-833574a9da27874614f7184f85f7993a539f3df1.zip
Update 3.0 release notes
And other docs cleanup.
Diffstat (limited to 'docs')
-rw-r--r--docs/authors.md28
-rw-r--r--docs/change_log/index.md3
-rw-r--r--docs/change_log/release-2.1.md7
-rw-r--r--docs/change_log/release-3.0.md206
-rw-r--r--docs/cli.md2
-rw-r--r--docs/extensions/api.md164
-rw-r--r--docs/extensions/code_hilite.md9
-rw-r--r--docs/extensions/extra.md1
-rw-r--r--docs/extensions/fenced_code_blocks.md4
-rw-r--r--docs/extensions/index.md6
-rw-r--r--docs/extensions/legacy_attr.md59
-rw-r--r--docs/extensions/legacy_em.md25
-rw-r--r--docs/extensions/sane_lists.md21
-rw-r--r--docs/extensions/smart_strong.md36
-rw-r--r--docs/extensions/smarty.md2
-rw-r--r--docs/index.md11
-rw-r--r--docs/reference.md27
17 files changed, 421 insertions, 190 deletions
diff --git a/docs/authors.md b/docs/authors.md
index 658707d..ba674c3 100644
--- a/docs/authors.md
+++ b/docs/authors.md
@@ -3,13 +3,24 @@ title: Authors
Primary Authors
===============
-* __[Waylan Limberg](http://achinghead.com/)__
+* __[Waylan Limberg](https://github.com/waylan)__
- Waylan is the current maintainer of the code and has written much of the
- current code base, included a complete refactor of the core. He started out
- by authoring many of the available extensions and later was asked to join
- Yuri, where he began fixing numerous bugs, adding documentation and making
- general improvements to the existing code base.
+ @waylan is the current maintainer of the code and has written much of the
+ current code base, included a complete refactor of the core for version 2.0.
+ He started out by authoring many of the available extensions and later was
+ asked to join Yuri, where he began fixing numerous bugs, adding
+ documentation and making general improvements to the existing code base.
+
+* __[Dmitry Shachnev](https://github.com/mitya57)__
+
+ @mitya57 joined the team after providing a number of helpful patches and has
+ been assisting with maintenance, reviewing pull requests and ticket triage.
+
+* __[Isaac Muse](https://github.com/facelessuser)__
+
+ @facelessuser joined the team after providing a number of helpful patches
+ and has been assisting with maintenance, reviewing pull requests and ticket
+ triage.
* __[Yuri Takteyev](http://freewisdom.org/)__
@@ -37,8 +48,9 @@ Other Contributors
==================
The incomplete list of individuals below have provided patches or otherwise
-contributed to the project in various ways. We would like to thank everyone
-who has contributed to the project in any way.
+contributed to the project prior to the project being hosted on GitHub. See the
+GitHub commit log for a list of recent contributors. We would like to thank
+everyone who has contributed to the project in any way.
* Eric Abrahamsen
* Jeff Balogh
diff --git a/docs/change_log/index.md b/docs/change_log/index.md
index f41559d..56d071d 100644
--- a/docs/change_log/index.md
+++ b/docs/change_log/index.md
@@ -3,6 +3,8 @@ title: Change Log
Python-Markdown Change Log
=========================
+???, 2018: Released version 3.0 ([Notes](release-3.0.md)).
+
Jan 4, 2018: Released version 2.6.11 (a bug-fix release). Added a new
`BACKLINK-TITLE` option to the footnote extension so that non-English
users can provide a custom title to back links (see #610).
@@ -229,4 +231,3 @@ Nov. 2004: Added links, blockquotes, HTML blocks to Manfred
Stienstra's code
Apr. 2004: Manfred's version at <http://www.dwerg.net/projects/markdown/>
-
diff --git a/docs/change_log/release-2.1.md b/docs/change_log/release-2.1.md
index 5b994d4..4f7ba75 100644
--- a/docs/change_log/release-2.1.md
+++ b/docs/change_log/release-2.1.md
@@ -65,10 +65,9 @@ What's New in Python-Markdown 2.1
---------------------------------
Three new extensions were added. [Attribute Lists](../extensions/attr_list.md),
-which was inspired by Maruku's feature of the same name,
-[Newline to Break](../extensions/nl2br.md), which was inspired by GitHub
-Flavored Markdown, and [Smart Strong](../extensions/smart_strong.md), which
-fills a hole in the Extra extension.
+which was inspired by Maruku's feature of the same name, [Newline to
+Break](../extensions/nl2br.md), which was inspired by GitHub Flavored Markdown,
+and Smart Strong, which fills a hole in the Extra extension.
HTML5 is now supported. All this really means is that new block level elements
introduced in the HTML5 spec are now properly recognized as raw HTML. As
diff --git a/docs/change_log/release-3.0.md b/docs/change_log/release-3.0.md
new file mode 100644
index 0000000..85a5d27
--- /dev/null
+++ b/docs/change_log/release-3.0.md
@@ -0,0 +1,206 @@
+title: Release Notes for v3.0
+
+# Python-Markdown 3.0 Release Notes
+
+We are pleased to release Python-Markdown 3.0 which adds a few new features and
+fixes various bugs and deprecates various old features. See the list of changes
+below for details.
+
+Python-Markdown version 3.0 supports Python versions 2.7, 3.4, 3.5, 3.6, 3.7,
+PyPy and PyPy3.
+
+## Backwards-incompatible changes
+
+### `enable_attributes` keyword deprecated
+
+The `enable_attributes` keyword is deprecated in version 3.0 and will be
+ignored. Previously the keyword was `True` by default and enabled an
+undocumented way to define attributes on document elements. The feature has been
+removed from version 3.0. As most users did not use the undocumented feature, it
+should not affect most users. For the few who did use the feature, it can be
+enabled by using the [Legacy Attributes](../extensions/legacy_attr.md)
+extension.
+
+### `smart_emphasis` keyword and `smart_strong` extension deprecated
+
+The `smart_emphasis` keyword is deprecated in version 3.0 and will be ignored.
+Previously the keyword was `True` by default and caused the parser to ignore
+middle-word emphasis. Additionally, the optional `smart_strong` extension
+provided the same behavior for strong emphasis. Both of those features are now
+part of the default behavior, and the [Legacy
+Emphasis](../extensions/legacy_em.md) extension is available to disable that
+behavior.
+
+### `output_formats` simplified to `html` and `xhtml`.
+
+The `output_formats` keyword now only accepts two options: `html` and `xhtml`
+Note that if `(x)html1`, `(x)html4` or `(x)html5` are passed in, the number is
+stripped and ignored.
+
+### `safe_mode` and `html_replacement_text` keywords deprecated
+
+Both `safe_mode` and the associated `html_replacement_text` keywords are
+deprecated in version 3.0 and will be ignored. The so-called "safe mode" was
+never actually "safe" which has resulted in many people having a false sense of
+security when using it. As an alternative, the developers of Python-Markdown
+recommend that any untrusted content be passed through an HTML sanitizer (like
+[Bleach]) after being converted to HTML by markdown. In fact, [Bleach Whitelist]
+provides a curated list of tags, attributes, and styles suitable for filtering
+user-provided HTML using bleach.
+
+If your code previously looked like this:
+
+```python
+html = markdown.markdown(text, safe_mode=True)
+```
+
+Then it is recommended that you change your code to read something like this:
+
+```python
+import bleach
+from bleach_whitelist import markdown_tags, markdown_attrs
+html = bleach.clean(markdown.markdown(text), markdown_tags, markdown_attrs)
+```
+
+If you are not interested in sanitizing untrusted text, but simply desire to
+escape raw HTML, then that can be accomplished through an extension which
+removes HTML parsing:
+
+```python
+from markdown.extensions import Extension
+
+class EscapeHtml(Extension):
+ def extendMarkdown(self, md):
+ md.preprocessors.deregister('html_block')
+ md.inlinePatterns.deregister('html')
+
+html = markdown.markdown(text, extensions=[EscapeHtml()])
+```
+
+As the HTML would not be parsed with the above Extension, then the serializer
+will escape the raw HTML, which is exactly what happened in previous versions
+with `safe_mode="escape"`.
+
+[Bleach]: https://bleach.readthedocs.io/
+[Bleach Whitelist]: https://github.com/yourcelf/bleach-whitelist
+
+### Positional arguments deprecated
+
+Positional arguments on the `markdown.Markdown()` class are deprecated as are
+all except the `text` argument on the `markdown.markdown()` wrapper function.
+Using positional arguments will raise an error. Only keyword arguments should be
+used. For example, if your code previously looked like this:
+
+```python
+html = markdown.markdown(text, [SomeExtension()])
+```
+
+Then it is recommended that you change it to read something like this:
+
+```python
+html = markdown.markdown(text, extensions=[SomeExtension()])
+```
+
+!!! Note
+ This change is being made as a result of deprecating `"safe_mode"` as the
+ `safe_mode` argument was one of the positional arguments. When that argument
+ is removed, the two arguments following it will no longer be at the correct
+ position. It is recommended that you always use keywords when they are
+ supported for this reason.
+
+### Extension name behavior has changed
+
+In previous versions of Python-Markdown, the built-in extensions received
+special status and did not require the full path to be provided. Additionally,
+third party extensions whose name started with `"mdx_"` received the same
+special treatment. This is no longer the case.
+
+Support has been added for extensions to define an [entry
+point](../extensions/api.md#entry_point). An entry point is a string name which
+can be used to point to an `Extension` class. The built-in extensions now have
+entry points which match the old short names. And any third-party extensions
+which define entry points can now get the same behavior. See the documentation
+for each specific extension to find the assigned name.
+
+If an extension does not define an entry point, then the full path to the
+extension must be used. See the [documentation](../reference.md#extensions) for
+a full explanation of the current behavior.
+
+### Extension configuration as part of extension name deprecated
+
+The previously documented method of appending the extension configuration
+options as a string to the extension name is deprecated and will raise an error.
+The [`extension_configs`](../reference.md#extension_configs) keyword should be
+used instead. See the [documentation](../reference.md#extension_configs) for a
+full explanation of the current behavior.
+
+### HeaderId extension deprecated
+
+The HeaderId Extension is deprecated and will raise an error if specified. Use
+the [Table of Contents](../extensions/toc.md) Extension instead, which offers
+most of the features of the HeaderId Extension and more (support for meta data
+is missing).
+
+Extension authors who have been using the `slugify` and `unique` functions
+defined in the HeaderId Extension should note that those functions are now
+defined in the Table of Contents extension and should adjust their import
+statements accordingly (`from markdown.extensions.toc import slugify, unique`).
+
+### Homegrown `OrderedDict` has been replaced with a purpose-built `Registry`
+
+All processors and patterns now get "registered" to a
+[Registry](../extensions/api.md#registry). A backwards compatible shim is
+included so that existing simple extensions should continue to work.
+A `DeprecationWarning` will be raised for any code which calls the old API.
+
+### Markdown class instance references.
+
+Previously, instances of the `Markdown` class were represented as any one of
+`md`, `md_instance`, or `markdown`. This inconsistency made it difficult when
+developing extensions, or just maintaining the existing code. Now, all instances
+are consistently represented as `md`.
+
+The old attributes on class instances still exist, but raise a
+`DeprecationWarning` when accessed. Also on classes where the instance was
+optional, the attribute always exists now and is simply `None` if no instance
+was provided (previously the attribute would not exist).
+
+### `markdown.util.isBlockLevel` deprecated
+
+The `markdown.util.isBlockLevel` function is deprecated and will raise a
+`DeprecationWarning`. Instead, extensions should use the `isBlockLevel` method
+of the `Markdown` class instance. Additionally, a list of block level elements
+is defined in the `block_level_elements` attribute of the `Markdown` class which
+extensions can access to alter the list of elements which are treated as block
+level elements.
+
+### `md_globals` keyword deprecated from extension API
+
+Previously, the `extendMarkdown` method of a `markdown.extensions.Extension`
+subclasses accepted an `md_globals` keyword, which contained the value returned
+by Python's `globals()` built-in function. As all of the configuration is now
+held within the `Markdown` class instance, access to the globals is no longer
+necessary and any extensions which expect the keyword will raise a
+`DeprecationWarning`. A future release will raise an error.
+
+### Added new, more flexible `InlineProcessor` class
+
+A new `InlineProcessor` class handles inline processing much better and allows
+for more flexibility. The new `InlineProcessor` classes no longer utilize
+unnecessary pretext and post-text captures. New class can accept the buffer that
+is being worked on and manually process the text without regular expressions and
+return new replacement bounds. This helps us to handle links in a better way and
+handle nested brackets and logic that is too much for regular expression.
+
+## New features
+
+The following new features have been included in the release:
+
+* A new [testing framework](../test_tools.md) is included as a part of the
+ Markdown library, which can also be used by third party extensions.
+
+* A new `toc_depth` parameter has been added to the
+ [Table of Contents Extension](../extensions/toc.md).
+
+* Additional CSS class names can be appended to
+ [Admonitions](../extensions/admonition.md).
diff --git a/docs/cli.md b/docs/cli.md
index 35c77b4..2c1abcf 100644
--- a/docs/cli.md
+++ b/docs/cli.md
@@ -168,7 +168,7 @@ The `--extension_configs` option will only support YAML configuration files if
[PyYAML] is installed on your system. JSON should work with no additional
dependencies. The format of your configuration file is automatically detected.
-[ec]: reference.html#extension_configs
+[ec]: reference.md#extension_configs
[YAML]: http://yaml.org/
[JSON]: http://json.org/
[PyYAML]: http://pyyaml.org/
diff --git a/docs/extensions/api.md b/docs/extensions/api.md
index a110cef..c236a93 100644
--- a/docs/extensions/api.md
+++ b/docs/extensions/api.md
@@ -495,25 +495,24 @@ 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.
+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 a [Registry][]. Your `Extension` class will need to manipulate
+those registries appropriately. You may `register` instances of your processors
+and patterns with an appropriate priority, `deregister` built-in instances, or
+replace a built-in instance with your own.
### `extendMarkdown` {: #extendmarkdown }
The `extendMarkdown` method of a `markdown.extensions.Extension` class
-accepts two arguments:
+accepts one argument:
* **`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:
+ access the [Registries][Registry] of processors and patterns. They are
+ found under the following attributes:
* `md.preprocessors`
* `md.inlinePatterns`
@@ -529,14 +528,9 @@ accepts two arguments:
* `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.
+ * `md.block_level_elements`
+ * `md.isBlockLevel()`
!!! Warning
With access to the above items, theoretically you have the option to
@@ -554,109 +548,75 @@ 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')
+ def extendMarkdown(self, md):
+ # Register instance of 'mypattern' with a priority of 175
+ md.inlinePatterns.register(MyPattern(md), 'mypattern', 175)
```
-### 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.
+### Registry
-The `add()` method accepts three arguments:
+The `markdown.util.Registry` class is a priority sorted registry which Markdown
+uses internally to determine the processing order of its various processors and
+patterns.
-* **`key`**: A string. The key is used for later reference to the item.
+A `Registry` instance provides two public methods to alter the data of the
+registry: `register` and `deregister`. Use `register` to add items and
+`deregister` to remove items. See each method for specifics.
-* **`value`**: The object instance stored in this item.
+When registering an item, a "name" and a "priority" must be provided. All
+items are automatically sorted by "priority" from highest to lowest. The
+"name" is used to remove (`deregister`) and get items.
-* **`location`**: The items location in relation to other items.
+A `Registry` instance is like a list (which maintains order) when reading
+data. You may iterate over the items, get an item and get a count (length)
+of all items. You may also check that the registry contains an item.
- Note that the location can consist of a few different values:
+When getting an item you may use either the index of the item or the
+string-based "name". For example:
- * 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:
-
-```pycon
->>> 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)]
-```
+ registry = Registry()
+ registry.register(SomeItem(), 'itemname', 20)
+ # Get the item by index
+ item = registry[0]
+ # Get the item by name
+ item = registry['itemname']
-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.
+When checking that the registry contains an item, you may use either the
+string-based "name", or a reference to the actual item. For example:
-```pycon
->>> od.add('two', 2, '>one') # Insert after 'one'
->>> od.values()
-[1, 2, 3, 4]
-```
+ someitem = SomeItem()
+ registry.register(someitem, 'itemname', 20)
+ # Contains the name
+ assert 'itemname' in registry
+ # Contains the item instance
+ assert someitem in registry
-Now let's insert another item.
+`markdown.util.Registry` has the following methods:
-```pycon
->>> od.add('two-point-five', 2.5, '<three') # Insert before 'three'
->>> od.keys()
-["one", "two", "two-point-five", "three", "four"]
-```
+#### `Registry.register(self, item, name, priority)` {: #registry.register }
-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.
+: Add an item to the registry with the given name and priority.
-Once an OrderedDict is created, the items are available via key:
+ Parameters:
-```python
-MyNode = od['somekey']
-```
+ * `item`: The item being registered.
+ * `name`: A string used to reference the item.
+ * `priority`: An integer or float used to sort against all items.
-Therefore, to delete an existing item:
+ If an item is registered with a "name" which already exists, the existing
+ item is replaced with the new item. Tread carefully as the old item is lost
+ with no way to recover it. The new item will be sorted according to its
+ priority and will **not** retain the position of the old item.
-```python
-del od['somekey']
-```
+#### `Registry.deregister(self, name, strict=True)` {: #registry.deregister }
-To change the value of an existing item (leaving location unchanged):
+: Remove an item from the registry.
-```python
-od['somekey'] = MyNewObject()
-```
+ Set `strict=False` to fail silently.
-To change the location of an existing item:
+#### `Registry.get_index_for_name(self, name)` {: #registry.get_index_for_name }
-```python
-t.link('somekey', '<otherkey')
-```
+: Return the index of the given `name`.
### registerExtension {: #registerextension }
@@ -682,7 +642,7 @@ To register an extension, call `md.registerExtension` from within your
`extendMarkdown` method:
```python
-def extendMarkdown(self, md, md_globals):
+def extendMarkdown(self, md):
md.registerExtension(self)
# insert processors and patterns here
```
@@ -850,7 +810,7 @@ module and call the `makeExtension` function to initiate your extension.
[workingwithetree]: #working_with_et
[Integrating your code into Markdown]: #integrating_into_markdown
[extendMarkdown]: #extendmarkdown
-[OrderedDict]: #ordereddict
+[Registry]: #registry
[registerExtension]: #registerextension
[Config Settings]: #configsettings
[makeExtension]: #makeextension
diff --git a/docs/extensions/code_hilite.md b/docs/extensions/code_hilite.md
index 552a82d..153a57c 100644
--- a/docs/extensions/code_hilite.md
+++ b/docs/extensions/code_hilite.md
@@ -132,6 +132,15 @@ Certain lines can be selected for emphasis with the colon syntax. When
using Pygments' default CSS styles, emphasized lines have a yellow background.
This is useful to direct the reader's attention to specific lines.
+```md
+ :::python hl_lines="1 3"
+ # This line is emphasized
+ # This line isn't
+ # This line is emphasized
+```
+
+Will result in:
+
:::python hl_lines="1 3"
# This line is emphasized
# This line isn't
diff --git a/docs/extensions/extra.md b/docs/extensions/extra.md
index 3d9f374..a74d175 100644
--- a/docs/extensions/extra.md
+++ b/docs/extensions/extra.md
@@ -15,7 +15,6 @@ The supported extensions include:
* [Fenced Code Blocks](fenced_code_blocks.md)
* [Footnotes](footnotes.md)
* [Tables](tables.md)
-* [Smart Strong](smart_strong.md)
See each individual extension for syntax documentation. Extra and all its
supported extensions are included in the standard Markdown library.
diff --git a/docs/extensions/fenced_code_blocks.md b/docs/extensions/fenced_code_blocks.md
index 4c8058d..410d652 100644
--- a/docs/extensions/fenced_code_blocks.md
+++ b/docs/extensions/fenced_code_blocks.md
@@ -104,9 +104,9 @@ The lines can be specified with PHP Extra's syntax:
```
````
-[CodeHilite]: code_hilite.html
+[CodeHilite]: code_hilite.md
[Pygments]: http://pygments.org/
-[colon]: code_hilite.html#colons
+[colon]: code_hilite.md#colons
## Usage
diff --git a/docs/extensions/index.md b/docs/extensions/index.md
index cbfdab6..26b117b 100644
--- a/docs/extensions/index.md
+++ b/docs/extensions/index.md
@@ -44,9 +44,10 @@ Extension | Entry Point | Dot Notation
&nbsp; &nbsp; [Fenced Code Blocks][] | `fenced_code` | `markdown.extensions.fenced_code`
&nbsp; &nbsp; [Footnotes][] | `footnotes` | `markdown.extensions.footnotes`
&nbsp; &nbsp; [Tables][] | `tables` | `markdown.extensions.tables`
-&nbsp; &nbsp; [Smart Strong][] | `smart_strong` | `markdown.extensions.smart_strong`
[Admonition][] | `admonition` | `markdown.extensions.admonition`
[CodeHilite][] | `codehilite` | `markdown.extensions.codehilite`
+[Legacy Attributes][] | `legacy_attr` | `markdown.extensions.legacy_attr`
+[Legacy Emphasis][] | `legacy_em` | `markdown.extensions.legacy_em`
[Meta-Data] | `meta` | `markdown.extensions.meta`
[New Line to Break] | `nl2br` | `markdown.extensions.nl2br`
[Sane Lists] | `sane_lists` | `markdown.extensions.sane_lists`
@@ -61,9 +62,10 @@ Extension | Entry Point | Dot Notation
[Fenced Code Blocks]: fenced_code_blocks.md
[Footnotes]: footnotes.md
[Tables]: tables.md
-[Smart Strong]: smart_strong.md
[Admonition]: admonition.md
[CodeHilite]: code_hilite.md
+[Legacy Attributes]: legacy_attr.md
+[Legacy Emphasis]: legacy_em.md
[Meta-Data]: meta_data.md
[New Line to Break]: nl2br.md
[Sane Lists]: sane_lists.md
diff --git a/docs/extensions/legacy_attr.md b/docs/extensions/legacy_attr.md
new file mode 100644
index 0000000..0066867
--- /dev/null
+++ b/docs/extensions/legacy_attr.md
@@ -0,0 +1,59 @@
+title: Legacy Attributes Extension
+
+# Legacy Attributes
+
+## Summary
+
+The Legacy Attributes extension restores Python-Markdown's original attribute
+setting syntax. Older versions of Python Markdown (prior to 3.0) included
+built-in and undocumented support for defining attributes on elements. Most
+users have never made use of the syntax and it has been deprecated in favor of
+[Attribute Lists](attr_list.md). This extension restores the legacy behavior for
+users who have existing documents which use the syntax.
+
+## Syntax
+
+Attributes are defined by including the following within the element you wish to
+assign the attributes to:
+
+```md
+{@key=value}
+```
+
+For example, to define a class to a paragraph:
+
+```md
+A paragraph with the attribute defined {@class=foo}anywhere within.
+```
+
+Which results in the following output:
+
+```html
+<p class="foo">A paragraph with the attribute defined anywhere within.</p>
+```
+
+The same applies for inline elements:
+
+```md
+Some *emphasized{@id=bar}* text.
+```
+
+```html
+<p>Some <em id="bar">emphasized</em> text.</p>
+
+You can also define attributes in images:
+
+```md
+![Alt text{@id=baz}](path/to/image.jpg)
+```
+
+```html
+<p><img alt="Alt text" id="baz" src="path/to/image.jpg" /></p>
+```
+
+## Usage
+
+See [Extensions](index.md) for general extension usage. Use `legacy_attr` as the
+name of the extension.
+
+This extension does not accept any special configuration options.
diff --git a/docs/extensions/legacy_em.md b/docs/extensions/legacy_em.md
new file mode 100644
index 0000000..aad1e50
--- /dev/null
+++ b/docs/extensions/legacy_em.md
@@ -0,0 +1,25 @@
+title: Legacy EM Extension
+
+# Legacy EM
+
+## Summary
+
+The Legacy EM extension restores Markdown's original behavior for emphasis and
+strong syntax when using underscores.
+
+By default Python-Markdown treats `_connected_words_` intelligently by
+recognizing that mid-word underscores should not be used for emphasis. In other
+words, by default, that input would result in this output:
+`<em>connected_words</em>`.
+
+However, that behavior is not consistent with the original rules or the behavior
+of the reference implementation. Therefore, this extension can be used to better
+match the reference implementation. With the extension enabled, the above input
+would result in this output: `<em>connected</em>words_`.
+
+## Usage
+
+See [Extensions](index.md) for general extension usage. Use `legacy_em` 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 81f8d84..6d364c1 100644
--- a/docs/extensions/sane_lists.md
+++ b/docs/extensions/sane_lists.md
@@ -66,6 +66,27 @@ With this extension the above will result in the following output:
</ol>
```
+Sane lists also recognize the number used in ordered lists. Given the following
+list:
+
+```md
+4. Apples
+5. Oranges
+6. Pears
+```
+
+By default markdown will ignore the fact that the first line started
+with item number "4" and the HTML list will start with a number "1".
+This extension will result in the following HTML output:
+
+```html
+<ol start="4">
+ <li>Apples</li>
+ <li>Oranges</li>
+ <li>Pears</li>
+</ol>
+```
+
In all other ways, Sane Lists should behave as normal Markdown lists.
Usage
diff --git a/docs/extensions/smart_strong.md b/docs/extensions/smart_strong.md
deleted file mode 100644
index 65c88d6..0000000
--- a/docs/extensions/smart_strong.md
+++ /dev/null
@@ -1,36 +0,0 @@
-title: Smart Strong Extension
-
-Smart_Strong
-============
-
-Summary
--------
-
-The Smart_Strong extension adds smarter handling of double underscores within
-words. This does for double underscores what [smart_emphasis][] does for single
-underscores.
-
-The Smart_Strong extension is included in the standard Markdown library.
-
-[smart_emphasis]: ../reference.md#smart_emphasis
-
-Example
--------
-
-```pycon
->>> import markdown
->>> markdown.markdown('Text with double__underscore__words.', extensions=['smart_strong'])
-u'<p>Text with double__underscore__words.</p>'
->>> markdown.markdown('__Strong__ still works.', extensions=['smart_strong'])
-u'<p><strong>Strong</strong> still works.</p>'
->>> markdown.markdown('__this__works__too__.', extensions=['smart_strong'])
-u'<p><strong>this__works__too</strong>.</p>'
-```
-
-Usage
------
-
-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 109d78c..0efbe4a 100644
--- a/docs/extensions/smarty.md
+++ b/docs/extensions/smarty.md
@@ -48,7 +48,7 @@ extension_configs = {
has been known to do.
[SmartyPants]: http://pythonhosted.org/smartypants/
-[CodeHilite]: code_hilite.html
+[CodeHilite]: code_hilite.md
Usage
-----
diff --git a/docs/index.md b/docs/index.md
index 8c32d51..d034e41 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -10,7 +10,8 @@ though there are a few very minor [differences](#differences). See John's
[Syntax Documentation](http://daringfireball.net/projects/markdown/syntax)
for the syntax rules.
-See the [installation instructions](install.md) to get started.
+To get started, see the [installation instructions](install.md), the [library
+reference](reference.md), and the [command line interface](cli.md).
Goals
-----
@@ -69,10 +70,10 @@ are summarized below:
* __Middle-Word Emphasis__
- Python-Markdown defaults to ignoring middle-word emphasis. In other words,
- `some_long_filename.txt` will not become `some<em>long</em>filename.txt`.
- This can be switched off if desired. See the
- [Library Reference](reference.md#smart_emphasis) for details.
+ Python-Markdown defaults to ignoring middle-word emphasis (and strong
+ emphasis). In other words, `some_long_filename.txt` will not become
+ `some<em>long</em>filename.txt`. This can be switched off if desired. See
+ the [Legacy EM Extension](extensions/legacy_em.md) for details.
* __Indentation/Tab Length__
diff --git a/docs/reference.md b/docs/reference.md
index 25c2058..f8f2e52 100644
--- a/docs/reference.md
+++ b/docs/reference.md
@@ -181,33 +181,6 @@ __tab_length__{: #tab_length }:
: Length of tabs in the source. Default: 4
-__smart_emphasis__{: #smart_emphasis }:
-
-: Treat `_connected_words_` intelligently Default: True
-
-__lazy_ol__{: #lazy_ol }:
-
-: Ignore number of first item of ordered lists. Default: True
-
- Given the following list:
-
- :::md
- 4. Apples
- 5. Oranges
- 6. Pears
-
- By default markdown will ignore the fact that the first line started
- with item number "4" and the HTML list will start with a number "1".
- If `lazy_ol` is set to `False`, then markdown will output the following
- HTML:
-
- :::html
- <ol start="4">
- <li>Apples</li>
- <li>Oranges</li>
- <li>Pears</li>
- </ol>
-
### `markdown.markdownFromFile (**kwargs)` {: #markdownFromFile }
With a few exceptions, `markdown.markdownFromFile` accepts the same options as