From 1f17afaa7c46b923c8b34adb4ca5592b35779952 Mon Sep 17 00:00:00 2001 From: Robin Sonnabend <robin@fsmpi.rwth-aachen.de> Date: Sat, 25 Feb 2017 17:15:09 +0100 Subject: [PATCH] Render todos in tex protocol --- models/database.py | 12 +++++ parser.py | 117 ++++++++++++++++++++++++++++++----------- tasks.py | 9 ++-- templates/protocol.tex | 14 +---- 4 files changed, 106 insertions(+), 46 deletions(-) diff --git a/models/database.py b/models/database.py index 215c3da..75fbf0f 100644 --- a/models/database.py +++ b/models/database.py @@ -312,6 +312,18 @@ class Todo(db.Model): ] return " ".join(parts) + def render_latex(self, current_protocol=None): + is_new = len(self.protocols) == 1 + if current_protocol is not None: + is_new = self.get_first_protocol() == current_protocol + return r"\textbf{{{}}}: {}: {} -- {}".format( + "Neuer Todo" if is_new else "Todo", + self.who, + self.description, + self.get_state_tex() + ) + + class TodoProtocolAssociation(db.Model): __tablename__ = "todoprotocolassociations" diff --git a/parser.py b/parser.py index ab64dd8..80b35f0 100644 --- a/parser.py +++ b/parser.py @@ -1,6 +1,7 @@ import regex as re import sys from collections import OrderedDict +from enum import Enum from shared import escape_tex @@ -24,12 +25,20 @@ class ParserException(Exception): result += "\n" + self.explanation return result +class RenderType(Enum): + latex = 0 + wikitext = 1 + plaintext = 2 + +def _not_implemented(self, render_type): + return NotImplementedError("The rendertype {} has not been implemented for {}.".format(render_type.name, self.__class__.__name__)) + class Element: """ Generic (abstract) base element. Should never really exist. Template for what an element class should contain. """ - def render(self, show_private): + def render(self, render_type, show_private, level=None, protocol=None): """ Renders the element to TeX. Returns: @@ -94,8 +103,8 @@ class Content(Element): self.children = children self.linenumber = linenumber - def render(self, show_private): - return "".join(map(lambda e: e.render(show_private), self.children)) + def render(self, render_type, show_private, level=None, protocol=None): + return "".join(map(lambda e: e.render(render_type, show_private, level=level, protocol=protocol), self.children)) def dump(self, level=None): if level is None: @@ -146,8 +155,15 @@ class Text: self.text = text self.linenumber = linenumber - def render(self, show_private): - return escape_tex(self.text) + def render(self, render_type, show_private, level=None, protocol=None): + if render_type == RenderType.latex: + return escape_tex(self.text) + elif render_type == RenderType.wikitext: + return self.text + elif render_Type == RenderType.plaintext: + return self.text + else: + raise _not_implemented(self, render_type) def dump(self, level=None): if level is None: @@ -172,11 +188,15 @@ class Tag: self.values = values self.linenumber = linenumber - def render(self, show_private): - if self.name == "url": - return r"\url{{{}}}".format(self.values[0]) - #return r"\textbf{{{}:}} {}".format(escape_tex(self.name.capitalize()), "; ".join(map(escape_tex, self.values))); - return r"\textbf{{{}:}} {}".format(escape_tex(self.name.capitalize()), escape_tex(self.values[0])) + def render(self, render_type, show_private, level=None, protocol=None): + if render_type == RenderType.latex: + if self.name == "url": + return r"\url{{{}}}".format(self.values[0]) + elif self.name == "todo": + return self.todo.render_latex(current_protocol=protocol) + return r"\textbf{{{}:}} {}".format(escape_tex(self.name.capitalize()), escape_tex(self.values[0])) + else: + raise _not_implemented(self, render_type) def dump(self, level=None): if level is None: @@ -199,7 +219,7 @@ class Empty(Element): def __init__(self, linenumber): linenumber = linenumber - def render(self, show_private): + def render(self, render_type, show_private, level=None, protocol=None): return "" def dump(self, level=None): @@ -220,8 +240,13 @@ class Remark(Element): self.value = value self.linenumber = linenumber - def render(self, show_private): - return r"\textbf{{{}}}: {}".format(self.name, self.value) + def render(self, render_type, show_private, level=None, protocol=None): + if render_type == RenderType.latex: + return r"\textbf{{{}}}: {}".format(self.name, self.value) + elif render_type == RenderType.wikitext: + return "{}: {}".format(self.name, self.value) + elif render_type == RenderType.plaintext: + return "{}: {}".format(RenderType.plaintex) def dump(self, level=None): if level is None: @@ -266,28 +291,58 @@ class Fork(Element): stripped_name = name.replace(":", "").strip() return stripped_name in config.PRIVATE_KEYS - def render(self, show_private, toplevel=False): + def render(self, render_type, show_private, level, protocol=None): name_line = self.name if self.name is not None and len(self.name) > 0 else "" - begin_line = r"\begin{itemize}" - end_line = r"\end{itemize}" - content_parts = [] - for child in self.children: - part = child.render(show_private) - if len(part.strip()) == 0: - continue - if not part.startswith(r"\item"): - part = r"\item {}".format(part) - content_parts.append(part) - content_lines = "\n".join(content_parts) - if toplevel: - return "\n".join([begin_line, content_lines, end_line]) - elif self.test_private(self.name): - if show_private: - return content_lines + if render_type == RenderType.latex: + begin_line = r"\begin{itemize}" + end_line = r"\end{itemize}" + content_parts = [] + for child in self.children: + part = child.render(render_type, show_private, level=level+1, protocol=protocol) + if len(part.strip()) == 0: + continue + if not part.startswith(r"\item"): + part = r"\item {}".format(part) + content_parts.append(part) + content_lines = "\n".join(content_parts) + if level == 0: + return "\n".join([begin_line, content_lines, end_line]) + elif self.test_private(self.name): + if show_private: + return content_lines + else: + return "" else: + return "\n".join([name_line, begin_line, content_lines, end_line]) + elif render_type == RenderType.wikitext: + title_line = "{0}{1}{0}".format("=" * (level + 2), name_line) + content_parts = [] + for child in self.children: + part = child.render(render_type, show_private, level=level+1, protocol=protocol) + if len(part.strip()) == 0: + continue + content_parts.append(part) + content_lines = "{}\n{}".format(title_line, "\n".join(content_parts)) + if self.test_private(self.name) and not show_private: return "" + else: + return content_lines + elif render_type == RenderType.plaintext: + title_line = "{} {}".format("#" * (level + 1), name_line) + content_parts = [] + for child in self.children: + part = child.render(render_Type, show_private, level=level+1, protocol=protocol) + if len(part.strip()) == 0: + continue + content_parts.append(part) + content_lines = "{}\n{}".format(title_line, "\n".join(content_parts)) + if self.test_private(self.name) and not show_private: + return "" + else: + return content_lines else: - return "\n".join([name_line, begin_line, content_lines, end_line]) + raise _not_implemented(self, render_type) + def get_tags(self, tags=None): if tags is None: diff --git a/tasks.py b/tasks.py index 972edea..8aee9d2 100644 --- a/tasks.py +++ b/tasks.py @@ -10,7 +10,7 @@ from models.errors import DateNotMatchingException from server import celery, app from shared import db, escape_tex, unhyphen, date_filter, datetime_filter, date_filter_long, date_filter_short, time_filter, class_filter from utils import mail_manager, url_manager, encode_kwargs, decode_kwargs -from parser import parse, ParserException, Element, Content, Text, Tag, Remark, Fork +from parser import parse, ParserException, Element, Content, Text, Tag, Remark, Fork, RenderType import config @@ -164,6 +164,7 @@ def parse_protocol_async(protocol_id, encoded_kwargs): elif other_field not in todo_tags_internal: todo_tags_internal.append(other_field) todo.tags = ";".join(todo_tags_internal) + todo_tag.todo = todo db.session.commit() old_decisions = list(protocol.decisions) for decision in old_decisions: @@ -189,8 +190,10 @@ def parse_protocol_async(protocol_id, encoded_kwargs): db.session.add(top) db.session.commit() - latex_source_private = texenv.get_template("protocol.tex").render(protocol=protocol, tree=tree, show_private=True) - latex_source_public = texenv.get_template("protocol.tex").render(protocol=protocol, tree=tree, show_private=False) + private_states = [False] + + latex_source_private = texenv.get_template("protocol.tex").render(protocol=protocol, tree=tree, show_private=True, render_type=RenderType.latex) + latex_source_public = texenv.get_template("protocol.tex").render(protocol=protocol, tree=tree, show_private=False, render_type=RenderType.latex) compile(latex_source_public, protocol, show_private=False) if latex_source_private != latex_source_public: compile(latex_source_private, protocol, show_private=True) diff --git a/templates/protocol.tex b/templates/protocol.tex index be04475..5acd7c3 100644 --- a/templates/protocol.tex +++ b/templates/protocol.tex @@ -45,18 +45,8 @@ Beginn der Sitzung: \VAR{protocol.start_time|timify} \ENV{for top in tree.children} \ENV{if top|class == "Fork"} - \TOP{\VAR{top.name|escape_tex}} % here we probably have information doubly - \ENV{if top.name == "Todos"} - \ENV{if protocol.todos|length > 0} - \begin{itemize} - \ENV{for todo in protocol.todos} - \item \VAR{todo.who}: \VAR{todo.description} -- \VAR{todo.get_state_tex()} - \ENV{endfor} - \end{itemize} - \ENV{endif} - \ENV{else} - \VAR{top.render(toplevel=True, show_private=show_private)} - \ENV{endif} + \TOP{\VAR{top.name|escape_tex}} + \VAR{top.render(render_type=render_type, level=0, show_private=show_private, protocol=protocol)} \ENV{endif} \ENV{endfor} -- GitLab