Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace Markdown package with Mistune #90

Merged
merged 5 commits into from
Dec 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion backend/models.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
"""Models for backend app"""

from django.conf import settings
from django.db.models import (
Model,
Expand Down
42 changes: 0 additions & 42 deletions backend/templates/songs/fragments/song.html

This file was deleted.

37 changes: 0 additions & 37 deletions backend/templates/songs/song.html

This file was deleted.

Empty file.
20 changes: 12 additions & 8 deletions chords/markdown.py
Original file line number Diff line number Diff line change
@@ -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"<br />"

RENDERER = create_markdown().convert

RENDERER = mistune.create_markdown(
escape=False, plugins=[paragraph, chords, spaces], renderer=CustomHTMLRenderer(escape=False)
)
36 changes: 19 additions & 17 deletions chords/plugins/chords.py
Original file line number Diff line number Diff line change
@@ -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<chords>.+?)(?!\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'<span class="chord">' + text + r"</span>&nbsp;"

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 += "&nbsp;"
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)
27 changes: 27 additions & 0 deletions chords/plugins/paragraph.py
Original file line number Diff line number Diff line change
@@ -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)
41 changes: 20 additions & 21 deletions chords/plugins/spaces.py
Original file line number Diff line number Diff line change
@@ -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<spacers>\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 += "&nbsp;"
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)
12 changes: 1 addition & 11 deletions chords/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down Expand Up @@ -49,12 +44,7 @@
"django_rq",
]

MARKDOWNX_MARKDOWN_EXTENSIONS = [
Nl2BrExtension(),
ChordsExtension(),
SpacesExtension(),
]

MARKDOWNX_MARKDOWNIFY_FUNCTION = "chords.markdown.RENDERER"

MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
Expand Down
4 changes: 2 additions & 2 deletions pdf/static/pdf.sass
Original file line number Diff line number Diff line change
@@ -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
Expand Down
2 changes: 1 addition & 1 deletion pdf/templates/pdf/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
<article id="contents">
<h1>{% if request.title %}{{ name }}{% endif %}</h1>
{% if request.show_date %}
<p class="date">{% now "m.d.Y" %}</p>
<p class="date">{% now "d.m.Y" %}</p>
{% endif %}
<h3 class="contents name">{% trans "Table of Contents" %}</h3>
<ul>
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 = "*"
Expand All @@ -21,7 +21,7 @@ weasyprint = ">=53.0"
Pillow = "*"
gunicorn = "*"
gevent = "*"
markdown = "*"
mistune = ">3"
netifaces = "*"
django-compressor = "*"
libsass = "*"
Expand Down