Download rtme/lib/python3.10/site-packages/mistune/plugins/footnotes.py from ckadirt/backup_rtme: direct link, hf CLI and curl.
- Browser
- Download file 4.99 kB
-
https://huggingface.co/ckadirt/backup_rtme/resolve/main/rtme/lib/python3.10/site-packages/mistune/plugins/footnotes.py
- Command line
-
hf download hf://ckadirt/backup_rtme/rtme/lib/python3.10/site-packages/mistune/plugins/footnotes.py
-
curl -L -o footnotes.py https://huggingface.co/ckadirt/backup_rtme/resolve/main/rtme/lib/python3.10/site-packages/mistune/plugins/footnotes.py
4.99 kB
| import re | |
| from typing import TYPE_CHECKING, Any, Dict, List, Match, Union | |
| from ..core import BlockState | |
| from ..helpers import LINK_LABEL | |
| from ..util import unikey | |
| if TYPE_CHECKING: | |
| from ..block_parser import BlockParser | |
| from ..core import BaseRenderer, InlineState | |
| from ..inline_parser import InlineParser | |
| from ..markdown import Markdown | |
| __all__ = ["footnotes"] | |
| _PARAGRAPH_SPLIT = re.compile(r"\n{2,}") | |
| # https://michelf.ca/projects/php-markdown/extra/#footnotes | |
| REF_FOOTNOTE = ( | |
| r"^(?P<footnote_lead> {0,3})" | |
| r"\[\^(?P<footnote_key>" + LINK_LABEL + r")]:[ \t]" | |
| r"(?P<footnote_text>[^\n]*(?:\n+|$)" | |
| r"(?:(?P=footnote_lead) {1,3}(?! )[^\n]*\n+)*" | |
| r")" | |
| ) | |
| INLINE_FOOTNOTE = r"\[\^(?P<footnote_key>" + LINK_LABEL + r")\]" | |
| def parse_inline_footnote(inline: "InlineParser", m: Match[str], state: "InlineState") -> int: | |
| key = unikey(m.group("footnote_key")) | |
| ref = state.env.get("ref_footnotes") | |
| if ref and key in ref: | |
| notes = state.env.get("footnotes") | |
| if not notes: | |
| notes = [] | |
| if key not in notes: | |
| notes.append(key) | |
| state.env["footnotes"] = notes | |
| state.append_token({"type": "footnote_ref", "raw": key, "attrs": {"index": notes.index(key) + 1}}) | |
| else: | |
| state.append_token({"type": "text", "raw": m.group(0)}) | |
| return m.end() | |
| def parse_ref_footnote(block: "BlockParser", m: Match[str], state: BlockState) -> int: | |
| ref = state.env.get("ref_footnotes") | |
| if not ref: | |
| ref = {} | |
| key = unikey(m.group("footnote_key")) | |
| if key not in ref: | |
| ref[key] = m.group("footnote_text") | |
| state.env["ref_footnotes"] = ref | |
| return m.end() | |
| def parse_footnote_item(block: "BlockParser", key: str, index: int, state: BlockState) -> Dict[str, Any]: | |
| ref = state.env.get("ref_footnotes") | |
| if not ref: | |
| raise ValueError("Missing 'ref_footnotes'.") | |
| text = ref[key] | |
| lines = text.splitlines() | |
| second_line = None | |
| for second_line in lines[1:]: | |
| if second_line: | |
| break | |
| if second_line: | |
| spaces = len(second_line) - len(second_line.lstrip()) | |
| pattern = re.compile(r"^ {" + str(spaces) + r",}", flags=re.M) | |
| text = pattern.sub("", text).strip() | |
| items = _PARAGRAPH_SPLIT.split(text) | |
| children = [{"type": "paragraph", "text": s} for s in items] | |
| else: | |
| text = text.strip() | |
| children = [{"type": "paragraph", "text": text}] | |
| return {"type": "footnote_item", "children": children, "attrs": {"key": key, "index": index}} | |
| def md_footnotes_hook( | |
| md: "Markdown", result: Union[str, List[Dict[str, Any]]], state: BlockState | |
| ) -> Union[str, List[Dict[str, Any]]]: | |
| notes = state.env.get("footnotes") | |
| if not notes: | |
| return result | |
| children = [parse_footnote_item(md.block, k, i + 1, state) for i, k in enumerate(notes)] | |
| state = BlockState() | |
| state.tokens = [{"type": "footnotes", "children": children}] | |
| output = md.render_state(state) | |
| return result + output # type: ignore[operator] | |
| def render_footnote_ref(renderer: "BaseRenderer", key: str, index: int) -> str: | |
| i = str(index) | |
| html = '<sup class="footnote-ref" id="fnref-' + i + '">' | |
| return html + '<a href="#fn-' + i + '">' + i + "</a></sup>" | |
| def render_footnotes(renderer: "BaseRenderer", text: str) -> str: | |
| return '<section class="footnotes">\n<ol>\n' + text + "</ol>\n</section>\n" | |
| def render_footnote_item(renderer: "BaseRenderer", text: str, key: str, index: int) -> str: | |
| i = str(index) | |
| back = '<a href="#fnref-' + i + '" class="footnote">↩</a>' | |
| text = text.rstrip()[:-4] + back + "</p>" | |
| return '<li id="fn-' + i + '">' + text + "</li>\n" | |
| def footnotes(md: "Markdown") -> None: | |
| """A mistune plugin to support footnotes, spec defined at | |
| https://michelf.ca/projects/php-markdown/extra/#footnotes | |
| Here is an example: | |
| .. code-block:: text | |
| That's some text with a footnote.[^1] | |
| [^1]: And that's the footnote. | |
| It will be converted into HTML: | |
| .. code-block:: html | |
| <p>That's some text with a footnote.<sup class="footnote-ref" id="fnref-1"><a href="#fn-1">1</a></sup></p> | |
| <section class="footnotes"> | |
| <ol> | |
| <li id="fn-1"><p>And that's the footnote.<a href="#fnref-1" class="footnote">↩</a></p></li> | |
| </ol> | |
| </section> | |
| :param md: Markdown instance | |
| """ | |
| md.inline.register( | |
| "footnote", | |
| INLINE_FOOTNOTE, | |
| parse_inline_footnote, | |
| before="link", | |
| ) | |
| md.block.register( | |
| "ref_footnote", | |
| REF_FOOTNOTE, | |
| parse_ref_footnote, | |
| before="ref_link", | |
| ) | |
| md.after_render_hooks.append(md_footnotes_hook) | |
| if md.renderer and md.renderer.NAME == "html": | |
| md.renderer.register("footnote_ref", render_footnote_ref) | |
| md.renderer.register("footnote_item", render_footnote_item) | |
| md.renderer.register("footnotes", render_footnotes) | |