Tuesday, February 05, 2008

"XML Namespaces are designed to support exactly this kind of thing." (Tim Bray)


We make really good progress on our interoperability work. In our current focus area of fields we extended the OpenOffice.org Writer core for better support of MS Word-like fields. The first feature which benefits from this work are “Input fields” which now support the long wanted "tabbing" feature.

However we want all fields to benefit from the new enhanced field core --- not only "Input fields". Other areas are e.g "Mail merge fields" etc.. Since all of this fields share the same generic mechanism we decided to add support for this generic MS Word-like fields in OpenOffice.org Writer. But by doing so we faced the problem that ODF is not supporting these kind of fields.

Interestingly Tim Bray (Director of Web Technologies at Sun Microsystems) suggested a solution already in November 2005: http://www.tbray.org/ongoing/When/200x/2005/11/27/Office-XML. Unsurprisingly he suggested XML namespaces to solve this problem.

Thats what we did. MS Word-like fields are now stored in the namespace

xmlns:field="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:field:1.0"

which clearly indicates the purpose: OOXML<->ODF interoperability.

The following RelaxNG fragment enhanced the current ODF specification with the new fields:
<define name="paragraph-content" combine="choice">
<choice>
<element name="field:fieldmark">
<attribute name="text:name">
<ref name="string"/>
</attribute>
<attribute name="field:type">
<ref name="namespacedToken"/>
</attribute>
<attribute name="field:locked">
<ref name="boolean"/>
</attribute>
<sequence>
<ref name="fieldmark-parameter"/>
<zeroOrMore>
<ref name="paragraph-content"/>
</zeroOrMore>
<sequence>
</element>
<element name="field:fieldmark-start">
<attribute name="text:name">
<ref name="string"/>
</attribute>
<attribute name="field:type">
<ref name="namespacedToken"/>
</attribute>
<attribute name="field:locked">
<ref name="boolean"/>
</attribute>
<ref name="fieldmark-parameter"/>
</element>
<element name="text:fieldmark-end">
</element>
</choice>
</define>


In general fieldmarks are very similar to bookmarks, except that they need to be properly nested. This is achieved by the fact, that a field:fieldmark-end does not have a "name" attribute, but instead closes the last opened field:fieldmark-start element.
The field:fieldmark element is a short form of field:fieldmark-start and field:fieldmark-end. It SHOULD preferably be written instead of start-/end marks.

Every fieldmark can have
  • a name (text:name); similar to the name of text:bookmark elements. They SHOULD be unique. (Preferably also with the bookmark names).
  • a type (field:type) which allows application to define the type of the fieldmark.
  • a sequence of associated (name, value) pair represented by the <field:param field:name=”string” field:value=”string”/>.
  • a locked attribute which specifies whether the user can edit the content or not.


A sample. Lets take a loog at the following sample docs:




The OOXML representation is:
  <w:p>
<w:r><w:t xml:space="preserve">Title: </w:t></w:r>
<w:bookmarkStart w:id="0" w:name="Text1"/>
<w:r>
<w:fldChar w:fldCharType="begin">
<w:ffData>
<w:name w:val="Text1"/>
<w:statusText w:type="text" w:val="Just a sample field."/>
<w:textInput/>
</w:ffData>
</w:fldChar>
<w:instrText xml:space="preserve"> FORMTEXT </w:instrText>
<w:fldChar w:fldCharType="separate"/>
<w:t xml:space="preserve">A sample input.</w:t>
<w:fldChar w:fldCharType="end"/>
</w:r>
<w:bookmarkEnd w:id="0"/>
</w:p>
<w:p>
<w:r><w:t xml:space="preserve">Description: </w:t></w:r>
<w:bookmarkStart w:id="1" w:name="Text2"/>
<w:r w:rsidR="00FA39C2">
<w:fldChar w:fldCharType="begin">
<w:ffData>
<w:name w:val="Text2"/>
<w:statusText w:type="text" w:val="Yet another sample field..."/>
<w:textInput/>
</w:ffData>
</w:fldChar>
<w:instrText xml:space="preserve"> FORMTEXT </w:instrText>
<w:fldChar w:fldCharType="separate"/>
<w:t>A sample input.</w:t>
</w:r>
</w:p>
<w:p>
<w:r><w:t>Second sample input paragraph.</w:t></w:r>
<w:r><w:fldChar w:fldCharType="end"/></w:r>
<w:bookmarkEnd w:id="1"/>
</w:p>
<w:bookmarkStart w:id="2" w:name="Check1"/>
<w:p>
<w:r>
<w:fldChar w:fldCharType="begin">
<w:ffData>
<w:name w:val="Check1"/>
<w:statusText w:type="text" w:val="A sample checkbox..."/>
<w:checkBox>
<w:checked/>
</w:checkBox>
</w:ffData>
</w:fldChar>
<w:instrText xml:space="preserve"> FORMCHECKBOX </w:instrText>
<w:fldChar w:fldCharType="end"/>
</w:r>
<w:bookmarkEnd w:id="2"/>
<w:r><w:t xml:space="preserve"> Make sense?</w:t></w:r>
</w:p>

The ODF+Enhancement representation is:
 
<text:p>Title: <field:fieldmark-start text:name="Text1" field:type="ecma.office-open-xml.field.FORMTEXT"><field:param field:name="Description" field:value="Just a sample field."/></field:fieldmark-start>A sample input.<field:fieldmark-end/></text:p>
<text:p>Description: <field:fieldmark-start text:name="Text2" field:type="ecma.office-open-xml.field.FORMTEXT"><field:param field:name="Description" field:value="Yet another sample field..."/></field:fieldmark-start>A sample input.</text:p>
<text:p>Second sample input paragraph.<field:fieldmark-end/></text:p>
<text:p><field:fieldmark text:name="Check1" field:type="ecma.office-open-xml.field.FORMCHECKBOX"><field:param field:name="Description" field:value="A sample checkbox..."/><field:param field:name="Result" field:value="1"/></field:fieldmark><text:s/>Make sense?</text:p>


Cool isn't it. Or with Tim's words: "Who could possibly be against it?"