~m4v/+junk/Factos

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# -*- Encoding: UTF-8 -*-
###
# Copyright (c) 2010, Elián Hanisch
#
# 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
# (at your option) 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 <http://www.gnu.org/licenses/>.
###

import re
#import supybot.log as log

def stringSub(s, vars):
    for k, v in vars.iteritems():
        if k in s:
            s = s.replace(k, v)
    return s

class SortedDict(dict):
    """Dict class where keys can be sorted."""
    def __init__(self, *args):
        dict.__init__(self, *args)
        self._sorting = []

    def __setitem__(self, k, v):
        dict.__setitem__(self, k, v)
        self._sorting.append(k)

    def __iter__(self):
        def generator():
            for k in self._sorting:
                yield k
            raise StopIteration
        return generator()

    def iteritems(self):
        def generator():
            for k in self._sorting:
                yield k, self[k]
            raise StopIteration
        return generator()

class LocalizedRegexp(object):
    """
    This class will store and keep track of the regular expresions used for plugin commands.
    When is initialized will fetch all the docstrings in the Factos <instance> and compile them,
    then it will compile the regular expressions in the languages dict."""
    flags = (re.IGNORECASE | re.VERBOSE | re.UNICODE)

    def __init__(self, instance, replaces={}):
        """Compile all the needed regular expresions."""
        # compile regexp defined in methods' docstrings, these will be the default
        defaultCompiledRe = SortedDict()
        for name in instance.commandRegexp:
            method = getattr(instance, name)
            regexp = method.__doc__
            regexp = stringSub(regexp, replaces)
            r = re.compile(regexp, self.flags)
            defaultCompiledRe[name] = r
        self.defaultCompiledRe = defaultCompiledRe

        enabledLanguages = instance.registryValue('l10n.enabledLanguages')
        localizedCompiledRe = { 'es': defaultCompiledRe }
        for lang in enabledLanguages:
            if lang in localizedCompiledRe: continue
            #log.debug('Compiling regular expressions for %s' %lang)
            localizedCompiledRe[lang] = SortedDict()
            for name in defaultCompiledRe:
                try:
                    regexp = languages[lang][name]
                    regexp = stringSub(regexp, replaces)
                    r = re.compile(regexp, self.flags)
                except KeyError:
                    r = defaultCompiledRe[name]
                localizedCompiledRe[lang][name] = r
        self.localizedCompiledRe = localizedCompiledRe

    def __call__(self, lang=None):
        """Return a regular expresion dict for a language if given."""
        if not lang or lang not in self.localizedCompiledRe:
            return self.defaultCompiledRe
        else:
            return self.localizedCompiledRe[lang]

# NOTE:
# Add comments in all regular expresion!
# the string ':fact:' is replaced by a valid factname regexp, usually "[\w\-\.\#]+"
# the string searched by these regexps is space normalized, no need of using matches like \s+ or \s*

regexp_english  = {
        'addFact':
        ur"""^
        (:fact:)            # fact name
        \s?(\sis\s|:)\s?    # separator : or ' is '
        (.+)                # fact's text
        $""",

        'editFact':
        ur"""^
        no[\s,]\s?                      # must start with 'no,' or 'no '
        (.+(?::|\sis\s|\salias\s).+)    # anything that looks like addFact or addAlias regexps
        $""",

        'tellFact':
        ur"""^
        tell\s      # tell <nick> about <fact>
        ([^\s]+)    # nick
        \sabout\s
        (:fact:)    # fact name
        $""",

        'appendFact':
        ur"""^append\sto\s    # append to <fact> <text>
        (:fact:)              # fact name
        \s(.+)                # text to append
        $""",
        }

languages = {
        'en': regexp_english
        }

# vim:set shiftwidth=4 softtabstop=4 tabstop=4 expandtab textwidth=100: