root/trunk/pylucid_project/PyLucid/middlewares/headline_anchor.py

Revision 1634, 2.7 KB (checked in by JensDiemer, 22 months ago)

Update Meta Informations:

  • file encoding
  • shebang
  • copyleft and license line
  • svn:keywords
  • Property svn:eol-style set to LF
  • Property svn:keywords set to Author Rev LastChangedDate
Line 
1# -*- coding: utf-8 -*-
2
3"""
4    PyLucid headline anchor
5    ~~~~~~~~~~~~~~~~~~~~~~~
6
7    A middleware to add a human readable, url safe anchor to all html headlines.
8    Every anchor is a permalink to the page. So you can easy copy&paste the
9    links for several use.
10   
11    more info: http://pylucid.org/_goto/147/Headline-anchor/   
12
13    Last commit info:
14    ~~~~~~~~~~~~~~~~~
15    $LastChangedDate: $
16    $Rev: $
17    $Author: $
18
19    :copyleft: 2008 by the PyLucid team, see AUTHORS for more details.
20    :license: GNU GPL v3 or above, see LICENSE for more details.
21"""
22
23import string, re
24
25from PyLucid.tools.shortcuts import makeUnique
26
27HEADLINE_RE = re.compile(r"<h(\d)>(.+?)</h(\d)>(?iusm)")
28
29HEADLINE = (
30    u'<h%(no)s id="%(anchor)s">'
31    '<a title="Link to this section" href="%(link)s#%(anchor)s" class="anchor">'
32    '%(txt)s</a>'
33    '</h%(no)s>\n'
34)
35
36
37class HeadlineAnchor(object):
38    def process_response(self, request, response):
39        """
40        Add anchors to every html headlines.
41        """
42        # Put only the statistic into HTML pages
43        if not "html" in response._headers["content-type"][1]:
44            # No HTML Page
45            return response
46
47        try:
48            context = request.CONTEXT
49        except AttributeError:
50            # No cms page request (e.g. the _install section) -> do nothing
51            return response
52
53        # Get the permalink to the current page
54        current_page = context["PAGE"]
55        self.permalink = current_page.get_permalink()
56
57        # A list of all existing anchors, used in self.add_anchor()
58        self.anchor_list = []
59
60        content = response.content
61        if not isinstance(content, unicode):
62            # FIXME: In my shared webhosting environment is response.content a
63            # string and not unicode. Why?
64            from django.utils.encoding import force_unicode
65            try:
66                content = force_unicode(content)
67            except:
68                return response
69
70        # add the anchor with re.sub
71        new_content = HEADLINE_RE.sub(self.add_anchor, content)
72        response.content = new_content
73
74        return response
75
76    def add_anchor(self, matchobj):
77        """
78        add a unique anchor to a html headline.
79        """
80        txt = matchobj.group(2)
81
82        # Strip all non-ASCII and make the anchor unique
83        anchor = makeUnique(txt, self.anchor_list)
84
85        # Remember the current anchor. So makeUnique can add a number on double
86        # anchors.
87        self.anchor_list.append(anchor)
88
89        result = HEADLINE % {
90            "no": matchobj.group(1),
91            "txt": txt,
92            "link": self.permalink,
93            "anchor": anchor,
94        }
95        return result
Note: See TracBrowser for help on using the browser.