From 80bb7a3d28cf7c9ef6e671ac228f0da81f62848d Mon Sep 17 00:00:00 2001 From: Tim Van Baak Date: Wed, 9 Jun 2021 15:47:54 -0700 Subject: [PATCH] Move render visitors out of parser module --- amanuensis/lexicon/gameloop.py | 48 +++++++++++- amanuensis/lexicon/manage.py | 2 +- amanuensis/parser/__init__.py | 3 - amanuensis/parser/render.py | 104 -------------------------- amanuensis/server/session/__init__.py | 6 +- amanuensis/server/session/editor.py | 52 ++++++++++++- 6 files changed, 100 insertions(+), 115 deletions(-) delete mode 100644 amanuensis/parser/render.py diff --git a/amanuensis/lexicon/gameloop.py b/amanuensis/lexicon/gameloop.py index 3e51150..d606d57 100644 --- a/amanuensis/lexicon/gameloop.py +++ b/amanuensis/lexicon/gameloop.py @@ -9,7 +9,6 @@ from amanuensis.config import ReadOnlyOrderedDict from amanuensis.models import LexiconModel, UserModel from amanuensis.parser import ( parse_raw_markdown, - HtmlRenderer, titlesort, filesafe_title) from amanuensis.parser.core import RenderableVisitor @@ -53,6 +52,53 @@ class ConstraintAnalysis(RenderableVisitor): return self +class HtmlRenderer(RenderableVisitor): + """ + Renders an article token tree into published article HTML. + """ + def __init__(self, lexicon_name: str, written_articles: Iterable[str]): + self.lexicon_name: str = lexicon_name + self.written_articles: Iterable[str] = written_articles + + def TextSpan(self, span): + return span.innertext + + def LineBreak(self, span): + return '
' + + def ParsedArticle(self, span): + return '\n'.join(span.recurse(self)) + + def BodyParagraph(self, span): + return f'

{"".join(span.recurse(self))}

' + + def SignatureParagraph(self, span): + return ( + '

' + f'{"".join(span.recurse(self))}' + '

' + ) + + def BoldSpan(self, span): + return f'{"".join(span.recurse(self))}' + + def ItalicSpan(self, span): + return f'{"".join(span.recurse(self))}' + + def CitationSpan(self, span): + if span.cite_target in self.written_articles: + link_class = '' + else: + link_class = ' class="phantom"' + # link = url_for( + # 'lexicon.article', + # name=self.lexicon_name, + # title=filesafe_title(span.cite_target)) + link = (f'/lexicon/{self.lexicon_name}' + + f'/article/{filesafe_title(span.cite_target)}') + return f'{"".join(span.recurse(self))}' + + def get_player_characters( lexicon: LexiconModel, uid: str) -> Iterable[ReadOnlyOrderedDict]: diff --git a/amanuensis/lexicon/manage.py b/amanuensis/lexicon/manage.py index bdfbeb0..eb7844b 100644 --- a/amanuensis/lexicon/manage.py +++ b/amanuensis/lexicon/manage.py @@ -13,7 +13,7 @@ # from amanuensis.config.loader import AttrOrderedDict # from amanuensis.errors import ArgumentError # from amanuensis.lexicon import LexiconModel -# from amanuensis.parser import parse_raw_markdown, GetCitations, HtmlRenderer, filesafe_title, titlesort +# from amanuensis.parser import parse_raw_markdown, filesafe_title, titlesort # from amanuensis.resources import get_stream diff --git a/amanuensis/parser/__init__.py b/amanuensis/parser/__init__.py index 5ef2072..aff1bd4 100644 --- a/amanuensis/parser/__init__.py +++ b/amanuensis/parser/__init__.py @@ -5,13 +5,10 @@ Module encapsulating all markdown parsing functionality. from .core import normalize_title from .helpers import titlesort, filesafe_title from .parsing import parse_raw_markdown -from .render import PreviewHtmlRenderer, HtmlRenderer __all__ = [ normalize_title.__name__, titlesort.__name__, filesafe_title.__name__, parse_raw_markdown.__name__, - PreviewHtmlRenderer.__name__, - HtmlRenderer.__name__, ] diff --git a/amanuensis/parser/render.py b/amanuensis/parser/render.py deleted file mode 100644 index 9313c07..0000000 --- a/amanuensis/parser/render.py +++ /dev/null @@ -1,104 +0,0 @@ -""" -Internal module encapsulating visitors that render articles into -readable formats. -""" - -from typing import Iterable - -from .core import RenderableVisitor -from .helpers import filesafe_title - - -class HtmlRenderer(RenderableVisitor): - """ - Renders an article token tree into published article HTML. - """ - def __init__(self, lexicon_name: str, written_articles: Iterable[str]): - self.lexicon_name: str = lexicon_name - self.written_articles: Iterable[str] = written_articles - - def TextSpan(self, span): - return span.innertext - - def LineBreak(self, span): - return '
' - - def ParsedArticle(self, span): - return '\n'.join(span.recurse(self)) - - def BodyParagraph(self, span): - return f'

{"".join(span.recurse(self))}

' - - def SignatureParagraph(self, span): - return ( - '

' - f'{"".join(span.recurse(self))}' - '

' - ) - - def BoldSpan(self, span): - return f'{"".join(span.recurse(self))}' - - def ItalicSpan(self, span): - return f'{"".join(span.recurse(self))}' - - def CitationSpan(self, span): - if span.cite_target in self.written_articles: - link_class = '' - else: - link_class = ' class="phantom"' - # link = url_for( - # 'lexicon.article', - # name=self.lexicon_name, - # title=filesafe_title(span.cite_target)) - link = (f'/lexicon/{self.lexicon_name}' - + f'/article/{filesafe_title(span.cite_target)}') - return f'{"".join(span.recurse(self))}' - - -class PreviewHtmlRenderer(RenderableVisitor): - def __init__(self, lexicon): - with lexicon.ctx.read('info') as info: - self.article_map = { - title: article.character - for title, article in info.items() - } - self.citations = [] - self.contents = "" - - def TextSpan(self, span): - return span.innertext - - def LineBreak(self, span): - return '
' - - def ParsedArticle(self, span): - self.contents = '\n'.join(span.recurse(self)) - return self - - def BodyParagraph(self, span): - return f'

{"".join(span.recurse(self))}

' - - def SignatureParagraph(self, span): - return ( - '

' - f'{"".join(span.recurse(self))}' - '

' - ) - - def BoldSpan(self, span): - return f'{"".join(span.recurse(self))}' - - def ItalicSpan(self, span): - return f'{"".join(span.recurse(self))}' - - def CitationSpan(self, span): - if span.cite_target in self.article_map: - if self.article_map.get(span.cite_target): - link_class = '[extant]' - else: - link_class = '[phantom]' - else: - link_class = '[new]' - self.citations.append(f'{span.cite_target} {link_class}') - return f'{"".join(span.recurse(self))}[{len(self.citations)}]' diff --git a/amanuensis/server/session/__init__.py b/amanuensis/server/session/__init__.py index 4c27787..743754d 100644 --- a/amanuensis/server/session/__init__.py +++ b/amanuensis/server/session/__init__.py @@ -15,9 +15,7 @@ from amanuensis.lexicon import ( create_character_in_lexicon, get_draft) from amanuensis.models import LexiconModel -from amanuensis.parser import ( - parse_raw_markdown, - PreviewHtmlRenderer) +from amanuensis.parser import parse_raw_markdown from amanuensis.server.helpers import ( lexicon_param, player_required, @@ -29,7 +27,7 @@ from .forms import ( LexiconPublishTurnForm, LexiconConfigForm) -from .editor import load_editor, new_draft, update_draft +from .editor import load_editor, new_draft, update_draft, PreviewHtmlRenderer bp_session = Blueprint('session', __name__, diff --git a/amanuensis/server/session/editor.py b/amanuensis/server/session/editor.py index 8492966..79a3cb3 100644 --- a/amanuensis/server/session/editor.py +++ b/amanuensis/server/session/editor.py @@ -17,8 +17,56 @@ from amanuensis.lexicon import ( from amanuensis.models import LexiconModel from amanuensis.parser import ( normalize_title, - parse_raw_markdown, - PreviewHtmlRenderer) + parse_raw_markdown) +from amanuensis.parser.core import RenderableVisitor + + +class PreviewHtmlRenderer(RenderableVisitor): + def __init__(self, lexicon): + with lexicon.ctx.read('info') as info: + self.article_map = { + title: article.character + for title, article in info.items() + } + self.citations = [] + self.contents = "" + + def TextSpan(self, span): + return span.innertext + + def LineBreak(self, span): + return '
' + + def ParsedArticle(self, span): + self.contents = '\n'.join(span.recurse(self)) + return self + + def BodyParagraph(self, span): + return f'

{"".join(span.recurse(self))}

' + + def SignatureParagraph(self, span): + return ( + '

' + f'{"".join(span.recurse(self))}' + '

' + ) + + def BoldSpan(self, span): + return f'{"".join(span.recurse(self))}' + + def ItalicSpan(self, span): + return f'{"".join(span.recurse(self))}' + + def CitationSpan(self, span): + if span.cite_target in self.article_map: + if self.article_map.get(span.cite_target): + link_class = '[extant]' + else: + link_class = '[phantom]' + else: + link_class = '[new]' + self.citations.append(f'{span.cite_target} {link_class}') + return f'{"".join(span.recurse(self))}[{len(self.citations)}]' def load_editor(lexicon: LexiconModel, aid: str):