+write_xml_with_line_breaks (struct odt_driver *odt, const char *line_)
+{
+ xmlTextWriterPtr writer = odt->content_wtr;
+
+ if (!strchr (line_, '\n'))
+ xmlTextWriterWriteString (writer, _xml(line_));
+ else
+ {
+ char *line = xstrdup (line_);
+ char *newline;
+ char *p;
+
+ for (p = line; *p; p = newline + 1)
+ {
+ newline = strchr (p, '\n');
+
+ if (!newline)
+ {
+ xmlTextWriterWriteString (writer, _xml(p));
+ free (line);
+ return;
+ }
+
+ if (newline > p && newline[-1] == '\r')
+ newline[-1] = '\0';
+ else
+ *newline = '\0';
+ xmlTextWriterWriteString (writer, _xml(p));
+ xmlTextWriterWriteElement (writer, _xml("text:line-break"), _xml(""));
+ }
+ }
+}
+
+static void
+write_footnote (struct odt_driver *odt, const char *footnote)
+{
+ char marker[16];
+
+ xmlTextWriterStartElement (odt->content_wtr, _xml("text:note"));
+ xmlTextWriterWriteAttribute (odt->content_wtr, _xml("text:note-class"),
+ _xml("footnote"));
+
+ xmlTextWriterStartElement (odt->content_wtr, _xml("text:note-citation"));
+ str_format_26adic (++odt->n_footnotes, false, marker, sizeof marker);
+ if (strlen (marker) > 1)
+ xmlTextWriterWriteFormatAttribute (odt->content_wtr, _xml("text:label"),
+ "(%s)", marker);
+ else
+ xmlTextWriterWriteAttribute (odt->content_wtr, _xml("text:label"),
+ _xml(marker));
+ xmlTextWriterEndElement (odt->content_wtr);
+
+ xmlTextWriterStartElement (odt->content_wtr, _xml("text:note-body"));
+ xmlTextWriterStartElement (odt->content_wtr, _xml("text:p"));
+ write_xml_with_line_breaks (odt, footnote);
+ xmlTextWriterEndElement (odt->content_wtr);
+ xmlTextWriterEndElement (odt->content_wtr);
+
+ xmlTextWriterEndElement (odt->content_wtr);
+}
+
+static void
+write_table (struct odt_driver *odt, const struct table_item *item)