Edgewall Software

Ticket #1513: TranslatedPages.py

File TranslatedPages.py, 4.4 KB (added by dstoecker, 17 months ago)

Translated pages macro as used on JOSM pages

Line 
1# -*- coding: utf8 -*-
2""" Macro to show the translated pages list. """
3
4__author__ = u'Dirk Stöcker'
5' based on a macro by Zhang Cong (ftofficer)'
6__version__ = '2.0'
7
8from trac.core import *
9from trac.wiki.macros import WikiMacroBase
10from StringIO import StringIO
11from trac.wiki.formatter import Formatter
12from trac.wiki.model import WikiPage
13from trac.wiki.api import WikiSystem
14import re
15
16class TranslatedPagesMacro(WikiMacroBase):
17    """
18    Macro to show the translated pages list.
19    """
20
21    TRAC_LANGUAGES_PAGE = u'TracLanguages'
22    BASE_LANG = u'En'
23
24    def __init__(self):
25        self.languages_page_version = 0
26        self._update_languages()
27
28    def _parse_languages_list(self, text):
29        """
30        Parses the list of languages in form
31         * <language code> <language name> x <description>
32         * <language code> <language name> x <description>
33        ...
34       
35        The x is used to allow better display of page for languages written right to left
36        The description contains the "Other languages" text in that language
37        """
38        langs = {}
39        reg = re.compile(u"^ \* ([A-Z][a-z](?:_[A-Z]{2})?) +(.+?) +x +(.+)$")
40        for line in text.split(u'\r\n'):
41            regres = reg.search(line)
42            if regres == None:
43                self.env.log.warn(
44                    u"Wrong line syntax while parsing languages list: %s" % line)
45            else:
46                code = regres.group(1)
47                name = regres.group(2)
48                desc = regres.group(3)
49                self.env.log.debug("Adding language %s -> %s (%s)" % (code, name, desc))
50                langs[code] = name
51                langs["_"+code] = desc
52        return langs
53
54    def _update_languages(self):
55        languages_page = WikiPage(self.env, self.TRAC_LANGUAGES_PAGE)
56        if not languages_page.exists:
57            self.env.log.warn(u"Can't find page %s" % self.TRAC_LANGUAGES_PAGE)
58            self.languages = {}
59            self.languages_page_version = 0
60        else:
61            if languages_page.version > self.languages_page_version:
62                self.languages = self._parse_languages_list(languages_page.text)
63                self.languages_page_version = languages_page.version
64
65    def _get_language_name(self, lang_code):
66        self._update_languages()
67        return self.languages.get(lang_code, lang_code)
68
69    def _get_translated_page(self, name, lang_code):
70        if lang_code == self.BASE_LANG:
71            return name
72        else:
73            return lang_code + u':' + name
74
75    def _get_page_info(self, page_name):
76        regres = re.compile("^([A-Z][a-z](_[A-Z][A-Z])?):(.+)$").search(page_name)
77        if regres == None:
78            return (page_name, self.BASE_LANG)
79        return (regres.group(3), regres.group(1))
80
81    def _get_translations(self, base_page_name):
82        for l in sorted(self.languages.keys()):
83            tr = self._get_translated_page(base_page_name, l);
84            for subpage in sorted(WikiSystem(self.env).get_pages(tr)):
85                if(subpage == tr):
86                    yield l
87
88    def _get_lang_link(self, base_name, lang_code):
89        page_name = self._get_translated_page(base_name, lang_code)
90        return u"  * [wiki:%s %s]" % (page_name, self._get_language_name(lang_code))
91
92    def _get_current_lang_link(self, lang_code):
93        return u"  * '''%s'''" % self._get_language_name(lang_code)
94
95    def expand_macro(self, formatter, name, args):
96        """
97        Return a list of translated pages with the native language names.
98        The list of languages supported can be configured by adding new
99        entries to TracLanguages page. Refer to ISO 639-1 for more information.
100        """
101
102        page_name = formatter.context.resource.id
103        (base_page_name, lang_code) = self._get_page_info(page_name)
104
105        lang_link_list = []
106        for translation in self._get_translations(base_page_name):
107            if translation != lang_code:
108                lang_link_list.append(self._get_lang_link(base_page_name, translation))
109            else:
110                lang_link_list.append(self._get_current_lang_link(lang_code))
111
112        out = StringIO()
113        Formatter(self.env, formatter.context).format(u'\n'.join(lang_link_list), out)
114
115        desc = "Languages"
116        if self.languages.has_key("_"+lang_code):
117            desc = self.languages["_"+lang_code]
118        return u"""
119<div class="wiki-toc trac-nav" style="clear:both">
120<h4>%s:</h4>
121%s
122</div>""" % (desc, out.getvalue())
123