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.
- {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/CHANGELOG.md +12 -0
- {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/PKG-INFO +1 -1
- edwh_editorjs-2.2.1/editorjs/__about__.py +1 -0
- {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/editorjs/blocks.py +73 -0
- {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/editorjs/core.py +8 -2
- {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/tests/test_core.py +33 -2
- edwh_editorjs-2.1.1/editorjs/__about__.py +0 -1
- {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/.github/workflows/build_documentation.yml +0 -0
- {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/.github/workflows/publish_to_pypi.yml +0 -0
- {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/.github/workflows/pytest.yml +0 -0
- {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/.gitignore +0 -0
- {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/README.md +0 -0
- {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/editorjs/__init__.py +0 -0
- {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/editorjs/exceptions.py +0 -0
- {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/editorjs/helpers.py +0 -0
- {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/editorjs/types.py +0 -0
- {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/htmlcov/.gitignore +0 -0
- {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/htmlcov/class_index.html +0 -0
- {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/htmlcov/favicon_32_cb_58284776.png +0 -0
- {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/htmlcov/function_index.html +0 -0
- {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/htmlcov/index.html +0 -0
- {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/htmlcov/keybd_closed_cb_ce680311.png +0 -0
- {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/htmlcov/status.json +0 -0
- {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/htmlcov/style_cb_8e611ae1.css +0 -0
- {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/htmlcov/z_a93c8aeb4b8fa1f9___init___py.html +0 -0
- {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/htmlcov/z_a93c8aeb4b8fa1f9_blocks_py.html +0 -0
- {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/htmlcov/z_a93c8aeb4b8fa1f9_exceptions_py.html +0 -0
- {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/htmlcov/z_a93c8aeb4b8fa1f9_parser_py.html +0 -0
- {edwh_editorjs-2.1.1 → edwh_editorjs-2.2.1}/pyproject.toml +0 -0
- {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.
|
|
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
|
-
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|