# HG changeset patch # User Goffi # Date 1383687646 -3600 # Node ID 6a64e0a759e614b805fd8d3a360c91d6ae20c942 # Parent cac98ca764790c43f1a79b893ea8c5e282f9244e plugin text syntaxes: this plugin manage rich text syntaxes conversions and cleaning. diff -r cac98ca76479 -r 6a64e0a759e6 src/plugins/plugin_misc_text_syntaxes.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/plugins/plugin_misc_text_syntaxes.py Tue Nov 05 22:40:46 2013 +0100 @@ -0,0 +1,187 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# SAT plugin for managing various text syntaxes +# Copyright (C) 2009, 2010, 2011, 2012, 2013 Jérôme Poisson (goffi@goffi.org) + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero 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 Affero General Public License for more details. + +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +from logging import debug, info, error + +from wokkel import disco, pubsub +from twisted.internet import defer +from twisted.internet.threads import deferToThread +from lxml.html import defs, clean + +CATEGORY = "Composition" +NAME = "Syntax" +_SYNTAX_XHTML = "XHTML" + + +PLUGIN_INFO = { + "name": "Text syntaxes", + "import_name": "TEXT-SYNTAXES", + "type": "MISC", + "protocols": [], + "dependencies": [], + "main": "TextSyntaxes", + "handler": "no", + "description": _("""Management of various text syntaxes (XHTML-IM, Markdown, etc)""") +} + +class UnknownSyntax(Exception): + pass + +class TextSyntaxes(object): + """ Text conversion class + XHTML utf-8 is used as intermediate language for conversions + """ + + OPT_DEFAULT = "DEFAULT" + OPT_HIDDEN = "HIDDEN" + OPT_NO_THREAD = "NO_THREAD" + SYNTAX_XHTML = _SYNTAX_XHTML + SYNTAX_MARKDOWN = "markdown" + + params = """ + + + + + %(options)s + + + + + """ + + params_data = { + 'category_name': CATEGORY, + 'category_label': _(CATEGORY), #FIXME: gof: vérifier que gettext gère ça + 'name': NAME, + 'label': _(NAME), + 'default': _SYNTAX_XHTML, + 'syntaxes': {}, + } + + def __init__(self, host): + info(_("Text syntaxes plugin initialization")) + self.host = host + self.syntaxes = {} + self.addSyntax(self.SYNTAX_XHTML, lambda xhtml: defer.succeed(xhtml), lambda xhtml: defer.succeed(xhtml), + TextSyntaxes.OPT_NO_THREAD) + try: + import markdown, html2text + self.addSyntax(self.SYNTAX_MARKDOWN, markdown.markdown, html2text.html2text, [TextSyntaxes.OPT_DEFAULT]) + except ImportError: + warning("markdown or html2text not found, can't use Markdown syntax") + host.bridge.addMethod("syntaxConvert", ".plugin", in_sign='sssb', out_sign='s', + async=True, method=self.convert) + + # TODO: gof: nettoyage XHTML avec lxml + + def _updateParamOptions(self): + data_synt = TextSyntaxes.params_data['syntaxes'] + syntaxes = [] + + for syntax in data_synt.keys(): + flags = data_synt[syntax]["flags"] + if TextSyntaxes.OPT_HIDDEN not in flags: + syntaxes.append(syntax) + + syntaxes.sort(key=unicode.lower) + options = [] + + for syntax in syntaxes: + options.append(u'