Mercurial > libervia-backend
comparison src/plugins/plugin_misc_text_syntaxes.py @ 2324:fe922e6fabd4
plugin text syntaxes: various improvments:
- syntaxes and default_syntax are now class attribute instead of members of params_data
- removed local exception UnknownSyntax in favor of exceptions.NotFound
- syntaxes are now saved with a key which is name in lower case and stripped, unmodified name is put in syntax's data
- new getSyntax (syntaxGet in bridge) method to get syntax key and raise an error if not found. Can be used by frontends to check that a syntax is known.
author | Goffi <goffi@goffi.org> |
---|---|
date | Thu, 13 Jul 2017 20:53:51 +0200 |
parents | 33c8c4973743 |
children | 8b37a62336c3 |
comparison
equal
deleted
inserted
replaced
2323:2dae79990122 | 2324:fe922e6fabd4 |
---|---|
61 C.PI_MAIN: "TextSyntaxes", | 61 C.PI_MAIN: "TextSyntaxes", |
62 C.PI_HANDLER: "no", | 62 C.PI_HANDLER: "no", |
63 C.PI_DESCRIPTION: _("""Management of various text syntaxes (XHTML-IM, Markdown, etc)""") | 63 C.PI_DESCRIPTION: _("""Management of various text syntaxes (XHTML-IM, Markdown, etc)""") |
64 } | 64 } |
65 | 65 |
66 class UnknownSyntax(Exception): | |
67 pass | |
68 | 66 |
69 class TextSyntaxes(object): | 67 class TextSyntaxes(object): |
70 """ Text conversion class | 68 """ Text conversion class |
71 XHTML utf-8 is used as intermediate language for conversions | 69 XHTML utf-8 is used as intermediate language for conversions |
72 """ | 70 """ |
75 OPT_HIDDEN = "HIDDEN" | 73 OPT_HIDDEN = "HIDDEN" |
76 OPT_NO_THREAD = "NO_THREAD" | 74 OPT_NO_THREAD = "NO_THREAD" |
77 SYNTAX_XHTML = _SYNTAX_XHTML | 75 SYNTAX_XHTML = _SYNTAX_XHTML |
78 SYNTAX_MARKDOWN = "markdown" | 76 SYNTAX_MARKDOWN = "markdown" |
79 SYNTAX_TEXT = "text" | 77 SYNTAX_TEXT = "text" |
78 syntaxes = {} | |
79 default_syntax = SYNTAX_XHTML | |
80 | 80 |
81 params = """ | 81 params = """ |
82 <params> | 82 <params> |
83 <individual> | 83 <individual> |
84 <category name="%(category_name)s" label="%(category_label)s"> | 84 <category name="%(category_name)s" label="%(category_label)s"> |
93 params_data = { | 93 params_data = { |
94 'category_name': CATEGORY, | 94 'category_name': CATEGORY, |
95 'category_label': _(CATEGORY), | 95 'category_label': _(CATEGORY), |
96 'name': NAME, | 96 'name': NAME, |
97 'label': _(NAME), | 97 'label': _(NAME), |
98 'syntaxes': {}, | 98 'syntaxes': syntaxes, |
99 } | 99 } |
100 | 100 |
101 def __init__(self, host): | 101 def __init__(self, host): |
102 log.info(_("Text syntaxes plugin initialization")) | 102 log.info(_("Text syntaxes plugin initialization")) |
103 self.host = host | 103 self.host = host |
104 self.syntaxes = {} | |
105 self.addSyntax(self.SYNTAX_XHTML, lambda xhtml: defer.succeed(xhtml), lambda xhtml: defer.succeed(xhtml), | 104 self.addSyntax(self.SYNTAX_XHTML, lambda xhtml: defer.succeed(xhtml), lambda xhtml: defer.succeed(xhtml), |
106 TextSyntaxes.OPT_NO_THREAD) | 105 TextSyntaxes.OPT_NO_THREAD) |
107 # TODO: text => XHTML should add <a/> to url like in frontends | 106 # TODO: text => XHTML should add <a/> to url like in frontends |
108 # it's probably best to move sat_frontends.tools.strings to sat.tools.common or similar | 107 # it's probably best to move sat_frontends.tools.strings to sat.tools.common or similar |
109 self.addSyntax(self.SYNTAX_TEXT, lambda text: escape(text), lambda xhtml: self._removeMarkups(xhtml), [TextSyntaxes.OPT_HIDDEN]) | 108 self.addSyntax(self.SYNTAX_TEXT, lambda text: escape(text), lambda xhtml: self._removeMarkups(xhtml), [TextSyntaxes.OPT_HIDDEN]) |
118 except ImportError: | 117 except ImportError: |
119 log.warning(u"markdown or html2text not found, can't use Markdown syntax") | 118 log.warning(u"markdown or html2text not found, can't use Markdown syntax") |
120 log.info(u"You can download/install them from https://pythonhosted.org/Markdown/ and https://github.com/Alir3z4/html2text/") | 119 log.info(u"You can download/install them from https://pythonhosted.org/Markdown/ and https://github.com/Alir3z4/html2text/") |
121 host.bridge.addMethod("syntaxConvert", ".plugin", in_sign='sssbs', out_sign='s', | 120 host.bridge.addMethod("syntaxConvert", ".plugin", in_sign='sssbs', out_sign='s', |
122 async=True, method=self.convert) | 121 async=True, method=self.convert) |
122 host.bridge.addMethod("syntaxGet", ".plugin", in_sign='s', out_sign='s', | |
123 method=self.getSyntax) | |
123 | 124 |
124 def _updateParamOptions(self): | 125 def _updateParamOptions(self): |
125 data_synt = TextSyntaxes.params_data['syntaxes'] | 126 data_synt = TextSyntaxes.syntaxes |
126 default_synt = TextSyntaxes.params_data.get('default', _SYNTAX_XHTML) | 127 default_synt = TextSyntaxes.default_syntax |
127 syntaxes = [] | 128 syntaxes = [] |
128 | 129 |
129 for syntax in data_synt.keys(): | 130 for syntax in data_synt.keys(): |
130 flags = data_synt[syntax]["flags"] | 131 flags = data_synt[syntax]["flags"] |
131 if TextSyntaxes.OPT_HIDDEN not in flags: | 132 if TextSyntaxes.OPT_HIDDEN not in flags: |
214 # when dealing with XHTML | 215 # when dealing with XHTML |
215 # TODO: a way for parser to return parsing errors/warnings | 216 # TODO: a way for parser to return parsing errors/warnings |
216 | 217 |
217 if syntax_from == _SYNTAX_CURRENT: | 218 if syntax_from == _SYNTAX_CURRENT: |
218 syntax_from = self.getCurrentSyntax(profile) | 219 syntax_from = self.getCurrentSyntax(profile) |
220 else: | |
221 syntax_from = syntax_from.lower().strip() | |
219 if syntax_to == _SYNTAX_CURRENT: | 222 if syntax_to == _SYNTAX_CURRENT: |
220 syntax_to = self.getCurrentSyntax(profile) | 223 syntax_to = self.getCurrentSyntax(profile) |
221 syntaxes = TextSyntaxes.params_data['syntaxes'] | 224 else: |
225 syntax_to = syntax_to.lower().strip() | |
226 syntaxes = TextSyntaxes.syntaxes | |
222 if syntax_from not in syntaxes: | 227 if syntax_from not in syntaxes: |
223 raise UnknownSyntax(syntax_from) | 228 raise exceptions.NotFound(syntax_from) |
224 if syntax_to not in syntaxes: | 229 if syntax_to not in syntaxes: |
225 raise UnknownSyntax(syntax_to) | 230 raise exceptions.NotFound(syntax_to) |
226 d = None | 231 d = None |
227 | 232 |
228 if TextSyntaxes.OPT_NO_THREAD in syntaxes[syntax_from]["flags"]: | 233 if TextSyntaxes.OPT_NO_THREAD in syntaxes[syntax_from]["flags"]: |
229 d = defer.maybeDeferred(syntaxes[syntax_from]["to"], text) | 234 d = defer.maybeDeferred(syntaxes[syntax_from]["to"], text) |
230 else: | 235 else: |
257 """ | 262 """ |
258 flags = flags if flags is not None else [] | 263 flags = flags if flags is not None else [] |
259 if TextSyntaxes.OPT_HIDDEN in flags and TextSyntaxes.OPT_DEFAULT in flags: | 264 if TextSyntaxes.OPT_HIDDEN in flags and TextSyntaxes.OPT_DEFAULT in flags: |
260 raise ValueError(u"{} and {} are mutually exclusive".format(TextSyntaxes.OPT_HIDDEN, TextSyntaxes.OPT_DEFAULT)) | 265 raise ValueError(u"{} and {} are mutually exclusive".format(TextSyntaxes.OPT_HIDDEN, TextSyntaxes.OPT_DEFAULT)) |
261 | 266 |
262 syntaxes = TextSyntaxes.params_data['syntaxes'] | 267 syntaxes = TextSyntaxes.syntaxes |
263 if name in syntaxes: | 268 key = name.lower().strip() |
264 raise exceptions.ConflictError(u"This syntax name already exists: {}".format(name)) | 269 if key in syntaxes: |
265 syntaxes[name] = {"to": to_xhtml_cb, "from": from_xhtml_cb, "flags": flags} | 270 raise exceptions.ConflictError(u"This syntax key already exists: {}".format(key)) |
271 syntaxes[key] = {"name": name, "to": to_xhtml_cb, "from": from_xhtml_cb, "flags": flags} | |
266 if TextSyntaxes.OPT_DEFAULT in flags: | 272 if TextSyntaxes.OPT_DEFAULT in flags: |
267 TextSyntaxes.params_data['default'] = name | 273 TextSyntaxes.default_syntaxe = key |
268 | 274 |
269 self._updateParamOptions() | 275 self._updateParamOptions() |
270 | 276 |
277 def getSyntax(self, name): | |
278 """get syntax key corresponding to a name | |
279 | |
280 @raise exceptions.NotFound: syntax doesn't exist | |
281 """ | |
282 key = name.lower().strip() | |
283 if key in self.syntaxes: | |
284 return key | |
285 raise exceptions.NotFound | |
286 | |
271 def _removeMarkups(self, xhtml): | 287 def _removeMarkups(self, xhtml): |
272 """ | 288 """Remove XHTML markups from the given string. |
273 Remove XHTML markups from the given string. | 289 |
274 @param xhtml: the XHTML string to be cleaned | 290 @param xhtml: the XHTML string to be cleaned |
275 @return: the cleaned string | 291 @return: the cleaned string |
276 """ | 292 """ |
277 cleaner = clean.Cleaner(kill_tags=['style']) | 293 cleaner = clean.Cleaner(kill_tags=['style']) |
278 cleaned = cleaner.clean_html(html.fromstring(xhtml)) | 294 cleaned = cleaner.clean_html(html.fromstring(xhtml)) |