[1]:
import sys, json, datetime
sys.path.insert(0, r'C:\Users\tglaubach\repos\pydocmaker\src')
[2]:
import pydocmaker as pyd
import os

Using templates (HTML and LaTeX)

pydocmaker supports mounting Jinja2 Templates organized in folders together with (optional) default parameters and assets. Such templates are organized in folders. pydocmaker has one such template directory with a base template shipped with it by default which is part of the installation.

The pydocmaker inbuild templates

[3]:
pyd.get_registered_template_dirs()
[3]:
['C:\\Users\\tglaubach\\repos\\pydocmaker\\src\\pydocmaker\\templates']
[4]:
pyd.get_available_template_ids()
[4]:
['base']

Definition of templates

Each template has

  • a name, and its format. The main name per template is then: <name>.<format>.j2

  • Optionally it can also have an assests folder <name>.assets/ where you can keep any assests such as images/logos etc.

  • Optionally it can have a JSON file <name>.params.json to define the parameters which can be used for this template type, since (as far as I know) Jinja2 has no possibility to reflect / track expected parameter names.

Such templates only work for text based formats, such as html and tex.

[5]:
for d in pyd.get_registered_template_dirs():
    print(d)
    for f in os.listdir(d):
        print('   ', f)
C:\Users\tglaubach\repos\pydocmaker\src\pydocmaker\templates
    assets
    base.assets
    base.html.j2
    base.params.json
    base.tex.j2
    word_template_with_mergefields.docx

Adding / defining you own template

Such Suppose you have the following folder structure

home/jovyan/templates/
├─ assets/
│  ├─ i_can_use_this_everywhere.png
├─ fancy_tempate.assets/
│  ├─ fancy_logo.png
│  ├─ fancy_title_picture.png
├─ fancy_template.params.json
├─ fancy_template.tex.j2
├─ normal_template.params.json
├─ normal_template.tex.j2

(NOTE: you can also check out the templates folder in this repository for an example).

You can then mount this folder in pydocmaker using

[6]:
pyd.register_new_template_dir(r'C:\Users\tglaubach\repos\pydocmaker\example_templates')
[6]:
True

Which will give you two available templates to use for exporting tex and pdf documents:

[7]:
pyd.get_available_template_ids()
[7]:
['base', 'fancy_template', 'normal_template']

Using your template

You can mark the templates to be used for a doc by setting it to the reports metadata:

[8]:
doc = pyd.get_example()
doc.set_template_to_meta('fancy_template')
[8]:
{'files_to_upload': {'i_can_use_this_everywhere.png': 'iVBORw0KGgoAAAANSUhEUgAAAH4AAAAVCAYAAACAEFoRAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAOwSURBVGhD7Zi/a9toGMc/vbW4l0LRonrQ4GDeQCFD0Q3GcAYPBwZDh3gygczpnj/BezwbjkzuYCgYOgRSCIY7kyEQqAjpoMHVYgJxIzL3Bv2I9OqVrSTOtcH6gMB69Up63+f7vM/7lZ+VSus/yFk5fpMbclaDXPgVJRd+RcmFX1GeJcydMOnXXnD64ZDONHbFR6eza2L4Zzdnh+wcu1KfHIBKtc77NwXvZDKm9dGRuzwyBfa262zOku++84pvN02MyZhWd0CrO3gaoguT/naZitz+yIyOD2l1B+yf3TNGWpnerklbbl8CKcJf4yhXewF9Deyv/3fm5jyEm6truUlR6ufilXmOBuxZ6mvBFhArbcKkX/rG/pUIS19yi5Dudy32/z5nJEz6NRh2xxwE11RtKrQyvS3Bc7kdJ3KvXw79ihwdd6VaZ4cJ0zcCA4fhETRq+m2fTPPyS/5LK1FuE3MO3y21h7ixLTi2lcTmtJhswmcIYLtpwsfgxVKCCJO+HLCYcF5/TRG0xLOAdvMdDZL7VirCpP/2u5dI0qX4s7wkWLe9cXiBhdMP/8JfdTax2P8EO1u/87k75kCel1amt1XkQvJHacLPjRlB3P13xe5MJn+lWue9MVHOUUVKqZeYnrPTHdDqjrEB+8jb31uRAR2EEwBw+DIB7VWQjf4KDiZufcPmBbrmnVaqAsO16CVEx0uuMxejpPvnOhtFl9N/Moo+F52NosMwFMSlc+Lw3NBv/cDECkW0TxRBjc5r6nDhFlh7JXdSszBmc2iXdOyj2/tHxxZ2oUjFj+kisgmfBWHS330XHo2i3CEd42UBZm4yqD6j8wk3xdeeyRGvMSJiPAitgIZOIzLufi1IsPuTVbz7x8zzWkYtMm7l1pDOcoTXyvRqeqQSDBhO5E7p2FeqlR5h6nDh6mwIP9OXai4dhv6YwyNjuUxjerlgPjw8ZsQqb3CkfYInWY7wALjMLv2fwrxD9gYr2qQj5CsBXgk23tb5c81imDCWC7j8zo2qDPoJ1Wg+fJUDVKp/sFlw+JJ5fAtiNnWZ4iV8HJeR7WLU7v+pl83chSgMiE+7GSlVrsXpTLB+5Zu1hLnS6ewKZlETJBvIwNUH53MN4GLSHbDk6iPO/NaUXbO3XWftZMDeZcRwBeYuZP5zIf7VMDdmAbF3zHP1qpilc0fhfyaKZPnZJBL66bDEUv+4eP8YLsnU5fz6Kz4sh6oyJm8PEqo/U5bKE17xv7zwOY/Dkyn1OcslF35F+Q9idByILrzS4QAAAABJRU5ErkJggg==',
  'fancy_logo.png': 'iVBORw0KGgoAAAANSUhEUgAAAH4AAAAVCAYAAACAEFoRAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAOwSURBVGhD7Zi/a9toGMc/vbW4l0LRonrQ4GDeQCFD0Q3GcAYPBwZDh3gygczpnj/BezwbjkzuYCgYOgRSCIY7kyEQqAjpoMHVYgJxIzL3Bv2I9OqVrSTOtcH6gMB69Up63+f7vM/7lZ+VSus/yFk5fpMbclaDXPgVJRd+RcmFX1GeJcydMOnXXnD64ZDONHbFR6eza2L4Zzdnh+wcu1KfHIBKtc77NwXvZDKm9dGRuzwyBfa262zOku++84pvN02MyZhWd0CrO3gaoguT/naZitz+yIyOD2l1B+yf3TNGWpnerklbbl8CKcJf4yhXewF9Deyv/3fm5jyEm6truUlR6ufilXmOBuxZ6mvBFhArbcKkX/rG/pUIS19yi5Dudy32/z5nJEz6NRh2xxwE11RtKrQyvS3Bc7kdJ3KvXw79ihwdd6VaZ4cJ0zcCA4fhETRq+m2fTPPyS/5LK1FuE3MO3y21h7ixLTi2lcTmtJhswmcIYLtpwsfgxVKCCJO+HLCYcF5/TRG0xLOAdvMdDZL7VirCpP/2u5dI0qX4s7wkWLe9cXiBhdMP/8JfdTax2P8EO1u/87k75kCel1amt1XkQvJHacLPjRlB3P13xe5MJn+lWue9MVHOUUVKqZeYnrPTHdDqjrEB+8jb31uRAR2EEwBw+DIB7VWQjf4KDiZufcPmBbrmnVaqAsO16CVEx0uuMxejpPvnOhtFl9N/Moo+F52NosMwFMSlc+Lw3NBv/cDECkW0TxRBjc5r6nDhFlh7JXdSszBmc2iXdOyj2/tHxxZ2oUjFj+kisgmfBWHS330XHo2i3CEd42UBZm4yqD6j8wk3xdeeyRGvMSJiPAitgIZOIzLufi1IsPuTVbz7x8zzWkYtMm7l1pDOcoTXyvRqeqQSDBhO5E7p2FeqlR5h6nDh6mwIP9OXai4dhv6YwyNjuUxjerlgPjw8ZsQqb3CkfYInWY7wALjMLv2fwrxD9gYr2qQj5CsBXgk23tb5c81imDCWC7j8zo2qDPoJ1Wg+fJUDVKp/sFlw+JJ5fAtiNnWZ4iV8HJeR7WLU7v+pl83chSgMiE+7GSlVrsXpTLB+5Zu1hLnS6ewKZlETJBvIwNUH53MN4GLSHbDk6iPO/NaUXbO3XWftZMDeZcRwBeYuZP5zIf7VMDdmAbF3zHP1qpilc0fhfyaKZPnZJBL66bDEUv+4eP8YLsnU5fz6Kz4sh6oyJm8PEqo/U5bKE17xv7zwOY/Dkyn1OcslF35F+Q9idByILrzS4QAAAABJRU5ErkJggg==',
  'fancy_title_picture.png': 'iVBORw0KGgoAAAANSUhEUgAAAH4AAAAVCAYAAACAEFoRAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAOwSURBVGhD7Zi/a9toGMc/vbW4l0LRonrQ4GDeQCFD0Q3GcAYPBwZDh3gygczpnj/BezwbjkzuYCgYOgRSCIY7kyEQqAjpoMHVYgJxIzL3Bv2I9OqVrSTOtcH6gMB69Up63+f7vM/7lZ+VSus/yFk5fpMbclaDXPgVJRd+RcmFX1GeJcydMOnXXnD64ZDONHbFR6eza2L4Zzdnh+wcu1KfHIBKtc77NwXvZDKm9dGRuzwyBfa262zOku++84pvN02MyZhWd0CrO3gaoguT/naZitz+yIyOD2l1B+yf3TNGWpnerklbbl8CKcJf4yhXewF9Deyv/3fm5jyEm6truUlR6ufilXmOBuxZ6mvBFhArbcKkX/rG/pUIS19yi5Dudy32/z5nJEz6NRh2xxwE11RtKrQyvS3Bc7kdJ3KvXw79ihwdd6VaZ4cJ0zcCA4fhETRq+m2fTPPyS/5LK1FuE3MO3y21h7ixLTi2lcTmtJhswmcIYLtpwsfgxVKCCJO+HLCYcF5/TRG0xLOAdvMdDZL7VirCpP/2u5dI0qX4s7wkWLe9cXiBhdMP/8JfdTax2P8EO1u/87k75kCel1amt1XkQvJHacLPjRlB3P13xe5MJn+lWue9MVHOUUVKqZeYnrPTHdDqjrEB+8jb31uRAR2EEwBw+DIB7VWQjf4KDiZufcPmBbrmnVaqAsO16CVEx0uuMxejpPvnOhtFl9N/Moo+F52NosMwFMSlc+Lw3NBv/cDECkW0TxRBjc5r6nDhFlh7JXdSszBmc2iXdOyj2/tHxxZ2oUjFj+kisgmfBWHS330XHo2i3CEd42UBZm4yqD6j8wk3xdeeyRGvMSJiPAitgIZOIzLufi1IsPuTVbz7x8zzWkYtMm7l1pDOcoTXyvRqeqQSDBhO5E7p2FeqlR5h6nDh6mwIP9OXai4dhv6YwyNjuUxjerlgPjw8ZsQqb3CkfYInWY7wALjMLv2fwrxD9gYr2qQj5CsBXgk23tb5c81imDCWC7j8zo2qDPoJ1Wg+fJUDVKp/sFlw+JJ5fAtiNnWZ4iV8HJeR7WLU7v+pl83chSgMiE+7GSlVrsXpTLB+5Zu1hLnS6ewKZlETJBvIwNUH53MN4GLSHbDk6iPO/NaUXbO3XWftZMDeZcRwBeYuZP5zIf7VMDdmAbF3zHP1qpilc0fhfyaKZPnZJBL66bDEUv+4eP8YLsnU5fz6Kz4sh6oyJm8PEqo/U5bKE17xv7zwOY/Dkyn1OcslF35F+Q9idByILrzS4QAAAABJRU5ErkJggg=='},
 'title': 'EMPTY',
 'date': '',
 'author': 'Automatically Generated',
 'acronyms': {},
 'references': {},
 'applicables': {},
 'template_id': 'fancy_template'}

which will write all needed data to the documents “metadata”. Specifically:

  • template_id will hold the id with which the specific template can be loaded. In our case it will be fancy_template.

  • files_to_upload will hold all assets as base64 encoded bytes in our case the following files:

    • key: fancy_logo.png value content from .../fancy_tempate.assets/fancy_logo.png

    • key: fancy_title_picture.png value content from .../fancy_tempate.assets/fancy_title_picture.png

    • key: i_can_use_this_everywhere.png value content from .../assets/i_can_use_this_everywhere.png (content from assets will be made available shared for all templates)

  • and all other fields loaded from fancy_template.params.json will be loaded to the metadata dictionary directly.

If you thereafter export your document to pdf (or html if you have an html type template), pydocmaker will automatically load the template and render it with parameters, attachments and your document as the body.

you can view the template and params by

[9]:
doc.get_meta()
[9]:
{'typ': 'meta',
 'children': '',
 'data': {'files_to_upload': {'i_can_use_this_everywhere.png': 'iVBORw0KGgoAAAANSUhEUgAAAH4AAAAVCAYAAACAEFoRAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAOwSURBVGhD7Zi/a9toGMc/vbW4l0LRonrQ4GDeQCFD0Q3GcAYPBwZDh3gygczpnj/BezwbjkzuYCgYOgRSCIY7kyEQqAjpoMHVYgJxIzL3Bv2I9OqVrSTOtcH6gMB69Up63+f7vM/7lZ+VSus/yFk5fpMbclaDXPgVJRd+RcmFX1GeJcydMOnXXnD64ZDONHbFR6eza2L4Zzdnh+wcu1KfHIBKtc77NwXvZDKm9dGRuzwyBfa262zOku++84pvN02MyZhWd0CrO3gaoguT/naZitz+yIyOD2l1B+yf3TNGWpnerklbbl8CKcJf4yhXewF9Deyv/3fm5jyEm6truUlR6ufilXmOBuxZ6mvBFhArbcKkX/rG/pUIS19yi5Dudy32/z5nJEz6NRh2xxwE11RtKrQyvS3Bc7kdJ3KvXw79ihwdd6VaZ4cJ0zcCA4fhETRq+m2fTPPyS/5LK1FuE3MO3y21h7ixLTi2lcTmtJhswmcIYLtpwsfgxVKCCJO+HLCYcF5/TRG0xLOAdvMdDZL7VirCpP/2u5dI0qX4s7wkWLe9cXiBhdMP/8JfdTax2P8EO1u/87k75kCel1amt1XkQvJHacLPjRlB3P13xe5MJn+lWue9MVHOUUVKqZeYnrPTHdDqjrEB+8jb31uRAR2EEwBw+DIB7VWQjf4KDiZufcPmBbrmnVaqAsO16CVEx0uuMxejpPvnOhtFl9N/Moo+F52NosMwFMSlc+Lw3NBv/cDECkW0TxRBjc5r6nDhFlh7JXdSszBmc2iXdOyj2/tHxxZ2oUjFj+kisgmfBWHS330XHo2i3CEd42UBZm4yqD6j8wk3xdeeyRGvMSJiPAitgIZOIzLufi1IsPuTVbz7x8zzWkYtMm7l1pDOcoTXyvRqeqQSDBhO5E7p2FeqlR5h6nDh6mwIP9OXai4dhv6YwyNjuUxjerlgPjw8ZsQqb3CkfYInWY7wALjMLv2fwrxD9gYr2qQj5CsBXgk23tb5c81imDCWC7j8zo2qDPoJ1Wg+fJUDVKp/sFlw+JJ5fAtiNnWZ4iV8HJeR7WLU7v+pl83chSgMiE+7GSlVrsXpTLB+5Zu1hLnS6ewKZlETJBvIwNUH53MN4GLSHbDk6iPO/NaUXbO3XWftZMDeZcRwBeYuZP5zIf7VMDdmAbF3zHP1qpilc0fhfyaKZPnZJBL66bDEUv+4eP8YLsnU5fz6Kz4sh6oyJm8PEqo/U5bKE17xv7zwOY/Dkyn1OcslF35F+Q9idByILrzS4QAAAABJRU5ErkJggg==',
   'fancy_logo.png': 'iVBORw0KGgoAAAANSUhEUgAAAH4AAAAVCAYAAACAEFoRAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAOwSURBVGhD7Zi/a9toGMc/vbW4l0LRonrQ4GDeQCFD0Q3GcAYPBwZDh3gygczpnj/BezwbjkzuYCgYOgRSCIY7kyEQqAjpoMHVYgJxIzL3Bv2I9OqVrSTOtcH6gMB69Up63+f7vM/7lZ+VSus/yFk5fpMbclaDXPgVJRd+RcmFX1GeJcydMOnXXnD64ZDONHbFR6eza2L4Zzdnh+wcu1KfHIBKtc77NwXvZDKm9dGRuzwyBfa262zOku++84pvN02MyZhWd0CrO3gaoguT/naZitz+yIyOD2l1B+yf3TNGWpnerklbbl8CKcJf4yhXewF9Deyv/3fm5jyEm6truUlR6ufilXmOBuxZ6mvBFhArbcKkX/rG/pUIS19yi5Dudy32/z5nJEz6NRh2xxwE11RtKrQyvS3Bc7kdJ3KvXw79ihwdd6VaZ4cJ0zcCA4fhETRq+m2fTPPyS/5LK1FuE3MO3y21h7ixLTi2lcTmtJhswmcIYLtpwsfgxVKCCJO+HLCYcF5/TRG0xLOAdvMdDZL7VirCpP/2u5dI0qX4s7wkWLe9cXiBhdMP/8JfdTax2P8EO1u/87k75kCel1amt1XkQvJHacLPjRlB3P13xe5MJn+lWue9MVHOUUVKqZeYnrPTHdDqjrEB+8jb31uRAR2EEwBw+DIB7VWQjf4KDiZufcPmBbrmnVaqAsO16CVEx0uuMxejpPvnOhtFl9N/Moo+F52NosMwFMSlc+Lw3NBv/cDECkW0TxRBjc5r6nDhFlh7JXdSszBmc2iXdOyj2/tHxxZ2oUjFj+kisgmfBWHS330XHo2i3CEd42UBZm4yqD6j8wk3xdeeyRGvMSJiPAitgIZOIzLufi1IsPuTVbz7x8zzWkYtMm7l1pDOcoTXyvRqeqQSDBhO5E7p2FeqlR5h6nDh6mwIP9OXai4dhv6YwyNjuUxjerlgPjw8ZsQqb3CkfYInWY7wALjMLv2fwrxD9gYr2qQj5CsBXgk23tb5c81imDCWC7j8zo2qDPoJ1Wg+fJUDVKp/sFlw+JJ5fAtiNnWZ4iV8HJeR7WLU7v+pl83chSgMiE+7GSlVrsXpTLB+5Zu1hLnS6ewKZlETJBvIwNUH53MN4GLSHbDk6iPO/NaUXbO3XWftZMDeZcRwBeYuZP5zIf7VMDdmAbF3zHP1qpilc0fhfyaKZPnZJBL66bDEUv+4eP8YLsnU5fz6Kz4sh6oyJm8PEqo/U5bKE17xv7zwOY/Dkyn1OcslF35F+Q9idByILrzS4QAAAABJRU5ErkJggg==',
   'fancy_title_picture.png': 'iVBORw0KGgoAAAANSUhEUgAAAH4AAAAVCAYAAACAEFoRAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAOwSURBVGhD7Zi/a9toGMc/vbW4l0LRonrQ4GDeQCFD0Q3GcAYPBwZDh3gygczpnj/BezwbjkzuYCgYOgRSCIY7kyEQqAjpoMHVYgJxIzL3Bv2I9OqVrSTOtcH6gMB69Up63+f7vM/7lZ+VSus/yFk5fpMbclaDXPgVJRd+RcmFX1GeJcydMOnXXnD64ZDONHbFR6eza2L4Zzdnh+wcu1KfHIBKtc77NwXvZDKm9dGRuzwyBfa262zOku++84pvN02MyZhWd0CrO3gaoguT/naZitz+yIyOD2l1B+yf3TNGWpnerklbbl8CKcJf4yhXewF9Deyv/3fm5jyEm6truUlR6ufilXmOBuxZ6mvBFhArbcKkX/rG/pUIS19yi5Dudy32/z5nJEz6NRh2xxwE11RtKrQyvS3Bc7kdJ3KvXw79ihwdd6VaZ4cJ0zcCA4fhETRq+m2fTPPyS/5LK1FuE3MO3y21h7ixLTi2lcTmtJhswmcIYLtpwsfgxVKCCJO+HLCYcF5/TRG0xLOAdvMdDZL7VirCpP/2u5dI0qX4s7wkWLe9cXiBhdMP/8JfdTax2P8EO1u/87k75kCel1amt1XkQvJHacLPjRlB3P13xe5MJn+lWue9MVHOUUVKqZeYnrPTHdDqjrEB+8jb31uRAR2EEwBw+DIB7VWQjf4KDiZufcPmBbrmnVaqAsO16CVEx0uuMxejpPvnOhtFl9N/Moo+F52NosMwFMSlc+Lw3NBv/cDECkW0TxRBjc5r6nDhFlh7JXdSszBmc2iXdOyj2/tHxxZ2oUjFj+kisgmfBWHS330XHo2i3CEd42UBZm4yqD6j8wk3xdeeyRGvMSJiPAitgIZOIzLufi1IsPuTVbz7x8zzWkYtMm7l1pDOcoTXyvRqeqQSDBhO5E7p2FeqlR5h6nDh6mwIP9OXai4dhv6YwyNjuUxjerlgPjw8ZsQqb3CkfYInWY7wALjMLv2fwrxD9gYr2qQj5CsBXgk23tb5c81imDCWC7j8zo2qDPoJ1Wg+fJUDVKp/sFlw+JJ5fAtiNnWZ4iV8HJeR7WLU7v+pl83chSgMiE+7GSlVrsXpTLB+5Zu1hLnS6ewKZlETJBvIwNUH53MN4GLSHbDk6iPO/NaUXbO3XWftZMDeZcRwBeYuZP5zIf7VMDdmAbF3zHP1qpilc0fhfyaKZPnZJBL66bDEUv+4eP8YLsnU5fz6Kz4sh6oyJm8PEqo/U5bKE17xv7zwOY/Dkyn1OcslF35F+Q9idByILrzS4QAAAABJRU5ErkJggg=='},
  'title': 'EMPTY',
  'date': '',
  'author': 'Automatically Generated',
  'acronyms': {},
  'references': {},
  'applicables': {},
  'template_id': 'fancy_template'}}
[10]:
doc.update_meta(author='Me!')
[10]:
{'files_to_upload': {'i_can_use_this_everywhere.png': 'iVBORw0KGgoAAAANSUhEUgAAAH4AAAAVCAYAAACAEFoRAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAOwSURBVGhD7Zi/a9toGMc/vbW4l0LRonrQ4GDeQCFD0Q3GcAYPBwZDh3gygczpnj/BezwbjkzuYCgYOgRSCIY7kyEQqAjpoMHVYgJxIzL3Bv2I9OqVrSTOtcH6gMB69Up63+f7vM/7lZ+VSus/yFk5fpMbclaDXPgVJRd+RcmFX1GeJcydMOnXXnD64ZDONHbFR6eza2L4Zzdnh+wcu1KfHIBKtc77NwXvZDKm9dGRuzwyBfa262zOku++84pvN02MyZhWd0CrO3gaoguT/naZitz+yIyOD2l1B+yf3TNGWpnerklbbl8CKcJf4yhXewF9Deyv/3fm5jyEm6truUlR6ufilXmOBuxZ6mvBFhArbcKkX/rG/pUIS19yi5Dudy32/z5nJEz6NRh2xxwE11RtKrQyvS3Bc7kdJ3KvXw79ihwdd6VaZ4cJ0zcCA4fhETRq+m2fTPPyS/5LK1FuE3MO3y21h7ixLTi2lcTmtJhswmcIYLtpwsfgxVKCCJO+HLCYcF5/TRG0xLOAdvMdDZL7VirCpP/2u5dI0qX4s7wkWLe9cXiBhdMP/8JfdTax2P8EO1u/87k75kCel1amt1XkQvJHacLPjRlB3P13xe5MJn+lWue9MVHOUUVKqZeYnrPTHdDqjrEB+8jb31uRAR2EEwBw+DIB7VWQjf4KDiZufcPmBbrmnVaqAsO16CVEx0uuMxejpPvnOhtFl9N/Moo+F52NosMwFMSlc+Lw3NBv/cDECkW0TxRBjc5r6nDhFlh7JXdSszBmc2iXdOyj2/tHxxZ2oUjFj+kisgmfBWHS330XHo2i3CEd42UBZm4yqD6j8wk3xdeeyRGvMSJiPAitgIZOIzLufi1IsPuTVbz7x8zzWkYtMm7l1pDOcoTXyvRqeqQSDBhO5E7p2FeqlR5h6nDh6mwIP9OXai4dhv6YwyNjuUxjerlgPjw8ZsQqb3CkfYInWY7wALjMLv2fwrxD9gYr2qQj5CsBXgk23tb5c81imDCWC7j8zo2qDPoJ1Wg+fJUDVKp/sFlw+JJ5fAtiNnWZ4iV8HJeR7WLU7v+pl83chSgMiE+7GSlVrsXpTLB+5Zu1hLnS6ewKZlETJBvIwNUH53MN4GLSHbDk6iPO/NaUXbO3XWftZMDeZcRwBeYuZP5zIf7VMDdmAbF3zHP1qpilc0fhfyaKZPnZJBL66bDEUv+4eP8YLsnU5fz6Kz4sh6oyJm8PEqo/U5bKE17xv7zwOY/Dkyn1OcslF35F+Q9idByILrzS4QAAAABJRU5ErkJggg==',
  'fancy_logo.png': 'iVBORw0KGgoAAAANSUhEUgAAAH4AAAAVCAYAAACAEFoRAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAOwSURBVGhD7Zi/a9toGMc/vbW4l0LRonrQ4GDeQCFD0Q3GcAYPBwZDh3gygczpnj/BezwbjkzuYCgYOgRSCIY7kyEQqAjpoMHVYgJxIzL3Bv2I9OqVrSTOtcH6gMB69Up63+f7vM/7lZ+VSus/yFk5fpMbclaDXPgVJRd+RcmFX1GeJcydMOnXXnD64ZDONHbFR6eza2L4Zzdnh+wcu1KfHIBKtc77NwXvZDKm9dGRuzwyBfa262zOku++84pvN02MyZhWd0CrO3gaoguT/naZitz+yIyOD2l1B+yf3TNGWpnerklbbl8CKcJf4yhXewF9Deyv/3fm5jyEm6truUlR6ufilXmOBuxZ6mvBFhArbcKkX/rG/pUIS19yi5Dudy32/z5nJEz6NRh2xxwE11RtKrQyvS3Bc7kdJ3KvXw79ihwdd6VaZ4cJ0zcCA4fhETRq+m2fTPPyS/5LK1FuE3MO3y21h7ixLTi2lcTmtJhswmcIYLtpwsfgxVKCCJO+HLCYcF5/TRG0xLOAdvMdDZL7VirCpP/2u5dI0qX4s7wkWLe9cXiBhdMP/8JfdTax2P8EO1u/87k75kCel1amt1XkQvJHacLPjRlB3P13xe5MJn+lWue9MVHOUUVKqZeYnrPTHdDqjrEB+8jb31uRAR2EEwBw+DIB7VWQjf4KDiZufcPmBbrmnVaqAsO16CVEx0uuMxejpPvnOhtFl9N/Moo+F52NosMwFMSlc+Lw3NBv/cDECkW0TxRBjc5r6nDhFlh7JXdSszBmc2iXdOyj2/tHxxZ2oUjFj+kisgmfBWHS330XHo2i3CEd42UBZm4yqD6j8wk3xdeeyRGvMSJiPAitgIZOIzLufi1IsPuTVbz7x8zzWkYtMm7l1pDOcoTXyvRqeqQSDBhO5E7p2FeqlR5h6nDh6mwIP9OXai4dhv6YwyNjuUxjerlgPjw8ZsQqb3CkfYInWY7wALjMLv2fwrxD9gYr2qQj5CsBXgk23tb5c81imDCWC7j8zo2qDPoJ1Wg+fJUDVKp/sFlw+JJ5fAtiNnWZ4iV8HJeR7WLU7v+pl83chSgMiE+7GSlVrsXpTLB+5Zu1hLnS6ewKZlETJBvIwNUH53MN4GLSHbDk6iPO/NaUXbO3XWftZMDeZcRwBeYuZP5zIf7VMDdmAbF3zHP1qpilc0fhfyaKZPnZJBL66bDEUv+4eP8YLsnU5fz6Kz4sh6oyJm8PEqo/U5bKE17xv7zwOY/Dkyn1OcslF35F+Q9idByILrzS4QAAAABJRU5ErkJggg==',
  'fancy_title_picture.png': 'iVBORw0KGgoAAAANSUhEUgAAAH4AAAAVCAYAAACAEFoRAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAOwSURBVGhD7Zi/a9toGMc/vbW4l0LRonrQ4GDeQCFD0Q3GcAYPBwZDh3gygczpnj/BezwbjkzuYCgYOgRSCIY7kyEQqAjpoMHVYgJxIzL3Bv2I9OqVrSTOtcH6gMB69Up63+f7vM/7lZ+VSus/yFk5fpMbclaDXPgVJRd+RcmFX1GeJcydMOnXXnD64ZDONHbFR6eza2L4Zzdnh+wcu1KfHIBKtc77NwXvZDKm9dGRuzwyBfa262zOku++84pvN02MyZhWd0CrO3gaoguT/naZitz+yIyOD2l1B+yf3TNGWpnerklbbl8CKcJf4yhXewF9Deyv/3fm5jyEm6truUlR6ufilXmOBuxZ6mvBFhArbcKkX/rG/pUIS19yi5Dudy32/z5nJEz6NRh2xxwE11RtKrQyvS3Bc7kdJ3KvXw79ihwdd6VaZ4cJ0zcCA4fhETRq+m2fTPPyS/5LK1FuE3MO3y21h7ixLTi2lcTmtJhswmcIYLtpwsfgxVKCCJO+HLCYcF5/TRG0xLOAdvMdDZL7VirCpP/2u5dI0qX4s7wkWLe9cXiBhdMP/8JfdTax2P8EO1u/87k75kCel1amt1XkQvJHacLPjRlB3P13xe5MJn+lWue9MVHOUUVKqZeYnrPTHdDqjrEB+8jb31uRAR2EEwBw+DIB7VWQjf4KDiZufcPmBbrmnVaqAsO16CVEx0uuMxejpPvnOhtFl9N/Moo+F52NosMwFMSlc+Lw3NBv/cDECkW0TxRBjc5r6nDhFlh7JXdSszBmc2iXdOyj2/tHxxZ2oUjFj+kisgmfBWHS330XHo2i3CEd42UBZm4yqD6j8wk3xdeeyRGvMSJiPAitgIZOIzLufi1IsPuTVbz7x8zzWkYtMm7l1pDOcoTXyvRqeqQSDBhO5E7p2FeqlR5h6nDh6mwIP9OXai4dhv6YwyNjuUxjerlgPjw8ZsQqb3CkfYInWY7wALjMLv2fwrxD9gYr2qQj5CsBXgk23tb5c81imDCWC7j8zo2qDPoJ1Wg+fJUDVKp/sFlw+JJ5fAtiNnWZ4iV8HJeR7WLU7v+pl83chSgMiE+7GSlVrsXpTLB+5Zu1hLnS6ewKZlETJBvIwNUH53MN4GLSHbDk6iPO/NaUXbO3XWftZMDeZcRwBeYuZP5zIf7VMDdmAbF3zHP1qpilc0fhfyaKZPnZJBL66bDEUv+4eP8YLsnU5fz6Kz4sh6oyJm8PEqo/U5bKE17xv7zwOY/Dkyn1OcslF35F+Q9idByILrzS4QAAAABJRU5ErkJggg=='},
 'title': 'EMPTY',
 'date': '',
 'author': 'Me!',
 'acronyms': {},
 'references': {},
 'applicables': {},
 'template_id': 'fancy_template'}

Jinja2 templates from strings

you can also use Jinja2 Templates directly to make HTML or PDF (latex) documents. An example is given below:

[11]:
# This is a minimal template, the document will be written to the "body" part.
template = r'''
\documentclass[a4paper]{article}

{% if title %}\title {{ title }}{% endif %}
{% if author %}\author {{ author }}{% endif %}

\begin{document}

{{ body }}

\end{document}
'''

from jinja2 import Environment, FileSystemLoader
import pydocmaker as pyd


doc = pyd.get_example()
pdf_bytes = doc.to_pdf(template=template, template_params=dict(title='My Title', author='Me'))
len(pdf_bytes), type(pdf_bytes)
testing available latex compilers
DONE testing latex compilers: found compiler="pdflatex"
Running with latex_compiler='pdflatex'
Writing file: 1769438669_mydocument.tex
Writing file: img_1769438669001321700.png
Compilation run 1
C:\Users\tglaubach\repos\pydocmaker\src\pydocmaker\backend\pdf_maker.py:100: UserWarning: Command pdflatex -interaction nonstopmode 1769438669_mydocument.tex returned non-zero exit status 1
  warnings.warn(s)
Compilation run 2
Compilation run 3
Reading PDF to bytes: C:\Users\tglaubach\AppData\Local\Temp\tmpgbj58z31
[11]:
(114227, bytes)
[12]:
tex_string, attachments = doc.to_tex(template=template, template_params=dict(title='My Title', author='Me'))
print(tex_string[:100] + '...')

\documentclass[a4paper]{article}

\title My Title
\author Me

\begin{document}

\subsection{Some Ex...

NOTE: If you use template strings directly and your document template has external references such as logos, you need to load them to a bytes array and pass them as a {filename:content} dictionary into the to_pdf(…) methods using the files_to_upload argument.

[13]:
assets = {}
with open(r'C:\Users\tglaubach\repos\pydocmaker\example_templates\fancy_template.assets\fancy_logo.png', 'rb') as fp:
    assets = {'fancy_logo.png': fp.read()}

pdf_bytes = doc.to_pdf(template=template, template_params=dict(title='My Title', author='Me'), files_to_upload=assets)
len(pdf_bytes), type(pdf_bytes)
Running with latex_compiler='pdflatex'
Writing file: 1769438671_mydocument.tex
Writing file: img_1769438669001321700.png
Writing file: fancy_logo.png
Compilation run 1
C:\Users\tglaubach\repos\pydocmaker\src\pydocmaker\backend\pdf_maker.py:100: UserWarning: Command pdflatex -interaction nonstopmode 1769438671_mydocument.tex returned non-zero exit status 1
  warnings.warn(s)
Compilation run 2
Compilation run 3
Reading PDF to bytes: C:\Users\tglaubach\AppData\Local\Temp\tmpwvh0s68l
[13]:
(114227, bytes)