diff --git a/src/calibre/ebooks/docx/fonts.py b/src/calibre/ebooks/docx/fonts.py index a196e0f070..6d766fd3c6 100644 --- a/src/calibre/ebooks/docx/fonts.py +++ b/src/calibre/ebooks/docx/fonts.py @@ -13,6 +13,7 @@ from calibre.ebooks.docx.block_styles import binary_property, inherit from calibre.utils.filenames import ascii_filename from calibre.utils.fonts.scanner import font_scanner, NoFonts from calibre.utils.fonts.utils import panose_to_css_generic_family, is_truetype_font +from calibre.utils.icu import ord_string Embed = namedtuple('Embed', 'name key subsetted') @@ -94,6 +95,40 @@ class Family(object): self.css_generic_family = self.css_generic_family or self.panose_name or 'serif' +SYMBOL_MAPS = { # {{{ + 'Wingdings': (' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '๐Ÿ–‰', 'โœ‚', 'โœ', '๐Ÿ‘“', '๐Ÿ•ญ', '๐Ÿ•ฎ', '๐Ÿ•ฏ', '๐Ÿ•ฟ', 'โœ†', '๐Ÿ–‚', '๐Ÿ–ƒ', '๐Ÿ“ช', '๐Ÿ“ซ', '๐Ÿ“ฌ', '๐Ÿ“ญ', '๐Ÿ—€', '๐Ÿ—', '๐Ÿ—Ž', '๐Ÿ—', '๐Ÿ—', '๐Ÿ—„', 'โณ', '๐Ÿ–ฎ', '๐Ÿ–ฐ', '๐Ÿ–ฒ', '๐Ÿ–ณ', '๐Ÿ–ด', '๐Ÿ–ซ', '๐Ÿ–ฌ', 'โœ‡', 'โœ', '๐Ÿ–Ž', 'โœŒ', '๐Ÿ–', '๐Ÿ‘', '๐Ÿ‘Ž', 'โ˜œ', 'โ˜ž', 'โ˜œ', '๐Ÿ–—', '๐Ÿ–', 'โ˜บ', '๐Ÿ˜', 'โ˜น', '๐Ÿ’ฃ', '๐Ÿ•ฑ', '๐Ÿณ', '๐Ÿฑ', 'โœˆ', 'โ˜ผ', '๐ŸŒข', 'โ„', '๐Ÿ•†', 'โœž', '๐Ÿ•ˆ', 'โœ ', 'โœก', 'โ˜ช', 'โ˜ฏ', '๐Ÿ•‰', 'โ˜ธ', 'โ™ˆ', 'โ™‰', 'โ™Š', 'โ™‹', 'โ™Œ', 'โ™', 'โ™Ž', 'โ™', 'โ™', 'โ™‘', 'โ™’', 'โ™“', '๐Ÿ™ฐ', '๐Ÿ™ต', 'โšซ', '๐Ÿ”พ', 'โ—ผ', '๐Ÿž', '๐Ÿž', 'โ‘', 'โ’', '๐ŸžŸ', 'โงซ', 'โ—†', 'โ–', '๐Ÿž™', 'โŒง', 'โฎน', 'โŒ˜', '๐Ÿต', '๐Ÿถ', '๐Ÿ™ถ', '๐Ÿ™ท', ' ', '๐Ÿ„‹', 'โž€', 'โž', 'โž‚', 'โžƒ', 'โž„', 'โž…', 'โž†', 'โž‡', 'โžˆ', 'โž‰', '๐Ÿ„Œ', 'โžŠ', 'โž‹', 'โžŒ', 'โž', 'โžŽ', 'โž', 'โž', 'โž‘', 'โž’', 'โž“', '๐Ÿ™ข', '๐Ÿ™ ', '๐Ÿ™ก', '๐Ÿ™ฃ', '๐Ÿ™ฆ', '๐Ÿ™ค', '๐Ÿ™ฅ', '๐Ÿ™ง', 'โˆ™', 'โ€ข', 'โฌ', 'โญ˜', '๐Ÿž†', '๐Ÿžˆ', '๐ŸžŠ', '๐Ÿž‹', '๐Ÿ”ฟ', 'โ–ช', '๐ŸžŽ', '๐ŸŸ€', '๐ŸŸ', 'โ˜…', '๐ŸŸ‹', '๐ŸŸ', '๐ŸŸ“', '๐ŸŸ‘', 'โฏ', 'โŒ–', 'โฏŽ', 'โฏ', 'โฏ‘', 'โœช', 'โœฐ', '๐Ÿ•', '๐Ÿ•‘', '๐Ÿ•’', '๐Ÿ•“', '๐Ÿ•”', '๐Ÿ••', '๐Ÿ•–', '๐Ÿ•—', '๐Ÿ•˜', '๐Ÿ•™', '๐Ÿ•š', '๐Ÿ•›', 'โฎฐ', 'โฎฑ', 'โฎฒ', 'โฎณ', 'โฎด', 'โฎต', 'โฎถ', 'โฎท', '๐Ÿ™ช', '๐Ÿ™ซ', '๐Ÿ™•', '๐Ÿ™”', '๐Ÿ™—', '๐Ÿ™–', '๐Ÿ™', '๐Ÿ™‘', '๐Ÿ™’', '๐Ÿ™“', 'โŒซ', 'โŒฆ', 'โฎ˜', 'โฎš', 'โฎ™', 'โฎ›', 'โฎˆ', 'โฎŠ', 'โฎ‰', 'โฎ‹', '๐Ÿกจ', '๐Ÿกช', '๐Ÿกฉ', '๐Ÿกซ', '๐Ÿกฌ', '๐Ÿกญ', '๐Ÿกฏ', '๐Ÿกฎ', '๐Ÿกธ', '๐Ÿกบ', '๐Ÿกน', '๐Ÿกป', '๐Ÿกผ', '๐Ÿกฝ', '๐Ÿกฟ', '๐Ÿกพ', 'โ‡ฆ', 'โ‡จ', 'โ‡ง', 'โ‡ฉ', 'โฌ„', 'โ‡ณ', 'โฌ', 'โฌ€', 'โฌƒ', 'โฌ‚', '๐Ÿขฌ', '๐Ÿขญ', '๐Ÿ—ถ', 'โœ“', '๐Ÿ—ท', '๐Ÿ—น', ' '), # noqa + + 'Wingdings 2': (' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '๐Ÿ–Š', '๐Ÿ–‹', '๐Ÿ–Œ', '๐Ÿ–', 'โœ„', 'โœ€', '๐Ÿ•พ', '๐Ÿ•ฝ', '๐Ÿ—…', '๐Ÿ—†', '๐Ÿ—‡', '๐Ÿ—ˆ', '๐Ÿ—‰', '๐Ÿ—Š', '๐Ÿ—‹', '๐Ÿ—Œ', '๐Ÿ—', '๐Ÿ“‹', '๐Ÿ—‘', '๐Ÿ—”', '๐Ÿ–ต', '๐Ÿ–ถ', '๐Ÿ–ท', '๐Ÿ–ธ', '๐Ÿ–ญ', '๐Ÿ–ฏ', '๐Ÿ–ฑ', '๐Ÿ–’', '๐Ÿ–“', '๐Ÿ–˜', '๐Ÿ–™', '๐Ÿ–š', '๐Ÿ–›', '๐Ÿ‘ˆ', '๐Ÿ‘‰', '๐Ÿ–œ', '๐Ÿ–', '๐Ÿ–ž', '๐Ÿ–Ÿ', '๐Ÿ– ', '๐Ÿ–ก', '๐Ÿ‘†', '๐Ÿ‘‡', '๐Ÿ–ข', '๐Ÿ–ฃ', '๐Ÿ–‘', '๐Ÿ—ด', '๐Ÿ—ธ', '๐Ÿ—ต', 'โ˜‘', 'โฎฝ', 'โ˜’', 'โฎพ', 'โฎฟ', '๐Ÿ›‡', 'โฆธ', '๐Ÿ™ฑ', '๐Ÿ™ด', '๐Ÿ™ฒ', '๐Ÿ™ณ', 'โ€ฝ', '๐Ÿ™น', '๐Ÿ™บ', '๐Ÿ™ป', '๐Ÿ™ฆ', '๐Ÿ™ค', '๐Ÿ™ฅ', '๐Ÿ™ง', '๐Ÿ™š', '๐Ÿ™˜', '๐Ÿ™™', '๐Ÿ™›', 'โ“ช', 'โ‘ ', 'โ‘ก', 'โ‘ข', 'โ‘ฃ', 'โ‘ค', 'โ‘ฅ', 'โ‘ฆ', 'โ‘ง', 'โ‘จ', 'โ‘ฉ', 'โ“ฟ', 'โถ', 'โท', 'โธ', 'โน', 'โบ', 'โป', 'โผ', 'โฝ', 'โพ', 'โฟ', ' ', 'โ˜‰', '๐ŸŒ•', 'โ˜ฝ', 'โ˜พ', 'โธฟ', 'โœ', '๐Ÿ•‡', '๐Ÿ•œ', '๐Ÿ•', '๐Ÿ•ž', '๐Ÿ•Ÿ', '๐Ÿ• ', '๐Ÿ•ก', '๐Ÿ•ข', '๐Ÿ•ฃ', '๐Ÿ•ค', '๐Ÿ•ฅ', '๐Ÿ•ฆ', '๐Ÿ•ง', '๐Ÿ™จ', '๐Ÿ™ฉ', 'โ‹…', '๐Ÿž„', 'โฆ', 'โ—', 'โ—', '๐Ÿž…', '๐Ÿž‡', '๐Ÿž‰', 'โŠ™', 'โฆฟ', '๐ŸžŒ', '๐Ÿž', 'โ—พ', 'โ– ', 'โ–ก', '๐Ÿž‘', '๐Ÿž’', '๐Ÿž“', '๐Ÿž”', 'โ–ฃ', '๐Ÿž•', '๐Ÿž–', '๐Ÿž—', '๐Ÿž˜', 'โฌฉ', 'โฌฅ', 'โ—‡', '๐Ÿžš', 'โ—ˆ', '๐Ÿž›', '๐Ÿžœ', '๐Ÿž', '๐Ÿžž', 'โฌช', 'โฌง', 'โ—Š', '๐Ÿž ', 'โ—–', 'โ——', 'โฏŠ', 'โฏ‹', 'โฏ€', 'โฏ', 'โฌŸ', 'โฏ‚', 'โฌฃ', 'โฌข', 'โฏƒ', 'โฏ„', '๐Ÿžก', '๐Ÿžข', '๐Ÿžฃ', '๐Ÿžค', '๐Ÿžฅ', '๐Ÿžฆ', '๐Ÿžง', '๐Ÿžจ', '๐Ÿžฉ', '๐Ÿžช', '๐Ÿžซ', '๐Ÿžฌ', '๐Ÿžญ', '๐Ÿžฎ', '๐Ÿžฏ', '๐Ÿžฐ', '๐Ÿžฑ', '๐Ÿžฒ', '๐Ÿžณ', '๐Ÿžด', '๐Ÿžต', '๐Ÿžถ', '๐Ÿžท', '๐Ÿžธ', '๐Ÿžน', '๐Ÿžบ', '๐Ÿžป', '๐Ÿžผ', '๐Ÿžฝ', '๐Ÿžพ', '๐Ÿžฟ', '๐ŸŸ€', '๐ŸŸ‚', '๐ŸŸ„', '๐ŸŸ†', '๐ŸŸ‰', '๐ŸŸŠ', 'โœถ', '๐ŸŸŒ', '๐ŸŸŽ', '๐ŸŸ', '๐ŸŸ’', 'โœน', '๐ŸŸƒ', '๐ŸŸ‡', 'โœฏ', '๐ŸŸ', '๐ŸŸ”', 'โฏŒ', 'โฏ', 'โ€ป', 'โ‚', ' ', ' ', ' ', ' ', ' ', ' ',), # noqa + + 'Wingdings 3': (' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'โญ ', 'โญข', 'โญก', 'โญฃ', 'โญค', 'โญฅ', 'โญง', 'โญฆ', 'โญฐ', 'โญฒ', 'โญฑ', 'โญณ', 'โญถ', 'โญธ', 'โญป', 'โญฝ', 'โญค', 'โญฅ', 'โญช', 'โญฌ', 'โญซ', 'โญญ', 'โญ', 'โฎ ', 'โฎก', 'โฎข', 'โฎฃ', 'โฎค', 'โฎฅ', 'โฎฆ', 'โฎง', 'โฎ', 'โฎ‘', 'โฎ’', 'โฎ“', 'โฎ€', 'โฎƒ', 'โญพ', 'โญฟ', 'โฎ„', 'โฎ†', 'โฎ…', 'โฎ‡', 'โฎ', 'โฎ', 'โฎŽ', 'โฎŒ', 'โญฎ', 'โญฏ', 'โŽ‹', 'โŒค', 'โŒƒ', 'โŒฅ', 'โฃ', 'โฝ', 'โ‡ช', 'โฎธ', '๐Ÿข ', '๐Ÿขก', '๐Ÿขข', '๐Ÿขฃ', '๐Ÿขค', '๐Ÿขฅ', '๐Ÿขฆ', '๐Ÿขง', '๐Ÿขจ', '๐Ÿขฉ', '๐Ÿขช', '๐Ÿขซ', '๐Ÿก', '๐Ÿก’', '๐Ÿก‘', '๐Ÿก“', '๐Ÿก”', '๐Ÿก•', '๐Ÿก—', '๐Ÿก–', '๐Ÿก˜', '๐Ÿก™', 'โ–ฒ', 'โ–ผ', 'โ–ณ', 'โ–ฝ', 'โ—€', 'โ–ถ', 'โ—', 'โ–ท', 'โ—ฃ', 'โ—ข', 'โ—ค', 'โ—ฅ', '๐Ÿž€', '๐Ÿž‚', '๐Ÿž', ' ', '๐Ÿžƒ', 'โฏ…', 'โฏ†', 'โฏ‡', 'โฏˆ', 'โฎœ', 'โฎž', 'โฎ', 'โฎŸ', '๐Ÿ ', '๐Ÿ ’', '๐Ÿ ‘', '๐Ÿ “', '๐Ÿ ”', '๐Ÿ –', '๐Ÿ •', '๐Ÿ —', '๐Ÿ ˜', '๐Ÿ š', '๐Ÿ ™', '๐Ÿ ›', '๐Ÿ œ', '๐Ÿ ž', '๐Ÿ ', '๐Ÿ Ÿ', '๐Ÿ €', '๐Ÿ ‚', '๐Ÿ ', '๐Ÿ ƒ', '๐Ÿ „', '๐Ÿ †', '๐Ÿ …', '๐Ÿ ‡', '๐Ÿ ˆ', '๐Ÿ Š', '๐Ÿ ‰', '๐Ÿ ‹', '๐Ÿ  ', '๐Ÿ ข', '๐Ÿ ค', '๐Ÿ ฆ', '๐Ÿ จ', '๐Ÿ ช', '๐Ÿ ฌ', '๐Ÿขœ', '๐Ÿข', '๐Ÿขž', '๐ŸขŸ', '๐Ÿ ฎ', '๐Ÿ ฐ', '๐Ÿ ฒ', '๐Ÿ ด', '๐Ÿ ถ', '๐Ÿ ธ', '๐Ÿ บ', '๐Ÿ น', '๐Ÿ ป', '๐Ÿข˜', '๐Ÿขš', '๐Ÿข™', '๐Ÿข›', '๐Ÿ ผ', '๐Ÿ พ', '๐Ÿ ฝ', '๐Ÿ ฟ', '๐Ÿก€', '๐Ÿก‚', '๐Ÿก', '๐Ÿกƒ', '๐Ÿก„', '๐Ÿก†', '๐Ÿก…', '๐Ÿก‡', 'โฎจ', 'โฎฉ', 'โฎช', 'โฎซ', 'โฎฌ', 'โฎญ', 'โฎฎ', 'โฎฏ', '๐Ÿก ', '๐Ÿกข', '๐Ÿกก', '๐Ÿกฃ', '๐Ÿกค', '๐Ÿกฅ', '๐Ÿกง', '๐Ÿกฆ', '๐Ÿกฐ', '๐Ÿกฒ', '๐Ÿกฑ', '๐Ÿกณ', '๐Ÿกด', '๐Ÿกต', '๐Ÿกท', '๐Ÿกถ', '๐Ÿข€', '๐Ÿข‚', '๐Ÿข', '๐Ÿขƒ', '๐Ÿข„', '๐Ÿข…', '๐Ÿข‡', '๐Ÿข†', '๐Ÿข', '๐Ÿข’', '๐Ÿข‘', '๐Ÿข“', '๐Ÿข”', '๐Ÿข•', '๐Ÿข—', '๐Ÿข–', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',), # noqa + + 'Webdings': (' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '๐Ÿ•ท', '๐Ÿ•ธ', '๐Ÿ•ฒ', '๐Ÿ•ถ', '๐Ÿ†', '๐ŸŽ–', '๐Ÿ–‡', '๐Ÿ—จ', '๐Ÿ—ฉ', '๐Ÿ—ฐ', '๐Ÿ—ฑ', '๐ŸŒถ', '๐ŸŽ—', '๐Ÿ™พ', '๐Ÿ™ผ', '๐Ÿ—•', '๐Ÿ—–', '๐Ÿ——', 'โด', 'โต', 'โถ', 'โท', 'โช', 'โฉ', 'โฎ', 'โญ', 'โธ', 'โน', 'โบ', '๐Ÿ—š', '๐Ÿ—ณ', '๐Ÿ› ', '๐Ÿ—', '๐Ÿ˜', '๐Ÿ™', '๐Ÿš', '๐Ÿœ', '๐Ÿญ', '๐Ÿ›', '๐Ÿ ', '๐Ÿ–', '๐Ÿ', '๐Ÿ›ฃ', '๐Ÿ”', '๐Ÿ”', '๐Ÿ‘', '๐Ÿ‘‚', '๐Ÿž', '๐Ÿ•', '๐Ÿ›ค', '๐ŸŸ', '๐Ÿ›ณ', '๐Ÿ•ฌ', '๐Ÿ•ซ', '๐Ÿ•จ', '๐Ÿ”ˆ', '๐ŸŽ”', '๐ŸŽ•', '๐Ÿ—ฌ', '๐Ÿ™ฝ', '๐Ÿ—ญ', '๐Ÿ—ช', '๐Ÿ—ซ', 'โฎ”', 'โœ”', '๐Ÿšฒ', 'โฌœ', '๐Ÿ›ก', '๐Ÿ“ฆ', '๐Ÿ›ฑ', 'โฌ›', '๐Ÿš‘', '๐Ÿ›ˆ', '๐Ÿ›ฉ', '๐Ÿ›ฐ', '๐ŸŸˆ', '๐Ÿ•ด', 'โฌค', '๐Ÿ›ฅ', '๐Ÿš”', '๐Ÿ—˜', '๐Ÿ—™', 'โ“', '๐Ÿ›ฒ', '๐Ÿš‡', '๐Ÿš', 'โ›ณ', 'โฆธ', 'โŠ–', '๐Ÿšญ', '๐Ÿ—ฎ', 'โ', '๐Ÿ—ฏ', '๐Ÿ—ฒ', ' ', '๐Ÿšน', '๐Ÿšบ', '๐Ÿ›‰', '๐Ÿ›Š', '๐Ÿšผ', '๐Ÿ‘ฝ', '๐Ÿ‹', 'โ›ท', '๐Ÿ‚', '๐ŸŒ', '๐ŸŠ', '๐Ÿ„', '๐Ÿ', '๐ŸŽ', '๐Ÿš˜', '๐Ÿ— ', '๐Ÿ›ข', '๐Ÿ“ ', '๐Ÿท', '๐Ÿ“ฃ', '๐Ÿ‘ช', '๐Ÿ—ก', '๐Ÿ—ข', '๐Ÿ—ฃ', 'โœฏ', '๐Ÿ–„', '๐Ÿ–…', '๐Ÿ–ƒ', '๐Ÿ–†', '๐Ÿ–น', '๐Ÿ–บ', '๐Ÿ–ป', '๐Ÿ•ต', '๐Ÿ•ฐ', '๐Ÿ–ฝ', '๐Ÿ–พ', '๐Ÿ“‹', '๐Ÿ—’', '๐Ÿ—“', '๐Ÿ•ฎ', '๐Ÿ“š', '๐Ÿ—ž', '๐Ÿ—Ÿ', '๐Ÿ—ƒ', '๐Ÿ—‚', '๐Ÿ–ผ', '๐ŸŽญ', '๐ŸŽœ', '๐ŸŽ˜', '๐ŸŽ™', '๐ŸŽง', '๐Ÿ’ฟ', '๐ŸŽž', '๐Ÿ“ท', '๐ŸŽŸ', '๐ŸŽฌ', '๐Ÿ“ฝ', '๐Ÿ“น', '๐Ÿ“พ', '๐Ÿ“ป', '๐ŸŽš', '๐ŸŽ›', '๐Ÿ“บ', '๐Ÿ’ป', '๐Ÿ–ฅ', '๐Ÿ–ฆ', '๐Ÿ–ง', '๐Ÿน', '๐ŸŽฎ', '๐ŸŽฎ', '๐Ÿ•ป', '๐Ÿ•ผ', '๐Ÿ–', '๐Ÿ–€', '๐Ÿ–จ', '๐Ÿ–ฉ', '๐Ÿ–ฟ', '๐Ÿ–ช', '๐Ÿ—œ', '๐Ÿ”’', '๐Ÿ”“', '๐Ÿ—', '๐Ÿ“ฅ', '๐Ÿ“ค', '๐Ÿ•ณ', '๐ŸŒฃ', '๐ŸŒค', '๐ŸŒฅ', '๐ŸŒฆ', 'โ˜', '๐ŸŒจ', '๐ŸŒง', '๐ŸŒฉ', '๐ŸŒช', '๐ŸŒฌ', '๐ŸŒซ', '๐ŸŒœ', '๐ŸŒก', '๐Ÿ›‹', '๐Ÿ›', '๐Ÿฝ', '๐Ÿธ', '๐Ÿ›Ž', '๐Ÿ›', 'โ“…', 'โ™ฟ', '๐Ÿ›†', '๐Ÿ–ˆ', '๐ŸŽ“', '๐Ÿ—ค', '๐Ÿ—ฅ', '๐Ÿ—ฆ', '๐Ÿ—ง', '๐Ÿ›ช', '๐Ÿฟ', '๐Ÿฆ', '๐ŸŸ', '๐Ÿ•', '๐Ÿˆ', '๐Ÿ™ฌ', '๐Ÿ™ฎ', '๐Ÿ™ญ', '๐Ÿ™ฏ', '๐Ÿ—บ', '๐ŸŒ', '๐ŸŒ', '๐ŸŒŽ', '๐Ÿ•Š',), # noqa + + 'Symbol': (' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '!', 'โˆ€', '#', 'โˆƒ', '%', '&', 'โˆ', '(', ')', '*', '+', ',', 'โˆ’', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', 'โ‰…', 'ฮ‘', 'ฮ’', 'ฮง', 'ฮ”', 'ฮ•', 'ฮฆ', 'ฮ“', 'ฮ—', 'ฮ™', 'ฯ‘', 'ฮ›', 'ฮœ', 'ฮ', 'ฮž', 'ฮŸ', 'ฮ ', 'ฮ˜', 'ฮก', 'ฮฃ', 'ฮค', 'ฮฅ', 'ฯ‚', 'ฮฉ', 'ฮž', 'ฮจ', 'ฮ–', '[', 'โˆด', ']', 'โŠฅ', '_', '๏ฃฅ', 'ฮฑ', 'ฮฒ', 'ฯ‡', 'ฮด', 'ฮต', 'ฯ†', 'ฮณ', 'ฮท', 'ฮน', 'ฯ•', 'ฮป', 'ฮผ', 'ฮฝ', 'ฮพ', 'ฮฟ', 'ฯ€', 'ฮธ', 'ฯ', 'ฯƒ', 'ฯ„', 'ฯ…', 'ฯ–', 'ฯ‰', 'ฮพ', 'ฯˆ', 'ฮถ', '{', '|', '}', '~', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'โ‚ฌ', 'ฯ’', 'โ€ฒ', 'โ‰ค', 'โ„', 'โˆž', 'ฦ’', 'โ™ฃ', 'โ™ฅ', 'โ™ฆ', 'โ™ ', 'โ†”', 'โ†', 'โ†‘', 'โ†’', 'โ†“', 'ยฐ', 'ยฑ', 'โ€ณ', 'โ‰ฅ', 'ร—', 'โˆ', 'โˆ‚', 'โ€ข', 'รท', 'โ‰ ', 'โ‰ก', 'โ‰ˆ', 'โ€ฆ', 'โ', 'โŽฏ', 'โ†ฒ', 'โ„ต', 'โ„‘', 'โ„œ', 'โ„˜', 'โŠ—', 'โŠ•', 'โˆ…', 'โˆฉ', 'โˆช', 'โŠƒ', 'โЇ', 'โŠ„', 'โŠ‚', 'โІ', 'โˆˆ', 'โˆ‰', 'โˆ ', 'โˆ‚', 'ยฎ', 'ยฉ', 'โ„ข', 'โˆ', 'โˆš', 'โ‹…', 'ยฌ', 'โˆฆ', 'โˆง', 'โ‡”', 'โ‡', 'โ‡‘', 'โ‡’', 'โ‡“', 'โ—Š', 'ใ€ˆ', 'ยฎ', 'ยฉ', 'โ„ข', 'โˆ‘', 'โŽ›', 'โŽœ', 'โŽ', 'โŽก', 'โŽข', 'โŽฃ', 'โŽง', 'โŽจ', 'โŽฉ', 'โŽช', ' ', 'ใ€‰', 'โˆซ', 'โŒ ', 'โŽฎ', 'โŒก', 'โŽž', 'โŽŸ', 'โŽ ', 'โŽค', 'โŽฅ', 'โŽฆ', 'โŽช', 'โŽซ', 'โŽฌ', ' ',), # noqa +} # }}} + +SYMBOL_FONT_NAMES = frozenset(n.lower() for n in SYMBOL_MAPS) + + +def is_symbol_font(family): + return family.lower() in SYMBOL_FONT_NAMES + + +def do_map(m, points): + base = 0xf000 + limit = len(m) + base + for p in points: + if base < p < limit: + yield m[p - base] + else: + yield unichr(p) + + +def map_symbol_text(text, font): + m = SYMBOL_MAPS[font] + return ''.join(do_map(m, ord_string(text))) + + class Fonts(object): def __init__(self, namespace): @@ -112,6 +147,8 @@ class Fonts(object): variant = get_variant(bold, italic) self.used.add((name, variant)) name = f.name if variant in f.embedded else f.family_name + if is_symbol_font(name): + return name return '"%s", %s' % (name.replace('"', ''), f.css_generic_family) def embed_fonts(self, dest_dir, docx): diff --git a/src/calibre/ebooks/docx/to_html.py b/src/calibre/ebooks/docx/to_html.py index 6673a76438..7924f1c09e 100644 --- a/src/calibre/ebooks/docx/to_html.py +++ b/src/calibre/ebooks/docx/to_html.py @@ -18,7 +18,7 @@ from calibre.ebooks.docx.container import DOCX, fromstring from calibre.ebooks.docx.names import XML, generate_anchor from calibre.ebooks.docx.styles import Styles, inherit, PageProperties from calibre.ebooks.docx.numbering import Numbering -from calibre.ebooks.docx.fonts import Fonts +from calibre.ebooks.docx.fonts import Fonts, is_symbol_font, map_symbol_text from calibre.ebooks.docx.images import Images from calibre.ebooks.docx.tables import Tables from calibre.ebooks.docx.footnotes import Footnotes @@ -37,11 +37,16 @@ class Text: def __init__(self, elem, attr, buf): self.elem, self.attr, self.buf = elem, attr, buf + self.elems = [self.elem] def add_elem(self, elem): + self.elems.append(elem) setattr(self.elem, self.attr, ''.join(self.buf)) self.elem, self.attr, self.buf = elem, 'tail', [] + def __iter__(self): + return iter(self.elems) + def html_lang(docx_lang): lang = canonicalize_lang(docx_lang) @@ -690,6 +695,13 @@ class Convert(object): ans.set('lang', lang) if style.rtl is True: ans.set('dir', 'rtl') + if is_symbol_font(style.font_family): + for elem in text: + if elem.text: + elem.text = map_symbol_text(elem.text, style.font_family) + if elem.tail: + elem.tail = map_symbol_text(elem.tail, style.font_family) + style.font_family = 'sans-serif' return ans def add_frame(self, html_obj, style):