Browse Source
Fix various issues to make 'invoke type-check' happy:
- Check for Tag instances explicitly
- Return early if soup.body is empty
- Add rruleset to the type signature for rrulestr(value)
merge-requests/162/head
Bauke
2 months ago
No known key found for this signature in database
GPG Key ID: C1C0F29952BCF558
4 changed files with
20 additions and
4 deletions
-
tildes/tests/test_markdown.py
-
tildes/tildes/lib/database.py
-
tildes/tildes/lib/html.py
-
tildes/tildes/lib/markdown.py
|
|
@ -506,3 +506,10 @@ def test_a_rel_kept_user_bio_context(): |
|
|
|
) |
|
|
|
|
|
|
|
assert "rel=" in processed |
|
|
|
|
|
|
|
|
|
|
|
def test_apply_syntax_highlighting(): |
|
|
|
"""Ensure syntax highlighting is applied""" |
|
|
|
markdown = "```sql\nSELECT * FROM EXAMPLE;```" |
|
|
|
processed = convert_markdown_to_safe_html(markdown) |
|
|
|
assert 'class="highlight"' in processed |
|
|
@ -7,7 +7,7 @@ import enum |
|
|
|
from collections.abc import Callable |
|
|
|
from typing import Any, Optional |
|
|
|
|
|
|
|
from dateutil.rrule import rrule, rrulestr |
|
|
|
from dateutil.rrule import rrule, rruleset, rrulestr |
|
|
|
from pyramid.paster import bootstrap |
|
|
|
from sqlalchemy import cast, func |
|
|
|
from sqlalchemy.dialects.postgresql import ARRAY |
|
|
@ -174,7 +174,7 @@ class RecurrenceRule(TypeDecorator): |
|
|
|
|
|
|
|
def process_result_value( |
|
|
|
self, value: Optional[str], dialect: Dialect |
|
|
|
) -> Optional[rrule]: |
|
|
|
) -> Optional[rrule | rruleset]: |
|
|
|
"""Convert the stored string to an rrule.""" |
|
|
|
if value is None: |
|
|
|
return value |
|
|
|
|
|
@ -3,7 +3,7 @@ |
|
|
|
|
|
|
|
"""Functions related to HTML parsing/modification.""" |
|
|
|
|
|
|
|
from bs4 import BeautifulSoup |
|
|
|
from bs4 import BeautifulSoup, Tag |
|
|
|
|
|
|
|
from tildes.lib.string import convert_to_url_slug |
|
|
|
|
|
|
@ -15,6 +15,9 @@ def add_anchors_to_headings(html: str) -> str: |
|
|
|
headings = soup.find_all(["h1", "h2", "h3", "h4", "h5", "h6"]) |
|
|
|
|
|
|
|
for heading in headings: |
|
|
|
if not isinstance(heading, Tag): |
|
|
|
continue |
|
|
|
|
|
|
|
# generate an anchor from the string contents of the heading |
|
|
|
anchor = convert_to_url_slug("".join(heading.strings)) |
|
|
|
|
|
|
@ -28,5 +31,8 @@ def add_anchors_to_headings(html: str) -> str: |
|
|
|
|
|
|
|
heading.replace_with(new_heading) |
|
|
|
|
|
|
|
if soup.body is None: |
|
|
|
return "" |
|
|
|
|
|
|
|
# html5lib adds <html> and <body> tags around the fragment, strip them back out |
|
|
|
return "".join([str(tag) for tag in soup.body.children]) |
|
|
@ -10,7 +10,7 @@ from random import randint |
|
|
|
from typing import Any, Optional, Union |
|
|
|
|
|
|
|
import bleach |
|
|
|
from bs4 import BeautifulSoup |
|
|
|
from bs4 import BeautifulSoup, Tag |
|
|
|
from html5lib.filters.base import Filter |
|
|
|
from html5lib.treewalkers.base import NonRecursiveTreeWalker |
|
|
|
from pygments import highlight |
|
|
@ -270,6 +270,9 @@ def apply_syntax_highlighting(html: str) -> str: |
|
|
|
# Get all code blocks and for every code block that has info string |
|
|
|
code_blocks = soup.find_all("code", class_=re.compile("^language-")) |
|
|
|
for code_block in code_blocks: |
|
|
|
if not isinstance(code_block, Tag): |
|
|
|
continue |
|
|
|
|
|
|
|
language = code_block["class"][0].replace("language-", "") |
|
|
|
|
|
|
|
try: |
|
|
|