ODF is “an open XML-based document file format for office applications
to be used for documents containing text, spreadsheets, charts, and graphical
elements,” developed under the auspices of OASIS.[281][282]http://www.openoffice.org/
) and KOffice (http://www.koffice.org/
), among other office suites. For a good
overview of the file format, consult J. David Eisenberg’s excellent book on ODF,
called OASIS OpenDocument Essentials, which is available for download
as a PDF (free of charge) or for purchase.[283]
The goal of this section is to introduce you to the issues of parsing and creating ODF files programmatically.
Note | |
---|---|
For this section, I am assuming you have OpenOffice.org version 2.2 installed. |
A good way to understand the essentials of the file format is to create a simple instance of an ODF file and then analyze it:
Fire up OpenOffice.org Writer, type Hello World,
and save the file as helloworld.odt
.[284]
Open the file in a ZIP utility (such as WinZip on the PC). One easy way to do so
is to change the file extension from .odt
to .zip
so that
the operating system will recognize it as a ZIP file. You will see that it’s
actually a ZIP-format file when you go to unzip it. (See the list of
files in Figure 17-1.)
Figure 17.1. Figure 17-1. Unzipping helloworld.zip. An OpenDocument file produced by OpenOffice.org is actually in the ZIP format.
You’ll see some of the files that can be part of an ODF file:
content.xml
styles.xml
meta.xml
settings.xml
META-INF/manifest.xml
mimetype
Configuration2/accelerator/
Thumbnails/thumbnail.png
You can also use your favorite programming language, such as Python or PHP, to generate a list of the files. The following is a Python example:
import zipfile z = zipfile.ZipFile(r'[path_to_your_file_here]') z.printdir()
This generates the following:
File Name Modified Size mimetype 2007-06-02 16:10:18 39 Configurations2/statusbar/ 2007-06-02 16:10:18 0 Configurations2/accelerator/current.xml 2007-06-02 16:10:18 0 Configurations2/floater/ 2007-06-02 16:10:18 0 Configurations2/popupmenu/ 2007-06-02 16:10:18 0 Configurations2/progressbar/ 2007-06-02 16:10:18 0 Configurations2/menubar/ 2007-06-02 16:10:18 0 Configurations2/toolbar/ 2007-06-02 16:10:18 0 Configurations2/images/Bitmaps/ 2007-06-02 16:10:18 0 content.xml 2007-06-02 16:10:18 2776 styles.xml 2007-06-02 16:10:18 8492 meta.xml 2007-06-02 16:10:18 1143 Thumbnails/thumbnail.png 2007-06-02 16:10:18 945 settings.xml 2007-06-02 16:10:18 7476 META-INF/manifest.xml 2007-06-02 16:10:18 1866
You can get the equivalent functionality in PHP with the PHP zip
library
(see http://us2.php.net/zip
):
<?php $zip = zip_open('[path_to_your_file]'); while ($entry = zip_read($zip)) { print zip_entry_name($entry) . "\t". zip_entry_filesize($entry). "\n"; } zip_close($zip); ?>
This produces the following:
mimetype 39 Configurations2/statusbar/ 0 Configurations2/accelerator/current.xml 0 Configurations2/floater/ 0 Configurations2/popupmenu/ 0 Configurations2/progressbar/ 0 Configurations2/menubar/ 0 Configurations2/toolbar/ 0 Configurations2/images/Bitmaps/ 0 content.xml 2776 styles.xml 8492 meta.xml 1143 Thumbnails/thumbnail.png 945 settings.xml 7476 META-INF/manifest.xml 1866
Generating a simple ODF file using OpenOffice.org gives you a basic file from which you can build. However, it’s useful to boil the file down even further because even the simple ODF generated by OO.o contains features that make it difficult to see what’s happening. Let’s pare down the “Hello World” ODF document further.
There are at least two ways to figure out a minimalist instance of an ODF document. One
is to consult the ODF specification, specifically the ODF schema, to generate a small
instance. OO.o 2.2 uses the ODF 1.0 specification.[285]http://relaxng.org/
) is a schema language for XML. That is, you can
use RELAX NG to specify what elements and attributes can be used in ODF—and in what
combination.
Schemas, stemming from the http://oasis-open.org
page, include the following:
The schema for office documents, “extracted from chapter 1 to 16 of the specification” —Version 1.0[286]
“The normative schema for the manifest file used by the OpenDocument package format” —Version 1.0[287]
“The strict schema for office documents that permits only meta information and formatting properties contained in this specification itself” —Version 1.0[288]
Instead of taking this approach here, I will instead show you how to use OO.o and the
online ODF Validator (http://opendocumentfellowship.com/validator
). The basic approach is to
use a bit of trial and error to generate an ODF file and add pieces while feeding it to the
ODF Validator to see how far you can distill the file. Why should you care about minimal
instances of ODF (and later OOXML) documents? ODF and OOXML are complicated markup formats.
One of the best ways to figure out how to create formats is to use a tool such as OO.o or
Microsoft Office to generate what you want, save the file, unzip the file, extract the
section of the document you want, and plug that stuff into a minimalist document that you
know is valid. That’s why you’re learning about boiling ODF down to its
essence.
The ODF specification (and its RELAX NG schema) should tell you theoretically how to find a valid ODF instance—but in practice, you need to actually feed a given instance to the applications that are the destinations for the ODF documents. OpenOffice.org is currently the most important implementation of an office suite that interprets ODF, making it a good place to experiment.
J. David Eisenberg’s excellent book on ODF, OASIS OpenDocument Essentials, provides an answer to the question of which files are actually required by OO.o:
The only files that are actually necessary are content.xml and the META-INF/manifest.xml file. If you create a file that contains word processor elements and zip it up and a manifest that points to that file, OpenOffice.org will be able to open it successfully. The result will be a plain text-only document with no styles. You won’t have any of the meta-information about who created the file or when it was last edited, and the printer settings, view area, and zoom factor will be set to the OpenOffice.org defaults.
Let’s verify Eisenberg’s assertion. Create an .odt
file with
the same content.xml
as hel
loworld.odt
, listed here:
<?xml version="1.0" encoding="UTF-8"?> <office:document-content xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" office:version="1.0"> <office:scripts/> <office:font-face-decls> <style:font-face style:name="Tahoma1" svg:font-family="Tahoma"/> <style:font-face style:name="Times New Roman" svg:font-family="'Times New Roman'" style:font-family-generic="roman" style:font-pitch="variable"/> <style:font-face style:name="Arial" svg:font-family="Arial" style:font-family-generic="swiss" style:font-pitch="variable"/> <style:font-face style:name="Arial Unicode MS" svg:font-family="'Arial Unicode MS'" style:font-family-generic="system" style:font-pitch="variable"/> <style:font-face style:name="MS Mincho" svg:font-family="'MS Mincho'" style:font-family-generic="system" style:font-pitch="variable"/> <style:font-face style:name="Tahoma" svg:font-family="Tahoma" style:font-family-generic="system" style:font-pitch="variable"/> </office:font-face-decls> <office:automatic-styles/> <office:body> <office:text> <office:forms form:automatic-focus="false" form:apply-design-mode="false"/> <text:sequence-decls> <text:sequence-decl text:display-outline-level="0" text:name="Illustration"/> <text:sequence-decl text:display-outline-level="0" text:name="Table"/> <text:sequence-decl text:display-outline-level="0" text:name="Text"/> <text:sequence-decl text:display-outline-level="0" text:name="Drawing"/> </text:sequence-decls> <text:p text:style-name="Standard">Hello World!</text:p> </office:text> </office:body> </office:document-content>
Now edit META-INF/metadata.xml
to reference only content.xml
and the META-INF
directory:
<?xml version="1.0" encoding="UTF-8"?> <manifest:manifest xmlns:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0"> <manifest:file-entry manifest:media-type="application/vnd.oasis.opendocument.text" manifest:full-path="/"/> <manifest:file-entry manifest:media-type="text/xml" manifest:full-path="content.xml"/> </manifest:manifest>
This leaves you with an .odt
file that consists of only those two files.[289][290]content.xml
and META-INF/manifest.xml
.
Nonetheless, the OpenDocument Validator doesn’t find the file to be valid; it produces the following error message:
1. warning does not contain a /mimetype file. This is a SHOULD in OpenDocument 1.0 2. error styles.xml is missing 3. error settings.xml is missing 4. error meta.xml is missing
Since the OpenDocument Validator dies on one of the Fellowship’s test files,[293]
If you insert skeletal styles.xml
, settings.xml
, and
meta.xml
files, you can convince the OpenDocument Validator to accept the
resulting .odt
file as a valid document. Furthermore, you can strip
content.xml
of extraneous declarations. (Strictly speaking, the namespace
declarations are extraneous, but they are useful to have once you start plugging in chunks
of ODF.) The resulting ODF text document is what you find here:
http://examples.mashupguide.net/ch17/helloworld_min_odt_2.odt
Here are the constituent files:
<!-- meta.xml --> <?xml version="1.0" ?> <office:document-meta office:version="1.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:xlink="http://www.w3.org/1999/xlink"/> <!-- settings.xml --> <?xml version="1.0" ?> <office:document-settings office:version="1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:xlink="http://www.w3.org/1999/xlink" /> <!-- styles.xml --> <?xml version="1.0" ?> <office:document-styles office:version="1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" /> <!-- content.xml --> <?xml version="1.0" ?> <office:document-content office:version="1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <office:body> <office:text> <text:p> Hello World! </text:p> </office:text> </office:body> </office:document-content> <!-- manifest.xml --> <?xml version="1.0" encoding="UTF-8"?> <manifest:manifest xmlns:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0"> <manifest:file-entry manifest:media-type="application/vnd.oasis.opendocument.text" manifest:full-path="/"/> <manifest:file-entry manifest:media-type="text/xml" manifest:full-path="content.xml"/> <manifest:file-entry manifest:media-type="text/xml" manifest:full-path="meta.xml"/> <manifest:file-entry manifest:media-type="text/xml" manifest:full-path="settings.xml"/> <manifest:file-entry manifest:media-type="text/xml" manifest:full-path="styles.xml"/> </manifest:manifest>
You now have a minimalist and valid ODF document.
As an exercise to the reader, I’ll leave it to you to generate minimal instances
of the spreadsheet (.ods
), presentation (.odp
), graphics
(.odg
), and math (.odf
) documents. In the rest of the chapter,
I’ll continue to focus on the text documents (.odt
)—but what you
learn from it applies to the other ODF formats as well.
With a minimalist ODF text document in hand, let’s look at how to generate a small example document that illustrates some of the basic features of ODF. Here we can consult Eisenberg once again on how to proceed:
Just start OpenOffice.org or KOffice, create a document that has the feature you want, unpack the file, and look for the XML that implements it. To get a better understanding of how things works, change the XML, repack the document, and reload it. Once you know how a feature works, don’t hesitate to copy and paste the XML from the OpenDocument file into your program. In other words, cheat. It worked for me when I was writing this book, and it can work for you too!
In this section, I’ll walk you through how to create the ODF text document (see Figure 17-2) in steps here:
http://examples.mashupguide.net/ch17/odt_example_4.odt
You can study the parts of this document by downloading and unzipping it or by looking at the files here:
http://examples.mashupguide.net/ch17/odt_example_4/
I will show you how I took the approach advocated by Eisenberg to construct this document. I added a new element in an ODT, unzipped the file, found the corresponding XML fragment, took that fragment, and added it to the document I was building. I consciously stripped out any references to styles to focus first on content. And then I applied styles to achieve the effects I want. I will leave it to you to take this approach on spreadsheets and presentations; the ODF for those files formats have a similar framework as the text documents.
This example text contains some common elements:
Headings of level 1 and 2
Several paragraphs
An ordered and unordered list
Text that has some italics and bold and a font change
A table
An image
I’ll show how to build this document in four steps to highlight what’s involved in constructing a nontrivial ODF document:
Create an ODF text document without any styling of ODF elements.
Set the style of the paragraph text.
Format lists to distinguish between ordered and unordered lists.
Get bold, italics, font changes, and color changes into text spans.
The first step is to create a document while purposefully eliminating any use of styling. This will let us focus on content-oriented tags, much like studying HTML first without CSS and then applying CSS. When studying ODF (and later Office Open XML), it’s useful to keep in mind analogous constructs from HTML and CSS.
When you create an ODF text document with headers, paragraphs, lists, and the other features listed earlier and strip out the style, you get something like this:
http://examples.mashupguide.net/ch17/odt_example_1.odt
whose constituent files (once you unzip the document) are here:
http://examples.mashupguide.net/ch17/odt_example_1/
Not surprisingly, most of the action is in content.xml
:
http://examples.mashupguide.net/ch17/odt_example_1/content.xml
Remember the overall structure of content.xml
, a framework in which you
can plug in the ODF tags representing various elements:
<?xml version="1.0" ?> <!-- the namespace declarations of office:document-content are omitted --> <office:document-content> <office:body> <office:text> [INSERT CONTENT HERE] </office:text> </office:body> </office:document-content>
There are headers and paragraphs as in HTML—but in HTML, you have h1, h2, .
. . , h6. With ODF, you use <text:h>
with
text:outline-level
to indicate the level of the header. For
paragraphs in ODF, you use the <text:p>
element. Note the
text:
namespace:
urn:oasis:names:tc:opendocument:xmlns:text:1.0
Here’s some ODF you can plug in to create two headers (one of level 1 and the other of level 2) along with a series of paragraphs:
<text:h text:outline-level="1">Purpose (Heading 1)</text:h> <text:p>The following sections illustrate various possibilities in ODF Text. </text:p> <text:h text:outline-level="2">A simple series of paragraphs (Heading 2)</text:h> <text:p>This section contains a series of paragraphs.</text:p> <text:p>This is a second paragraph.</text:p> <text:p>And a third paragraph.</text:p>
The following ODF markup creates two lists. The first one will ultimately be an
unordered one, and the second one will be an ordered one. Unlike HTML in which you
would use <ul>
and <ol>
, with ODF you get
across the difference between an ordered and unordered list through styling alone,
which we’ll do in a moment. In the meantime, let’s set up the two lists
using <text:list>
and <text:list-item>
:
<text:h text:outline-level="2">A section with lists (Heading 2)</text:h> <text:p>Elements to illustrate:</text:p> <text:list> <text:list-item> <text:p>hyperlinks</text:p> </text:list-item> <text:list-item> <text:p>italics and bold text</text:p> </text:list-item> <text:list-item> <text:p>lists (ordered and unordered)</text:p> </text:list-item> </text:list> <text:p>How to figure out ODF</text:p> <text:list> <text:list-item> <text:p>work out the content.xml tags</text:p> </text:list-item> <text:list-item> <text:p>work styles into the mix</text:p> </text:list-item> <text:list-item> <text:p>figure out how to apply what we learned to spreadsheets and presentations</text:p> </text:list-item> </text:list>
The following markup constructs a paragraph with embedded hyperlinks, indicated by
<text:a>
elements. You also want to eventually mark certain
text areas as italics (“URL”), as bold (“API page”), and as
Arial and red in color (“Flickr”). It turns out that doing so requires
styling, which we’ll do later. Here we partition out the regions to which
styles can then be applied with <text:span>
—akin to an HTML
span.
<text:p>The <text:span>URL</text:span> for Flickr is <text:a xlink:type="simple" xlink:href="http://www.flickr.com/"> http://www.flickr.com </text:a>. <text:s/>The <text:span>API page</text:span> is <text:a xlink:type="simple" xlink:href="http://www.flickr.com/services/api/"> http://www.flickr.com/services/api/ </text:a> </text:p>
The following markup creates a table with three columns and three rows. Note the
use of <table:table>
, <table:table-row>
, and
<table:table-cell>
where the table namespace is
urn:oasis:names:tc:opendocument:xmlns:table:1.0
:
<text:h text:outline-level="1"> A Table (Heading 1)</text:h> <table:table table:name="Table1"> <table:table-column table:number-columns-repeated="3"/> <table:table-row> <table:table-cell office:value-type="string"> <text:p>Website</text:p> </table:table-cell> <table:table-cell office:value-type="string"> <text:p>Description</text:p> </table:table-cell> <table:table-cell office:value-type="string"> <text:p>URL</text:p> </table:table-cell> </table:table-row> <table:table-row> <table:table-cell office:value-type="string"> <text:p>Flickr</text:p> </table:table-cell> <table:table-cell office:value-type="string"> <text:p>A social photo sharing site</text:p> </table:table-cell> <table:table-cell office:value-type="string"> <text:p> <text:a xlink:type="simple" xlink:href="http://www.flickr.com/" >http://www.flickr.com</text:a> </text:p> </table:table-cell> </table:table-row> <table:table-row> <table:table-cell office:value-type="string"> <text:p>Google Maps</text:p> </table:table-cell> <table:table-cell office:value-type="string"> <text:p>An online map</text:p> </table:table-cell> <table:table-cell office:value-type="string"> <text:p> <text:a xlink:type="simple" xlink:href="http://maps.google.com/" >http://maps.google.com</text:a> </text:p> </table:table-cell> </table:table-row> </table:table>
The following ODF shows how to embed a footnote through a
<text:note>
element, which contains
<text:note-citation>
, <text:note-body>
, and
<text:note>
elements:
<text:h text:outline-level="1">Footnotes (Heading 1)</text:h> <text:p>This sentence has an accompanying footnote.<text:note text:id="ftn0" text:note-class="footnote"> <text:note-citation>1</text:note-citation> <text:note-body> <text:p text:style-name="Footnote">You are reading a footnote.</text:p> </text:note-body> </text:note> <text:s text:c="2"/>Where does the text after a footnote go? </text:p>
The markup in this section embeds an image that I have shown before:
http://flickr.com/photos/raymondyee/18389540/
specifically the original size:
http://farm1.static.flickr.com/12/18389540_e37cc4d464_o.jpg
You download the image, rename it to campanile_fog.jpg
, and insert it
into the Pictures
subdirectory of the ODF structure. (Remember that when
you unzip an ODF text document, you can often find a Pictures
subdirectory. That’s where embedded images get placed.) Here’s what you
have to include in content.xml
:
<text:h text:outline-level="1">An Image</text:h> <text:p> <draw:frame draw:name="graphics1" text:anchor-type="paragraph" svg:width="5in" svg:height="6.6665in" draw:z-index="0"> <draw:image xlink:href="Pictures/campanile_fog.jpg" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/> </draw:frame> </text:p>
Note that you need to add the photo to the list of files in
META-INF/manifest.xml
(which keeps track of the files that are zipped
up in an ODF text document). See the specific changes:[294]
<manifest:file-entry manifest:media-type="image/jpeg" manifest:full-path="Pictures/campanile_fog.jpg"/> <manifest:file-entry manifest:media-type="" manifest:full-path="Pictures/"/>
Now that you have the content elements of the ODF text document in place, you can turn to applying styles. In this section, you’ll focus first on styling the paragraphs. The default style for paragraphs in OpenOffice.org make it hard to tell when the paragraphs start and end. Let’s apply the Text body style from OO.o to some paragraphs. You can do so in two steps: first define the relevant styles, and then apply the new styles to the relevant paragraphs.
To define the styles, you insert the following definition in styles.xml
:[295]
<?xml version="1.0" ?> <!-- the namespace declarations of office:document-styles are omitted --> <office:document-styles office:version="1.0"> <office:styles> <style:style style:name="Standard" style:family="paragraph" style:class="text"/> <style:style style:name="Text_20_body" style:display-name="Text body" style:family="paragraph" style:parent-style-name="Standard" style:class="text"> <style:paragraph-properties fo:margin-top="0in" fo:margin-bottom="0.0835in"/> </style:style> </office:styles> </office:document-styles>
Then you use text:style-name
attribute to associate this style with a
<text:p>
in content.xml
to the relevant paragraphs.
For example:[296]
<text:p text:style-name="Text_20_body">The following sections illustrate various possibilities in ODF Text.</text:p>
You can see the resulting ODF text file here:
http://examples.mashupguide.net/ch17/odt_example_2.odt
whose constituent files are here:
Let’s now style the two lists. Recall that you couldn’t make the first
list unordered and the second ordered without using styling. Let’s now do so by
using <style:style>
again—but this time embedded in an
<office:automat-styles>
element in
content.xml
.
<?xml version="1.0" ?> <!-- the namespace declarations of office:document-content are omitted <office:document-content> <office:automatic-styles> [INSERT ?automatic-?styles here] </office:automatic-styles> <office:body> <office:text> [...] </office:text> </office:body> </office:document-content>
specifically:
<office:automatic-styles> <style:style style:name="P1" style:family="paragraph" style:parent-style-name="Standard" style:list-style-name="L1"/> <style:style style:name="P6" style:family="paragraph" style:parent-style-name="Standard" style:list-style-name="L5"/> <text:list-style style:name="L1"> <text:list-level-style-bullet text:level="1" text:style-name="Numbering_20_Symbols" style:num-suffix="." text:bullet-char="•"> <style:list-level-properties text:space-before="0.25in" text:min-label-width="0.25in"/> <style:text-properties style:font-name="StarSymbol"/> </text:list-level-style-bullet> [....] </text:list-style> <text:list-style style:name="L5"> <text:list-level-style-number text:level="1" text:style-name="Numbering_20_Symbols" style:num-suffix="." style:num-format="1"> <style:list-level-properties text:space-before="0.25in" text:min-label-width="0.25in"/> </text:list-level-style-number> [....] </text:list-style> </office:automatic-styles>
Note that the styling for levels beyond level 1 are deleted in this excerpt.
Once these styles are defined, you then use text:style-name
attributes
to associate the L1/ P1 and L5/P6 styles to the unordered and ordered lists,
respectively:
<text:p>Elements to illustrate:</text:p> <text:list text:style-name="L1"> <text:list-item> <text:p text:style-name="P1">hyperlinks</text:p> </text:list-item> <text:list-item> <text:p text:style-name="P1">italics and bold text</text:p> </text:list-item> <text:list-item> <text:p text:style-name="P1">lists (ordered and unordered)</text:p> </text:list-item> </text:list> <text:p>How to figure out ODF</text:p> <text:list text:style-name="L5"> <text:list-item> <text:p text:style-name="P6">work out the content.xml tags</text:p> </text:list-item> <text:list-item> <text:p text:style-name="P6">work styles into the mix</text:p> </text:list-item>
The final changes to make are to define and apply the relevant styles to introduce a
number of text effects (bold, italics, font changes, and color changes). Remember that
you have the <text:span>
in place already in content.xml
. In content.xml
, you need to do the following:
Add an <office:font-face-decls>
element containing a
<style:font-face>
that declares an Arial style.
Create <style:style>
elements named T1, T2, T5,
respectively, to express the styles of the three <text:span>
elements to which you are applying styling.
Associate the T1, T2, and T5 styles with the <text:span>
elements using text:style-name
attributes.
Concretely, this means the following:[297]
<?xml version="1.0" ?> <!-- the namespace declarations of office:document-content are omitted <office:document-content office:version="1.0"> <office:font-face-decls> <style:font-face style:name="Arial" svg:font-family="Arial" style:font-family-generic="swiss" style:font-pitch="variable"/> </office:font-face-decls> <office:automatic-styles> [....] <style:style style:name="T1" style:family="text"> <style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic"/> </style:style> <style:style style:name="T2" style:family="text"> <style:text-properties fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold"/> </style:style> <style:style style:name="T5" style:family="text"> <style:text-properties fo:color="#ff0000" style:font-name="Arial"/> </style:style> </office:automatic-styles> <office:body> <office:text> [...] <text:p>The <text:span text:style-name="T1">URL</text:span> for <text:span text:style-name="T5">Flickr</text:span> is <text:a xlink:type="simple" xlink:href="http://www.flickr.com/" >http://www.flickr.com</text:a>. <text:s/> The <text:span text:style-name="T2">API page</text:span> is <text:a xlink:type="simple" xlink:href="http://www.flickr.com/services/api/" >http://www.flickr.com/services/api/</text:a></text:p> [....] </office:text> </office:body> </office:document-content>
This series of changes brings you to the completed ODF text document here:
http://examples.mashupguide.net/ch17/odt_example_4.odt
There are obviously many other features in ODF that are not demonstrated here. But these examples should give you a good idea of how to learn about the other elements.
[283] http://books.evc-cit.info/OD_Essentials.pdf or http://develop.opendocumentfellowship.com/book/
[287] http://www.oasis-open.org/committees/download.php/12570/OpenDocument-manifest-schema-?v1.0-os.rng
[288] http://www.oasis-open.org/committees/download.php/12569/OpenDocument-strict-schema-?v1.0-os.rng