-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #270 from nofusscomputing/feat-2024-09-11
- Loading branch information
Showing
40 changed files
with
947 additions
and
217 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
import re | ||
|
||
from markdown_it import MarkdownIt | ||
|
||
from mdit_py_plugins import admon, anchors, footnote, tasklists | ||
|
||
from pygments import highlight | ||
from pygments.formatters.html import HtmlFormatter | ||
from pygments.lexers import get_lexer_by_name | ||
|
||
from django.template.loader import render_to_string | ||
|
||
from .markdown_plugins import ticket_number | ||
|
||
|
||
|
||
class Markdown: | ||
"""Ticket and Comment markdown functions | ||
Intended to be used for all areas of a tickets, projects and comments. | ||
""" | ||
|
||
|
||
def highlight_func(self, code: str, lang: str, _) -> str | None: | ||
"""Use pygments for code high lighting""" | ||
|
||
if not lang: | ||
|
||
return None | ||
|
||
lexer = get_lexer_by_name(lang) | ||
|
||
formatter = HtmlFormatter(style='vs', cssclass='codehilite') | ||
|
||
return highlight(code, lexer, formatter) | ||
|
||
|
||
def render_markdown(self, markdown_text): | ||
"""Render Markdown | ||
implemented using https://markdown-it-py.readthedocs.io/en/latest/index.html | ||
Args: | ||
markdown_text (str): Markdown text | ||
Returns: | ||
str: HTML text | ||
""" | ||
|
||
md = ( | ||
MarkdownIt( | ||
config = "commonmark", | ||
options_update={ | ||
'linkify': True, | ||
'highlight': self.highlight_func, | ||
} | ||
) | ||
|
||
.enable([ | ||
'linkify', | ||
'strikethrough', | ||
'table', | ||
]) | ||
|
||
.use(admon.admon_plugin) | ||
.use(anchors.anchors_plugin, permalink=True) | ||
.use(footnote.footnote_plugin) | ||
.use(tasklists.tasklists_plugin) | ||
.use(ticket_number.plugin, enabled=True) | ||
) | ||
|
||
return md.render(markdown_text) | ||
|
||
|
||
def build_ticket_html(self, match): | ||
|
||
ticket_id = match.group(1) | ||
|
||
try: | ||
if hasattr(self, 'ticket'): | ||
|
||
ticket = self.ticket.__class__.objects.get(pk=ticket_id) | ||
|
||
else: | ||
|
||
ticket = self.__class__.objects.get(pk=ticket_id) | ||
|
||
project_id = str('0') | ||
|
||
if ticket.project: | ||
|
||
project_id = str(ticket.project.id).lower() | ||
|
||
context: dict = { | ||
'id': ticket.id, | ||
'name': ticket, | ||
'ticket_type': str(ticket.get_ticket_type_display()).lower(), | ||
'ticket_status': str(ticket.get_status_display()).lower(), | ||
'project_id': project_id, | ||
} | ||
|
||
html_link = render_to_string('core/ticket/renderers/ticket_link.html.j2', context) | ||
|
||
return str(html_link) | ||
except: | ||
|
||
return str('#' + ticket_id) | ||
|
||
|
||
|
||
def ticket_reference(self, text): | ||
|
||
return re.sub('#(\d+)', self.build_ticket_html, text) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
|
||
import re | ||
|
||
from django.template.loader import render_to_string | ||
|
||
from markdown_it import MarkdownIt | ||
from markdown_it.rules_core import StateCore | ||
from markdown_it.token import Token | ||
|
||
# Regex string to match a whitespace character, as specified in | ||
# https://github.github.com/gfm/#whitespace-character | ||
# (spec version 0.29-gfm (2019-04-06)) | ||
_GFM_WHITESPACE_RE = r"[ \t\n\v\f\r]" | ||
|
||
|
||
def plugin( | ||
md: MarkdownIt, | ||
enabled: bool = False, | ||
) -> None: | ||
"""markdown_it plugin to render ticket numbers | ||
Placing `#<number>` within markdown will be rendered as a pretty link to the ticket. | ||
Args: | ||
md (MarkdownIt): markdown object | ||
enabled (bool, optional): Enable the parsing of ticket references. Defaults to False. | ||
Returns: | ||
None: nada | ||
""" | ||
|
||
def main(state: StateCore) -> None: | ||
|
||
tokens = state.tokens | ||
for i in range(0, len(tokens) - 1): | ||
if is_tag_item(tokens, i): | ||
tag_render(tokens[i]) | ||
|
||
|
||
def is_inline(token: Token) -> bool: | ||
return token.type == "inline" | ||
|
||
|
||
def is_tag_item(tokens: list[Token], index: int) -> bool: | ||
|
||
return ( | ||
is_inline(tokens[index]) | ||
and contains_tag_item(tokens[index]) | ||
) | ||
|
||
|
||
def tag_html(match): | ||
|
||
ticket_id = match.group(1) | ||
|
||
try: | ||
from core.models.ticket.ticket import Ticket | ||
|
||
ticket = Ticket.objects.get(pk=ticket_id) | ||
|
||
project_id = str('0') | ||
|
||
if ticket.project: | ||
|
||
project_id = str(ticket.project.id).lower() | ||
|
||
context: dict = { | ||
'id': ticket.id, | ||
'name': ticket, | ||
'ticket_type': str(ticket.get_ticket_type_display()).lower(), | ||
'ticket_status': str(ticket.get_status_display()).lower(), | ||
'project_id': project_id, | ||
} | ||
|
||
html_link = render_to_string('core/ticket/renderers/ticket_link.html.j2', context) | ||
|
||
return html_link | ||
except: | ||
|
||
return str('#' + ticket_id) | ||
|
||
|
||
def tag_render(token: Token) -> None: | ||
assert token.children is not None | ||
|
||
checkbox = Token("html_inline", "", 0) | ||
|
||
checkbox.content = tag_replace(token.content) | ||
|
||
token.children[0] = checkbox | ||
|
||
|
||
def tag_replace(text): | ||
|
||
return re.sub('#(\d+)', tag_html, text) | ||
|
||
def contains_tag_item(token: Token) -> bool: | ||
|
||
return re.match(rf"(.+)?#(\d+){_GFM_WHITESPACE_RE}?(.+)?", token.content) is not None | ||
|
||
if enabled: | ||
|
||
md.core.ruler.after("inline", "links", fn=main) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.