notionary 0.1.13__py3-none-any.whl → 0.1.15__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.
- notionary/__init__.py +2 -2
- notionary/{converters/elements → elements}/audio_element.py +1 -1
- notionary/{converters/registry → elements}/block_element_registry.py +2 -5
- notionary/elements/block_element_registry_builder.py +383 -0
- notionary/{converters/elements → elements}/bookmark_element.py +1 -1
- notionary/{converters/elements → elements}/callout_element.py +2 -2
- notionary/{converters/elements → elements}/code_block_element.py +1 -1
- notionary/{converters/elements → elements}/column_element.py +1 -1
- notionary/{converters/elements → elements}/divider_element.py +1 -1
- notionary/{converters/elements → elements}/embed_element.py +1 -1
- notionary/{converters/elements → elements}/heading_element.py +2 -2
- notionary/{converters/elements → elements}/image_element.py +1 -1
- notionary/{converters/elements → elements}/list_element.py +2 -2
- notionary/elements/mention_element.py +227 -0
- notionary/{converters/elements → elements}/paragraph_element.py +2 -2
- notionary/{converters/elements → elements}/qoute_element.py +1 -1
- notionary/{converters/elements → elements}/table_element.py +2 -2
- notionary/{converters/elements → elements}/todo_lists.py +2 -2
- notionary/{converters/elements → elements}/toggle_element.py +1 -1
- notionary/{converters/elements → elements}/video_element.py +1 -1
- notionary/notion_client.py +55 -5
- notionary/page/content/page_content_manager.py +98 -26
- notionary/{converters → page}/markdown_to_notion_converter.py +2 -4
- notionary/page/notion_page.py +23 -5
- notionary/page/notion_page_factory.py +1 -15
- notionary/page/notion_to_markdown_converter.py +261 -0
- {notionary-0.1.13.dist-info → notionary-0.1.15.dist-info}/METADATA +1 -1
- notionary-0.1.15.dist-info/RECORD +56 -0
- notionary/converters/__init__.py +0 -50
- notionary/converters/notion_to_markdown_converter.py +0 -45
- notionary/converters/registry/block_element_registry_builder.py +0 -284
- notionary-0.1.13.dist-info/RECORD +0 -56
- /notionary/{converters/elements → elements}/notion_block_element.py +0 -0
- /notionary/{converters/elements → elements}/text_inline_formatter.py +0 -0
- {notionary-0.1.13.dist-info → notionary-0.1.15.dist-info}/WHEEL +0 -0
- {notionary-0.1.13.dist-info → notionary-0.1.15.dist-info}/licenses/LICENSE +0 -0
- {notionary-0.1.13.dist-info → notionary-0.1.15.dist-info}/top_level.txt +0 -0
notionary/__init__.py
CHANGED
@@ -7,8 +7,8 @@ from .database.database_discovery import DatabaseDiscovery
|
|
7
7
|
from .page.notion_page import NotionPage
|
8
8
|
from .page.notion_page_factory import NotionPageFactory
|
9
9
|
|
10
|
-
from .
|
11
|
-
from .
|
10
|
+
from .elements.block_element_registry import BlockElementRegistry
|
11
|
+
from .elements.block_element_registry_builder import (
|
12
12
|
BlockElementRegistryBuilder,
|
13
13
|
)
|
14
14
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
from typing import Dict, Any, Optional, List, Type
|
2
2
|
|
3
|
-
from notionary.
|
4
|
-
from notionary.
|
3
|
+
from notionary.elements.notion_block_element import NotionBlockElement
|
4
|
+
from notionary.elements.text_inline_formatter import TextInlineFormatter
|
5
5
|
|
6
6
|
|
7
7
|
class BlockElementRegistry:
|
@@ -96,9 +96,6 @@ class BlockElementRegistry:
|
|
96
96
|
# Create a copy of registered elements
|
97
97
|
element_classes = self._elements.copy()
|
98
98
|
|
99
|
-
# TODO: Das hier besser formattieren und über debug level lösen . )
|
100
|
-
print("Elements in registry:", element_classes)
|
101
|
-
|
102
99
|
formatter_names = [e.__name__ for e in element_classes]
|
103
100
|
if "TextInlineFormatter" not in formatter_names:
|
104
101
|
element_classes = [TextInlineFormatter] + element_classes
|
@@ -0,0 +1,383 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
from typing import List, Type
|
3
|
+
from collections import OrderedDict
|
4
|
+
|
5
|
+
from notionary.elements.audio_element import AudioElement
|
6
|
+
from notionary.elements.embed_element import EmbedElement
|
7
|
+
from notionary.elements.mention_element import MentionElement
|
8
|
+
from notionary.elements.notion_block_element import NotionBlockElement
|
9
|
+
from notionary.elements.block_element_registry import (
|
10
|
+
BlockElementRegistry,
|
11
|
+
)
|
12
|
+
|
13
|
+
from notionary.elements.paragraph_element import ParagraphElement
|
14
|
+
from notionary.elements.heading_element import HeadingElement
|
15
|
+
from notionary.elements.callout_element import CalloutElement
|
16
|
+
from notionary.elements.code_block_element import CodeBlockElement
|
17
|
+
from notionary.elements.divider_element import DividerElement
|
18
|
+
from notionary.elements.table_element import TableElement
|
19
|
+
from notionary.elements.todo_lists import TodoElement
|
20
|
+
from notionary.elements.list_element import (
|
21
|
+
BulletedListElement,
|
22
|
+
NumberedListElement,
|
23
|
+
)
|
24
|
+
from notionary.elements.qoute_element import QuoteElement
|
25
|
+
from notionary.elements.image_element import ImageElement
|
26
|
+
from notionary.elements.video_element import VideoElement
|
27
|
+
from notionary.elements.toggle_element import ToggleElement
|
28
|
+
from notionary.elements.bookmark_element import BookmarkElement
|
29
|
+
from notionary.elements.column_element import ColumnElement
|
30
|
+
|
31
|
+
|
32
|
+
class BlockElementRegistryBuilder:
|
33
|
+
"""
|
34
|
+
True builder for constructing BlockElementRegistry instances.
|
35
|
+
|
36
|
+
This builder allows for incremental construction of registry instances
|
37
|
+
with specific configurations of block elements.
|
38
|
+
"""
|
39
|
+
|
40
|
+
def __init__(self):
|
41
|
+
"""Initialize a new builder with an empty element list."""
|
42
|
+
self._elements = OrderedDict()
|
43
|
+
|
44
|
+
@classmethod
|
45
|
+
def start_empty(cls) -> BlockElementRegistryBuilder:
|
46
|
+
"""
|
47
|
+
Start with a completely empty registry builder.
|
48
|
+
|
49
|
+
Returns:
|
50
|
+
A new builder instance with no elements
|
51
|
+
"""
|
52
|
+
return cls()
|
53
|
+
|
54
|
+
@classmethod
|
55
|
+
def start_minimal(cls) -> BlockElementRegistryBuilder:
|
56
|
+
"""
|
57
|
+
Start with a minimal set of essential elements.
|
58
|
+
|
59
|
+
Returns:
|
60
|
+
A new builder instance with basic elements
|
61
|
+
"""
|
62
|
+
builder = cls()
|
63
|
+
return builder.with_headings().with_lists().with_paragraphs()
|
64
|
+
|
65
|
+
@classmethod
|
66
|
+
def start_standard(cls) -> BlockElementRegistryBuilder:
|
67
|
+
"""
|
68
|
+
Start with all standard elements in recommended order.
|
69
|
+
|
70
|
+
Returns:
|
71
|
+
A new builder instance with all standard elements
|
72
|
+
"""
|
73
|
+
builder = cls()
|
74
|
+
return (
|
75
|
+
builder.with_headings()
|
76
|
+
.with_callouts()
|
77
|
+
.with_code()
|
78
|
+
.with_dividers()
|
79
|
+
.with_tables()
|
80
|
+
.with_columns()
|
81
|
+
.with_lists()
|
82
|
+
.with_toggles()
|
83
|
+
.with_quotes()
|
84
|
+
.with_todos()
|
85
|
+
.with_bookmarks()
|
86
|
+
.with_images()
|
87
|
+
.with_videos()
|
88
|
+
.with_embeds()
|
89
|
+
.with_audio()
|
90
|
+
.with_mention()
|
91
|
+
.with_paragraphs()
|
92
|
+
)
|
93
|
+
|
94
|
+
# Element manipulation methods
|
95
|
+
|
96
|
+
def add_element(
|
97
|
+
self, element_class: Type[NotionBlockElement]
|
98
|
+
) -> BlockElementRegistryBuilder:
|
99
|
+
"""
|
100
|
+
Add an element class to the registry configuration.
|
101
|
+
If the element already exists, it's moved to the end.
|
102
|
+
|
103
|
+
Args:
|
104
|
+
element_class: The element class to add
|
105
|
+
|
106
|
+
Returns:
|
107
|
+
Self for method chaining
|
108
|
+
"""
|
109
|
+
self._elements.pop(element_class.__name__, None)
|
110
|
+
self._elements[element_class.__name__] = element_class
|
111
|
+
|
112
|
+
return self
|
113
|
+
|
114
|
+
def add_elements(
|
115
|
+
self, element_classes: List[Type[NotionBlockElement]]
|
116
|
+
) -> BlockElementRegistryBuilder:
|
117
|
+
"""
|
118
|
+
Add multiple element classes to the registry configuration.
|
119
|
+
|
120
|
+
Args:
|
121
|
+
element_classes: List of element classes to add
|
122
|
+
|
123
|
+
Returns:
|
124
|
+
Self for method chaining
|
125
|
+
"""
|
126
|
+
for element_class in element_classes:
|
127
|
+
self.add_element(element_class)
|
128
|
+
return self
|
129
|
+
|
130
|
+
def remove_element(
|
131
|
+
self, element_class: Type[NotionBlockElement]
|
132
|
+
) -> BlockElementRegistryBuilder:
|
133
|
+
"""
|
134
|
+
Remove an element class from the registry configuration.
|
135
|
+
|
136
|
+
Args:
|
137
|
+
element_class: The element class to remove
|
138
|
+
|
139
|
+
Returns:
|
140
|
+
Self for method chaining
|
141
|
+
"""
|
142
|
+
self._elements.pop(element_class.__name__, None)
|
143
|
+
return self
|
144
|
+
|
145
|
+
def move_element_to_end(
|
146
|
+
self, element_class: Type[NotionBlockElement]
|
147
|
+
) -> BlockElementRegistryBuilder:
|
148
|
+
"""
|
149
|
+
Move an existing element to the end of the registry.
|
150
|
+
If the element doesn't exist, it will be added.
|
151
|
+
|
152
|
+
Args:
|
153
|
+
element_class: The element class to move
|
154
|
+
|
155
|
+
Returns:
|
156
|
+
Self for method chaining
|
157
|
+
"""
|
158
|
+
return self.add_element(element_class)
|
159
|
+
|
160
|
+
def _ensure_paragraph_at_end(self) -> None:
|
161
|
+
"""
|
162
|
+
Internal method to ensure ParagraphElement is the last element in the registry.
|
163
|
+
"""
|
164
|
+
if ParagraphElement.__name__ in self._elements:
|
165
|
+
paragraph_class = self._elements.pop(ParagraphElement.__name__)
|
166
|
+
self._elements[ParagraphElement.__name__] = paragraph_class
|
167
|
+
|
168
|
+
def with_paragraphs(self) -> BlockElementRegistryBuilder:
|
169
|
+
"""
|
170
|
+
Add support for paragraph elements.
|
171
|
+
|
172
|
+
Returns:
|
173
|
+
Self for method chaining
|
174
|
+
"""
|
175
|
+
return self.add_element(ParagraphElement)
|
176
|
+
|
177
|
+
def with_headings(self) -> BlockElementRegistryBuilder:
|
178
|
+
"""
|
179
|
+
Add support for heading elements.
|
180
|
+
|
181
|
+
Returns:
|
182
|
+
Self for method chaining
|
183
|
+
"""
|
184
|
+
return self.add_element(HeadingElement)
|
185
|
+
|
186
|
+
def with_callouts(self) -> BlockElementRegistryBuilder:
|
187
|
+
"""
|
188
|
+
Add support for callout elements.
|
189
|
+
|
190
|
+
Returns:
|
191
|
+
Self for method chaining
|
192
|
+
"""
|
193
|
+
return self.add_element(CalloutElement)
|
194
|
+
|
195
|
+
def with_code(self) -> BlockElementRegistryBuilder:
|
196
|
+
"""
|
197
|
+
Add support for code blocks.
|
198
|
+
|
199
|
+
Returns:
|
200
|
+
Self for method chaining
|
201
|
+
"""
|
202
|
+
return self.add_element(CodeBlockElement)
|
203
|
+
|
204
|
+
def with_dividers(self) -> BlockElementRegistryBuilder:
|
205
|
+
"""
|
206
|
+
Add support for divider elements.
|
207
|
+
|
208
|
+
Returns:
|
209
|
+
Self for method chaining
|
210
|
+
"""
|
211
|
+
return self.add_element(DividerElement)
|
212
|
+
|
213
|
+
def with_tables(self) -> BlockElementRegistryBuilder:
|
214
|
+
"""
|
215
|
+
Add support for tables.
|
216
|
+
|
217
|
+
Returns:
|
218
|
+
Self for method chaining
|
219
|
+
"""
|
220
|
+
return self.add_element(TableElement)
|
221
|
+
|
222
|
+
def with_columns(self) -> BlockElementRegistryBuilder:
|
223
|
+
"""
|
224
|
+
Add support for column elements.
|
225
|
+
|
226
|
+
Returns:
|
227
|
+
Self for method chaining
|
228
|
+
"""
|
229
|
+
return self.add_element(ColumnElement)
|
230
|
+
|
231
|
+
def with_lists(self) -> BlockElementRegistryBuilder:
|
232
|
+
"""
|
233
|
+
Add support for list elements.
|
234
|
+
|
235
|
+
Returns:
|
236
|
+
Self for method chaining
|
237
|
+
"""
|
238
|
+
return self.add_element(BulletedListElement).add_element(NumberedListElement)
|
239
|
+
|
240
|
+
def with_toggles(self) -> BlockElementRegistryBuilder:
|
241
|
+
"""
|
242
|
+
Add support for toggle elements.
|
243
|
+
|
244
|
+
Returns:
|
245
|
+
Self for method chaining
|
246
|
+
"""
|
247
|
+
return self.add_element(ToggleElement)
|
248
|
+
|
249
|
+
def with_quotes(self) -> BlockElementRegistryBuilder:
|
250
|
+
"""
|
251
|
+
Add support for quote elements.
|
252
|
+
|
253
|
+
Returns:
|
254
|
+
Self for method chaining
|
255
|
+
"""
|
256
|
+
return self.add_element(QuoteElement)
|
257
|
+
|
258
|
+
def with_todos(self) -> BlockElementRegistryBuilder:
|
259
|
+
"""
|
260
|
+
Add support for todo elements.
|
261
|
+
|
262
|
+
Returns:
|
263
|
+
Self for method chaining
|
264
|
+
"""
|
265
|
+
return self.add_element(TodoElement)
|
266
|
+
|
267
|
+
def with_bookmarks(self) -> BlockElementRegistryBuilder:
|
268
|
+
"""
|
269
|
+
Add support for bookmark elements.
|
270
|
+
|
271
|
+
Returns:
|
272
|
+
Self for method chaining
|
273
|
+
"""
|
274
|
+
return self.add_element(BookmarkElement)
|
275
|
+
|
276
|
+
def with_images(self) -> BlockElementRegistryBuilder:
|
277
|
+
"""
|
278
|
+
Add support for image elements.
|
279
|
+
|
280
|
+
Returns:
|
281
|
+
Self for method chaining
|
282
|
+
"""
|
283
|
+
return self.add_element(ImageElement)
|
284
|
+
|
285
|
+
def with_videos(self) -> BlockElementRegistryBuilder:
|
286
|
+
"""
|
287
|
+
Add support for video elements.
|
288
|
+
|
289
|
+
Returns:
|
290
|
+
Self for method chaining
|
291
|
+
"""
|
292
|
+
return self.add_element(VideoElement)
|
293
|
+
|
294
|
+
def with_embeds(self) -> BlockElementRegistryBuilder:
|
295
|
+
"""
|
296
|
+
Add support for embed elements.
|
297
|
+
|
298
|
+
Returns:
|
299
|
+
Self for method chaining
|
300
|
+
"""
|
301
|
+
return self.add_element(EmbedElement)
|
302
|
+
|
303
|
+
def with_audio(self) -> BlockElementRegistryBuilder:
|
304
|
+
"""
|
305
|
+
Add support for audio elements.
|
306
|
+
|
307
|
+
Returns:
|
308
|
+
Self for method chaining
|
309
|
+
"""
|
310
|
+
return self.add_element(AudioElement)
|
311
|
+
|
312
|
+
def with_media_support(self) -> BlockElementRegistryBuilder:
|
313
|
+
"""
|
314
|
+
Add support for media elements (images, videos, audio).
|
315
|
+
|
316
|
+
Returns:
|
317
|
+
Self for method chaining
|
318
|
+
"""
|
319
|
+
return self.with_images().with_videos().with_audio()
|
320
|
+
|
321
|
+
def with_mention(self) -> BlockElementRegistryBuilder:
|
322
|
+
return self.add_element(MentionElement)
|
323
|
+
|
324
|
+
def build(self) -> BlockElementRegistry:
|
325
|
+
"""
|
326
|
+
Build and return the configured BlockElementRegistry instance.
|
327
|
+
|
328
|
+
This automatically ensures that ParagraphElement is at the end
|
329
|
+
of the registry (if present) as a fallback element, unless
|
330
|
+
this behavior was explicitly disabled.
|
331
|
+
|
332
|
+
Returns:
|
333
|
+
A configured BlockElementRegistry instance
|
334
|
+
"""
|
335
|
+
if ParagraphElement.__name__ not in self._elements:
|
336
|
+
# Add paragraph as fallback if not present
|
337
|
+
self.add_element(ParagraphElement)
|
338
|
+
else:
|
339
|
+
# Ensure it's at the end
|
340
|
+
self._ensure_paragraph_at_end()
|
341
|
+
|
342
|
+
registry = BlockElementRegistry()
|
343
|
+
|
344
|
+
# Add elements in the recorded order
|
345
|
+
for element_class in self._elements.values():
|
346
|
+
registry.register(element_class)
|
347
|
+
|
348
|
+
return registry
|
349
|
+
|
350
|
+
@classmethod
|
351
|
+
def create_standard_registry(cls) -> BlockElementRegistry:
|
352
|
+
"""
|
353
|
+
Factory method to directly create a standard registry.
|
354
|
+
|
355
|
+
Returns:
|
356
|
+
A fully configured registry instance
|
357
|
+
"""
|
358
|
+
return cls.start_standard().build()
|
359
|
+
|
360
|
+
@classmethod
|
361
|
+
def create_minimal_registry(cls) -> BlockElementRegistry:
|
362
|
+
"""
|
363
|
+
Factory method to directly create a minimal registry.
|
364
|
+
|
365
|
+
Returns:
|
366
|
+
A minimal registry instance
|
367
|
+
"""
|
368
|
+
return cls.start_minimal().build()
|
369
|
+
|
370
|
+
@classmethod
|
371
|
+
def create_custom_registry(
|
372
|
+
cls, element_classes: List[Type[NotionBlockElement]]
|
373
|
+
) -> BlockElementRegistry:
|
374
|
+
"""
|
375
|
+
Factory method to directly create a custom registry.
|
376
|
+
|
377
|
+
Args:
|
378
|
+
element_classes: List of element classes to register
|
379
|
+
|
380
|
+
Returns:
|
381
|
+
A custom configured registry instance
|
382
|
+
"""
|
383
|
+
return cls().add_elements(element_classes).build()
|
@@ -2,7 +2,7 @@ import re
|
|
2
2
|
from typing import Dict, Any, Optional, List, Tuple
|
3
3
|
from typing_extensions import override
|
4
4
|
|
5
|
-
from notionary.
|
5
|
+
from notionary.elements.notion_block_element import NotionBlockElement
|
6
6
|
|
7
7
|
|
8
8
|
class BookmarkElement(NotionBlockElement):
|
@@ -2,8 +2,8 @@ from typing import Dict, Any, Optional
|
|
2
2
|
from typing_extensions import override
|
3
3
|
import re
|
4
4
|
|
5
|
-
from notionary.
|
6
|
-
from notionary.
|
5
|
+
from notionary.elements.text_inline_formatter import TextInlineFormatter
|
6
|
+
from notionary.elements.notion_block_element import NotionBlockElement
|
7
7
|
|
8
8
|
|
9
9
|
class CalloutElement(NotionBlockElement):
|
@@ -1,7 +1,7 @@
|
|
1
1
|
from typing import Dict, Any, Optional, List, Tuple
|
2
2
|
from typing_extensions import override
|
3
3
|
import re
|
4
|
-
from notionary.
|
4
|
+
from notionary.elements.notion_block_element import NotionBlockElement
|
5
5
|
|
6
6
|
|
7
7
|
class CodeBlockElement(NotionBlockElement):
|
@@ -2,7 +2,7 @@ import re
|
|
2
2
|
from typing import Dict, Any, Optional, List, Tuple, Callable
|
3
3
|
from typing_extensions import override
|
4
4
|
|
5
|
-
from notionary.
|
5
|
+
from notionary.elements.notion_block_element import NotionBlockElement
|
6
6
|
|
7
7
|
|
8
8
|
class ColumnElement(NotionBlockElement):
|
@@ -4,7 +4,7 @@ from typing import Dict, Any, Optional
|
|
4
4
|
from typing_extensions import override
|
5
5
|
import re
|
6
6
|
|
7
|
-
from notionary.
|
7
|
+
from notionary.elements.notion_block_element import NotionBlockElement
|
8
8
|
|
9
9
|
|
10
10
|
class DividerElement(NotionBlockElement):
|
@@ -2,8 +2,8 @@ from typing import Dict, Any, Optional
|
|
2
2
|
from typing_extensions import override
|
3
3
|
import re
|
4
4
|
|
5
|
-
from notionary.
|
6
|
-
from notionary.
|
5
|
+
from notionary.elements.notion_block_element import NotionBlockElement
|
6
|
+
from notionary.elements.text_inline_formatter import TextInlineFormatter
|
7
7
|
|
8
8
|
|
9
9
|
class HeadingElement(NotionBlockElement):
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import re
|
2
2
|
from typing import Dict, Any, Optional, List
|
3
3
|
from typing_extensions import override
|
4
|
-
from notionary.
|
4
|
+
from notionary.elements.notion_block_element import NotionBlockElement
|
5
5
|
|
6
6
|
|
7
7
|
class ImageElement(NotionBlockElement):
|
@@ -1,8 +1,8 @@
|
|
1
1
|
import re
|
2
2
|
from typing import Dict, Any, Optional
|
3
3
|
from typing_extensions import override
|
4
|
-
from notionary.
|
5
|
-
from notionary.
|
4
|
+
from notionary.elements.notion_block_element import NotionBlockElement
|
5
|
+
from notionary.elements.text_inline_formatter import TextInlineFormatter
|
6
6
|
|
7
7
|
|
8
8
|
class BulletedListElement(NotionBlockElement):
|