blob: c0dfe44c782ad101d287a137ddc15deb3ef3070f [file] [log] [blame]
Armin Ronacher3c8b7ad2008-04-28 13:52:21 +02001# -*- coding: utf-8 -*-
2"""
3 Jinja Documentation Extensions
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
6 Support for automatically documenting filters and tests.
7
8 :copyright: Copyright 2008 by Armin Ronacher.
9 :license: BSD.
10"""
11import inspect
12from docutils import nodes
13from docutils.statemachine import ViewList
14from sphinx.ext.autodoc import prepare_docstring
15
16
17def format_filter(name, aliases, func):
18 try:
19 argspec = inspect.getargspec(func)
20 except:
21 try:
22 argspec = inspect.getargspec(func.__init__)
23 except:
24 try:
25 argspec = inspect.getargspec(func.__new__)
26 except:
27 return []
28 del argspec[0][0]
29 if getattr(func, 'environmentfilter', False) or \
30 getattr(func, 'contextfilter', False):
31 del argspec[0][0]
32 signature = inspect.formatargspec(*argspec)
33 result = ['.. function:: %s%s' % (name, signature), '']
34 for line in inspect.getdoc(func).splitlines():
35 result.append(' ' + line)
36 if aliases:
37 result.extend(('', ' :aliases: %s' % ', '.join(
38 '``%s``' % x for x in sorted(aliases))))
39 return result
40
41
42def jinja_filters(dirname, arguments, options, content, lineno,
43 content_offset, block_text, state, state_machine):
44 from jinja2.defaults import DEFAULT_FILTERS
45 mapping = {}
46 for name, func in DEFAULT_FILTERS.iteritems():
47 mapping.setdefault(func, []).append(name)
48 filters = []
49 for func, names in mapping.iteritems():
50 aliases = sorted(names, key=lambda x: len(x))
51 name = aliases.pop()
52 filters.append((name, aliases, func))
53 filters.sort()
54
55 result = ViewList()
56 for name, aliases, func in filters:
57 for item in format_filter(name, aliases, func):
58 result.append(item, '<jinjaext>')
59
60 node = nodes.paragraph()
61 state.nested_parse(result, content_offset, node)
62 return node.children
63
64
65def setup(app):
66 app.add_directive('jinjafilters', jinja_filters, 1, (0, 0, 0))