Skip to content

Commit 7b1b0d0

Browse files
authored
Merge branch 'master' into pep561
2 parents 00d1c04 + b16ee04 commit 7b1b0d0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+1890
-290
lines changed

.github/workflows/tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ jobs:
4040
- name: Install dependencies
4141
run: |
4242
python -m pip install --upgrade pip
43-
pip install .[testing]
43+
pip install .[testing,linkify]
4444
- name: Run pytest
4545
run: |
4646
pytest --cov=markdown_it --cov-report=xml --cov-report=term-missing

.mypy.ini

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[mypy]
2+
warn_unused_ignores = True
3+
warn_redundant_casts = True
4+
no_implicit_optional = True
5+
strict_equality = True

.pre-commit-config.yaml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,30 @@ exclude: >
1515
repos:
1616

1717
- repo: https://github.com/pre-commit/pre-commit-hooks
18-
rev: v3.2.0
18+
rev: v3.3.0
1919
hooks:
2020
- id: check-json
2121
- id: check-yaml
2222
- id: end-of-file-fixer
2323
- id: trailing-whitespace
2424

2525
- repo: https://github.com/mgedmin/check-manifest
26-
rev: "0.42"
26+
rev: "0.44"
2727
hooks:
2828
- id: check-manifest
2929

3030
- repo: https://gitlab.com/pycqa/flake8
31-
rev: 3.8.3
31+
rev: 3.8.4
3232
hooks:
3333
- id: flake8
3434

3535
- repo: https://github.com/psf/black
3636
rev: 20.8b1
3737
hooks:
3838
- id: black
39+
40+
- repo: https://github.com/pre-commit/mirrors-mypy
41+
rev: v0.790
42+
hooks:
43+
- id: mypy
44+
additional_dependencies: [attrs]

CHANGELOG.md

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,68 @@
11
# Change Log
22

3+
## 0.5.8 - 2020-12-13
4+
5+
✨ NEW: Add linkify, thanks to [@tsutsu3](https://github.com/tsutsu3).
6+
7+
This extension uses [linkify-it-py](https://github.com/tsutsu3/linkify-it-py) to identify URL links within text:
8+
9+
- `github.com` -> `<a href="http://github.com">github.com</a>`
10+
11+
**Important:** To use this extension you must install linkify-it-py; `pip install markdown-it-py[linkify]`
12+
13+
It can then be activated by:
14+
15+
```python
16+
from markdown_it import MarkdownIt
17+
md = MarkdownIt().enable("linkify")
18+
md.options["linkify"] = True
19+
```
20+
21+
## 0.5.7 - 2020-12-13
22+
23+
✨ NEW: Add smartquotes, thanks to [@tsutsu3](https://github.com/tsutsu3).
24+
25+
This extension will convert basic quote marks to their opening and closing variants:
26+
27+
- 'single quotes' -> ‘single quotes’
28+
- "double quotes" -> “double quotes”
29+
30+
It can be activated by:
31+
32+
```python
33+
from markdown_it import MarkdownIt
34+
md = MarkdownIt().enable("replacements").enable("smartquotes")
35+
```
36+
37+
✨ NEW: Add markdown-it-task-lists plugin, thanks to [@wna-se](https://github.com/wna-se).
38+
39+
This is a port of the JS [markdown-it-task-lists](https://github.com/revin/markdown-it-task-lists),
40+
for building task/todo lists out of markdown lists with items starting with `[ ]` or `[x]`.
41+
For example:
42+
43+
```markdown
44+
- [ ] An item that needs doing
45+
- [x] An item that is complete
46+
```
47+
48+
This plugin can be activated by:
49+
50+
```python
51+
from markdown_it import MarkdownIt
52+
from markdown_it.extensions.tasklists import tasklists_plugin
53+
md = MarkdownIt().use(tasklists_plugin)
54+
```
55+
56+
🐛 Various bug fixes, thanks to [@hukkinj1](https://github.com/hukkinj1):
57+
58+
- Do not copy empty `env` arg in `MarkdownIt.render`
59+
- `_Entities.__contains__` fix return data
60+
- Parsing of unicode ordinals
61+
- Handling of final character in `skipSpacesBack` and `skipCharsBack` methods
62+
- Avoid exception when document ends in heading/blockquote marker
63+
64+
🧪 TESTS: Add CI for Python 3.9 and PyPy3
65+
366
## 0.5.6 - 2020-10-21
467

568
- ✨ NEW: Add simple typographic replacements, thanks to [@tsutsu3](https://github.com/tsutsu3):
@@ -20,7 +83,7 @@
2083
- ``---`` → &mdash
2184

2285
```python
23-
md = MarkdownIt()
86+
md = MarkdownIt().enable("replacements")
2487
md.options["typographer"] = True
2588
```
2689

MANIFEST.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ exclude .flake8
1313
exclude .circleci
1414
exclude .circleci/config.yml
1515
exclude codecov.yml
16+
exclude .mypy.ini
1617

1718
include LICENSE
1819
include LICENSE.markdown-it

docs/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
# This pattern also affects html_static_path and html_extra_path.
4646
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
4747

48-
nitpick_ignore = [("py:class", "Match")]
48+
nitpick_ignore = [("py:class", "Match"), ("py:class", "x in the interval [0, 1).")]
4949

5050

5151
# -- Options for HTML output -------------------------------------------------

docs/plugins.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ html_string = md.render("some *Markdown*")
4040
4141
.. autofunction:: markdown_it.extensions.amsmath.amsmath_plugin
4242
:noindex:
43+
44+
.. autofunction:: markdown_it.extensions.tasklists.tasklists_plugin
45+
:noindex:
4346
```
4447

4548
`myst_blocks` and `myst_role` plugins are also available, for utilisation by the [MyST renderer](https://myst-parser.readthedocs.io/en/latest/using/syntax.html)

markdown_it/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
from .main import MarkdownIt # noqa: F401
22

33

4-
__version__ = "0.5.6"
4+
__version__ = "0.5.8"

markdown_it/cli/parse.py

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,11 @@ def convert_file(filename):
4040
sys.exit('Cannot open file "{}".'.format(filename))
4141

4242

43-
def interactive(import_readline=False):
43+
def interactive():
4444
"""
4545
Parse user input, dump to stdout, rinse and repeat.
4646
Python REPL style.
4747
"""
48-
if import_readline:
49-
_import_readline()
5048
print_heading()
5149
contents = []
5250
more = False
@@ -98,13 +96,6 @@ def parse_args(args):
9896
return parser.parse_args(args)
9997

10098

101-
def _import_readline():
102-
try:
103-
import readline # noqa: F401
104-
except ImportError:
105-
print("[warning] readline library not available.")
106-
107-
10899
def print_heading():
109100
print("{} (interactive)".format(version_str))
110101
print("Type Ctrl-D to complete input, or Ctrl-C to exit.")

markdown_it/common/entities.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""HTML5 entities map: { name -> characters }."""
2-
import html
2+
import html.entities
33

44

55
class _Entities:

markdown_it/common/normalize_url.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import html
22
import re
3-
from typing import Callable
3+
from typing import Callable, Optional
44
from urllib.parse import urlparse, urlunparse, quote, unquote # noqa: F401
55

66
from .utils import ESCAPABLE
@@ -166,7 +166,7 @@ def normalizeLinkText(link):
166166
GOOD_DATA_RE = re.compile(r"^data:image\/(gif|png|jpeg|webp);")
167167

168168

169-
def validateLink(url: str, validator: Callable = None):
169+
def validateLink(url: str, validator: Optional[Callable] = None):
170170
"""Validate URL link is allowed in output.
171171
172172
This validator can prohibit more than really needed to prevent XSS.
@@ -180,8 +180,4 @@ def validateLink(url: str, validator: Callable = None):
180180
if validator is not None:
181181
return validator(url)
182182
url = url.strip().lower()
183-
return (
184-
(True if GOOD_DATA_RE.search(url) else False)
185-
if BAD_PROTO_RE.search(url)
186-
else True
187-
)
183+
return bool(GOOD_DATA_RE.search(url)) if BAD_PROTO_RE.search(url) else True

markdown_it/common/utils.py

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def assign(obj):
5353
# })
5454
# })
5555

56-
return obj
56+
# return obj
5757

5858

5959
def arrayReplaceAt(src: list, pos: int, newElements: list):
@@ -92,15 +92,13 @@ def isValidEntityCode(c):
9292
return True
9393

9494

95-
def fromCodePoint(c):
96-
97-
if c > 0xFFFF:
98-
c -= 0x10000
99-
surrogate1 = 0xD800 + (c >> 10)
100-
surrogate2 = 0xDC00 + (c & 0x3FF)
101-
102-
return "".join(map(chr, [surrogate1, surrogate2]))
95+
def fromCodePoint(c: int) -> str:
96+
"""Convert ordinal to unicode.
10397
98+
Note, in the original Javascript two string characters were required,
99+
for codepoints larger than `0xFFFF`.
100+
But Python 3 can represent any unicode codepoint in one character.
101+
"""
104102
return chr(c)
105103

106104

@@ -141,9 +139,10 @@ def replaceEntityPattern(match, name):
141139

142140

143141
def unescapeMd(string: str):
144-
if "\\" in string:
145-
return string
146-
return string.replace(UNESCAPE_MD_RE, "$1")
142+
raise NotImplementedError
143+
# if "\\" in string:
144+
# return string
145+
# return string.replace(UNESCAPE_MD_RE, "$1")
147146

148147

149148
def unescapeAll(string: str):
@@ -272,7 +271,7 @@ def isPunctChar(ch):
272271
}
273272

274273

275-
def isMdAsciiPunct(ch: str):
274+
def isMdAsciiPunct(ch: int):
276275
"""Markdown ASCII punctuation characters.
277276
278277
::

markdown_it/extensions/anchors/index.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import re
2-
from typing import Callable, List, Optional
2+
from typing import Callable, List, Optional, Set
33

44
from markdown_it import MarkdownIt
55
from markdown_it.rules_core import StateCore
@@ -65,19 +65,20 @@ def _make_anchors_func(
6565
permalinkBefore: bool,
6666
permalinkSpace: bool,
6767
):
68-
slugs = set()
68+
slugs: Set[str] = set()
6969

7070
def _anchor_func(state: StateCore):
7171
for (idx, token) in enumerate(state.tokens):
72-
token: Token
7372
if token.type != "heading_open":
7473
continue
7574
level = int(token.tag[1])
7675
if level not in selected_levels:
7776
continue
77+
inline_token = state.tokens[idx + 1]
78+
assert inline_token.children is not None
7879
title = "".join(
7980
child.content
80-
for child in state.tokens[idx + 1].children
81+
for child in inline_token.children
8182
if child.type in ["text", "code_inline"]
8283
)
8384
slug = unique_slug(slug_func(title), slugs)
@@ -95,17 +96,17 @@ def _anchor_func(state: StateCore):
9596
Token("link_close", "a", -1),
9697
]
9798
if permalinkBefore:
98-
state.tokens[idx + 1].children = (
99+
inline_token.children = (
99100
link_tokens
100101
+ (
101102
[Token("text", "", 0, content=" ")]
102103
if permalinkSpace
103104
else []
104105
)
105-
+ state.tokens[idx + 1].children
106+
+ inline_token.children
106107
)
107108
else:
108-
state.tokens[idx + 1].children.extend(
109+
inline_token.children.extend(
109110
([Token("text", "", 0, content=" ")] if permalinkSpace else [])
110111
+ link_tokens
111112
)

0 commit comments

Comments
 (0)