%PDF- %PDF-
Direktori : /usr/lib/calibre/calibre/ebooks/docx/ |
Current File : //usr/lib/calibre/calibre/ebooks/docx/char_styles.py |
#!/usr/bin/env python3 __license__ = 'GPL v3' __copyright__ = '2013, Kovid Goyal <kovid at kovidgoyal.net>' from collections import OrderedDict from calibre.ebooks.docx.block_styles import ( # noqa inherit, simple_color, LINE_STYLES, simple_float, binary_property, read_shd) # Read from XML {{{ def read_text_border(parent, dest, XPath, get): border_color = border_style = border_width = padding = inherit elems = XPath('./w:bdr')(parent) if elems and elems[0].attrib: border_color = simple_color('auto') border_style = 'none' border_width = 1 for elem in elems: color = get(elem, 'w:color') if color is not None: border_color = simple_color(color) style = get(elem, 'w:val') if style is not None: border_style = LINE_STYLES.get(style, 'solid') space = get(elem, 'w:space') if space is not None: try: padding = float(space) except (ValueError, TypeError): pass sz = get(elem, 'w:sz') if sz is not None: # we dont care about art borders (they are only used for page borders) try: # A border of less than 1pt is not rendered by WebKit border_width = min(96, max(8, float(sz))) / 8 except (ValueError, TypeError): pass setattr(dest, 'border_color', border_color) setattr(dest, 'border_style', border_style) setattr(dest, 'border_width', border_width) setattr(dest, 'padding', padding) def read_color(parent, dest, XPath, get): ans = inherit for col in XPath('./w:color[@w:val]')(parent): val = get(col, 'w:val') if not val: continue ans = simple_color(val) setattr(dest, 'color', ans) def convert_highlight_color(val): return { 'darkBlue': '#000080', 'darkCyan': '#008080', 'darkGray': '#808080', 'darkGreen': '#008000', 'darkMagenta': '#800080', 'darkRed': '#800000', 'darkYellow': '#808000', 'lightGray': '#c0c0c0'}.get(val, val) def read_highlight(parent, dest, XPath, get): ans = inherit for col in XPath('./w:highlight[@w:val]')(parent): val = get(col, 'w:val') if not val: continue if not val or val == 'none': val = 'transparent' else: val = convert_highlight_color(val) ans = val setattr(dest, 'highlight', ans) def read_lang(parent, dest, XPath, get): ans = inherit for col in XPath('./w:lang[@w:val]')(parent): val = get(col, 'w:val') if not val: continue try: code = int(val, 16) except (ValueError, TypeError): ans = val else: from calibre.ebooks.docx.lcid import lcid val = lcid.get(code, None) if val: ans = val setattr(dest, 'lang', ans) def read_letter_spacing(parent, dest, XPath, get): ans = inherit for col in XPath('./w:spacing[@w:val]')(parent): val = simple_float(get(col, 'w:val'), 0.05) if val is not None: ans = val setattr(dest, 'letter_spacing', ans) def read_underline(parent, dest, XPath, get): ans = inherit for col in XPath('./w:u[@w:val]')(parent): val = get(col, 'w:val') if val: ans = val if val == 'none' else 'underline' setattr(dest, 'text_decoration', ans) def read_vert_align(parent, dest, XPath, get): ans = inherit for col in XPath('./w:vertAlign[@w:val]')(parent): val = get(col, 'w:val') if val and val in {'baseline', 'subscript', 'superscript'}: ans = val setattr(dest, 'vert_align', ans) def read_position(parent, dest, XPath, get): ans = inherit for col in XPath('./w:position[@w:val]')(parent): val = get(col, 'w:val') try: ans = float(val)/2.0 except Exception: pass setattr(dest, 'position', ans) def read_font(parent, dest, XPath, get): ff = inherit for col in XPath('./w:rFonts')(parent): val = get(col, 'w:asciiTheme') if val: val = '|%s|' % val else: val = get(col, 'w:ascii') if val: ff = val setattr(dest, 'font_family', ff) for col in XPath('./w:sz[@w:val]')(parent): val = simple_float(get(col, 'w:val'), 0.5) if val is not None: setattr(dest, 'font_size', val) return setattr(dest, 'font_size', inherit) def read_font_cs(parent, dest, XPath, get): ff = inherit for col in XPath('./w:rFonts')(parent): val = get(col, 'w:csTheme') if val: val = '|%s|' % val else: val = get(col, 'w:cs') if val: ff = val setattr(dest, 'cs_font_family', ff) for col in XPath('./w:szCS[@w:val]')(parent): val = simple_float(get(col, 'w:val'), 0.5) if val is not None: setattr(dest, 'font_size', val) return setattr(dest, 'cs_font_size', inherit) # }}} class RunStyle: all_properties = { 'b', 'bCs', 'caps', 'cs', 'dstrike', 'emboss', 'i', 'iCs', 'imprint', 'rtl', 'shadow', 'smallCaps', 'strike', 'vanish', 'webHidden', 'border_color', 'border_style', 'border_width', 'padding', 'color', 'highlight', 'background_color', 'letter_spacing', 'font_size', 'text_decoration', 'vert_align', 'lang', 'font_family', 'position', 'cs_font_size', 'cs_font_family' } toggle_properties = { 'b', 'bCs', 'caps', 'emboss', 'i', 'iCs', 'imprint', 'shadow', 'smallCaps', 'strike', 'vanish', } def __init__(self, namespace, rPr=None): self.namespace = namespace self.linked_style = None if rPr is None: for p in self.all_properties: setattr(self, p, inherit) else: X, g = namespace.XPath, namespace.get for p in ( 'b', 'bCs', 'caps', 'cs', 'dstrike', 'emboss', 'i', 'iCs', 'imprint', 'rtl', 'shadow', 'smallCaps', 'strike', 'vanish', 'webHidden', ): setattr(self, p, binary_property(rPr, p, X, g)) read_font(rPr, self, X, g) read_font_cs(rPr, self, X, g) read_text_border(rPr, self, X, g) read_color(rPr, self, X, g) read_highlight(rPr, self, X, g) read_shd(rPr, self, X, g) read_letter_spacing(rPr, self, X, g) read_underline(rPr, self, X, g) read_vert_align(rPr, self, X, g) read_position(rPr, self, X, g) read_lang(rPr, self, X, g) for s in X('./w:rStyle[@w:val]')(rPr): self.linked_style = g(s, 'w:val') self._css = None def update(self, other): for prop in self.all_properties: nval = getattr(other, prop) if nval is not inherit: setattr(self, prop, nval) if other.linked_style is not None: self.linked_style = other.linked_style def resolve_based_on(self, parent): for p in self.all_properties: val = getattr(self, p) if val is inherit: setattr(self, p, getattr(parent, p)) def get_border_css(self, ans): for x in ('color', 'style', 'width'): val = getattr(self, 'border_'+x) if x == 'width' and val is not inherit: val = '%.3gpt' % val if val is not inherit: ans['border-%s' % x] = val def clear_border_css(self): for x in ('color', 'style', 'width'): setattr(self, 'border_'+x, inherit) @property def css(self): if self._css is None: c = self._css = OrderedDict() td = set() if self.text_decoration is not inherit: td.add(self.text_decoration) if self.strike and self.strike is not inherit: td.add('line-through') if self.dstrike and self.dstrike is not inherit: td.add('line-through') if td: c['text-decoration'] = ' '.join(td) if self.caps is True: c['text-transform'] = 'uppercase' if self.i is True: c['font-style'] = 'italic' if self.shadow and self.shadow is not inherit: c['text-shadow'] = '2px 2px' if self.smallCaps is True: c['font-variant'] = 'small-caps' if self.vanish is True or self.webHidden is True: c['display'] = 'none' self.get_border_css(c) if self.padding is not inherit: c['padding'] = '%.3gpt' % self.padding for x in ('color', 'background_color'): val = getattr(self, x) if val is not inherit: c[x.replace('_', '-')] = val for x in ('letter_spacing', 'font_size'): val = getattr(self, x) if val is not inherit: c[x.replace('_', '-')] = '%.3gpt' % val if self.position is not inherit: c['vertical-align'] = '%.3gpt' % self.position if self.highlight is not inherit and self.highlight != 'transparent': c['background-color'] = self.highlight if self.b: c['font-weight'] = 'bold' if self.font_family is not inherit: c['font-family'] = self.font_family return self._css def same_border(self, other): return self.get_border_css({}) == other.get_border_css({})