mirror of
https://github.com/gryf/ebook-converter.git
synced 2026-04-19 20:53:35 +02:00
Cleanup get_path usage in favor of pkg_resources.
This commit is contained in:
149
ebook_converter/data/jacket/stylesheet.css
Normal file
149
ebook_converter/data/jacket/stylesheet.css
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
/*
|
||||||
|
** Book Jacket generation
|
||||||
|
**
|
||||||
|
** The template for Book Jackets is template.xhtml
|
||||||
|
** This CSS is inserted into the generated HTML at conversion time
|
||||||
|
**
|
||||||
|
** Users can control parts of the presentation of a generated book jacket by
|
||||||
|
** editing this file and template.xhtml
|
||||||
|
**
|
||||||
|
** The general form of a generated Book Jacket:
|
||||||
|
**
|
||||||
|
** Title
|
||||||
|
** Series: series [series_index]
|
||||||
|
** Published: year_of_publication
|
||||||
|
** Rating: #_of_stars
|
||||||
|
** Tags: tag1, tag2, tag3 ...
|
||||||
|
**
|
||||||
|
** Comments
|
||||||
|
**
|
||||||
|
** If a book does not have Series information, a date of publication, a rating or tags
|
||||||
|
** the corresponding row is automatically removed from the generated book jacket.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Banner
|
||||||
|
** Only affects EPUB, kindle ignores this type of formatting
|
||||||
|
*/
|
||||||
|
.cbj_banner {
|
||||||
|
background: #eee;
|
||||||
|
color: black;
|
||||||
|
border: thin solid black;
|
||||||
|
margin: 1em;
|
||||||
|
padding: 1em;
|
||||||
|
border-radius:8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Title
|
||||||
|
*/
|
||||||
|
table.cbj_header td.cbj_title {
|
||||||
|
font-size: 1.5em;
|
||||||
|
font-style: italic;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Series
|
||||||
|
*/
|
||||||
|
table.cbj_header td.cbj_series {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Author
|
||||||
|
*/
|
||||||
|
table.cbj_header td.cbj_author {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Publisher/published
|
||||||
|
*/
|
||||||
|
table.cbj_header td.cbj_pubdata {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Table containing Rating and Tags
|
||||||
|
*/
|
||||||
|
table.cbj_header {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** General formatting for banner labels
|
||||||
|
*/
|
||||||
|
table.cbj_header td.cbj_label {
|
||||||
|
font-family: sans-serif;
|
||||||
|
text-align: right;
|
||||||
|
width: 33%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** General formatting for banner content
|
||||||
|
*/
|
||||||
|
table.cbj_header td.cbj_content {
|
||||||
|
font-family: sans-serif;
|
||||||
|
text-align: left;
|
||||||
|
width:67%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Metadata divider
|
||||||
|
*/
|
||||||
|
hr.metadata_divider {
|
||||||
|
width:90%;
|
||||||
|
margin-left:5%;
|
||||||
|
border-top: solid white 0px;
|
||||||
|
border-right: solid white 0px;
|
||||||
|
border-bottom: solid black 1px;
|
||||||
|
border-left: solid white 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** To skip a banner item (Series|Published|Rating|Tags),
|
||||||
|
** edit the appropriate CSS rule below.
|
||||||
|
*/
|
||||||
|
table.cbj_header tr.cbj_series {
|
||||||
|
/* Uncomment the next line to remove 'Series' from banner section */
|
||||||
|
/* display:none; */
|
||||||
|
}
|
||||||
|
|
||||||
|
table.cbj_header tr.cbj_pubdata {
|
||||||
|
/* Uncomment the next line to remove 'Published (year of publication)' from banner section */
|
||||||
|
/* display:none; */
|
||||||
|
}
|
||||||
|
|
||||||
|
table.cbj_header tr.cbj_rating {
|
||||||
|
/* Uncomment the next line to remove 'Rating' from banner section */
|
||||||
|
/* display:none; */
|
||||||
|
}
|
||||||
|
|
||||||
|
table.cbj_header tr.cbj_tags {
|
||||||
|
/* Uncomment the next line to remove 'Tags' from banner section */
|
||||||
|
/* display:none; */
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
/* This rule controls formatting for any hr elements contained in the jacket */
|
||||||
|
border-top: 0px solid white;
|
||||||
|
border-right: 0px solid white;
|
||||||
|
border-bottom: 2px solid black;
|
||||||
|
border-left: 0px solid white;
|
||||||
|
margin-left: 10%;
|
||||||
|
width: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cbj_footer {
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 0.8em;
|
||||||
|
margin-top: 8px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cbj_comments {
|
||||||
|
font-family: sans-serif;
|
||||||
|
}
|
||||||
58
ebook_converter/data/jacket/template.xhtml
Normal file
58
ebook_converter/data/jacket/template.xhtml
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
<html xmlns="{xmlns}">
|
||||||
|
<head>
|
||||||
|
<title>{title_str}</title>
|
||||||
|
<meta name="calibre-content" content="jacket"/>
|
||||||
|
<style type="text/css">{css}</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="cbj_banner">
|
||||||
|
<table class="cbj_header">
|
||||||
|
<tr>
|
||||||
|
<td class="cbj_title" colspan="2">{title}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<!-- If you do not want the series number to be formatted using roman numerals
|
||||||
|
change {series.roman} to {series}. You can also access the raw series name and number
|
||||||
|
using {series.name}, {series.number} or {series.roman_number} -->
|
||||||
|
<td class="cbj_series" colspan="2">{series.roman}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="cbj_author" colspan="2">{author}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="cbj_pubdata" colspan="2">{publisher} ({pubdate})</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td class="cbj_author" colspan="2"><hr class="metadata_divider" /></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr class="cbj_rating">
|
||||||
|
<td class="cbj_label">{rating_label}:</td>
|
||||||
|
<td class="cbj_content">{rating}</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="cbj_tags">
|
||||||
|
<td class="cbj_label">{tags_label}:</td>
|
||||||
|
<!-- If you want the tags to be alphabetical, change {tags} to
|
||||||
|
{tags.alphabetical} -->
|
||||||
|
<td class="cbj_content">{tags}</td>
|
||||||
|
</tr>
|
||||||
|
<tr data-calibre-jacket-searchable-tags="1" style="color:white; display:none"><td colspan="2">{searchable_tags}</td></tr>
|
||||||
|
</table>
|
||||||
|
<div class="cbj_footer">{footer}</div>
|
||||||
|
</div>
|
||||||
|
<hr class="cbj_kindle_banner_hr" />
|
||||||
|
<!--
|
||||||
|
In addition you can add code to show the values of custom columns here.
|
||||||
|
The value is available as _column_name and the title as
|
||||||
|
_column_name_label. For example, if you have a custom column with
|
||||||
|
label #genre, you can add it to this template with _genre_label and
|
||||||
|
_genre. Note that the # is replaced by an underscore. For example
|
||||||
|
|
||||||
|
<div><b>{_genre_label}:</b> {_genre}</div>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<div class="cbj_comments">{comments}</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
210
ebook_converter/data/lrf.xsl
Normal file
210
ebook_converter/data/lrf.xsl
Normal file
@@ -0,0 +1,210 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<xsl:stylesheet
|
||||||
|
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||||
|
xmlns:c="calibre"
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:opf="http://www.idpf.org/2007/opf"
|
||||||
|
xmlns:calibre="http://calibre.kovidgoyal.net/2009/metadata"
|
||||||
|
extension-element-prefixes="c"
|
||||||
|
xsl:version = "1.1"
|
||||||
|
>
|
||||||
|
<xsl:output method="xml" indent="yes"/>
|
||||||
|
|
||||||
|
<xsl:template match="/">
|
||||||
|
<package version="2.0">
|
||||||
|
<metadata>
|
||||||
|
<xsl:call-template name="make-metadata"/>
|
||||||
|
</metadata>
|
||||||
|
<manifest>
|
||||||
|
<xsl:call-template name="make-manifest"/>
|
||||||
|
</manifest>
|
||||||
|
<spine toc="ncx">
|
||||||
|
<xsl:call-template name="make-spine"/>
|
||||||
|
</spine>
|
||||||
|
</package>
|
||||||
|
<xsl:call-template name="make-ncx"/>
|
||||||
|
<xsl:call-template name="make-css"/>
|
||||||
|
<xsl:for-each select="//Page">
|
||||||
|
<xsl:call-template name="make-page"/>
|
||||||
|
</xsl:for-each>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template name="make-css">
|
||||||
|
<xsl:for-each select="//TextStyle|//BlockStyle">
|
||||||
|
<c:styles/>
|
||||||
|
</xsl:for-each>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template name="make-page">
|
||||||
|
<xsl:variable name="pid" select="@objid"/>
|
||||||
|
<xsl:document href="{$pid}.xhtml" method="xml" indent="yes">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title><xsl:value-of select="//Title"/></title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="styles.css"/>
|
||||||
|
</head>
|
||||||
|
<body class="body">
|
||||||
|
<xsl:apply-templates />
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
</xsl:document>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="RuledLine">
|
||||||
|
<c:ruled-line/>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="TextBlock">
|
||||||
|
<c:text-block/>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="ImageBlock">
|
||||||
|
<c:image-block/>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="Canvas">
|
||||||
|
<c:canvas/>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template name="make-metadata">
|
||||||
|
<xsl:for-each select='//BookInformation/Info/BookInfo'>
|
||||||
|
<xsl:apply-templates select="Title"/>
|
||||||
|
<xsl:apply-templates select="Author"/>
|
||||||
|
<xsl:apply-templates select="Publisher"/>
|
||||||
|
<xsl:apply-templates select="Category|Classification"/>
|
||||||
|
</xsl:for-each>
|
||||||
|
<xsl:for-each select='//BookInformation/Info/DocInfo'>
|
||||||
|
<xsl:apply-templates select="Language"/>
|
||||||
|
<xsl:apply-templates select="Producer"/>
|
||||||
|
</xsl:for-each>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="Title">
|
||||||
|
<xsl:element name="dc:title">
|
||||||
|
<xsl:if test="@reading and @reading != ''">
|
||||||
|
<xsl:attribute name="opf:file-as"><xsl:value-of select="@reading"/></xsl:attribute>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:value-of select="."/>
|
||||||
|
</xsl:element>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="Author">
|
||||||
|
<xsl:element name="dc:creator">
|
||||||
|
<xsl:attribute name="opf:role">aut</xsl:attribute>
|
||||||
|
<xsl:if test="@reading and @reading != ''">
|
||||||
|
<xsl:attribute name="opf:file-as"><xsl:value-of select="@reading"/></xsl:attribute>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:value-of select="."/>
|
||||||
|
</xsl:element>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="Publisher">
|
||||||
|
<xsl:element name="dc:publisher">
|
||||||
|
<xsl:if test="@reading and @reading != ''">
|
||||||
|
<xsl:attribute name="opf:file-as"><xsl:value-of select="@reading"/></xsl:attribute>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:value-of select="."/>
|
||||||
|
</xsl:element>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="Producer">
|
||||||
|
<xsl:element name="dc:creator">
|
||||||
|
<xsl:attribute name="opf:role">bkp</xsl:attribute>
|
||||||
|
<xsl:if test="@reading and @reading != ''">
|
||||||
|
<xsl:attribute name="opf:file-as"><xsl:value-of select="@reading"/></xsl:attribute>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:value-of select="."/>
|
||||||
|
</xsl:element>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="Language">
|
||||||
|
<xsl:element name="dc:language">
|
||||||
|
<xsl:value-of select="."/>
|
||||||
|
</xsl:element>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="Category|Classification">
|
||||||
|
<xsl:if test=".!=''">
|
||||||
|
<xsl:element name="dc:subject">
|
||||||
|
<xsl:value-of select="."/>
|
||||||
|
</xsl:element>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template name="make-manifest">
|
||||||
|
<xsl:for-each select='//Page'>
|
||||||
|
<xsl:element name="item">
|
||||||
|
<xsl:attribute name="id"><xsl:value-of select="@objid"/></xsl:attribute>
|
||||||
|
<xsl:attribute name="media-type"><xsl:text>application/xhtml+xml</xsl:text></xsl:attribute>
|
||||||
|
<xsl:attribute name="href"><xsl:value-of select="@objid"/><xsl:text>.xhtml</xsl:text></xsl:attribute>
|
||||||
|
</xsl:element>
|
||||||
|
</xsl:for-each>
|
||||||
|
<xsl:for-each select="//ImageStream">
|
||||||
|
<xsl:element name="item">
|
||||||
|
<xsl:attribute name="id"><xsl:value-of select="@objid"/></xsl:attribute>
|
||||||
|
<xsl:attribute name="media-type"><c:media-type/></xsl:attribute>
|
||||||
|
<xsl:attribute name="href"><xsl:value-of select="@file"/></xsl:attribute>
|
||||||
|
</xsl:element>
|
||||||
|
</xsl:for-each>
|
||||||
|
<xsl:for-each select="//RegistFont">
|
||||||
|
<xsl:element name="item">
|
||||||
|
<xsl:attribute name="id"><xsl:value-of select="@objid"/></xsl:attribute>
|
||||||
|
<xsl:attribute name="media-type"><c:media-type/></xsl:attribute>
|
||||||
|
<xsl:attribute name="href"><xsl:value-of select="@file"/></xsl:attribute>
|
||||||
|
</xsl:element>
|
||||||
|
</xsl:for-each>
|
||||||
|
<item id="ncx" href="toc.ncx" media-type="application/x-dtbncx+xml" />
|
||||||
|
<item id="styles" href="styles.css" media-type="text/css" />
|
||||||
|
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template name="make-spine">
|
||||||
|
<xsl:for-each select='//Page'>
|
||||||
|
<xsl:element name="itemref">
|
||||||
|
<xsl:attribute name="idref"><xsl:value-of select="@objid"/></xsl:attribute>
|
||||||
|
</xsl:element>
|
||||||
|
</xsl:for-each>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="*">
|
||||||
|
<xsl:message>
|
||||||
|
<xsl:text>no match for element: "</xsl:text>
|
||||||
|
<xsl:value-of select="name(.)"/>
|
||||||
|
<xsl:text>" 
</xsl:text>
|
||||||
|
</xsl:message>
|
||||||
|
<xsl:apply-templates/>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
|
||||||
|
<xsl:template name="make-ncx">
|
||||||
|
<xsl:document href="toc.ncx" method="xml" indent="yes">
|
||||||
|
<ncx version="2005-1"
|
||||||
|
xmlns="http://www.daisy.org/z3986/2005/ncx/"
|
||||||
|
xmlns:calibre="http://calibre.kovidgoyal.net/2009/metadata"
|
||||||
|
>
|
||||||
|
<head>
|
||||||
|
<meta name="dtb:uid" content="uid"/>
|
||||||
|
<meta name="dtb:depth" content="1"/>
|
||||||
|
<meta name="dtb:generator" content="calibre"/>
|
||||||
|
<meta name="dtb:totalPageCount" content="0"/>
|
||||||
|
<meta name="dtb:maxPageNumber" content="0"/>
|
||||||
|
</head>
|
||||||
|
<docTitle><text>Table of Contents</text></docTitle>
|
||||||
|
<navMap>
|
||||||
|
<xsl:for-each select="//TOC/TocLabel">
|
||||||
|
<xsl:element name="navPoint">
|
||||||
|
<xsl:attribute name="id"><xsl:value-of select="count(preceding-sibling::*)"/></xsl:attribute>
|
||||||
|
<xsl:attribute name="playOrder"><xsl:value-of select="count(preceding-sibling::*)+1"/></xsl:attribute>
|
||||||
|
<navLabel><text><xsl:value-of select="."/></text></navLabel>
|
||||||
|
<xsl:element name="content">
|
||||||
|
<xsl:attribute name="src">
|
||||||
|
<xsl:value-of select="@refpage"/>.xhtml#<xsl:value-of select="@refobj"/>
|
||||||
|
</xsl:attribute>
|
||||||
|
</xsl:element>
|
||||||
|
</xsl:element>
|
||||||
|
</xsl:for-each>
|
||||||
|
</navMap>
|
||||||
|
</ncx>
|
||||||
|
</xsl:document>
|
||||||
|
</xsl:template>
|
||||||
|
</xsl:stylesheet>
|
||||||
9
ebook_converter/data/new_nav.html
Normal file
9
ebook_converter/data/new_nav.html
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
|
||||||
|
<head>
|
||||||
|
<title>Navigation</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -6,6 +6,7 @@ __copyright__ = '2008, Anatoly Shipitsin <norguhtar at gmail.com>'
|
|||||||
Convert .fb2 files to .lrf
|
Convert .fb2 files to .lrf
|
||||||
"""
|
"""
|
||||||
import os, re
|
import os, re
|
||||||
|
import pkg_resources
|
||||||
|
|
||||||
from ebook_converter.customize.conversion import InputFormatPlugin, OptionRecommendation
|
from ebook_converter.customize.conversion import InputFormatPlugin, OptionRecommendation
|
||||||
from ebook_converter import guess_type
|
from ebook_converter import guess_type
|
||||||
@@ -86,8 +87,9 @@ class FB2Input(InputFormatPlugin):
|
|||||||
css = re.sub(r'name\s*=\s*', 'class=', css)
|
css = re.sub(r'name\s*=\s*', 'class=', css)
|
||||||
self.extract_embedded_content(doc)
|
self.extract_embedded_content(doc)
|
||||||
log.debug('Converting XML to HTML...')
|
log.debug('Converting XML to HTML...')
|
||||||
with open(P('templates/fb2.xsl'), 'rb') as f:
|
with open(pkg_resources.resource_filename('ebook_converter',
|
||||||
ss = f.read().decode('utf-8')
|
'data/fb2.xsl')) as f:
|
||||||
|
ss = f.read().decode()
|
||||||
ss = ss.replace("__FB_NS__", fb_ns)
|
ss = ss.replace("__FB_NS__", fb_ns)
|
||||||
if options.no_inline_fb2_toc:
|
if options.no_inline_fb2_toc:
|
||||||
log('Disabling generation of inline FB2 TOC')
|
log('Disabling generation of inline FB2 TOC')
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ __docformat__ = 'restructuredtext en'
|
|||||||
|
|
||||||
import os, re, shutil
|
import os, re, shutil
|
||||||
from os.path import dirname, abspath, relpath as _relpath, exists, basename
|
from os.path import dirname, abspath, relpath as _relpath, exists, basename
|
||||||
|
import pkg_resources
|
||||||
|
|
||||||
from ebook_converter.customize.conversion import OutputFormatPlugin, OptionRecommendation
|
from ebook_converter.customize.conversion import OutputFormatPlugin, OptionRecommendation
|
||||||
from ebook_converter import CurrentDir
|
from ebook_converter import CurrentDir
|
||||||
@@ -95,19 +96,31 @@ class HTMLOutput(OutputFormatPlugin):
|
|||||||
with open(opts.template_html_index, 'rb') as f:
|
with open(opts.template_html_index, 'rb') as f:
|
||||||
template_html_index_data = f.read()
|
template_html_index_data = f.read()
|
||||||
else:
|
else:
|
||||||
template_html_index_data = P('templates/html_export_default_index.tmpl', data=True)
|
with open(pkg_resources.
|
||||||
|
resource_filename('ebook_converter',
|
||||||
|
'data/html_export_default_index.tmpl')
|
||||||
|
) as fobj:
|
||||||
|
template_html_index_data = fobj.read().decode()
|
||||||
|
|
||||||
if opts.template_html is not None:
|
if opts.template_html is not None:
|
||||||
with open(opts.template_html, 'rb') as f:
|
with open(opts.template_html, 'rb') as f:
|
||||||
template_html_data = f.read()
|
template_html_data = f.read()
|
||||||
else:
|
else:
|
||||||
template_html_data = P('templates/html_export_default.tmpl', data=True)
|
with open(pkg_resources.
|
||||||
|
resource_filename('ebook_converter',
|
||||||
|
'data/html_export_default.tmpl')
|
||||||
|
) as fobj:
|
||||||
|
template_html_data = fobj.read().decode()
|
||||||
|
|
||||||
if opts.template_css is not None:
|
if opts.template_css is not None:
|
||||||
with open(opts.template_css, 'rb') as f:
|
with open(opts.template_css, 'rb') as f:
|
||||||
template_css_data = f.read()
|
template_css_data = f.read()
|
||||||
else:
|
else:
|
||||||
template_css_data = P('templates/html_export_default.css', data=True)
|
with open(pkg_resources.
|
||||||
|
resource_filename('ebook_converter',
|
||||||
|
'data/html_export_default.css')
|
||||||
|
) as fobj:
|
||||||
|
template_css_data = fobj.read().decode()
|
||||||
|
|
||||||
template_html_index_data = template_html_index_data.decode('utf-8')
|
template_html_index_data = template_html_index_data.decode('utf-8')
|
||||||
template_html_data = template_html_data.decode('utf-8')
|
template_html_data = template_html_data.decode('utf-8')
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ __copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
|
|||||||
__docformat__ = 'restructuredtext en'
|
__docformat__ = 'restructuredtext en'
|
||||||
|
|
||||||
import os, sys
|
import os, sys
|
||||||
|
import pkg_resources
|
||||||
|
|
||||||
from ebook_converter.customize.conversion import InputFormatPlugin
|
from ebook_converter.customize.conversion import InputFormatPlugin
|
||||||
|
|
||||||
|
|
||||||
@@ -54,7 +56,12 @@ class LRFInput(InputFormatPlugin):
|
|||||||
plot_map[ro] = imgstr[0].get('file')
|
plot_map[ro] = imgstr[0].get('file')
|
||||||
|
|
||||||
self.log('Converting XML to HTML...')
|
self.log('Converting XML to HTML...')
|
||||||
styledoc = safe_xml_fromstring(P('templates/lrf.xsl', data=True))
|
|
||||||
|
with open(pkg_resources.
|
||||||
|
resource_filename('ebook_converter',
|
||||||
|
'data/lrf.xsl')) as fobj:
|
||||||
|
# TODO(gryf): change this nonsense to etree.parse() instead.
|
||||||
|
styledoc = safe_xml_fromstring(fobj.read())
|
||||||
media_type = MediaType()
|
media_type = MediaType()
|
||||||
styles = Styles()
|
styles = Styles()
|
||||||
text_block = TextBlock(styles, char_button_map, plot_map, log)
|
text_block = TextBlock(styles, char_button_map, plot_map, log)
|
||||||
|
|||||||
@@ -5,29 +5,40 @@ __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
|||||||
|
|
||||||
from PIL import ImageFont
|
from PIL import ImageFont
|
||||||
|
|
||||||
|
from ebook_converter.utils.fonts.scanner import font_scanner
|
||||||
|
|
||||||
'''
|
'''
|
||||||
Default fonts used in the PRS500
|
Default fonts used in the PRS500
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
LIBERATION_FONT_MAP = {
|
LIBERATION_FONT_MAP = {'Swis721 BT Roman': 'Liberation Sans Regular',
|
||||||
'Swis721 BT Roman' : 'LiberationSans-Regular',
|
'Dutch801 Rm BT Roman': 'Liberation Serif Regular',
|
||||||
'Dutch801 Rm BT Roman' : 'LiberationSerif-Regular',
|
'Courier10 BT Roman': 'Liberation Mono Regular'}
|
||||||
'Courier10 BT Roman' : 'LiberationMono-Regular',
|
_LIB_CACHE = {}
|
||||||
}
|
|
||||||
|
|
||||||
FONT_FILE_MAP = {}
|
FONT_FILE_MAP = {}
|
||||||
|
|
||||||
|
|
||||||
def get_font(name, size, encoding='unic'):
|
def get_font(name, size, encoding='unic'):
|
||||||
'''
|
"""
|
||||||
Get an ImageFont object by name.
|
Get an ImageFont object by name.
|
||||||
@param size: Font height in pixels. To convert from pts:
|
@param size: Font height in pixels. To convert from pts:
|
||||||
sz in pixels = (dpi/72) * size in pts
|
sz in pixels = (dpi/72) * size in pts
|
||||||
@param encoding: Font encoding to use. E.g. 'unic', 'symbol', 'ADOB', 'ADBE', 'aprm'
|
@param encoding: Font encoding to use. E.g. 'unic', 'symbol', 'ADOB',
|
||||||
@param manager: A dict that will store the PersistentTemporary
|
'ADBE', 'aprm'
|
||||||
'''
|
"""
|
||||||
if name in LIBERATION_FONT_MAP:
|
if name in LIBERATION_FONT_MAP:
|
||||||
return ImageFont.truetype(P('fonts/liberation/%s.ttf' % LIBERATION_FONT_MAP[name]), size, encoding=encoding)
|
if not _LIB_CACHE:
|
||||||
|
for key in font_scanner.cache['fonts']:
|
||||||
|
record = font_scanner.cache['fonts'][key]
|
||||||
|
_LIB_CACHE[record['family_name'] + ' ' +
|
||||||
|
record['subfamily_name']] = record['path']
|
||||||
|
|
||||||
|
fpath = _LIB_CACHE.get(LIBERATION_FONT_MAP[name])
|
||||||
|
if not fpath:
|
||||||
|
raise ValueError('There is no liberation font existing in the '
|
||||||
|
'system. Please install them before converter '
|
||||||
|
'use.')
|
||||||
|
return ImageFont.truetype(fpath, size, encoding=encoding)
|
||||||
elif name in FONT_FILE_MAP:
|
elif name in FONT_FILE_MAP:
|
||||||
return ImageFont.truetype(FONT_FILE_MAP[name], size, encoding=encoding)
|
return ImageFont.truetype(FONT_FILE_MAP[name], size, encoding=encoding)
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import re
|
|||||||
from collections import Counter, OrderedDict
|
from collections import Counter, OrderedDict
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
|
import pkg_resources
|
||||||
|
|
||||||
from lxml import etree
|
from lxml import etree
|
||||||
from lxml.builder import ElementMaker
|
from lxml.builder import ElementMaker
|
||||||
@@ -690,7 +691,10 @@ def commit_nav_toc(container, toc, lang=None, landmarks=None, previous_nav=None)
|
|||||||
if previous_nav is not None:
|
if previous_nav is not None:
|
||||||
root = previous_nav[1]
|
root = previous_nav[1]
|
||||||
else:
|
else:
|
||||||
root = container.parse_xhtml(P('templates/new_nav.html', data=True).decode('utf-8'))
|
with open(pkg_resources.
|
||||||
|
resource_filename('ebook_converter',
|
||||||
|
'data/new_nav.html')) as fobj:
|
||||||
|
root = container.parse_xhtml(fobj.read())
|
||||||
container.replace(tocname, root)
|
container.replace(tocname, root)
|
||||||
else:
|
else:
|
||||||
root = container.parsed(tocname)
|
root = container.parsed(tocname)
|
||||||
|
|||||||
@@ -9,13 +9,13 @@ __docformat__ = 'restructuredtext en'
|
|||||||
import sys, os, re
|
import sys, os, re
|
||||||
from xml.sax.saxutils import escape
|
from xml.sax.saxutils import escape
|
||||||
from string import Formatter
|
from string import Formatter
|
||||||
|
import pkg_resources
|
||||||
|
|
||||||
from ebook_converter import guess_type, strftime
|
from ebook_converter import guess_type, strftime
|
||||||
from ebook_converter.constants import iswindows
|
from ebook_converter.constants import iswindows
|
||||||
from ebook_converter.ebooks.oeb.base import XPath, XHTML_NS, XHTML, xml2text, urldefrag, urlnormalize
|
from ebook_converter.ebooks.oeb.base import XPath, XHTML_NS, XHTML, xml2text, urldefrag, urlnormalize
|
||||||
from ebook_converter.library.comments import comments_to_html, markdown
|
from ebook_converter.library.comments import comments_to_html, markdown
|
||||||
from ebook_converter.utils.date import is_date_undefined, as_local_time
|
from ebook_converter.utils.date import is_date_undefined, as_local_time
|
||||||
from ebook_converter.utils.icu import sort_key
|
|
||||||
from ebook_converter.ebooks.chardet import strip_encoding_declarations
|
from ebook_converter.ebooks.chardet import strip_encoding_declarations
|
||||||
from ebook_converter.ebooks.metadata import fmt_sidx, rating_to_stars
|
from ebook_converter.ebooks.metadata import fmt_sidx, rating_to_stars
|
||||||
from ebook_converter.polyglot.builtins import unicode_type, map
|
from ebook_converter.polyglot.builtins import unicode_type, map
|
||||||
@@ -196,7 +196,7 @@ class Tags(unicode_type):
|
|||||||
def __new__(self, tags, output_profile):
|
def __new__(self, tags, output_profile):
|
||||||
tags = [escape(x) for x in tags or ()]
|
tags = [escape(x) for x in tags or ()]
|
||||||
t = unicode_type.__new__(self, ', '.join(tags))
|
t = unicode_type.__new__(self, ', '.join(tags))
|
||||||
t.alphabetical = ', '.join(sorted(tags, key=sort_key))
|
t.alphabetical = ', '.join(sorted(tags))
|
||||||
t.tags_list = tags
|
t.tags_list = tags
|
||||||
return t
|
return t
|
||||||
|
|
||||||
@@ -232,8 +232,14 @@ def postprocess_jacket(root, output_profile, has_data):
|
|||||||
def render_jacket(mi, output_profile,
|
def render_jacket(mi, output_profile,
|
||||||
alt_title=_('Unknown'), alt_tags=[], alt_comments='',
|
alt_title=_('Unknown'), alt_tags=[], alt_comments='',
|
||||||
alt_publisher='', rescale_fonts=False, alt_authors=None):
|
alt_publisher='', rescale_fonts=False, alt_authors=None):
|
||||||
css = P('jacket/stylesheet.css', data=True).decode('utf-8')
|
with open(pkg_resources.resource_filename('ebook_converter',
|
||||||
template = P('jacket/template.xhtml', data=True).decode('utf-8')
|
'data/jacket/stylesheet.css'),
|
||||||
|
'rb') as fobj:
|
||||||
|
css = fobj.read().decode()
|
||||||
|
with open(pkg_resources.resource_filename('ebook_converter',
|
||||||
|
'data/jacket/template.xhtml'),
|
||||||
|
'rb') as fobj:
|
||||||
|
template = fobj.read().decode()
|
||||||
|
|
||||||
template = re.sub(r'<!--.*?-->', '', template, flags=re.DOTALL)
|
template = re.sub(r'<!--.*?-->', '', template, flags=re.DOTALL)
|
||||||
css = re.sub(r'/\*.*?\*/', '', css, flags=re.DOTALL)
|
css = re.sub(r'/\*.*?\*/', '', css, flags=re.DOTALL)
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ __license__ = 'GPL v3'
|
|||||||
__copyright__ = '2014, Kovid Goyal <kovid at kovidgoyal.net>'
|
__copyright__ = '2014, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
import json
|
||||||
|
import pkg_resources
|
||||||
|
|
||||||
from ebook_converter.utils.localization import canonicalize_lang
|
from ebook_converter.utils.localization import canonicalize_lang
|
||||||
|
|
||||||
@@ -17,9 +19,31 @@ ccodes, ccodemap, country_names = None, None, None
|
|||||||
def get_codes():
|
def get_codes():
|
||||||
global ccodes, ccodemap, country_names
|
global ccodes, ccodemap, country_names
|
||||||
if ccodes is None:
|
if ccodes is None:
|
||||||
from ebook_converter.utils.serialize import msgpack_loads
|
src = pkg_resources.resource_filename('ebook_converter',
|
||||||
data = msgpack_loads(P('localization/iso3166.calibre_msgpack', allow_user_override=False, data=True))
|
'data/iso_3166-1.json')
|
||||||
ccodes, ccodemap, country_names = data['codes'], data['three_map'], data['names']
|
with open(src, 'rb') as f:
|
||||||
|
db = json.load(f)
|
||||||
|
codes = set()
|
||||||
|
three_map = {}
|
||||||
|
name_map = {}
|
||||||
|
unicode_type = type(u'')
|
||||||
|
for x in db['3166-1']:
|
||||||
|
two = x.get('alpha_2')
|
||||||
|
if two:
|
||||||
|
two = unicode_type(two)
|
||||||
|
codes.add(two)
|
||||||
|
name_map[two] = x.get('name')
|
||||||
|
if name_map[two]:
|
||||||
|
name_map[two] = unicode_type(name_map[two])
|
||||||
|
three = x.get('alpha_3')
|
||||||
|
if three:
|
||||||
|
three_map[unicode_type(three)] = two
|
||||||
|
data = {'names': name_map,
|
||||||
|
'codes': frozenset(codes),
|
||||||
|
'three_map': three_map}
|
||||||
|
|
||||||
|
ccodes, ccodemap, country_names = (data['codes'], data['three_map'],
|
||||||
|
data['names'])
|
||||||
return ccodes, ccodemap
|
return ccodes, ccodemap
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import os, re, traceback, numbers
|
|||||||
from functools import partial
|
from functools import partial
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
|
import pkg_resources
|
||||||
|
|
||||||
from ebook_converter.utils.lock import ExclusiveFile
|
from ebook_converter.utils.lock import ExclusiveFile
|
||||||
from ebook_converter.constants import config_dir, CONFIG_DIR_MODE, ispy3, preferred_encoding, filesystem_encoding, iswindows
|
from ebook_converter.constants import config_dir, CONFIG_DIR_MODE, ispy3, preferred_encoding, filesystem_encoding, iswindows
|
||||||
@@ -634,7 +635,9 @@ def read_custom_tweaks():
|
|||||||
|
|
||||||
|
|
||||||
def default_tweaks_raw():
|
def default_tweaks_raw():
|
||||||
return P('default_tweaks.py', data=True, allow_user_override=False)
|
with open(pkg_resources.resource_filename('ebook_converter',
|
||||||
|
'data/default_tweaks.py')) as f:
|
||||||
|
return f.read().encode()
|
||||||
|
|
||||||
|
|
||||||
def read_tweaks():
|
def read_tweaks():
|
||||||
|
|||||||
@@ -195,8 +195,7 @@ class FontScanner(Thread):
|
|||||||
|
|
||||||
def __init__(self, folders=[], allowed_extensions={'ttf', 'otf'}):
|
def __init__(self, folders=[], allowed_extensions={'ttf', 'otf'}):
|
||||||
Thread.__init__(self)
|
Thread.__init__(self)
|
||||||
self.folders = folders + font_dirs() + [os.path.join(config_dir, 'fonts'),
|
self.folders = folders + font_dirs()
|
||||||
P('fonts/liberation')]
|
|
||||||
self.folders = [os.path.normcase(os.path.abspath(font)) for font in
|
self.folders = [os.path.normcase(os.path.abspath(font)) for font in
|
||||||
self.folders]
|
self.folders]
|
||||||
self.font_families = ()
|
self.font_families = ()
|
||||||
|
|||||||
@@ -451,6 +451,7 @@ def get_font_for_text(text, candidate_font_data=None):
|
|||||||
|
|
||||||
def test_glyph_ids():
|
def test_glyph_ids():
|
||||||
from ebook_converter.utils.fonts.free_type import FreeType
|
from ebook_converter.utils.fonts.free_type import FreeType
|
||||||
|
# TODO(gryf): move this test to test files
|
||||||
data = P('fonts/liberation/LiberationSerif-Regular.ttf', data=True)
|
data = P('fonts/liberation/LiberationSerif-Regular.ttf', data=True)
|
||||||
ft = FreeType()
|
ft = FreeType()
|
||||||
font = ft.load_font(data)
|
font = ft.load_font(data)
|
||||||
@@ -462,6 +463,7 @@ def test_glyph_ids():
|
|||||||
|
|
||||||
|
|
||||||
def test_supports_text():
|
def test_supports_text():
|
||||||
|
# TODO(gryf): move this test to test files
|
||||||
data = P('fonts/calibreSymbols.otf', data=True)
|
data = P('fonts/calibreSymbols.otf', data=True)
|
||||||
if not supports_text(data, '.★½'):
|
if not supports_text(data, '.★½'):
|
||||||
raise RuntimeError('Incorrectly returning that text is not supported')
|
raise RuntimeError('Incorrectly returning that text is not supported')
|
||||||
@@ -470,6 +472,7 @@ def test_supports_text():
|
|||||||
|
|
||||||
|
|
||||||
def test_find_font():
|
def test_find_font():
|
||||||
|
# TODO(gryf): move this test to test files
|
||||||
from ebook_converter.utils.fonts.scanner import font_scanner
|
from ebook_converter.utils.fonts.scanner import font_scanner
|
||||||
abcd = '诶比西迪'
|
abcd = '诶比西迪'
|
||||||
family = font_scanner.find_font_for_text(abcd)[0]
|
family = font_scanner.find_font_for_text(abcd)[0]
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ __license__ = 'GPL v3'
|
|||||||
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
|
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||||
__docformat__ = 'restructuredtext en'
|
__docformat__ = 'restructuredtext en'
|
||||||
|
|
||||||
import os, locale, re, io, sys
|
import re, io, sys
|
||||||
import json
|
import json
|
||||||
from gettext import GNUTranslations, NullTranslations
|
from gettext import GNUTranslations, NullTranslations
|
||||||
import pkg_resources
|
import pkg_resources
|
||||||
@@ -12,64 +12,6 @@ from ebook_converter.polyglot.builtins import is_py3, iteritems, unicode_type
|
|||||||
_available_translations = None
|
_available_translations = None
|
||||||
|
|
||||||
|
|
||||||
def available_translations():
|
|
||||||
global _available_translations
|
|
||||||
if _available_translations is None:
|
|
||||||
stats = P('localization/stats.calibre_msgpack', allow_user_override=False)
|
|
||||||
if os.path.exists(stats):
|
|
||||||
from ebook_converter.utils.serialize import msgpack_loads
|
|
||||||
with open(stats, 'rb') as f:
|
|
||||||
stats = msgpack_loads(f.read())
|
|
||||||
else:
|
|
||||||
stats = {}
|
|
||||||
_available_translations = [x for x in stats if stats[x] > 0.1]
|
|
||||||
return _available_translations
|
|
||||||
|
|
||||||
|
|
||||||
def get_system_locale():
|
|
||||||
from ebook_converter.constants import iswindows, isosx, plugins
|
|
||||||
lang = None
|
|
||||||
if iswindows:
|
|
||||||
try:
|
|
||||||
from ebook_converter.constants import get_windows_user_locale_name
|
|
||||||
lang = get_windows_user_locale_name()
|
|
||||||
lang = lang.strip()
|
|
||||||
if not lang:
|
|
||||||
lang = None
|
|
||||||
except:
|
|
||||||
pass # Windows XP does not have the GetUserDefaultLocaleName fn
|
|
||||||
elif isosx:
|
|
||||||
try:
|
|
||||||
lang = plugins['usbobserver'][0].user_locale() or None
|
|
||||||
except:
|
|
||||||
# Fallback to environment vars if something bad happened
|
|
||||||
import traceback
|
|
||||||
traceback.print_exc()
|
|
||||||
if lang is None:
|
|
||||||
try:
|
|
||||||
envvars = ['LANGUAGE', 'LC_ALL', 'LC_CTYPE', 'LC_MESSAGES', 'LANG']
|
|
||||||
lang = locale.getdefaultlocale(envvars)[0]
|
|
||||||
|
|
||||||
# lang is None in two cases: either the environment variable is not
|
|
||||||
# set or it's "C". Stop looking for a language in the latter case.
|
|
||||||
if lang is None:
|
|
||||||
for var in envvars:
|
|
||||||
if os.environ.get(var) == 'C':
|
|
||||||
lang = 'en_US'
|
|
||||||
break
|
|
||||||
except:
|
|
||||||
pass # This happens on Ubuntu apparently
|
|
||||||
if lang is None and 'LANG' in os.environ: # Needed for OS X
|
|
||||||
try:
|
|
||||||
lang = os.environ['LANG']
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
if lang:
|
|
||||||
lang = lang.replace('-', '_')
|
|
||||||
lang = '_'.join(lang.split('_')[:2])
|
|
||||||
return lang
|
|
||||||
|
|
||||||
|
|
||||||
def sanitize_lang(lang):
|
def sanitize_lang(lang):
|
||||||
if lang:
|
if lang:
|
||||||
match = re.match('[a-z]{2,3}(_[A-Z]{2}){0,1}', lang)
|
match = re.match('[a-z]{2,3}(_[A-Z]{2}){0,1}', lang)
|
||||||
@@ -83,101 +25,16 @@ def sanitize_lang(lang):
|
|||||||
|
|
||||||
|
|
||||||
def get_lang():
|
def get_lang():
|
||||||
'Try to figure out what language to display the interface in'
|
return 'en_US'
|
||||||
from ebook_converter.utils.config_base import prefs
|
|
||||||
lang = prefs['language']
|
|
||||||
lang = os.environ.get('CALIBRE_OVERRIDE_LANG', lang)
|
|
||||||
if lang:
|
|
||||||
return lang
|
|
||||||
try:
|
|
||||||
lang = get_system_locale()
|
|
||||||
except:
|
|
||||||
import traceback
|
|
||||||
traceback.print_exc()
|
|
||||||
lang = None
|
|
||||||
return sanitize_lang(lang)
|
|
||||||
|
|
||||||
|
|
||||||
def is_rtl():
|
def is_rtl():
|
||||||
return get_lang()[:2].lower() in {'he', 'ar'}
|
return get_lang()[:2].lower() in {'he', 'ar'}
|
||||||
|
|
||||||
|
|
||||||
def get_lc_messages_path(lang):
|
|
||||||
hlang = None
|
|
||||||
if zf_exists():
|
|
||||||
if lang in available_translations():
|
|
||||||
hlang = lang
|
|
||||||
else:
|
|
||||||
xlang = lang.split('_')[0].lower()
|
|
||||||
if xlang in available_translations():
|
|
||||||
hlang = xlang
|
|
||||||
return hlang
|
|
||||||
|
|
||||||
|
|
||||||
def zf_exists():
|
|
||||||
return os.path.exists(P('localization/locales.zip',
|
|
||||||
allow_user_override=False))
|
|
||||||
|
|
||||||
|
|
||||||
_lang_trans = None
|
_lang_trans = None
|
||||||
|
|
||||||
|
|
||||||
def get_all_translators():
|
|
||||||
from zipfile import ZipFile
|
|
||||||
with ZipFile(P('localization/locales.zip', allow_user_override=False), 'r') as zf:
|
|
||||||
for lang in available_translations():
|
|
||||||
mpath = get_lc_messages_path(lang)
|
|
||||||
if mpath is not None:
|
|
||||||
buf = io.BytesIO(zf.read(mpath + '/messages.mo'))
|
|
||||||
yield lang, GNUTranslations(buf)
|
|
||||||
|
|
||||||
|
|
||||||
def get_single_translator(mpath, which='messages'):
|
|
||||||
from zipfile import ZipFile
|
|
||||||
with ZipFile(P('localization/locales.zip', allow_user_override=False), 'r') as zf:
|
|
||||||
path = '{}/{}.mo'.format(mpath, which)
|
|
||||||
data = zf.read(path)
|
|
||||||
buf = io.BytesIO(data)
|
|
||||||
try:
|
|
||||||
return GNUTranslations(buf)
|
|
||||||
except Exception as e:
|
|
||||||
import traceback
|
|
||||||
traceback.print_exc()
|
|
||||||
import hashlib
|
|
||||||
sig = hashlib.sha1(data).hexdigest()
|
|
||||||
raise ValueError('Failed to load translations for: {} (size: {} and signature: {}) with error: {}'.format(
|
|
||||||
path, len(data), sig, e))
|
|
||||||
|
|
||||||
|
|
||||||
def get_iso639_translator(lang):
|
|
||||||
lang = sanitize_lang(lang)
|
|
||||||
mpath = get_lc_messages_path(lang) if lang else None
|
|
||||||
return get_single_translator(mpath, 'iso639') if mpath else None
|
|
||||||
|
|
||||||
|
|
||||||
def get_translator(bcp_47_code):
|
|
||||||
parts = bcp_47_code.replace('-', '_').split('_')[:2]
|
|
||||||
parts[0] = lang_as_iso639_1(parts[0].lower()) or 'en'
|
|
||||||
if len(parts) > 1:
|
|
||||||
parts[1] = parts[1].upper()
|
|
||||||
lang = '_'.join(parts)
|
|
||||||
lang = {'pt':'pt_BR', 'zh':'zh_CN'}.get(lang, lang)
|
|
||||||
available = available_translations()
|
|
||||||
found = True
|
|
||||||
if lang == 'en' or lang.startswith('en_'):
|
|
||||||
return found, lang, NullTranslations()
|
|
||||||
if lang not in available:
|
|
||||||
lang = {'pt':'pt_BR', 'zh':'zh_CN'}.get(parts[0], parts[0])
|
|
||||||
if lang not in available:
|
|
||||||
lang = get_lang()
|
|
||||||
if lang not in available:
|
|
||||||
lang = 'en'
|
|
||||||
found = False
|
|
||||||
if lang == 'en':
|
|
||||||
return True, lang, NullTranslations()
|
|
||||||
return found, lang, get_single_translator(lang)
|
|
||||||
|
|
||||||
|
|
||||||
lcdata = {
|
lcdata = {
|
||||||
'abday': ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'),
|
'abday': ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'),
|
||||||
'abmon': ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'),
|
'abmon': ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'),
|
||||||
@@ -208,62 +65,9 @@ def load_po(path):
|
|||||||
|
|
||||||
|
|
||||||
def set_translators():
|
def set_translators():
|
||||||
global _lang_trans, lcdata
|
t = NullTranslations()
|
||||||
# To test different translations invoke as
|
set_translators.lang = t.info().get('language')
|
||||||
# CALIBRE_OVERRIDE_LANG=de_DE.utf8 program
|
t.install(names=('ngettext',))
|
||||||
lang = get_lang()
|
|
||||||
t = buf = iso639 = None
|
|
||||||
|
|
||||||
if 'CALIBRE_TEST_TRANSLATION' in os.environ:
|
|
||||||
buf = load_po(os.path.expanduser(os.environ['CALIBRE_TEST_TRANSLATION']))
|
|
||||||
|
|
||||||
if lang:
|
|
||||||
mpath = get_lc_messages_path(lang)
|
|
||||||
if buf is None and mpath and os.access(mpath + '.po', os.R_OK):
|
|
||||||
buf = load_po(mpath + '.po')
|
|
||||||
|
|
||||||
if mpath is not None:
|
|
||||||
from zipfile import ZipFile
|
|
||||||
with ZipFile(P('localization/locales.zip',
|
|
||||||
allow_user_override=False), 'r') as zf:
|
|
||||||
if buf is None:
|
|
||||||
buf = io.BytesIO(zf.read(mpath + '/messages.mo'))
|
|
||||||
if mpath == 'nds':
|
|
||||||
mpath = 'de'
|
|
||||||
isof = mpath + '/iso639.mo'
|
|
||||||
try:
|
|
||||||
iso639 = io.BytesIO(zf.read(isof))
|
|
||||||
except:
|
|
||||||
pass # No iso639 translations for this lang
|
|
||||||
if buf is not None:
|
|
||||||
from ebook_converter.utils.serialize import msgpack_loads
|
|
||||||
try:
|
|
||||||
lcdata = msgpack_loads(zf.read(mpath + '/lcdata.calibre_msgpack'))
|
|
||||||
except:
|
|
||||||
pass # No lcdata
|
|
||||||
|
|
||||||
if buf is not None:
|
|
||||||
t = GNUTranslations(buf)
|
|
||||||
if iso639 is not None:
|
|
||||||
iso639 = _lang_trans = GNUTranslations(iso639)
|
|
||||||
t.add_fallback(iso639)
|
|
||||||
|
|
||||||
if t is None:
|
|
||||||
t = NullTranslations()
|
|
||||||
|
|
||||||
try:
|
|
||||||
set_translators.lang = t.info().get('language')
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
if is_py3:
|
|
||||||
t.install(names=('ngettext',))
|
|
||||||
else:
|
|
||||||
t.install(unicode=True, names=('ngettext',))
|
|
||||||
# Now that we have installed a translator, we have to retranslate the help
|
|
||||||
# for the global prefs object as it was instantiated in get_lang(), before
|
|
||||||
# the translator was installed.
|
|
||||||
from ebook_converter.utils.config_base import prefs
|
|
||||||
prefs.retranslate_help()
|
|
||||||
|
|
||||||
|
|
||||||
set_translators.lang = None
|
set_translators.lang = None
|
||||||
@@ -535,53 +339,5 @@ def get_udc():
|
|||||||
return _udc
|
return _udc
|
||||||
|
|
||||||
|
|
||||||
def user_manual_stats():
|
|
||||||
stats = getattr(user_manual_stats, 'stats', None)
|
|
||||||
if stats is None:
|
|
||||||
import json
|
|
||||||
try:
|
|
||||||
stats = json.loads(P('user-manual-translation-stats.json', allow_user_override=False, data=True))
|
|
||||||
except EnvironmentError:
|
|
||||||
stats = {}
|
|
||||||
user_manual_stats.stats = stats
|
|
||||||
return stats
|
|
||||||
|
|
||||||
|
|
||||||
def localize_user_manual_link(url):
|
def localize_user_manual_link(url):
|
||||||
#lc = lang_as_iso639_1(get_lang())
|
|
||||||
# if lc == 'en':
|
|
||||||
return url
|
return url
|
||||||
# stats = user_manual_stats()
|
|
||||||
# if stats.get(lc, 0) < 0.3:
|
|
||||||
# return url
|
|
||||||
# from polyglot.urllib import urlparse, urlunparse
|
|
||||||
# parts = urlparse(url)
|
|
||||||
# path = re.sub(r'/generated/[a-z]+/', '/generated/%s/' % lc, parts.path or '')
|
|
||||||
# path = '/%s%s' % (lc, path)
|
|
||||||
# parts = list(parts)
|
|
||||||
# parts[2] = path
|
|
||||||
# return urlunparse(parts)
|
|
||||||
|
|
||||||
|
|
||||||
def website_languages():
|
|
||||||
stats = getattr(website_languages, 'stats', None)
|
|
||||||
if stats is None:
|
|
||||||
try:
|
|
||||||
stats = frozenset(P('localization/website-languages.txt', allow_user_override=False, data=True).split())
|
|
||||||
except EnvironmentError:
|
|
||||||
stats = frozenset()
|
|
||||||
website_languages.stats = stats
|
|
||||||
return stats
|
|
||||||
|
|
||||||
|
|
||||||
def localize_website_link(url):
|
|
||||||
lc = lang_as_iso639_1(get_lang())
|
|
||||||
langs = website_languages()
|
|
||||||
if lc == 'en' or lc not in langs:
|
|
||||||
return url
|
|
||||||
from ebook_converter.polyglot.urllib import urlparse, urlunparse
|
|
||||||
parts = urlparse(url)
|
|
||||||
path = '/{}{}'.format(lc, parts.path)
|
|
||||||
parts = list(parts)
|
|
||||||
parts[2] = path
|
|
||||||
return urlunparse(parts)
|
|
||||||
|
|||||||
Reference in New Issue
Block a user