mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Merge from trunk
This commit is contained in:
commit
4122a6dea8
Binary file not shown.
71
resources/recipes/china_press.recipe
Normal file
71
resources/recipes/china_press.recipe
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
class AdvancedUserRecipe1277228948(BasicNewsRecipe):
|
||||||
|
title = u'China Press USA'
|
||||||
|
oldest_article = 7
|
||||||
|
max_articles_per_feed = 100
|
||||||
|
|
||||||
|
__author__ = 'rty'
|
||||||
|
__version__ = '1.0'
|
||||||
|
language = 'zh_CN'
|
||||||
|
pubisher = 'www.chinapressusa.com'
|
||||||
|
description = 'Overseas Chinese Network Newspaper in the USA'
|
||||||
|
category = 'News in Chinese, USA'
|
||||||
|
remove_javascript = True
|
||||||
|
use_embedded_content = False
|
||||||
|
no_stylesheets = True
|
||||||
|
#encoding = 'GB2312'
|
||||||
|
encoding = 'UTF-8'
|
||||||
|
conversion_options = {'linearize_tables':True}
|
||||||
|
masthead_url ='http://www.chinapressusa.com/common/images/logo.gif'
|
||||||
|
extra_css = '''
|
||||||
|
@font-face { font-family: "DroidFont", serif, sans-serif; src: url(res:///system/fonts/DroidSansFallback.ttf); }\n
|
||||||
|
body {
|
||||||
|
margin-right: 8pt;
|
||||||
|
font-family: 'DroidFont', serif;}
|
||||||
|
h1 {font-family: 'DroidFont', serif, sans-serif}
|
||||||
|
.show {font-family: 'DroidFont', serif, sans-serif}
|
||||||
|
'''
|
||||||
|
feeds = [
|
||||||
|
(u'\u65b0\u95fb\u9891\u9053', u'http://news.uschinapress.com/news.xml'),
|
||||||
|
(u'\u534e\u4eba\u9891\u9053', u'http://chinese.uschinapress.com/chinese.xml'),
|
||||||
|
(u'\u8bc4\u8bba\u9891\u9053', u'http://review.uschinapress.com/review.xml'),
|
||||||
|
]
|
||||||
|
keep_only_tags = [
|
||||||
|
dict(name='div', attrs={'class':'show'}),
|
||||||
|
]
|
||||||
|
remove_tags = [
|
||||||
|
# dict(name='table', attrs={'class':'xle'}),
|
||||||
|
dict(name='div', attrs={'class':'time'}),
|
||||||
|
]
|
||||||
|
remove_tags_after = [
|
||||||
|
dict(name='div', attrs={'class':'bank17'}),
|
||||||
|
# dict(name='a', attrs={'class':'ab12'}),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def append_page(self, soup, appendtag, position):
|
||||||
|
pager = soup.find('div',attrs={'id':'displaypagenum'})
|
||||||
|
if pager:
|
||||||
|
nexturl = self.INDEX + pager.a['href']
|
||||||
|
soup2 = self.index_to_soup(nexturl)
|
||||||
|
texttag = soup2.find('div', attrs={'class':'show'})
|
||||||
|
for it in texttag.findAll(style=True):
|
||||||
|
del it['style']
|
||||||
|
newpos = len(texttag.contents)
|
||||||
|
self.append_page(soup2,texttag,newpos)
|
||||||
|
texttag.extract()
|
||||||
|
appendtag.insert(position,texttag)
|
||||||
|
|
||||||
|
|
||||||
|
def preprocess_html(self, soup):
|
||||||
|
mtag = '<meta http-equiv="Content-Language" content="zh-CN"/>\n<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>'
|
||||||
|
soup.head.insert(0,mtag)
|
||||||
|
|
||||||
|
for item in soup.findAll(style=True):
|
||||||
|
del item['style']
|
||||||
|
self.append_page(soup, soup.body, 3)
|
||||||
|
pager = soup.find('div',attrs={'id':'displaypagenum'})
|
||||||
|
if pager:
|
||||||
|
pager.extract()
|
||||||
|
return soup
|
@ -372,7 +372,7 @@ class DevicePlugin(Plugin):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def settings(cls):
|
def settings(cls):
|
||||||
'''
|
'''
|
||||||
Should return an opts object. The opts object should have one attribute
|
Should return an opts object. The opts object should have at least one attribute
|
||||||
`format_map` which is an ordered list of formats for the device.
|
`format_map` which is an ordered list of formats for the device.
|
||||||
'''
|
'''
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
@ -282,7 +282,7 @@ class MetaInformation(object):
|
|||||||
for attr in ('author_sort', 'title_sort', 'category',
|
for attr in ('author_sort', 'title_sort', 'category',
|
||||||
'publisher', 'series', 'series_index', 'rating',
|
'publisher', 'series', 'series_index', 'rating',
|
||||||
'isbn', 'application_id', 'manifest', 'spine', 'toc',
|
'isbn', 'application_id', 'manifest', 'spine', 'toc',
|
||||||
'cover', 'language', 'guide', 'book_producer',
|
'cover', 'guide', 'book_producer',
|
||||||
'timestamp', 'lccn', 'lcc', 'ddc', 'pubdate', 'rights',
|
'timestamp', 'lccn', 'lcc', 'ddc', 'pubdate', 'rights',
|
||||||
'publication_type', 'uuid'):
|
'publication_type', 'uuid'):
|
||||||
if hasattr(mi, attr):
|
if hasattr(mi, attr):
|
||||||
@ -314,6 +314,11 @@ class MetaInformation(object):
|
|||||||
if len(other_comments.strip()) > len(my_comments.strip()):
|
if len(other_comments.strip()) > len(my_comments.strip()):
|
||||||
self.comments = other_comments
|
self.comments = other_comments
|
||||||
|
|
||||||
|
other_lang = getattr(mi, 'language', None)
|
||||||
|
if other_lang and other_lang.lower() != 'und':
|
||||||
|
self.language = other_lang
|
||||||
|
|
||||||
|
|
||||||
def format_series_index(self):
|
def format_series_index(self):
|
||||||
try:
|
try:
|
||||||
x = float(self.series_index)
|
x = float(self.series_index)
|
||||||
|
@ -18,7 +18,7 @@ from calibre.constants import __appname__, __version__, filesystem_encoding
|
|||||||
from calibre.ebooks.metadata.toc import TOC
|
from calibre.ebooks.metadata.toc import TOC
|
||||||
from calibre.ebooks.metadata import MetaInformation, string_to_authors
|
from calibre.ebooks.metadata import MetaInformation, string_to_authors
|
||||||
from calibre.utils.date import parse_date, isoformat
|
from calibre.utils.date import parse_date, isoformat
|
||||||
|
from calibre.utils.localization import get_lang
|
||||||
|
|
||||||
class Resource(object):
|
class Resource(object):
|
||||||
'''
|
'''
|
||||||
@ -1069,7 +1069,7 @@ class OPFCreator(MetaInformation):
|
|||||||
dc_attrs={'id':__appname__+'_id'}))
|
dc_attrs={'id':__appname__+'_id'}))
|
||||||
if getattr(self, 'pubdate', None) is not None:
|
if getattr(self, 'pubdate', None) is not None:
|
||||||
a(DC_ELEM('date', self.pubdate.isoformat()))
|
a(DC_ELEM('date', self.pubdate.isoformat()))
|
||||||
a(DC_ELEM('language', self.language if self.language else 'UND'))
|
a(DC_ELEM('language', self.language if self.language else get_lang()))
|
||||||
if self.comments:
|
if self.comments:
|
||||||
a(DC_ELEM('description', self.comments))
|
a(DC_ELEM('description', self.comments))
|
||||||
if self.publisher:
|
if self.publisher:
|
||||||
@ -1184,7 +1184,6 @@ def metadata_to_opf(mi, as_string=True):
|
|||||||
factory(DC('contributor'), mi.book_producer, __appname__, 'bkp')
|
factory(DC('contributor'), mi.book_producer, __appname__, 'bkp')
|
||||||
if hasattr(mi.pubdate, 'isoformat'):
|
if hasattr(mi.pubdate, 'isoformat'):
|
||||||
factory(DC('date'), isoformat(mi.pubdate))
|
factory(DC('date'), isoformat(mi.pubdate))
|
||||||
factory(DC('language'), mi.language)
|
|
||||||
if mi.category:
|
if mi.category:
|
||||||
factory(DC('type'), mi.category)
|
factory(DC('type'), mi.category)
|
||||||
if mi.comments:
|
if mi.comments:
|
||||||
@ -1195,6 +1194,7 @@ def metadata_to_opf(mi, as_string=True):
|
|||||||
factory(DC('identifier'), mi.isbn, scheme='ISBN')
|
factory(DC('identifier'), mi.isbn, scheme='ISBN')
|
||||||
if mi.rights:
|
if mi.rights:
|
||||||
factory(DC('rights'), mi.rights)
|
factory(DC('rights'), mi.rights)
|
||||||
|
factory(DC('language'), mi.language if mi.language and mi.language.lower() != 'und' else get_lang())
|
||||||
if mi.tags:
|
if mi.tags:
|
||||||
for tag in mi.tags:
|
for tag in mi.tags:
|
||||||
factory(DC('subject'), tag)
|
factory(DC('subject'), tag)
|
||||||
|
@ -957,16 +957,19 @@ class LayoutButton(QToolButton):
|
|||||||
|
|
||||||
self.splitter = splitter
|
self.splitter = splitter
|
||||||
splitter.state_changed.connect(self.update_state)
|
splitter.state_changed.connect(self.update_state)
|
||||||
|
self.setCursor(Qt.PointingHandCursor)
|
||||||
|
|
||||||
def set_state_to_show(self, *args):
|
def set_state_to_show(self, *args):
|
||||||
self.setChecked(False)
|
self.setChecked(False)
|
||||||
label =_('Show')
|
label =_('Show')
|
||||||
self.setText(label + ' ' + self.label)
|
self.setText(label + ' ' + self.label)
|
||||||
|
self.setToolTip(self.text())
|
||||||
|
|
||||||
def set_state_to_hide(self, *args):
|
def set_state_to_hide(self, *args):
|
||||||
self.setChecked(True)
|
self.setChecked(True)
|
||||||
label = _('Hide')
|
label = _('Hide')
|
||||||
self.setText(label + ' ' + self.label)
|
self.setText(label + ' ' + self.label)
|
||||||
|
self.setToolTip(self.text())
|
||||||
|
|
||||||
def update_state(self, *args):
|
def update_state(self, *args):
|
||||||
if self.splitter.is_side_index_hidden:
|
if self.splitter.is_side_index_hidden:
|
||||||
|
@ -100,9 +100,8 @@ html_use_smartypants = True
|
|||||||
html_title = 'calibre User Manual'
|
html_title = 'calibre User Manual'
|
||||||
html_short_title = 'Start'
|
html_short_title = 'Start'
|
||||||
html_logo = 'resources/logo.png'
|
html_logo = 'resources/logo.png'
|
||||||
epub_titlepage = 'resources/titlepage.html'
|
|
||||||
epub_logo = 'resources/logo.png'
|
|
||||||
epub_author = 'Kovid Goyal'
|
epub_author = 'Kovid Goyal'
|
||||||
|
epub_cover = 'resources/epub_cover.jpg'
|
||||||
|
|
||||||
# Custom sidebar templates, maps document names to template names.
|
# Custom sidebar templates, maps document names to template names.
|
||||||
#html_sidebars = {}
|
#html_sidebars = {}
|
||||||
|
@ -304,9 +304,8 @@ def auto_member(dirname, arguments, options, content, lineno,
|
|||||||
return list(node)
|
return list(node)
|
||||||
|
|
||||||
def setup(app):
|
def setup(app):
|
||||||
app.add_config_value('epub_titlepage', None, False)
|
app.add_config_value('epub_cover', None, False)
|
||||||
app.add_config_value('epub_author', '', False)
|
app.add_config_value('epub_author', '', False)
|
||||||
app.add_config_value('epub_logo', None, False)
|
|
||||||
app.add_builder(CustomBuilder)
|
app.add_builder(CustomBuilder)
|
||||||
app.add_builder(CustomQtBuild)
|
app.add_builder(CustomQtBuild)
|
||||||
app.add_builder(EPUBHelpBuilder)
|
app.add_builder(EPUBHelpBuilder)
|
||||||
|
@ -50,6 +50,7 @@ OPF = '''\
|
|||||||
<dc:identifier opf:scheme="sphinx" id="sphinx_id">{uid}</dc:identifier>
|
<dc:identifier opf:scheme="sphinx" id="sphinx_id">{uid}</dc:identifier>
|
||||||
<dc:date>{date}</dc:date>
|
<dc:date>{date}</dc:date>
|
||||||
<meta name="calibre:publication_type" content="sphinx_manual" />
|
<meta name="calibre:publication_type" content="sphinx_manual" />
|
||||||
|
<meta name="cover" content="cover"/>
|
||||||
</metadata>
|
</metadata>
|
||||||
<manifest>
|
<manifest>
|
||||||
{manifest}
|
{manifest}
|
||||||
@ -71,6 +72,29 @@ CONTAINER='''\
|
|||||||
</rootfiles>
|
</rootfiles>
|
||||||
</container>
|
</container>
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
SVG_TEMPLATE = '''\
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
<meta name="calibre:cover" content="true" />
|
||||||
|
<title>Cover</title>
|
||||||
|
<style type="text/css" title="override_css">
|
||||||
|
@page {padding: 0pt; margin:0pt}
|
||||||
|
body { text-align: center; padding:0pt; margin: 0pt; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
width="100%%" height="100%%" viewBox="0 0 600 800"
|
||||||
|
preserveAspectRatio="none">
|
||||||
|
<image width="600" height="800" xlink:href="%s"/>
|
||||||
|
</svg>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
'''
|
||||||
|
|
||||||
class TOC(list):
|
class TOC(list):
|
||||||
|
|
||||||
def __init__(self, title=None, href=None):
|
def __init__(self, title=None, href=None):
|
||||||
@ -151,8 +175,6 @@ class EPUBHelpBuilder(StandaloneHTMLBuilder):
|
|||||||
spine = [' '*8+'<itemref idref=%s />'%quoteattr(x) for x in self.spine]
|
spine = [' '*8+'<itemref idref=%s />'%quoteattr(x) for x in self.spine]
|
||||||
spine = '\n'.join(spine)
|
spine = '\n'.join(spine)
|
||||||
guide = ''
|
guide = ''
|
||||||
if self.conf.epub_titlepage:
|
|
||||||
guide = ' '*8 + '<reference type="cover" href="_static/titlepage.html" />'
|
|
||||||
|
|
||||||
opf = OPF.format(title=escape(self.conf.html_title),
|
opf = OPF.format(title=escape(self.conf.html_title),
|
||||||
author=escape(self.conf.epub_author), uid=str(uuid.uuid4()),
|
author=escape(self.conf.epub_author), uid=str(uuid.uuid4()),
|
||||||
@ -162,18 +184,15 @@ class EPUBHelpBuilder(StandaloneHTMLBuilder):
|
|||||||
self.manifest['content.opf'] = ('application/oebps-package+xml', 'opf')
|
self.manifest['content.opf'] = ('application/oebps-package+xml', 'opf')
|
||||||
|
|
||||||
def create_titlepage(self):
|
def create_titlepage(self):
|
||||||
if self.conf.epub_titlepage:
|
self.cover_image_url = None
|
||||||
img = ''
|
if self.conf.epub_cover:
|
||||||
if self.conf.epub_logo:
|
img = '_static/'+os.path.basename(self.conf.epub_cover)
|
||||||
img = '_static/epub_logo'+os.path.splitext(self.conf.epub_logo)[1]
|
shutil.copyfile(self.conf.epub_cover, os.path.join(self.html_outdir,
|
||||||
shutil.copyfile(self.conf.epub_logo,
|
*img.split('/')))
|
||||||
os.path.join(self.html_outdir, *img.split('/')))
|
self.cover_image_url = img
|
||||||
raw = open(self.conf.epub_titlepage, 'rb').read()
|
tp = SVG_TEMPLATE%img.split('/')[-1]
|
||||||
raw = raw%dict(title=self.conf.html_title,
|
open(os.path.join(self.html_outdir, '_static', 'titlepage.html'),
|
||||||
version=self.conf.version,
|
'wb').write(tp)
|
||||||
img=img.split('/')[-1],
|
|
||||||
author=self.conf.epub_author)
|
|
||||||
open(os.path.join(self.html_outdir, '_static', 'titlepage.html'), 'wb').write(raw)
|
|
||||||
|
|
||||||
def generate_manifest(self):
|
def generate_manifest(self):
|
||||||
self.manifest = {}
|
self.manifest = {}
|
||||||
@ -190,8 +209,12 @@ class EPUBHelpBuilder(StandaloneHTMLBuilder):
|
|||||||
self.manifest[url] = 'application/octet-stream'
|
self.manifest[url] = 'application/octet-stream'
|
||||||
if self.manifest[url] == 'text/html':
|
if self.manifest[url] == 'text/html':
|
||||||
self.manifest[url] = 'application/xhtml+xml'
|
self.manifest[url] = 'application/xhtml+xml'
|
||||||
self.manifest[url] = (self.manifest[url], 'id'+str(id))
|
if self.cover_image_url and url.endswith(self.cover_image_url):
|
||||||
id += 1
|
id_ = 'cover'
|
||||||
|
else:
|
||||||
|
id_ = 'id'+str(id)
|
||||||
|
id += 1
|
||||||
|
self.manifest[url] = (self.manifest[url], id_)
|
||||||
|
|
||||||
def isdocnode(self, node):
|
def isdocnode(self, node):
|
||||||
if not isinstance(node, nodes.list_item):
|
if not isinstance(node, nodes.list_item):
|
||||||
@ -227,7 +250,7 @@ class EPUBHelpBuilder(StandaloneHTMLBuilder):
|
|||||||
open('toc.ncx', 'wb').write(ncx)
|
open('toc.ncx', 'wb').write(ncx)
|
||||||
self.manifest['toc.ncx'] = ('application/x-dtbncx+xml', 'ncx')
|
self.manifest['toc.ncx'] = ('application/x-dtbncx+xml', 'ncx')
|
||||||
self.spine.insert(0, self.manifest[self.conf.master_doc+'.html'][1])
|
self.spine.insert(0, self.manifest[self.conf.master_doc+'.html'][1])
|
||||||
if self.conf.epub_titlepage:
|
if self.conf.epub_cover:
|
||||||
self.spine.insert(0, self.manifest['_static/titlepage.html'][1])
|
self.spine.insert(0, self.manifest['_static/titlepage.html'][1])
|
||||||
|
|
||||||
def add_to_spine(self, href):
|
def add_to_spine(self, href):
|
||||||
|
@ -160,7 +160,7 @@ Alternative for the iPad
|
|||||||
As of |app| version 0.7.0, you can plugin your iPad into the computer using its charging cable, and |app| will detect it and show you a list of books on the iPad. You can then use the Send to device button to send books directly to iBooks on the iPad.
|
As of |app| version 0.7.0, you can plugin your iPad into the computer using its charging cable, and |app| will detect it and show you a list of books on the iPad. You can then use the Send to device button to send books directly to iBooks on the iPad.
|
||||||
|
|
||||||
This method only works on Windows XP and higher and OS X 10.5 and higher. Linux is not supported (iTunes is not available in linux) and OS X 10.4 is not supported. For more details, see
|
This method only works on Windows XP and higher and OS X 10.5 and higher. Linux is not supported (iTunes is not available in linux) and OS X 10.4 is not supported. For more details, see
|
||||||
`this forum post http://www.mobileread.com/forums/showpost.php?p=944079&postcount=1`_.
|
`this forum post <http://www.mobileread.com/forums/showpost.php?p=944079&postcount=1>`_.
|
||||||
|
|
||||||
How do I use |app| with my Android phone?
|
How do I use |app| with my Android phone?
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
BIN
src/calibre/manual/resources/epub_cover.jpg
Normal file
BIN
src/calibre/manual/resources/epub_cover.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 144 KiB |
@ -1,29 +0,0 @@
|
|||||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
|
||||||
<head>
|
|
||||||
<title>%(title)s</title>
|
|
||||||
<style type="text/css">
|
|
||||||
body {
|
|
||||||
text-align: center;
|
|
||||||
vertical-align: center;
|
|
||||||
overflow: hidden;
|
|
||||||
font-size: 16pt;
|
|
||||||
}
|
|
||||||
.logo {
|
|
||||||
text-align:center;
|
|
||||||
font-size: 1pt;
|
|
||||||
overflow:hidden;
|
|
||||||
}
|
|
||||||
h1 { font-family: serif; }
|
|
||||||
h2, h4 { font-family: monospace; }
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>%(title)s</h1>
|
|
||||||
<h4 style="font-family:monospace">%(version)s</h4>
|
|
||||||
<div style="text-align:center">
|
|
||||||
<img class="logo" src="%(img)s" alt="calibre logo" />
|
|
||||||
</div>
|
|
||||||
<h2>%(author)s</h2>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user