Render pdf templates with jinja
This commit is contained in:
parent
3e4b951bf1
commit
19df5f4b2a
9 changed files with 121 additions and 19 deletions
16
md_pdf/assets/templates/footer-template.html
Normal file
16
md_pdf/assets/templates/footer-template.html
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet" href="../static/style.css" />
|
||||||
|
</head>
|
||||||
|
<body class="footer">
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
Page <span class="page"></span> of <span class="topage"></span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<script type="text/javascript" src="../static/context.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
9
md_pdf/assets/templates/header-template.html
Normal file
9
md_pdf/assets/templates/header-template.html
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet" href="../static/style.css" />
|
||||||
|
</head>
|
||||||
|
<body class="header">
|
||||||
|
<script type="text/javascript" src="../static/context.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
62
md_pdf/assets/templates/toc-template.xsl
Normal file
62
md_pdf/assets/templates/toc-template.xsl
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<xsl:stylesheet version="2.0"
|
||||||
|
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||||
|
xmlns:outline="http://wkhtmltopdf.org/outline"
|
||||||
|
xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<xsl:output doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||||
|
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
|
||||||
|
indent="yes" />
|
||||||
|
<xsl:template match="outline:outline">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Table of Contents</title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
|
<style>
|
||||||
|
h1 {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 20px;
|
||||||
|
font-family: arial;
|
||||||
|
}
|
||||||
|
div {border-bottom: 1px dashed rgb(200,200,200);}
|
||||||
|
span {float: right;}
|
||||||
|
li {list-style: none;}
|
||||||
|
ul {
|
||||||
|
font-size: 20px;
|
||||||
|
font-family: arial;
|
||||||
|
}
|
||||||
|
ul ul {font-size: 80%; }
|
||||||
|
ul {padding-left: 0em;}
|
||||||
|
ul ul {padding-left: 1em;}
|
||||||
|
a {text-decoration:none; color: black;}
|
||||||
|
</style>
|
||||||
|
<link rel="stylesheet" href="{{ static_dir }}/style.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Table of Contents</h1>
|
||||||
|
<ul><xsl:apply-templates select="outline:item/outline:item"/></ul>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
</xsl:template>
|
||||||
|
<xsl:template match="outline:item">
|
||||||
|
<li>
|
||||||
|
<xsl:if test="@page!='2'">
|
||||||
|
<div>
|
||||||
|
<a>
|
||||||
|
<xsl:if test="@link">
|
||||||
|
<xsl:attribute name="href"><xsl:value-of select="@link"/></xsl:attribute>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:if test="@backLink">
|
||||||
|
<xsl:attribute name="name"><xsl:value-of select="@backLink"/></xsl:attribute>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:value-of select="@title" />
|
||||||
|
</a>
|
||||||
|
<span> <xsl:value-of select="@page" /> </span>
|
||||||
|
</div>
|
||||||
|
</xsl:if>
|
||||||
|
<ul>
|
||||||
|
<xsl:comment>added to prevent self-closing tags in QtXmlPatterns</xsl:comment>
|
||||||
|
<xsl:apply-templates select="outline:item"/>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</xsl:template>
|
||||||
|
</xsl:stylesheet>
|
|
@ -29,6 +29,7 @@
|
||||||
ul ul {padding-left: 1em;}
|
ul ul {padding-left: 1em;}
|
||||||
a {text-decoration:none; color: black;}
|
a {text-decoration:none; color: black;}
|
||||||
</style>
|
</style>
|
||||||
|
<link rel="stylesheet" href="/home/jake/Projects/md-pdf/md_pdf/assets/static/style.css" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>Table of Contents</h1>
|
<h1>Table of Contents</h1>
|
||||||
|
@ -38,7 +39,7 @@
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
<xsl:template match="outline:item">
|
<xsl:template match="outline:item">
|
||||||
<li>
|
<li>
|
||||||
<xsl:if test="@title!=''">
|
<xsl:if test="@page!='2'">
|
||||||
<div>
|
<div>
|
||||||
<a>
|
<a>
|
||||||
<xsl:if test="@link">
|
<xsl:if test="@link">
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from md_pdf.build.md import read_files
|
from md_pdf.build.md import read_files
|
||||||
from md_pdf.build.pandoc import build_document, output_html
|
from md_pdf.build.pandoc import build_document, output_html
|
||||||
from md_pdf.build.templates import render_cover
|
from md_pdf.build.templates import render_templates
|
||||||
from md_pdf.build.css import render_css
|
from md_pdf.build.css import render_css
|
||||||
from md_pdf.build.pdf import export_pdf
|
from md_pdf.build.pdf import export_pdf
|
||||||
from md_pdf.build.content import parse_template
|
from md_pdf.build.content import parse_template
|
||||||
|
@ -20,7 +20,7 @@ def build(config):
|
||||||
if 'html' in config['output_formats']:
|
if 'html' in config['output_formats']:
|
||||||
output_html(parsed_template, os.path.abspath(config['output_dir']))
|
output_html(parsed_template, os.path.abspath(config['output_dir']))
|
||||||
if 'pdf' in config['output_formats']:
|
if 'pdf' in config['output_formats']:
|
||||||
render_cover(config)
|
render_templates(config)
|
||||||
render_css()
|
render_css()
|
||||||
export_pdf(parsed_template, config)
|
export_pdf(parsed_template, config)
|
||||||
logger.info('Output completed in {:.2f} seconds.'.format(time.time() - start_time))
|
logger.info('Output completed in {:.2f} seconds.'.format(time.time() - start_time))
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import pdfkit
|
import pdfkit
|
||||||
from md_pdf.consts import TEMPLATES_DIR, STATIC_DIR
|
from md_pdf.consts import TEMPLATES_DIR, STATIC_DIR
|
||||||
from md_pdf.build.templates import OUTPUT_COVER_FILE
|
from md_pdf.build.templates import FILE_NAME_FORMAT
|
||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
@ -14,10 +14,9 @@ DEFAULT_MARGIN_HORIZONTAL = '2.5cm'
|
||||||
STYLE_FILE = os.path.join(STATIC_DIR, 'style.css')
|
STYLE_FILE = os.path.join(STATIC_DIR, 'style.css')
|
||||||
HEADER_FILE = os.path.join(TEMPLATES_DIR, 'header.html')
|
HEADER_FILE = os.path.join(TEMPLATES_DIR, 'header.html')
|
||||||
FOOTER_FILE = os.path.join(TEMPLATES_DIR, 'footer.html')
|
FOOTER_FILE = os.path.join(TEMPLATES_DIR, 'footer.html')
|
||||||
TOC_TEMPLATE_FILE = os.path.join(TEMPLATES_DIR, 'toc.xsl')
|
|
||||||
|
|
||||||
TOC_OPTIONS = {
|
TOC_OPTIONS = {
|
||||||
'xsl-style-sheet': TOC_TEMPLATE_FILE
|
'xsl-style-sheet': os.path.join(TEMPLATES_DIR, 'toc.xsl')
|
||||||
}
|
}
|
||||||
|
|
||||||
PDF_OPTIONS = {
|
PDF_OPTIONS = {
|
||||||
|
@ -49,7 +48,7 @@ def export_pdf(content, config):
|
||||||
content,
|
content,
|
||||||
os.path.join(os.path.abspath(config['output_dir']), 'output.pdf'),
|
os.path.join(os.path.abspath(config['output_dir']), 'output.pdf'),
|
||||||
options=PDF_OPTIONS,
|
options=PDF_OPTIONS,
|
||||||
cover=OUTPUT_COVER_FILE,
|
cover=FILE_NAME_FORMAT.format('cover'),
|
||||||
toc=TOC_OPTIONS,
|
toc=TOC_OPTIONS,
|
||||||
cover_first=True
|
cover_first=True
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,22 +1,37 @@
|
||||||
from jinja2 import Template
|
from jinja2 import Template
|
||||||
from md_pdf.consts import TEMPLATES_DIR
|
from md_pdf.consts import TEMPLATES_DIR, STATIC_DIR
|
||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
logger = logging.getLogger(__file__)
|
logger = logging.getLogger(__file__)
|
||||||
|
|
||||||
|
EXTRA_CONFIG = {
|
||||||
|
'templates_dir': TEMPLATES_DIR,
|
||||||
|
'static_dir': STATIC_DIR
|
||||||
|
}
|
||||||
|
|
||||||
COVER_TEMPLATE = os.path.join(TEMPLATES_DIR, 'cover-template.html')
|
FILE_NAME_FORMAT = os.path.join(TEMPLATES_DIR, "{}.html")
|
||||||
OUTPUT_COVER_FILE = os.path.join(TEMPLATES_DIR, 'cover.html')
|
TEMPLATE_FORMAT = os.path.join(TEMPLATES_DIR, "{}-template.html")
|
||||||
|
|
||||||
|
|
||||||
def render_cover(config):
|
def render_page(input_file, output_file, context):
|
||||||
logger.debug("Rendering Cover...")
|
logger.debug("Rendering {}...")
|
||||||
context = config['context'].copy()
|
with open(input_file) as f:
|
||||||
context['title'] = config['title']
|
|
||||||
with open(COVER_TEMPLATE) as f:
|
|
||||||
template = Template(f.read())
|
template = Template(f.read())
|
||||||
with open(OUTPUT_COVER_FILE, "w") as f:
|
with open(output_file, "w") as f:
|
||||||
cover = template.render(context)
|
cover = template.render(context)
|
||||||
f.write(cover)
|
f.write(cover)
|
||||||
return cover
|
return cover
|
||||||
|
|
||||||
|
|
||||||
|
def render_templates(config):
|
||||||
|
context = config['context'].copy()
|
||||||
|
context['title'] = config['title']
|
||||||
|
context = dict(context, **EXTRA_CONFIG)
|
||||||
|
for template in [
|
||||||
|
'cover',
|
||||||
|
'header',
|
||||||
|
'footer'
|
||||||
|
]:
|
||||||
|
render_page(TEMPLATE_FORMAT.format(template), FILE_NAME_FORMAT.format(template), context)
|
||||||
|
render_page(os.path.join(TEMPLATES_DIR, 'toc-template.xsl'), os.path.join(TEMPLATES_DIR, 'toc.xsl'), context)
|
||||||
|
|
Reference in a new issue