ODF visualization using WebKit

2010-06-23

Today is day 1 of of the OdfKit Hack Week. We wrote a list of things we want to achieve this week. In order to avoid embarrassment, we'll spare you the details and go straight through to an explanation of how you can use WebKit (or any modern browser) to visualize ODF documents. The general idea is to incorporate the ODF XML into a live HTML document.

Step 0: load content and styles into an HTML document

ODF files come in two flavors: single XML files and XML files in ZIP containers. Most people use the ZIP form exclusively. In both cases there are two XML elements of importance: <document-content/> and <document-styles/>. These are comparable to HTML and CSS respectively. We'll avoid the details of how we load these elements into the DOM tree for now and simply state that we have two javascript variables:

var documentcontents;
var documentstyles;

Step 1: put the document contents in the web page.

Let's start from a simple HTML document with a <div/> element where the ODF element <document-content/> can be imported.

<html>
 <head><title>My ODF Document</title></head>
 <body>
  <div id='contentxml'></div>
 </body>
</html>

The importing can be done like this:

documentcontents = document.importNode(documentcontents, true); // deep import
var div = document.getElementById('contentxml');
div.appendChild(documentcontents);

The result is that the DOM tree has now mixed namespaces: elements from the ODF namespaces are imported into the HTML namespace. HTML viewers display the text inside the foreign elements even though there are no rules for rendering the foreign elements.

Step 2: adding document styles

Even though the added elements are in a foreign namespace, it is still possible to use CSS to give them styles. This is possible by using namespaces in CSS:

<style type="text/css">
  @namespace text url(urn:oasis:names:tc:opendocument:xmlns:text:1.0);
  @namespace table url(urn:oasis:names:tc:opendocument:xmlns:table:1.0);
  text|p, text|h { // define ODF paragraphs and headers as block elements
    display: block;
  }
  text|list { // reset the list numbering for each list
    counter-reset: list-num;
  }
  text|list-item {
    display: block;
  }
  text|list-item:before { // prefix each list-item with a roman numeral
    content: counter(par-num, upper-roman) ". ";
  }
  table|table-row { // style ODF table rows as table rows
    display: table-row;
  }
  table|table-cell { // style ODF table cells as cells
    display: table-cell;
  }
</style>

This simple CSS example already improves the visualization of the ODF elements a lot. It is, however, very general. There are only general ODF styles, but no user-defined styles. No panic! CSS selectors are flexible to allow these too. Here is an example of specific ODF style ported to CSS. The original ODF

<style:style style:name="MyItalicStyle" style:family="text">
  <style:text-properties fo:font-style="italic" />
</style>

becomes

<style type="text/css">
  @namespace text url(urn:oasis:names:tc:opendocument:xmlns:text:1.0);
  text|p[text|style-name="MyItalicStyle"] {
    font-style: italic;
  }
</style>

So you see that it is possible to display ODF documents in a web browser or web widget. There is a demo with a more elaborate visualization at our demo page.

Comments

Post a comment