mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
IGN:Improved formatting for CLI documentation
This commit is contained in:
parent
ae0274ceab
commit
ff5b248822
@ -95,7 +95,8 @@ def option_parser():
|
|||||||
writers = set([])
|
writers = set([])
|
||||||
for w in metadata_writers():
|
for w in metadata_writers():
|
||||||
writers = writers.union(set(w.file_types))
|
writers = writers.union(set(w.file_types))
|
||||||
return config().option_parser(USAGE%(list(filetypes()), list(writers)))
|
ft, w = ', '.join(filetypes()), ', '.join(writers)
|
||||||
|
return config().option_parser(USAGE%(ft, w))
|
||||||
|
|
||||||
def do_set_metadata(opts, mi, stream, stream_type):
|
def do_set_metadata(opts, mi, stream, stream_type):
|
||||||
mi = MetaInformation(mi)
|
mi = MetaInformation(mi)
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||||
import sys, os, inspect, re, textwrap, cStringIO
|
import sys, os, inspect, re, textwrap
|
||||||
|
|
||||||
from sphinx.builder import StandaloneHTMLBuilder
|
from sphinx.builder import StandaloneHTMLBuilder
|
||||||
from qthelp import QtHelpBuilder
|
from qthelp import QtHelpBuilder
|
||||||
@ -14,7 +14,6 @@ from sphinx.ext.autodoc import prepare_docstring
|
|||||||
from docutils.statemachine import ViewList
|
from docutils.statemachine import ViewList
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
|
|
||||||
from genshi.template import OldTextTemplate as TextTemplate
|
|
||||||
sys.path.append(os.path.abspath('../../../'))
|
sys.path.append(os.path.abspath('../../../'))
|
||||||
from calibre.linux import entry_points
|
from calibre.linux import entry_points
|
||||||
|
|
||||||
@ -27,100 +26,56 @@ class CustomQtBuild(QtHelpBuilder):
|
|||||||
def substitute(app, doctree):
|
def substitute(app, doctree):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
CLI_INDEX = '''\
|
CLI_INDEX='''
|
||||||
.. include:: ../global.rst
|
.. include:: ../global.rst
|
||||||
||
|
|
||||||
.. _cli:
|
.. _cli:
|
||||||
||
|
|
||||||
||
|
|
||||||
Command Line Interface
|
Command Line Interface
|
||||||
==========================
|
==========================
|
||||||
||
|
|
||||||
.. image:: ../images/cli.png
|
.. image:: ../images/cli.png
|
||||||
||
|
|
||||||
||
|
|
||||||
Documented Commands
|
Documented Commands
|
||||||
--------------------
|
--------------------
|
||||||
||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 1
|
:maxdepth: 1
|
||||||
||
|
|
||||||
#for cmd, parser in documented_commands
|
{documented}
|
||||||
$cmd
|
|
||||||
#end
|
|
||||||
||
|
|
||||||
Undocumented Commands
|
Undocumented Commands
|
||||||
-------------------------
|
-------------------------
|
||||||
||
|
|
||||||
#for cmd in undocumented_commands
|
{undocumented}
|
||||||
* ${cmd}
|
|
||||||
||
|
You can see usage for undocumented commands by executing them without arguments
|
||||||
#end
|
in a terminal.
|
||||||
||
|
|
||||||
You can see usage for undocumented commands by executing them without arguments in a terminal
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
CLI_CMD=r'''
|
CLI_PREAMBLE='''\
|
||||||
.. include:: ../global.rst
|
.. include:: ../global.rst
|
||||||
||
|
|
||||||
.. _$cmd:
|
.. _{cmd}:
|
||||||
||
|
|
||||||
$cmd
|
{cmd}
|
||||||
====================================================================
|
===================================================================
|
||||||
||
|
|
||||||
.. code-block:: none
|
.. code-block:: none
|
||||||
||
|
|
||||||
$cmdline
|
{cmdline}
|
||||||
||
|
|
||||||
#for line in usage
|
{usage}
|
||||||
#choose
|
|
||||||
#when len(line) > 0
|
|
||||||
$line
|
|
||||||
#end
|
|
||||||
#otherwise
|
|
||||||
||
|
|
||||||
#end
|
|
||||||
#end
|
|
||||||
#end
|
|
||||||
||
|
|
||||||
'''
|
|
||||||
CLI_GROUPS=r'''
|
|
||||||
[options]
|
|
||||||
------------
|
|
||||||
||
|
|
||||||
#def option(opt)
|
|
||||||
:option:`${opt.get_opt_string() + ((', '+', '.join(opt._short_opts)) if opt._short_opts else '')}`
|
|
||||||
#end
|
|
||||||
#for title, desc, options in groups
|
|
||||||
#if title
|
|
||||||
$title
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
||
|
|
||||||
#end
|
|
||||||
#if desc
|
|
||||||
$desc
|
|
||||||
||
|
|
||||||
#end
|
|
||||||
#for opt in options
|
|
||||||
${option(opt)}
|
|
||||||
${opt.help.replace('\n', ' ').replace('*', '\\*').replace('%default', str(opt.default)) if opt.help else ''}
|
|
||||||
||
|
|
||||||
#end
|
|
||||||
#end
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
EBOOK_CONVERT = CLI_CMD + r'''
|
|
||||||
$groups
|
|
||||||
'''
|
|
||||||
|
|
||||||
CLI_CMD += CLI_GROUPS
|
def generate_ebook_convert_help(preamble, info):
|
||||||
|
|
||||||
|
|
||||||
def generate_ebook_convert_help(info):
|
|
||||||
from calibre.ebooks.conversion.cli import create_option_parser
|
from calibre.ebooks.conversion.cli import create_option_parser
|
||||||
from calibre.customize.ui import input_format_plugins, output_format_plugins
|
from calibre.customize.ui import input_format_plugins, output_format_plugins
|
||||||
from calibre.utils.logging import default_log
|
from calibre.utils.logging import default_log
|
||||||
ans = textwrap.dedent('''
|
preamble = re.sub(r'http.*\.html', ':ref:`conversion`', preamble)
|
||||||
|
raw = preamble + textwrap.dedent('''
|
||||||
Since the options supported by ebook-convert vary depending on both the
|
Since the options supported by ebook-convert vary depending on both the
|
||||||
input and the output formats, the various combinations are listed below:
|
input and the output formats, the various combinations are listed below:
|
||||||
|
|
||||||
@ -128,7 +83,7 @@ def generate_ebook_convert_help(info):
|
|||||||
sections = []
|
sections = []
|
||||||
toc = {}
|
toc = {}
|
||||||
sec_templ = textwrap.dedent('''\
|
sec_templ = textwrap.dedent('''\
|
||||||
.. include:: global.rst
|
.. include:: ../global.rst
|
||||||
|
|
||||||
{0}
|
{0}
|
||||||
================================================================
|
================================================================
|
||||||
@ -139,34 +94,55 @@ def generate_ebook_convert_help(info):
|
|||||||
|
|
||||||
''')
|
''')
|
||||||
for i, ip in enumerate(input_format_plugins()):
|
for i, ip in enumerate(input_format_plugins()):
|
||||||
f = cStringIO.StringIO()
|
|
||||||
path = os.path.join('cli', 'ebook-convert-%d.rst'%i)
|
path = os.path.join('cli', 'ebook-convert-%d.rst'%i)
|
||||||
f.write(sec_templ.format(ip.name))
|
sraw = sec_templ.format(ip.name)
|
||||||
toc[ip.name] = 'ebook-convert-%d'%i
|
toc[ip.name] = 'ebook-convert-%d'%i
|
||||||
for op in output_format_plugins():
|
for op in output_format_plugins():
|
||||||
title = ip.name + ' to ' + op.name
|
title = ip.name + ' to ' + op.name
|
||||||
parser, plumber = create_option_parser(['ebook-convert',
|
parser, plumber = create_option_parser(['ebook-convert',
|
||||||
'dummyi.'+list(ip.file_types)[0],
|
'dummyi.'+list(ip.file_types)[0],
|
||||||
'dummyo.'+op.file_type, '-h'], default_log)
|
'dummyo.'+op.file_type, '-h'], default_log)
|
||||||
|
cmd = 'ebook-convert '+list(ip.file_types)[0]+' '+op.file_type
|
||||||
groups = [(None, None, parser.option_list)]
|
groups = [(None, None, parser.option_list)]
|
||||||
for grp in parser.option_groups:
|
for grp in parser.option_groups:
|
||||||
groups.append((grp.title, grp.description, grp.option_list))
|
groups.append((grp.title, grp.description, grp.option_list))
|
||||||
template = str(CLI_GROUPS)
|
options = '\n'.join(render_options(cmd, groups, False))
|
||||||
template = TextTemplate(template[template.find('||'):])
|
sraw += title+'\n------------------------------------------------------\n\n'
|
||||||
options = template.generate(groups=groups).render()
|
sraw += options + '\n\n'
|
||||||
f.write(title+'\n------------------------------------------------------')
|
update_cli_doc(os.path.join('cli', toc[ip.name]+'.rst'), sraw, info)
|
||||||
f.write('\n\n'+options.replace('||', '\n'))
|
|
||||||
if not os.path.exists(path):
|
|
||||||
info('creating '+path)
|
|
||||||
open(path, 'wb').write(f.getvalue())
|
|
||||||
|
|
||||||
toct = '||||.. toctree::|| :maxdepth: 2||||'
|
toct = '\n\n.. toctree::\n :maxdepth: 2\n\n'
|
||||||
for ip in sorted(toc):
|
for ip in sorted(toc):
|
||||||
toct += ' ' + toc[ip]+'||'
|
toct += ' ' + toc[ip]+'\n'
|
||||||
|
|
||||||
ans += toct+'||||'
|
raw += toct+'\n\n'
|
||||||
|
update_cli_doc(os.path.join('cli', 'ebook-convert.rst'), raw, info)
|
||||||
|
|
||||||
return ans
|
def update_cli_doc(path, raw, info):
|
||||||
|
if isinstance(raw, unicode):
|
||||||
|
raw = raw.encode('utf-8')
|
||||||
|
if not os.path.exists(path) or open(path, 'rb').read() != raw:
|
||||||
|
info('creating '+os.path.splitext(os.path.basename(path))[0])
|
||||||
|
open(path, 'wb').write(raw)
|
||||||
|
|
||||||
|
def render_options(cmd, groups, options_header=True):
|
||||||
|
lines = []
|
||||||
|
if options_header:
|
||||||
|
lines = ['[options]', '-'*15, '']
|
||||||
|
lines += ['.. program:: '+cmd, '']
|
||||||
|
for title, desc, options in groups:
|
||||||
|
if title:
|
||||||
|
lines.extend([title, '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'])
|
||||||
|
lines.append('')
|
||||||
|
if desc:
|
||||||
|
lines.extend([desc, ''])
|
||||||
|
for opt in options:
|
||||||
|
help = opt.help if opt.help else ''
|
||||||
|
help = help.replace('\n', ' ').replace('*', '\\*').replace('%default', str(opt.default))
|
||||||
|
opt = opt.get_opt_string() + ((', '+', '.join(opt._short_opts)) if opt._short_opts else '')
|
||||||
|
opt = '.. cmdoption:: '+opt
|
||||||
|
lines.extend([opt, '', ' '+help, ''])
|
||||||
|
return lines
|
||||||
|
|
||||||
def cli_docs(app):
|
def cli_docs(app):
|
||||||
info = app.builder.info
|
info = app.builder.info
|
||||||
@ -186,36 +162,32 @@ def cli_docs(app):
|
|||||||
documented_cmds.sort(cmp=lambda x, y: cmp(x[0], y[0]))
|
documented_cmds.sort(cmp=lambda x, y: cmp(x[0], y[0]))
|
||||||
undocumented_cmds.sort()
|
undocumented_cmds.sort()
|
||||||
|
|
||||||
templ = TextTemplate(CLI_INDEX)
|
documented = [' '*4 + cmd[0] for cmd in documented_cmds]
|
||||||
raw = templ.generate(documented_commands=documented_cmds,
|
undocumented = [' * ' + cmd for cmd in undocumented_cmds]
|
||||||
undocumented_commands=undocumented_cmds).render()
|
|
||||||
raw = raw.replace('||', '\n')
|
raw = CLI_INDEX.format(documented='\n'.join(documented),
|
||||||
|
undocumented='\n'.join(undocumented))
|
||||||
if not os.path.exists('cli'):
|
if not os.path.exists('cli'):
|
||||||
os.makedirs('cli')
|
os.makedirs('cli')
|
||||||
if not os.path.exists(os.path.join('cli', 'global.rst')):
|
update_cli_doc(os.path.join('cli', 'cli-index.rst'), raw, info)
|
||||||
os.link('global.rst', os.path.join('cli', 'global.rst'))
|
|
||||||
if not os.path.exists(os.path.join('cli', 'cli-index.rst')):
|
|
||||||
info(bold('creating cli-index...'))
|
|
||||||
open(os.path.join('cli', 'cli-index.rst'), 'wb').write(raw)
|
|
||||||
|
|
||||||
templ = TextTemplate(CLI_CMD)
|
|
||||||
for cmd, parser in documented_cmds:
|
for cmd, parser in documented_cmds:
|
||||||
usage = [i for i in parser.usage.replace('%prog', cmd).splitlines()]
|
usage = [i for i in parser.usage.replace('%prog', cmd).splitlines()]
|
||||||
cmdline = usage[0]
|
cmdline = usage[0]
|
||||||
usage = usage[1:]
|
usage = usage[1:]
|
||||||
usage = [i.replace(cmd, ':command:`%s`'%cmd) for i in usage]
|
usage = [i.replace(cmd, ':command:`%s`'%cmd) for i in usage]
|
||||||
groups = [(None, None, parser.option_list)]
|
usage = '\n'.join(usage)
|
||||||
for grp in parser.option_groups:
|
preamble = CLI_PREAMBLE.format(cmd=cmd, cmdline=cmdline, usage=usage)
|
||||||
groups.append((grp.title, grp.description, grp.option_list))
|
|
||||||
if cmd == 'ebook-convert':
|
if cmd == 'ebook-convert':
|
||||||
groups = generate_ebook_convert_help(info)
|
generate_ebook_convert_help(preamble, info)
|
||||||
templ = TextTemplate(EBOOK_CONVERT)
|
else:
|
||||||
raw = templ.generate(cmd=cmd, cmdline=cmdline, usage=usage, groups=groups).render()
|
groups = [(None, None, parser.option_list)]
|
||||||
raw = raw.replace('||', '\n').replace('<', '<').replace('>', '>')
|
for grp in parser.option_groups:
|
||||||
if not os.path.exists(os.path.join('cli', cmd+'.rst')):
|
groups.append((grp.title, grp.description, grp.option_list))
|
||||||
info(bold('creating docs for %s...'%cmd))
|
raw = preamble
|
||||||
open(os.path.join('cli', cmd+'.rst'), 'wb').write(raw)
|
lines = render_options(cmd, groups)
|
||||||
|
raw += '\n'+'\n'.join(lines)
|
||||||
|
update_cli_doc(os.path.join('cli', cmd+'.rst'), raw, info)
|
||||||
|
|
||||||
def auto_member(dirname, arguments, options, content, lineno,
|
def auto_member(dirname, arguments, options, content, lineno,
|
||||||
content_offset, block_text, state, state_machine):
|
content_offset, block_text, state, state_machine):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user