edwh-editorjs 2.0.0b3__py3-none-any.whl → 2.0.0b4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
editorjs/__about__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "2.0.0-beta.3"
1
+ __version__ = "2.0.0-beta.4"
editorjs/blocks.py CHANGED
@@ -5,6 +5,7 @@ mdast to editorjs
5
5
  import abc
6
6
  import re
7
7
  import typing as t
8
+ from html.parser import HTMLParser
8
9
 
9
10
  from .exceptions import TODO
10
11
  from .types import EditorChildData, MDChildNode
@@ -56,7 +57,7 @@ def process_styled_content(item: MDChildNode, strict: bool = True) -> str:
56
57
  "strongEmphasis": "<b><i>{value}</i></b>",
57
58
  "link": '<a href="{url}">{value}</a>',
58
59
  "inlineCode": '<code class="inline-code">{value}</code>',
59
- # todo: <mark>
60
+ # todo: <mark>, linktool
60
61
  }
61
62
 
62
63
  if _type in BLOCKS:
@@ -138,16 +139,52 @@ class ParagraphBlock(EditorJSBlock):
138
139
  result = []
139
140
  current_text = ""
140
141
 
141
- for child in node.get("children"):
142
+ skip = 0
143
+ nodes = node.get("children", [])
144
+
145
+ for idx, child in enumerate(nodes):
146
+ if skip:
147
+ skip -= 1
148
+ continue
149
+
142
150
  _type = child.get("type")
143
- if _type == "image":
151
+
152
+ # deal with custom types
153
+ if _type == "html" and child.get("value", "").startswith("<editorjs"):
154
+ # special type, e.g. <editorjs type="linkTool" href=...>...</editorjs>
155
+
156
+ if child.get("value", "").endswith("/>"):
157
+ # self-closing
158
+ result.append(EditorJSCustom.to_json(node))
159
+ continue
160
+ else:
161
+ # <editorjs>something</editorjs> = 3 children
162
+ result.extend(
163
+ EditorJSCustom.to_json({"children": nodes[idx : idx + 2]})
164
+ )
165
+
166
+ skip = 2
167
+ continue
168
+
169
+ elif _type == "image":
144
170
  if current_text:
145
171
  result.append({"data": {"text": current_text}, "type": "paragraph"})
146
172
  current_text = ""
147
173
 
148
174
  result.extend(ImageBlock.to_json(child))
149
175
  else:
150
- current_text += cls.to_text(child)
176
+ child_text = cls.to_text(child)
177
+ _child_text = child_text.strip()
178
+ if _child_text.startswith("|") and _child_text.endswith("|"):
179
+ # note: this just supports text-only tables.
180
+ # tables with more complex elements break into multiple children.
181
+ # and mdast DOES support converting into a Table/TableCell structure
182
+ # via the GFM exttension
183
+ # but their default mdast->md converter does NOT implement these functionalities.
184
+ result.extend(TableBlock.to_json(child))
185
+ continue
186
+
187
+ current_text += child_text
151
188
 
152
189
  # final text after image:
153
190
  if current_text:
@@ -380,3 +417,149 @@ class QuoteBlock(EditorJSBlock):
380
417
  @classmethod
381
418
  def to_text(cls, node: MDChildNode) -> str:
382
419
  return default_to_text(node)
420
+
421
+
422
+ @block("table")
423
+ class TableBlock(EditorJSBlock):
424
+
425
+ @classmethod
426
+ def to_markdown(cls, data: EditorChildData) -> str:
427
+ """
428
+ | Script | Interpreter | User | System | |
429
+ |--------|-------------|------|--------|---|
430
+ | | | | | |
431
+ | | | | | |
432
+ | | | | | |
433
+ """
434
+
435
+ table = ""
436
+ rows = data.get("content", [])
437
+
438
+ # Add an empty header row if no headings are provided
439
+ if not data.get("withHeadings", False) and rows:
440
+ table += "| " + " | ".join([""] * len(rows[0])) + " |\n"
441
+ table += "|" + " - |" * len(rows[0]) + "\n"
442
+
443
+ # Populate rows
444
+ for idx, tr in enumerate(rows):
445
+ table += "| " + " | ".join(tr) + " |\n"
446
+
447
+ # Add separator if headings are enabled and it's the first row
448
+ if not idx and data.get("withHeadings", False):
449
+ table += "|" + " - |" * len(tr) + "\n"
450
+
451
+ return f"\n{table}\n"
452
+
453
+ @classmethod
454
+ def to_json(cls, node: MDChildNode) -> list[dict]:
455
+ # content":[["Yeah","Okay"],["<i>1</i>","<code class=\"inline-code\">2</code>"]]}}]
456
+ table = []
457
+ with_headings = False
458
+
459
+ # first row is headings or empty. If not empty, withHeadings is True
460
+ # second row must be ignored
461
+ for idx, row in enumerate(node.get("value", "").strip().split("\n")):
462
+ tr = [_.strip() for _ in row.split("|")[1:-1]]
463
+ if not idx:
464
+ # first
465
+ if any(tr):
466
+ with_headings = True
467
+ table.append(tr)
468
+
469
+ elif idx == 1:
470
+ continue
471
+ else:
472
+ table.append(tr)
473
+
474
+ return [
475
+ {
476
+ "type": "table",
477
+ "content": table,
478
+ "withHeadings": with_headings,
479
+ }
480
+ ]
481
+
482
+ @classmethod
483
+ def to_text(cls, node: MDChildNode) -> str:
484
+ raise TODO(node)
485
+
486
+
487
+ @block("linkTool")
488
+ class LinkBlock(EditorJSBlock):
489
+ @classmethod
490
+ def to_markdown(cls, data: EditorChildData) -> str:
491
+ link = data.get("link", "")
492
+ meta = data.get("meta", {})
493
+ title = meta.get("title", "")
494
+ description = meta.get("description", "")
495
+ image = meta.get("image", {}).get("url", "")
496
+ return f"""<editorjs type="linkTool" href="{link}" title="{title}" image="{image}">{description}</editorjs>"""
497
+
498
+ @classmethod
499
+ def to_json(cls, node: MDChildNode) -> list[dict]:
500
+ return [
501
+ {
502
+ "type": "linkTool",
503
+ "data": {
504
+ "link": node.get("href", ""),
505
+ "meta": {
506
+ "title": node.get("title", ""),
507
+ "description": node.get("body", ""),
508
+ "image": {
509
+ "url": node.get("image", ""),
510
+ },
511
+ },
512
+ },
513
+ }
514
+ ]
515
+
516
+ @classmethod
517
+ def to_text(cls, node: MDChildNode) -> str:
518
+ return ""
519
+
520
+
521
+ class AttributeParser(HTMLParser):
522
+ def __init__(self):
523
+ super().__init__()
524
+ self.attributes = {}
525
+ self.data = None
526
+
527
+ def handle_starttag(self, tag, attrs):
528
+ # Collect attributes when the tag is encountered
529
+ self.attributes = dict(attrs)
530
+
531
+ def handle_data(self, data):
532
+ self.data = data
533
+
534
+
535
+ class EditorJSCustom(EditorJSBlock):
536
+ """
537
+ Special type of block to deal with custom attributes
538
+ """
539
+
540
+ @classmethod
541
+ def parse_html(cls, html: str):
542
+ parser = AttributeParser()
543
+ parser.feed(html)
544
+
545
+ return parser.attributes, parser.data
546
+
547
+ @classmethod
548
+ def to_markdown(cls, data: EditorChildData) -> str:
549
+ raise TODO()
550
+
551
+ @classmethod
552
+ def to_json(cls, node: MDChildNode) -> list[dict]:
553
+ html = "".join(_["value"] for _ in node.get("children", []))
554
+ attrs, body = cls.parse_html(html)
555
+ _type = attrs.get("type", "")
556
+ attrs.setdefault("body", body) # only if there is no such attribute yet
557
+
558
+ if not (handler := BLOCKS.get(_type)):
559
+ raise ValueError(f"Unknown custom type {_type}")
560
+
561
+ return handler.to_json(attrs)
562
+
563
+ @classmethod
564
+ def to_text(cls, node: MDChildNode) -> str:
565
+ raise TODO()
editorjs/core.py CHANGED
@@ -18,7 +18,11 @@ class EditorJS:
18
18
  # internal representation is mdast, because we can convert to other types
19
19
  _mdast: MDRootNode
20
20
 
21
- def __init__(self, _mdast: str | dict, extras: list = ("task_list", "fenced-code-blocks")):
21
+ def __init__(
22
+ self,
23
+ _mdast: str | dict,
24
+ extras: list = ("task_list", "fenced-code-blocks", "tables"),
25
+ ):
22
26
  if not isinstance(_mdast, str | dict):
23
27
  raise TypeError("Only `str` or `dict` is supported!")
24
28
 
@@ -26,7 +30,7 @@ class EditorJS:
26
30
  MDRootNode, json.loads(_mdast) if isinstance(_mdast, str) else _mdast
27
31
  )
28
32
 
29
- self._md = markdown2.Markdown(extras=extras) # todo: striketrough, table, ?
33
+ self._md = markdown2.Markdown(extras=extras) # todo: striketrough, ?
30
34
 
31
35
  @classmethod
32
36
  def from_json(cls, data: str | dict) -> Self:
@@ -98,6 +102,7 @@ class EditorJS:
98
102
  Export HTML string
99
103
  """
100
104
  md = self.to_markdown()
105
+ # todo: deal with custom elements like linktool
101
106
  return self._md.convert(md)
102
107
 
103
108
  def __repr__(self):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: edwh-editorjs
3
- Version: 2.0.0b3
3
+ Version: 2.0.0b4
4
4
  Summary: EditorJS.py
5
5
  Project-URL: Homepage, https://github.com/educationwarehouse/edwh-EditorJS
6
6
  Author-email: SKevo <skevo.cw@gmail.com>, Robin van der Noord <robin.vdn@educationwarehouse.nl>
@@ -0,0 +1,11 @@
1
+ editorjs/__about__.py,sha256=nNwsxbhqslw4VX_3DwOL0FdYImal5yO3Y3Co_qiJaQk,29
2
+ editorjs/__init__.py,sha256=-OHUf7ZXfkbdFB1r85eIjpHRfql-GCNUCKuBEdEt2Rc,58
3
+ editorjs/blocks.py,sha256=g9gP09aIc63gRU7kbI7by1cJyvPFm69JxYn_43xblpM,17230
4
+ editorjs/core.py,sha256=RiJYbQk6ladkOuTM7Gj7nrmHO_ud6qQg31dhTxMn6bI,3354
5
+ editorjs/exceptions.py,sha256=TyfHvk2Z5RbKxTDK7lrjgwAgVgInXIuDW63eO5jzVFw,106
6
+ editorjs/helpers.py,sha256=q861o5liNibMTp-Ozay17taF7CTNsRe901lYhhxdwHg,73
7
+ editorjs/types.py,sha256=W7IZWMWgzJaQulybIt0Gx5N63rVj4mEy73VJWo4VAQA,1029
8
+ edwh_editorjs-2.0.0b4.dist-info/METADATA,sha256=x9NF5PqOaUK-5YaAMrqABybTV0SmX4LsRAq2rotleOo,1009
9
+ edwh_editorjs-2.0.0b4.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
10
+ edwh_editorjs-2.0.0b4.dist-info/licenses/LICENSE,sha256=zzllbk0pvnmgzk31iq8Zkg0GkA8vVx_Zc3OHjVlTjxo,1101
11
+ edwh_editorjs-2.0.0b4.dist-info/RECORD,,
@@ -1,11 +0,0 @@
1
- editorjs/__about__.py,sha256=TTjbddHImhhMSF_k6S9WFgA-Fcil370fw4WeR8a-eBk,29
2
- editorjs/__init__.py,sha256=-OHUf7ZXfkbdFB1r85eIjpHRfql-GCNUCKuBEdEt2Rc,58
3
- editorjs/blocks.py,sha256=WTtzsflkbhkZhjYQ6vZ_6Frl66ZU9uUbWwnX4mGzu4c,11341
4
- editorjs/core.py,sha256=_mr-WJ2QgB2drgBLnPM38DAPTaxZba--H_EWiQcAZMY,3264
5
- editorjs/exceptions.py,sha256=TyfHvk2Z5RbKxTDK7lrjgwAgVgInXIuDW63eO5jzVFw,106
6
- editorjs/helpers.py,sha256=q861o5liNibMTp-Ozay17taF7CTNsRe901lYhhxdwHg,73
7
- editorjs/types.py,sha256=W7IZWMWgzJaQulybIt0Gx5N63rVj4mEy73VJWo4VAQA,1029
8
- edwh_editorjs-2.0.0b3.dist-info/METADATA,sha256=QeUtRWqC6v8mGhkm16JoFJ78KhFW0mSEhxHifKTmYjI,1009
9
- edwh_editorjs-2.0.0b3.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
10
- edwh_editorjs-2.0.0b3.dist-info/licenses/LICENSE,sha256=zzllbk0pvnmgzk31iq8Zkg0GkA8vVx_Zc3OHjVlTjxo,1101
11
- edwh_editorjs-2.0.0b3.dist-info/RECORD,,