diff options
author | blackbird <devnull@localhost> | 2006-10-22 12:54:00 +0200 |
---|---|---|
committer | blackbird <devnull@localhost> | 2006-10-22 12:54:00 +0200 |
commit | f2db9aedba7959d57d43903e4eff78db101e6234 (patch) | |
tree | f84bda4581de9a456c47b2ee8aeb61482ff385d7 | |
parent | 7fd6f0d8a3903a6538ffeec2d64102cfe8ce23b1 (diff) | |
download | pygments-f2db9aedba7959d57d43903e4eff78db101e6234.tar.gz |
[svn] added experimental (untested) plugin support. i'll try writing some plugins tomorrow when i've more time ;)
-rw-r--r-- | docs/src/index.txt | 2 | ||||
-rw-r--r-- | docs/src/plugins.txt | 72 | ||||
-rw-r--r-- | pygments/formatters/__init__.py | 8 | ||||
-rw-r--r-- | pygments/lexers/__init__.py | 14 | ||||
-rw-r--r-- | pygments/plugin.py | 61 | ||||
-rw-r--r-- | pygments/styles/__init__.py | 8 |
6 files changed, 160 insertions, 5 deletions
diff --git a/docs/src/index.txt b/docs/src/index.txt index 87d7afab..08e77f62 100644 --- a/docs/src/index.txt +++ b/docs/src/index.txt @@ -34,6 +34,8 @@ Welcome to the Pygments documentation. - `Write your own formatter <formatterdev.txt>`_ + - `Register Plugins <plugins.txt>`_ + - Hints and Tricks - `Using Pygments in ReST documents <rstdirective.txt>`_ diff --git a/docs/src/plugins.txt b/docs/src/plugins.txt new file mode 100644 index 00000000..6c37d707 --- /dev/null +++ b/docs/src/plugins.txt @@ -0,0 +1,72 @@ +================ +Register Plugins +================ + +If you want to extend pygments without hacking in the sources but want to +use the lexer/formatter/style resolve functions you can use setuptools +entrypoints to add new lexers, formatters or styles to the pygments core. + +That means you can use your highlighter also with the ``pygmentize`` script. + + +Entrypoints +=========== + +Here a list of setuptools entrypoints pygments understands: + +`pygments.lexers` + + This entrypoint is used for adding new lexers to the pygments core. + The name of entrypoint values doesn't really matter, pygements extract + required informations from the class definition: + + .. sourcecode:: ini + + [pygments.lexers] + yourlexer = yourmodule:YourLexer + + Note that you have to + defined a ``name``, ``aliases`` and ``filename`` patterns so that you + can use the highlighter from the command line: + + .. sourcecode:: python + + class YourLexer(...): + name = 'Name Of Your Lexer' + aliases = ['alias'] + filenames = ['*.ext'] + + +`pygments.formatters` + + You can use this entrypoint to add new formatters to pygments. The + name of an entrypoint item is the name of the formatter. If you + prefix the name with a slash it's used for the filename pattern: + + .. sourcecode:: ini + + [pygments.formatters] + yourformatter = yourmodule:YourFormatter + /.ext = yourmodule:YourFormatter + + +`pygments.styles` + + To add a new style you can use this entrypoint. The name of the entrypoint + is the name of the style: + + .. sourcecode:: ini + + [pygments.styles] + yourstyle = yourmodule:YourStyle + + +How To Use Entrypoints +====================== + +This documentation doesn't explain how to use those entrypoints because this is +covered in the `setuptools documentation`_. That page should cover everything +you need to write a plugin. Also `this blog entry`_ might be interesting. + +.. _setuptools documentation: http://peak.telecommunity.com/DevCenter/setuptools +.. _this blog entry: http://lucumr.pocoo.org/entry/setuptools-plugins/ diff --git a/pygments/formatters/__init__.py b/pygments/formatters/__init__.py index d112a88e..74557440 100644 --- a/pygments/formatters/__init__.py +++ b/pygments/formatters/__init__.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """ pygments.formatters - ~~~~~~~~~~~~~~~~~~ + ~~~~~~~~~~~~~~~~~~~ Pygments formatters. @@ -14,6 +14,7 @@ from pygments.formatters.terminal import TerminalFormatter from pygments.formatters.latex import LatexFormatter from pygments.formatters.bbcode import BBCodeFormatter from pygments.formatters.other import NullFormatter, RawTokenFormatter +from pygments.plugin import find_plugin_formatters def _doc_desc(obj): @@ -46,12 +47,15 @@ FORMATTERS = { _formatter_cache = {} def _init_formatter_cache(): - if _formatter_cache: return + if _formatter_cache: + return for cls, info in FORMATTERS.iteritems(): for alias in info[1]: _formatter_cache[alias] = cls for ext in info[2]: _formatter_cache["/"+ext] = cls + for name, cls in find_plugin_formatters(): + _formatter_cache[name] = cls def get_formatter_by_name(name, **options): diff --git a/pygments/lexers/__init__.py b/pygments/lexers/__init__.py index 0ef200db..99ec4a79 100644 --- a/pygments/lexers/__init__.py +++ b/pygments/lexers/__init__.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """ pygments.lexers - ~~~~~~~~~~~~~~ + ~~~~~~~~~~~~~~~ Pygments lexers. @@ -13,6 +13,7 @@ import types from os.path import basename from pygments.lexers._mapping import LEXERS +from pygments.plugin import find_plugin_lexers __all__ = ['get_lexer_by_name', 'get_lexer_for_filename'] + LEXERS.keys() @@ -34,11 +35,16 @@ def get_lexer_by_name(alias, **options): """ Get a lexer by an alias """ + # lookup builtin lexers for module_name, name, aliases, _ in LEXERS.itervalues(): if alias in aliases: if name not in _lexer_cache: _load_lexers(module_name) return _lexer_cache[name](**options) + # continue with lexers from setuptools entrypoints + for cls in find_plugin_lexers(): + if alias in cls.aliases: + return cls(**options) raise ValueError('no lexer for alias %r found' % alias) @@ -47,12 +53,18 @@ def get_lexer_for_filename(fn, **options): Guess a lexer by a filename """ fn = basename(fn) + # lookup builtin lexers for module_name, name, _, filenames in LEXERS.itervalues(): for filename in filenames: if fnmatch.fnmatch(fn, filename): if name not in _lexer_cache: _load_lexers(module_name) return _lexer_cache[name](**options) + # continue with lexers from setuptools entrypoints + for cls in find_plugin_lexers(): + for filename in cls.filenames: + if fnmatch.fnmatch(fn, filename): + return cls(**options) raise ValueError('no lexer for filename %r found' % fn) diff --git a/pygments/plugin.py b/pygments/plugin.py new file mode 100644 index 00000000..7cbb9f1c --- /dev/null +++ b/pygments/plugin.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +""" + pygments.plugin + ~~~~~~~~~~~~~~~ + + Pygments setuptools plugin interface. The methods defined + here also work if setuptools isn't installed but they just + return nothing. + + lexer plugins:: + + [pygments.lexers] + yourlexer = yourmodule:YourLexer + + formatter plugins:: + + [pygments.formatters] + yourformatter = yourformatter:YourFormatter + /.ext = yourformatter:YourFormatter + + As you can see, you can define extensions for the formatter + with a leading slash. + + syntax plugins:: + + [pygments.styles] + yourstyle = yourstyle:YourStyle + + + :coypright: 2006 by Armin Ronacher. + :license: GNU LGPG; see LICENSE for more details. +""" +try: + import pkg_resources +except ImportError: + pkg_resources = None + +LEXER_ENTRY_POINT = 'pygments.lexers' +FORMATTER_ENTRY_POINT = 'pygments.formatters' +STYLE_ENTRY_POINT = 'pygments.styles' + + +def find_plugin_lexers(): + if pkg_resources is None: + return + for entrypoint in pkg_resources.iter_entry_points(LEXER_ENTRY_POINT): + yield entrypoint.load() + + +def find_plugin_formatters(): + if pkg_resources is None: + return + for entrypoint in pkg_resources.iter_entry_points(FORMATTER_ENTRY_POINT): + yield entrypoint.name, entrypoint.load() + + +def find_plugin_styles(): + if pkg_resources is None: + return + for entrypoint in pkg_resources.iter_entry_points(STYLE_ENTRY_POINT): + yield entrypoint.name, entrypoint.load() diff --git a/pygments/styles/__init__.py b/pygments/styles/__init__.py index bfa0730d..c92456d5 100644 --- a/pygments/styles/__init__.py +++ b/pygments/styles/__init__.py @@ -1,13 +1,15 @@ # -*- coding: utf-8 -*- """ pygments.styles - ~~~~~~~~~~~~~~ + ~~~~~~~~~~~~~~~ Contains built-in styles. :copyright: 2006 by Georg Brandl. :license: GNU LGPL, see LICENSE for more details. """ +from pygments.plugin import find_plugin_styles + #: Maps style names to 'submodule::classname'. STYLE_MAP = { @@ -28,9 +30,11 @@ STYLE_MAP = { def get_style_by_name(name): if name not in STYLE_MAP: + for found_name, style in find_plugin_styles(): + if name == found_name: + return style raise ValueError("Style %r not found" % name) mod, cls = STYLE_MAP[name].split('::') - mod = __import__('pygments.styles.' + mod, None, None, [cls]) return getattr(mod, cls) |