Fix pair tag formatting
This commit is contained in:
parent
2a71d4733a
commit
f684695836
|
@ -47,13 +47,13 @@ class BoldSpan(SpanContainer):
|
||||||
class ItalicSpan(SpanContainer):
|
class ItalicSpan(SpanContainer):
|
||||||
"""A span of text inside italic marks"""
|
"""A span of text inside italic marks"""
|
||||||
|
|
||||||
class CitationSpan(Renderable):
|
class CitationSpan(SpanContainer):
|
||||||
"""A citation to another article"""
|
"""A citation to another article"""
|
||||||
def __init__(self, cite_text, cite_target):
|
def __init__(self, spans, cite_target):
|
||||||
self.cite_text = cite_text
|
super().__init__(spans)
|
||||||
self.cite_target = cite_target
|
self.cite_target = cite_target
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{{{self.cite_text}:{self.cite_target}}}"
|
return f"{{{' '.join([str(span) for span in self.spans])}:{self.cite_target}}}"
|
||||||
|
|
||||||
|
|
||||||
def parse_raw_markdown(text):
|
def parse_raw_markdown(text):
|
||||||
|
@ -67,46 +67,83 @@ def parse_paragraph(text):
|
||||||
# Parse the paragraph as a span of text
|
# Parse the paragraph as a span of text
|
||||||
text = text.strip()
|
text = text.strip()
|
||||||
if text and text[0] == '~':
|
if text and text[0] == '~':
|
||||||
return SignatureParagraph(parse_citations(text[1:]))
|
return SignatureParagraph(parse_paired_formatting(text[1:]))
|
||||||
else:
|
else:
|
||||||
return BodyParagraph(parse_citations(text))
|
return BodyParagraph(parse_paired_formatting(text))
|
||||||
|
|
||||||
def parse_citations(text):
|
def parse_paired_formatting(text, cite=True, bold=True, italic=True):
|
||||||
|
# Find positions of any paired formatting
|
||||||
|
first_cite = text.find("[[") if cite else -1
|
||||||
|
first_bold = text.find("**") if bold else -1
|
||||||
|
first_italic = text.find("//") if italic else -1
|
||||||
|
# Load the possible parse handlers into the map
|
||||||
|
handlers = {}
|
||||||
|
handlers[first_cite] = lambda: parse_citation(text, bold=bold, italic=italic)
|
||||||
|
handlers[first_bold] = lambda: parse_bold(text, cite=cite, italic=italic)
|
||||||
|
handlers[first_italic] = lambda: parse_italic(text, cite=cite, bold=bold)
|
||||||
|
# If nothing was found, move on to the next parsing step
|
||||||
|
handlers[-1] = lambda: parse_breaks(text)
|
||||||
|
# Choose a handler based on the earliest found result
|
||||||
|
finds = [i for i in (first_cite, first_bold, first_italic) if i > -1]
|
||||||
|
first = min(finds) if finds else -1
|
||||||
|
return handlers[first]()
|
||||||
|
|
||||||
|
def parse_citation(text, bold=True, italic=True):
|
||||||
cite_open = text.find("[[")
|
cite_open = text.find("[[")
|
||||||
if cite_open > -1:
|
if cite_open > -1:
|
||||||
cite_close = text.find("]]", cite_open + 2)
|
cite_close = text.find("]]", cite_open + 2)
|
||||||
spans_before = parse_bold(text[:cite_open])
|
# Since we searched for pairs from the beginning, there should be no
|
||||||
spans_after = parse_citations(text[cite_close+2:])
|
# undetected pair formatting before this one, so move to the next
|
||||||
text_inner = text[cite_open+2:cite_close]
|
# level of parsing
|
||||||
alias_split = text_inner.split("|", 1)
|
spans_before = parse_breaks(text[:cite_open])
|
||||||
citation = CitationSpan(alias_split[0], alias_split[-1])
|
# Continue parsing pair formatting after this one closes with all
|
||||||
|
# three as valid choices
|
||||||
|
spans_after = parse_paired_formatting(text[cite_close + 2:])
|
||||||
|
# Parse inner text and skip parsing for this format pair
|
||||||
|
text_inner = text[cite_open + 2:cite_close]
|
||||||
|
# For citations specifically, we may need to split off a citation
|
||||||
|
# target from the alias text
|
||||||
|
inner_split = text_inner.split("|", 1)
|
||||||
|
text_inner_actual, cite_target = inner_split[0], inner_split[-1]
|
||||||
|
spans_inner = parse_paired_formatting(text_inner_actual,
|
||||||
|
cite=False, bold=bold, italic=italic)
|
||||||
|
citation = CitationSpan(spans_inner, cite_target)
|
||||||
return spans_before + [citation] + spans_after
|
return spans_before + [citation] + spans_after
|
||||||
# No citations, just parse the regular formatting
|
# Should never happen
|
||||||
return parse_bold(text)
|
return parse_breaks(text)
|
||||||
|
|
||||||
def parse_bold(text):
|
def parse_bold(text, cite=True, italic=True):
|
||||||
bold_open = text.find("**")
|
bold_open = text.find("**")
|
||||||
if bold_open > -1:
|
if bold_open > -1:
|
||||||
bold_close = text.find("**", bold_open + 2)
|
bold_close = text.find("**", bold_open + 2)
|
||||||
spans_before = parse_italic(text[:bold_open])
|
# Should be no formatting behind us
|
||||||
spans_after = parse_bold(text[bold_close+2:])
|
spans_before = parse_breaks(text[:bold_open])
|
||||||
spans_inner = parse_italic(text[bold_open+2:bold_close])
|
# Freely parse formatting after us
|
||||||
|
spans_after = parse_paired_formatting(text[bold_close+2:])
|
||||||
|
# Parse inner text minus bold parsing
|
||||||
|
text_inner = text[bold_open+2:bold_close]
|
||||||
|
spans_inner = parse_paired_formatting(text_inner,
|
||||||
|
cite=cite, bold=False, italic=italic)
|
||||||
bold = BoldSpan(spans_inner)
|
bold = BoldSpan(spans_inner)
|
||||||
return spans_before + [bold] + spans_after
|
return spans_before + [bold] + spans_after
|
||||||
|
# Should never happen
|
||||||
return parse_italic(text)
|
return parse_italic(text)
|
||||||
|
|
||||||
def parse_italic(text):
|
def parse_italic(text, cite=True, bold=True):
|
||||||
italic_open = text.find("//")
|
italic_open = text.find("//")
|
||||||
if italic_open > -1:
|
if italic_open > -1:
|
||||||
italic_close = text.find("//", italic_open + 2)
|
italic_close = text.find("//", italic_open + 2)
|
||||||
text_before = text[:italic_open]
|
# Should be no formatting behind us
|
||||||
|
spans_before = parse_breaks(text[:italic_open])
|
||||||
|
# Freely parse formatting after us
|
||||||
|
spans_after = parse_paired_formatting(text[italic_close+2:])
|
||||||
|
# Parse inner text minus italic parsing
|
||||||
text_inner = text[italic_open+2:italic_close]
|
text_inner = text[italic_open+2:italic_close]
|
||||||
text_after = text[italic_close+2:]
|
spans_inner = parse_paired_formatting(text_inner,
|
||||||
spans_before = parse_breaks(text_before)
|
cite=cite, bold=bold, italic=False)
|
||||||
spans_after = parse_italic(text_after)
|
|
||||||
spans_inner = parse_breaks(text_inner)
|
|
||||||
italic = ItalicSpan(spans_inner)
|
italic = ItalicSpan(spans_inner)
|
||||||
return spans_before + [italic] + spans_after
|
return spans_before + [italic] + spans_after
|
||||||
|
# Should never happen
|
||||||
return parse_breaks(text)
|
return parse_breaks(text)
|
||||||
|
|
||||||
def parse_breaks(text):
|
def parse_breaks(text):
|
||||||
|
|
Loading…
Reference in New Issue