[gen] XhtmlCleaner now only keeps useful CSS attributes within XHTML style attributes.
This commit is contained in:
parent
9477865f44
commit
d16b03e0d6
|
@ -217,7 +217,7 @@ class Renderer:
|
||||||
'text': pe.NS_TEXT}))
|
'text': pe.NS_TEXT}))
|
||||||
self.stylesParser = self.createPodParser('styles.xml', context,
|
self.stylesParser = self.createPodParser('styles.xml', context,
|
||||||
stylesInserts)
|
stylesInserts)
|
||||||
# Stores the styles mapping
|
# Store the styles mapping
|
||||||
self.setStylesMapping(stylesMapping)
|
self.setStylesMapping(stylesMapping)
|
||||||
|
|
||||||
def createPodParser(self, odtFile, context, inserts):
|
def createPodParser(self, odtFile, context, inserts):
|
||||||
|
@ -398,6 +398,12 @@ class Renderer:
|
||||||
and, on the other hand, ODT styles found into the template.'''
|
and, on the other hand, ODT styles found into the template.'''
|
||||||
try:
|
try:
|
||||||
stylesMapping = self.stylesManager.checkStylesMapping(stylesMapping)
|
stylesMapping = self.stylesManager.checkStylesMapping(stylesMapping)
|
||||||
|
# The predefined styles below are currently ignored, because the
|
||||||
|
# xhtml2odt parser does not take into account span tags.
|
||||||
|
if 'span[font-weight=bold]' not in stylesMapping:
|
||||||
|
stylesMapping['span[font-weight=bold]'] = 'podBold'
|
||||||
|
if 'span[font-style=italic]' not in stylesMapping:
|
||||||
|
stylesMapping['span[font-style=italic]'] = 'podItalic'
|
||||||
self.stylesManager.stylesMapping = stylesMapping
|
self.stylesManager.stylesMapping = stylesMapping
|
||||||
except PodError, po:
|
except PodError, po:
|
||||||
self.contentParser.env.currentBuffer.content.close()
|
self.contentParser.env.currentBuffer.content.close()
|
||||||
|
|
|
@ -22,6 +22,7 @@ from UserDict import UserDict
|
||||||
import appy.pod
|
import appy.pod
|
||||||
from appy.pod import *
|
from appy.pod import *
|
||||||
from appy.pod.odf_parser import OdfEnvironment, OdfParser
|
from appy.pod.odf_parser import OdfEnvironment, OdfParser
|
||||||
|
from appy.shared.css import parseStyleAttribute
|
||||||
|
|
||||||
# Possible states for the parser
|
# Possible states for the parser
|
||||||
READING = 0 # Default state
|
READING = 0 # Default state
|
||||||
|
@ -329,12 +330,7 @@ class StylesManager:
|
||||||
else: return
|
else: return
|
||||||
# If I am here, I have style info. Check if it corresponds to some style
|
# If I am here, I have style info. Check if it corresponds to some style
|
||||||
# in p_styles.
|
# in p_styles.
|
||||||
infos = attrs['style'].split(';')
|
styleInfo = parseStyleAttribute(attrs['style'], asDict=True)
|
||||||
styleInfo = {}
|
|
||||||
for info in infos:
|
|
||||||
if not info.strip(): continue
|
|
||||||
name, value = info.split(':')
|
|
||||||
styleInfo[name.strip()] = value.strip()
|
|
||||||
for matchingAttrs, style in styles:
|
for matchingAttrs, style in styles:
|
||||||
if self.styleMatch(styleInfo, matchingAttrs):
|
if self.styleMatch(styleInfo, matchingAttrs):
|
||||||
return style
|
return style
|
||||||
|
|
14
shared/css.py
Normal file
14
shared/css.py
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
def parseStyleAttribute(value, asDict=False):
|
||||||
|
'''Returns a list of CSS (name, value) pairs (or a dict if p_asDict is
|
||||||
|
True), parsed from p_value, which holds the content of a HTML "style"
|
||||||
|
tag.'''
|
||||||
|
if asDict: res = {}
|
||||||
|
else: res = []
|
||||||
|
for attr in value.split(';'):
|
||||||
|
if not attr.strip(): continue
|
||||||
|
name, value = attr.split(':')
|
||||||
|
if asDict: res[name.strip()] = value.strip()
|
||||||
|
else: res.append( (name.strip(), value.strip()) )
|
||||||
|
return res
|
||||||
|
# ------------------------------------------------------------------------------
|
|
@ -26,6 +26,7 @@ from xml.sax import SAXParseException
|
||||||
from appy.shared import UnicodeBuffer, xmlPrologue
|
from appy.shared import UnicodeBuffer, xmlPrologue
|
||||||
from appy.shared.errors import AppyError
|
from appy.shared.errors import AppyError
|
||||||
from appy.shared.utils import sequenceTypes
|
from appy.shared.utils import sequenceTypes
|
||||||
|
from appy.shared.css import parseStyleAttribute
|
||||||
|
|
||||||
# Constants --------------------------------------------------------------------
|
# Constants --------------------------------------------------------------------
|
||||||
CONVERSION_ERROR = '"%s" value "%s" could not be converted by the XML ' \
|
CONVERSION_ERROR = '"%s" value "%s" could not be converted by the XML ' \
|
||||||
|
@ -906,6 +907,10 @@ class XhtmlCleaner(XmlParser):
|
||||||
# Attributes to ignore, if keepStyles if False.
|
# Attributes to ignore, if keepStyles if False.
|
||||||
attrsToIgnore = ('align', 'valign', 'cellpadding', 'cellspacing', 'width',
|
attrsToIgnore = ('align', 'valign', 'cellpadding', 'cellspacing', 'width',
|
||||||
'height', 'bgcolor', 'lang', 'border', 'class')
|
'height', 'bgcolor', 'lang', 'border', 'class')
|
||||||
|
# CSS attributes to keep, if keepStyles if False. These attributes can be
|
||||||
|
# used by appy.pod (to align a paragraph, center/resize an image...).
|
||||||
|
cssAttrsToKeep = ('width', 'height', 'float', 'text-align',
|
||||||
|
'font-style', 'font-weight')
|
||||||
# Attrs to add, if not present, to ensure good formatting, be it at the web
|
# Attrs to add, if not present, to ensure good formatting, be it at the web
|
||||||
# or ODT levels.
|
# or ODT levels.
|
||||||
attrsToAdd = {'table': {'cellspacing':'0', 'cellpadding':'6', 'border':'1'},
|
attrsToAdd = {'table': {'cellspacing':'0', 'cellpadding':'6', 'border':'1'},
|
||||||
|
@ -957,6 +962,15 @@ class XhtmlCleaner(XmlParser):
|
||||||
raise self.Error(str(e))
|
raise self.Error(str(e))
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
def cleanStyleAttribute(self, value):
|
||||||
|
'''p_value contains some CSS attributes from a "style" attribute. We
|
||||||
|
keep those that pod can manage.'''
|
||||||
|
res = []
|
||||||
|
for name, v in parseStyleAttribute(value):
|
||||||
|
if name in self.cssAttrsToKeep:
|
||||||
|
res.append('%s: %s' % (name, v))
|
||||||
|
return '; '.join(res)
|
||||||
|
|
||||||
def startDocument(self):
|
def startDocument(self):
|
||||||
# The result will be cleaned XHTML, joined from self.res.
|
# The result will be cleaned XHTML, joined from self.res.
|
||||||
self.res = []
|
self.res = []
|
||||||
|
@ -989,7 +1003,11 @@ class XhtmlCleaner(XmlParser):
|
||||||
res = '%s<%s' % (prefix, elem)
|
res = '%s<%s' % (prefix, elem)
|
||||||
# Include the found attributes, excepted those that must be ignored.
|
# Include the found attributes, excepted those that must be ignored.
|
||||||
for name, value in attrs.items():
|
for name, value in attrs.items():
|
||||||
if not e.keepStyles and (name in self.attrsToIgnore): continue
|
if not e.keepStyles:
|
||||||
|
if name in self.attrsToIgnore: continue
|
||||||
|
elif name == 'style':
|
||||||
|
value = self.cleanStyleAttribute(value)
|
||||||
|
if not value: continue
|
||||||
res += ' %s="%s"' % (name, value)
|
res += ' %s="%s"' % (name, value)
|
||||||
# Include additional attributes if required.
|
# Include additional attributes if required.
|
||||||
if elem in self.attrsToAdd:
|
if elem in self.attrsToAdd:
|
||||||
|
|
Loading…
Reference in a new issue