0005528: ODF output fails validation. Added generation of settings.xml, and fixed illegal characters in style-name

svn: r18765
This commit is contained in:
Tim G L Lyons 2012-01-24 16:00:11 +00:00
parent 00fde7d03a
commit abddb6bcf6
2 changed files with 71 additions and 30 deletions

View File

@ -112,7 +112,8 @@ _esc_map = {
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import re import re
NewStyle = re.compile('style-name="([a-zA-Z0-9]*)__([#a-zA-Z0-9 ]*)__">') # Hyphen is added because it is used to replace spaces in the font name
NewStyle = re.compile('style-name="([a-zA-Z0-9]*)__([#a-zA-Z0-9 -]*)__">')
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -156,6 +157,7 @@ _FONTS = '''\
svg:font-family="Arial" svg:font-family="Arial"
style:font-family-generic="swiss" style:font-family-generic="swiss"
style:font-pitch="variable"/> style:font-pitch="variable"/>
''' '''
_META_XML = '''\ _META_XML = '''\
@ -298,6 +300,7 @@ _AUTOMATIC_STYLES = '''\
<style:text-properties <style:text-properties
style:font-name="Courier"/> style:font-name="Courier"/>
</style:style> </style:style>
''' '''
_CLEAR_STYLE = '''\ _CLEAR_STYLE = '''\
@ -444,6 +447,7 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc):
self.mimetype = None self.mimetype = None
self.meta = None self.meta = None
self.mfile = None self.mfile = None
self.stfile = None
self.filename = None self.filename = None
self.lang = None self.lang = None
self._backend = None self._backend = None
@ -810,6 +814,7 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc):
self.finish_cntnt_creation() self.finish_cntnt_creation()
self._write_styles_file() self._write_styles_file()
self._write_manifest() self._write_manifest()
self._write_settings()
self._write_meta_file() self._write_meta_file()
self._write_mimetype_file() self._write_mimetype_file()
self._write_zip() self._write_zip()
@ -822,11 +827,14 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc):
wrt1 = self.cntnt1.write wrt1 = self.cntnt1.write
for style in self.StyleList_notes: for style in self.StyleList_notes:
if style[1] == "FontFace": if style[1] == "FontFace":
# Restore any spaced that were replaced by hyphens in
# libodfbackend
wrt1( wrt1(
'<style:font-face ' + '<style:font-face ' +
'style:name="%s" ' % style[2] + ' style:name="%s"\n' % style[2].replace("-", " ") +
'svg:font-family="&apos;%s&apos;" ' % style[2] + ' svg:font-family="&apos;%s&apos;"\n' %
'style:font-pitch="fixed"/>\n' style[2].replace("-", " ") +
' style:font-pitch="fixed"/>\n\n'
) )
def add_styled_notes_styles(self): def add_styled_notes_styles(self):
@ -839,44 +847,49 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc):
if style[1] == "FontSize": if style[1] == "FontSize":
wrt2( wrt2(
'<style:style ' + '<style:style ' +
'style:name="FontSize__%s__" ' % style[2] + 'style:name="FontSize__%s__"\n' % style[2] +
'style:family="text"> ' + ' style:family="text">\n' +
'<style:text-properties ' + ' <style:text-properties\n' +
'fo:font-size="%spt" ' % style[2] + ' fo:font-size="%spt"\n' % style[2] +
'style:font-size-asian="%spt" ' % style[2] + ' style:font-size-asian="%spt"\n' % style[2] +
'style:font-size-complex="%spt"/>' % style[2] + ' style:font-size-complex="%spt"/>\n' % style[2] +
'</style:style>\n' '</style:style>\n\n'
) )
elif style[1] == "FontColor": elif style[1] == "FontColor":
# Restore the hash at the start that was removed by
# libodfbackend
wrt2( wrt2(
'<style:style ' + '<style:style ' +
'style:name="FontColor__%s__" ' % style[2] + 'style:name="FontColor__%s__"\n' % style[2] +
'style:family="text">' + ' style:family="text">\n' +
' <style:text-properties ' + ' <style:text-properties\n' +
'fo:color="%s"/>' % style[2] + ' fo:color="#%s"/>\n' % style[2] +
'</style:style>\n' '</style:style>\n\n'
) )
elif style[1] == "FontHighlight": elif style[1] == "FontHighlight":
wrt2( wrt2(
'<style:style ' + '<style:style ' +
'style:name="FontHighlight__%s__" ' % style[2] + 'style:name="FontHighlight__%s__"\n' % style[2] +
'style:family="text"> ' + ' style:family="text">\n' +
'<style:text-properties ' + ' <style:text-properties\n' +
'fo:background-color="%s"/>' % style[2] + ' fo:background-color="#%s"/>\n' % style[2] +
'</style:style>\n' '</style:style>\n\n'
) )
elif style[1] == "FontFace": elif style[1] == "FontFace":
# Restore any spaced that were replaced by hyphens in
# libodfbackend
wrt2( wrt2(
'<style:style ' + '<style:style ' +
'style:name="FontFace__%s__" ' % style[2] + 'style:name="FontFace__%s__"\n' % style[2] +
'style:family="text"> ' + ' style:family="text">\n' +
'<style:text-properties ' + ' <style:text-properties\n' +
'style:font-name="%s" ' % style[2] + ' style:font-name="%s"\n' %
'style:font-pitch="variable"/>' + style[2].replace("-", " ") +
'</style:style>\n' ' style:font-pitch="variable"/>\n' +
'</style:style>\n\n'
) )
def add_styled_photo_styles(self): def add_styled_photo_styles(self):
@ -1184,12 +1197,14 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc):
self._add_zip(zfile, "META-INF/manifest.xml", self.mfile.getvalue(), t) self._add_zip(zfile, "META-INF/manifest.xml", self.mfile.getvalue(), t)
self._add_zip(zfile, "content.xml", self.cntntx.getvalue(), t) self._add_zip(zfile, "content.xml", self.cntntx.getvalue(), t)
self._add_zip(zfile, "meta.xml", self.meta.getvalue(), t) self._add_zip(zfile, "meta.xml", self.meta.getvalue(), t)
self._add_zip(zfile, "settings.xml", self.stfile.getvalue(), t)
self._add_zip(zfile, "styles.xml", self.sfile.getvalue(), t) self._add_zip(zfile, "styles.xml", self.sfile.getvalue(), t)
self._add_zip(zfile, "mimetype", self.mimetype.getvalue(), t) self._add_zip(zfile, "mimetype", self.mimetype.getvalue(), t)
self.mfile.close() self.mfile.close()
self.cntnt.close() self.cntnt.close()
self.meta.close() self.meta.close()
self.stfile.close()
self.sfile.close() self.sfile.close()
self.mimetype.close() self.mimetype.close()
@ -1617,11 +1632,30 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc):
'manifest:full-path="content.xml"/>' 'manifest:full-path="content.xml"/>'
'<manifest:file-entry manifest:media-type="text/xml" ' '<manifest:file-entry manifest:media-type="text/xml" '
'manifest:full-path="styles.xml"/>' 'manifest:full-path="styles.xml"/>'
'<manifest:file-entry manifest:media-type="text/xml" '
'manifest:full-path="settings.xml"/>'
'<manifest:file-entry manifest:media-type="text/xml" ' '<manifest:file-entry manifest:media-type="text/xml" '
'manifest:full-path="meta.xml"/>' 'manifest:full-path="meta.xml"/>'
'</manifest:manifest>\n' '</manifest:manifest>\n'
) )
def _write_settings(self):
"""
create the settings.xml file
"""
self.stfile = StringIO()
# This minimal settings file has been taken from
# http://mashupguide.net/1.0/html/ch17s03.xhtml (Creative commons
# licence): http://mashupguide.net/1.0/html/apas02.xhtml
self.stfile.write(
'<?xml version="1.0" encoding="UTF-8"?>\n' +
'<office:document-settings office:version="1.0"\n' +
'xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0"\n' +
'xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"\n' +
'xmlns:ooo="http://openoffice.org/2004/office"\n' +
'xmlns:xlink="http://www.w3.org/1999/xlink" />'
)
def _write_mimetype_file(self): def _write_mimetype_file(self):
""" """
create the mimetype.xml file create the mimetype.xml file

View File

@ -121,18 +121,25 @@ class OdfBackend(DocBackend):
""" """
if tagtype not in self.SUPPORTED_MARKUP: if tagtype not in self.SUPPORTED_MARKUP:
return None return None
# The ODF validator does not like spaces or hash in style-names. the
# font name needs to have the spaces restored, we just hope that the
# name did not have a hyphen in it originally. The colour is represented
# without the leading hash, this can be replaced when used in the text-
# property font colour
if ( tagtype == DocBackend.FONTCOLOR ): if ( tagtype == DocBackend.FONTCOLOR ):
return ('<text:span text:style-name=\"FontColor__%s__\">' % value, return ('<text:span text:style-name=\"FontColor__%s__\">' %
value.replace("#", ""),
'</text:span>') '</text:span>')
elif ( tagtype == DocBackend.FONTFACE ): elif ( tagtype == DocBackend.FONTFACE ):
return ('<text:span text:style-name=\"FontFace__%s__\">' % return ('<text:span text:style-name=\"FontFace__%s__\">' %
self.ESCAPE_FUNC()(value), self.ESCAPE_FUNC()(value).replace(" ", "-"),
'</text:span>') '</text:span>')
elif ( tagtype == DocBackend.FONTSIZE ): elif ( tagtype == DocBackend.FONTSIZE ):
return ('<text:span text:style-name=\"FontSize__%d__\">' % value, return ('<text:span text:style-name=\"FontSize__%d__\">' % value,
'</text:span>') '</text:span>')
else: #elif ( tagtype == DocBackend.HIGHLIGHT ): else: #elif ( tagtype == DocBackend.HIGHLIGHT ):
return ('<text:span text:style-name=\"FontHighlight__%s__\">' % value, return ('<text:span text:style-name=\"FontHighlight__%s__\">' %
value.replace("#", ""),
'</text:span>') '</text:span>')
def format_link(self, value): def format_link(self, value):