Exemplo n.º 1
0
def export():
    if request.json is None:
        abort(400)

    exporter_config = request.json['exporterConfig']

    entity_decorators = {}
    block_map = dict(BLOCK_MAP, **exporter_config.get('block_map', {}))
    style_map = dict(STYLE_MAP, **exporter_config.get('style_map', {}))

    entity_decorators[ENTITY_TYPES.FALLBACK] = import_decorator(
        'missing_inline')
    block_map[BLOCK_TYPES.FALLBACK] = import_decorator('missing_block')
    style_map[INLINE_STYLES.FALLBACK] = import_decorator('missing_inline')

    for type_, value in exporter_config.get('entity_decorators',
                                            {}).iteritems():
        entity_decorators[type_] = import_decorator(value)

    exporter = HTML({
        'entity_decorators': entity_decorators,
        'block_map': block_map,
        'style_map': style_map,
    })

    html = exporter.render(request.json['contentState'])

    return json.dumps({
        'html': html,
        'prettified': prettify(html),
    })
Exemplo n.º 2
0
 def test_render_with_none_return_value(self):
     self.assertEqual(HTML({
         'block_map': dict(BLOCK_MAP, **{
             BLOCK_TYPES.UNSTYLED: lambda props: None,
         }),
     }).render({
         'entityMap': {},
         'blocks': [
             {
                 'key': 'dem12p',
                 'text': 'header',
                 'type': 'header-one',
                 'depth': 0,
                 'inlineStyleRanges': [],
                 'entityRanges': []
             },
             {
                 'key': 'dem1p',
                 'text': 'paragraph',
                 'type': 'unstyled',
                 'depth': 0,
                 'inlineStyleRanges': [],
                 'entityRanges': []
             },
         ],
     }), '<h1>header</h1>')
Exemplo n.º 3
0
def export():
    if request.json is None:
        abort(400)

    exporter_config = request.json["exporterConfig"]

    entity_decorators = {}
    block_map = dict(BLOCK_MAP, **exporter_config.get("block_map", {}))
    style_map = dict(STYLE_MAP, **exporter_config.get("style_map", {}))

    entity_decorators[ENTITY_TYPES.FALLBACK] = import_decorator(
        "missing_inline"
    )
    block_map[BLOCK_TYPES.FALLBACK] = import_decorator("missing_block")
    style_map[INLINE_STYLES.FALLBACK] = import_decorator("missing_inline")

    for type_, value in exporter_config.get("entity_decorators", {}).items():
        entity_decorators[type_] = import_decorator(value)

    exporter = HTML(
        {
            "entity_decorators": entity_decorators,
            "block_map": block_map,
            "style_map": style_map,
        }
    )

    html = exporter.render(request.json["contentState"])
    markdown = render_markdown(request.json["contentState"])

    return json.dumps(
        {"html": html, "markdown": markdown, "prettified": prettify(html)}
    )
Exemplo n.º 4
0
 def __init__(self, content_editor):
     self.content_editor = content_editor
     # XXX: we need one exporter per DraftJSHTMLExporter because
     #      self.render_media needs to access "entityMap" from local
     #      instance. If MEDIA rendering changes in the future, exporter
     #      should be global for all DraftJSHTMLExporter instances
     self.exporter = HTML({
         "engine":
         DOM.LXML,
         "style_map":
         dict(
             STYLE_MAP,
             **{
                 INLINE_STYLES.BOLD: "b",
                 INLINE_STYLES.ITALIC: "i",
                 INLINE_STYLES.FALLBACK: self.style_fallback,
             },
         ),
         "entity_decorators": {
             ENTITY_TYPES.LINK:
             self.render_link,
             ENTITY_TYPES.HORIZONTAL_RULE:
             lambda props: DOM.create_element("hr"),
             ENTITY_TYPES.EMBED:
             self.render_embed,
             MEDIA:
             self.render_media,
             ANNOTATION:
             self.render_annotation,
             TABLE:
             self.render_table,
         },
     })
Exemplo n.º 5
0
 def test_render_with_default_block_map(self):
     self.assertEqual(HTML({
         'style_map': {
             INLINE_STYLES.ITALIC: {'element': 'em'},
             INLINE_STYLES.BOLD: {'element': 'strong'},
             'HIGHLIGHT': {'element': 'strong', 'props': {'style': {'textDecoration': 'underline'}}},
         },
     }).render({
         'entityMap': {},
         'blocks': [
             {
                 'key': 'dem5p',
                 'text': 'some paragraph text',
                 'type': 'unstyled',
                 'depth': 0,
                 'inlineStyleRanges': [
                     {
                         'offset': 0,
                         'length': 4,
                         'style': 'ITALIC'
                     }
                 ],
                 'entityRanges': []
             }
         ]
     }), '<p><em>some</em> paragraph text</p>')
Exemplo n.º 6
0
 def test_render_with_element_options(self):
     self.assertEqual(
         HTML({
             'block_map':
             dict(
                 BLOCK_MAP, **{
                     BLOCK_TYPES.HEADER_TWO: {
                         'element':
                         ['h2', {
                             'className': 'c-amazing-heading'
                         }],
                     },
                 })
         }).render({
             'entityMap': {},
             'blocks': [
                 {
                     'key': 'dem1p',
                     'text': 'item1',
                     'type': 'header-two',
                     'depth': 0,
                     'inlineStyleRanges': [],
                     'entityRanges': []
                 },
             ],
         }), '<h2 class="c-amazing-heading">item1</h2>')
Exemplo n.º 7
0
 def test_render_with_unknown_attribute(self):
     self.assertEqual(
         HTML({
             'block_map':
             dict(
                 BLOCK_MAP, **{
                     BLOCK_TYPES.UNORDERED_LIST_ITEM: {
                         'element': 'li',
                         'wrapper': ['ul', {
                             '*ngFor': 'test'
                         }],
                     },
                 })
         }).render({
             'entityMap': {},
             'blocks': [
                 {
                     'key': 'dem1p',
                     'text': 'item1',
                     'type': 'unordered-list-item',
                     'depth': 0,
                     'inlineStyleRanges': [],
                     'entityRanges': []
                 },
             ],
         }), '<ul *ngfor="test"><li>item1</li></ul>')
Exemplo n.º 8
0
 def test_render_with_boolean_attribute_false(self):
     self.assertEqual(
         HTML({
             'block_map':
             dict(
                 BLOCK_MAP, **{
                     BLOCK_TYPES.UNORDERED_LIST_ITEM: {
                         'element': 'li',
                         'wrapper': ['ul', {
                             'disabled': False
                         }],
                     },
                 }),
         }).render({
             'entityMap': {},
             'blocks': [
                 {
                     'key': 'dem1p',
                     'text': 'item1',
                     'type': 'unordered-list-item',
                     'depth': 0,
                     'inlineStyleRanges': [],
                     'entityRanges': []
                 },
             ]
         }), '<ul disabled="False"><li>item1</li></ul>')
Exemplo n.º 9
0
 def test_render_with_default_style_map(self):
     self.assertEqual(HTML({
         'block_map': dict(BLOCK_MAP, **{
             BLOCK_TYPES.UNORDERED_LIST_ITEM: {
                 'element': 'li',
                 'wrapper': 'ul',
                 'wrapper_props': {'class': 'steps'},
             },
         })
     }).render({
         'entityMap': {},
         'blocks': [
             {
                 'key': 'dem5p',
                 'text': 'some paragraph text',
                 'type': 'unstyled',
                 'depth': 0,
                 'inlineStyleRanges': [
                     {
                         'offset': 0,
                         'length': 4,
                         'style': 'ITALIC'
                     }
                 ],
                 'entityRanges': []
             }
         ]
     }), '<p><em>some</em> paragraph text</p>')
Exemplo n.º 10
0
    def do_POST(self):
        try:
            content_length = int(self.headers["Content-Length"])
            post_data = self.rfile.read(content_length)
            request_json = json.loads(post_data)
        except Exception:
            self.send_response(400)
            return

        exporter_config = request_json["exporterConfig"]

        entity_decorators = {}
        block_map = dict(BLOCK_MAP, **exporter_config.get("block_map", {}))
        style_map = dict(STYLE_MAP, **exporter_config.get("style_map", {}))

        entity_decorators[ENTITY_TYPES.FALLBACK] = missing_inline
        block_map[BLOCK_TYPES.FALLBACK] = missing_block
        style_map[INLINE_STYLES.FALLBACK] = missing_inline

        for type_, value in exporter_config.get("entity_decorators",
                                                {}).items():
            entity_decorators[type_] = import_decorator(value)

        exporter = HTML({
            "entity_decorators": entity_decorators,
            "block_map": block_map,
            "style_map": style_map,
        })

        html = exporter.render(request_json["contentState"])
        markdown = render_markdown(request_json["contentState"])

        ret = json.dumps({
            "html": html,
            "markdown": markdown,
            "prettified": prettify(html),
            "version": __version__,
        })

        self.send_response(200)
        self.send_header("Content-type", "application/json; charset=utf-8")
        self.end_headers()
        self.wfile.write(ret.encode("utf8"))
        return
Exemplo n.º 11
0
 def test_render_with_default_config(self):
     self.assertEqual(HTML().render({
         'entityMap': {},
         'blocks': [
             {
                 'key': 'dem5p',
                 'text': 'some paragraph text',
                 'type': 'unstyled',
                 'depth': 0,
                 'inlineStyleRanges': [
                     {
                         'offset': 0,
                         'length': 4,
                         'style': 'ITALIC'
                     }
                 ],
                 'entityRanges': []
             }
         ]
     }), '<p><em>some</em> paragraph text</p>')
Exemplo n.º 12
0
 def test_render_with_many_line_breaks(self):
     self.assertEqual(
         HTML().render({
             'entityMap': {},
             'blocks': [{
                 'key':
                 'dem5p',
                 'text':
                 '\nsome paragraph text\nsplit in half\n',
                 'type':
                 'unstyled',
                 'depth':
                 0,
                 'inlineStyleRanges': [{
                     'offset': 1,
                     'length': 4,
                     'style': 'ITALIC'
                 }],
                 'entityRanges': []
             }]
         }),
         '<p><br/><em>some</em> paragraph text<br/>split in half<br/></p>')
Exemplo n.º 13
0
}

# Demo content from https://github.com/springload/draftjs_exporter/blob/master/example.py.
# with open('docs/example.json') as example:
#     content_state = json.load(example)

if __name__ == '__main__':
    exporter = HTML({
        'block_map': BLOCK_MAP,
        'style_map': STYLE_MAP,
        'entity_decorators': {
            # Map entities to components so they can be rendered with their data.
            ENTITY_TYPES.IMAGE:
            image,
            ENTITY_TYPES.LINK:
            link,
            # Lambdas work too.
            ENTITY_TYPES.HORIZONTAL_RULE:
            lambda props: DOM.create_element('hr'),
            # Discard those entities.
            ENTITY_TYPES.EMBED:
            None,
        },
        'engine': 'draftjs_exporter_rust_engine.engine.DOMString',
    })

    markup = exporter.render(content_state)

    print(markup)

    # Output to a Markdown file to showcase the output in GitHub (and see changes in git).
    with codecs.open('docs/example.txt', 'w', 'utf-8') as file:
        BLOCK_TYPES.UNSTYLED: prefixed_block(""),
        BLOCK_TYPES.HEADER_ONE: prefixed_block("# "),
        BLOCK_TYPES.HEADER_TWO: prefixed_block("## "),
        BLOCK_TYPES.HEADER_THREE: prefixed_block("### "),
        BLOCK_TYPES.HEADER_FOUR: prefixed_block("#### "),
        BLOCK_TYPES.HEADER_FIVE: prefixed_block("##### "),
        BLOCK_TYPES.HEADER_SIX: prefixed_block("###### "),
        BLOCK_TYPES.UNORDERED_LIST_ITEM: {
            "element": ul,
            "wrapper": list_wrapper
        },
        BLOCK_TYPES.ORDERED_LIST_ITEM: {
            "element": ol,
            "wrapper": list_wrapper
        },
        BLOCK_TYPES.BLOCKQUOTE: prefixed_block("> "),
        # BLOCK_TYPES.CODE: {"element": code_element, "wrapper": code_wrapper},
    })

exporter = HTML({
    # Those configurations are overridable like for draftjs_exporter.
    "block_map": BLOCK_MAP,
    "style_map": STYLE_MAP,
    "entity_decorators": ENTITY_DECORATORS,
    "engine": ENGINE,
})


def render(content):
    return exporter.render(content)[:-4]
Exemplo n.º 15
0
exporter = HTML({
    "entity_decorators": {
        ENTITY_TYPES.LINK: link,
        ENTITY_TYPES.HORIZONTAL_RULE: hr,
        ENTITY_TYPES.IMAGE: image,
        ENTITY_TYPES.EMBED: None,
    },
    "composite_decorators": [
        BR_DECORATOR,
        LINKIFY_DECORATOR,
        HASHTAG_DECORATOR,
    ],
    "block_map":
    dict(
        BLOCK_MAP,
        **{
            BLOCK_TYPES.UNORDERED_LIST_ITEM: {
                "element": "li",
                "wrapper": "ul",
                "wrapper_props": {
                    "class": "bullet-list"
                },
            }
        },
    ),
    "style_map":
    dict(
        STYLE_MAP,
        **{
            "KBD": "kbd",
            "HIGHLIGHT": {
                "element": "strong",
                "props": {
                    "style": {
                        "textDecoration": "underline"
                    }
                },
            },
        },
    ),
})
Exemplo n.º 16
0
fixtures_path = os.path.join(os.path.dirname(__file__), 'test_exports.json')
fixtures = json.loads(open(fixtures_path, 'r').read())

exporter = HTML({
    'entity_decorators': {
        ENTITY_TYPES.LINK: Link(),
        ENTITY_TYPES.IMAGE: Image(),
    },
    'block_map':
    dict(
        BLOCK_MAP, **{
            BLOCK_TYPES.UNORDERED_LIST_ITEM: {
                'element': 'li',
                'wrapper': ['ul', {
                    'className': 'bullet-list'
                }],
            },
        }),
    'style_map': {
        INLINE_STYLES.ITALIC: {
            'element': 'em'
        },
        INLINE_STYLES.BOLD: {
            'element': 'strong'
        },
    },
})


class TestExportsMeta(type):
    """
Exemplo n.º 17
0
from draftjs_exporter.html import HTML
from draftjs_exporter.dom import DOM
from draftjs_exporter_markdown import (
    BLOCK_MAP,
    ENGINE,
    ENTITY_DECORATORS,
    STYLE_MAP,
)

exporter = HTML({
    "block_map": BLOCK_MAP,
    "style_map": STYLE_MAP,
    "entity_decorators": ENTITY_DECORATORS,
    "engine": ENGINE,
})


def render_markdown(content_state):
    DOM.use(ENGINE)
    return exporter.render(content_state)
Exemplo n.º 18
0
    def _parse_editor_state(self, article, ninjs):
        """Parse editor_state (DraftJs internals) to retrieve annotations

        body_html will be rewritten with HTML generated from DraftJS representation
        and annotation will be included in <span> elements
        :param article: item to modify, must contain "editor_state" data
        :param ninjs: ninjs item which will be formatted
        """
        blocks = article['editor_state']['blocks']
        blocks_map = {}
        ann_idx = 0
        data = {}
        config = {
            'engine': 'lxml',
            'entity_decorators': {
                ENTITY_TYPES.LINK:
                self._render_link,
                ENTITY_TYPES.HORIZONTAL_RULE:
                lambda props: DOM.create_element('hr'),
                ENTITY_TYPES.EMBED:
                self._render_embed,
                MEDIA:
                self._render_media,
                ANNOTATION:
                self._render_annotation
            }
        }
        renderer = HTML(config)

        for block in blocks:
            blocks_map[block['key']] = block
            data.update(block['data'])

        # we sort data keys to have consistent annotations ids
        for key in sorted(data):
            data_block = data[key]
            if data_block['type'] == ANNOTATION:
                ninjs.setdefault('annotations', []).append({
                    'id':
                    ann_idx,
                    'type':
                    data_block['annotationType'],
                    'body':
                    renderer.render(json.loads(data_block['msg']))
                })
                entity_key = '_annotation_{}'.format(ann_idx)
                article['editor_state']['entityMap'][entity_key] = {
                    'type': ANNOTATION,
                    'data': {
                        'id': ann_idx
                    }
                }
                ann_idx += 1
                selection = json.loads(key)
                if selection['isBackward']:
                    first, second = 'focus', 'anchor'
                else:
                    first, second = 'anchor', 'focus'
                first_key = selection[first + 'Key']
                second_key = selection[second + 'Key']
                first_offset = selection[first + 'Offset']
                second_offset = selection[second + 'Offset']
                # we want to style annotation with <span>, so we put them as entities
                if first_key == second_key:
                    # selection is done in a single block
                    annotated_block = blocks_map[first_key]
                    annotated_block.setdefault('entityRanges', []).append({
                        'key':
                        entity_key,
                        'offset':
                        first_offset,
                        'length':
                        second_offset - first_offset
                    })
                else:
                    # selection is done on multiple blocks, we have to select them
                    started = False
                    for block in blocks:
                        if block['key'] == first_key:
                            started = True
                            block.setdefault('entityRanges', []).append({
                                'key':
                                entity_key,
                                'offset':
                                first_offset,
                                'length':
                                len(block['text']) - first_offset
                            })
                        elif started:
                            inline = {'key': entity_key, 'offset': 0}
                            block.setdefault('entityRanges', []).append(inline)
                            if block['key'] == second_key:
                                # last block, we end the annotation here
                                inline['length'] = second_offset
                                break
                            else:
                                # intermediate block, we annotate it whole
                                inline['length'] = len(block['text'])
        # HTML rendering
        # now we have annotation ready, we can render HTML
        # we change body_html if and only if we have annotations to render
        if ninjs.get('annotations'):
            article['body_html'] = renderer.render(article['editor_state'])
Exemplo n.º 19
0
 def test_init_dom_engine_default(self):
     HTML()
     self.assertEqual(DOM.dom, DOMString)
Exemplo n.º 20
0
from draftjs_exporter.html import HTML

from draftjs_exporter_markdown import BLOCK_MAP, ENGINE, ENTITY_DECORATORS, STYLE_MAP

content_state = {}

# Demo content from https://github.com/springload/draftjs_exporter/blob/master/example.py.
with open('docs/example.json') as example:
    content_state = json.load(example)

if __name__ == '__main__':
    # Initialise the exporter.
    exporter = HTML({
        # Those configurations are overridable like for draftjs_exporter.
        'block_map': BLOCK_MAP,
        'style_map': STYLE_MAP,
        'entity_decorators': ENTITY_DECORATORS,
        'engine': ENGINE,
    })

    markup = exporter.render(content_state)

    print(markup)

    # Output to a Markdown file to showcase the output in GitHub (and see changes in git).
    with codecs.open('docs/example.txt', 'w', 'utf-8') as file:
        file.write(
            """# Example output (generated by [`example.py`](../example.py))

---
Exemplo n.º 21
0
 def setUp(self):
     self.exporter = HTML(config)
Exemplo n.º 22
0
 def test(self):
     self.maxDiff = None
     self.assertEqual(HTML(config).render(export.get('content_state')), export.get('output'))
Exemplo n.º 23
0
 def setUp(self):
     self.maxDiff = None
     self.exporter = HTML(config)
Exemplo n.º 24
0
        ENTITY_TYPES.IMAGE: image,
        ENTITY_TYPES.LINK: link,
        ENTITY_TYPES.DOCUMENT: document,
        ENTITY_TYPES.HORIZONTAL_RULE: lambda props: DOM.create_element("hr"),
        ENTITY_TYPES.EMBED: None,
        ENTITY_TYPES.FALLBACK: entity_fallback,
    },
    "composite_decorators": [{
        "strategy": re.compile(r"\n"),
        "component": br
    }],
    "engine":
    DOM.STRING,
}

exporter = HTML(config)

content_states = get_content_sample()

BENCHMARK_RUNS = int(os.environ.get("BENCHMARK_RUNS", 1))

print(f"Exporting {len(content_states)} ContentStates {BENCHMARK_RUNS} times")

pr = cProfile.Profile()
pr.enable()

for i in range(0, BENCHMARK_RUNS):
    for content_state in content_states:
        exporter.render(content_state)

pr.disable()
fixtures_path = os.path.join(os.path.dirname(__file__), 'test_exports.json')
fixtures = json.loads(open(fixtures_path, 'r').read())

exporter = HTML({
    'entity_decorators': {
        ENTITY_TYPES.LINK: link,
        ENTITY_TYPES.HORIZONTAL_RULE: hr,
        ENTITY_TYPES.IMAGE: image,
        ENTITY_TYPES.EMBED: None,
    },
    'composite_decorators': [
        BR_DECORATOR,
        LINKIFY_DECORATOR,
        HASHTAG_DECORATOR,
    ],
    'block_map': dict(BLOCK_MAP, **{
        BLOCK_TYPES.UNORDERED_LIST_ITEM: {
            'element': 'li',
            'wrapper': 'ul',
            'wrapper_props': {'class': 'bullet-list'},
        },
    }),
    'style_map': dict(STYLE_MAP, **{
        'KBD': 'kbd',
        'HIGHLIGHT': {'element': 'strong', 'props': {'style': {'textDecoration': 'underline'}}},
    }),
})


class TestExportsMeta(type):
    """
Exemplo n.º 26
0
"""
This package contains utilities for Ashley's WYSIWYG editor.
"""

import json
import logging

from draftjs_exporter.html import HTML

from ..defaults import DRAFTJS_EXPORTER_CONFIG

logger = logging.getLogger(__name__)

DRAFTJS_EXPORTER = HTML(DRAFTJS_EXPORTER_CONFIG)


def draftjs_renderer(content: str) -> str:
    """Convert a Draft.js JSON state into HTML"""
    try:
        return str(DRAFTJS_EXPORTER.render(json.loads(content)))
    except json.JSONDecodeError as err:
        logger.warning("Unable to render content : %s (content : [%s])", err, content)
    return ""
Exemplo n.º 27
0
 def test_render_with_big_content(self):
     self.assertEqual(HTML({
         'entity_decorators': {
             'LINK': link
         },
         'block_map': {
             'header-two': {'element': 'h2'},
             'blockquote': {'element': 'blockquote'},
             'unordered-list-item': {
                 'element': 'li',
                 'wrapper': 'ul',
                 'wrapper_props': {},
             },
             'unstyled': {'element': 'p'}
         },
         'style_map': {
             'ITALIC': {'element': 'em'},
             'BOLD': {'element': 'strong'}
         }
     }).render({
         'entityMap': {
             '0': {
                 'type': 'LINK',
                 'mutability': 'MUTABLE',
                 'data': {
                     'url': 'http://example.com'
                 }
             },
             '1': {
                 'type': 'LINK',
                 'mutability': 'MUTABLE',
                 'data': {
                     'url': 'https://www.springload.co.nz/work/nz-festival/'
                 }
             }
         },
         'blocks': [
             {
                 'key': '6mgfh',
                 'text': 'User experience (UX) design',
                 'type': 'header-two',
                 'depth': 0,
                 'inlineStyleRanges': [
                     {
                         'offset': 16,
                         'length': 4,
                         'style': 'BOLD'
                     }
                 ],
                 'entityRanges': []
             },
             {
                 'key': '5384u',
                 'text': 'Everyone at Springload applies the best principles of UX to their work.',
                 'type': 'blockquote',
                 'depth': 0,
                 'inlineStyleRanges': [],
                 'entityRanges': []
             },
             {
                 'key': 'eelkd',
                 'text': 'The design decisions we make building tools and services for your customers are based on empathy for what your customers need.',
                 'type': 'unstyled',
                 'depth': 0,
                 'inlineStyleRanges': [],
                 'entityRanges': []
             },
             {
                 'key': 'b9grk',
                 'text': 'User research',
                 'type': 'unordered-list-item',
                 'depth': 0,
                 'inlineStyleRanges': [],
                 'entityRanges': []
             },
             {
                 'key': 'a1tis',
                 'text': 'User testing and analysis',
                 'type': 'unordered-list-item',
                 'depth': 0,
                 'inlineStyleRanges': [],
                 'entityRanges': [
                     {
                         'offset': 0,
                         'length': 25,
                         'key': 0
                     }
                 ]
             },
             {
                 'key': 'adjdn',
                 'text': 'A/B testing',
                 'type': 'unordered-list-item',
                 'depth': 0,
                 'inlineStyleRanges': [],
                 'entityRanges': []
             },
             {
                 'key': '62lio',
                 'text': 'Prototyping',
                 'type': 'unordered-list-item',
                 'depth': 0,
                 'inlineStyleRanges': [],
                 'entityRanges': []
             },
             {
                 'key': 'fq3f',
                 'text': 'How we made it delightful and easy for people to find NZ Festival shows',
                 'type': 'unstyled',
                 'depth': 0,
                 'inlineStyleRanges': [],
                 'entityRanges': [
                     {
                         'offset': 0,
                         'length': 71,
                         'key': 1
                     }
                 ]
             }
         ]
     }), '<h2>User experience <strong>(UX)</strong> design</h2><blockquote>Everyone at Springload applies the best principles of UX to their work.</blockquote><p>The design decisions we make building tools and services for your customers are based on empathy for what your customers need.</p><ul><li>User research</li><li><a href="http://example.com">User testing and analysis</a></li><li>A/B testing</li><li>Prototyping</li></ul><p><a href="https://www.springload.co.nz/work/nz-festival/">How we made it delightful and easy for people to find NZ Festival shows</a></p>')
Exemplo n.º 28
0
from draftjs_exporter.html import HTML
from draftjs_exporter.dom import DOM
from draftjs_exporter_markdown import BLOCK_MAP, ENGINE, ENTITY_DECORATORS, STYLE_MAP

exporter = HTML({
    'block_map': BLOCK_MAP,
    'style_map': STYLE_MAP,
    'entity_decorators': ENTITY_DECORATORS,
    'engine': ENGINE,
})


def render_markdown(content_state):
    DOM.use(ENGINE)
    return exporter.render(content_state)
Exemplo n.º 29
0
def memory_consumption_run():
    exporter = HTML(config)

    for content_state in content_states:
        exporter.render(content_state)
Exemplo n.º 30
0
 def __init__(self, value, **kwargs):
     super(DraftText, self).__init__(value or '{}', **kwargs)
     self.exporter = HTML(get_exporter_config())