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))
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))
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)
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 )
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)
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 )