| 1 | # LinkExchange - Universal link exchange service client |
|---|
| 2 | # Copyright (C) 2009 Konstantin Korikov |
|---|
| 3 | # |
|---|
| 4 | # This library is free software; you can redistribute it and/or |
|---|
| 5 | # modify it under the terms of the GNU Lesser General Public |
|---|
| 6 | # License as published by the Free Software Foundation; either |
|---|
| 7 | # version 2.1 of the License, or (at your option) any later version. |
|---|
| 8 | # |
|---|
| 9 | # This library is distributed in the hope that it will be useful, |
|---|
| 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|---|
| 12 | # Lesser General Public License for more details. |
|---|
| 13 | # |
|---|
| 14 | # You should have received a copy of the GNU Lesser General Public |
|---|
| 15 | # License along with this library; if not, write to the Free Software |
|---|
| 16 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|---|
| 17 | # |
|---|
| 18 | # NOTE: In the context of the Python environment, I interpret "dynamic |
|---|
| 19 | # linking" as importing -- thus the LGPL applies to the contents of |
|---|
| 20 | # the modules, but make no requirements on code importing these |
|---|
| 21 | # modules. |
|---|
| 22 | |
|---|
| 23 | from xml.sax import saxutils |
|---|
| 24 | |
|---|
| 25 | class BaseFormatter(object): |
|---|
| 26 | def __init__(self, count): |
|---|
| 27 | """ |
|---|
| 28 | @param count: links count in the block (0 or None - catch all) |
|---|
| 29 | """ |
|---|
| 30 | self.count = count |
|---|
| 31 | |
|---|
| 32 | def format(self, tags, links): |
|---|
| 33 | """ |
|---|
| 34 | Perform links formatting. tags is a list of unicode strings that don't |
|---|
| 35 | contains '<a '. links is a list of unicode strings that contains links |
|---|
| 36 | HTML code. |
|---|
| 37 | |
|---|
| 38 | @param tags: list of special tags |
|---|
| 39 | @param links: list of links |
|---|
| 40 | @return: HTML code |
|---|
| 41 | """ |
|---|
| 42 | pass |
|---|
| 43 | |
|---|
| 44 | def _add_prefix(self, link, prefix): |
|---|
| 45 | i = 0 |
|---|
| 46 | while not (prefix[:i] + link).startswith(prefix): |
|---|
| 47 | i += 1 |
|---|
| 48 | link = prefix[:i] + link |
|---|
| 49 | return link |
|---|
| 50 | |
|---|
| 51 | def _add_suffix(self, link, suffix): |
|---|
| 52 | i = len(suffix) |
|---|
| 53 | while not (link + suffix[i:]).endswith(suffix): |
|---|
| 54 | i -= 1 |
|---|
| 55 | link += suffix[i:] |
|---|
| 56 | return link |
|---|
| 57 | |
|---|
| 58 | def _format_container(self, tag, id, class_, content): |
|---|
| 59 | html = u'<' + tag |
|---|
| 60 | if id: |
|---|
| 61 | html += u' id="%s"' % saxutils.escape(id) |
|---|
| 62 | if class_: |
|---|
| 63 | html += u' class="%s"' % saxutils.escape(class_) |
|---|
| 64 | html += u'>' |
|---|
| 65 | html += content |
|---|
| 66 | html += u'</%s>' % tag |
|---|
| 67 | return html |
|---|
| 68 | |
|---|
| 69 | class InlineFormatter(BaseFormatter): |
|---|
| 70 | def __init__(self, count, |
|---|
| 71 | delimiter='', |
|---|
| 72 | prefix='', |
|---|
| 73 | suffix='', |
|---|
| 74 | prolog='', |
|---|
| 75 | epilog='', |
|---|
| 76 | id=None, |
|---|
| 77 | class_=None, |
|---|
| 78 | class_for_empty=None, |
|---|
| 79 | strip=False): |
|---|
| 80 | """ |
|---|
| 81 | @param count: links count in the block (None - catch all) |
|---|
| 82 | @keyword delimiter: links delimiter |
|---|
| 83 | @keyword prefix: links prefix |
|---|
| 84 | @keyword suffix: links suffix |
|---|
| 85 | @keyword prolog: text before links |
|---|
| 86 | @keyword epilog: text after links |
|---|
| 87 | @keyword id: value for id attribute |
|---|
| 88 | @keyword class_: CSS class for nonempty block |
|---|
| 89 | @keyword class_for_empty: CSS class for empty block |
|---|
| 90 | @keyword strip: skip DIV tag |
|---|
| 91 | """ |
|---|
| 92 | super(InlineFormatter, self).__init__(count) |
|---|
| 93 | self.delimiter = delimiter |
|---|
| 94 | self.prefix = prefix |
|---|
| 95 | self.suffix = suffix |
|---|
| 96 | self.prolog = prolog |
|---|
| 97 | self.epilog = epilog |
|---|
| 98 | self.id = id |
|---|
| 99 | self.class_ = class_ |
|---|
| 100 | self.class_for_empty = class_for_empty |
|---|
| 101 | self.strip = strip |
|---|
| 102 | |
|---|
| 103 | def format(self, tags, links): |
|---|
| 104 | def format_link(link): |
|---|
| 105 | if self.prefix: |
|---|
| 106 | link = self._add_prefix(link, self.prefix) |
|---|
| 107 | if self.suffix: |
|---|
| 108 | link = self._add_suffix(link, self.suffix) |
|---|
| 109 | return link |
|---|
| 110 | if links: |
|---|
| 111 | css_class = self.class_ |
|---|
| 112 | content = self.prolog + self.delimiter.join( |
|---|
| 113 | map(format_link, links)) + self.epilog |
|---|
| 114 | else: |
|---|
| 115 | css_class = self.class_for_empty |
|---|
| 116 | content = u'' |
|---|
| 117 | if self.strip: |
|---|
| 118 | html = content |
|---|
| 119 | else: |
|---|
| 120 | html = self._format_container('div', self.id, css_class, content) |
|---|
| 121 | html += u''.join(tags) |
|---|
| 122 | return html |
|---|
| 123 | |
|---|
| 124 | class ListFormatter(BaseFormatter): |
|---|
| 125 | def __init__(self, count, |
|---|
| 126 | prefix='', |
|---|
| 127 | suffix='', |
|---|
| 128 | id=None, |
|---|
| 129 | class_=None, |
|---|
| 130 | class_for_empty=None, |
|---|
| 131 | li_class=None, |
|---|
| 132 | tag_for_empty='span', |
|---|
| 133 | strip=False): |
|---|
| 134 | """ |
|---|
| 135 | @param count: links count in the block (None - catch all) |
|---|
| 136 | @keyword prefix: links prefix |
|---|
| 137 | @keyword suffix: links suffix |
|---|
| 138 | @keyword id: value for id attribute |
|---|
| 139 | @keyword class_: CSS class for nonempty block |
|---|
| 140 | @keyword class_for_empty: CSS class for empty block |
|---|
| 141 | @keyword li_class: CSS class for LI elements |
|---|
| 142 | @keyword tag_for_empty: HTML tag for empty block |
|---|
| 143 | @keyword strip: skip UL tag or empty tag |
|---|
| 144 | """ |
|---|
| 145 | super(ListFormatter, self).__init__(count) |
|---|
| 146 | self.prefix = prefix |
|---|
| 147 | self.suffix = suffix |
|---|
| 148 | self.id = id |
|---|
| 149 | self.class_ = class_ |
|---|
| 150 | self.class_for_empty = class_for_empty |
|---|
| 151 | self.li_class = li_class |
|---|
| 152 | self.tag_for_empty = tag_for_empty |
|---|
| 153 | self.strip = strip |
|---|
| 154 | |
|---|
| 155 | def format(self, tags, links): |
|---|
| 156 | def format_link(link): |
|---|
| 157 | if self.prefix: |
|---|
| 158 | link = self._add_prefix(link, self.prefix) |
|---|
| 159 | if self.suffix: |
|---|
| 160 | link = self._add_suffix(link, self.suffix) |
|---|
| 161 | if self.li_class: |
|---|
| 162 | attrs = u' class="%s"' % saxutils.escape(self.li_class) |
|---|
| 163 | else: |
|---|
| 164 | attrs = u'' |
|---|
| 165 | link = u'<li%s>%s</li>' % (attrs, link) |
|---|
| 166 | return link |
|---|
| 167 | content = u''.join(map(format_link, links)) |
|---|
| 168 | if self.strip: |
|---|
| 169 | html = content |
|---|
| 170 | else: |
|---|
| 171 | if links: |
|---|
| 172 | css_class = self.class_ |
|---|
| 173 | else: |
|---|
| 174 | css_class = self.class_for_empty |
|---|
| 175 | html_tag = links and u'ul' or self.tag_for_empty |
|---|
| 176 | html = self._format_container(html_tag, self.id, |
|---|
| 177 | css_class, content) |
|---|
| 178 | html += u''.join(tags) |
|---|
| 179 | return html |
|---|