""" Slixmpp: The Slick XMPP Library Copyright (C) 2017 Emmanuel Gil Peyrot This file is part of Slixmpp. See the file LICENSE for copying permission. """ from slixmpp.stanza import Message from slixmpp.plugins import BasePlugin from slixmpp.xmlstream import register_stanza_plugin, ET, tostring from slixmpp.plugins.xep_0394 import stanza, Markup, Span, BlockCode, List, Li, BlockQuote from slixmpp.plugins.xep_0071 import XHTML_IM class Start: def __init__(self, elem): self.elem = elem def __repr__(self): return 'Start(%s)' % self.elem class End: def __init__(self, elem): self.elem = elem def __repr__(self): return 'End(%s)' % self.elem class XEP_0394(BasePlugin): name = 'xep_0394' description = 'XEP-0394: Message Markup' dependencies = {'xep_0030', 'xep_0071'} stanza = stanza def plugin_init(self): register_stanza_plugin(Message, Markup) def session_bind(self, jid): self.xmpp['xep_0030'].add_feature(feature=Markup.namespace) def plugin_end(self): self.xmpp['xep_0030'].del_feature(feature=Markup.namespace) @staticmethod def _split_first_level(body, markup_elem): split_points = [] elements = {} for markup in markup_elem['substanzas']: start = markup['start'] end = markup['end'] split_points.append(start) split_points.append(end) elements.setdefault(start, []).append(Start(markup)) elements.setdefault(end, []).append(End(markup)) if isinstance(markup, List): lis = markup['lis'] for i, li in enumerate(lis): start = li['start'] split_points.append(start) li_end = lis[i + 1]['start'] if i < len(lis) - 1 else end elements.setdefault(li_end, []).append(End(li)) elements.setdefault(start, []).append(Start(li)) split_points = set(split_points) new_body = [[]] for i, letter in enumerate(body + '\x00'): if i in split_points: body_elements = [] for elem in elements[i]: body_elements.append(elem) new_body.append(body_elements) new_body.append([]) new_body[-1].append(letter) new_body[-1] = new_body[-1][:-1] final = [] for chunk in new_body: if not chunk: continue final.append(''.join(chunk) if isinstance(chunk[0], str) else chunk) return final def to_plain_text(self, body, markup_elem): chunks = self._split_first_level(body, markup_elem) final = [] for chunk in chunks: if isinstance(chunk, str): final.append(chunk) return ''.join(final) def to_xhtml_im(self, body, markup_elem): chunks = self._split_first_level(body, markup_elem) final = [] stack = [] for chunk in chunks: if isinstance(chunk, str): chunk = (chunk.replace("&", '&') .replace('<', '<') .replace('>', '>') .replace('"', '"') .replace("'", ''') .replace('\n', '
')) final.append(chunk) continue num_end = 0 for elem in chunk: if isinstance(elem, End): num_end += 1 for i in range(num_end): stack_top = stack.pop() for elem in chunk: if not isinstance(elem, End): continue elem = elem.elem if elem is stack_top: if isinstance(elem, Span): final.append('') elif isinstance(elem, BlockCode): final.append('') elif isinstance(elem, List): final.append('') elif isinstance(elem, Li): final.append('') elif isinstance(elem, BlockQuote): final.append('') break else: assert False for elem in chunk: if not isinstance(elem, Start): continue elem = elem.elem stack.append(elem) if isinstance(elem, Span): style = [] for type_ in elem['types']: if type_ == 'emphasis': style.append('font-style: italic;') if type_ == 'code': style.append('font-family: monospace;') if type_ == 'deleted': style.append('text-decoration: line-through;') final.append("" % ' '.join(style)) elif isinstance(elem, BlockCode): final.append('
')
                elif isinstance(elem, List):
                    final.append('
    ') elif isinstance(elem, Li): final.append('
  • ') elif isinstance(elem, BlockQuote): final.append('
    ') p = "

    %s

    " % ''.join(final) p2 = ET.fromstring(p) print('coucou', p, tostring(p2)) xhtml_im = XHTML_IM() xhtml_im['body'] = p2 return xhtml_im