diff --git a/backend/models.py b/backend/models.py
index a323b6d..38c826c 100644
--- a/backend/models.py
+++ b/backend/models.py
@@ -1,5 +1,4 @@
"""Models for backend app"""
-
from django.conf import settings
from django.db.models import (
Model,
diff --git a/backend/templates/songs/fragments/song.html b/backend/templates/songs/fragments/song.html
deleted file mode 100644
index d43406e..0000000
--- a/backend/templates/songs/fragments/song.html
+++ /dev/null
@@ -1,42 +0,0 @@
-{% load i18n %}
-{% load markdown %}
-
-
- {{ song.song_number }}
- {{ song.text }}
- {{ song.name }}
- {{ song.author }}
-
-
{{ song.song_number }}. {{ song.name }}
- {% if song.author %}
- {{ song.author }}
- {% endif %}
-
- {% if user.is_authenticated %}
-
-
- {% endif %}
-
-
-
- {% if song.capo > 0 %}
Capo {{ song.capo }}
{% endif %}
-
-
- {{ song.text|show_markdown|safe }}
-
-
-
\ No newline at end of file
diff --git a/backend/templates/songs/song.html b/backend/templates/songs/song.html
deleted file mode 100644
index 7f1d46b..0000000
--- a/backend/templates/songs/song.html
+++ /dev/null
@@ -1,37 +0,0 @@
-{% load markdown %}
-{% load i18n %}
-
-{{ song.song_number }}
-{{ song.text }}
-{{ song.name }}
-{{ song.author }}
-
-
{{ song.song_number }}. {{ song.name }} {% if song.capo %}/Capo {{ song.capo }}/{% endif %}
- {% if song.author %}
- {{ song.author }}
- {% endif %}
- {% if user.is_authenticated %}
-
-
- {% endif %}
-
-
-
-
- {{ song.text|show_markdown|safe }}
-
-
\ No newline at end of file
diff --git a/backend/templatetags/markdown.py b/backend/templatetags/markdown.py
new file mode 100644
index 0000000..e69de29
diff --git a/chords/markdown.py b/chords/markdown.py
index 7acbde4..b6af3c6 100644
--- a/chords/markdown.py
+++ b/chords/markdown.py
@@ -1,14 +1,18 @@
"""Module containing Rendering function for converting Markdown to HTML"""
-from django.conf import settings
-from markdown import Markdown
+import mistune
+from chords.plugins.chords import chords
+from chords.plugins.paragraph import paragraph
+from chords.plugins.spaces import spaces
-def create_markdown(extensions=None):
- """Creates new Markdown instance"""
- if extensions is None:
- extensions = settings.MARKDOWNX_MARKDOWN_EXTENSIONS
- return Markdown(extensions=extensions, extension_configs={})
+class CustomHTMLRenderer(mistune.HTMLRenderer):
+ """Soft breaks are also breaks"""
+ def softbreak(self) -> str:
+ return r"
"
-RENDERER = create_markdown().convert
+
+RENDERER = mistune.create_markdown(
+ escape=False, plugins=[paragraph, chords, spaces], renderer=CustomHTMLRenderer(escape=False)
+)
diff --git a/chords/plugins/chords.py b/chords/plugins/chords.py
index 679257d..8b40a0e 100644
--- a/chords/plugins/chords.py
+++ b/chords/plugins/chords.py
@@ -1,26 +1,28 @@
"""Markdown extension for chords"""
-from markdown.extensions import Extension
-from markdown.inlinepatterns import SimpleTagInlineProcessor
+from mistune import InlineState
-CHORD_RE = r"({)(.*?)}"
+CHORD_RE = r"\{(?!\s)(?P.+?)(?!\s)\}"
-class ChordsExtension(Extension):
- """Markdown extension for convert {chord} into chords"""
+# pylint: disable=unused-argument
+def parse_chords(inline, m, state: InlineState):
+ """Parses tag"""
+ text = m.group("chords")
+ state.append_token({"type": "inline_chords", "raw": text})
+ return m.end()
- def extendMarkdown(self, md):
- # Insert del pattern into markdown parser
- md.inlinePatterns.register(ChordPattern(CHORD_RE), "chord", 175)
+def render_chords(renderer, text):
+ """Renders tag into HTML"""
+ return r'' + text + r" "
-class ChordPattern(SimpleTagInlineProcessor):
- """Pattern for ChordsExtension"""
- def __init__(self, pattern):
- super().__init__(pattern, "span")
+def chords(md):
+ """A mistune plugin to support chords.
+ Inline chords are surrounded by `{}`, such as {Ami}
- def handleMatch(self, m, data):
- tag, start, end = super().handleMatch(m, data)
- tag.set("class", "chord")
- tag.text += " "
- return tag, start, end
+ :param md: Markdown instance
+ """
+ md.inline.register("inline_chords", CHORD_RE, parse_chords, before="link")
+ if md.renderer and md.renderer.NAME == "html":
+ md.renderer.register("inline_chords", render_chords)
diff --git a/chords/plugins/paragraph.py b/chords/plugins/paragraph.py
new file mode 100644
index 0000000..49372b1
--- /dev/null
+++ b/chords/plugins/paragraph.py
@@ -0,0 +1,27 @@
+"""Markdown extension for paragraphs"""
+import re
+import string
+
+# because mismatch is too slow, add parsers for paragraph and text
+
+PARAGRAPH = (
+ # start with none punctuation, not number, not whitespace
+ r"(?:^[^\s\d"
+ + re.escape(string.punctuation)
+ + r"][^\n]*\n)+"
+)
+
+__all__ = ["paragraph"]
+
+
+# pylint: disable=unused-argument
+def parse_paragraph(block, m, state):
+ """Parse paragraph"""
+ text = m.group(0)
+ state.add_paragraph(text)
+ return m.end()
+
+
+def paragraph(md):
+ """Increase the speed of parsing paragraph"""
+ md.block.register("paragraph", PARAGRAPH, parse_paragraph)
diff --git a/chords/plugins/spaces.py b/chords/plugins/spaces.py
index ead7034..9ce7bc0 100644
--- a/chords/plugins/spaces.py
+++ b/chords/plugins/spaces.py
@@ -1,29 +1,28 @@
-"""Spaces markdown extension"""
-from markdown.extensions import Extension
-from markdown.inlinepatterns import SimpleTagInlineProcessor
+"""Markdown extension for spaces"""
+from mistune import InlineState
-SPACES_RE = r"(\/)(\d+)\/"
+SPACES_RE = r"\/(?P\d+)\/"
-class SpacesExtension(Extension):
- """Markdown extension that transforms /{number}/ into actual spaces"""
+# pylint: disable=unused-argument
+def parse_chords(inline, m, state: InlineState):
+ """Parses tag"""
+ text = m.group("spacers")
+ state.append_token({"type": "spaces", "raw": text})
+ return m.end()
- def extendMarkdown(self, md):
- md.inlinePatterns.register(SpacesPattern(SPACES_RE), "spaces", 200)
+def render_chords(renderer, text):
+ """Renders tag into HTML"""
+ return r" " * int(text)
-class SpacesPattern(SimpleTagInlineProcessor):
- """Pattern for SpacesExtension"""
- def __init__(self, pattern):
- super().__init__(pattern, "span")
+def spaces(md):
+ """A mistune plugin to insert amount of spaces.
+ Inline chords are surrounded by `/`, such as /5/
- def handleMatch(self, m, data):
- tag, start, end = super().handleMatch(m, data)
- tag.set("class", "spaces")
- count = int(tag.text)
- txt = ""
- for _ in range(count):
- txt += " "
- tag.text = txt
- return tag, start, end
+ :param md: Markdown instance
+ """
+ md.inline.register("spaces", SPACES_RE, parse_chords, before="link")
+ if md.renderer and md.renderer.NAME == "html":
+ md.renderer.register("spaces", render_chords)
diff --git a/chords/settings/base.py b/chords/settings/base.py
index 8679242..2745bae 100644
--- a/chords/settings/base.py
+++ b/chords/settings/base.py
@@ -15,11 +15,6 @@
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
from pathlib import Path
-from markdown.extensions.nl2br import Nl2BrExtension
-
-from chords.plugins.chords import ChordsExtension
-from chords.plugins.spaces import SpacesExtension
-
BASE_DIR = Path(__file__).resolve().parent.parent
@@ -49,12 +44,7 @@
"django_rq",
]
-MARKDOWNX_MARKDOWN_EXTENSIONS = [
- Nl2BrExtension(),
- ChordsExtension(),
- SpacesExtension(),
-]
-
+MARKDOWNX_MARKDOWNIFY_FUNCTION = "chords.markdown.RENDERER"
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
diff --git a/pdf/static/pdf.sass b/pdf/static/pdf.sass
index 948b85a..cd88872 100644
--- a/pdf/static/pdf.sass
+++ b/pdf/static/pdf.sass
@@ -1,11 +1,11 @@
@font-face
font-family: "Open Sans"
- src: url(/static/OpenSans-Regular.ttf)
+ src: url(OpenSans-Regular.ttf)
@font-face
font-family: "Open Sans"
font-weight: bold
- src: url(/static/OpenSans-Bold.ttf)
+ src: url(OpenSans-Bold.ttf)
@page
@bottom-left
diff --git a/pdf/templates/pdf/index.html b/pdf/templates/pdf/index.html
index 1d795cd..ef5f197 100644
--- a/pdf/templates/pdf/index.html
+++ b/pdf/templates/pdf/index.html
@@ -40,7 +40,7 @@
{% if request.title %}{{ name }}{% endif %}
{% if request.show_date %}
- {% now "m.d.Y" %}
+ {% now "d.m.Y" %}
{% endif %}
{% trans "Table of Contents" %}
diff --git a/pyproject.toml b/pyproject.toml
index fb13996..9483cc6 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -7,7 +7,7 @@ readme = "README.md"
[tool.poetry.dependencies]
python = "^3.9"
-django = "==4.2.5"
+django = "==4.2.7"
django-bootstrap4 = "*"
dj-datatables-view = "*"
django-debug-toolbar = "*"
@@ -21,7 +21,7 @@ weasyprint = ">=53.0"
Pillow = "*"
gunicorn = "*"
gevent = "*"
-markdown = "*"
+mistune = ">3"
netifaces = "*"
django-compressor = "*"
libsass = "*"