Added TeX escaping utility functions and template filters. Removed

html escaping and added TeX escaping for relevant parts of the bibtext
template.  Fixes issue #2459.
 - Legacy-Id: 14711
This commit is contained in:
Henrik Levkowetz 2018-02-27 18:15:21 +00:00
parent 93633cd1e7
commit 0800304b67
4 changed files with 192 additions and 7 deletions

View file

@ -1,6 +1,7 @@
{% spaceless %}
{% autoescape off %}
{% load ietf_filters %}
{% load textfilters %}
{% if doc.get_state_slug == "rfc" %}
{% if doc.stream|slugify == "legacy" %}
@ -24,13 +25,14 @@
publisher = {% templatetag openbrace %}Internet Engineering Task Force{% templatetag closebrace %},
note = {% templatetag openbrace %}Work in Progress{% templatetag closebrace %},
url = {% templatetag openbrace %}https://datatracker.ietf.org/doc/html/{{doc.name}}-{{doc.rev}}{% templatetag closebrace %},{% endif %}
author = {% templatetag openbrace %}{% for author in doc.documentauthor_set.all %}{{ author.person.name}}{% if not forloop.last %} and {% endif %}{% endfor %}{% templatetag closebrace %},
title = {% templatetag openbrace %}{% templatetag openbrace %}{{doc.title}}{% templatetag closebrace %}{% templatetag closebrace %},
author = {% templatetag openbrace %}{% for author in doc.documentauthor_set.all %}{{ author.person.name|texescape}}{% if not forloop.last %} and {% endif %}{% endfor %}{% templatetag closebrace %},
title = {% templatetag openbrace %}{% templatetag openbrace %}{{doc.title|texescape}}{% templatetag closebrace %}{% templatetag closebrace %},
pagetotal = {{ doc.pages }},
year = {{ doc.pub_date.year }},
month = {{ doc.pub_date|date:"b" }},{% if not doc.rfc_number or doc.pub_date.day == 1 and doc.pub_date.month == 4 %}
day = {{ doc.pub_date.day }},{% endif %}
abstract = {% templatetag openbrace %}{{ doc.abstract|clean_whitespace }}{% templatetag closebrace %},
abstract = {% templatetag openbrace %}{{ doc.abstract|clean_whitespace|texescape }}{% templatetag closebrace %},
{% templatetag closebrace %}
{% endautoescape %}
{% endspaceless %}

View file

@ -1,11 +1,13 @@
from __future__ import unicode_literals
from django.template.library import Library
from django import template
from django.template.defaultfilters import stringfilter
from ietf.utils.text import xslugify as _xslugify
import debug # pyflakes:ignore
register = Library()
from ietf.utils.text import xslugify as _xslugify, texescape
register = template.Library()
@register.filter(is_safe=True)
@stringfilter
@ -26,3 +28,40 @@ def format(format, values):
tmp[f.name] = getattr(values, f.name)
values = tmp
return format.format(**values)
# ----------------------------------------------------------------------
# from django.utils.safestring import mark_safe
# class TeXEscapeNode(template.Node):
# """TeX escaping, rather than html escaping.
#
# Mostly, this tag is _not_ the right thing to use in a template that produces TeX
# markup, as it will escape all the markup characters, which is not what you want.
# Use the '|texescape' filter instead on text fragments where escaping is needed
# """
# def __init__(self, nodelist):
# self.nodelist = nodelist
#
# def render(self, context):
# saved_autoescape = context.autoescape
# context.autoescape = False
# text = self.nodelist.render(context)
# text = texescape(text)
# context.autoescape = saved_autoescape
# return mark_safe(text)
#
# @register.tag('texescape')
# def do_texescape(parser, token):
# args = token.contents.split()
# if len(args) != 1:
# raise TemplateSyntaxError("'texescape' tag takes no arguments.")
# nodelist = parser.parse(('endtexescape',))
# parser.delete_first_token()
# return TeXEscapeNode(nodelist)
@register.filter('texescape')
@stringfilter
def texescape_filter(value):
"A TeX escape filter"
return texescape(value)

136
ietf/utils/texescape.py Normal file
View file

@ -0,0 +1,136 @@
# -*- coding: utf-8 -*-
# Copied from https://github.com/sphinx-doc/sphinx/blob/master/sphinx/util/texescape.py
# Copyright and license as indicated in the original and below
"""
sphinx.util.texescape
~~~~~~~~~~~~~~~~~~~~~
TeX escaping helper.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from __future__ import unicode_literals
tex_replacements = [
# map TeX special chars
('$', r'\$'),
('%', r'\%'),
('&', r'\&'),
('#', r'\#'),
('_', r'\_'),
('{', r'\{'),
('}', r'\}'),
('[', r'{[}'),
(']', r'{]}'),
('`', r'{}`'),
('\\', r'\textbackslash{}'),
('~', r'\textasciitilde{}'),
('<', r'\textless{}'),
('>', r'\textgreater{}'),
('^', r'\textasciicircum{}'),
# map special Unicode characters to TeX commands
('', r'\P{}'),
('§', r'\S{}'),
('', r'\texteuro{}'),
('', r'\(\infty\)'),
('±', r'\(\pm\)'),
('', r'\(\rightarrow\)'),
('', r'\(\rightarrow\)'),
('', r'\(\checkmark\)'),
# used to separate -- in options
('', r'{}'),
# map some special Unicode characters to similar ASCII ones
('', r'\_'),
('', r'\textendash{}'),
('|', r'\textbar{}'),
('', r'e'),
('', r'i'),
('', r'\(\sp{\text{0}}\)'),
('¹', r'\(\sp{\text{1}}\)'),
('²', r'\(\sp{\text{2}}\)'),
('³', r'\(\sp{\text{3}}\)'),
('', r'\(\sp{\text{4}}\)'),
('', r'\(\sp{\text{5}}\)'),
('', r'\(\sp{\text{6}}\)'),
('', r'\(\sp{\text{7}}\)'),
('', r'\(\sp{\text{8}}\)'),
('', r'\(\sp{\text{9}}\)'),
('', r'\(\sb{\text{0}}\)'),
('', r'\(\sb{\text{1}}\)'),
('', r'\(\sb{\text{2}}\)'),
('', r'\(\sb{\text{3}}\)'),
('', r'\(\sb{\text{4}}\)'),
('', r'\(\sb{\text{5}}\)'),
('', r'\(\sb{\text{6}}\)'),
('', r'\(\sb{\text{7}}\)'),
('', r'\(\sb{\text{8}}\)'),
('', r'\(\sb{\text{9}}\)'),
# map Greek alphabet
('α', r'\(\alpha\)'),
('β', r'\(\beta\)'),
('γ', r'\(\gamma\)'),
('δ', r'\(\delta\)'),
('ε', r'\(\epsilon\)'),
('ζ', r'\(\zeta\)'),
('η', r'\(\eta\)'),
('θ', r'\(\theta\)'),
('ι', r'\(\iota\)'),
('κ', r'\(\kappa\)'),
('λ', r'\(\lambda\)'),
('μ', r'\(\mu\)'),
('ν', r'\(\nu\)'),
('ξ', r'\(\xi\)'),
('ο', r'o'),
('π', r'\(\pi\)'),
('ρ', r'\(\rho\)'),
('σ', r'\(\sigma\)'),
('τ', r'\(\tau\)'),
('υ', '\\(\\upsilon\\)'),
('φ', r'\(\phi\)'),
('χ', r'\(\chi\)'),
('ψ', r'\(\psi\)'),
('ω', r'\(\omega\)'),
('Α', r'A'),
('Β', r'B'),
('Γ', r'\(\Gamma\)'),
('Δ', r'\(\Delta\)'),
('Ε', r'E'),
('Ζ', r'Z'),
('Η', r'H'),
('Θ', r'\(\Theta\)'),
('Ι', r'I'),
('Κ', r'K'),
('Λ', r'\(\Lambda\)'),
('Μ', r'M'),
('Ν', r'N'),
('Ξ', r'\(\Xi\)'),
('Ο', r'O'),
('Π', r'\(\Pi\)'),
('Ρ', r'P'),
('Σ', r'\(\Sigma\)'),
('Τ', r'T'),
('Υ', '\\(\\Upsilon\\)'),
('Φ', r'\(\Phi\)'),
('Χ', r'X'),
('Ψ', r'\(\Psi\)'),
('Ω', r'\(\Omega\)'),
('', r'\(\Omega\)'),
]
tex_escape_map = {}
tex_replace_map = {}
tex_hl_escape_map_new = {}
def init():
# type: () -> None
for a, b in tex_replacements:
tex_escape_map[ord(a)] = b
tex_replace_map[ord(a)] = '_'
for a, b in tex_replacements:
if a in '[]{}\\':
continue
tex_hl_escape_map_new[ord(a)] = b

View file

@ -11,6 +11,8 @@ from django.utils.safestring import mark_safe
import debug # pyflakes:ignore
from texescape import init as texescape_init, tex_escape_map
@keep_lazy(six.text_type)
def xslugify(value):
"""
@ -174,3 +176,9 @@ def dict_to_text(d):
for k, v in d.items():
t += "%s: %s\n" % (k, v)
return t
def texescape(s):
if not tex_escape_map:
texescape_init()
t = s.translate(tex_escape_map)
return t