示例#1
0
    def test_transform_attrs(self):
        obj = self.D()
        container = {'attr': 19, 'attr1': 22}

        transform_attrs(obj, (
            ("param1", "attr"),
            ("param2", "attr1"),
        ), container, str)

        self.assertEqual(obj.param1, str(19))
        self.assertEqual(obj.param2, str(22))
示例#2
0
    def test_transform_attrs(self):
        obj = self.D()
        container = {'attr': 19, 'attr1': 22}

        transform_attrs(obj,
                        (
                            ("param1", "attr"),
                            ("param2", "attr1"),
                        ),
                        container,
                        str
                        )

        self.assertEqual(obj.param1, str(19))
        self.assertEqual(obj.param2, str(22))
示例#3
0
def pisaLoop(node, context, path=None, **kw):
    if path is None:
        path = []

    # Initialize KW
    if not kw:
        kw = {
            "margin-top": 0,
            "margin-bottom": 0,
            "margin-left": 0,
            "margin-right": 0,
        }
    else:
        kw = copy.copy(kw)

    # indent = len(path) * "  " # only used for debug print statements

    # TEXT
    if node.nodeType == Node.TEXT_NODE:
        # print indent, "#", repr(node.data) #, context.frag
        context.addFrag(node.data)

        # context.text.append(node.value)

    # ELEMENT
    elif node.nodeType == Node.ELEMENT_NODE:

        node.tagName = node.tagName.replace(":", "").lower()

        if node.tagName in ("style", "script"):
            return

        path = copy.copy(path) + [node.tagName]

        # Prepare attributes
        attr = pisaGetAttributes(context, node.tagName, node.attributes)
        # log.debug(indent + "<%s %s>" % (node.tagName, attr) +
        # repr(node.attributes.items())) #, path

        # Calculate styles
        context.cssAttr = CSSCollect(node, context)
        context.cssAttr = mapNonStandardAttrs(context.cssAttr, node, attr)
        context.node = node

        # Block?
        PAGE_BREAK = 1
        PAGE_BREAK_RIGHT = 2
        PAGE_BREAK_LEFT = 3

        pageBreakAfter = False
        frameBreakAfter = False
        display = lower(context.cssAttr.get("display", "inline"))
        # print indent, node.tagName, display,
        # context.cssAttr.get("background-color", None), attr
        isBlock = (display == "block")

        if isBlock:
            context.addPara()

            # Page break by CSS
            if "-pdf-next-page" in context.cssAttr:
                context.addStory(
                    NextPageTemplate(str(context.cssAttr["-pdf-next-page"])))
            if "-pdf-page-break" in context.cssAttr:
                if str(context.cssAttr["-pdf-page-break"]).lower() == "before":
                    context.addStory(PageBreak())
            if "-pdf-frame-break" in context.cssAttr:
                if str(context.cssAttr["-pdf-frame-break"]).lower() == "before":
                    context.addStory(FrameBreak())
                if str(context.cssAttr["-pdf-frame-break"]).lower() == "after":
                    frameBreakAfter = True
            if "page-break-before" in context.cssAttr:
                if str(context.cssAttr["page-break-before"]).lower() == "always":
                    context.addStory(PageBreak())
                if str(context.cssAttr["page-break-before"]).lower() == "right":
                    context.addStory(PageBreak())
                    context.addStory(PmlRightPageBreak())
                if str(context.cssAttr["page-break-before"]).lower() == "left":
                    context.addStory(PageBreak())
                    context.addStory(PmlLeftPageBreak())
            if "page-break-after" in context.cssAttr:
                if str(context.cssAttr["page-break-after"]).lower() == "always":
                    pageBreakAfter = PAGE_BREAK
                if str(context.cssAttr["page-break-after"]).lower() == "right":
                    pageBreakAfter = PAGE_BREAK_RIGHT
                if str(context.cssAttr["page-break-after"]).lower() == "left":
                    pageBreakAfter = PAGE_BREAK_LEFT

        if display == "none":
            # print "none!"
            return

        # Translate CSS to frags

        # Save previous frag styles
        context.pushFrag()

        # Map styles to Reportlab fragment properties
        CSS2Frag(context, kw, isBlock)

        # EXTRAS
        transform_attrs(context.frag,
                        (
                            ("keepWithNext", "-pdf-keep-with-next"),
                            ("outline", "-pdf-outline"),
                            ("borderLeftColor", "-pdf-outline-open"),
                        ),
                        context.cssAttr,
                        getBool
                        )

        if "-pdf-outline-level" in context.cssAttr:
            context.frag.outlineLevel = int(
                context.cssAttr["-pdf-outline-level"])

        if "-pdf-word-wrap" in context.cssAttr:
            context.frag.wordWrap = context.cssAttr["-pdf-word-wrap"]

        # handle keep-in-frame
        keepInFrameMode = None
        keepInFrameMaxWidth = 0
        keepInFrameMaxHeight = 0
        if "-pdf-keep-in-frame-mode" in context.cssAttr:
            value = str(
                context.cssAttr["-pdf-keep-in-frame-mode"]).strip().lower()
            if value in ("shrink", "error", "overflow", "truncate"):
                keepInFrameMode = value
            else:
                keepInFrameMode = "shrink"
            # Added because we need a default value.

        if "-pdf-keep-in-frame-max-width" in context.cssAttr:
            keepInFrameMaxWidth = getSize(
                "".join(context.cssAttr["-pdf-keep-in-frame-max-width"]))
        if "-pdf-keep-in-frame-max-height" in context.cssAttr:
            keepInFrameMaxHeight = getSize(
                "".join(context.cssAttr["-pdf-keep-in-frame-max-height"]))

        # ignore nested keep-in-frames, tables have their own KIF handling
        keepInFrame = keepInFrameMode is not None and context.keepInFrameIndex is None
        if keepInFrame:
            # keep track of current story index, so we can wrap everythink
            # added after this point in a KeepInFrame
            context.keepInFrameIndex = len(context.story)

        # BEGIN tag
        klass = globals().get("pisaTag%s" %
                              node.tagName.replace(":", "").upper(), None)
        obj = None

        # Static block
        elementId = attr.get("id", None)
        staticFrame = context.frameStatic.get(elementId, None)
        if staticFrame:
            context.frag.insideStaticFrame += 1
            oldStory = context.swapStory()

        # Tag specific operations
        if klass is not None:
            obj = klass(node, attr)
            obj.start(context)

        # Visit child nodes
        context.fragBlock = fragBlock = copy.copy(context.frag)
        for nnode in node.childNodes:
            pisaLoop(nnode, context, path, **kw)
        context.fragBlock = fragBlock

        # END tag
        if obj:
            obj.end(context)

        # Block?
        if isBlock:
            context.addPara()

            # XXX Buggy!

            # Page break by CSS
            if pageBreakAfter:
                context.addStory(PageBreak())
                if pageBreakAfter == PAGE_BREAK_RIGHT:
                    context.addStory(PmlRightPageBreak())
                if pageBreakAfter == PAGE_BREAK_LEFT:
                    context.addStory(PmlLeftPageBreak())
            if frameBreakAfter:
                context.addStory(FrameBreak())

        if keepInFrame:
            # get all content added after start of -pdf-keep-in-frame and wrap
            # it in a KeepInFrame
            substory = context.story[context.keepInFrameIndex:]
            context.story = context.story[:context.keepInFrameIndex]
            context.story.append(
                KeepInFrame(
                    content=substory,
                    maxWidth=keepInFrameMaxWidth,
                    maxHeight=keepInFrameMaxHeight,
                    mode=keepInFrameMode))
            # mode wasn't being used; it is necessary for tables or images at
            # end of page.
            context.keepInFrameIndex = None

        # Static block, END
        if staticFrame:
            context.addPara()
            for frame in staticFrame:
                frame.pisaStaticStory = context.story
            context.swapStory(oldStory)
            context.frag.insideStaticFrame -= 1

        # context.debug(1, indent, "</%s>" % (node.tagName))

        # Reset frag style
        context.pullFrag()

    # Unknown or not handled
    else:
        # context.debug(1, indent, "???", node, node.nodeType, repr(node))
        # Loop over children
        for node in node.childNodes:
            pisaLoop(node, context, path, **kw)
示例#4
0
def CSS2Frag(c, kw, isBlock):
    # COLORS
    if "color" in c.cssAttr:
        c.frag.textColor = getColor(c.cssAttr["color"])
    if "background-color" in c.cssAttr:
        c.frag.backColor = getColor(c.cssAttr["background-color"])
        # FONT SIZE, STYLE, WEIGHT
    if "font-family" in c.cssAttr:
        c.frag.fontName = c.getFontName(c.cssAttr["font-family"])
    if "font-size" in c.cssAttr:
        # XXX inherit
        c.frag.fontSize = max(
            getSize("".join(c.cssAttr["font-size"]), c.frag.fontSize, c.baseFontSize), 1.0)
    if "line-height" in c.cssAttr:
        leading = "".join(c.cssAttr["line-height"])
        c.frag.leading = getSize(leading, c.frag.fontSize)
        c.frag.leadingSource = leading
    else:
        c.frag.leading = getSize(c.frag.leadingSource, c.frag.fontSize)
    if "letter-spacing" in c.cssAttr:
        c.frag.letterSpacing = c.cssAttr["letter-spacing"]
    if "-pdf-line-spacing" in c.cssAttr:
        c.frag.leadingSpace = getSize("".join(c.cssAttr["-pdf-line-spacing"]))
        # print "line-spacing", c.cssAttr["-pdf-line-spacing"], c.frag.leading
    if "font-weight" in c.cssAttr:
        value = lower(c.cssAttr["font-weight"])
        if value in ("bold", "bolder", "500", "600", "700", "800", "900"):
            c.frag.bold = 1
        else:
            c.frag.bold = 0
    for value in toList(c.cssAttr.get("text-decoration", "")):
        if "underline" in value:
            c.frag.underline = 1
        if "line-through" in value:
            c.frag.strike = 1
        if "none" in value:
            c.frag.underline = 0
            c.frag.strike = 0
    if "font-style" in c.cssAttr:
        value = lower(c.cssAttr["font-style"])
        if value in ("italic", "oblique"):
            c.frag.italic = 1
        else:
            c.frag.italic = 0
    if "white-space" in c.cssAttr:
        # normal | pre | nowrap
        c.frag.whiteSpace = str(c.cssAttr["white-space"]).lower()
        # ALIGN & VALIGN
    if "text-align" in c.cssAttr:
        c.frag.alignment = getAlign(c.cssAttr["text-align"])
    if "vertical-align" in c.cssAttr:
        c.frag.vAlign = c.cssAttr["vertical-align"]
        # HEIGHT & WIDTH
    if "height" in c.cssAttr:
        try:
            # XXX Relative is not correct!
            c.frag.height = "".join(toList(c.cssAttr["height"]))
        except TypeError:
            # sequence item 0: expected string, tuple found
            c.frag.height = "".join(toList(c.cssAttr["height"][0]))
        if c.frag.height in ("auto",):
            c.frag.height = None
    if "width" in c.cssAttr:
        try:
            # XXX Relative is not correct!
            c.frag.width = "".join(toList(c.cssAttr["width"]))
        except TypeError:
            c.frag.width = "".join(toList(c.cssAttr["width"][0]))
        if c.frag.width in ("auto",):
            c.frag.width = None
        # ZOOM
    if "zoom" in c.cssAttr:
        # XXX Relative is not correct!
        zoom = "".join(toList(c.cssAttr["zoom"]))
        if zoom.endswith("%"):
            zoom = float(zoom[: - 1]) / 100.0
        c.frag.zoom = float(zoom)
        # MARGINS & LIST INDENT, STYLE
    if isBlock:
        transform_attrs(c.frag,
                        (("spaceBefore", "margin-top"),
                         ("spaceAfter", "margin-bottom"),
                         ("firstLineIndent", "text-indent"),
                         ),
                        c.cssAttr,
                        getSize,
                        extras=c.frag.fontSize
                        )

        if "margin-left" in c.cssAttr:
            c.frag.bulletIndent = kw["margin-left"]  # For lists
            kw["margin-left"] += getSize(c.cssAttr["margin-left"],
                                         c.frag.fontSize)
            c.frag.leftIndent = kw["margin-left"]
        if "margin-right" in c.cssAttr:
            kw["margin-right"] += getSize(
                c.cssAttr["margin-right"], c.frag.fontSize)
            c.frag.rightIndent = kw["margin-right"]

        if "list-style-type" in c.cssAttr:
            c.frag.listStyleType = str(c.cssAttr["list-style-type"]).lower()
        if "list-style-image" in c.cssAttr:
            c.frag.listStyleImage = c.getFile(c.cssAttr["list-style-image"])
        # PADDINGS
    if isBlock:
        transform_attrs(c.frag,
                        (("paddingTop", "padding-top"),
                         ("paddingBottom", "padding-bottom"),
                         ("paddingLeft", "padding-left"),
                         ("paddingRight", "padding-right"),
                         ),
                        c.cssAttr,
                        getSize,
                        extras=c.frag.fontSize
                        )

        # BORDERS
    if isBlock:
        transform_attrs(c.frag,
                        (("borderTopWidth", "border-top-width"),
                         ("borderBottomWidth", "border-bottom-width"),
                         ("borderLeftWidth", "border-left-width"),
                         ("borderRightWidth", "border-right-width"),
                         ),
                        c.cssAttr,
                        getSize,
                        extras=c.frag.fontSize
                        )
        transform_attrs(c.frag,
                        (
                            ("borderTopStyle", "border-top-style"),
                            ("borderBottomStyle", "border-bottom-style"),
                            ("borderLeftStyle", "border-left-style"),
                            ("borderRightStyle", "border-right-style")
                        ),
                        c.cssAttr,
                        lambda x: x
                        )

        transform_attrs(c.frag,
                        (
                            ("borderTopColor", "border-top-color"),
                            ("borderBottomColor", "border-bottom-color"),
                            ("borderLeftColor", "border-left-color"),
                            ("borderRightColor",  "border-right-color")
                        ),
                        c.cssAttr,
                        getColor
                        )
示例#5
0
def pisaLoop(node, context, path=None, **kw):
    if path is None:
        path = []

    # Initialize KW
    if not kw:
        kw = {
            "margin-top": 0,
            "margin-bottom": 0,
            "margin-left": 0,
            "margin-right": 0,
        }
    else:
        kw = copy.copy(kw)

    # indent = len(path) * "  " # only used for debug print statements

    # TEXT
    if node.nodeType == Node.TEXT_NODE:
        # print indent, "#", repr(node.data) #, context.frag
        context.addFrag(node.data)

        # context.text.append(node.value)

    # ELEMENT
    elif node.nodeType == Node.ELEMENT_NODE:

        node.tagName = node.tagName.replace(":", "").lower()

        if node.tagName in ("style", "script"):
            return

        path = copy.copy(path) + [node.tagName]

        # Prepare attributes
        attr = pisaGetAttributes(context, node.tagName, node.attributes)
        # log.debug(indent + "<%s %s>" % (node.tagName, attr) +
        # repr(node.attributes.items())) #, path

        # Calculate styles
        context.cssAttr = CSSCollect(node, context)
        context.cssAttr = mapNonStandardAttrs(context.cssAttr, node, attr)
        context.node = node

        # Block?
        PAGE_BREAK = 1
        PAGE_BREAK_RIGHT = 2
        PAGE_BREAK_LEFT = 3

        pageBreakAfter = False
        frameBreakAfter = False
        display = lower(context.cssAttr.get("display", "inline"))
        # print indent, node.tagName, display,
        # context.cssAttr.get("background-color", None), attr
        isBlock = (display == "block")

        if isBlock:
            context.addPara()

            # Page break by CSS
            if "-pdf-next-page" in context.cssAttr:
                context.addStory(
                    NextPageTemplate(str(context.cssAttr["-pdf-next-page"])))
            if "-pdf-page-break" in context.cssAttr:
                if str(context.cssAttr["-pdf-page-break"]).lower() == "before":
                    context.addStory(PageBreak())
            if "-pdf-frame-break" in context.cssAttr:
                if str(context.cssAttr["-pdf-frame-break"]).lower() == "before":
                    context.addStory(FrameBreak())
                if str(context.cssAttr["-pdf-frame-break"]).lower() == "after":
                    frameBreakAfter = True
            if "page-break-before" in context.cssAttr:
                if str(context.cssAttr["page-break-before"]).lower() == "always":
                    context.addStory(PageBreak())
                if str(context.cssAttr["page-break-before"]).lower() == "right":
                    context.addStory(PageBreak())
                    context.addStory(PmlRightPageBreak())
                if str(context.cssAttr["page-break-before"]).lower() == "left":
                    context.addStory(PageBreak())
                    context.addStory(PmlLeftPageBreak())
            if "page-break-after" in context.cssAttr:
                if str(context.cssAttr["page-break-after"]).lower() == "always":
                    pageBreakAfter = PAGE_BREAK
                if str(context.cssAttr["page-break-after"]).lower() == "right":
                    pageBreakAfter = PAGE_BREAK_RIGHT
                if str(context.cssAttr["page-break-after"]).lower() == "left":
                    pageBreakAfter = PAGE_BREAK_LEFT

        if display == "none":
            # print "none!"
            return

        # Translate CSS to frags

        # Save previous frag styles
        context.pushFrag()

        # Map styles to Reportlab fragment properties
        CSS2Frag(context, kw, isBlock)

        # EXTRAS
        transform_attrs(context.frag,
                        (
                            ("keepWithNext", "-pdf-keep-with-next"),
                            ("outline", "-pdf-outline"),
                            ("borderLeftColor", "-pdf-outline-open"),
                        ),
                        context.cssAttr,
                        getBool
                        )

        if "-pdf-outline-level" in context.cssAttr:
            context.frag.outlineLevel = int(
                context.cssAttr["-pdf-outline-level"])

        if "-pdf-word-wrap" in context.cssAttr:
            context.frag.wordWrap = context.cssAttr["-pdf-word-wrap"]

        # handle keep-in-frame
        keepInFrameMode = None
        keepInFrameMaxWidth = 0
        keepInFrameMaxHeight = 0
        if "-pdf-keep-in-frame-mode" in context.cssAttr:
            value = str(
                context.cssAttr["-pdf-keep-in-frame-mode"]).strip().lower()
            if value in ("shrink", "error", "overflow", "truncate"):
                keepInFrameMode = value
            else:
                keepInFrameMode = "shrink"
            # Added because we need a default value.

        if "-pdf-keep-in-frame-max-width" in context.cssAttr:
            keepInFrameMaxWidth = getSize(
                "".join(context.cssAttr["-pdf-keep-in-frame-max-width"]))
        if "-pdf-keep-in-frame-max-height" in context.cssAttr:
            keepInFrameMaxHeight = getSize(
                "".join(context.cssAttr["-pdf-keep-in-frame-max-height"]))

        # ignore nested keep-in-frames, tables have their own KIF handling
        keepInFrame = keepInFrameMode is not None and context.keepInFrameIndex is None
        if keepInFrame:
            # keep track of current story index, so we can wrap everythink
            # added after this point in a KeepInFrame
            context.keepInFrameIndex = len(context.story)

        # BEGIN tag
        klass = globals().get("pisaTag%s" %
                              node.tagName.replace(":", "").upper(), None)
        obj = None

        # Static block
        elementId = attr.get("id", None)
        staticFrame = context.frameStatic.get(elementId, None)
        if staticFrame:
            context.frag.insideStaticFrame += 1
            oldStory = context.swapStory()

        # Tag specific operations
        if klass is not None:
            obj = klass(node, attr)
            obj.start(context)

        # Visit child nodes
        context.fragBlock = fragBlock = copy.copy(context.frag)
        for nnode in node.childNodes:
            pisaLoop(nnode, context, path, **kw)
        context.fragBlock = fragBlock

        # END tag
        if obj:
            obj.end(context)

        # Block?
        if isBlock:
            context.addPara()

            # XXX Buggy!

            # Page break by CSS
            if pageBreakAfter:
                context.addStory(PageBreak())
                if pageBreakAfter == PAGE_BREAK_RIGHT:
                    context.addStory(PmlRightPageBreak())
                if pageBreakAfter == PAGE_BREAK_LEFT:
                    context.addStory(PmlLeftPageBreak())
            if frameBreakAfter:
                context.addStory(FrameBreak())

        if keepInFrame:
            # get all content added after start of -pdf-keep-in-frame and wrap
            # it in a KeepInFrame
            substory = context.story[context.keepInFrameIndex:]
            context.story = context.story[:context.keepInFrameIndex]
            context.story.append(
                KeepInFrame(
                    content=substory,
                    maxWidth=keepInFrameMaxWidth,
                    maxHeight=keepInFrameMaxHeight,
                    mode=keepInFrameMode))
            # mode wasn't being used; it is necessary for tables or images at
            # end of page.
            context.keepInFrameIndex = None

        # Static block, END
        if staticFrame:
            context.addPara()
            for frame in staticFrame:
                frame.pisaStaticStory = context.story
            context.swapStory(oldStory)
            context.frag.insideStaticFrame -= 1

        # context.debug(1, indent, "</%s>" % (node.tagName))

        # Reset frag style
        context.pullFrag()

    # Unknown or not handled
    else:
        # context.debug(1, indent, "???", node, node.nodeType, repr(node))
        # Loop over children
        for node in node.childNodes:
            pisaLoop(node, context, path, **kw)
示例#6
0
def CSS2Frag(c, kw, isBlock):
    # COLORS
    if "color" in c.cssAttr:
        c.frag.textColor = getColor(c.cssAttr["color"])
    if "background-color" in c.cssAttr:
        c.frag.backColor = getColor(c.cssAttr["background-color"])
        # FONT SIZE, STYLE, WEIGHT
    if "font-family" in c.cssAttr:
        c.frag.fontName = c.getFontName(c.cssAttr["font-family"])
    if "font-size" in c.cssAttr:
        # XXX inherit
        c.frag.fontSize = max(
            getSize("".join(c.cssAttr["font-size"]), c.frag.fontSize, c.baseFontSize), 1.0)
    if "line-height" in c.cssAttr:
        leading = "".join(c.cssAttr["line-height"])
        c.frag.leading = getSize(leading, c.frag.fontSize)
        c.frag.leadingSource = leading
    else:
        c.frag.leading = getSize(c.frag.leadingSource, c.frag.fontSize)
    if "letter-spacing" in c.cssAttr:
        c.frag.letterSpacing = c.cssAttr["letter-spacing"]
    if "-pdf-line-spacing" in c.cssAttr:
        c.frag.leadingSpace = getSize("".join(c.cssAttr["-pdf-line-spacing"]))
        # print "line-spacing", c.cssAttr["-pdf-line-spacing"], c.frag.leading
    if "font-weight" in c.cssAttr:
        value = lower(c.cssAttr["font-weight"])
        if value in ("bold", "bolder", "500", "600", "700", "800", "900"):
            c.frag.bold = 1
        else:
            c.frag.bold = 0
    for value in toList(c.cssAttr.get("text-decoration", "")):
        if "underline" in value:
            c.frag.underline = 1
        if "line-through" in value:
            c.frag.strike = 1
        if "none" in value:
            c.frag.underline = 0
            c.frag.strike = 0
    if "font-style" in c.cssAttr:
        value = lower(c.cssAttr["font-style"])
        if value in ("italic", "oblique"):
            c.frag.italic = 1
        else:
            c.frag.italic = 0
    if "white-space" in c.cssAttr:
        # normal | pre | nowrap
        c.frag.whiteSpace = str(c.cssAttr["white-space"]).lower()
        # ALIGN & VALIGN
    if "text-align" in c.cssAttr:
        c.frag.alignment = getAlign(c.cssAttr["text-align"])
    if "vertical-align" in c.cssAttr:
        c.frag.vAlign = c.cssAttr["vertical-align"]
        # HEIGHT & WIDTH
    if "height" in c.cssAttr:
        try:
            # XXX Relative is not correct!
            c.frag.height = "".join(toList(c.cssAttr["height"]))
        except TypeError:
            # sequence item 0: expected string, tuple found
            c.frag.height = "".join(toList(c.cssAttr["height"][0]))
        if c.frag.height in ("auto",):
            c.frag.height = None
    if "width" in c.cssAttr:
        try:
            # XXX Relative is not correct!
            c.frag.width = "".join(toList(c.cssAttr["width"]))
        except TypeError:
            c.frag.width = "".join(toList(c.cssAttr["width"][0]))
        if c.frag.width in ("auto",):
            c.frag.width = None
        # ZOOM
    if "zoom" in c.cssAttr:
        # XXX Relative is not correct!
        zoom = "".join(toList(c.cssAttr["zoom"]))
        if zoom.endswith("%"):
            zoom = float(zoom[: - 1]) / 100.0
        c.frag.zoom = float(zoom)
        # MARGINS & LIST INDENT, STYLE
    if isBlock:
        transform_attrs(c.frag,
                        (("spaceBefore", "margin-top"),
                         ("spaceAfter", "margin-bottom"),
                         ("firstLineIndent", "text-indent"),
                         ),
                        c.cssAttr,
                        getSize,
                        extras=c.frag.fontSize
                        )

        if "margin-left" in c.cssAttr:
            c.frag.bulletIndent = kw["margin-left"]  # For lists
            kw["margin-left"] += getSize(c.cssAttr["margin-left"],
                                         c.frag.fontSize)
            c.frag.leftIndent = kw["margin-left"]
        if "margin-right" in c.cssAttr:
            kw["margin-right"] += getSize(
                c.cssAttr["margin-right"], c.frag.fontSize)
            c.frag.rightIndent = kw["margin-right"]

        if "list-style-type" in c.cssAttr:
            c.frag.listStyleType = str(c.cssAttr["list-style-type"]).lower()
        if "list-style-image" in c.cssAttr:
            c.frag.listStyleImage = c.getFile(c.cssAttr["list-style-image"])
        # PADDINGS
    if isBlock:
        transform_attrs(c.frag,
                        (("paddingTop", "padding-top"),
                         ("paddingBottom", "padding-bottom"),
                         ("paddingLeft", "padding-left"),
                         ("paddingRight", "padding-right"),
                         ),
                        c.cssAttr,
                        getSize,
                        extras=c.frag.fontSize
                        )

        # BORDERS
    if isBlock:
        transform_attrs(c.frag,
                        (("borderTopWidth", "border-top-width"),
                         ("borderBottomWidth", "border-bottom-width"),
                         ("borderLeftWidth", "border-left-width"),
                         ("borderRightWidth", "border-right-width"),
                         ),
                        c.cssAttr,
                        getSize,
                        extras=c.frag.fontSize
                        )
        transform_attrs(c.frag,
                        (
                            ("borderTopStyle", "border-top-style"),
                            ("borderBottomStyle", "border-bottom-style"),
                            ("borderLeftStyle", "border-left-style"),
                            ("borderRightStyle", "border-right-style")
                        ),
                        c.cssAttr,
                        lambda x: x
                        )

        transform_attrs(c.frag,
                        (
                            ("borderTopColor", "border-top-color"),
                            ("borderBottomColor", "border-bottom-color"),
                            ("borderLeftColor", "border-left-color"),
                            ("borderRightColor",  "border-right-color")
                        ),
                        c.cssAttr,
                        getColor
                        )