| 1 |
import re |
|---|
| 2 |
from trac.core import * |
|---|
| 3 |
from trac.util import escape, Markup, sorted |
|---|
| 4 |
from trac.wiki.api import WikiSystem, IWikiSyntaxProvider, IWikiChangeListener |
|---|
| 5 |
from trac.config import * |
|---|
| 6 |
try: |
|---|
| 7 |
set = set |
|---|
| 8 |
except: |
|---|
| 9 |
from sets import Set as set |
|---|
| 10 |
|
|---|
| 11 |
|
|---|
| 12 |
class AutoWikify(Component): |
|---|
| 13 |
""" Automatically create links for all known Wiki pages, even those that |
|---|
| 14 |
are not in CamelCase. """ |
|---|
| 15 |
implements(IWikiSyntaxProvider, IWikiChangeListener) |
|---|
| 16 |
|
|---|
| 17 |
minimum_length = IntOption('autowikify', 'minimum_length', 3, |
|---|
| 18 |
"""Minimum page length to perform auto-wikification on.""") |
|---|
| 19 |
explicitly_wikify = ListOption('autowikify', 'explicitly_wikify', doc= |
|---|
| 20 |
"""List of Wiki pages to always Wikify, regardless of size.""") |
|---|
| 21 |
exclude = ListOption('autowikify', 'exclude', doc= |
|---|
| 22 |
"""List of Wiki pages to exclude from auto-wikification.""") |
|---|
| 23 |
|
|---|
| 24 |
pages = set() |
|---|
| 25 |
pages_re = None |
|---|
| 26 |
|
|---|
| 27 |
def __init__(self): |
|---|
| 28 |
self._all_pages() |
|---|
| 29 |
self._update() |
|---|
| 30 |
|
|---|
| 31 |
# IWikiChangeListener methods |
|---|
| 32 |
def wiki_page_added(self, page): |
|---|
| 33 |
self.pages.add(page.name) |
|---|
| 34 |
self._update() |
|---|
| 35 |
|
|---|
| 36 |
def wiki_page_changed(self, page, version, t, comment, author, ipnr): |
|---|
| 37 |
pass |
|---|
| 38 |
|
|---|
| 39 |
def wiki_page_deleted(self, page): |
|---|
| 40 |
if page.name in self.pages: |
|---|
| 41 |
self.pages.remove(page.name) |
|---|
| 42 |
else: |
|---|
| 43 |
self._all_pages() |
|---|
| 44 |
self._update() |
|---|
| 45 |
|
|---|
| 46 |
def wiki_page_version_deleted(self, page): |
|---|
| 47 |
pass |
|---|
| 48 |
|
|---|
| 49 |
# IWikiSyntaxProvider methods |
|---|
| 50 |
def get_wiki_syntax(self): |
|---|
| 51 |
yield (self.pages_re, self._page_formatter) |
|---|
| 52 |
|
|---|
| 53 |
def get_link_resolvers(self): |
|---|
| 54 |
return [] |
|---|
| 55 |
|
|---|
| 56 |
# Internal methods |
|---|
| 57 |
def _all_pages(self): |
|---|
| 58 |
self.pages = set(WikiSystem(self.env).get_pages()) |
|---|
| 59 |
|
|---|
| 60 |
def _update(self): |
|---|
| 61 |
explicitly_wikified = set([p.strip() for p in (self.env.config.get('autowikify', 'explicitly_wikify') or '').split(',') if p.strip()]) |
|---|
| 62 |
pages = set([p for p in self.pages if len(p) >= self.minimum_length]) |
|---|
| 63 |
pages.update(self.explicitly_wikify) |
|---|
| 64 |
pages.difference_update(self.exclude) |
|---|
| 65 |
pattern = r'\b(?P<autowiki>' + '|'.join([re.escape(page) for page in pages]) + r')\b' |
|---|
| 66 |
self.pages_re = pattern |
|---|
| 67 |
WikiSystem(self.env)._compiled_rules = None |
|---|
| 68 |
|
|---|
| 69 |
def _page_formatter(self, f, n, match): |
|---|
| 70 |
page = match.group('autowiki') |
|---|
| 71 |
return Markup('<a href="%s" class="wiki">%s</a>' |
|---|
| 72 |
% (self.env.href.wiki(page), |
|---|
| 73 |
escape(page))) |
|---|