Esempio n. 1
0
def transform_declaration(decl):
    decl = StyleDeclaration(decl)
    changed = False
    for prop, parent_prop in tuple(decl):
        if prop.name in page_break_properties:
            changed = True
            name = prop.name.partition('-')[2]
            for prefix in ('', '-webkit-column-'):
                # Note that Firefox does not support break-after at all
                # https://bugzil.la/549114
                decl.set_property(prefix + name, prop.value, prop.priority)
            decl.remove_property(prop, parent_prop)
        elif prop.name == 'font-size':
            raw = prop.value
            afs = absolute_font_sizes.get(raw)
            if afs is not None:
                changed = True
                decl.change_property(prop, parent_prop, afs)
                continue
            l, unit = parse_css_length(raw)
            if unit in absolute_units:
                changed = True
                l = convert_fontsize(l, unit)
                decl.change_property(prop, parent_prop,
                                     unicode_type(l) + 'rem')
    return changed
Esempio n. 2
0
def parse_css_length_or_number(raw, default_unit=None):
    if isinstance(raw, (int, long, float)):
        return raw, default_unit
    try:
        return float(raw), default_unit
    except Exception:
        return parse_css_length(raw)
def parse_css_length_or_number(raw, default_unit=None):
    if isinstance(raw, (int, long, float)):
        return raw, default_unit
    try:
        return float(raw), default_unit
    except Exception:
        return parse_css_length(raw)
Esempio n. 4
0
def transform_declaration(decl):
    decl = StyleDeclaration(decl)
    changed = False
    for prop, parent_prop in tuple(decl):
        if prop.name in {'page-break-before', 'page-break-after', 'page-break-inside'}:
            changed = True
            name = prop.name.partition('-')[2]
            for prefix in ('', '-webkit-column-'):
                # Note that Firefox does not support break-after at all
                # https://bugzil.la/549114
                decl.set_property(prefix + name, prop.value, prop.priority)
            decl.remove_property(prop, parent_prop)
        elif prop.name == 'font-size':
            l, unit = parse_css_length(prop.value)
            if unit in absolute_units:
                changed = True
                l = convert_fontsize(l, unit)
                decl.change_property(prop, parent_prop, str(l) + 'rem')
    return changed
Esempio n. 5
0
def transform_declaration(decl):
    decl = StyleDeclaration(decl)
    changed = False
    for prop, parent_prop in tuple(decl):
        if prop.name in {'page-break-before', 'page-break-after', 'page-break-inside'}:
            changed = True
            name = prop.name.partition('-')[2]
            for prefix in ('', '-webkit-column-'):
                # Note that Firefox does not support break-after at all
                # https://bugzil.la/549114
                decl.set_property(prefix + name, prop.value, prop.priority)
            decl.remove_property(prop, parent_prop)
        elif prop.name == 'font-size':
            l, unit = parse_css_length(prop.value)
            if unit in absolute_units:
                changed = True
                l = convert_fontsize(l, unit)
                decl.change_property(prop, parent_prop, str(l) + 'rem')
    return changed
Esempio n. 6
0
def transform_declaration(decl):
    decl = StyleDeclaration(decl)
    changed = False
    nonstandard_writing_mode_props = {}
    standard_writing_mode_props = {}

    for prop, parent_prop in tuple(decl):
        if prop.name in page_break_properties:
            changed = True
            name = prop.name.partition('-')[2]
            for prefix in ('', '-webkit-column-'):
                # Note that Firefox does not support break-after at all
                # https://bugzil.la/549114
                decl.set_property(prefix + name, prop.value, prop.priority)
            decl.remove_property(prop, parent_prop)
        elif prop.name == 'font-size':
            raw = prop.value
            afs = absolute_font_sizes.get(raw)
            if afs is not None:
                changed = True
                decl.change_property(prop, parent_prop, afs)
                continue
            l, unit = parse_css_length(raw)
            if unit in absolute_units:
                changed = True
                l = convert_fontsize(l, unit)
                decl.change_property(prop, parent_prop,
                                     unicode_type(l) + 'rem')
        elif prop.name in nonstandard_writing_mode_property_names:
            nonstandard_writing_mode_props[prop.value] = prop.priority
        elif prop.name == 'writing-mode':
            standard_writing_mode_props[prop.value] = True

    # Add standard writing-mode properties if they don't exist so that
    # all of the browsers supported by the viewer work in vertical modes
    for value, priority in nonstandard_writing_mode_props.items():
        if value not in standard_writing_mode_props:
            decl.set_property('writing-mode', value, priority)
            changed = True

    return changed
Esempio n. 7
0
    def serialize_properties(self, pPr, normal_style):
        makeelement, w = self.makeelement, self.w
        spacing = makeelement(pPr, 'spacing')
        for edge, attr in iteritems({'top': 'before', 'bottom': 'after'}):
            getter = attrgetter('css_margin_' + edge)
            css_val, css_unit = parse_css_length(getter(self))
            if css_unit in ('em', 'ex'):
                lines = max(0,
                            int(css_val * (50 if css_unit == 'ex' else 100)))
                if (self is normal_style
                        and lines > 0) or getter(self) != getter(normal_style):
                    spacing.set(w(attr + 'Lines'), unicode_type(lines))
            else:
                getter = attrgetter('margin_' + edge)
                val = getter(self)
                if (self is normal_style
                        and val > 0) or val != getter(normal_style):
                    spacing.set(w(attr), unicode_type(val))

        if self is normal_style or self.line_height != normal_style.line_height:
            spacing.set(w('line'), unicode_type(self.line_height))
            spacing.set(w('lineRule'), 'atLeast')

        if spacing.attrib:
            pPr.append(spacing)

        ind = makeelement(pPr, 'ind')
        for edge in ('left', 'right'):
            getter = attrgetter('css_margin_' + edge)
            css_val, css_unit = parse_css_length(getter(self))
            if css_unit in ('em', 'ex'):
                chars = max(0,
                            int(css_val * (50 if css_unit == 'ex' else 100)))
                if (self is normal_style
                        and chars > 0) or getter(self) != getter(normal_style):
                    ind.set(w(edge + 'Chars'), unicode_type(chars))
            else:
                getter = attrgetter('margin_' + edge)
                val = getter(self)
                if (self is normal_style
                        and val > 0) or val != getter(normal_style):
                    ind.set(w(edge), unicode_type(val))
                    ind.set(
                        w(edge + 'Chars'), '0'
                    )  # This is needed to override any declaration in the parent style
        css_val, css_unit = parse_css_length(self.css_text_indent)
        if css_unit in ('em', 'ex'):
            chars = int(css_val * (50 if css_unit == 'ex' else 100))
            if css_val >= 0:
                if (self is normal_style and chars > 0
                    ) or self.css_text_indent != normal_style.css_text_indent:
                    ind.set(w('firstLineChars'), unicode_type(chars))
            else:
                if (self is normal_style and chars < 0
                    ) or self.css_text_indent != normal_style.css_text_indent:
                    ind.set(w('hangingChars'), unicode_type(abs(chars)))
        else:
            val = self.text_indent
            if val >= 0:
                if (self is normal_style and val > 0
                    ) or self.text_indent != normal_style.text_indent:
                    ind.set(w('firstLine'), unicode_type(val))
                    ind.set(
                        w('firstLineChars'), '0'
                    )  # This is needed to override any declaration in the parent style
            else:
                if (self is normal_style and val < 0
                    ) or self.text_indent != normal_style.text_indent:
                    ind.set(w('hanging'), unicode_type(abs(val)))
                    ind.set(w('hangingChars'), '0')
        if ind.attrib:
            pPr.append(ind)

        if (self is normal_style and self.background_color
            ) or self.background_color != normal_style.background_color:
            pPr.append(
                makeelement(pPr,
                            'shd',
                            val='clear',
                            color='auto',
                            fill=self.background_color or 'auto'))

        pbdr = self.serialize_borders(pPr.makeelement(w('pBdr')), normal_style)
        if len(pbdr):
            pPr.append(pbdr)

        if self is normal_style or self.text_align != normal_style.text_align:
            pPr.append(makeelement(pPr, 'jc', val=self.text_align))

        if self is not normal_style and self.next_style is not None:
            pPr.append(makeelement(pPr, 'next', val=self.next_style))
Esempio n. 8
0
    def serialize(self, styles, normal_style):
        w, makeelement = self.w, self.makeelement
        style_root = DOCXStyle.serialize(self, styles, normal_style)
        style = makeelement(style_root, 'pPr')

        spacing = makeelement(style, 'spacing')
        for edge, attr in {'top': 'before', 'bottom': 'after'}.iteritems():
            getter = attrgetter('css_margin_' + edge)
            css_val, css_unit = parse_css_length(getter(self))
            if css_unit in ('em', 'ex'):
                lines = max(0,
                            int(css_val * (50 if css_unit == 'ex' else 100)))
                if (self is normal_style
                        and lines > 0) or getter(self) != getter(normal_style):
                    spacing.set(w(attr + 'Lines'), str(lines))
            else:
                getter = attrgetter('margin_' + edge)
                val = getter(self)
                if (self is normal_style
                        and val > 0) or val != getter(normal_style):
                    spacing.set(w(attr), str(val))

        if self is normal_style or self.line_height != normal_style.line_height:
            spacing.set(w('line'), str(self.line_height))
            spacing.set(w('lineRule'), 'atLeast')

        if spacing.attrib:
            style.append(spacing)

        ind = makeelement(style, 'ind')
        for edge in ('left', 'right'):
            getter = attrgetter('css_margin_' + edge)
            css_val, css_unit = parse_css_length(getter(self))
            if css_unit in ('em', 'ex'):
                chars = max(0,
                            int(css_val * (50 if css_unit == 'ex' else 100)))
                if (self is normal_style
                        and chars > 0) or getter(self) != getter(normal_style):
                    ind.set(w(edge + 'Chars'), str(chars))
            else:
                getter = attrgetter('margin_' + edge)
                val = getter(self)
                if (self is normal_style
                        and val > 0) or val != getter(normal_style):
                    ind.set(w(edge), str(val))
        css_val, css_unit = parse_css_length(self.css_text_indent)
        if css_unit in ('em', 'ex'):
            chars = max(0, int(css_val * (50 if css_unit == 'ex' else 100)))
            if (self is normal_style and chars > 0
                ) or self.css_text_indent != normal_style.css_text_indent:
                ind.set('firstLineChars', str(chars))
        else:
            val = self.text_indent
            if (self is normal_style and
                    val > 0) or self.text_indent != normal_style.text_indent:
                ind.set('firstLine', str(val))
        if ind.attrib:
            style.append(ind)

        if (self is normal_style and self.background_color
            ) or self.background_color != normal_style.background_color:
            style.append(
                makeelement(style,
                            'shd',
                            val='clear',
                            color='auto',
                            fill=self.background_color or 'auto'))

        pbdr = self.serialize_borders(style.makeelement(w('pBdr')),
                                      normal_style)
        if len(pbdr):
            style.append(pbdr)

        if self is normal_style or self.text_align != normal_style.text_align:
            style.append(makeelement(style, 'jc', val=self.text_align))

        if (self is normal_style and self.page_break_before
            ) or self.page_break_before != normal_style.page_break_before:
            style.append(
                makeelement(style,
                            'pageBreakBefore',
                            val=bmap(self.page_break_before)))
        if (self is normal_style and
                self.keep_lines) or self.keep_lines != normal_style.keep_lines:
            style.append(
                makeelement(style, 'keepLines', val=bmap(self.keep_lines)))

        if self is not normal_style and self.next_style is not None:
            style.append(makeelement(style, 'next', val=self.next_style))

        if len(style) > 0:
            style_root.append(style)
        return style_root
Esempio n. 9
0
    def serialize(self, styles, normal_style):
        style_root = DOCXStyle.serialize(self, styles, normal_style)
        style = makeelement(style_root, 'pPr')

        spacing = makeelement(style, 'spacing')
        for edge, attr in {'top':'before', 'bottom':'after'}.iteritems():
            getter = attrgetter('css_margin_' + edge)
            css_val, css_unit = parse_css_length(getter(self))
            if css_unit in ('em', 'ex'):
                lines = max(0, int(css_val * (50 if css_unit == 'ex' else 100)))
                if (self is normal_style and lines > 0) or getter(self) != getter(normal_style):
                    spacing.set(w(attr + 'Lines'), str(lines))
            else:
                getter = attrgetter('margin_' + edge)
                val = getter(self)
                if (self is normal_style and val > 0) or val != getter(normal_style):
                    spacing.set(w(attr), str(val))

        if (self is normal_style and self.css_line_height != 'normal') or self.css_line_height != normal_style.css_line_height:
            try:
                css_val, css_unit = float(self.css_line_height), 'ratio'
            except Exception:
                css_val, css_unit = parse_css_length(self.css_line_height)
            if css_unit in {'em', 'ex', '%', 'ratio'}:
                mult = {'ex':0.5, '%':0.01}.get(css_unit, 1)
                val = int(css_val * 240 * mult)
                spacing.set(w('line'), str(val))
            else:
                spacing.set(w('line'), str(0 if self.css_line_height == 'normal' else self.line_height))
                spacing.set(w('lineRule'), 'exactly')

        if spacing.attrib:
            style.append(spacing)

        ind = makeelement(style, 'ind')
        for edge in ('left', 'right'):
            getter = attrgetter('css_margin_' + edge)
            css_val, css_unit = parse_css_length(getter(self))
            if css_unit in ('em', 'ex'):
                chars = max(0, int(css_val * (50 if css_unit == 'ex' else 100)))
                if (self is normal_style and chars > 0) or getter(self) != getter(normal_style):
                    ind.set(w(edge + 'Chars'), str(chars))
            else:
                getter = attrgetter('margin_' + edge)
                val = getter(self)
                if (self is normal_style and val > 0) or val != getter(normal_style):
                    ind.set(w(edge), str(val))
        css_val, css_unit = parse_css_length(self.css_text_indent)
        if css_unit in ('em', 'ex'):
            chars = max(0, int(css_val * (50 if css_unit == 'ex' else 100)))
            if (self is normal_style and chars > 0) or self.css_text_indent != normal_style.css_text_indent:
                ind.set('firstLineChars', str(chars))
        else:
            val = self.text_indent
            if (self is normal_style and val > 0) or self.text_indent != normal_style.text_indent:
                ind.set('firstLine', str(val))
        if ind.attrib:
            style.append(ind)

        if (self is normal_style and self.background_color) or self.background_color != normal_style.background_color:
            style.append(makeelement(style, 'shd', val='clear', color='auto', fill=self.background_color or 'auto'))

        pbdr = self.serialize_borders(style.makeelement(w('pBdr')), normal_style)
        if len(pbdr):
            style.append(pbdr)

        if self is normal_style or self.text_align != normal_style.text_align:
            style.append(makeelement(style, 'jc', val=self.text_align))

        if (self is normal_style and self.page_break_before) or self.page_break_before != normal_style.page_break_before:
            style.append(makeelement(style, 'pageBreakBefore', val=bmap(self.page_break_before)))
        if (self is normal_style and self.keep_lines) or self.keep_lines != normal_style.keep_lines:
            style.append(makeelement(style, 'keepLines', bmap(self.keep_lines)))

        if self is not normal_style and self.next_style is not None:
            style.append(makeelement(style, 'next', val=self.next_style))

        if len(style) > 0:
            style_root.append(style)
        return style_root
Esempio n. 10
0
    def serialize(self, styles, normal_style):
        w, makeelement = self.w, self.makeelement
        style_root = DOCXStyle.serialize(self, styles, normal_style)
        style = makeelement(style_root, 'pPr')

        spacing = makeelement(style, 'spacing')
        for edge, attr in {'top':'before', 'bottom':'after'}.iteritems():
            getter = attrgetter('css_margin_' + edge)
            css_val, css_unit = parse_css_length(getter(self))
            if css_unit in ('em', 'ex'):
                lines = max(0, int(css_val * (50 if css_unit == 'ex' else 100)))
                if (self is normal_style and lines > 0) or getter(self) != getter(normal_style):
                    spacing.set(w(attr + 'Lines'), str(lines))
            else:
                getter = attrgetter('margin_' + edge)
                val = getter(self)
                if (self is normal_style and val > 0) or val != getter(normal_style):
                    spacing.set(w(attr), str(val))

        if self is normal_style or self.line_height != normal_style.line_height:
            spacing.set(w('line'), str(self.line_height))
            spacing.set(w('lineRule'), 'atLeast')

        if spacing.attrib:
            style.append(spacing)

        ind = makeelement(style, 'ind')
        for edge in ('left', 'right'):
            getter = attrgetter('css_margin_' + edge)
            css_val, css_unit = parse_css_length(getter(self))
            if css_unit in ('em', 'ex'):
                chars = max(0, int(css_val * (50 if css_unit == 'ex' else 100)))
                if (self is normal_style and chars > 0) or getter(self) != getter(normal_style):
                    ind.set(w(edge + 'Chars'), str(chars))
            else:
                getter = attrgetter('margin_' + edge)
                val = getter(self)
                if (self is normal_style and val > 0) or val != getter(normal_style):
                    ind.set(w(edge), str(val))
                    ind.set(w(edge + 'Chars'), '0')  # This is needed to override any declaration in the parent style
        css_val, css_unit = parse_css_length(self.css_text_indent)
        if css_unit in ('em', 'ex'):
            chars = int(css_val * (50 if css_unit == 'ex' else 100))
            if css_val >= 0:
                if (self is normal_style and chars > 0) or self.css_text_indent != normal_style.css_text_indent:
                    ind.set(w('firstLineChars'), str(chars))
            else:
                if (self is normal_style and chars < 0) or self.css_text_indent != normal_style.css_text_indent:
                    ind.set(w('hangingChars'), str(abs(chars)))
        else:
            val = self.text_indent
            if val >= 0:
                if (self is normal_style and val > 0) or self.text_indent != normal_style.text_indent:
                    ind.set(w('firstLine'), str(val))
                    ind.set(w('firstLineChars'), '0')  # This is needed to override any declaration in the parent style
            else:
                if (self is normal_style and val < 0) or self.text_indent != normal_style.text_indent:
                    ind.set(w('hanging'), str(abs(val)))
                    ind.set(w('hangingChars'), '0')
        if ind.attrib:
            style.append(ind)

        if (self is normal_style and self.background_color) or self.background_color != normal_style.background_color:
            style.append(makeelement(style, 'shd', val='clear', color='auto', fill=self.background_color or 'auto'))

        pbdr = self.serialize_borders(style.makeelement(w('pBdr')), normal_style)
        if len(pbdr):
            style.append(pbdr)

        if self is normal_style or self.text_align != normal_style.text_align:
            style.append(makeelement(style, 'jc', val=self.text_align))

        if (self is normal_style and self.page_break_before) or self.page_break_before != normal_style.page_break_before:
            style.append(makeelement(style, 'pageBreakBefore', val=bmap(self.page_break_before)))
        if (self is normal_style and self.keep_lines) or self.keep_lines != normal_style.keep_lines:
            style.append(makeelement(style, 'keepLines', val=bmap(self.keep_lines)))

        if self is not normal_style and self.next_style is not None:
            style.append(makeelement(style, 'next', val=self.next_style))

        if len(style) > 0:
            style_root.append(style)
        return style_root
Esempio n. 11
0
    def serialize(self, style):
        spacing = style.makeelement(w('spacing'))
        for edge, attr in {'top':'before', 'bottom':'after'}.iteritems():
            css_val, css_unit = parse_css_length(getattr(self, 'css_margin_' + edge))
            if css_unit in ('em', 'ex'):
                lines = max(0, int(css_val * (50 if css_unit == 'ex' else 100)))
                if lines > 0:
                    spacing.set(w(attr + 'Lines'), str(lines))
            else:
                val = getattr(self, 'margin_' + edge)
                if val > 0:
                    spacing.set(w(attr), str(val))
        if self.css_line_height != 'normal':
            try:
                css_val, css_unit = float(self.css_line_height), 'ratio'
            except Exception:
                css_val, css_unit = parse_css_length(self.css_line_height)
            if css_unit in {'em', 'ex', '%', 'ratio'}:
                mult = {'ex':0.5, '%':0.01}.get(css_unit, 1)
                val = int(css_val * 240 * mult)
                spacing.set(w('line'), str(val))
            else:
                spacing.set(w('line'), str(self.line_height))
                spacing.set(w('lineRule', 'exactly'))

        if spacing.attrib:
            style.append(spacing)

        ind = style.makeelement(w('ind'))
        for edge in ('left', 'right'):
            css_val, css_unit = parse_css_length(getattr(self, 'css_margin_' + edge))
            if css_unit in ('em', 'ex'):
                chars = max(0, int(css_val * (50 if css_unit == 'ex' else 100)))
                if chars > 0:
                    ind.set(w(edge + 'Chars'), str(chars))
            else:
                val = getattr(self, 'margin_' + edge)
                if val > 0:
                    ind.set(w(attr), str(val))
        css_val, css_unit = parse_css_length(self.css_text_indent)
        if css_unit in ('em', 'ex'):
            chars = max(0, int(css_val * (50 if css_unit == 'ex' else 100)))
            if chars > 0:
                ind.set('firstLineChars', str(chars))
        else:
            val = self.text_indent
            if val > 0:
                ind.set('firstLine', str(val))
        if ind.attrib:
            style.append(ind)

        if self.background_color:
            shd = style.makeelement(w('shd'))
            style.append(shd)
            shd.set(w('val'), 'clear'), shd.set(w('fill'), self.background_color), shd.set(w('color'), 'auto')

        pbdr = self.serialize_borders(style.makeelement(w('pBdr')))
        if len(pbdr):
            style.append(pbdr)
        jc = style.makeelement(w('jc'))
        jc.set(w('val'), self.text_align)
        style.append(jc)
        if self.page_break_before:
            style.append(style.makeelement(w('pageBreakBefore'), **{w('val'):'on'}))
        if self.keep_lines:
            style.append(style.makeelement(w('keepLines'), **{w('val'):'on'}))
        return style
Esempio n. 12
0
    def serialize_properties(self, pPr, normal_style):
        makeelement, w = self.makeelement, self.w
        spacing = makeelement(pPr, "spacing")
        for edge, attr in {"top": "before", "bottom": "after"}.iteritems():
            getter = attrgetter("css_margin_" + edge)
            css_val, css_unit = parse_css_length(getter(self))
            if css_unit in ("em", "ex"):
                lines = max(0, int(css_val * (50 if css_unit == "ex" else 100)))
                if (self is normal_style and lines > 0) or getter(self) != getter(normal_style):
                    spacing.set(w(attr + "Lines"), str(lines))
            else:
                getter = attrgetter("margin_" + edge)
                val = getter(self)
                if (self is normal_style and val > 0) or val != getter(normal_style):
                    spacing.set(w(attr), str(val))

        if self is normal_style or self.line_height != normal_style.line_height:
            spacing.set(w("line"), str(self.line_height))
            spacing.set(w("lineRule"), "atLeast")

        if spacing.attrib:
            pPr.append(spacing)

        ind = makeelement(pPr, "ind")
        for edge in ("left", "right"):
            getter = attrgetter("css_margin_" + edge)
            css_val, css_unit = parse_css_length(getter(self))
            if css_unit in ("em", "ex"):
                chars = max(0, int(css_val * (50 if css_unit == "ex" else 100)))
                if (self is normal_style and chars > 0) or getter(self) != getter(normal_style):
                    ind.set(w(edge + "Chars"), str(chars))
            else:
                getter = attrgetter("margin_" + edge)
                val = getter(self)
                if (self is normal_style and val > 0) or val != getter(normal_style):
                    ind.set(w(edge), str(val))
                    ind.set(w(edge + "Chars"), "0")  # This is needed to override any declaration in the parent style
        css_val, css_unit = parse_css_length(self.css_text_indent)
        if css_unit in ("em", "ex"):
            chars = int(css_val * (50 if css_unit == "ex" else 100))
            if css_val >= 0:
                if (self is normal_style and chars > 0) or self.css_text_indent != normal_style.css_text_indent:
                    ind.set(w("firstLineChars"), str(chars))
            else:
                if (self is normal_style and chars < 0) or self.css_text_indent != normal_style.css_text_indent:
                    ind.set(w("hangingChars"), str(abs(chars)))
        else:
            val = self.text_indent
            if val >= 0:
                if (self is normal_style and val > 0) or self.text_indent != normal_style.text_indent:
                    ind.set(w("firstLine"), str(val))
                    ind.set(w("firstLineChars"), "0")  # This is needed to override any declaration in the parent style
            else:
                if (self is normal_style and val < 0) or self.text_indent != normal_style.text_indent:
                    ind.set(w("hanging"), str(abs(val)))
                    ind.set(w("hangingChars"), "0")
        if ind.attrib:
            pPr.append(ind)

        if (self is normal_style and self.background_color) or self.background_color != normal_style.background_color:
            pPr.append(makeelement(pPr, "shd", val="clear", color="auto", fill=self.background_color or "auto"))

        pbdr = self.serialize_borders(pPr.makeelement(w("pBdr")), normal_style)
        if len(pbdr):
            pPr.append(pbdr)

        if self is normal_style or self.text_align != normal_style.text_align:
            pPr.append(makeelement(pPr, "jc", val=self.text_align))

        if self is not normal_style and self.next_style is not None:
            pPr.append(makeelement(pPr, "next", val=self.next_style))
Esempio n. 13
0
    def serialize_properties(self, pPr, normal_style):
        makeelement, w = self.makeelement, self.w
        spacing = makeelement(pPr, 'spacing')
        for edge, attr in iteritems({'top':'before', 'bottom':'after'}):
            getter = attrgetter('css_margin_' + edge)
            css_val, css_unit = parse_css_length(getter(self))
            if css_unit in ('em', 'ex'):
                lines = max(0, int(css_val * (50 if css_unit == 'ex' else 100)))
                if (self is normal_style and lines > 0) or getter(self) != getter(normal_style):
                    spacing.set(w(attr + 'Lines'), str(lines))
            else:
                getter = attrgetter('margin_' + edge)
                val = getter(self)
                if (self is normal_style and val > 0) or val != getter(normal_style):
                    spacing.set(w(attr), str(val))

        if self is normal_style or self.line_height != normal_style.line_height:
            spacing.set(w('line'), str(self.line_height))
            spacing.set(w('lineRule'), 'atLeast')

        if spacing.attrib:
            pPr.append(spacing)

        ind = makeelement(pPr, 'ind')
        for edge in ('left', 'right'):
            getter = attrgetter('css_margin_' + edge)
            css_val, css_unit = parse_css_length(getter(self))
            if css_unit in ('em', 'ex'):
                chars = max(0, int(css_val * (50 if css_unit == 'ex' else 100)))
                if (self is normal_style and chars > 0) or getter(self) != getter(normal_style):
                    ind.set(w(edge + 'Chars'), str(chars))
            else:
                getter = attrgetter('margin_' + edge)
                val = getter(self)
                if (self is normal_style and val > 0) or val != getter(normal_style):
                    ind.set(w(edge), str(val))
                    ind.set(w(edge + 'Chars'), '0')  # This is needed to override any declaration in the parent style
        css_val, css_unit = parse_css_length(self.css_text_indent)
        if css_unit in ('em', 'ex'):
            chars = int(css_val * (50 if css_unit == 'ex' else 100))
            if css_val >= 0:
                if (self is normal_style and chars > 0) or self.css_text_indent != normal_style.css_text_indent:
                    ind.set(w('firstLineChars'), str(chars))
            else:
                if (self is normal_style and chars < 0) or self.css_text_indent != normal_style.css_text_indent:
                    ind.set(w('hangingChars'), str(abs(chars)))
        else:
            val = self.text_indent
            if val >= 0:
                if (self is normal_style and val > 0) or self.text_indent != normal_style.text_indent:
                    ind.set(w('firstLine'), str(val))
                    ind.set(w('firstLineChars'), '0')  # This is needed to override any declaration in the parent style
            else:
                if (self is normal_style and val < 0) or self.text_indent != normal_style.text_indent:
                    ind.set(w('hanging'), str(abs(val)))
                    ind.set(w('hangingChars'), '0')
        if ind.attrib:
            pPr.append(ind)

        if (self is normal_style and self.background_color) or self.background_color != normal_style.background_color:
            pPr.append(makeelement(pPr, 'shd', val='clear', color='auto', fill=self.background_color or 'auto'))

        pbdr = self.serialize_borders(pPr.makeelement(w('pBdr')), normal_style)
        if len(pbdr):
            pPr.append(pbdr)

        if self is normal_style or self.text_align != normal_style.text_align:
            pPr.append(makeelement(pPr, 'jc', val=self.text_align))

        if self is not normal_style and self.next_style is not None:
            pPr.append(makeelement(pPr, 'next', val=self.next_style))