def serialize_border_edge(self, bdr, edge): width = getattr(self, 'border_%s_width' % edge) bstyle = getattr(self, 'border_%s_style' % edge) if width > 0 and bstyle != 'none': makeelement(bdr, 'w:' + edge, w_val=bstyle, w_sz=str(width), w_color=getattr(self, 'border_%s_color' % edge)) return True return False
def serialize(self, text_styles, fonts, embed_relationships, font_data_map): font_families, seen = set(), set() for ts in text_styles: if ts.font_family: lf = ts.font_family.lower() if lf not in seen: seen.add(lf) font_families.add(ts.font_family) family_map = {} for family in sorted(font_families): family_map[family] = makeelement(fonts, 'w:font', w_name=family) embedded_fonts = [] for item in self.oeb.manifest: if item.media_type in OEB_STYLES and hasattr( item.data, 'cssRules'): embedded_fonts.extend(find_font_face_rules(item, self.oeb)) num = 0 face_map = defaultdict(set) rel_map = {} for ef in embedded_fonts: ff = ef['font-family'][0] if ff not in font_families: continue num += 1 bold = ef['weight'] > 400 italic = ef['font-style'] != 'normal' tag = 'Regular' if bold or italic: tag = 'Italic' if bold and italic: tag = 'BoldItalic' elif bold: tag = 'Bold' if tag in face_map[ff]: continue face_map[ff].add(tag) font = family_map[ff] key = uuid4() item = ef['item'] rid = rel_map.get(item) if rid is None: rel_map[item] = rid = 'rId%d' % num fname = 'fonts/font%d.odttf' % num makeelement(embed_relationships, 'Relationship', Id=rid, Type=EMBEDDED_FONT, Target=fname) font_data_map['word/' + fname] = obfuscate_font_data( item.data, key) makeelement(font, 'w:embed' + tag, r_id=rid, w_fontKey='{%s}' % key.urn.rpartition(':')[-1].upper(), w_subsetted="true" if self.opts.subset_embedded_fonts else "false")
def serialize(self, parent): rows = [r for r in self.rows if r.cells] if not rows: return tbl = makeelement(parent, 'w:tbl') tblPr = makeelement(tbl, 'w:tblPr') tblPr for row in rows: row.serialize(tbl)
def serialize(self, text_styles, fonts, embed_relationships): font_families, seen = set(), set() for ts in text_styles: if ts.font_family: lf = ts.font_family.lower() if lf not in seen: seen.add(lf) font_families.add(ts.font_family) for family in sorted(font_families): makeelement(fonts, 'w:font', w_name=family)
def serialize(self, parent): tc = makeelement(parent, 'w:tc') tcPr = makeelement(tc, 'w:tcPr') makeelement(tcPr, 'w:tcW', w_type=self.width[0], w_w=str(self.width[1])) # For some reason, Word 2007 refuses to honor <w:shd> at the table or row # level, despite what the specs say, so we inherit and apply at the # cell level bc = self.background_color or self.row.background_color or self.row.table.background_color if bc: makeelement(tcPr, 'w:shd', w_val="clear", w_color="auto", w_fill=bc) b = makeelement(tcPr, 'w:tcBorders', append=False) for edge, border in self.borders.iteritems(): if border.width > 0 and border.style != 'none': makeelement(b, 'w:' + edge, w_val=border.style, w_sz=str(border.width), w_color=border.color) if len(b) > 0: tcPr.append(b) for item in self.items: item.serialize(tc)
def serialize(self, text_styles, fonts, embed_relationships, font_data_map): font_families, seen = set(), set() for ts in text_styles: if ts.font_family: lf = ts.font_family.lower() if lf not in seen: seen.add(lf) font_families.add(ts.font_family) family_map = {} for family in sorted(font_families): family_map[family] = makeelement(fonts, 'w:font', w_name=family) embedded_fonts = [] for item in self.oeb.manifest: if item.media_type in OEB_STYLES and hasattr(item.data, 'cssRules'): embedded_fonts.extend(find_font_face_rules(item, self.oeb)) num = 0 face_map = defaultdict(set) rel_map = {} for ef in embedded_fonts: ff = ef['font-family'][0] if ff not in font_families: continue num += 1 bold = ef['weight'] > 400 italic = ef['font-style'] != 'normal' tag = 'Regular' if bold or italic: tag = 'Italic' if bold and italic: tag = 'BoldItalic' elif bold: tag = 'Bold' if tag in face_map[ff]: continue face_map[ff].add(tag) font = family_map[ff] key = uuid4() item = ef['item'] rid = rel_map.get(item) if rid is None: rel_map[item] = rid = 'rId%d' % num fname = 'fonts/font%d.odttf' % num makeelement(embed_relationships, 'Relationship', Id=rid, Type=EMBEDDED_FONT, Target=fname) font_data_map['word/' + fname] = obfuscate_font_data(item.data, key) makeelement(font, 'w:embed' + tag, r_id=rid, w_fontKey='{%s}' % key.urn.rpartition(':')[-1].upper(), w_subsetted="true" if self.opts.subset_embedded_fonts else "false")
def serialize(self, tr): tc = makeelement(tr, 'w:tc') tcPr = makeelement(tc, 'w:tcPr') makeelement(tcPr, 'w:%sMerge' % ('h' if self.horizontal else 'v'), w_val='continue') makeelement(tc, 'w:p')
def serialize(self, parent): rows = [r for r in self.rows if r.cells] if not rows: return tbl = makeelement(parent, 'w:tbl') tblPr = makeelement(tbl, 'w:tblPr') makeelement(tblPr, 'w:tblW', w_type=self.width[0], w_w=str(self.width[1])) if self.jc is not None: makeelement(tblPr, 'w:jc', w_val=self.jc) for row in rows: row.serialize(tbl)
def serialize(self, parent): tc = makeelement(parent, 'w:tc') tcPr = makeelement(tc, 'w:tcPr') makeelement(tcPr, 'w:tcW', w_type=self.width[0], w_w=str(self.width[1])) # For some reason, Word 2007 refuses to honor <w:shd> at the table or row # level, despite what the specs say, so we inherit and apply at the # cell level bc = self.background_color or self.row.background_color or self.row.table.background_color if bc: makeelement(tcPr, 'w:shd', w_val="clear", w_color="auto", w_fill=bc) b = makeelement(tcPr, 'w:tcBorders', append=False) for edge, border in self.borders.iteritems(): if border.width > 0 and border.style != 'none': makeelement(b, 'w:' + edge, w_val=border.style, w_sz=str(border.width), w_color=border.color) if len(b) > 0: tcPr.append(b) m = makeelement(tcPr, 'w:tcMar', append=False) for edge in border_edges: padding = getattr(self, 'padding_' + edge) if edge in { 'top', 'bottom' } or (edge == 'left' and self is self.row.first_cell) or ( edge == 'right' and self is self.row.last_cell): padding += getattr(self.row, 'padding_' + edge) if padding > 0: makeelement(m, 'w:' + edge, w_type='dxa', w_w=str(int(padding * 20))) if len(m) > 0: tcPr.append(m) for item in self.items: item.serialize(tc)
def serialize(self, parent): tc = makeelement(parent, 'w:tc') for item in self.items: item.serialize(tc)
def serialize(self, parent): tr = makeelement(parent, 'w:tr') for cell in self.cells: cell.serialize(tr)
def serialize(self, parent): tc = makeelement(parent, 'w:tc') tcPr = makeelement(tc, 'w:tcPr') makeelement(tcPr, 'w:tcW', w_type=self.width[0], w_w=str(self.width[1])) # For some reason, Word 2007 refuses to honor <w:shd> at the table or row # level, despite what the specs say, so we inherit and apply at the # cell level bc = self.background_color or self.row.background_color or self.row.table.background_color if bc: makeelement(tcPr, 'w:shd', w_val="clear", w_color="auto", w_fill=bc) b = makeelement(tcPr, 'w:tcBorders', append=False) for edge, border in self.borders.iteritems(): if border.width > 0 and border.style != 'none': makeelement(b, 'w:' + edge, w_val=border.style, w_sz=str(border.width), w_color=border.color) if len(b) > 0: tcPr.append(b) m = makeelement(tcPr, 'w:tcMar', append=False) for edge in border_edges: padding = getattr(self, 'padding_' + edge) if edge in {'top', 'bottom'} or (edge == 'left' and self is self.row.first_cell) or (edge == 'right' and self is self.row.last_cell): padding += getattr(self.row, 'padding_' + edge) if padding > 0: makeelement(m, 'w:' + edge, w_type='dxa', w_w=str(int(padding * 20))) if len(m) > 0: tcPr.append(m) for item in self.items: item.serialize(tc)
def create_image_markup(self, html_img, stylizer, href): # TODO: img inside a link (clickable image) style = stylizer.style(html_img) floating = style['float'] if floating not in {'left', 'right'}: floating = None fake_margins = floating is None self.count += 1 img = self.images[href] name = urlunquote(posixpath.basename(href)) width, height = map(pt_to_emu, style.img_size(img.width, img.height)) root = etree.Element('root', nsmap=namespaces) ans = makeelement(root, 'w:drawing', append=False) if floating is None: parent = makeelement(ans, 'wp:inline') else: parent = makeelement(ans, 'wp:anchor', **get_image_margins(style)) # The next three lines are boilerplate that Word requires, even # though the DOCX specs define defaults for all of them parent.set('simplePos', '0'), parent.set('relativeHeight', '1'), parent.set( 'behindDoc', "0"), parent.set('locked', "0") parent.set('layoutInCell', "1"), parent.set('allowOverlap', '1') makeelement(parent, 'wp:simplePos', x='0', y='0') makeelement( makeelement(parent, 'wp:positionH', relativeFrom='margin'), 'wp:align').text = floating makeelement( makeelement(parent, 'wp:positionV', relativeFrom='line'), 'wp:align').text = 'top' makeelement(parent, 'wp:extent', cx=str(width), cy=str(width)) if fake_margins: # DOCX does not support setting margins for inline images, so we # fake it by using effect extents to simulate margins makeelement( parent, 'wp:effectExtent', **{ k[-1].lower(): v for k, v in get_image_margins(style).iteritems() }) else: makeelement(parent, 'wp:effectExtent', l='0', r='0', t='0', b='0') if floating is not None: # The idiotic Word requires this to be after the extent settings makeelement(parent, 'wp:wrapSquare', wrapText='bothSides') makeelement(parent, 'wp:docPr', id=str(self.count), name=name, descr=html_img.get('alt') or name) makeelement(makeelement(parent, 'wp:cNvGraphicFramePr'), 'a:graphicFrameLocks', noChangeAspect="1") g = makeelement(parent, 'a:graphic') gd = makeelement(g, 'a:graphicData', uri=namespaces['pic']) pic = makeelement(gd, 'pic:pic') nvPicPr = makeelement(pic, 'pic:nvPicPr') makeelement(nvPicPr, 'pic:cNvPr', id='0', name=name, descr=html_img.get('alt') or name) makeelement(nvPicPr, 'pic:cNvPicPr') bf = makeelement(pic, 'pic:blipFill') makeelement(bf, 'a:blip', r_embed=img.rid) makeelement(makeelement(bf, 'a:stretch'), 'a:fillRect') spPr = makeelement(pic, 'pic:spPr') xfrm = makeelement(spPr, 'a:xfrm') makeelement(xfrm, 'a:off', x='0', y='0'), makeelement(xfrm, 'a:ext', cx=str(width), cy=str(height)) makeelement(makeelement(spPr, 'a:prstGeom', prst='rect'), 'a:avLst') return ans