Building Project Files
هذا الالتزام موجود في:
ملف ثنائي غير معروض.
ملف ثنائي غير معروض.
ملف ثنائي غير معروض.
ملف ثنائي غير معروض.
ملف ثنائي غير معروض.
70
venv/lib/python3.12/site-packages/mistune/renderers/_list.py
Normal file
70
venv/lib/python3.12/site-packages/mistune/renderers/_list.py
Normal file
@@ -0,0 +1,70 @@
|
||||
from typing import TYPE_CHECKING, Any, Dict, Iterable, cast
|
||||
|
||||
from ..util import strip_end
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ..core import BaseRenderer, BlockState
|
||||
|
||||
|
||||
def render_list(renderer: "BaseRenderer", token: Dict[str, Any], state: "BlockState") -> str:
|
||||
attrs = token["attrs"]
|
||||
if attrs["ordered"]:
|
||||
children = _render_ordered_list(renderer, token, state)
|
||||
else:
|
||||
children = _render_unordered_list(renderer, token, state)
|
||||
|
||||
text = "".join(children)
|
||||
parent = token.get("parent")
|
||||
if parent:
|
||||
if parent["tight"]:
|
||||
return text
|
||||
return text + "\n"
|
||||
return strip_end(text) + "\n"
|
||||
|
||||
|
||||
def _render_list_item(
|
||||
renderer: "BaseRenderer",
|
||||
parent: Dict[str, Any],
|
||||
item: Dict[str, Any],
|
||||
state: "BlockState",
|
||||
) -> str:
|
||||
leading = cast(str, parent["leading"])
|
||||
text = ""
|
||||
for tok in item["children"]:
|
||||
if tok["type"] == "list":
|
||||
tok["parent"] = parent
|
||||
elif tok["type"] == "blank_line":
|
||||
continue
|
||||
text += renderer.render_token(tok, state)
|
||||
|
||||
lines = text.splitlines()
|
||||
text = (lines[0] if lines else "") + "\n"
|
||||
prefix = " " * len(leading)
|
||||
for line in lines[1:]:
|
||||
if line:
|
||||
text += prefix + line + "\n"
|
||||
else:
|
||||
text += "\n"
|
||||
return leading + text
|
||||
|
||||
|
||||
def _render_ordered_list(renderer: "BaseRenderer", token: Dict[str, Any], state: "BlockState") -> Iterable[str]:
|
||||
attrs = token["attrs"]
|
||||
start = attrs.get("start", 1)
|
||||
for item in token["children"]:
|
||||
leading = str(start) + token["bullet"] + " "
|
||||
parent = {
|
||||
"leading": leading,
|
||||
"tight": token["tight"],
|
||||
}
|
||||
yield _render_list_item(renderer, parent, item, state)
|
||||
start += 1
|
||||
|
||||
|
||||
def _render_unordered_list(renderer: "BaseRenderer", token: Dict[str, Any], state: "BlockState") -> Iterable[str]:
|
||||
parent = {
|
||||
"leading": token["bullet"] + " ",
|
||||
"tight": token["tight"],
|
||||
}
|
||||
for item in token["children"]:
|
||||
yield _render_list_item(renderer, parent, item, state)
|
153
venv/lib/python3.12/site-packages/mistune/renderers/html.py
Normal file
153
venv/lib/python3.12/site-packages/mistune/renderers/html.py
Normal file
@@ -0,0 +1,153 @@
|
||||
from typing import Any, ClassVar, Dict, Optional, Tuple, Literal
|
||||
from ..core import BaseRenderer, BlockState
|
||||
from ..util import escape as escape_text
|
||||
from ..util import safe_entity, striptags
|
||||
|
||||
|
||||
class HTMLRenderer(BaseRenderer):
|
||||
"""A renderer for converting Markdown to HTML."""
|
||||
|
||||
_escape: bool
|
||||
NAME: ClassVar[Literal["html"]] = "html"
|
||||
HARMFUL_PROTOCOLS: ClassVar[Tuple[str, ...]] = (
|
||||
"javascript:",
|
||||
"vbscript:",
|
||||
"file:",
|
||||
"data:",
|
||||
)
|
||||
GOOD_DATA_PROTOCOLS: ClassVar[Tuple[str, ...]] = (
|
||||
"data:image/gif;",
|
||||
"data:image/png;",
|
||||
"data:image/jpeg;",
|
||||
"data:image/webp;",
|
||||
)
|
||||
|
||||
def __init__(self, escape: bool = True, allow_harmful_protocols: Optional[bool] = None) -> None:
|
||||
super(HTMLRenderer, self).__init__()
|
||||
self._allow_harmful_protocols = allow_harmful_protocols
|
||||
self._escape = escape
|
||||
|
||||
def render_token(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
# backward compitable with v2
|
||||
func = self._get_method(token["type"])
|
||||
attrs = token.get("attrs")
|
||||
|
||||
if "raw" in token:
|
||||
text = token["raw"]
|
||||
elif "children" in token:
|
||||
text = self.render_tokens(token["children"], state)
|
||||
else:
|
||||
if attrs:
|
||||
return func(**attrs)
|
||||
else:
|
||||
return func()
|
||||
if attrs:
|
||||
return func(text, **attrs)
|
||||
else:
|
||||
return func(text)
|
||||
|
||||
def safe_url(self, url: str) -> str:
|
||||
"""Ensure the given URL is safe. This method is used for rendering
|
||||
links, images, and etc.
|
||||
"""
|
||||
if self._allow_harmful_protocols is True:
|
||||
return escape_text(url)
|
||||
|
||||
_url = url.lower()
|
||||
if self._allow_harmful_protocols and _url.startswith(tuple(self._allow_harmful_protocols)):
|
||||
return escape_text(url)
|
||||
|
||||
if _url.startswith(self.HARMFUL_PROTOCOLS) and not _url.startswith(self.GOOD_DATA_PROTOCOLS):
|
||||
return "#harmful-link"
|
||||
return escape_text(url)
|
||||
|
||||
def text(self, text: str) -> str:
|
||||
if self._escape:
|
||||
return escape_text(text)
|
||||
return safe_entity(text)
|
||||
|
||||
def emphasis(self, text: str) -> str:
|
||||
return "<em>" + text + "</em>"
|
||||
|
||||
def strong(self, text: str) -> str:
|
||||
return "<strong>" + text + "</strong>"
|
||||
|
||||
def link(self, text: str, url: str, title: Optional[str] = None) -> str:
|
||||
s = '<a href="' + self.safe_url(url) + '"'
|
||||
if title:
|
||||
s += ' title="' + safe_entity(title) + '"'
|
||||
return s + ">" + text + "</a>"
|
||||
|
||||
def image(self, text: str, url: str, title: Optional[str] = None) -> str:
|
||||
src = self.safe_url(url)
|
||||
alt = escape_text(striptags(text))
|
||||
s = '<img src="' + src + '" alt="' + alt + '"'
|
||||
if title:
|
||||
s += ' title="' + safe_entity(title) + '"'
|
||||
return s + " />"
|
||||
|
||||
def codespan(self, text: str) -> str:
|
||||
return "<code>" + escape_text(text) + "</code>"
|
||||
|
||||
def linebreak(self) -> str:
|
||||
return "<br />\n"
|
||||
|
||||
def softbreak(self) -> str:
|
||||
return "\n"
|
||||
|
||||
def inline_html(self, html: str) -> str:
|
||||
if self._escape:
|
||||
return escape_text(html)
|
||||
return html
|
||||
|
||||
def paragraph(self, text: str) -> str:
|
||||
return "<p>" + text + "</p>\n"
|
||||
|
||||
def heading(self, text: str, level: int, **attrs: Any) -> str:
|
||||
tag = "h" + str(level)
|
||||
html = "<" + tag
|
||||
_id = attrs.get("id")
|
||||
if _id:
|
||||
html += ' id="' + _id + '"'
|
||||
return html + ">" + text + "</" + tag + ">\n"
|
||||
|
||||
def blank_line(self) -> str:
|
||||
return ""
|
||||
|
||||
def thematic_break(self) -> str:
|
||||
return "<hr />\n"
|
||||
|
||||
def block_text(self, text: str) -> str:
|
||||
return text
|
||||
|
||||
def block_code(self, code: str, info: Optional[str] = None) -> str:
|
||||
html = "<pre><code"
|
||||
if info is not None:
|
||||
info = safe_entity(info.strip())
|
||||
if info:
|
||||
lang = info.split(None, 1)[0]
|
||||
html += ' class="language-' + lang + '"'
|
||||
return html + ">" + escape_text(code) + "</code></pre>\n"
|
||||
|
||||
def block_quote(self, text: str) -> str:
|
||||
return "<blockquote>\n" + text + "</blockquote>\n"
|
||||
|
||||
def block_html(self, html: str) -> str:
|
||||
if self._escape:
|
||||
return "<p>" + escape_text(html.strip()) + "</p>\n"
|
||||
return html + "\n"
|
||||
|
||||
def block_error(self, text: str) -> str:
|
||||
return '<div class="error"><pre>' + text + "</pre></div>\n"
|
||||
|
||||
def list(self, text: str, ordered: bool, **attrs: Any) -> str:
|
||||
if ordered:
|
||||
html = "<ol"
|
||||
start = attrs.get("start")
|
||||
if start is not None:
|
||||
html += ' start="' + str(start) + '"'
|
||||
return html + ">\n" + text + "</ol>\n"
|
||||
return "<ul>\n" + text + "</ul>\n"
|
||||
|
||||
def list_item(self, text: str) -> str:
|
||||
return "<li>" + text + "</li>\n"
|
150
venv/lib/python3.12/site-packages/mistune/renderers/markdown.py
Normal file
150
venv/lib/python3.12/site-packages/mistune/renderers/markdown.py
Normal file
@@ -0,0 +1,150 @@
|
||||
import re
|
||||
from textwrap import indent
|
||||
from typing import Any, Dict, Iterable, cast
|
||||
|
||||
from ..core import BaseRenderer, BlockState
|
||||
from ..util import strip_end
|
||||
from ._list import render_list
|
||||
|
||||
fenced_re = re.compile(r"^[`~]+", re.M)
|
||||
|
||||
|
||||
class MarkdownRenderer(BaseRenderer):
|
||||
"""A renderer to re-format Markdown text."""
|
||||
|
||||
NAME = "markdown"
|
||||
|
||||
def __call__(self, tokens: Iterable[Dict[str, Any]], state: BlockState) -> str:
|
||||
out = self.render_tokens(tokens, state)
|
||||
# special handle for line breaks
|
||||
out += "\n\n".join(self.render_referrences(state)) + "\n"
|
||||
return strip_end(out)
|
||||
|
||||
def render_referrences(self, state: BlockState) -> Iterable[str]:
|
||||
ref_links = state.env["ref_links"]
|
||||
for key in ref_links:
|
||||
attrs = ref_links[key]
|
||||
text = "[" + attrs["label"] + "]: " + attrs["url"]
|
||||
title = attrs.get("title")
|
||||
if title:
|
||||
text += ' "' + title + '"'
|
||||
yield text
|
||||
|
||||
def render_children(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
children = token["children"]
|
||||
return self.render_tokens(children, state)
|
||||
|
||||
def text(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
return cast(str, token["raw"])
|
||||
|
||||
def emphasis(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
return "*" + self.render_children(token, state) + "*"
|
||||
|
||||
def strong(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
return "**" + self.render_children(token, state) + "**"
|
||||
|
||||
def link(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
label = cast(str, token.get("label"))
|
||||
text = self.render_children(token, state)
|
||||
out = "[" + text + "]"
|
||||
if label:
|
||||
return out + "[" + label + "]"
|
||||
|
||||
attrs = token["attrs"]
|
||||
url = attrs["url"]
|
||||
title = attrs.get("title")
|
||||
if text == url and not title:
|
||||
return "<" + text + ">"
|
||||
elif "mailto:" + text == url and not title:
|
||||
return "<" + text + ">"
|
||||
|
||||
out += "("
|
||||
if "(" in url or ")" in url:
|
||||
out += "<" + url + ">"
|
||||
else:
|
||||
out += url
|
||||
if title:
|
||||
out += ' "' + title + '"'
|
||||
return out + ")"
|
||||
|
||||
def image(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
return "!" + self.link(token, state)
|
||||
|
||||
def codespan(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
return "`" + cast(str, token["raw"]) + "`"
|
||||
|
||||
def linebreak(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
return " \n"
|
||||
|
||||
def softbreak(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
return "\n"
|
||||
|
||||
def blank_line(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
return ""
|
||||
|
||||
def inline_html(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
return cast(str, token["raw"])
|
||||
|
||||
def paragraph(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
text = self.render_children(token, state)
|
||||
return text + "\n\n"
|
||||
|
||||
def heading(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
level = cast(int, token["attrs"]["level"])
|
||||
marker = "#" * level
|
||||
text = self.render_children(token, state)
|
||||
return marker + " " + text + "\n\n"
|
||||
|
||||
def thematic_break(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
return "***\n\n"
|
||||
|
||||
def block_text(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
return self.render_children(token, state) + "\n"
|
||||
|
||||
def block_code(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
attrs = token.get("attrs", {})
|
||||
info = cast(str, attrs.get("info", ""))
|
||||
code = cast(str, token["raw"])
|
||||
if code and code[-1] != "\n":
|
||||
code += "\n"
|
||||
|
||||
marker = token.get("marker")
|
||||
if not marker:
|
||||
marker = _get_fenced_marker(code)
|
||||
marker2 = cast(str, marker)
|
||||
return marker2 + info + "\n" + code + marker2 + "\n\n"
|
||||
|
||||
def block_quote(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
text = indent(self.render_children(token, state), "> ", lambda _: True)
|
||||
text = text.rstrip("> \n")
|
||||
return text + "\n\n"
|
||||
|
||||
def block_html(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
return cast(str, token["raw"]) + "\n\n"
|
||||
|
||||
def block_error(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
return ""
|
||||
|
||||
def list(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
return render_list(self, token, state)
|
||||
|
||||
|
||||
def _get_fenced_marker(code: str) -> str:
|
||||
found = fenced_re.findall(code)
|
||||
if not found:
|
||||
return "```"
|
||||
|
||||
ticks = [] # `
|
||||
waves = [] # ~
|
||||
for s in found:
|
||||
if s[0] == "`":
|
||||
ticks.append(len(s))
|
||||
else:
|
||||
waves.append(len(s))
|
||||
|
||||
if not ticks:
|
||||
return "```"
|
||||
|
||||
if not waves:
|
||||
return "~~~"
|
||||
return "`" * (max(ticks) + 1)
|
149
venv/lib/python3.12/site-packages/mistune/renderers/rst.py
Normal file
149
venv/lib/python3.12/site-packages/mistune/renderers/rst.py
Normal file
@@ -0,0 +1,149 @@
|
||||
from textwrap import indent
|
||||
from typing import Any, Dict, Iterable, List, cast
|
||||
|
||||
from ..core import BaseRenderer, BlockState
|
||||
from ..util import strip_end
|
||||
from ._list import render_list
|
||||
|
||||
|
||||
class RSTRenderer(BaseRenderer):
|
||||
"""A renderer for converting Markdown to ReST."""
|
||||
|
||||
NAME = "rst"
|
||||
|
||||
#: marker symbols for heading
|
||||
HEADING_MARKERS = {
|
||||
1: "=",
|
||||
2: "-",
|
||||
3: "~",
|
||||
4: "^",
|
||||
5: '"',
|
||||
6: "'",
|
||||
}
|
||||
INLINE_IMAGE_PREFIX = "img-"
|
||||
|
||||
def iter_tokens(self, tokens: Iterable[Dict[str, Any]], state: BlockState) -> Iterable[str]:
|
||||
prev = None
|
||||
for tok in tokens:
|
||||
# ignore blank line
|
||||
if tok["type"] == "blank_line":
|
||||
continue
|
||||
tok["prev"] = prev
|
||||
prev = tok
|
||||
yield self.render_token(tok, state)
|
||||
|
||||
def __call__(self, tokens: Iterable[Dict[str, Any]], state: BlockState) -> str:
|
||||
state.env["inline_images"] = []
|
||||
out = self.render_tokens(tokens, state)
|
||||
# special handle for line breaks
|
||||
out += "\n\n".join(self.render_referrences(state)) + "\n"
|
||||
return strip_end(out)
|
||||
|
||||
def render_referrences(self, state: BlockState) -> Iterable[str]:
|
||||
images = state.env["inline_images"]
|
||||
for index, token in enumerate(images):
|
||||
attrs = token["attrs"]
|
||||
alt = self.render_children(token, state)
|
||||
ident = self.INLINE_IMAGE_PREFIX + str(index)
|
||||
yield ".. |" + ident + "| image:: " + attrs["url"] + "\n :alt: " + alt
|
||||
|
||||
def render_children(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
children = token["children"]
|
||||
return self.render_tokens(children, state)
|
||||
|
||||
def text(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
text = cast(str, token["raw"])
|
||||
return text.replace("|", r"\|")
|
||||
|
||||
def emphasis(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
return "*" + self.render_children(token, state) + "*"
|
||||
|
||||
def strong(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
return "**" + self.render_children(token, state) + "**"
|
||||
|
||||
def link(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
attrs = token["attrs"]
|
||||
text = self.render_children(token, state)
|
||||
return "`" + text + " <" + cast(str, attrs["url"]) + ">`__"
|
||||
|
||||
def image(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
refs: List[Dict[str, Any]] = state.env["inline_images"]
|
||||
index = len(refs)
|
||||
refs.append(token)
|
||||
return "|" + self.INLINE_IMAGE_PREFIX + str(index) + "|"
|
||||
|
||||
def codespan(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
return "``" + cast(str, token["raw"]) + "``"
|
||||
|
||||
def linebreak(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
return "<linebreak>"
|
||||
|
||||
def softbreak(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
return " "
|
||||
|
||||
def inline_html(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
# rst does not support inline html
|
||||
return ""
|
||||
|
||||
def paragraph(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
children = token["children"]
|
||||
if len(children) == 1 and children[0]["type"] == "image":
|
||||
image = children[0]
|
||||
attrs = image["attrs"]
|
||||
title = cast(str, attrs.get("title"))
|
||||
alt = self.render_children(image, state)
|
||||
text = ".. figure:: " + cast(str, attrs["url"])
|
||||
if title:
|
||||
text += "\n :alt: " + title
|
||||
text += "\n\n" + indent(alt, " ")
|
||||
else:
|
||||
text = self.render_tokens(children, state)
|
||||
lines = text.split("<linebreak>")
|
||||
if len(lines) > 1:
|
||||
text = "\n".join("| " + line for line in lines)
|
||||
return text + "\n\n"
|
||||
|
||||
def heading(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
attrs = token["attrs"]
|
||||
text = self.render_children(token, state)
|
||||
marker = self.HEADING_MARKERS[attrs["level"]]
|
||||
return text + "\n" + marker * len(text) + "\n\n"
|
||||
|
||||
def thematic_break(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
return "--------------\n\n"
|
||||
|
||||
def block_text(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
return self.render_children(token, state) + "\n"
|
||||
|
||||
def block_code(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
attrs = token.get("attrs", {})
|
||||
info = cast(str, attrs.get("info"))
|
||||
code = indent(cast(str, token["raw"]), " ")
|
||||
if info:
|
||||
lang = info.split()[0]
|
||||
return ".. code:: " + lang + "\n\n" + code + "\n"
|
||||
else:
|
||||
return "::\n\n" + code + "\n\n"
|
||||
|
||||
def block_quote(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
text = indent(self.render_children(token, state), " ")
|
||||
prev = token["prev"]
|
||||
ignore_blocks = (
|
||||
"paragraph",
|
||||
"thematic_break",
|
||||
"linebreak",
|
||||
"heading",
|
||||
)
|
||||
if prev and prev["type"] not in ignore_blocks:
|
||||
text = "..\n\n" + text
|
||||
return text
|
||||
|
||||
def block_html(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
raw = token["raw"]
|
||||
return ".. raw:: html\n\n" + indent(raw, " ") + "\n\n"
|
||||
|
||||
def block_error(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
return ""
|
||||
|
||||
def list(self, token: Dict[str, Any], state: BlockState) -> str:
|
||||
return render_list(self, token, state)
|
المرجع في مشكلة جديدة
حظر مستخدم