Merge pull request #12 from RealOrangeOne/context
More rendering context
This commit is contained in:
commit
2c7c905c42
16 changed files with 121 additions and 18 deletions
|
@ -0,0 +1 @@
|
||||||
|
__version__ = '1.0'
|
|
@ -1,9 +1,11 @@
|
||||||
import argparse
|
import argparse
|
||||||
|
from md_pdf import __version__
|
||||||
|
|
||||||
|
|
||||||
def parse_args():
|
def parse_args():
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument("-v", "--verbose", help="Set verbosity level (repeat argument)", action="count", default=0)
|
parser.add_argument("-v", "--verbose", help="Set verbosity level (repeat argument)", action="count", default=0)
|
||||||
parser.add_argument("--update-csl", help="Update CSL files", action="store_true")
|
parser.add_argument("--update-csl", help="Update CSL files", action="store_true")
|
||||||
|
parser.add_argument("--version", action="version", version="%(prog)s {}".format(__version__))
|
||||||
parser.add_help = True
|
parser.add_help = True
|
||||||
return parser.parse_args()
|
return parser.parse_args()
|
||||||
|
|
|
@ -54,6 +54,7 @@ body.footer, body.header {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
td {
|
td {
|
||||||
|
width: 33%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,5 +16,9 @@
|
||||||
{% if turnitin_number %}
|
{% if turnitin_number %}
|
||||||
<h4>TurnItIn Number: {{ turnitin_number }}</h4>
|
<h4>TurnItIn Number: {{ turnitin_number }}</h4>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{% if submission_date %}
|
||||||
|
<h4>Submission Date: {{ submission_date }}</h4>
|
||||||
|
{% endif %}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -6,9 +6,15 @@
|
||||||
<body class="footer">
|
<body class="footer">
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
|
<td></td>
|
||||||
<td>
|
<td>
|
||||||
Page <span class="page"></span> of <span class="topage"></span>
|
Page <span class="page"></span> of <span class="topage"></span>
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
{% if word_count %}
|
||||||
|
Total Words: {{ word_count }}
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<script type="text/javascript" src="../static/context.js"></script>
|
<script type="text/javascript" src="../static/context.js"></script>
|
||||||
|
|
|
@ -4,6 +4,17 @@
|
||||||
<link rel="stylesheet" href="../static/style.css" />
|
<link rel="stylesheet" href="../static/style.css" />
|
||||||
</head>
|
</head>
|
||||||
<body class="header">
|
<body class="header">
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>{{ title }}</td>
|
||||||
|
<td></td>
|
||||||
|
<td>
|
||||||
|
{% if submission_date %}
|
||||||
|
Date: {{ submission_date }}
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
<script type="text/javascript" src="../static/context.js"></script>
|
<script type="text/javascript" src="../static/context.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -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_templates(config)
|
render_templates(config, parsed_template)
|
||||||
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))
|
||||||
|
|
|
@ -2,6 +2,7 @@ from jinja2 import Template
|
||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
|
from md_pdf.build.context import get_context
|
||||||
|
|
||||||
logger = logging.getLogger(__file__)
|
logger = logging.getLogger(__file__)
|
||||||
|
|
||||||
|
@ -38,7 +39,8 @@ def add_body_class(doc, config):
|
||||||
def render_template(html, config):
|
def render_template(html, config):
|
||||||
logger.debug("Rendering Template...")
|
logger.debug("Rendering Template...")
|
||||||
template = Template(html)
|
template = Template(html)
|
||||||
return template.render(config)
|
context = get_context(config, html)
|
||||||
|
return template.render(context)
|
||||||
|
|
||||||
|
|
||||||
def parse_template(doc, config):
|
def parse_template(doc, config):
|
||||||
|
|
40
md_pdf/build/context.py
Normal file
40
md_pdf/build/context.py
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
from md_pdf.consts import TEMPLATES_DIR, STATIC_DIR, DATE_FORMAT, TIME_FORMAT, DATETIME_FORMAT
|
||||||
|
from word_count import word_count
|
||||||
|
from md_pdf.utils import get_plain_text
|
||||||
|
from md_pdf import __version__
|
||||||
|
from dateutil import parser
|
||||||
|
import datetime
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
EXTRA_CONTEXT = {
|
||||||
|
'templates_dir': TEMPLATES_DIR,
|
||||||
|
'static_dir': STATIC_DIR,
|
||||||
|
'date': datetime.datetime.now().strftime(DATE_FORMAT),
|
||||||
|
'time': datetime.datetime.now().strftime(TIME_FORMAT),
|
||||||
|
'datetime': datetime.datetime.now().strftime(DATETIME_FORMAT),
|
||||||
|
'mdp_version': __version__
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def get_context(config, content):
|
||||||
|
config = config.copy()
|
||||||
|
context = config['context'].copy()
|
||||||
|
del config['context']
|
||||||
|
context = dict(
|
||||||
|
config,
|
||||||
|
**EXTRA_CONTEXT,
|
||||||
|
**context,
|
||||||
|
**{
|
||||||
|
'output_dir': os.path.abspath(config['output_dir']),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if config.get('show_word_count'):
|
||||||
|
context['word_count'] = word_count(get_plain_text(content))
|
||||||
|
if config.get('submission_date'):
|
||||||
|
if type(config['submission_date']) in [datetime.date, datetime.datetime, datetime.time]:
|
||||||
|
submission_date = config['submission_date']
|
||||||
|
else:
|
||||||
|
submission_date = parser.parse(config['submission_date'])
|
||||||
|
context['submission_date'] = submission_date.strftime(DATE_FORMAT)
|
||||||
|
return context
|
|
@ -1,14 +1,11 @@
|
||||||
from jinja2 import Template
|
from jinja2 import Template
|
||||||
from md_pdf.consts import TEMPLATES_DIR, STATIC_DIR
|
from md_pdf.consts import TEMPLATES_DIR
|
||||||
|
from md_pdf.build.context import get_context
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
FILE_NAME_FORMAT = os.path.join(TEMPLATES_DIR, "{}.html")
|
FILE_NAME_FORMAT = os.path.join(TEMPLATES_DIR, "{}.html")
|
||||||
TEMPLATE_FORMAT = os.path.join(TEMPLATES_DIR, "{}-template.html")
|
TEMPLATE_FORMAT = os.path.join(TEMPLATES_DIR, "{}-template.html")
|
||||||
|
@ -24,10 +21,8 @@ def render_page(input_file, output_file, context):
|
||||||
return cover
|
return cover
|
||||||
|
|
||||||
|
|
||||||
def render_templates(config):
|
def render_templates(config, content):
|
||||||
context = config['context'].copy()
|
context = get_context(config, content)
|
||||||
context['title'] = config['title']
|
|
||||||
context = dict(context, **EXTRA_CONFIG)
|
|
||||||
for template in [
|
for template in [
|
||||||
'cover',
|
'cover',
|
||||||
'header',
|
'header',
|
||||||
|
|
|
@ -3,7 +3,8 @@ from md_pdf.consts import CSL_DIR
|
||||||
import glob
|
import glob
|
||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
|
from dateutil import parser
|
||||||
|
import datetime
|
||||||
|
|
||||||
logger = logging.getLogger(__file__)
|
logger = logging.getLogger(__file__)
|
||||||
|
|
||||||
|
@ -76,6 +77,24 @@ def validate_toc(config):
|
||||||
raise ConfigValidationException("Table of contents key should be either true or false")
|
raise ConfigValidationException("Table of contents key should be either true or false")
|
||||||
|
|
||||||
|
|
||||||
|
def validate_wordcount(config):
|
||||||
|
if 'show_word_count' not in config:
|
||||||
|
return
|
||||||
|
if type(config['show_word_count']) != bool:
|
||||||
|
raise ConfigValidationException("Show word count key should be either true or false")
|
||||||
|
|
||||||
|
|
||||||
|
def validate_submission_date(config):
|
||||||
|
if 'submission_date' not in config:
|
||||||
|
return
|
||||||
|
if type(config['submission_date']) in [datetime.date, datetime.datetime, datetime.time]:
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
parser.parse(config['submission_date'])
|
||||||
|
except ValueError:
|
||||||
|
raise ConfigValidationException("Invalid Submission Date format")
|
||||||
|
|
||||||
|
|
||||||
def validate_config(config):
|
def validate_config(config):
|
||||||
logger.debug("Validating Config...")
|
logger.debug("Validating Config...")
|
||||||
for validator in [
|
for validator in [
|
||||||
|
@ -84,7 +103,9 @@ def validate_config(config):
|
||||||
test_output,
|
test_output,
|
||||||
validate_bibliography,
|
validate_bibliography,
|
||||||
validate_context,
|
validate_context,
|
||||||
validate_toc
|
validate_toc,
|
||||||
|
validate_wordcount,
|
||||||
|
validate_submission_date
|
||||||
]:
|
]:
|
||||||
validator(config)
|
validator(config)
|
||||||
logger.debug("Config Ok!")
|
logger.debug("Config Ok!")
|
||||||
|
|
|
@ -11,3 +11,7 @@ STATIC_DIR = os.path.join(ASSET_DIR, 'static')
|
||||||
CONFIG_FILE = os.path.join(WORKING_DIR, 'mdp.yml')
|
CONFIG_FILE = os.path.join(WORKING_DIR, 'mdp.yml')
|
||||||
|
|
||||||
CSL_DOWNLOAD_LINK = "https://github.com/citation-style-language/styles/archive/master.zip"
|
CSL_DOWNLOAD_LINK = "https://github.com/citation-style-language/styles/archive/master.zip"
|
||||||
|
|
||||||
|
DATE_FORMAT = "%d %B %Y"
|
||||||
|
TIME_FORMAT = "%H:%M"
|
||||||
|
DATETIME_FORMAT = "{} {}".format(DATE_FORMAT, TIME_FORMAT)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import shutil
|
import shutil
|
||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
|
from bs4 import BeautifulSoup
|
||||||
|
|
||||||
logger = logging.getLogger(__file__)
|
logger = logging.getLogger(__file__)
|
||||||
|
|
||||||
|
@ -19,3 +20,14 @@ def safe_list_get(l, idx, default):
|
||||||
return l[idx]
|
return l[idx]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
return default
|
return default
|
||||||
|
|
||||||
|
|
||||||
|
def get_plain_text(content):
|
||||||
|
soup = BeautifulSoup(content, 'html.parser')
|
||||||
|
body = soup.find('body')
|
||||||
|
try:
|
||||||
|
body.find('h1', class_='references-title').extract()
|
||||||
|
body.find('div', class_='references').extract()
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
return body.text
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
sudo apt-get install -y openssl build-essential xorg libssl-dev
|
sudo apt-get install -y openssl build-essential xorg libssl-dev
|
||||||
wget http://download.gna.org/wkhtmltopdf/0.12/0.12.3/wkhtmltox-0.12.3_linux-generic-amd64.tar.xz
|
wget https://downloads.wkhtmltopdf.org/0.12/0.12.4/wkhtmltox-0.12.4_linux-generic-amd64.tar.xz
|
||||||
tar -xJf wkhtmltox-0.12.3_linux-generic-amd64.tar.xz
|
tar -xJf wkhtmltox-0.12.4_linux-generic-amd64.tar.xz
|
||||||
cd wkhtmltox
|
cd wkhtmltox
|
||||||
sudo chown root:root bin/wkhtmltopdf
|
sudo chown root:root bin/wkhtmltopdf
|
||||||
sudo cp -r * /usr/
|
sudo cp -r * /usr/
|
||||||
|
|
8
setup.py
8
setup.py
|
@ -1,9 +1,9 @@
|
||||||
from setuptools import setup, find_packages
|
from setuptools import setup, find_packages
|
||||||
|
from md_pdf import __version__
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name="md-pdf",
|
name="md-pdf",
|
||||||
version="1.0",
|
version=__version__,
|
||||||
use_scm_version=True,
|
use_scm_version=True,
|
||||||
install_requires=[
|
install_requires=[
|
||||||
"beautifulsoup4==4.5.3",
|
"beautifulsoup4==4.5.3",
|
||||||
|
@ -12,7 +12,9 @@ setup(
|
||||||
"progressbar2==3.16.0",
|
"progressbar2==3.16.0",
|
||||||
"pypandoc==1.3.3",
|
"pypandoc==1.3.3",
|
||||||
"pyscss==1.3.5",
|
"pyscss==1.3.5",
|
||||||
"PyYAML==3.12"
|
"python-dateutil==2.6.0",
|
||||||
|
"PyYAML==3.12",
|
||||||
|
"word-count==0.1.0"
|
||||||
],
|
],
|
||||||
setup_requires=['setuptools_scm'],
|
setup_requires=['setuptools_scm'],
|
||||||
packages=find_packages(),
|
packages=find_packages(),
|
||||||
|
|
|
@ -13,3 +13,5 @@ context:
|
||||||
turnitin_number: 789123
|
turnitin_number: 789123
|
||||||
title: test title
|
title: test title
|
||||||
toc: true
|
toc: true
|
||||||
|
show_word_count: true
|
||||||
|
submission_date: 2017-01-01
|
||||||
|
|
Reference in a new issue