1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
|
# coding: utf-8
"""
Implements the plugin API for MkDocs.
"""
from __future__ import unicode_literals
import pkg_resources
import logging
from collections import OrderedDict
from mkdocs.config.base import Config
log = logging.getLogger('mkdocs.plugins')
EVENTS = (
'config', 'pre_build', 'files', 'nav', 'env', 'pre_template', 'template_context',
'post_template', 'pre_page', 'page_read_source', 'page_markdown',
'page_content', 'page_context', 'post_page', 'post_build', 'serve'
)
def get_plugins():
""" Return a dict of all installed Plugins by name. """
plugins = pkg_resources.iter_entry_points(group='mkdocs.plugins')
return dict((plugin.name, plugin) for plugin in plugins)
class BasePlugin(object):
"""
Plugin base class.
All plugins should subclass this class.
"""
config_scheme = ()
config = {}
def load_config(self, options, config_file_path=None):
""" Load config from a dict of options. Returns a tuple of (errors, warnings)."""
self.config = Config(schema=self.config_scheme, config_file_path=config_file_path)
self.config.load_dict(options)
return self.config.validate()
class PluginCollection(OrderedDict):
"""
A collection of plugins.
In addition to being a dict of Plugin instances, each event method is registered
upon being added. All registered methods for a given event can then be run in order
by calling `run_event`.
"""
def __init__(self, *args, **kwargs):
super(PluginCollection, self).__init__(*args, **kwargs)
self.events = {x: [] for x in EVENTS}
def _register_event(self, event_name, method):
""" Register a method for an event. """
self.events[event_name].append(method)
def __setitem__(self, key, value, **kwargs):
if not isinstance(value, BasePlugin):
raise TypeError(
'{0}.{1} only accepts values which are instances of {3}.{4} '
'sublcasses'.format(self.__module__, self.__name__,
BasePlugin.__module__, BasePlugin.__name__))
super(PluginCollection, self).__setitem__(key, value, **kwargs)
# Register all of the event methods defined for this Plugin.
for event_name in (x for x in dir(value) if x.startswith('on_')):
method = getattr(value, event_name)
if callable(method):
self._register_event(event_name[3:], method)
def run_event(self, name, item, **kwargs):
"""
Run all registered methods of an event.
`item` is the object to be modified and returned by the event method.
All other keywords are variables for context, but would not generally
be modified by the event method.
"""
for method in self.events[name]:
result = method(item, **kwargs)
# keep item if method returned `None`
if result is not None:
item = result
return item
|