mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
DOCX: Add support for theme fonts
This commit is contained in:
parent
19cb39873c
commit
bd9bb1bad8
@ -117,8 +117,12 @@ def read_vert_align(parent, dest):
|
|||||||
|
|
||||||
def read_font_family(parent, dest):
|
def read_font_family(parent, dest):
|
||||||
ans = inherit
|
ans = inherit
|
||||||
for col in XPath('./w:rFonts[@w:ascii]')(parent):
|
for col in XPath('./w:rFonts')(parent):
|
||||||
val = get(col, 'w:ascii')
|
val = get(col, 'w:asciiTheme')
|
||||||
|
if val:
|
||||||
|
val = '|%s|' % val
|
||||||
|
else:
|
||||||
|
val = get(col, 'w:ascii')
|
||||||
if val:
|
if val:
|
||||||
ans = val
|
ans = val
|
||||||
setattr(dest, 'font_family', ans)
|
setattr(dest, 'font_family', ans)
|
||||||
|
@ -22,6 +22,7 @@ IMAGES = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships
|
|||||||
LINKS = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink'
|
LINKS = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink'
|
||||||
FOOTNOTES = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes'
|
FOOTNOTES = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes'
|
||||||
ENDNOTES = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes'
|
ENDNOTES = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes'
|
||||||
|
THEMES = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme'
|
||||||
|
|
||||||
namespaces = {
|
namespaces = {
|
||||||
'mo': 'http://schemas.microsoft.com/office/mac/office/2008/main',
|
'mo': 'http://schemas.microsoft.com/office/mac/office/2008/main',
|
||||||
|
@ -142,8 +142,8 @@ class Styles(object):
|
|||||||
def get(self, key, default=None):
|
def get(self, key, default=None):
|
||||||
return self.id_map.get(key, default)
|
return self.id_map.get(key, default)
|
||||||
|
|
||||||
def __call__(self, root, fonts):
|
def __call__(self, root, fonts, theme):
|
||||||
self.fonts = fonts
|
self.fonts, self.theme = fonts, theme
|
||||||
for s in XPath('//w:style')(root):
|
for s in XPath('//w:style')(root):
|
||||||
s = Style(s)
|
s = Style(s)
|
||||||
if s.style_id:
|
if s.style_id:
|
||||||
@ -304,7 +304,8 @@ class Styles(object):
|
|||||||
setattr(ans, attr, self.run_val(parent_styles, direct_formatting, attr))
|
setattr(ans, attr, self.run_val(parent_styles, direct_formatting, attr))
|
||||||
|
|
||||||
if ans.font_family is not inherit:
|
if ans.font_family is not inherit:
|
||||||
ans.font_family = self.fonts.family_for(ans.font_family, ans.b, ans.i)
|
ff = self.theme.resolve_font_family(ans.font_family)
|
||||||
|
ans.font_family = self.fonts.family_for(ff, ans.b, ans.i)
|
||||||
|
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
|
31
src/calibre/ebooks/docx/theme.py
Normal file
31
src/calibre/ebooks/docx/theme.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# vim:fileencoding=utf-8
|
||||||
|
from __future__ import (unicode_literals, division, absolute_import,
|
||||||
|
print_function)
|
||||||
|
|
||||||
|
__license__ = 'GPL v3'
|
||||||
|
__copyright__ = '2013, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||||
|
|
||||||
|
from calibre.ebooks.docx.names import XPath
|
||||||
|
|
||||||
|
|
||||||
|
class Theme(object):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.major_latin_font = 'Cambria'
|
||||||
|
self.minor_latin_font = 'Calibri'
|
||||||
|
|
||||||
|
def __call__(self, root):
|
||||||
|
for fs in XPath('//a:fontScheme')(root):
|
||||||
|
for mj in XPath('./a:majorFont')(fs):
|
||||||
|
for l in XPath('./a:latin[@typeface]')(mj):
|
||||||
|
self.major_latin_font = l.get('typeface')
|
||||||
|
for mj in XPath('./a:minorFont')(fs):
|
||||||
|
for l in XPath('./a:latin[@typeface]')(mj):
|
||||||
|
self.minor_latin_font = l.get('typeface')
|
||||||
|
|
||||||
|
def resolve_font_family(self, ff):
|
||||||
|
if ff.startswith('|'):
|
||||||
|
ff = ff[1:-1]
|
||||||
|
ff = self.major_latin_font if ff.startswith('major') else self.minor_latin_font
|
||||||
|
return ff
|
@ -16,7 +16,7 @@ from lxml.html.builder import (
|
|||||||
from calibre.ebooks.docx.container import DOCX, fromstring
|
from calibre.ebooks.docx.container import DOCX, fromstring
|
||||||
from calibre.ebooks.docx.names import (
|
from calibre.ebooks.docx.names import (
|
||||||
XPath, is_tag, XML, STYLES, NUMBERING, FONTS, get, generate_anchor,
|
XPath, is_tag, XML, STYLES, NUMBERING, FONTS, get, generate_anchor,
|
||||||
descendants, FOOTNOTES, ENDNOTES, children)
|
descendants, FOOTNOTES, ENDNOTES, children, THEMES)
|
||||||
from calibre.ebooks.docx.styles import Styles, inherit, PageProperties
|
from calibre.ebooks.docx.styles import Styles, inherit, PageProperties
|
||||||
from calibre.ebooks.docx.numbering import Numbering
|
from calibre.ebooks.docx.numbering import Numbering
|
||||||
from calibre.ebooks.docx.fonts import Fonts
|
from calibre.ebooks.docx.fonts import Fonts
|
||||||
@ -24,6 +24,7 @@ from calibre.ebooks.docx.images import Images
|
|||||||
from calibre.ebooks.docx.tables import Tables
|
from calibre.ebooks.docx.tables import Tables
|
||||||
from calibre.ebooks.docx.footnotes import Footnotes
|
from calibre.ebooks.docx.footnotes import Footnotes
|
||||||
from calibre.ebooks.docx.cleanup import cleanup_markup
|
from calibre.ebooks.docx.cleanup import cleanup_markup
|
||||||
|
from calibre.ebooks.docx.theme import Theme
|
||||||
from calibre.ebooks.metadata.opf2 import OPFCreator
|
from calibre.ebooks.metadata.opf2 import OPFCreator
|
||||||
from calibre.ebooks.metadata.toc import TOC
|
from calibre.ebooks.metadata.toc import TOC
|
||||||
from calibre.ebooks.oeb.polish.toc import elem_to_toc_text
|
from calibre.ebooks.oeb.polish.toc import elem_to_toc_text
|
||||||
@ -49,6 +50,7 @@ class Convert(object):
|
|||||||
self.dest_dir = dest_dir or os.getcwdu()
|
self.dest_dir = dest_dir or os.getcwdu()
|
||||||
self.mi = self.docx.metadata
|
self.mi = self.docx.metadata
|
||||||
self.body = BODY()
|
self.body = BODY()
|
||||||
|
self.theme = Theme()
|
||||||
self.tables = Tables()
|
self.tables = Tables()
|
||||||
self.styles = Styles(self.tables)
|
self.styles = Styles(self.tables)
|
||||||
self.images = Images()
|
self.images = Images()
|
||||||
@ -203,6 +205,7 @@ class Convert(object):
|
|||||||
nname = get_name(NUMBERING, 'numbering.xml')
|
nname = get_name(NUMBERING, 'numbering.xml')
|
||||||
sname = get_name(STYLES, 'styles.xml')
|
sname = get_name(STYLES, 'styles.xml')
|
||||||
fname = get_name(FONTS, 'fontTable.xml')
|
fname = get_name(FONTS, 'fontTable.xml')
|
||||||
|
tname = get_name(THEMES, 'theme1.xml')
|
||||||
foname = get_name(FOOTNOTES, 'footnotes.xml')
|
foname = get_name(FOOTNOTES, 'footnotes.xml')
|
||||||
enname = get_name(ENDNOTES, 'endnotes.xml')
|
enname = get_name(ENDNOTES, 'endnotes.xml')
|
||||||
numbering = self.numbering = Numbering()
|
numbering = self.numbering = Numbering()
|
||||||
@ -231,13 +234,21 @@ class Convert(object):
|
|||||||
else:
|
else:
|
||||||
fonts(fromstring(raw), embed_relationships, self.docx, self.dest_dir)
|
fonts(fromstring(raw), embed_relationships, self.docx, self.dest_dir)
|
||||||
|
|
||||||
|
if tname is not None:
|
||||||
|
try:
|
||||||
|
raw = self.docx.read(tname)
|
||||||
|
except KeyError:
|
||||||
|
self.log.warn('Styles %s do not exist' % sname)
|
||||||
|
else:
|
||||||
|
self.theme(fromstring(raw))
|
||||||
|
|
||||||
if sname is not None:
|
if sname is not None:
|
||||||
try:
|
try:
|
||||||
raw = self.docx.read(sname)
|
raw = self.docx.read(sname)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
self.log.warn('Styles %s do not exist' % sname)
|
self.log.warn('Styles %s do not exist' % sname)
|
||||||
else:
|
else:
|
||||||
self.styles(fromstring(raw), fonts)
|
self.styles(fromstring(raw), fonts, self.theme)
|
||||||
|
|
||||||
if nname is not None:
|
if nname is not None:
|
||||||
try:
|
try:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user