Added initial Apple help support.

This commit is contained in:
Alastair Houghton
2015-01-13 13:25:28 +00:00
parent 9df7b53782
commit b90f319e37
4 changed files with 222 additions and 0 deletions
+1
View File
@@ -442,6 +442,7 @@ BUILTIN_BUILDERS = {
'htmlhelp': ('htmlhelp', 'HTMLHelpBuilder'),
'devhelp': ('devhelp', 'DevhelpBuilder'),
'qthelp': ('qthelp', 'QtHelpBuilder'),
'applehelp': ('applehelp', 'AppleHelpBuilder'),
'epub': ('epub', 'EpubBuilder'),
'latex': ('latex', 'LaTeXBuilder'),
'text': ('text', 'TextBuilder'),
+158
View File
@@ -0,0 +1,158 @@
# -*- coding: utf-8 -*-
"""
sphinx.builders.applehelp
~~~~~~~~~~~~~~~~~~~~~~~~~
Build Apple help books.
:copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from __future__ import print_function
import os
import codecs
import errno
from os import path
from sphinx.builders.html import StandaloneHTMLBuilder
from sphinx.util.osutil import copyfile, ensuredir, os_path
from sphinx.util.console import bold
from sphinx.errors import SphinxError
import plistlib
import subprocess
# Use plistlib.dump in 3.4 and above
try:
write_plist = plistlib.dump
except AttributeError:
write_plist = plistlib.writePlist
class AppleHelpIndexerFailed(SphinxError):
def __str__(self):
return 'Help indexer failed'
class AppleHelpBuilder(StandaloneHTMLBuilder):
"""
Builder that outputs an Apple help book. Requires Mac OS X as it relies
on the ``hiutil`` command line tool.
"""
name = 'applehelp'
# don't copy the reST source
copysource = False
supported_image_types = ['image/png', 'image/gif', 'image/jpeg',
'image/tiff', 'image/jp2', 'image/svg+xml']
# don't add links
add_permalinks = False
# *do* add the sidebar (Apple Help doesn't have its own)
embedded = False
def init(self):
super(AppleHelpBuilder, self).init()
# the output files for HTML help must be .html only
self.out_suffix = '.html'
self.bundle_path = path.join(self.outdir,
self.config.applehelp_bundle_name \
+ '.help')
self.outdir = path.join(self.bundle_path,
'Contents',
'Resources',
(self.config.language or 'en') + '.lproj')
def handle_finish(self):
contents_dir = path.join(self.bundle_path, 'Contents')
resources_dir = path.join(contents_dir, 'Resources')
language_dir = path.join(resources_dir,
(self.config.language or 'en') + '.lproj')
for d in [contents_dir, resources_dir, language_dir]:
ensuredir(d)
# Construct the Info.plist file
info_plist = {
'CFBundleDevelopmentRegion': self.config.applehelp_dev_region,
'CFBundleIdentifier': self.config.applehelp_bundle_id,
'CFBundleInfoDictionaryVersion': 6.0,
'CFBundleName': self.config.applehelp_bundle_name,
'CFBundlePackageType': 'BNDL',
'CFBundleShortVersionString': self.config.release,
'CFBundleSignature': 'hbwr',
'CFBundleVersion': self.config.applehelp_bundle_version,
'CFBundleHelpTOCFile': 'index.html',
'HPDBookAccessPath': 'index.html',
'HPDBookIndexPath': 'index.helpindex',
'HPDBookTitle': self.config.html_title,
'HPDBookType': 3,
}
if self.config.applehelp_icon is not None:
info_plist['HPDBookIconPath'] \
= path.basename(self.config.applehelp_icon)
if self.config.applehelp_kb_url is not None:
info_plist['HPDBookKBProduct'] = self.config.applehelp_kb_product
info_plist['HPDBookKBURL'] = self.config.applehelp_kb_url
if self.config.applehelp_remote_url is not None:
info_plist['HPDBookRemoteURL'] = self.config.applehelp_remote_url
self.info(bold('writing Info.plist... '), nonl=True)
f = codecs.open(path.join(contents_dir, 'Info.plist'), 'w')
try:
write_plist(info_plist, f)
finally:
f.close()
self.info('done')
# Copy the icon, if one is supplied
if self.config.applehelp_icon:
self.info(bold('copying icon... '), nonl=True)
try:
copyfile(path.join(self.srcdir, self.config.applehelp_icon),
path.join(resources_dir, info_plist['HPDBookIconPath']))
self.info('done')
except Exception as err:
self.warn('cannot copy icon file %r: %s' %
(path.join(self.srcdir, self.config.applehelp_icon),
err))
del info_plist['HPDBookIconPath']
# Generate the help index
self.info(bold('generating help index... '), nonl=True)
args = [
'/usr/bin/hiutil',
'-Cf',
path.join(language_dir, 'index.helpindex'),
language_dir
]
if self.config.applehelp_index_anchors is not None:
args.append('-a')
if self.config.applehelp_min_term_length is not None:
args += ['-m', '%s' % self.config.applehelp_min_term_length]
if self.config.applehelp_stopwords is not None:
args += ['-s', self.config.applehelp_stopwords]
if self.config.applehelp_locale is not None:
args += ['-l', self.config.applehelp_locale]
result = subprocess.call(args)
if result != 0:
raise AppleHelpIndexerFailed
else:
self.info('done')
+18
View File
@@ -129,6 +129,24 @@ class Config(object):
# Devhelp only options
devhelp_basename = (lambda self: make_filename(self.project), None),
# Apple help only options
applehelp_bundle_name = (lambda self: make_filename(self.project),
'applehelp'),
applehelp_bundle_id = (lambda self: 'com.mycompany.%s.help' \
% make_filename(self.project), 'applehelp'),
applehelp_dev_region = ('en_us', 'applehelp'),
applehelp_bundle_version = (1, 'applehelp'),
applehelp_icon = (None, 'applehelp'),
applehelp_kb_product = (lambda self: '%s-%s' \
% (make_filename(self.project), self.release),
'applehelp'),
applehelp_kb_url = (None, 'applehelp'),
applehelp_remote_url = (None, 'applehelp'),
applehelp_index_anchors = (False, 'applehelp'),
applehelp_min_term_length = (None, 'applehelp'),
applehelp_stopwords = (lambda self: self.language or 'en', 'applehelp'),
applehelp_locale = (lambda self: self.language or 'en_us', 'applehelp'),
# Epub options
epub_basename = (lambda self: make_filename(self.project), None),
epub_theme = ('epub', 'html'),
+45
View File
@@ -32,6 +32,7 @@ except ImportError:
from six import PY2, PY3, text_type
from six.moves import input
from six.moves.urllib.parse import quote as urlquote
from docutils.utils import column_width
from sphinx import __version__
@@ -266,6 +267,43 @@ html_static_path = ['%(dot)sstatic']
# Output file base name for HTML help builder.
htmlhelp_basename = '%(project_fn)sdoc'
# -- Options for Apple Help output ----------------------------------------
# The bundle name.
#applehelp_bundle_name = u'%(project_fn)s'
# The bundle id.
#applehelp_bundle_id = 'com.mycompany.%(project_url)s.help'
# The development region. Should be 'en_us' in most cases.
#applehelp_dev_region = 'en_us'
# The bundle version.
#applehelp_bundle_version = 1
# The icon file
#applehelp_icon = '%(project_fn)s.icns'
# These allow remote searching of a knowledge base on your server
#applehelp_kb_url = "https://kb.example.com/search?p='product'&q='query'&l='lang'"
#applehelp_kb_product = '%(project_fn)s-%(release)s'
# This lets you host a remote copy of the documentation that you can update
# without having to ship new versions of your application
#applehelp_remote_url = 'https://help.example.com/%(project_fn)s/%(version)s/'
# Whether to index anchors
#applehelp_index_anchors = False
# Minimum term length for indexing
#applehelp_min_term_length = None
# Stop words (either a language identifier, for built-in stop words, or a plist)
#applehelp_stopwords = %(language)r
# Locale for indexing
#applehelp_locale = %(language)r
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
@@ -491,6 +529,7 @@ help:
\t@echo " json to make JSON files"
\t@echo " htmlhelp to make HTML files and a HTML help project"
\t@echo " qthelp to make HTML files and a qthelp project"
\t@echo " applehelp to make an Apple Help Book"
\t@echo " devhelp to make HTML files and a Devhelp project"
\t@echo " epub to make an epub"
\t@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@@ -552,6 +591,11 @@ qthelp:
\t@echo "To view the help file:"
\t@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/%(project_fn)s.qhc"
applehelp:
\t$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
\t@echo
\t@echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
devhelp:
\t$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
\t@echo
@@ -1273,6 +1317,7 @@ def generate(d, overwrite=True, silent=False):
d['mastertocmaxdepth'] = 2
d['project_fn'] = make_filename(d['project'])
d['project_url'] = urlquote(d['project'])
d['project_manpage'] = d['project_fn'].lower()
d['now'] = time.asctime()
d['project_underline'] = column_width(d['project']) * '='