Building Project Files

هذا الالتزام موجود في:
ahmedgamalyousef
2025-09-27 23:34:33 +03:00
التزام bb279b263f
1831 ملفات معدلة مع 330295 إضافات و0 حذوفات

عرض الملف

عرض الملف

@@ -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)

عرض الملف

@@ -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"

عرض الملف

@@ -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)

عرض الملف

@@ -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)