Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

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

from django.utils.encoding import force_unicode 

 

from markupmirror.exceptions import * 

 

 

class BaseMarkup(object): 

    """Basic interface for markup converter classes. 

 

    An example converter could look like this:: 

 

        class ExampleMarkup(BaseMarkup): 

 

            def convert(self, markup): 

                return markup.replace("example", "markup") 

 

    """ 

    codemirror_mode = '' 

    title = "" 

 

    @classmethod 

    def get_name(cls): 

        """Returns lowercase markup name, without the "Markup" part. 

 

        Class naming convention is ``<Markup-Type>Markup``. 

        """ 

        return cls.__name__.replace("Markup", "", 1).lower() 

 

    def convert(self, markup): 

        """Main conversion method. Must be implemented in subclasses.""" 

        return markup 

 

    def before_convert(self, markup): 

        """Called before ``convert``. Can be used to separate the main 

        conversion through a third-party library (e.g. Markdown) from 

        additional logic. 

 

        """ 

        return markup 

 

    def after_convert(self, markup): 

        """Called after ``convert``. Similar to ``before_convert``.""" 

        return markup 

 

    def __call__(self, markup): 

        """Main entry point. Calls ``before_convert``, ``convert`` and 

        ``after_convert`` in that order. 

 

        """ 

        return force_unicode( 

            self.after_convert(self.convert(self.before_convert(markup)))) 

 

 

class MarkupPool(object): 

    """Pool for markup converters. 

 

    Each markup class, subclassing 

    ``markupmirror.markup.base.BaseMarkup``, must register to this 

    pool using ``register_markup`` defined below. 

 

    """ 

    def __init__(self): 

        self.markups = {} 

 

    def register_markup(self, markup): 

        """Registers a markup converter class. 

 

        ``markup`` must be a subclass of ``BaseMarkup`` and may not be 

        registered already. 

 

        """ 

        # check for correct subclassing 

        if not issubclass(markup, BaseMarkup): 

            raise InvalidMarkup( 

                "Markups must be subclasses of " 

                "markupmirror.markup.base.BaseMarkup. %r is not." 

                % markup) 

 

        markup_name = markup.get_name() 

        self.markups[markup_name] = markup() 

 

    def unregister_markup(self, markup_name): 

        """Unregisters a markup converter with the name ``markup_name``. 

        Fails silently if no converter was registered by that name. 

 

        Alternatively you can also use the ``del`` operator:: 

 

           del markup_pool['restructuredtext'] 

 

        """ 

        if markup_name in self.markups: 

            del self.markups[markup_name] 

 

    def has_markup(self, markup_name): 

        """Tests if a markup converter with the name ``markup_name`` is already 

        registered with the markup pool. 

 

        Alternatively you can also use the ``in`` operator, like with a 

        dictionary:: 

 

            if 'restructuredtext' in markup_pool: 

                pass 

 

        """ 

        return markup_name in self.markups 

 

    def get_markup(self, markup_name): 

        """Returns one markup converter by name. 

        Raises ``KeyError`` if no converter was registered by ``markup_name``. 

 

        Alternatively you can also use the ``[]`` accessor, like with a 

        dictionary:: 

 

            markup = markup_pool['restructuredtext'] 

 

        """ 

        return self.markups[markup_name] 

 

    def __contains__(self, key): 

        return self.has_markup(key) 

 

    def __getitem__(self, key): 

        return self.get_markup(key) 

 

    def __delitem__(self, key): 

        self.unregister_markup(key) 

 

 

markup_pool = MarkupPool()  # Instance of ``MarkupPool`` for public use. 

register_markup = markup_pool.register_markup 

 

 

__all__ = ('markup_pool', 'register_markup', 'BaseMarkup')