
# RESOURCES

There is indeed an official and free available standard for
WordprocessingML:
<https://standards.iso.org/ittf/PubliclyAvailableStandards/index.html>
and look for the ISO/IEC 29500 documents.

You for sure will need the pdf document with a titel as "INTERNATIONAL
STANDARD ISO/IEC 29500-1 Fourth edition 2016-11-01 Part 1:
Fundamentals and Markup Language Reference". The file name is
something crude as C071691e.pdf.

A web version of the same content can be found at <https://ooxml.info/>.

Very helpful (indispensable perhaps) is also wml.xsd

For introductional material to WordprocessingML see
<http://www.officeopenxml.com/anatomyofOOXML.php>

Microsoft has
<https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-offfflp>

Other libraries do similar things.

For python see <https://python-docx.readthedocs.io/en/latest/>.

For C# and .net see <https://github.com/dotnet/Open-XML-SDK>

Good Tcl level is required. And tDOM knowledge is helpful, or course.

# BASICS

Working with Tcl is mostly a pleasure. Working with tDOM hopefully is
and working with this Tcl docx framework hopefully will be too.
Working with WordprocessingML is not always a pleasure. In some
hindsight it looks more like the translation of a binary format into
XML than as a well-designed document markup.

At least it is a voluminous beast - which is kind of inevitable (to
some degree) for a powerful layout markup language.

Almost all WordprocessingML elements have no text content. Values and
options are carried out by attributes. That attributes are namespaced
(for no obvious or good reason).

Some elements can have a meaning just by their precence, without any
attribute or content. These elements are switches. For example there
is an element which switches bold text on if it is not and off if it
is. This package does not use this WordprocessingML feature; all of
this elements have a *w:val* attribute to explicitly set the switch
(and this is used).

Most attribute values are some measurement (dimension, size, etc) or
a symbol out of a certain list.

# GETTING STARTED

Looking at the XML data of an unzipped document will be more or less
unavoidable part of the work of enhancing or debbuging the library. To
help with this a kind of pretty printing tool is part of the source
distribution. Look at tools/pp.tcl and read the comment on top. Tcl 9
is required to run the tool. Call it just with the .docx you want to
unpack:

```
tclsh9 tools/pp.tcl my.docx
```

One way to get information which WordprocessingML is needed to
implement a certain feature is to create a (typically as simple as
possible) document with a wordprocessing programm as Libreoffic or
Word and to look at the generated XML. The usual next steps are to
look up the elements needed in the specification PDF and the xsd file.

The next step will be to implement a ooxml::docx interface to create
that WordprocessingML content at the right place.

It also typically works well to zip an unzipped document back into an
.docx. This can be helpful to see what elements and attributes are
more or less "noice" for the feature your implementing or to see (by
copying parts of the XML from a processor created docx into the docx
generated by the ooxml::docx) what additional content is needed for a
certain effect. The inserted indentataion by pp.tcl doesn't provide
trouble here. At the top level of the unzipped docx do something like:

```
zip -r ../my-rezipped.docx .
```


# GENERATING ELEMENTS AND ATTRIBUTES ON USER INPUT

In a lot of cases with the method Create it is possible to create
WordprocessingML content directly from option values given by the
user. This method expects a list of opion value pairs as argument.

The value of an option (as -bold, -margins etc.) must be a Tcl list
with at least two elements.

The first element of that list is the list of elements to create. 

The second argument is a list with information about the attributes to
set and how the values for the attributes are extracted from the value
given to the option and the types of that value.

If the second argument has only one element and that element itself is
not a list with more than 1 element then the name of the attribute to
create is *w:val* and this element is the type callback for the value.

Otherwise every element of the second argument list itself is threated
as a list. If the second argument list has one element 
then the name of created attribute will be the first element of that
element and the value, after calling the as second element given type
callback. will be the value of the option.

Otherwise - which means that this option may set more than one
attribute at once - the value to the option is seen as a keyword value
list. 

If the list element has two members then the name of the keyword and
the name of the attribute to create is the first element of the list
and the second argument the type callback.

If the list element has three members then the the first element of
that list is the keyword, the second element is the name of the
attribute to create and the third element is the type callback.

If the list the option name points to has three elements then the
second list element will be ignored and the processing is done by the
specialized procedure given with the third element.

If the second argument has two elements then 
