Skip to content

Commit

Permalink
ODT compiler plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
ralsina committed Jun 11, 2015
1 parent 26faadd commit 9552c90
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 0 deletions.
4 changes: 4 additions & 0 deletions v7/odt/README.md
@@ -0,0 +1,4 @@
Compiler plugin to support the ODT format used by LibreOffice and OpenOffice.



7 changes: 7 additions & 0 deletions v7/odt/conf.py.sample
@@ -0,0 +1,7 @@
# Add the odt compiler to your COMPILERS dict.
COMPILERS["odt"] = ('.odt',)

# Add odt files to your POSTS, PAGES
POSTS = POSTS + (("posts/*.odt", "posts", "post.tmpl"),)
PAGES = PAGES + (("stories/*.odt", "posts", "post.tmpl"),)

Binary file added v7/odt/empty.odt
Binary file not shown.
12 changes: 12 additions & 0 deletions v7/odt/odt.plugin
@@ -0,0 +1,12 @@
[Core]
Name = odt
Module = odt

[Nikola]
MinVersion = 7.0.0

[Documentation]
Author = Roberto Alsina
Version = 0.1
Website = http://plugins.getnikola.com#odf
Description = Compile ODT files into HTML
87 changes: 87 additions & 0 deletions v7/odt/odt.py
@@ -0,0 +1,87 @@
# -*- coding: utf-8 -*-

# Copyright © 2015 Roberto Alsina and others.

# 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.

"""Implementation of compile_html based on odfpy.
You will need, of course, to install odfpy
"""

import os
import subprocess
import shutil

import lxml.etree as etree

from nikola.plugin_categories import PageCompiler
from nikola.utils import makedirs, req_missing

try:
from collections import OrderedDict
except ImportError:
OrderedDict = dict # NOQA


class CompileODT(PageCompiler):
"""Compile ODT into HTML."""

name = "odt"

def compile_html(self, source, dest, is_two_file=True):
makedirs(os.path.dirname(dest))
binary = 'odf2xhtml'
try:
data = subprocess.check_output((binary, source))

This comment has been minimized.

Copy link
@Kwpolska

Kwpolska Jun 11, 2015

Member

can’t you access this odfpy feature programmatically?

This comment has been minimized.

Copy link
@ralsina

ralsina Jun 11, 2015

Author Member

probably but why?

This comment has been minimized.

Copy link
@Kwpolska

Kwpolska Jun 11, 2015

Member

I don’t trust calling out to processes, especially if we’re likely to be dealing with Unicode.

This comment has been minimized.

Copy link
@ralsina

ralsina Jun 11, 2015

Author Member

I had 55 minutes (lunch) to implement this, while eating a sandwich. This is as far as I got ;-)

This comment has been minimized.

Copy link
@ralsina

ralsina Jun 11, 2015

Author Member

Looking at odf2xhtml it looks crazy simple, though.

This comment has been minimized.

Copy link
@Kwpolska

Kwpolska Jun 11, 2015

Member

I’ll fix it now.

This comment has been minimized.

Copy link
@Kwpolska

Kwpolska Jun 11, 2015

Member

done in f9f80a5


# Take the CSS from the head and put it in body
doc = etree.fromstring(data)
body = doc.find('{http://www.w3.org/1999/xhtml}body')

for style in doc.findall('*//{http://www.w3.org/1999/xhtml}style'):
style.getparent().remove(style)

# keep only classes:
filtered = []
for line in style.text.splitlines():
if line and line[0] in '.\t}':
filtered.append(line)
style.text = ''.join(filtered)

body.insert(0, style)

with open(dest, 'wb+') as outf:
outf.write(etree.tostring(body, encoding='unicode'))
except OSError as e:
if e.strreror == 'No such file or directory':
req_missing(['odfpy'], 'build this site (compile with odt)', python=False)

def create_post(self, path, **kw):
onefile = kw.pop('onefile', False)
# is_page is not used by create_post as of now.
kw.pop('is_page', False)
if onefile:
raise Exception('The one-file format is not supported by this compiler.')
shutil.copyfile(os.path.join(os.path.dirname(__file__), 'empty.odt'), path)
1 change: 1 addition & 0 deletions v7/odt/requirements.txt
@@ -0,0 +1 @@
odfpy

1 comment on commit 9552c90

@Kwpolska
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WOAH.

Please sign in to comment.