Thanks for the reply! I don’t mean to dismiss your solutions but we have tried some of them and unfortunately the results are not very good. Here is a brief overview:
We started with HTML → PDF with a prototype using WeasyPrint
. Because of inconsistent renders compared to a browser (IIRC flexbox and tables, cf. issues on GitHub), we tried pdfkit
(a wrapper for wkhtmltopdf). We encountered some issues with it (IIRC it is something about fonts but in general wkhtmltopdf is outdated) and ended up with pupeteer
+ Chrome. There the render finally looks alright but margin boxes aren’t supported. We are aware of Paged.js and used it with headless Chrome but for some reason it doesn’t work well enough (we need something to stay at a particular page, while break-before/inside/after
works, it also creates a massive empty space where an element could fit). Page numbers didn’t work either.
After investing quite some effort rewriting layout with older CSS and fighting with renderers to get an arguably acceptable output we switched to LaTeX. There are some issues (distro packaging) but in general it went very well, the performance is comparable with headless Chrome yet the output is way better. We had a prototype built with Python3+Jinja2 and I am integrating it into our Phoenix application to simplify the codebase. DocRaptor and PrinceXML are great solutions but I will need to go through some company process, in the meantime I would like to make EEx work with it.
Anyway I created a format encoder based on the one within Phoenix.HTML and changed the list of escape characters. When I look at the output on the browser, the whole template is escaped besides the EEx snippets. What did I miss?
Controller:
conn
|> put_resp_content_type("text/plain")
|> render("invoice.tex", example_invoice)
List of escaped characters (taken from PyLaTeX):
escapes = [
{?{, "\\{"},
{?}, "\\}"},
{?\\, "\\textbackslash{}"},
{?#, "\\#"},
{?$, "\\$"},
{?%, "\\%"},
{?&, "\\&"},
{?^, "\\^{}"},
{?_, "\\_"},
{?~, "\\textasciitilde{}"},
{?\n, "\\\\newline%\n"},
{?-, "{-}"},
{0xA0, "~"},
{?[, "{[}"},
{?], "{]}"}
]
The rest are the same in both engine.ex
and safe.ex
besides renaming the modules and html_escape/1
to tex_escape/1
config.exs:
config :phoenix, :format_encoders,
html: Phoenix.HTML.Engine,
tex: MyApp.TeX.Engine