From d26fa6aac098be12b2d725ddb7ffb2a972b4b016 Mon Sep 17 00:00:00 2001 From: Markus Scheller <scheller_m@live.de> Date: Sat, 24 Feb 2018 20:29:19 +0100 Subject: [PATCH 1/6] Insert example configuration for a custom latex template protokollsystem/proto3#170 --- config.py.example | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/config.py.example b/config.py.example index 7dcd0a6..2df2cd9 100644 --- a/config.py.example +++ b/config.py.example @@ -185,6 +185,19 @@ LATEX_BULLETPOINTS = [ # optional: include header and footer in asta-style, not just a page number on top #LATEX_HEADER_FOOTER = True +# optional: define multiple LaTeX-templates to use with a each protocol type individually +#LATEX_TEMPLATES = { +# "yourtemplate": { +# "name": "Dein Template", +# "path": "local-templates/yourtemplate", +# "logo": "asta-logo.tex", +# "geometry": "bottom=1.6cm,top=1.6cm,inner=2.5cm,outer=1.0cm,footskip=1.0cm,headsep=0.6cm", +# "pagestyle": "fancy", +# "additionalpackages": ["[absolute]{textpos}", "{fancyheadings}"], +# "headerfooter": True +# } +#} + HTML_LEVEL_OFFSET = 3 def dummy_todomail_provider(): -- GitLab From 7ba49fddffd6db922068882c466ed1fc876d9d23 Mon Sep 17 00:00:00 2001 From: Markus Scheller <scheller_m@live.de> Date: Sat, 24 Feb 2018 20:31:09 +0100 Subject: [PATCH 2/6] Add column 'latex_template' to ProtocolType to use in the compiling process and the corresponding view protokollsystem/proto3#170 --- models/database.py | 1 + 1 file changed, 1 insertion(+) diff --git a/models/database.py b/models/database.py index 8eed90e..5304fbf 100644 --- a/models/database.py +++ b/models/database.py @@ -71,6 +71,7 @@ class ProtocolType(DatabaseModel): calendar = db.Column(db.String) restrict_networks = db.Column(db.Boolean) allowed_networks = db.Column(db.String) + latex_template = db.Column(db.String) protocols = relationship("Protocol", backref=backref("protocoltype"), cascade="all, delete-orphan", order_by="Protocol.id") default_tops = relationship("DefaultTOP", backref=backref("protocoltype"), cascade="all, delete-orphan", order_by="DefaultTOP.number") -- GitLab From 4dff3185d9deccf9451d8fc30c35c5628805a5d7 Mon Sep 17 00:00:00 2001 From: Markus Scheller <scheller_m@live.de> Date: Sat, 24 Feb 2018 20:33:38 +0100 Subject: [PATCH 3/6] Add configuration SelectField for latex_template selection protokollsystem/proto3#170 --- views/forms.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/views/forms.py b/views/forms.py index 67b39af..0512117 100644 --- a/views/forms.py +++ b/views/forms.py @@ -58,6 +58,17 @@ def get_printer_choices(): choices = list(zip(config.PRINTING_PRINTERS, config.PRINTING_PRINTERS)) choices.insert(0, ("", "Nicht drucken")) return choices + +def get_latex_template_choices(): + choices = [] + if config.LATEX_TEMPLATES is not None: + choices = [ + (key, values['name']) + for key, values + in config.LATEX_TEMPLATES.items() + ] + choices.insert(0, ("", "Standardvorlage")) + return choices def get_group_choices(): user = current_user() @@ -130,12 +141,14 @@ class ProtocolTypeForm(FlaskForm): calendar = SelectField("Kalender", choices=[]) restrict_networks = BooleanField("Netzwerke einschränken") allowed_networks = IPNetworkField("Erlaubte Netzwerke") + latex_template = SelectField("LaTeX Vorlage", choices=[]) def __init__(self, **kwargs): super().__init__(**kwargs) protocoltype = kwargs["obj"] if "obj" in kwargs else None self.calendar.choices = get_calendar_choices(protocoltype=protocoltype) self.printer.choices = get_printer_choices() + self.latex_template.choices = get_latex_template_choices() group_choices = get_group_choices() self.publish_group.choices = group_choices self.modify_group.choices = group_choices -- GitLab From 07178395be49809e6016f45239e420dd15fc2120 Mon Sep 17 00:00:00 2001 From: Markus Scheller <scheller_m@live.de> Date: Sun, 25 Feb 2018 12:08:13 +0100 Subject: [PATCH 4/6] Changed the process of getting the standard value for the latex template protokollsystem/proto3#170 --- views/forms.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/views/forms.py b/views/forms.py index 0512117..7ec3a3f 100644 --- a/views/forms.py +++ b/views/forms.py @@ -61,11 +61,12 @@ def get_printer_choices(): def get_latex_template_choices(): choices = [] - if config.LATEX_TEMPLATES is not None: + _latex_templates = getattr(config, "LATEX_TEMPLATES", None) + if _latex_templates is not None: choices = [ (key, values['name']) for key, values - in config.LATEX_TEMPLATES.items() + in _latex_templates.items() ] choices.insert(0, ("", "Standardvorlage")) return choices -- GitLab From 094f2e0fdc9b2353f08e4c3bb1165d0b0a0c3878 Mon Sep 17 00:00:00 2001 From: Markus Scheller <scheller_m@live.de> Date: Sun, 25 Feb 2018 12:09:45 +0100 Subject: [PATCH 5/6] Add row to view the selected LaTeX template The row will only be shown when different templates are set up in config.py and available. protokollsystem/proto3#170 Bugfix: Replaced ethernet_part with etherpad_part in line 221 to ensure that this part will only be shwon when the systems consumes the etherpad --- views/tables.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/views/tables.py b/views/tables.py index 48842b1..8b59ea0 100644 --- a/views/tables.py +++ b/views/tables.py @@ -193,12 +193,13 @@ class ProtocolTypeTable(SingleValueTable): network_headers = ["Netzwerke einschränken", "Erlaubte Netzwerke"] action_headers = ["Aktion"] feed_headers = [] + latex_template_headers = ["LaTeX Vorlage"] if getattr(config, "LATEX_TEMPLATES", None) is not None else [] if self.value.has_public_anonymous_view_right(): feed_headers = [Markup("<img height=\"18px\" src=\"{}\" /> Feed".format( url_for("static", filename="images/feed-icon.svg")))] return (general_headers + etherpad_headers + mail_headers + printing_headers + wiki_headers + calendar_headers - + network_headers + feed_headers + action_headers) + + network_headers + latex_template_headers + feed_headers + action_headers) def row(self): user = current_user() @@ -217,7 +218,7 @@ class ProtocolTypeTable(SingleValueTable): Table.bool(self.value.non_reproducible_pad_links) ] if not config.ETHERPAD_ACTIVE: - ethernet_part = [] + etherpad_part = [] mail_part = [ self.value.private_mail, self.value.public_mail, @@ -242,6 +243,11 @@ class ProtocolTypeTable(SingleValueTable): network_part.append(", ".join(map(str.strip, self.value.allowed_networks.split(",")))) else: network_part.append("") + _latex_templates = getattr(config, "LATEX_TEMPLATES", None) + if _latex_templates is not None: + latex_template_part = [_latex_templates[self.value.latex_template]['name'] if self.value.latex_template is not (None or "") else "Standardvorlage"] + else: + latex_template_part = [] feed_part = [] if self.value.has_public_anonymous_view_right(): feed_part = [Markup(", ".join([ @@ -260,7 +266,7 @@ class ProtocolTypeTable(SingleValueTable): if not self.value.has_admin_right(user): action_part = [""] return (general_part + etherpad_part + mail_part + printing_part - + wiki_part + calendar_part + network_part + feed_part + + wiki_part + calendar_part + network_part + latex_template_part + feed_part + action_part) class DefaultTOPsTable(Table): -- GitLab From 9ceabf71e75688e28521f99572e9ecfe27c4a775 Mon Sep 17 00:00:00 2001 From: Markus Scheller <scheller_m@live.de> Date: Sun, 25 Feb 2018 12:31:37 +0100 Subject: [PATCH 6/6] Added the logic for the template selection process and the example configuration setup close protokollsystem/proto3#170 --- config.py.example | 21 ++++++++++++--------- tasks.py | 48 ++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 57 insertions(+), 12 deletions(-) diff --git a/config.py.example b/config.py.example index 2df2cd9..d23beb8 100644 --- a/config.py.example +++ b/config.py.example @@ -172,7 +172,7 @@ LATEX_BULLETPOINTS = [ r"\textperiodcentered" ] -# optional: path to additional jinja-templates +# optional: path to additional jinja-templates, will be need in combination with LATEX_TEMPLATES #LATEX_LOCAL_TEMPLATES = "local-templates" # optional: the template to include at the top of protocol.tex #LATEX_LOGO_TEMPLATE = "asta-logo.tex" @@ -184,17 +184,20 @@ LATEX_BULLETPOINTS = [ #LATEX_ADDITIONAL_PACKAGES = ["[absolute]{textpos}", "{fancyheadings}"] # optional: include header and footer in asta-style, not just a page number on top #LATEX_HEADER_FOOTER = True - -# optional: define multiple LaTeX-templates to use with a each protocol type individually +# optional: define multiple LaTeX-templates to use with a each protocol type individually overiding the general LATEX options +# the LATEX_LOCAL_TEMPLATES parameter is need to provide the path for the templates +# each template must be placed in an individual folder named by its ID in LATEX_TEMPLATES and must contain the provided template files: e.g. +# - the files for the template "yourtemplate" need to be in the folder named "yourtemplate" +# - the templates provides the files: "protokoll2.cls" (class), "protocol.tex" (protocol), "decision.tex" (decision) and "asta-logo.tex" #LATEX_TEMPLATES = { # "yourtemplate": { # "name": "Dein Template", -# "path": "local-templates/yourtemplate", -# "logo": "asta-logo.tex", -# "geometry": "bottom=1.6cm,top=1.6cm,inner=2.5cm,outer=1.0cm,footskip=1.0cm,headsep=0.6cm", -# "pagestyle": "fancy", -# "additionalpackages": ["[absolute]{textpos}", "{fancyheadings}"], -# "headerfooter": True +# "provides": ["class", "protocol", "decision"], # optional: if this option is set the corresponding files must be provided +# "logo": "asta-logo.tex", # optional: replaces the general template to include at the top of protocol.tex set by LATEX_LOGO_TEMPLATE +# "geometry": "bottom=1.6cm,top=1.6cm,inner=2.5cm,outer=1.0cm,footskip=1.0cm,headsep=0.6cm", # optional: replaces the general protocol page geometry set by LATEX_GEOMETRY +# "pagestyle": "fancy", # optional: replaces the general protocol pagestyle set by LATEX_PAGESTYLE +# "additionalpackages": ["[absolute]{textpos}", "{fancyheadings}"], # optional: replaces the general latex packages set by LATEX_ADDITIONAL_PACKAGES +# "headerfooter": True # optional: replaces the general LATEX_HEADER_FOOTER option # } #} diff --git a/tasks.py b/tasks.py index 28a9770..9ed0ea2 100644 --- a/tasks.py +++ b/tasks.py @@ -57,6 +57,48 @@ if latex_pagestyle is not None and latex_pagestyle: texenv.globals["latex_pagestyle"] = latex_pagestyle latex_header_footer = getattr(config, "LATEX_HEADER_FOOTER", False) texenv.globals["latex_header_footer"] = latex_header_footer +latex_templates = getattr(config, "LATEX_TEMPLATES", None) + +def provide_latex_template(template, documenttype): + _latex_template_documenttype_filename = { + "class": "protokoll2.cls", + "protocol": "protocol.tex", + "decision": "decision.tex" + } + _latex_template_filename = _latex_template_documenttype_filename[documenttype] + _latex_template_foldername = "" + if logo_template is not None: + texenv.globals["logo_template"] = logo_template + texenv.globals["latex_geometry"] = latex_geometry + texenv.globals["additional_packages"] = additional_packages + if latex_pagestyle is not None and latex_pagestyle: + texenv.globals["latex_pagestyle"] = latex_pagestyle + elif "latex_pagestyle" in texenv.globals: + del texenv.globals["latex_pagestyle"] + texenv.globals["latex_header_footer"] = latex_header_footer + if (latex_templates is not None) and (template is not ""): + if template in latex_templates: + if "provides" in latex_templates[template]: + _latex_template_foldername = (template + "/") if documenttype in latex_templates[template]["provides"] else "" + if "logo" in latex_templates[template]: + texenv.globals["logo_template"] = template + "/" + latex_templates[template]["logo"] + if "geometry" in latex_templates[template]: + texenv.globals["latex_geometry"] = latex_templates[template]["geometry"] + if "pagestyle" in latex_templates[template]: + if latex_templates[template]["pagestyle"]: + texenv.globals["latex_pagestyle"] = latex_templates[template]["pagestyle"] + if "additionalpackages" in latex_templates[template]: + _raw_additional_packages = latex_templates[template]["additionalpackages"] + _additional_packages = [] + if _raw_additional_packages is not None: + for _package in _raw_additional_packages: + if "{" not in _package: + _package = "{{{}}}".format(_package) + _additional_packages.append(_package) + texenv.globals["additional_packages"] = _additional_packages + if "headerfooter" in latex_templates[template]: + texenv.globals["latex_header_footer"] = latex_templates[template]["headerfooter"] + return _latex_template_foldername + _latex_template_filename mailenv = app.create_jinja_environment() mailenv.trim_blocks = True @@ -370,7 +412,7 @@ def parse_protocol_async_inner(protocol, encoded_kwargs): decisions_to_render.append((decision, decision_tag)) for decision, decision_tag in decisions_to_render: decision_top = decision_tag.fork.get_top() - decision_content = texenv.get_template("decision.tex").render( + decision_content = texenv.get_template(provide_latex_template(protocol.protocoltype.latex_template, "decision")).render( render_type=RenderType.latex, decision=decision, protocol=protocol, top=decision_top, show_private=True) maxdepth = decision_top.get_maxdepth() @@ -458,7 +500,7 @@ def parse_protocol_async_inner(protocol, encoded_kwargs): render_type=RenderType.html, show_private=False, **public_render_kwargs) for show_private in privacy_states: - latex_source = texenv.get_template("protocol.tex").render( + latex_source = texenv.get_template(provide_latex_template(protocol.protocoltype.latex_template, "protocol")).render( render_type=RenderType.latex, show_private=show_private, **render_kwargs[show_private]) @@ -558,7 +600,7 @@ def compile_async(content, protocol_id, show_private=False, use_decision=False, log_filename = "protocol.log" with open(os.path.join(compile_dir, protocol_source_filename), "w") as source_file: source_file.write(content) - protocol2_class_source = texenv.get_template(protocol_class_filename).render(fonts=config.FONTS, maxdepth=maxdepth, bulletpoints=config.LATEX_BULLETPOINTS) + protocol2_class_source = texenv.get_template(provide_latex_template(protocol.protocoltype.latex_template, "class")).render(fonts=config.FONTS, maxdepth=maxdepth, bulletpoints=config.LATEX_BULLETPOINTS) with open(os.path.join(compile_dir, protocol_class_filename), "w") as protocol2_class_file: protocol2_class_file.write(protocol2_class_source) os.chdir(compile_dir) -- GitLab