Source code for quill.importer.xournal

"""
Import Xournal notebook

EXAMPLES::

    >>> from quill.importer.xournal import Xournal
    >>> x = Xournal(xournal_file)
    >>> print x    # doctest: +ELLIPSIS
    <quill.importer.xournal.Xournal object at 0x...>
    >>> book = x.get_book()
    >>> book.title()
    'Xournal document - see http://math.mit.edu/~auroux/software/xournal/'
    >>> book.get_page(0)
    page number 0
"""

import gzip
import math

try:
    import xml.etree.cElementTree as ET
except ImportError:
    import xml.etree.ElementTree as ET


from quill.importer.base import ImporterBase, QuillImporterError
from quill.book import Book
from quill.page import Page
from quill.stroke import Stroke
from quill.line import Line
from quill.image import Image




[docs]class Xournal(ImporterBase): def __init__(self, xournal_filename): self._filename = xournal_filename f = gzip.open(xournal_filename, 'rb') self._tree = ET.ElementTree(file=f) self._pages = [ page for page in self._tree.iter(tag='page') ]
[docs] def title(self): return self._tree.find('title').text
[docs] def n_pages(self): return len(self._pages) #### From the xournal sources #const char *color_names[COLOR_MAX] = {"black", "blue", "red", "green", # "gray", "lightblue", "lightgreen", "magenta", "orange", "yellow", "white"}; #guint predef_colors_rgba[COLOR_MAX] = # { 0x000000ff, 0x3333ccff, 0xff0000ff, 0x008000ff, # 0x808080ff, 0x00c0ffff, 0x00ff00ff, 0xff00ffff, # 0xff8000ff, 0xffff00ff, 0xffffffff };
xournal_pen_thickness_factor = 0.5 xournal_page_scale_factor = 820.0 xournal_color_constants = { 'black': (0x0, 0x0, 0x0), 'blue': (0x33, 0x33, 0xcc), 'red': (0xff, 0x00, 0x0), 'green': (0x00, 0x80, 0x0), 'gray': (0x80, 0x80, 0x80), 'lightblue': (0x0, 0xc0, 0xff), 'lightgreen': (0x0, 0xff, 0x00), 'magenta': (0xff, 0x0, 0xff), 'orange': (0xff, 0x80, 0x0), 'yellow': (0xff, 0xff, 0x0), 'white': (0xff, 0xff, 0xff) } def _parse_color(self, color): try: return self.xournal_color_constants[color] except KeyError: red = int(color[1:3], 16) green = int(color[3:5], 16) blue = int(color[5:7], 16) return (red, green, blue) def _parse_width(self, width): width = [ float(w) / self.xournal_pen_thickness_factor for w in width.split() ] max_width = max(width) if max_width > 12: max_width = 40 elif max_width > 5: max_width = 12 elif max_width > 2: max_width = 5 elif max_width > 1: max_width = 2 else: max_width = 1 pressure = [ w/max_width for w in width ] return max_width, pressure def _parse_stroke(self, stroke): red, green, blue = self._parse_color(stroke.attrib['color']) thickness, pressure = self._parse_width(stroke.attrib['width']) xy = [ float(data) / self.xournal_page_scale_factor for data in stroke.text.split() ] fountain_pen = (len(pressure) > 1) if not fountain_pen and len(xy)==4: return Line(thickness, red, green, blue, xy[0], xy[1], xy[2], xy[3]) if fountain_pen: points = zip(xy[::2], xy[1::2], pressure) else: points = zip(xy[::2], xy[1::2], [1.0]*(len(xy)/2)) return Stroke(fountain_pen, thickness, red, green, blue, points)
[docs] def get_page(self, n): xoj_page = self._pages[n] strokes = [] lines = [] for xoj_stroke in xoj_page.iter('stroke'): stroke = self._parse_stroke(xoj_stroke) if isinstance(stroke, Stroke): strokes.append(stroke) if isinstance(stroke, Line): lines.append(stroke) images = [] aspect_ratio_A4 = 1.0/math.sqrt(2) return Page(n, self.uuid(), aspect_ratio_A4, strokes, lines, images)