blob: 3a4e87aa960ea85f810a467610c70dc2418258a6 [file] [log] [blame]
import re
from pyparsing import (
ParserElement,
ParseResults,
QuotedString,
StringStart,
SkipTo,
Literal,
LineEnd,
Combine,
Literal,
replaceWith,
)
from jira2markdown.markup.base import AbstractMarkup
class TweakedBlockQuote(AbstractMarkup):
def action(self, tokens: ParseResults) -> str:
text = self.markup.transformString("\n".join([line.lstrip() for line in tokens[0].strip().splitlines()]))
# escape numbered list in quotes.
# e.g.,
# {quote}
# 2. foo
# 5. bar
# {quote}
# should be
# > 2\\. foo
# > 5\\. bar
pat_ordered_list = re.compile(r"((?<=^\d)||(?<=^\d\d))\.")
return "\n".join(["> " + re.sub(pat_ordered_list, '\.', line) for line in text.splitlines()]) + "\n" # needs additional line feed at the end of quotation to preserve indentation
@property
def expr(self) -> ParserElement:
return QuotedString("{quote}", multiline=True).setParseAction(self.action)
class TweakedQuote(AbstractMarkup):
is_inline_element = False
@property
def expr(self) -> ParserElement:
return ("\n" | StringStart()) + Combine(
Literal("bq. ").setParseAction(replaceWith("> "))
+ SkipTo(LineEnd()) + LineEnd().setParseAction(replaceWith("\n\n")) # needs additional line feed at the end of quotation to preserve indentation
)
class TweakedMonospaced(AbstractMarkup):
def action(self, tokens: ParseResults) -> str:
# remove extra brackets in {{monospaced}}
# e.g. {{{}BooleanScorer{}}}
token = re.sub(r"^[{}]+", "", tokens[0])
token = re.sub(r"[{}]+$", "", token)
return f"`{token}`"
@property
def expr(self) -> ParserElement:
return QuotedString("{{", endQuoteChar="}}").setParseAction(self.action)
class EscapeHtml(AbstractMarkup):
"""
Escapes HTML characters that are not a part of any expression grammar
"""
@property
def expr(self) -> ParserElement:
return Literal("<").setParseAction(replaceWith("&lt;")) ^ Literal(">").setParseAction(replaceWith("&gt;")) ^ Literal("&").setParseAction(replaceWith("&amp;"))