pyltk/pyltk/element.py

129 lines
3.9 KiB
Python

# -*- encoding: utf-8 -*-
from .formatter import formatter
from collections import Iterable
class element:
""" Class representing a latex element.
An element is a latex element (e.g. \\figure), with a parent and some
childrens. An element can have no parent and 0 childrens.
By default, all childrens of an element must be instances of element
themselves. To avoid this behavior, `raw` element can be used. `raw`
elements do not wrap their children in `wrapper_element` when they
are no subclasses of `element`. """
# Joiner for childrens
sep = "\n"
# Automatically add label after element if present
autolabel = True
# Do not wrap non-element in wrapper_element
raw = False
def __init__(self, parent=None, childrens=[], label=None, raw=False, **kargs):
""" Create a new element with given parameters.
Parameters:
- parent Parent of the element (another element).
- childrens Childrens of the element - Single element or list of
objects (element or not).
- label Label of the element.
- raw Raw childrens (see description of `element`).
- kargs Options for the element. """
self.parent = parent
self.raw = raw
if childrens is None:
childrens = []
if not isinstance(childrens, Iterable):
childrens = [childrens]
self.childrens = []
self.add(childrens)
self.label = label
self.options = kargs
def add(self, childrens):
if not isinstance(childrens, Iterable) or isinstance(childrens, str):
childrens = [childrens]
for child in childrens:
if not self.raw:
if not isinstance(child, element):
child = wrapper_element(child, self)
try:
child.parent.remove(child)
except:
pass
child.parent = self
self.childrens.append(child)
def content(self):
return self.sep.join(map(str, self.childrens))
def fmt(self):
return formatter(self.templates)
def format_options_dict(self, options):
opts = []
# Note: Sorted to have a guaranteed output
for k in sorted(options):
value = options[k]
if value is True:
opts.append(k)
else:
if isinstance(value, dict):
value = self.format_options_dict(value)
elif isinstance(value, list) or isinstance(value, tuple):
value = ",".join(value)
else:
value = str(value).strip()
if value[0] == "{" and value[1] == "}":
value = value[1:-1]
opts.append("{key}={{{value}}}".format(key=k, value=value))
return ", ".join(opts)
def format_options(self, options):
if not options:
return ""
return self.fmt().format(
"options", {"content": self.format_options_dict(options)}
)
def format_label(self, label):
if not label:
return ""
return "\\label{{{}}}".format(label)
def __str__(self):
out = self.content().strip()
if self.autolabel:
out += self.format_label(self.label)
return out
class wrapper_element(element):
""" Wrapper for standard python types working as latex elements. """
escape_list = ["_", "#", "%"]
def __init__(self, data, parent=None, autoescape=True):
super().__init__(parent=parent)
self.autoescape = autoescape
self.data = data
def escape(self, s):
if not self.autoescape:
return s
for e in self.escape_list:
s = s.replace(e, "\\" + e)
return s
def content(self):
return self.escape(str(self.data))