[Python-checkins] r64530 - in doctools/trunk: CHANGES doc/builders.rst sphinx/builder.py sphinx/quickstart.py sphinx/search.py sphinx/templates/genindex-single.html sphinx/templates/genindex.html sphinx/util/_json.py sphinx/util/json.py
armin.ronacher
python-checkins at python.org
Thu Jun 26 13:11:21 CEST 2008
Author: armin.ronacher
Date: Thu Jun 26 13:11:20 2008
New Revision: 64530
Log:
Implemented JSONHTMLBuilder and improved JSON handling (it now prefers json from the 2.6 stdlib or simplejson).
Added:
doctools/trunk/sphinx/util/_json.py
Modified:
doctools/trunk/CHANGES
doctools/trunk/doc/builders.rst
doctools/trunk/sphinx/builder.py
doctools/trunk/sphinx/quickstart.py
doctools/trunk/sphinx/search.py
doctools/trunk/sphinx/templates/genindex-single.html
doctools/trunk/sphinx/templates/genindex.html
doctools/trunk/sphinx/util/json.py
Modified: doctools/trunk/CHANGES
==============================================================================
--- doctools/trunk/CHANGES (original)
+++ doctools/trunk/CHANGES Thu Jun 26 13:11:20 2008
@@ -9,6 +9,9 @@
`PickleHTMLBuilder` is a concrete subclass of it that uses pickle as
serialization implementation.
+* `JSONHTMLBuilder` was added that similarily to `PickleHTMLBuilder`
+ dumps the generated HTML into JSON files for further processing.
+
Release 0.4 (Jun 23, 2008)
==========================
Modified: doctools/trunk/doc/builders.rst
==============================================================================
--- doctools/trunk/doc/builders.rst (original)
+++ doctools/trunk/doc/builders.rst Thu Jun 26 13:11:20 2008
@@ -34,8 +34,7 @@
This builder produces a directory with pickle files containing mostly HTML
fragments and TOC information, for use of a web application (or custom
- postprocessing tool) that doesn't use the standard HTML templates. It also
- is the format used by the Sphinx Web application.
+ postprocessing tool) that doesn't use the standard HTML templates.
See :ref:`serialization-details` for details about the output format.
@@ -44,6 +43,21 @@
The file suffix is ``.fpickle``. The global context is called
``globalcontext.pickle``, the search index ``searchindex.pickle``.
+.. class:: JSONHTMLBuilder
+
+ This builder produces a directory with JSON files containing mostly HTML
+ fragments and TOC information, for use of a web application (or custom
+ postprocessing tool) that doesn't use the standard HTML templates.
+
+ See :ref:`serialization-details` for details about the output format.
+
+ Its name is ``json``.
+
+ The file suffix is ``.fjson``. The global context is called
+ ``globalcontext.json``, the search index ``searchindex.json``.
+
+ .. versionadded:: 0.5
+
.. class:: LaTeXBuilder
This builder produces a bunch of LaTeX files in the output directory. You
@@ -70,17 +84,19 @@
(`pickle`, `simplejson`, `phpserialize`, and others) to dump the generated
HTML documentation. The pickle builder is a subclass of it.
- A concreate subclass of this builder serializing to JSON could look like
- this::
+ A concreate subclass of this builder serializing to the `PHP serialization`_
+ format could look like this::
+
+ import phpserialize
- import simplejson
+ classs PHPSerializedBuilder(SerializingHTMLBuilder):
+ name = 'phpserialized'
+ implementation = phpserialize
+ out_suffix = '.file.phpdump'
+ globalcontext_filename = 'globalcontext.phpdump'
+ searchindex_filename = 'searchindex.phpdump'
- classs JSONBuilder(SerializingHTMLBuilder):
- name = 'json'
- implementation = simplejson
- out_suffix = '.fjson'
- globalcontext_filename = 'globalcontext.json'
- searchindex_filename = 'searchindex.json'
+ .. _PHP serialization: http://pypi.python.org/pypi/phpserialize
.. attribute:: implementation
Modified: doctools/trunk/sphinx/builder.py
==============================================================================
--- doctools/trunk/sphinx/builder.py (original)
+++ doctools/trunk/sphinx/builder.py Thu Jun 26 13:11:20 2008
@@ -25,7 +25,7 @@
from docutils.readers.doctree import Reader as DoctreeReader
from sphinx import addnodes
-from sphinx.util import ensuredir, relative_uri, SEP, os_path
+from sphinx.util import ensuredir, relative_uri, SEP, os_path, json
from sphinx.htmlhelp import build_hhx
from sphinx.htmlwriter import HTMLWriter, HTMLTranslator, SmartyPantsHTMLTranslator
from sphinx.textwriter import TextWriter
@@ -294,7 +294,7 @@
name = 'html'
copysource = True
out_suffix = '.html'
- indexer_format = 'json'
+ indexer_format = json
supported_image_types = ['image/svg+xml', 'image/png', 'image/gif',
'image/jpeg']
searchindex_filename = 'searchindex.json'
@@ -379,8 +379,7 @@
builder = self.name,
parents = [],
logo = logo,
- favicon = favicon,
- len = len, # the built-in
+ favicon = favicon
)
def get_doc_context(self, docname, body):
@@ -624,12 +623,14 @@
def load_indexer(self, docnames):
try:
- f = open(path.join(self.outdir, self.searchindex_filename), 'r')
+ f = open(path.join(self.outdir, self.searchindex_filename), 'rb')
try:
self.indexer.load(f, self.indexer_format)
finally:
f.close()
- except (IOError, OSError):
+ except (IOError, OSError, NotImplementedError):
+ # we catch NotImplementedError here because if no simplejson
+ # is installed the searchindex can't be loaded
pass
# delete all entries for files that will be rebuilt
self.indexer.prune(set(self.env.all_docs) - set(docnames))
@@ -683,9 +684,9 @@
def handle_finish(self):
self.info(bold('dumping search index...'))
self.indexer.prune(self.env.all_docs)
- f = open(path.join(self.outdir, 'searchindex.json'), 'w')
+ f = open(path.join(self.outdir, self.searchindex_filename), 'wb')
try:
- self.indexer.dump(f, 'json')
+ self.indexer.dump(f, self.indexer_format)
finally:
f.close()
@@ -702,9 +703,6 @@
#: the filename for the global context file
globalcontext_filename = None
- #: If set to `None` the indexer uses the serialization implementation
- indexer_format = None
-
supported_image_types = ('image/svg+xml', 'image/png', 'image/gif',
'image/jpeg')
@@ -712,6 +710,9 @@
self.init_translator_class()
self.templates = None # no template bridge necessary
+ indexer_format = property(lambda x: x.implementation, doc='''
+ Alias the indexer format to the serilization implementation''')
+
def get_target_uri(self, docname, typ=None):
if docname == 'index':
return ''
@@ -754,13 +755,8 @@
finally:
f.close()
- self.info(bold('dumping search index...'))
- self.indexer.prune(self.env.all_docs)
- f = open(path.join(self.outdir, self.searchindex_filename), 'wb')
- try:
- self.indexer.dump(f, self.indexer_format or self.implementation)
- finally:
- f.close()
+ # super here to dump the search index
+ StandaloneHTMLBuilder.handle_finish(self)
# copy the environment file from the doctree dir to the output dir
# as needed by the web app
@@ -773,6 +769,9 @@
class PickleHTMLBuilder(SerializingHTMLBuilder):
+ """
+ A Builder that dumps the generated HTML into pickle files.
+ """
implementation = pickle
name = 'pickle'
out_suffix = '.fpickle'
@@ -780,6 +779,17 @@
searchindex_filename = 'searchindex.pickle'
+class JSONHTMLBuilder(SerializingHTMLBuilder):
+ """
+ A builder that dumps the generated HTML into JSON files.
+ """
+ implementation = json
+ name = 'json'
+ out_suffix = '.fjson'
+ globalcontext_filename = 'globalcontext.json'
+ searchindex_filename = 'searchindex.json'
+
+
class HTMLHelpBuilder(StandaloneHTMLBuilder):
"""
Builder that also outputs Windows HTML help project, contents and index files.
@@ -1128,6 +1138,7 @@
builtin_builders = {
'html': StandaloneHTMLBuilder,
'pickle': PickleHTMLBuilder,
+ 'json': JSONHTMLBuilder,
'web': PickleHTMLBuilder,
'htmlhelp': HTMLHelpBuilder,
'latex': LaTeXBuilder,
Modified: doctools/trunk/sphinx/quickstart.py
==============================================================================
--- doctools/trunk/sphinx/quickstart.py (original)
+++ doctools/trunk/sphinx/quickstart.py Thu Jun 26 13:11:20 2008
@@ -238,7 +238,8 @@
help:
\t at echo "Please use \\`make <target>' where <target> is one of"
\t at echo " html to make standalone HTML files"
-\t at echo " pickle to make pickle files (usable by e.g. sphinx-web)"
+\t at echo " pickle to make pickle files"
+\t at echo " json to make JSON files"
\t at echo " htmlhelp to make HTML files and a HTML help project"
\t at echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
\t at echo " changes to make an overview over all changed/added/deprecated items"
@@ -261,6 +262,12 @@
web: pickle
+json:
+\tmkdir -p %(rbuilddir)s/json %(rbuilddir)s/doctrees
+\t$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) %(rbuilddir)s/json
+\t at echo
+\t at echo "Build finished; now you can process the JSON files."
+
htmlhelp:
\tmkdir -p %(rbuilddir)s/htmlhelp %(rbuilddir)s/doctrees
\t$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) %(rbuilddir)s/htmlhelp
Modified: doctools/trunk/sphinx/search.py
==============================================================================
--- doctools/trunk/sphinx/search.py (original)
+++ doctools/trunk/sphinx/search.py Thu Jun 26 13:11:20 2008
@@ -9,7 +9,7 @@
:license: BSD.
"""
import re
-import pickle
+import cPickle as pickle
from docutils.nodes import Text, NodeVisitor
Modified: doctools/trunk/sphinx/templates/genindex-single.html
==============================================================================
--- doctools/trunk/sphinx/templates/genindex-single.html (original)
+++ doctools/trunk/sphinx/templates/genindex-single.html Thu Jun 26 13:11:20 2008
@@ -24,7 +24,7 @@
{%- endfor %}
</dl></dd>
{%- endif -%}
-{%- set numitems = numitems + 1 + len(subitems) -%}
+{%- set numitems = numitems + 1 + subitems|length -%}
{%- if numcols < 2 and numitems > breakat -%}
{%- set numcols = numcols+1 -%}
</dl></td><td width="33%" valign="top"><dl>
Modified: doctools/trunk/sphinx/templates/genindex.html
==============================================================================
--- doctools/trunk/sphinx/templates/genindex.html (original)
+++ doctools/trunk/sphinx/templates/genindex.html Thu Jun 26 13:11:20 2008
@@ -32,7 +32,7 @@
{%- endfor %}
</dl></dd>
{%- endif -%}
-{%- set numitems = numitems + 1 + len(subitems) -%}
+{%- set numitems = numitems + 1 + subitems|length -%}
{%- if numcols < 2 and numitems > breakat -%}
{%- set numcols = numcols+1 -%}
</dl></td><td width="33%" valign="top"><dl>
Added: doctools/trunk/sphinx/util/_json.py
==============================================================================
--- (empty file)
+++ doctools/trunk/sphinx/util/_json.py Thu Jun 26 13:11:20 2008
@@ -0,0 +1,75 @@
+# -*- coding: utf-8 -*-
+"""
+ sphinx.util._json
+ ~~~~~~~~~~~~~~~~~
+
+ This module implements a simple JSON serializer if simplejson is
+ unavailable.
+
+ This is not fully JSON compliant but enough for the searchindex.
+ And the generated files are smaller than the simplejson ones.
+
+ Uses the basestring encode function from simplejson.
+
+ :copyright: Copyright 2008 by Armin Ronacher, Bob Ippolito.
+ :license: BSD.
+"""
+import re
+
+
+# escape \, ", control characters and everything outside ASCII
+ESCAPE_ASCII = re.compile(r'([\\"]|[^\ -~])')
+ESCAPE_DICT = {
+ '\\': '\\\\',
+ '"': '\\"',
+ '\b': '\\b',
+ '\f': '\\f',
+ '\n': '\\n',
+ '\r': '\\r',
+ '\t': '\\t',
+}
+
+
+def encode_basestring_ascii(s):
+ def replace(match):
+ s = match.group(0)
+ try:
+ return ESCAPE_DICT[s]
+ except KeyError:
+ n = ord(s)
+ if n < 0x10000:
+ return '\\u%04x' % (n,)
+ else:
+ # surrogate pair
+ n -= 0x10000
+ s1 = 0xd800 | ((n >> 10) & 0x3ff)
+ s2 = 0xdc00 | (n & 0x3ff)
+ return '\\u%04x\\u%04x' % (s1, s2)
+ return '"' + str(ESCAPE_ASCII.sub(replace, s)) + '"'
+
+
+def dumps(obj, key=False):
+ if key:
+ if not isinstance(obj, basestring):
+ obj = str(obj)
+ return encode_basestring_ascii(obj)
+ if obj is None:
+ return 'null'
+ elif obj is True or obj is False:
+ return obj and 'true' or 'false'
+ elif isinstance(obj, (int, long, float)):
+ return str(obj)
+ elif isinstance(obj, dict):
+ return '{%s}' % ','.join('%s:%s' % (
+ dumps(key, True),
+ dumps(value)
+ ) for key, value in obj.iteritems())
+ elif isinstance(obj, (tuple, list, set)):
+ return '[%s]' % ','.join(dumps(x) for x in obj)
+ elif isinstance(obj, basestring):
+ return encode_basestring_ascii(obj)
+ raise TypeError(type(obj))
+
+
+def dump(obj, f):
+ f.write(dumps(obj))
Modified: doctools/trunk/sphinx/util/json.py
==============================================================================
--- doctools/trunk/sphinx/util/json.py (original)
+++ doctools/trunk/sphinx/util/json.py Thu Jun 26 13:11:20 2008
@@ -3,87 +3,32 @@
sphinx.util.json
~~~~~~~~~~~~~~~~
- Minimal JSON module that generates small dumps.
+ This module imports JSON functions from various locations.
- This is not fully JSON compliant but enough for the searchindex.
- And the generated files are smaller than the simplejson ones.
-
- Uses the basestring encode function from simplejson.
-
- :copyright: 2007-2008 by Armin Ronacher, Bob Ippolito.
+ :copyright: Copyright 2008 by Armin Ronacher.
:license: BSD.
"""
-import re
-
-# escape \, ", control characters and everything outside ASCII
-ESCAPE_ASCII = re.compile(r'([\\"]|[^\ -~])')
-ESCAPE_DICT = {
- '\\': '\\\\',
- '"': '\\"',
- '\b': '\\b',
- '\f': '\\f',
- '\n': '\\n',
- '\r': '\\r',
- '\t': '\\t',
-}
-
-
-def encode_basestring_ascii(s):
- def replace(match):
- s = match.group(0)
- try:
- return ESCAPE_DICT[s]
- except KeyError:
- n = ord(s)
- if n < 0x10000:
- return '\\u%04x' % (n,)
- else:
- # surrogate pair
- n -= 0x10000
- s1 = 0xd800 | ((n >> 10) & 0x3ff)
- s2 = 0xdc00 | (n & 0x3ff)
- return '\\u%04x\\u%04x' % (s1, s2)
- return '"' + str(ESCAPE_ASCII.sub(replace, s)) + '"'
-
-
-def dump_json(obj, key=False):
- if key:
- if not isinstance(obj, basestring):
- obj = str(obj)
- return encode_basestring_ascii(obj)
- if obj is None:
- return 'null'
- elif obj is True or obj is False:
- return obj and 'true' or 'false'
- elif isinstance(obj, (int, long, float)):
- return str(obj)
- elif isinstance(obj, dict):
- return '{%s}' % ','.join('%s:%s' % (
- dump_json(key, True),
- dump_json(value)
- ) for key, value in obj.iteritems())
- elif isinstance(obj, (tuple, list, set)):
- return '[%s]' % ','.join(dump_json(x) for x in obj)
- elif isinstance(obj, basestring):
- return encode_basestring_ascii(obj)
- raise TypeError(type(obj))
-
-
-STRING = re.compile(r'("(\\\\|\\"|[^"])*")')
-
-def load_json(s):
- d = {'null': None, 'true': True, 'false': False}
- s = STRING.sub(r'u\1', s)
- return eval(s, d)
-
-
-# serializer interface
-dumps = dump_json
-loads = load_json
+# if no simplejson is available this module can not load json files.
+can_load = True
-def dump(obj, f):
- f.write(dumps(obj))
+# unset __name__ for a moment so that the import goes straight into
+# the stdlib for python 2.4.
+_old_name = __name__
+del __name__
+
+try:
+ from simplejson import dumps, dump, loads, load
+except ImportError:
+ try:
+ from json import dumps, dump, loads, load
+ except ImportError:
+ from sphinx.util._json import dumps, dump
+ def _dummy(x):
+ raise NotImplementedError('simplejson unavailable, can\'t load')
+ load = loads = _dummy
+ can_load = False
+ del _dummy
-def load(f):
- return loads(f.read())
+__name__ = _old_name
+del _old_name
More information about the Python-checkins
mailing list