edwh-editorjs 2.1.1__tar.gz → 2.2.1__tar.gz

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.
Files changed (30) hide show
  1. {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/CHANGELOG.md +12 -0
  2. {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/PKG-INFO +1 -1
  3. edwh_editorjs-2.2.1/editorjs/__about__.py +1 -0
  4. {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/editorjs/blocks.py +73 -0
  5. {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/editorjs/core.py +8 -2
  6. {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/tests/test_core.py +33 -2
  7. edwh_editorjs-2.1.1/editorjs/__about__.py +0 -1
  8. {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/.github/workflows/build_documentation.yml +0 -0
  9. {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/.github/workflows/publish_to_pypi.yml +0 -0
  10. {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/.github/workflows/pytest.yml +0 -0
  11. {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/.gitignore +0 -0
  12. {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/README.md +0 -0
  13. {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/editorjs/__init__.py +0 -0
  14. {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/editorjs/exceptions.py +0 -0
  15. {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/editorjs/helpers.py +0 -0
  16. {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/editorjs/types.py +0 -0
  17. {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/htmlcov/.gitignore +0 -0
  18. {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/htmlcov/class_index.html +0 -0
  19. {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/htmlcov/favicon_32_cb_58284776.png +0 -0
  20. {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/htmlcov/function_index.html +0 -0
  21. {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/htmlcov/index.html +0 -0
  22. {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/htmlcov/keybd_closed_cb_ce680311.png +0 -0
  23. {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/htmlcov/status.json +0 -0
  24. {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/htmlcov/style_cb_8e611ae1.css +0 -0
  25. {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/htmlcov/z_a93c8aeb4b8fa1f9___init___py.html +0 -0
  26. {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/htmlcov/z_a93c8aeb4b8fa1f9_blocks_py.html +0 -0
  27. {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/htmlcov/z_a93c8aeb4b8fa1f9_exceptions_py.html +0 -0
  28. {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/htmlcov/z_a93c8aeb4b8fa1f9_parser_py.html +0 -0
  29. {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/pyproject.toml +0 -0
  30. {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/tests/__init__.py +0 -0
@@ -2,6 +2,18 @@
2
2
 
3
3
  <!--next-version-placeholder-->
4
4
 
5
+ ## v2.2.1 (2024-11-26)
6
+
7
+ ### Fix
8
+
9
+ * Quick fix to prevent unlimited spaces being added by mdast ([`a196a22`](https://github.com/educationwarehouse/edwh-editorjs/commit/a196a221b623f7d4808aec64ef455197bdcfacaf))
10
+
11
+ ## v2.2.0 (2024-11-26)
12
+
13
+ ### Feature
14
+
15
+ * Support the alignment tune plugin ([`652cb58`](https://github.com/educationwarehouse/edwh-editorjs/commit/652cb58920b35fbb36c56d665e52e69a40811258))
16
+
5
17
  ## v2.1.1 (2024-11-26)
6
18
 
7
19
  ### Fix
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: edwh-editorjs
3
- Version: 2.1.1
3
+ Version: 2.2.1
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 @@
1
+ __version__ = "2.2.1"
@@ -93,10 +93,25 @@ class HeadingBlock(EditorJSBlock):
93
93
  def to_markdown(cls, data: EditorChildData) -> str:
94
94
  level = data.get("level", 1)
95
95
  text = data.get("text", "")
96
+ tunes = data.get("tunes", {})
96
97
 
97
98
  if not (1 <= level <= 6):
98
99
  raise ValueError("Header level must be between 1 and 6.")
99
100
 
101
+ if (
102
+ tunes.get("alignmentTune")
103
+ and (alignment := tunes["alignmentTune"].get("alignment"))
104
+ and (alignment != "left")
105
+ ):
106
+ # can't just return regular HTML because then it will turn into a raw block
107
+ return AlignmentBlock.to_markdown(
108
+ {
109
+ "text": text,
110
+ "tag": f"h{level}",
111
+ "alignment": alignment,
112
+ }
113
+ )
114
+
100
115
  return f"{'#' * level} {text}\n"
101
116
 
102
117
  @classmethod
@@ -143,6 +158,21 @@ class ParagraphBlock(EditorJSBlock):
143
158
  @classmethod
144
159
  def to_markdown(cls, data: EditorChildData) -> str:
145
160
  text = data.get("text", "")
161
+ tunes = data.get("tunes", {})
162
+
163
+ if (
164
+ tunes.get("alignmentTune")
165
+ and (alignment := tunes["alignmentTune"].get("alignment"))
166
+ and (alignment != "left")
167
+ ):
168
+ return AlignmentBlock.to_markdown(
169
+ {
170
+ "text": text,
171
+ "tag": "p",
172
+ "alignment": alignment,
173
+ }
174
+ )
175
+
146
176
  return f"{text}\n\n"
147
177
 
148
178
  @classmethod
@@ -617,6 +647,49 @@ class AttachmentBlock(EditorJSBlock):
617
647
  """
618
648
 
619
649
 
650
+ @block("alignment")
651
+ class AlignmentBlock(EditorJSBlock):
652
+ @classmethod
653
+ def to_markdown(cls, data: EditorChildData) -> str:
654
+ tag = data["tag"]
655
+ alignment = data["alignment"]
656
+ content = data["text"]
657
+
658
+ return f"<editorjs type='alignment' tag='{tag}' alignment='{alignment}'>{content}</editorjs>\n\n"
659
+
660
+ @classmethod
661
+ def to_json(cls, node: MDChildNode) -> list[dict]:
662
+ # only paragraph and headers can be aligned
663
+ tag: str = node["tag"]
664
+ text: str = node["body"]
665
+ alignment = node["alignment"]
666
+ data = {"text": text}
667
+
668
+ if tag == "p":
669
+ _type = "paragraph"
670
+ elif tag.startswith("h"):
671
+ _type = "header"
672
+ data["level"] = int(tag.removeprefix("h"))
673
+ else:
674
+ # doesn't support alignment
675
+ raise TODO(f"Unsupported tag for alignment: {tag}")
676
+
677
+ return [
678
+ {
679
+ "type": _type,
680
+ "data": data,
681
+ "tunes": {"alignmentTune": {"alignment": alignment}},
682
+ }
683
+ ]
684
+
685
+ @classmethod
686
+ def to_text(cls, node: MDChildNode) -> str:
687
+ tag = node["tag"]
688
+ body = node["body"]
689
+ alignment = node["alignment"]
690
+ return f"<{tag} style='text-align: {alignment}'>{body}</{tag}>"
691
+
692
+
620
693
  class AttributeParser(HTMLParser):
621
694
  def __init__(self):
622
695
  super().__init__()
@@ -43,7 +43,11 @@ class EditorJS:
43
43
  if not (block := BLOCKS.get(_type)):
44
44
  raise TypeError(f"Unsupported block type `{_type}`")
45
45
 
46
- markdown_items.append(block.to_markdown(child.get("data", {})))
46
+ data = child.get("data", {})
47
+ # forward any 'tunes' via data:
48
+ data["tunes"] = data.get("tunes") or child.get("tunes") or {}
49
+
50
+ markdown_items.append(block.to_markdown(data))
47
51
 
48
52
  markdown = "".join(markdown_items)
49
53
  return cls.from_markdown(markdown)
@@ -88,7 +92,9 @@ class EditorJS:
88
92
  # idk why this happens:
89
93
  md = md.replace(r"\[ ]", "[ ]")
90
94
  md = md.replace(r"\[x]", "[x]")
91
- return md
95
+ return md.replace(
96
+ " <", " <"
97
+ ) # replace double space (added by mdast) with single one
92
98
 
93
99
  def to_mdast(self) -> str:
94
100
  """
@@ -135,12 +135,27 @@ def test_raw_html():
135
135
  e = EditorJS.from_json(raw_html_json)
136
136
  blocks = json.loads(e.to_json())
137
137
 
138
- print(blocks)
139
-
140
138
  assert blocks["blocks"][0]["type"] == "paragraph", blocks["blocks"][0]["type"]
141
139
  assert blocks["blocks"][1]["type"] == "raw", blocks["blocks"][1]["type"]
142
140
  assert blocks["blocks"][2]["type"] == "paragraph", blocks["blocks"][2]["type"]
143
141
 
142
+ raw_html_json = r"""[{"id":"xGbqrb40Uz","type":"raw","data":{"html":"<marquee><kaas>mannetje</kaas></marquee>"}}]"""
143
+
144
+ e = EditorJS.from_json(raw_html_json)
145
+
146
+ print(e.to_mdast(), e.to_markdown())
147
+ e = EditorJS.from_markdown(e.to_markdown())
148
+ print(e.to_mdast(), e.to_markdown())
149
+
150
+ e = EditorJS.from_markdown(e.to_markdown())
151
+ e = EditorJS.from_markdown(e.to_markdown())
152
+ e = EditorJS.from_markdown(e.to_markdown())
153
+ e = EditorJS.from_markdown(e.to_markdown())
154
+ e = EditorJS.from_markdown(e.to_markdown())
155
+
156
+ print(e.to_markdown())
157
+ assert " " not in e.to_markdown(), "added too many whitespaces"
158
+
144
159
 
145
160
  def test_code():
146
161
  e = EditorJS.from_markdown(textwrap.dedent("""
@@ -179,3 +194,19 @@ def test_code():
179
194
  assert blocks["blocks"][0]["type"] == "paragraph", blocks["blocks"][0]["type"]
180
195
  assert blocks["blocks"][1]["type"] == "code", blocks["blocks"][1]["type"]
181
196
  assert blocks["blocks"][2]["type"] == "paragraph", blocks["blocks"][2]["type"]
197
+
198
+
199
+ def test_alignment():
200
+ json_blocks = r"""[{"id":"7pEj7OVRiI","type":"header","data":{"text":"Right","level":2},"tunes":{"alignmentTune":{"alignment":"right"}}},{"id":"BxL_tpq3AD","type":"paragraph","data":{"text":"right"},"tunes":{"alignmentTune":{"alignment":"right"}}},{"id":"KOh0mMtNQf","type":"header","data":{"text":"Center","level":2},"tunes":{"alignmentTune":{"alignment":"center"}}},{"id":"AegxKSR6Oa","type":"paragraph","data":{"text":"center"},"tunes":{"alignmentTune":{"alignment":"center"}}},{"id":"xJK82ujRe5","type":"header","data":{"text":"Left","level":3},"tunes":{"alignmentTune":{"alignment":"left"}}},{"id":"bwwQwKdZf0","type":"paragraph","data":{"text":"left"},"tunes":{"alignmentTune":{"alignment":"left"}}}]"""
201
+
202
+ e = EditorJS.from_json(json_blocks)
203
+
204
+ print(e.to_markdown())
205
+ print(e.to_html())
206
+
207
+ blocks = json.loads(e.to_json())
208
+
209
+ assert blocks["blocks"][0]["tunes"]
210
+
211
+ print(e.to_json())
212
+
@@ -1 +0,0 @@
1
- __version__ = "2.1.1"
File without changes
File without changes