IGN:Various User Manual cleanups. Also split ebook-convert documentation into multiple files

This commit is contained in:
Kovid Goyal 2009-08-20 21:56:09 -06:00
parent fb552eba06
commit 8d0febf18f
10 changed files with 402 additions and 46 deletions

View File

@ -29,6 +29,20 @@ html:
@echo
@echo "Build finished. The HTML pages are in .build/html."
qthelp:
mkdir -p .build/qthelp .build/doctrees
$(SPHINXBUILD) -b customqt $(ALLSPHINXOPTS) .build/qthelp
@echo
@echo "Build finished."
epub:
mkdir -p .build/qthelp .build/doctrees
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) .build/epub
@echo
@echo "Build finished."
web:
mkdir -p .build/web .build/doctrees
$(SPHINXBUILD) -b web $(ALLSPHINXOPTS) .build/web

View File

@ -105,8 +105,8 @@ html_logo = 'resources/logo.png'
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
# html_use_modindex = True
html_use_modindex = False
html_use_index = False
# If true, the reST sources are included in the HTML build as _sources/<name>.
html_copy_source = False
@ -116,6 +116,8 @@ htmlhelp_basename = 'calibredoc'
html_use_opensearch = 'http://calibre.kovidgoyal.net/user_manual'
html_show_sphinx = False
# Options for LaTeX output
# ------------------------

View File

@ -6,6 +6,8 @@ __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
import sys, os, inspect, re, textwrap
from sphinx.builder import StandaloneHTMLBuilder
from qthelp import QtHelpBuilder
from epub import EPUBHelpBuilder
from sphinx.util import rpartition
from sphinx.util.console import bold
from sphinx.ext.autodoc import prepare_docstring
@ -19,6 +21,8 @@ from calibre.linux import entry_points
class CustomBuilder(StandaloneHTMLBuilder):
name = 'custom'
class CustomQtBuild(QtHelpBuilder):
name = 'customqt'
def substitute(app, doctree):
pass
@ -121,19 +125,25 @@ def generate_ebook_convert_help():
input and the output formats, the various combinations are listed below:
''')
c = 0
sections = []
toc = {}
for ip in input_format_plugins():
toc[ip.name] = []
sec_templ = textwrap.dedent('''\
.. include:: global.rst
{0}
================================================================
.. contents:: Contents
:depth: 1
:local:
''')
for i, ip in enumerate(input_format_plugins()):
with open(os.path.join('cli', 'ebook-convert-%d.rst'%i), 'wb') as f:
f.write(sec_templ.format(ip.name))
toc[ip.name] = 'ebook-convert-%d'%i
for op in output_format_plugins():
c += 1
idr = 'ebook-convert-sec-'+str(c)
title = ip.name + ' to ' + op.name
section = '.. _'+idr+':||||'
section += title+'||'+\
'-------------------------------------------------------'
toc[ip.name].append([idr, op.name])
parser, plumber = create_option_parser(['ebook-convert',
'dummyi.'+list(ip.file_types)[0],
'dummyo.'+op.file_type, '-h'], default_log)
@ -142,18 +152,15 @@ def generate_ebook_convert_help():
groups.append((grp.title, grp.description, grp.option_list))
template = str(CLI_GROUPS)
template = TextTemplate(template[template.find('||'):])
section += template.generate(groups=groups).render()
options = template.generate(groups=groups).render()
f.write(title+'\n------------------------------------------------------')
f.write('\n\n'+options.replace('||', '\n'))
sections.append(section)
toct = '||||'
toct = '||||.. toctree::|| :maxdepth: 2||||'
for ip in sorted(toc):
toct += ' * '+ip+'||||'
for idr, name in toc[ip]:
toct += ' * :ref:`'+name +' <'+idr+'>`||'
toct += '||'
toct += ' ' + toc[ip]+'||'
ans += toct+'||||'+'||||'.join(sections)
ans += toct+'||||'
return ans
@ -259,6 +266,8 @@ def auto_member(dirname, arguments, options, content, lineno,
def setup(app):
app.add_builder(CustomBuilder)
app.add_builder(CustomQtBuild)
app.add_builder(EPUBHelpBuilder)
app.add_directive('automember', auto_member, 1, (1, 0, 1))
app.connect('doctree-read', substitute)
app.connect('builder-inited', cli_docs)

View File

@ -0,0 +1,39 @@
#!/usr/bin/env python
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
from __future__ import with_statement
__license__ = 'GPL v3'
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en'
import os
from sphinx.builders.html import StandaloneHTMLBuilder
class EPUBHelpBuilder(StandaloneHTMLBuilder):
"""
Builder that also outputs Qt help project, contents and index files.
"""
name = 'epub'
# don't copy the reST source
copysource = False
supported_image_types = ['image/svg+xml', 'image/png', 'image/gif',
'image/jpeg']
# don't add links
add_permalinks = False
# don't add sidebar etc.
embedded = True
def init(self):
StandaloneHTMLBuilder.init(self)
# the output files for HTML help must be .html only
self.out_suffix = '.xhtml'
self.outdir = os.path.join(self.outdir, 'src')
#self.config.html_style = 'traditional.css'
def finish(self):
StandaloneHTMLBuilder.finish(self)
print 11111111

View File

@ -64,7 +64,7 @@ There are two aspects to this problem:
How do I use some of the advanced features of the conversion tools?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can get help on any individual feature of the converters by mousing over it in the GUI or running ``html2lrf --help`` at a terminal. A good place to start is to look at the following demo files that demonstrate some of the advanced features:
You can get help on any individual feature of the converters by mousing over it in the GUI or running ``ebook-convert dummy.html .epub -h`` at a terminal. A good place to start is to look at the following demo files that demonstrate some of the advanced features:
* `html-demo.zip <http://calibre.kovidgoyal.net/downloads/html-demo.zip>`_
* `txt-demo.zip <http://calibre.kovidgoyal.net/downloads/txt-demo.zip>`_
@ -78,7 +78,7 @@ Device Integration
What devices does |app| support?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
At the moment |app| has full support for the SONY PRS 500/505/700, Cybook Gen 3, Amazon Kindle 1/2/DX, Netronix EB600, Ectaco Jetbook, BeBook/BeBook Mini and the iPhone. In addition, using the :guilabel:`Save to disk` function you can use it with any ebook reader that exports itself as a USB disk.
At the moment |app| has full support for the SONY PRS 500/505/700, Cybook Gen 3/Opus, Amazon Kindle 1/2/DX, Netronix EB600, Ectaco Jetbook, BeBook/BeBook Mini, Irex Illiad/DR1000, Adroid phones and the iPhone. In addition, using the :guilabel:`Save to disk` function you can use it with any ebook reader that exports itself as a USB disk.
I used |app| to transfer some books to my reader, and now the SONY software hangs every time I connect the reader?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -121,7 +121,7 @@ Library Management
What formats does |app| read metadata from?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|app| reads metadata from the following formats: LRF, PDF, LIT, RTF, OPF, MOBI, PRC, EPUB, FB2, IMP, RB, HTML. In addition it can write metadata to: LRF, RTF, OPF
|app| reads metadata from the following formats: LRF, PDF, LIT, RTF, OPF, MOBI, PRC, EPUB, FB2, IMP, RB, HTML. In addition it can write metadata to: LRF, RTF, OPF, EPUB, PDF, MOBI
Where are the book files stored?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -5,13 +5,13 @@
|app| is an e-book library manager. It can view, convert and catalog e-books in most of the major e-book formats. It can also talk to a few e-book reader devices. It can go out to the internet and fetch metadata for your books. It can download newspapers and convert them into e-books for convenient reading. It is cross platform, running on Linux, Windows and OS X.
So you've just started |app|. What do you do now? Well, before |app| can do anything with your ebooks, it first has to know about them. So drag and drop a few ebook files into |app|, or click the "Add books" button and browse for the ebooks you want to work with. Once you've added the books, they will show up in the main view looking something like this:
So you've just started |app|. What do you do now? Well, before |app| can do anything with your ebooks, it first has to know about them. So drag and drop a few e-book files into |app|, or click the "Add books" button and browse for the ebooks you want to work with. Once you've added the books, they will show up in the main view looking something like this:
.. image:: images/added_books.png
Once you've admired the list of books you just added to your heart's content, you'll probably want to actually read one. In order to do that you'll have to convert the book to a format your reader understands. For the SONY Reader that's the LRF format. Conversion is a breeze, just select the book you want to convert, and click the "Convert E-book" button. Ignore all the options for now and just click "OK". The little hourglass in the bottom right corner will start spinning. Once it's finished spinning, your converted book is ready. Click to "View" button to read the book.
Once you've admired the list of books you just added to your heart's content, you'll probably want to actually read one. In order to do that you'll have to convert the book to a format your reader understands. When first running |app|, the Welcome Wizard starts and it will have setup calibre for your reader device. Conversion is a breeze, just select the book you want to convert, and click the "Convert E-book" button. Ignore all the options for now and just click "OK". The little hourglass in the bottom right corner will start spinning. Once it's finished spinning, your converted book is ready. Click the "View" button to read the book.
Now if you want to read the book on your reader, just connect it to the computer, wait till calibre detects it (10-20secs) and then click the "Send to device" button. Once the hourglass stops spinning again, disconnect your reader and read away!
Now if you want to read the book on your reader, just connect it to the computer, wait till calibre detects it (10-20secs) and then click the "Send to device" button. Once the hourglass stops spinning again, disconnect your reader and read away! If you didn't convert the book in the previous step, |app| will auto convert it to the format your reader device understands.
To get started with more advanced usage, you should read about the :ref:`Graphical User Interface <gui>`. For even more power and versatility, learn the :ref:`Command Line Interface <cli>`.
@ -33,14 +33,7 @@ Sections
customize
glossary
Convenience
-----------------------
:ref:`search`: Search the help
:ref:`genindex`
.. toctree::
:hidden:
plugins

View File

@ -101,6 +101,8 @@ Pre/post processing of downloaded HTML
.. automember:: BasicNewsRecipe.remove_tags_before
.. automember:: BasicNewsRecipe.remove_attributes
.. automember:: BasicNewsRecipe.keep_only_tags
.. automember:: BasicNewsRecipe.preprocess_regexps

View File

@ -0,0 +1,295 @@
# -*- coding: utf-8 -*-
import os
import re
import cgi
import subprocess
from os import path
from docutils import nodes
from sphinx import addnodes
from sphinx.builders.html import StandaloneHTMLBuilder
_idpattern = re.compile(
r'(?P<title>.+) (\((?P<id>[\w\.]+)( (?P<descr>\w+))?\))$')
# Qt Help Collection Project (.qhcp).
# Is the input file for the help collection generator.
# It contains references to compressed help files which should be
# included in the collection.
# It may contain various other information for customizing Qt Assistant.
collection_template = '''\
<?xml version="1.0" encoding="utf-8" ?>
<QHelpCollectionProject version="1.0">
<docFiles>
<generate>
<file>
<input>%(outname)s.qhp</input>
<output>%(outname)s.qch</output>
</file>
</generate>
<register>
<file>%(outname)s.qch</file>
</register>
</docFiles>
<assistant>
<title>calibre User Manual</title>
<applicationIcon>_static/logo.png</applicationIcon>
<enableDocumentationManager>false</enableDocumentationManager>
<enableAddressBar visible="false">true</enableAddressBar>
<cacheDirectory>calibre/user_manual</cacheDirectory>
<aboutMenuText>
<text>About calibre</text>
</aboutMenuText>
<aboutDialog>
<file>about.txt</file>
<icon>_static/logo.png</icon>
</aboutDialog>
</assistant>
</QHelpCollectionProject>
'''
ABOUT='''\
calibre is the one stop solution for all your e-book needs. It was created
originally by Kovid Goyal, to help him manage his e-book collection and is now
very actively developed by an international community of e-book enthusiasts.
Its goal is to empower you, the user, to do whatever you like with the e-books
in your collection. You can convert them to many different formats, read them
on your computer, send them to many different devices, edit their metadata
and covers, etc.
calibre also allows you to download news from a variety of different sources all
over the internet and read conveniently in e-books form. In keeping with its
philosophy of empowering the user, it has a simple system to allow you to add
your own favorite news sources. In fact, most the builtin news sources in
calibre were originally contributed by users.
'''
# Qt Help Project (.qhp)
# This is the input file for the help generator.
# It contains the table of contents, indices and references to the
# actual documentation files (*.html).
# In addition it defines a unique namespace for the documentation.
project_template = '''\
<?xml version="1.0" encoding="UTF-8"?>
<QtHelpProject version="1.0">
<namespace>%(outname)s.org.%(outname)s.%(nversion)s</namespace>
<virtualFolder>doc</virtualFolder>
<customFilter name="%(project)s %(version)s">
<filterAttribute>%(outname)s</filterAttribute>
<filterAttribute>%(version)s</filterAttribute>
</customFilter>
<filterSection>
<filterAttribute>%(outname)s</filterAttribute>
<filterAttribute>%(version)s</filterAttribute>
<toc>
<section title="%(title)s" ref="%(masterdoc)s.html">
%(sections)s
</section>
</toc>
<files>
%(files)s
</files>
</filterSection>
</QtHelpProject>
'''
section_template = '<section title="%(title)s" ref="%(ref)s"/>'
file_template = ' '*12 + '<file>%(filename)s</file>'
class QtHelpBuilder(StandaloneHTMLBuilder):
"""
Builder that also outputs Qt help project, contents and index files.
"""
name = 'qthelp'
# don't copy the reST source
copysource = False
supported_image_types = ['image/svg+xml', 'image/png', 'image/gif',
'image/jpeg']
# don't add links
add_permalinks = False
# don't add sidebar etc.
embedded = True
def init(self):
StandaloneHTMLBuilder.init(self)
# the output files for HTML help must be .html only
self.out_suffix = '.html'
#self.config.html_style = 'traditional.css'
def handle_finish(self):
self.build_qhcp(self.outdir, self.config.qthelp_basename)
self.build_qhp(self.outdir, self.config.qthelp_basename)
self.build_qhc(self.outdir, self.config.qthelp_basename)
def build_qhc(self, outdir, outname):
self.info('create Qt Help Collection...')
with open(os.path.join(outdir, 'about.txt'), 'wb') as f:
f.write(ABOUT)
qhcp = os.path.abspath(os.path.join(outdir, outname+'.qhcp'))
subprocess.check_call(['qcollectiongenerator', qhcp])
qhc = qhcp[:-5]+'.qhc'
self.info('Qt Help Collection: '+qhc)
self.info('To test: assistant -collectionFile '+qhc)
def build_qhcp(self, outdir, outname):
self.info('writing collection project file...')
f = open(path.join(outdir, outname+'.qhcp'), 'w')
try:
f.write(collection_template % {'outname': outname})
finally:
f.close()
def build_qhp(self, outdir, outname):
self.info('writing project file...')
# sections
tocdoc = self.env.get_and_resolve_doctree(self.config.master_doc, self,
prune_toctrees=False)
istoctree = lambda node: (
isinstance(node, addnodes.compact_paragraph)
and node.has_key('toctree'))
sections = []
for node in tocdoc.traverse(istoctree):
sections.extend(self.write_toc(node))
if self.config.html_use_modindex:
item = section_template % {'title': _('Global Module Index'),
'ref': 'modindex.html'}
sections.append(' '*4*4 + item)
sections = '\n'.join(sections)
# keywords
keywords = []
index = self.env.create_index(self)
for (key, group) in index:
for title, (refs, subitems) in group:
keywords.extend(self.build_keywords(title, refs, subitems))
keywords = '\n'.join(keywords)
# files
if not outdir.endswith(os.sep):
outdir += os.sep
olen = len(outdir)
projectfiles = []
staticdir = path.join(outdir, '_static')
imagesdir = path.join(outdir, '_images')
for root, dirs, files in os.walk(outdir):
resourcedir = root.startswith(staticdir) or root.startswith(imagesdir)
for fn in files:
if (resourcedir and not fn.endswith('.js')) or \
fn.endswith('.html'):
filename = path.join(root, fn)[olen:]
#filename = filename.replace(os.sep, '\\') # XXX
projectfiles.append(file_template % {'filename': filename})
projectfiles = '\n'.join(projectfiles)
# write the project file
f = open(path.join(outdir, outname+'.qhp'), 'w')
try:
nversion = self.config.version.replace('.', '_')
nversion = nversion.replace(' ', '_')
f.write(project_template % {'outname': outname,
'title': self.config.html_title,
'version': self.config.version,
'project': self.config.project,
'nversion': nversion,
'masterdoc': self.config.master_doc,
'sections': sections,
'keywords': keywords,
'files': projectfiles})
finally:
f.close()
def isdocnode(self, node):
if not isinstance(node, nodes.list_item):
return False
if len(node.children) != 2:
return False
if not isinstance(node.children[0], addnodes.compact_paragraph):
return False
if not isinstance(node.children[0][0], nodes.reference):
return False
if not isinstance(node.children[1], nodes.bullet_list):
return False
return True
def write_toc(self, node, indentlevel=4):
parts = []
if self.isdocnode(node):
refnode = node.children[0][0]
link = refnode['refuri']
title = cgi.escape(refnode.astext()).replace('"','&quot;')
item = '<section title="%(title)s" ref="%(ref)s">' % {
'title': title,
'ref': link}
parts.append(' '*4*indentlevel + item)
for subnode in node.children[1]:
parts.extend(self.write_toc(subnode, indentlevel+1))
parts.append(' '*4*indentlevel + '</section>')
elif isinstance(node, nodes.list_item):
for subnode in node:
parts.extend(self.write_toc(subnode, indentlevel))
elif isinstance(node, nodes.reference):
link = node['refuri']
title = cgi.escape(node.astext()).replace('"','&quot;')
item = section_template % {'title': title, 'ref': link}
item = ' '*4*indentlevel + item.encode('ascii', 'xmlcharrefreplace')
parts.append(item.encode('ascii', 'xmlcharrefreplace'))
elif isinstance(node, nodes.bullet_list):
for subnode in node:
parts.extend(self.write_toc(subnode, indentlevel))
elif isinstance(node, addnodes.compact_paragraph):
for subnode in node:
parts.extend(self.write_toc(subnode, indentlevel))
return parts
def keyword_item(self, name, ref):
matchobj = _idpattern.match(name)
if matchobj:
groupdict = matchobj.groupdict()
shortname = groupdict['title']
id = groupdict.get('id')
# descr = groupdict.get('descr')
if shortname.endswith('()'):
shortname = shortname[:-2]
id = '%s.%s' % (id, shortname)
else:
id = descr = None
if id:
item = ' '*12 + '<keyword name="%s" id="%s" ref="%s"/>' % (
name, id, ref)
else:
item = ' '*12 + '<keyword name="%s" ref="%s"/>' % (name, ref)
item.encode('ascii', 'xmlcharrefreplace')
return item
def build_keywords(self, title, refs, subitems):
keywords = []
title = cgi.escape(title)
# if len(refs) == 0: # XXX
# write_param('See Also', title)
if len(refs) == 1:
keywords.append(self.keyword_item(title, refs[0]))
elif len(refs) > 1:
for i, ref in enumerate(refs): # XXX
# item = (' '*12 +
# '<keyword name="%s [%d]" ref="%s"/>' % (
# title, i, ref))
# item.encode('ascii', 'xmlcharrefreplace')
# keywords.append(item)
keywords.append(self.keyword_item(title, ref))
if subitems:
for subitem in subitems:
keywords.extend(self.build_keywords(subitem[0], subitem[1], []))
return keywords

View File

@ -164,6 +164,7 @@ class BasicNewsRecipe(Recipe):
#: Recipe specific options to control the conversion of the downloaded
#: content into an e-book. These will override any user or plugin specified
#: values, so only use if absolutely necessary. For example::
#:
#: conversion_options = {
#: 'base_font_size' : 16,
#: 'tags' : 'mytag1,mytag2',

3
todo
View File

@ -3,5 +3,6 @@
* Testing framework
* MOBI navigation indexing support
* Add a languages column to books. Best implementation is comma separated IANA codes
* Add a hash column to the formats table (used for stanza identifier)