This commit is contained in:
Georg Brandl 2009-04-09 21:38:36 +02:00
commit 95392585b2
3 changed files with 52 additions and 27 deletions

View File

@ -23,7 +23,7 @@ except ImportError:
from docutils import nodes
from docutils.io import DocTreeInput, StringOutput
from docutils.core import publish_parts
from docutils.core import Publisher, publish_parts
from docutils.utils import new_document
from docutils.frontend import OptionParser
from docutils.readers.doctree import Reader as DoctreeReader
@ -74,6 +74,8 @@ class StandaloneHTMLBuilder(Builder):
script_files = ['_static/jquery.js', '_static/doctools.js']
def init(self):
# cached publisher object for snippets
self._publisher = None
# a hash of all config values that, if changed, cause a full rebuild
self.config_hash = ''
self.tags_hash = ''
@ -181,13 +183,24 @@ class StandaloneHTMLBuilder(Builder):
"""Utility: Render a lone doctree node."""
doc = new_document('<partial node>')
doc.append(node)
return publish_parts(
doc,
source_class=DocTreeInput,
reader=DoctreeReader(),
writer=HTMLWriter(self),
settings_overrides={'output_encoding': 'unicode'}
)
if self._publisher is None:
self._publisher = Publisher(
source_class = DocTreeInput,
destination_class=StringOutput)
self._publisher.set_components('standalone',
'restructuredtext', 'pseudoxml')
pub = self._publisher
pub.reader = DoctreeReader()
pub.writer = HTMLWriter(self)
pub.process_programmatic_settings(
None, {'output_encoding': 'unicode'}, None)
pub.set_source(doc, None)
pub.set_destination(None, None)
pub.publish()
return pub.writer.parts
def prepare_writing(self, docnames):
from sphinx.search import IndexBuilder

View File

@ -14,8 +14,14 @@ from cStringIO import StringIO
from docutils.nodes import Text, NodeVisitor
from sphinx.util.stemmer import PorterStemmer
from sphinx.util import jsdump, rpartition
try:
# http://bitbucket.org/methane/porterstemmer/
from porterstemmer import Stemmer as CStemmer
CSTEMMER = True
except ImportError:
from sphinx.util.stemmer import PorterStemmer
CSTEMMER = False
word_re = re.compile(r'\w+(?u)')
@ -62,15 +68,23 @@ class _JavaScriptIndex(object):
js_index = _JavaScriptIndex()
class Stemmer(PorterStemmer):
"""
All those porter stemmer implementations look hideous.
make at least the stem method nicer.
"""
if CSTEMMER:
class Stemmer(CStemmer):
def stem(self, word):
return self(word.lower())
else:
class Stemmer(PorterStemmer):
"""
All those porter stemmer implementations look hideous.
make at least the stem method nicer.
"""
def stem(self, word):
word = word.lower()
return PorterStemmer.stem(self, word, 0, len(word) - 1)
def stem(self, word):
word = word.lower()
return PorterStemmer.stem(self, word, 0, len(word) - 1)
class WordCollector(NodeVisitor):
@ -196,11 +210,11 @@ class IndexBuilder(object):
visitor = WordCollector(doctree)
doctree.walk(visitor)
def add_term(word, prefix='', stem=self._stemmer.stem):
def add_term(word, stem=self._stemmer.stem):
word = stem(word)
if len(word) < 3 or word in stopwords or word.isdigit():
return
self._mapping.setdefault(prefix + word, set()).add(filename)
self._mapping.setdefault(word, set()).add(filename)
for word in word_re.findall(title):
add_term(word)

View File

@ -416,30 +416,28 @@ def copy_static_entry(source, target, builder, context={}):
# traverse() is called so many times during a build that it saves
# on average 20-25% overall build time!
def _all_traverse(self):
def _all_traverse(self, result):
"""Version of Node.traverse() that doesn't need a condition."""
result = []
result.append(self)
for child in self.children:
result.extend(child._all_traverse())
child._all_traverse(result)
return result
def _fast_traverse(self, cls):
def _fast_traverse(self, cls, result):
"""Version of Node.traverse() that only supports instance checks."""
result = []
if isinstance(self, cls):
result.append(self)
for child in self.children:
result.extend(child._fast_traverse(cls))
child._fast_traverse(cls, result)
return result
def _new_traverse(self, condition=None,
include_self=1, descend=1, siblings=0, ascend=0):
if include_self and descend and not siblings and not ascend:
if condition is None:
return self._all_traverse()
return self._all_traverse([])
elif isinstance(condition, (types.ClassType, type)):
return self._fast_traverse(condition)
return self._fast_traverse(condition, [])
return self._old_traverse(condition, include_self,
descend, siblings, ascend)