Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions mdit_py_plugins/attrs/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,14 @@ def attrs_plugin(
- `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 (`}`).
Backslash escapes may be used inside quoted values,
to allow a ``"`` character within the value.
Note that the backslash is retained in the value:
``{k="a\\"b"}`` gives ``k`` the value ``a\\"b``.
- `%` begins a comment, which ends with the next `%`.
If no further `%` occurs in the rest of the line (for a block attribute)
or of the paragraph (for an inline attribute),
the comment instead ends at the next `}`, which also ends the attribute.

Multiple attribute blocks are merged.

Expand Down Expand Up @@ -175,8 +181,8 @@ def _attr_inline_rule(
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"{token.attrs['class']} {attrs['class']}"
if "class" in attrs and "class" in attr_token.attrs:
attrs["class"] = f"{attr_token.attrs['class']} {attrs['class']}"
_add_attrs(attr_token, attrs, allowed)
return True

Expand Down Expand Up @@ -238,7 +244,8 @@ def _attr_resolve_block_rule(state: StateCore, *, allowed: set[str] | None) -> N
i += 1
continue

if i + 1 < len_tokens:
# skip closing tokens; attributes would be rendered into the closing tag
if i + 1 < len_tokens and state.tokens[i + 1].nesting >= 0:
next_token = state.tokens[i + 1]

# classes are appended
Expand Down
15 changes: 13 additions & 2 deletions mdit_py_plugins/attrs/parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,17 +100,28 @@ def parse(string: str) -> tuple[int, dict[str, str]]:
"""Parse attributes from start of string.

:returns: (length of parsed string, dict of attributes)
:raises ParseError: if the attributes are malformed,
or the string ends before the closing `}`
"""
pos = 0
state: State = State.START
tokens = TokenState()
while pos < len(string):
state = HANDLERS[state](string[pos], pos, tokens)
if (
state == State.SCANNING_COMMENT
and string[pos] == "}"
and "%" not in string[pos + 1 :]
):
# a comment ends at the next `%`, but there is none left to close it,
# so this `}` ends both the comment and the attributes
state = State.DONE
else:
state = HANDLERS[state](string[pos], pos, tokens)
if state == State.DONE:
return pos, tokens.compile(string)
pos = pos + 1

return pos, tokens.compile(string)
raise ParseError("Attributes not terminated", pos)


def handle_start(char: str, pos: int, tokens: TokenState) -> State:
Expand Down
Loading
Loading