-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into task-list-gfm-compliancy
- Loading branch information
Showing
35 changed files
with
702 additions
and
140 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,7 +2,7 @@ coverage: | |
status: | ||
project: | ||
default: | ||
target: 93% | ||
target: 92% | ||
threshold: 0.2% | ||
patch: | ||
default: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
__version__ = "0.3.0" | ||
__version__ = "0.3.1" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from .index import attrs_plugin # noqa: F401 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
from typing import List, Optional | ||
|
||
from markdown_it import MarkdownIt | ||
from markdown_it.rules_inline import StateInline | ||
from markdown_it.token import Token | ||
|
||
from .parse import ParseError, parse | ||
|
||
|
||
def attrs_plugin( | ||
md: MarkdownIt, | ||
*, | ||
after=("image", "code_inline", "link_close", "span_close"), | ||
spans=True, | ||
): | ||
"""Parse inline attributes that immediately follow certain inline elements:: | ||
![alt](https://image.com){#id .a b=c} | ||
This syntax is inspired by | ||
`Djot spans | ||
<https://htmlpreview.github.io/?https://github.com/jgm/djot/blob/master/doc/syntax.html#inline-attributes>`_. | ||
Inside the curly braces, the following syntax is possible: | ||
- `.foo` specifies foo as a class. | ||
Multiple classes may be given in this way; they will be combined. | ||
- `#foo` specifies foo as an identifier. | ||
An element may have only one identifier; | ||
if multiple identifiers are given, the last one is used. | ||
- `key="value"` or `key=value` specifies a key-value attribute. | ||
Quotes are not needed when the value consists entirely of | ||
ASCII alphanumeric characters or `_` or `:` or `-`. | ||
Backslash escapes may be used inside quoted values. | ||
- `%` begins a comment, which ends with the next `%` or the end of the attribute (`}`). | ||
Multiple attribute blocks are merged. | ||
:param md: The MarkdownIt instance to modify. | ||
:param after: The names of inline elements after which attributes may be specified. | ||
This plugin does not support attributes after emphasis, strikethrough or text elements, | ||
which all require post-parse processing. | ||
:param spans: If True, also parse attributes after spans of text, encapsulated by `[]`. | ||
Note Markdown link references take precedence over this syntax. | ||
""" | ||
|
||
def _attr_rule(state: StateInline, silent: bool): | ||
if state.pending or not state.tokens: | ||
return False | ||
token = state.tokens[-1] | ||
if token.type not in after: | ||
return False | ||
try: | ||
new_pos, attrs = parse(state.src[state.pos :]) | ||
except ParseError: | ||
return False | ||
token_index = _find_opening(state.tokens, len(state.tokens) - 1) | ||
if token_index is None: | ||
return False | ||
state.pos += new_pos + 1 | ||
if not silent: | ||
attr_token = state.tokens[token_index] | ||
if "class" in attrs and "class" in token.attrs: | ||
attrs["class"] = f"{attr_token.attrs['class']} {attrs['class']}" | ||
attr_token.attrs.update(attrs) | ||
return True | ||
|
||
if spans: | ||
md.inline.ruler.after("link", "span", _span_rule) | ||
md.inline.ruler.push("attr", _attr_rule) | ||
|
||
|
||
def _find_opening(tokens: List[Token], index: int) -> Optional[int]: | ||
"""Find the opening token index, if the token is closing.""" | ||
if tokens[index].nesting != -1: | ||
return index | ||
level = 0 | ||
while index >= 0: | ||
level += tokens[index].nesting | ||
if level == 0: | ||
return index | ||
index -= 1 | ||
return None | ||
|
||
|
||
def _span_rule(state: StateInline, silent: bool): | ||
if state.srcCharCode[state.pos] != 0x5B: # /* [ */ | ||
return False | ||
|
||
maximum = state.posMax | ||
labelStart = state.pos + 1 | ||
labelEnd = state.md.helpers.parseLinkLabel(state, state.pos, False) | ||
|
||
# parser failed to find ']', so it's not a valid span | ||
if labelEnd < 0: | ||
return False | ||
|
||
pos = labelEnd + 1 | ||
|
||
try: | ||
new_pos, attrs = parse(state.src[pos:]) | ||
except ParseError: | ||
return False | ||
|
||
pos += new_pos + 1 | ||
|
||
if not silent: | ||
state.pos = labelStart | ||
state.posMax = labelEnd | ||
token = state.push("span_open", "span", 1) | ||
token.attrs = attrs | ||
state.md.inline.tokenize(state) | ||
token = state.push("span_close", "span", -1) | ||
|
||
state.pos = pos | ||
state.posMax = maximum | ||
return True |
Oops, something went wrong.