mirror of https://github.com/nanoy42/coope
Yoann Piétri
5 years ago
13 changed files with 6 additions and 189 deletions
@ -1,21 +0,0 @@ |
|||
MIT License |
|||
|
|||
Copyright (c) 2017 Martin Bierbaum |
|||
|
|||
Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
of this software and associated documentation files (the "Software"), to deal |
|||
in the Software without restriction, including without limitation the rights |
|||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|||
copies of the Software, and to permit persons to whom the Software is |
|||
furnished to do so, subject to the following conditions: |
|||
|
|||
The above copyright notice and this permission notice shall be included in all |
|||
copies or substantial portions of the Software. |
|||
|
|||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
|||
SOFTWARE. |
@ -1,50 +0,0 @@ |
|||
|
|||
import os |
|||
from subprocess import PIPE, run |
|||
import tempfile |
|||
|
|||
from django.template.loader import get_template |
|||
|
|||
from django_tex.exceptions import TexError |
|||
from django.conf import settings |
|||
|
|||
DEFAULT_INTERPRETER = 'pdflatex' |
|||
|
|||
def run_tex(source): |
|||
""" |
|||
Copy the source to temp dict and run latex. |
|||
""" |
|||
with tempfile.TemporaryDirectory() as tempdir: |
|||
filename = os.path.join(tempdir, 'texput.tex') |
|||
with open(filename, 'x', encoding='utf-8') as f: |
|||
f.write(source) |
|||
print(source) |
|||
latex_interpreter = getattr(settings, 'LATEX_INTERPRETER', DEFAULT_INTERPRETER) |
|||
latex_command = 'cd "{tempdir}" && {latex_interpreter} -interaction=batchmode {path}'.format(tempdir=tempdir, latex_interpreter=latex_interpreter, path=os.path.basename(filename)) |
|||
process = run(latex_command, shell=True, stdout=PIPE, stderr=PIPE) |
|||
try: |
|||
if process.returncode == 1: |
|||
with open(os.path.join(tempdir, 'texput.log'), encoding='utf8') as f: |
|||
log = f.read() |
|||
raise TexError(log=log, source=source) |
|||
with open(os.path.join(tempdir, 'texput.pdf'), 'rb') as pdf_file: |
|||
pdf = pdf_file.read() |
|||
except FileNotFoundError: |
|||
if process.stderr: |
|||
raise Exception(process.stderr.decode('utf-8')) |
|||
raise |
|||
return pdf |
|||
|
|||
def compile_template_to_pdf(template_name, context): |
|||
""" |
|||
Compile the source with :func:`~django_tex.core.render_template_with_context` and :func:`~django_tex.core.run_tex`. |
|||
""" |
|||
source = render_template_with_context(template_name, context) |
|||
return run_tex(source) |
|||
|
|||
def render_template_with_context(template_name, context): |
|||
""" |
|||
Render the template |
|||
""" |
|||
template = get_template(template_name, using='tex') |
|||
return template.render(context) |
@ -1,11 +0,0 @@ |
|||
|
|||
from django.template.backends.jinja2 import Jinja2 |
|||
|
|||
class TeXEngine(Jinja2): |
|||
app_dirname = 'templates' |
|||
|
|||
def __init__(self, params): |
|||
default_environment = 'django_tex.environment.environment' |
|||
if 'environment' not in params['OPTIONS'] or not params['OPTIONS']['environment']: |
|||
params['OPTIONS']['environment'] = default_environment |
|||
super().__init__(params) |
@ -1,16 +0,0 @@ |
|||
|
|||
from jinja2 import Environment |
|||
|
|||
from django.template.defaultfilters import register |
|||
|
|||
from django_tex.filters import FILTERS as tex_specific_filters |
|||
|
|||
# Django's built-in filters ... |
|||
filters = register.filters |
|||
# ... updated with tex specific filters |
|||
filters.update(tex_specific_filters) |
|||
|
|||
def environment(**options): |
|||
env = Environment(**options) |
|||
env.filters = filters |
|||
return env |
@ -1,40 +0,0 @@ |
|||
|
|||
import re |
|||
|
|||
def prettify_message(message): |
|||
''' |
|||
Helper methods that removes consecutive whitespaces and newline characters |
|||
''' |
|||
# Replace consecutive whitespaces with a single whitespace |
|||
message = re.sub(r'[ ]{2,}', ' ', message) |
|||
# Replace consecutive newline characters, optionally separated by whitespace, with a single newline |
|||
message = re.sub(r'([\r\n][ \t]*)+', '\n', message) |
|||
return message |
|||
|
|||
def tokenizer(code): |
|||
token_specification = [ |
|||
('ERROR', r'\! (?:.+[\r\n])+[\r\n]+'), |
|||
('WARNING', r'latex warning.*'), |
|||
('NOFILE', r'no file.*') |
|||
] |
|||
token_regex = '|'.join('(?P<{}>{})'.format(label, regex) for label, regex in token_specification) |
|||
for m in re.finditer(token_regex, code, re.IGNORECASE): |
|||
token_dict = dict(type=m.lastgroup, message=prettify_message(m.group())) |
|||
yield token_dict |
|||
|
|||
class TexError(Exception): |
|||
|
|||
def __init__(self, log, source): |
|||
self.log = log |
|||
self.source = source |
|||
self.tokens = list(tokenizer(self.log)) |
|||
self.message = self.get_message() |
|||
|
|||
def get_message(self): |
|||
for token in self.tokens: |
|||
if token['type'] == 'ERROR': |
|||
return token['message'] |
|||
return 'No error message found in log' |
|||
|
|||
def __str__(self): |
|||
return self.message |
@ -1,9 +0,0 @@ |
|||
from django.utils.formats import localize_input |
|||
|
|||
def do_linebreaks(value): |
|||
return value.replace('\n', '\\\\\n') |
|||
|
|||
FILTERS = { |
|||
'localize': localize_input, |
|||
'linebreaks': do_linebreaks |
|||
} |
@ -1,19 +0,0 @@ |
|||
from django.db import models |
|||
from django.core.exceptions import ValidationError |
|||
from django.template import TemplateDoesNotExist |
|||
from django.utils.translation import ugettext_lazy as _ |
|||
from django.template.loader import get_template |
|||
|
|||
def validate_template_path(name): |
|||
try: |
|||
get_template(name, using='tex') |
|||
except TemplateDoesNotExist: |
|||
raise ValidationError(_('Template not found.')) |
|||
|
|||
class TeXTemplateFile(models.Model): |
|||
|
|||
title = models.CharField(max_length=255) |
|||
name = models.CharField(max_length=255, validators=[validate_template_path,]) |
|||
|
|||
class Meta: |
|||
abstract = True |
@ -1,17 +0,0 @@ |
|||
|
|||
from django.http import HttpResponse |
|||
|
|||
from django_tex.core import compile_template_to_pdf |
|||
|
|||
class PDFResponse(HttpResponse): |
|||
|
|||
def __init__(self, content, filename=None): |
|||
super(PDFResponse, self).__init__(content_type='application/pdf') |
|||
self['Content-Disposition'] = 'filename="{}"'.format(filename) |
|||
self.write(content) |
|||
|
|||
|
|||
def render_to_pdf(request, template_name, context=None, filename=None): |
|||
# Request is not needed and only included to make the signature conform to django's render function |
|||
pdf = compile_template_to_pdf(template_name, context) |
|||
return PDFResponse(pdf, filename=filename) |
Loading…
Reference in new issue