pax_global_header00006660000000000000000000000064112657634520014525gustar00rootroot0000000000000052 comment=7d61f618f9a7c1ecada1d0ea307f89444ea16585 django-genshi-1.1.3/000077500000000000000000000000001126576345200142445ustar00rootroot00000000000000django-genshi-1.1.3/PKG-INFO000066400000000000000000000064201126576345200153430ustar00rootroot00000000000000Metadata-Version: 1.0 Name: django-genshi Version: 1.1.3 Summary: Django integration for Genshi Home-page: https://launchpad.net/django-genshi Author: John Millikin Author-email: jmillikin@gmail.com License: GPL Download-URL: http://pypi.python.org/pypi/django-genshi/1.1.3 Description: :Author: John Millikin :Copyright: This document has been placed in the public domain. Overview ======== ``django-genshi`` is a small wrapper library around Genshi that provides an API similar to ``django.template``. Included are imitations of ``Context`` and ``RequestContext``. There is also an implemention of the Django template loader system adapted for Genshi, and a selection of shortcut functions. Usage ===== See the `Django` [#]_ and `Genshi` [#]_ documentation for detailed usage notes. The API of ``django-genshi`` is intended to mirror that of Django, while writing or manipulating the templates will require knowledge of Genshi. Genshi cannot use Django's default template loaders -- to work around this, the ``app_directories``, ``eggs``, and ``filesystem`` loaders have been modified and included in the ``django_genshi.loaders`` package. To avoid conflicts with Django's template system, place such loaders in the ``GENSHI_TEMPLATE_LOADERS`` setting. Example:: >>> from django_genshi import render_to_response >>> response = render_to_response ('template_name.xml', {"name": "world"}) >>> print response.content

Hello world!

.. [#] http://docs.djangoproject.com/en/dev/ref/templates/api/ .. [#] http://genshi.edgewall.org/wiki/Documentation Output Type Autodetection ========================= Because Genshi is based on abstract markup streams, it is possible for a template to be rendered to multiple output representations (such as HTML or XHTML). The decision of which to render is usually based on the HTTP ``Accept`` header. The ``shortcuts.render_to_response_autodetect`` function implements a reasonable algorithm for autodetecting output formats, and serves as an example for writing custom encoders in general. Filters ======= Arbitrary Genshi filter functions may be registered, using the ``GENSHI_TEMPLATE_FILTERS`` setting. They will be applied to generated template streams by the shortcut functions prior to rendering the streams. Example filters are included in the ``django_genshi.filters`` module. Keywords: django,genshi Platform: Platform Independent Classifier: Development Status :: 4 - Beta Classifier: Framework :: Django Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: GNU General Public License (GPL) Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content Classifier: Topic :: Software Development :: Libraries :: Python Modules Classifier: Topic :: Text Processing :: Markup :: HTML Classifier: Topic :: Text Processing :: Markup :: XML django-genshi-1.1.3/README.txt000066400000000000000000000040251126576345200157430ustar00rootroot00000000000000:Author: John Millikin :Copyright: This document has been placed in the public domain. Overview ======== ``django-genshi`` is a small wrapper library around Genshi that provides an API similar to ``django.template``. Included are imitations of ``Context`` and ``RequestContext``. There is also an implemention of the Django template loader system adapted for Genshi, and a selection of shortcut functions. Usage ===== See the `Django` [#]_ and `Genshi` [#]_ documentation for detailed usage notes. The API of ``django-genshi`` is intended to mirror that of Django, while writing or manipulating the templates will require knowledge of Genshi. Genshi cannot use Django's default template loaders -- to work around this, the ``app_directories``, ``eggs``, and ``filesystem`` loaders have been modified and included in the ``django_genshi.loaders`` package. To avoid conflicts with Django's template system, place such loaders in the ``GENSHI_TEMPLATE_LOADERS`` setting. Example:: >>> from django_genshi import render_to_response >>> response = render_to_response ('template_name.xml', {"name": "world"}) >>> print response.content

Hello world!

.. [#] http://docs.djangoproject.com/en/dev/ref/templates/api/ .. [#] http://genshi.edgewall.org/wiki/Documentation Output Type Autodetection ========================= Because Genshi is based on abstract markup streams, it is possible for a template to be rendered to multiple output representations (such as HTML or XHTML). The decision of which to render is usually based on the HTTP ``Accept`` header. The ``shortcuts.render_to_response_autodetect`` function implements a reasonable algorithm for autodetecting output formats, and serves as an example for writing custom encoders in general. Filters ======= Arbitrary Genshi filter functions may be registered, using the ``GENSHI_TEMPLATE_FILTERS`` setting. They will be applied to generated template streams by the shortcut functions prior to rendering the streams. Example filters are included in the ``django_genshi.filters`` module. django-genshi-1.1.3/django_genshi.egg-info/000077500000000000000000000000001126576345200205355ustar00rootroot00000000000000django-genshi-1.1.3/django_genshi.egg-info/PKG-INFO000066400000000000000000000064201126576345200216340ustar00rootroot00000000000000Metadata-Version: 1.0 Name: django-genshi Version: 1.1.3 Summary: Django integration for Genshi Home-page: https://launchpad.net/django-genshi Author: John Millikin Author-email: jmillikin@gmail.com License: GPL Download-URL: http://pypi.python.org/pypi/django-genshi/1.1.3 Description: :Author: John Millikin :Copyright: This document has been placed in the public domain. Overview ======== ``django-genshi`` is a small wrapper library around Genshi that provides an API similar to ``django.template``. Included are imitations of ``Context`` and ``RequestContext``. There is also an implemention of the Django template loader system adapted for Genshi, and a selection of shortcut functions. Usage ===== See the `Django` [#]_ and `Genshi` [#]_ documentation for detailed usage notes. The API of ``django-genshi`` is intended to mirror that of Django, while writing or manipulating the templates will require knowledge of Genshi. Genshi cannot use Django's default template loaders -- to work around this, the ``app_directories``, ``eggs``, and ``filesystem`` loaders have been modified and included in the ``django_genshi.loaders`` package. To avoid conflicts with Django's template system, place such loaders in the ``GENSHI_TEMPLATE_LOADERS`` setting. Example:: >>> from django_genshi import render_to_response >>> response = render_to_response ('template_name.xml', {"name": "world"}) >>> print response.content

Hello world!

.. [#] http://docs.djangoproject.com/en/dev/ref/templates/api/ .. [#] http://genshi.edgewall.org/wiki/Documentation Output Type Autodetection ========================= Because Genshi is based on abstract markup streams, it is possible for a template to be rendered to multiple output representations (such as HTML or XHTML). The decision of which to render is usually based on the HTTP ``Accept`` header. The ``shortcuts.render_to_response_autodetect`` function implements a reasonable algorithm for autodetecting output formats, and serves as an example for writing custom encoders in general. Filters ======= Arbitrary Genshi filter functions may be registered, using the ``GENSHI_TEMPLATE_FILTERS`` setting. They will be applied to generated template streams by the shortcut functions prior to rendering the streams. Example filters are included in the ``django_genshi.filters`` module. Keywords: django,genshi Platform: Platform Independent Classifier: Development Status :: 4 - Beta Classifier: Framework :: Django Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: GNU General Public License (GPL) Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content Classifier: Topic :: Software Development :: Libraries :: Python Modules Classifier: Topic :: Text Processing :: Markup :: HTML Classifier: Topic :: Text Processing :: Markup :: XML django-genshi-1.1.3/django_genshi.egg-info/SOURCES.txt000066400000000000000000000007551126576345200224300ustar00rootroot00000000000000README.txt setup.py django_genshi/__init__.py django_genshi/context.py django_genshi/filters.py django_genshi/loader.py django_genshi/shortcuts.py django_genshi/util.py django_genshi.egg-info/PKG-INFO django_genshi.egg-info/SOURCES.txt django_genshi.egg-info/dependency_links.txt django_genshi.egg-info/requires.txt django_genshi.egg-info/top_level.txt django_genshi/loaders/__init__.py django_genshi/loaders/app_directories.py django_genshi/loaders/eggs.py django_genshi/loaders/filesystem.pydjango-genshi-1.1.3/django_genshi.egg-info/dependency_links.txt000066400000000000000000000000011126576345200246030ustar00rootroot00000000000000 django-genshi-1.1.3/django_genshi.egg-info/requires.txt000066400000000000000000000000371126576345200231350ustar00rootroot00000000000000Django>=1.0_final Genshi>=0.5.1django-genshi-1.1.3/django_genshi.egg-info/top_level.txt000066400000000000000000000000161126576345200232640ustar00rootroot00000000000000django_genshi django-genshi-1.1.3/django_genshi/000077500000000000000000000000001126576345200170435ustar00rootroot00000000000000django-genshi-1.1.3/django_genshi/__init__.py000066400000000000000000000021001126576345200211450ustar00rootroot00000000000000# Copyright (C) 2008-2009 John Millikin # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . __author__ = "John Millikin " __copyright__ = "Copyright 2008-2009, John Millikin" __version__ = (1, 1, 3) __license__ = "GPL" from django_genshi.context import Context, RequestContext from django_genshi.loader import get_template, select_template, TemplateNotFound from django_genshi.shortcuts import (render_to_stream, render_to_response, render_to_response_autodetect) django-genshi-1.1.3/django_genshi/context.py000066400000000000000000000027521126576345200211070ustar00rootroot00000000000000# Copyright (C) 2008-2009 John Millikin # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . from itertools import chain from django.conf import settings import genshi.template from django_genshi.util import load_module_attr, memoize __all__ = ['Context', 'RequestContext'] @memoize ({}, 0) def get_standard_processors (): return map (load_module_attr, settings.TEMPLATE_CONTEXT_PROCESSORS) class Context (genshi.template.Context): """Wrapper class so instances of ``genshi.template.Context`` can be constructed using the same style as ``django.template.Context``. """ def __init__ (self, dict_ = None): if dict_ is None: dict_ = {} super (Context, self).__init__ (**dict_) class RequestContext (Context): def __init__(self, request, dict_ = None, processors = ()): super (RequestContext, self).__init__ (dict_) for processor in chain (get_standard_processors (), processors): self.update (processor (request)) django-genshi-1.1.3/django_genshi/filters.py000066400000000000000000000037271126576345200210760ustar00rootroot00000000000000# Copyright (C) 2008-2009 John Millikin # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . """Useful template stream processing filters.""" import re from genshi.core import START, START_NS, TEXT, END, END_NS IGNORED_ELEMENTS = ('pre', 'textarea') COLLAPSE_REGEX = re.compile (r'[ \t\n\r\f\v]+') def collapse (text): """Collapse long runs of whitespace to a single space. If the whitespace contains a newline, it is collapsed to a single newline. >>> collapse (' ') ' ' >>> collapse (' \\n\\n ') '\\n' >>> collapse ('test test') 'test test' >>> collapse ('test \\n test') 'test test' """ if text.isspace (): if "\n" in text: return "\n" return " " ret_type = type (text) return ret_type (COLLAPSE_REGEX.sub (" ", text)) def strip_whitespace (stream): """Strip all unneeded whitespace from the stream.""" state_stack = [] for kind, data, pos in stream: if kind == START: element, _ = data if element.localname in IGNORED_ELEMENTS: state_stack.append (False) else: state_stack.append (True) yield kind, data, pos elif kind == START_NS: state_stack.append (True) yield kind, data, pos elif kind in (END, END_NS): state_stack.pop () yield kind, data, pos elif kind == TEXT: if state_stack[-1]: yield kind, collapse (data), pos else: yield kind, data, pos else: yield kind, data, pos if __name__ == '__main__': import doctest doctest.testmod () django-genshi-1.1.3/django_genshi/loader.py000066400000000000000000000046331126576345200206710ustar00rootroot00000000000000# Copyright (C) 2008-2009 John Millikin # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging from django.conf import settings from genshi.template.loader import TemplateLoader, TemplateNotFound from django_genshi.util import memoize, load_module_attr __all__ = ['get_template', 'select_template', 'TemplateNotFound'] log = logging.getLogger (__name__) def _genshi_template_loadfunc (template_name, load_funcs): for loader_name, loader in load_funcs: try: info = loader (template_name) except StandardError: log.error ("Error calling template loader %r", loader_name, exc_info = 1) continue if info is not None: return info raise TemplateNotFound (template_name, []) def _get_load_func (path): func = load_module_attr (path) if func.is_usable: return func log.warning ("Your GENSHI_TEMPLATE_LOADERS setting includes %r," " but your Python installation doesn't support" " that type of template loading. Consider" " removing that line from" " GENSHI_TEMPLATE_LOADERS.", path) @memoize ({}, 0) def _get_loader (): loader_paths = getattr (settings, 'GENSHI_TEMPLATE_LOADERS', ()) loaders = ((path, _get_load_func (path)) for path in loader_paths) load_funcs = tuple ((p, l) for p, l in loaders if l) def genshi_loader_wrapper (name): return _genshi_template_loadfunc (name, load_funcs) return TemplateLoader ( [genshi_loader_wrapper], variable_lookup = 'strict', auto_reload = True, ) def get_template (template_name): loader = _get_loader () return loader.load (template_name, relative_to = '/') def select_template (template_name_list): loader = _get_loader () for name in template_name_list: try: return loader.load (name, relative_to = '/') except TemplateNotFound: pass raise TemplateNotFound (', '.join (template_name_list), []) django-genshi-1.1.3/django_genshi/loaders/000077500000000000000000000000001126576345200204745ustar00rootroot00000000000000django-genshi-1.1.3/django_genshi/loaders/__init__.py000066400000000000000000000000001126576345200225730ustar00rootroot00000000000000django-genshi-1.1.3/django_genshi/loaders/app_directories.py000066400000000000000000000030401126576345200242170ustar00rootroot00000000000000# Copyright (C) 2008-2009 John Millikin # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . from os.path import dirname, join from django.conf import settings from django.core.exceptions import ImproperlyConfigured from django_genshi.loaders.filesystem import load_template as filesystem_loader from django_genshi.util import memoize __all__ = ['load_template'] @memoize ({}, 0) def get_template_dirs (): template_dirs = [] for app in settings.INSTALLED_APPS: i = app.rfind ('.') if i == -1: m, a = app, None else: m, a = app[:i], app[i+1:] try: if a is None: mod = __import__ (m, {}, {}, []) else: mod = getattr (__import__ (m, {}, {}, [a]), a) except ImportError, e: raise ImproperlyConfigured ("ImportError %s: %s" % (app, e.args[0])) template_dirs.append (join (dirname (mod.__file__), 'templates')) return template_dirs def load_template (template_name): return filesystem_loader (template_name, get_template_dirs ()) load_template.is_usable = True django-genshi-1.1.3/django_genshi/loaders/eggs.py000066400000000000000000000021661126576345200220000ustar00rootroot00000000000000# Copyright (C) 2008-2009 John Millikin # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . from django.conf import settings try: from pkg_resources import resource_stream except ImportError: resource_stream = None __all__ = ['load_template'] def load_template (template_name): assert resource_stream tmpl_path = 'templates/' + template_name for app in settings.INSTALLED_APPS: try: fileobj = resource_stream (app, tmpl_path) except IOError: continue return tmpl_path, template_name, fileobj, None load_template.is_usable = (resource_stream is not None) django-genshi-1.1.3/django_genshi/loaders/filesystem.py000066400000000000000000000027041126576345200232350ustar00rootroot00000000000000# Copyright (C) 2008-2009 John Millikin # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . from os.path import getmtime from django.conf import settings from django.utils._os import safe_join __all__ = ['load_template'] def get_template_sources (template_name, template_dirs): for template_dir in template_dirs: try: yield safe_join (template_dir, template_name) except ValueError: # The joined path was located outside of template_dir. pass def load_template (template_name, template_dirs = None): if template_dirs is None: template_dirs = settings.TEMPLATE_DIRS for filepath in get_template_sources (template_name, template_dirs): try: fileobj = open (filepath, 'rb') mtime = getmtime (filepath) except IOError: continue def _uptodate (): return mtime == getmtime (filepath) return filepath, template_name, fileobj, _uptodate load_template.is_usable = True django-genshi-1.1.3/django_genshi/shortcuts.py000066400000000000000000000066761126576345200214720ustar00rootroot00000000000000# Copyright (C) 2008-2009 John Millikin # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . from django.conf import settings from django.http import HttpResponse from django_genshi.context import Context from django_genshi.loader import get_template, select_template from django_genshi.util import memoize, load_module_attr __all__ = ['render_to_stream', 'render_to_response', 'render_to_response_autodetect'] XHTML_CONTENT_TYPE = 'application/xhtml+xml' def _stream_to_response (stream, charset, output_type, content_type): filtered = stream.filter (*_get_filters ()) text = filtered.render (output_type, encoding = charset, strip_whitespace = False) full_content_type = '%s; charset=%s' % (content_type, charset) return HttpResponse (text, content_type = full_content_type) @memoize ({}, 0) def _get_filters (): names = getattr (settings, 'GENSHI_TEMPLATE_FILTERS', ()) return tuple (map (load_module_attr, names)) def render_to_stream (template_name, dictionary = None, context_instance = None): """Render a template and data into a Genshi markup stream.""" if dictionary is None: dictionary = {} if isinstance (template_name, (list, tuple)): template = select_template (template_name) else: template = get_template (template_name) if context_instance: context_instance.update (dictionary) else: context_instance = Context (dictionary) return template.generate (context_instance) def render_to_response (*args, **kwargs): """Render a template and data into an ``HttpResponse``.""" charset = settings.DEFAULT_CHARSET content_type = settings.DEFAULT_CONTENT_TYPE stream = render_to_stream (*args, **kwargs) return _stream_to_response (stream, charset, 'html', content_type) def render_to_response_autodetect (request, template_name, dictionary = None, context_instance = None): """Render a template and context into an ``HttpResponse``, with output autodetection. The main purpose of this function is to let templates that a valid both as HTML and XHTML be rendered in the correct format, based on the HTTP ``Accept`` header. """ from genshi.core import DOCTYPE from genshi.output import DocType def _get_content_type (): if request is not None: if XHTML_CONTENT_TYPE in request.META.get ('HTTP_ACCEPT', ''): return 'xml', 'xhtml11', XHTML_CONTENT_TYPE return 'html', 'html', 'text/html' def replace_doctype (stream): for kind, data, pos in stream: if kind == DOCTYPE: yield kind, DocType.get (doctype), pos else: yield kind, data, pos charset = settings.DEFAULT_CHARSET output_type, doctype, content_type = _get_content_type () stream = render_to_stream (template_name, dictionary, context_instance) stream = stream.filter (replace_doctype) return _stream_to_response (stream, charset, output_type, content_type) django-genshi-1.1.3/django_genshi/util.py000066400000000000000000000023551126576345200203770ustar00rootroot00000000000000# Copyright (C) 2008-2009 John Millikin # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . from django.core.exceptions import ImproperlyConfigured from django.utils import functional def memoize (cache, num_args): def decorator (func): return functional.memoize (func, cache, num_args) return decorator def load_module_attr (path): module, attr = path.rsplit ('.', 1) try: mod = __import__ (module, {}, {}, [attr]) except ImportError, error: raise ImproperlyConfigured ("Error importing module %r: \"%s\"" % (module, error)) try: return getattr (mod, attr) except AttributeError: raise ImproperlyConfigured ("Module %r does not define the %r attribute." % (module, attr)) django-genshi-1.1.3/setup.cfg000066400000000000000000000000731126576345200160650ustar00rootroot00000000000000[egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 django-genshi-1.1.3/setup.py000066400000000000000000000021751126576345200157630ustar00rootroot00000000000000from os.path import dirname, join from setuptools import setup, Extension version = '1.1.3' setup ( name = 'django-genshi', version = version, description = "Django integration for Genshi", long_description = open (join (dirname (__file__), 'README.txt')).read (), author = "John Millikin", author_email = "jmillikin@gmail.com", license = "GPL", url = "https://launchpad.net/django-genshi", download_url = "http://pypi.python.org/pypi/django-genshi/%s" % version, platforms = ["Platform Independent"], packages = ['django_genshi', 'django_genshi.loaders'], classifiers = [ "Development Status :: 4 - Beta", "Framework :: Django", "Intended Audience :: Developers", "License :: OSI Approved :: GNU General Public License (GPL)", "Operating System :: OS Independent", "Programming Language :: Python", "Topic :: Internet :: WWW/HTTP :: Dynamic Content", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Text Processing :: Markup :: HTML", "Topic :: Text Processing :: Markup :: XML", ], keywords = ["django", "genshi"], install_requires = [ "Django>=1.0_final", "Genshi>=0.5.1", ], )