Skip to content

Commit 1d09013

Browse files
authored
Merge pull request #2694 from peterbe/support-toclinks-when-saving-markdown
Support toclinks when saving Markdown
2 parents f7b3b58 + 55689fc commit 1d09013

File tree

2 files changed

+87
-1
lines changed

2 files changed

+87
-1
lines changed

peterbecom/api/test_blogitem.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,3 +234,66 @@ def test_edit_blogitem(admin_client):
234234
assert response.status_code == 200
235235
blogitem.refresh_from_db()
236236
assert blogitem.proper_keywords == ["three", "four"]
237+
238+
239+
sample_markdown = """
240+
# Header 1
241+
242+
Textblock 1
243+
244+
## Header *2*
245+
246+
Textblock 2
247+
248+
### Header `three`
249+
250+
Moo boo
251+
252+
## 2 Headers
253+
254+
foo muu
255+
"""
256+
257+
258+
@pytest.mark.django_db
259+
def test_edit_blogitem_markdown_render(admin_client):
260+
blogitem = BlogItem.objects.create(
261+
oid="hello-world",
262+
title="Hello World",
263+
pub_date=timezone.now(),
264+
proper_keywords=["one", "two"],
265+
display_format="markdown",
266+
text=sample_markdown,
267+
)
268+
url = reverse("api:blogitem", args=["hello-world"])
269+
270+
cat1 = Category.objects.create(name="Code")
271+
response = admin_client.post(
272+
url,
273+
json.dumps(
274+
{
275+
"title": "New title",
276+
"oid": "new-oid",
277+
"summary": "New summary",
278+
"keywords": "three \n four ", # ["three ", " four "],
279+
"pub_date": json_datetime(timezone.now()),
280+
"categories": [cat1.id],
281+
"text": sample_markdown,
282+
"display_format": "markdown",
283+
}
284+
),
285+
content_type="application/json",
286+
)
287+
assert response.status_code == 200
288+
blogitem.refresh_from_db()
289+
290+
html = blogitem.text_rendered
291+
292+
assert (
293+
'<h2 id="header-1"><a class="toclink" href="#header-1">Header 1</a></h2>'
294+
in html
295+
)
296+
assert (
297+
'<h3 id="h-2-headers"><a class="toclink" href="#h-2-headers">2 Headers</a></h3>'
298+
in html
299+
)

peterbecom/plog/utils.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from django.core.exceptions import ValidationError
1919
from django.core.validators import validate_email
2020
from django.utils import timezone
21+
from markdown.extensions.toc import slugify as toc_slugify
2122

2223
# https://github.com/vzhou842/profanity-check is probably better but it requires
2324
# scikit-learn or whatever it's called.
@@ -27,6 +28,13 @@
2728
from .gfm import gfm
2829

2930

31+
def custom_toc_slugify(value: str, separator: str, unicode: bool = False) -> str:
32+
s = toc_slugify(value, separator, unicode)
33+
if s[0].isdigit():
34+
s = "h-" + s
35+
return s
36+
37+
3038
def blog_post_url(oid, page=None):
3139
if page and page != 1:
3240
return f"/plog/{oid}/p{page}"
@@ -223,7 +231,22 @@ def highlighter(m):
223231
return found
224232

225233
text = _markdown_pre_regex.sub(matcher, text)
226-
html = markdown.markdown(gfm(text), extensions=["markdown.extensions.tables"])
234+
html = markdown.markdown(
235+
gfm(text),
236+
extensions=[
237+
"tables",
238+
"toc",
239+
],
240+
extension_configs={
241+
"toc": {
242+
"anchorlink": True,
243+
"permalink": False,
244+
"baselevel": 2,
245+
"toc_depth": 3,
246+
"slugify": custom_toc_slugify,
247+
}
248+
},
249+
)
227250
html = html.replace("<pre><span></span>", "<pre>")
228251

229252
# Markdown leaves a strange whitespace before the end of the paragraph.

0 commit comments

Comments
 (0)