diff --git a/.gitignore b/.gitignore index e35e87c506..8991d99b2e 100644 --- a/.gitignore +++ b/.gitignore @@ -6,9 +6,7 @@ .check-cache.pickle src/calibre/plugins resources/images.qrc -manual/.build/ -manual/cli/ -manual/template_ref.rst +manual/generated manual/locale build dist diff --git a/manual/Makefile b/manual/Makefile deleted file mode 100644 index 1f70ac023a..0000000000 --- a/manual/Makefile +++ /dev/null @@ -1,80 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build2 -PAPER = - -ALLSPHINXOPTS = -d .build/doctrees -D language=en -D latex_paper_size=$(PAPER) \ - $(SPHINXOPTS) . - -.PHONY: help clean html web htmlhelp latex changes linkcheck - -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " web to make files usable by Sphinx.web" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " changes to make an overview over all changed/added/deprecated items" - @echo " linkcheck to check all external links for integrity" - -clean: - rm -rf .build/* cli - -html: - mkdir -p .build/html .build/doctrees - $(SPHINXBUILD) -b html -t online $(ALLSPHINXOPTS) .build/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 myepub $(ALLSPHINXOPTS) .build/epub - @echo - @echo "Build finished." - - - -web: - mkdir -p .build/web .build/doctrees - $(SPHINXBUILD) -b web $(ALLSPHINXOPTS) .build/web - @echo - @echo "Build finished; now you can run" - @echo " python -m sphinx.web .build/web" - @echo "to start the server." - -htmlhelp: - mkdir -p .build/htmlhelp .build/doctrees - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) .build/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in .build/htmlhelp." - -latex: - mkdir -p .build/latex .build/doctrees - $(SPHINXBUILD) -b mylatex $(ALLSPHINXOPTS) .build/latex - @echo - @echo "Build finished; the LaTeX files are in .build/latex." - @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ - "run these through (pdf)latex." - -changes: - mkdir -p .build/changes .build/doctrees - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) .build/changes - @echo - @echo "The overview file is in .build/changes." - -linkcheck: - mkdir -p .build/linkcheck .build/doctrees - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) .build/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in .build/linkcheck/output.txt." diff --git a/manual/build.py b/manual/build.py old mode 100644 new mode 100755 index 8787273818..9e1ffa4224 --- a/manual/build.py +++ b/manual/build.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env calibre-debug # vim:fileencoding=utf-8 from __future__ import (unicode_literals, division, absolute_import, print_function) @@ -6,30 +6,38 @@ from __future__ import (unicode_literals, division, absolute_import, __license__ = 'GPL v3' __copyright__ = '2014, Kovid Goyal ' +from functools import partial + +from calibre import __appname__, __version__ from calibre.utils.icu import upper # ensure encoding is set to utf-8 del upper import sys, os, subprocess, shutil +SPHINX_BUILD = 'sphinx-build2' + j, d, a = os.path.join, os.path.dirname, os.path.abspath -def build_manual(language, base): - - def sphinx_build(builder='html', bdir='html', t=None): - destdir = j(base, bdir) +def sphinx_build(language, base, builder='html', bdir='html', t=None, quiet=True): + destdir = j(base, bdir) + if not os.path.exists(destdir): os.makedirs(destdir) - ans = ['sphinx-build2', '-D', ('language=' + language), '-q', '-b', builder] - if builder == 'html': - ans += ['-w', j(destdir, 'sphinx-build-warnings.txt')] - if t: - ans += ['-t', t] - ans += ['-d', j(base, 'doctrees'), '.', destdir] - print(' '.join(ans)) - subprocess.check_call(ans) - return destdir + ans = [SPHINX_BUILD, '-D', ('language=' + language), '-b', builder] + if quiet: + ans.append('-q') + if builder == 'html': + ans += ['-w', j(destdir, 'sphinx-build-warnings.txt')] + if t: + ans += ['-t', t] + ans += ['-d', j(base, 'doctrees'), '.', destdir] + print(' '.join(ans)) + subprocess.check_call(ans) + return destdir - onlinedir = sphinx_build(t='online') - epubdir = sphinx_build('myepub', 'epub') - latexdir = sphinx_build('mylatex', 'latex') +def build_manual(language, base): + sb = partial(sphinx_build, language, base) + onlinedir = sb(t='online') + epubdir = sb('myepub', 'epub') + latexdir = sb('mylatex', 'latex') pwd = os.getcwdu() os.chdir(latexdir) def run_cmd(cmd): @@ -55,8 +63,15 @@ def build_manual(language, base): epub_to_azw3(epub_dest) if __name__ == '__main__': - language, base, src, __appname__, __version__ = sys.argv[1:] - os.chdir(src) + os.chdir(d(a(__file__))) os.environ['__appname__'] = __appname__ os.environ['__version__'] = __version__ - build_manual(language, base) + if len(sys.argv) == 1: + base = '/tmp/manual' + os.environ['CALIBRE_OVERRIDE_LANG'] = 'en' + sphinx_build('en', base, t='online', quiet=False) + else: + language, base = sys.argv[1:] + os.environ['CALIBRE_OVERRIDE_LANG'] = language + build_manual(language, base) + print ('Manual for', language, 'built in', j(base, 'html')) diff --git a/manual/conf.py b/manual/conf.py index 31d7a891c7..c1c4e7ec88 100644 --- a/manual/conf.py +++ b/manual/conf.py @@ -43,7 +43,9 @@ master_doc = 'index' if tags.has('online') else 'simple_index' # noqa exclude_patterns = ['simple_index.rst'] if master_doc == 'index' else ['index'] # The language -language = 'en' +language = os.environ.get('CALIBRE_OVERRIDE_LANG', 'en') +# ignore generated files in languages other than the language we are building for +exclude_patterns += ['generated/' + x for x in os.listdir('generated') if x != language] # General substitutions. project = __appname__ diff --git a/manual/custom.py b/manual/custom.py index ed0b841536..9506e60cf1 100644 --- a/manual/custom.py +++ b/manual/custom.py @@ -17,13 +17,21 @@ from latex import LaTeXHelpBuilder def substitute(app, doctree): pass +def source_read_handler(app, docname, source): + source[0] = source[0].replace('/|lang|/', '/%s/' % app.config.language) + if docname == 'index': + # Sphinx does not call source_read_handle for the .. include directive + ss = [open('simple_index.rst', 'rb').read().decode('utf-8')] + source_read_handler(app, 'simple_index', ss) + source[0] = source[0].replace('.. include:: simple_index.rst', ss[0]) + CLI_INDEX=''' .. _cli: Command Line Interface ========================== -.. image:: ../images/cli.png +.. image:: ../../images/cli.png .. note:: On OS X, the command line tools are inside the |app| bundle, for example, @@ -60,7 +68,7 @@ CLI_PREAMBLE='''\ {usage} ''' -def generate_calibredb_help(preamble, info): +def generate_calibredb_help(preamble, app): from calibre.library.cli import COMMANDS, get_parser import calibre.library.cli as cli preamble = preamble[:preamble.find('\n\n\n', preamble.find('code-block'))] @@ -103,9 +111,9 @@ def generate_calibredb_help(preamble, info): toc = '\n'.join(toc) raw = preamble + '\n\n'+toc + '\n\n' + global_options+'\n\n'+'\n'.join(lines) - update_cli_doc(os.path.join('cli', 'calibredb.rst'), raw, info) + update_cli_doc('calibredb', raw, app) -def generate_ebook_convert_help(preamble, info): +def generate_ebook_convert_help(preamble, app): from calibre.ebooks.conversion.cli import create_option_parser from calibre.customize.ui import input_format_plugins, output_format_plugins from calibre.utils.logging import default_log @@ -146,11 +154,12 @@ def generate_ebook_convert_help(preamble, info): prog = 'ebook-convert-'+(pl.name.lower().replace(' ', '-')) raw += '\n\n' + '\n'.join(render_options(prog, groups, False, True)) - update_cli_doc(os.path.join('cli', 'ebook-convert.rst'), raw, info) + update_cli_doc('ebook-convert', raw, app) -def update_cli_doc(path, raw, info): +def update_cli_doc(name, raw, app): if isinstance(raw, unicode): raw = raw.encode('utf-8') + path = 'generated/%s/%s.rst' % (app.config.language, name) old_raw = open(path, 'rb').read() if os.path.exists(path) else '' if not os.path.exists(path) or old_raw != raw: import difflib @@ -160,7 +169,10 @@ def update_cli_doc(path, raw, info): path, path) for line in lines: print line - info('creating '+os.path.splitext(os.path.basename(path))[0]) + app.builder.info('creating '+os.path.splitext(os.path.basename(path))[0]) + p = os.path.dirname(path) + if p and not os.path.exists(p): + os.makedirs(p) open(path, 'wb').write(raw) def render_options(cmd, groups, options_header=True, add_program=True): @@ -217,7 +229,7 @@ def cli_docs(app): undocumented='\n'.join(undocumented)) if not os.path.exists('cli'): os.makedirs('cli') - update_cli_doc(os.path.join('cli', 'cli-index.rst'), raw, info) + update_cli_doc('cli-index', raw, app) for cmd, parser in documented_cmds: usage = [mark_options(i) for i in parser.usage.replace('%prog', cmd).splitlines()] @@ -227,9 +239,9 @@ def cli_docs(app): usage = '\n'.join(usage) preamble = CLI_PREAMBLE.format(cmd=cmd, cmdline=cmdline, usage=usage) if cmd == 'ebook-convert': - generate_ebook_convert_help(preamble, info) + generate_ebook_convert_help(preamble, app) elif cmd == 'calibredb': - generate_calibredb_help(preamble, info) + generate_calibredb_help(preamble, app) else: groups = [(None, None, parser.option_list)] for grp in parser.option_groups: @@ -237,7 +249,7 @@ def cli_docs(app): raw = preamble lines = render_options(cmd, groups) raw += '\n'+'\n'.join(lines) - update_cli_doc(os.path.join('cli', cmd+'.rst'), raw, info) + update_cli_doc(cmd, raw, app) def generate_docs(app): cli_docs(app) @@ -245,13 +257,13 @@ def generate_docs(app): def template_docs(app): from template_ref_generate import generate_template_language_help - info = app.builder.info raw = generate_template_language_help() - update_cli_doc('template_ref.rst', raw, info) + update_cli_doc('template_ref', raw, app) def setup(app): app.add_builder(EPUBHelpBuilder) app.add_builder(LaTeXHelpBuilder) + app.connect('source-read', source_read_handler) app.connect('doctree-read', substitute) app.connect('builder-inited', generate_docs) app.connect('build-finished', finished) diff --git a/manual/index.rst b/manual/index.rst index ef02dc3e6a..47d3b95a46 100755 --- a/manual/index.rst +++ b/manual/index.rst @@ -86,7 +86,7 @@ The Command Line Interface .. toctree:: :maxdepth: 2 - cli/cli-index + generated/|lang|/cli-index Setting up a |app| development environment ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/manual/simple_index.rst b/manual/simple_index.rst index f36556ae8c..2682aae443 100644 --- a/manual/simple_index.rst +++ b/manual/simple_index.rst @@ -35,7 +35,7 @@ Sections faq tutorials customize - cli/cli-index + generated/|lang|/cli-index develop glossary diff --git a/manual/template_lang.rst b/manual/template_lang.rst index ceb0cbf532..c2e25364c4 100644 --- a/manual/template_lang.rst +++ b/manual/template_lang.rst @@ -330,7 +330,7 @@ Function classification .. toctree:: :maxdepth: 3 - template_ref + generated/|lang|/template_ref .. _general_mode: @@ -479,5 +479,5 @@ You might find the following tips useful. .. toctree:: :hidden: - template_ref + generated/|lang|/template_ref diff --git a/manual/template_ref_generate.py b/manual/template_ref_generate.py index af7a754a6b..054088981d 100644 --- a/manual/template_ref_generate.py +++ b/manual/template_ref_generate.py @@ -53,7 +53,7 @@ The python implementation of the template functions is passed in a Metadata obje The set of standard metadata fields. -.. literalinclude:: ../src/calibre/ebooks/metadata/book/__init__.py +.. literalinclude:: ../../../src/calibre/ebooks/metadata/book/__init__.py :lines: 7- ''' diff --git a/setup/publish.py b/setup/publish.py index 5c10e5f478..2028d51886 100644 --- a/setup/publish.py +++ b/setup/publish.py @@ -8,7 +8,7 @@ __docformat__ = 'restructuredtext en' import os, shutil, subprocess, glob, tempfile, json, time, filecmp -from setup import Command, __appname__, __version__, require_clean_git, require_git_master +from setup import Command, __version__, require_clean_git, require_git_master from setup.parallel_build import parallel_build class Stage1(Command): @@ -91,18 +91,17 @@ class Manual(Command): shutil.rmtree(tdir) os.mkdir(tdir) st = time.time() - for d in ('.build', 'cli'): + for d in ('generated'): if os.path.exists(d): shutil.rmtree(d) os.makedirs(d) jobs = [] - mandir = self.j(self.d(self.SRC), 'manual') languages = opts.language or list(json.load(open(self.j(self.d(self.SRC), 'manual', 'locale', 'completed.json'), 'rb'))) for language in (['en'] + languages): jobs.append((['calibre-debug', self.j(self.d(self.SRC), 'manual', 'build.py'), - language, self.j(tdir, language), mandir, __appname__, __version__], + language, self.j(tdir, language)], '\n\n**************** Building translations for: %s'%language)) - self.info('Building translations for %d languages' % (len(jobs) - 1)) + self.info('Building manual for %d languages' % len(jobs)) if not parallel_build(jobs, self.info): raise SystemExit(1) os.chdir(self.j(tdir, 'en', 'html'))