notionary 0.2.18__py3-none-any.whl → 0.2.21__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 +8 -4
- notionary/base_notion_client.py +3 -1
- notionary/blocks/__init__.py +2 -91
- notionary/blocks/_bootstrap.py +263 -0
- notionary/blocks/audio/__init__.py +8 -2
- notionary/blocks/audio/audio_element.py +42 -104
- notionary/blocks/audio/audio_markdown_node.py +3 -1
- notionary/blocks/audio/audio_models.py +6 -55
- notionary/blocks/base_block_element.py +30 -0
- notionary/blocks/bookmark/__init__.py +9 -2
- notionary/blocks/bookmark/bookmark_element.py +46 -139
- notionary/blocks/bookmark/bookmark_markdown_node.py +3 -1
- notionary/blocks/bookmark/bookmark_models.py +15 -0
- notionary/blocks/breadcrumbs/__init__.py +17 -0
- notionary/blocks/breadcrumbs/breadcrumb_element.py +39 -0
- notionary/blocks/breadcrumbs/breadcrumb_markdown_node.py +32 -0
- notionary/blocks/breadcrumbs/breadcrumb_models.py +12 -0
- notionary/blocks/bulleted_list/__init__.py +12 -2
- notionary/blocks/bulleted_list/bulleted_list_element.py +40 -55
- notionary/blocks/bulleted_list/bulleted_list_markdown_node.py +2 -1
- notionary/blocks/bulleted_list/bulleted_list_models.py +18 -0
- notionary/blocks/callout/__init__.py +9 -2
- notionary/blocks/callout/callout_element.py +40 -89
- notionary/blocks/callout/callout_markdown_node.py +3 -1
- notionary/blocks/callout/callout_models.py +33 -0
- notionary/blocks/child_database/__init__.py +7 -0
- notionary/blocks/child_database/child_database_models.py +19 -0
- notionary/blocks/child_page/__init__.py +9 -0
- notionary/blocks/child_page/child_page_models.py +12 -0
- notionary/blocks/{shared/block_client.py → client.py} +55 -54
- notionary/blocks/code/__init__.py +6 -2
- notionary/blocks/code/code_element.py +53 -187
- notionary/blocks/code/code_markdown_node.py +13 -13
- notionary/blocks/code/code_models.py +94 -0
- notionary/blocks/column/__init__.py +25 -1
- notionary/blocks/column/column_element.py +40 -314
- notionary/blocks/column/column_list_element.py +37 -0
- notionary/blocks/column/column_list_markdown_node.py +50 -0
- notionary/blocks/column/column_markdown_node.py +59 -0
- notionary/blocks/column/column_models.py +26 -0
- notionary/blocks/divider/__init__.py +9 -2
- notionary/blocks/divider/divider_element.py +26 -49
- notionary/blocks/divider/divider_markdown_node.py +2 -1
- notionary/blocks/divider/divider_models.py +12 -0
- notionary/blocks/embed/__init__.py +9 -2
- notionary/blocks/embed/embed_element.py +47 -114
- notionary/blocks/embed/embed_markdown_node.py +3 -1
- notionary/blocks/embed/embed_models.py +14 -0
- notionary/blocks/equation/__init__.py +14 -0
- notionary/blocks/equation/equation_element.py +80 -0
- notionary/blocks/equation/equation_element_markdown_node.py +36 -0
- notionary/blocks/equation/equation_models.py +11 -0
- notionary/blocks/file/__init__.py +25 -0
- notionary/blocks/file/file_element.py +93 -0
- notionary/blocks/file/file_element_markdown_node.py +35 -0
- notionary/blocks/file/file_element_models.py +39 -0
- notionary/blocks/heading/__init__.py +16 -2
- notionary/blocks/heading/heading_element.py +67 -72
- notionary/blocks/heading/heading_markdown_node.py +2 -1
- notionary/blocks/heading/heading_models.py +29 -0
- notionary/blocks/image_block/__init__.py +13 -0
- notionary/blocks/image_block/image_element.py +84 -0
- notionary/blocks/{image → image_block}/image_markdown_node.py +3 -1
- notionary/blocks/image_block/image_models.py +10 -0
- notionary/blocks/models.py +172 -0
- notionary/blocks/numbered_list/__init__.py +12 -2
- notionary/blocks/numbered_list/numbered_list_element.py +33 -58
- notionary/blocks/numbered_list/numbered_list_markdown_node.py +3 -1
- notionary/blocks/numbered_list/numbered_list_models.py +17 -0
- notionary/blocks/paragraph/__init__.py +12 -2
- notionary/blocks/paragraph/paragraph_element.py +27 -69
- notionary/blocks/paragraph/paragraph_markdown_node.py +2 -1
- notionary/blocks/paragraph/paragraph_models.py +16 -0
- notionary/blocks/pdf/__init__.py +13 -0
- notionary/blocks/pdf/pdf_element.py +91 -0
- notionary/blocks/pdf/pdf_markdown_node.py +35 -0
- notionary/blocks/pdf/pdf_models.py +11 -0
- notionary/blocks/quote/__init__.py +11 -2
- notionary/blocks/quote/quote_element.py +31 -65
- notionary/blocks/quote/quote_markdown_node.py +4 -1
- notionary/blocks/quote/quote_models.py +18 -0
- notionary/blocks/registry/__init__.py +4 -0
- notionary/blocks/registry/block_registry.py +75 -91
- notionary/blocks/registry/block_registry_builder.py +107 -59
- notionary/blocks/rich_text/__init__.py +33 -0
- notionary/blocks/rich_text/rich_text_models.py +188 -0
- notionary/blocks/rich_text/text_inline_formatter.py +125 -0
- notionary/blocks/table/__init__.py +16 -2
- notionary/blocks/table/table_element.py +48 -241
- notionary/blocks/table/table_markdown_node.py +2 -1
- notionary/blocks/table/table_models.py +28 -0
- notionary/blocks/table_of_contents/__init__.py +19 -0
- notionary/blocks/table_of_contents/table_of_contents_element.py +51 -0
- notionary/blocks/table_of_contents/table_of_contents_markdown_node.py +35 -0
- notionary/blocks/table_of_contents/table_of_contents_models.py +18 -0
- notionary/blocks/todo/__init__.py +9 -2
- notionary/blocks/todo/todo_element.py +38 -95
- notionary/blocks/todo/todo_markdown_node.py +2 -1
- notionary/blocks/todo/todo_models.py +19 -0
- notionary/blocks/toggle/__init__.py +13 -3
- notionary/blocks/toggle/toggle_element.py +57 -264
- notionary/blocks/toggle/toggle_markdown_node.py +24 -14
- notionary/blocks/toggle/toggle_models.py +17 -0
- notionary/blocks/toggleable_heading/__init__.py +6 -2
- notionary/blocks/toggleable_heading/toggleable_heading_element.py +74 -244
- notionary/blocks/toggleable_heading/toggleable_heading_markdown_node.py +26 -18
- notionary/blocks/types.py +61 -0
- notionary/blocks/video/__init__.py +8 -2
- notionary/blocks/video/video_element.py +67 -143
- notionary/blocks/video/video_element_models.py +10 -0
- notionary/blocks/video/video_markdown_node.py +3 -1
- notionary/database/client.py +3 -8
- notionary/database/database.py +13 -14
- notionary/database/database_filter_builder.py +2 -2
- notionary/database/database_provider.py +5 -4
- notionary/database/models.py +337 -0
- notionary/database/notion_database.py +6 -7
- notionary/file_upload/client.py +5 -7
- notionary/file_upload/models.py +2 -1
- notionary/file_upload/notion_file_upload.py +2 -3
- notionary/markdown/markdown_builder.py +722 -0
- notionary/markdown/markdown_document_model.py +228 -0
- notionary/{blocks → markdown}/markdown_node.py +1 -0
- notionary/models/notion_database_response.py +0 -338
- notionary/page/client.py +9 -10
- notionary/page/models.py +327 -0
- notionary/page/notion_page.py +99 -52
- notionary/page/notion_text_length_utils.py +119 -0
- notionary/page/{content/page_content_writer.py → page_content_writer.py} +88 -38
- notionary/page/reader/handler/__init__.py +17 -0
- notionary/page/reader/handler/base_block_renderer.py +44 -0
- notionary/page/reader/handler/block_processing_context.py +35 -0
- notionary/page/reader/handler/block_rendering_context.py +43 -0
- notionary/page/reader/handler/column_list_renderer.py +51 -0
- notionary/page/reader/handler/column_renderer.py +60 -0
- notionary/page/reader/handler/line_renderer.py +60 -0
- notionary/page/reader/handler/toggle_renderer.py +69 -0
- notionary/page/reader/handler/toggleable_heading_renderer.py +89 -0
- notionary/page/reader/page_content_retriever.py +69 -0
- notionary/page/search_filter_builder.py +2 -1
- notionary/page/writer/handler/__init__.py +22 -0
- notionary/page/writer/handler/code_handler.py +100 -0
- notionary/page/writer/handler/column_handler.py +141 -0
- notionary/page/writer/handler/column_list_handler.py +139 -0
- notionary/page/writer/handler/line_handler.py +35 -0
- notionary/page/writer/handler/line_processing_context.py +54 -0
- notionary/page/writer/handler/regular_line_handler.py +92 -0
- notionary/page/writer/handler/table_handler.py +130 -0
- notionary/page/writer/handler/toggle_handler.py +153 -0
- notionary/page/writer/handler/toggleable_heading_handler.py +167 -0
- notionary/page/writer/markdown_to_notion_converter.py +76 -0
- notionary/telemetry/__init__.py +2 -2
- notionary/telemetry/service.py +4 -3
- notionary/user/__init__.py +2 -2
- notionary/user/base_notion_user.py +2 -1
- notionary/user/client.py +2 -3
- notionary/user/models.py +1 -0
- notionary/user/notion_bot_user.py +4 -5
- notionary/user/notion_user.py +3 -4
- notionary/user/notion_user_manager.py +3 -2
- notionary/user/notion_user_provider.py +1 -1
- notionary/util/__init__.py +3 -2
- notionary/util/fuzzy.py +2 -1
- notionary/util/logging_mixin.py +2 -2
- notionary/util/singleton_metaclass.py +1 -1
- notionary/workspace.py +3 -2
- {notionary-0.2.18.dist-info → notionary-0.2.21.dist-info}/METADATA +12 -8
- notionary-0.2.21.dist-info/RECORD +185 -0
- notionary/blocks/document/__init__.py +0 -7
- notionary/blocks/document/document_element.py +0 -102
- notionary/blocks/document/document_markdown_node.py +0 -31
- notionary/blocks/image/__init__.py +0 -7
- notionary/blocks/image/image_element.py +0 -151
- notionary/blocks/markdown_builder.py +0 -356
- notionary/blocks/mention/__init__.py +0 -7
- notionary/blocks/mention/mention_element.py +0 -229
- notionary/blocks/mention/mention_markdown_node.py +0 -38
- notionary/blocks/prompts/element_prompt_builder.py +0 -83
- notionary/blocks/prompts/element_prompt_content.py +0 -41
- notionary/blocks/shared/__init__.py +0 -0
- notionary/blocks/shared/models.py +0 -710
- notionary/blocks/shared/notion_block_element.py +0 -37
- notionary/blocks/shared/text_inline_formatter.py +0 -262
- notionary/blocks/shared/text_inline_formatter_new.py +0 -139
- notionary/blocks/toggleable_heading/toggleable_heading_models.py +0 -0
- notionary/database/models/page_result.py +0 -10
- notionary/models/notion_block_response.py +0 -264
- notionary/models/notion_page_response.py +0 -78
- notionary/models/search_response.py +0 -0
- notionary/page/__init__.py +0 -0
- notionary/page/content/notion_text_length_utils.py +0 -87
- notionary/page/content/page_content_retriever.py +0 -52
- notionary/page/formatting/line_processor.py +0 -153
- notionary/page/formatting/markdown_to_notion_converter.py +0 -153
- notionary/page/markdown_syntax_prompt_generator.py +0 -114
- notionary/page/notion_to_markdown_converter.py +0 -179
- notionary/page/properites/property_value_extractor.py +0 -0
- notionary-0.2.18.dist-info/RECORD +0 -149
- /notionary/{blocks/document/document_models.py → markdown/___init__.py} +0 -0
- /notionary/{blocks/image/image_models.py → markdown/makdown_document_model.py} +0 -0
- /notionary/page/{content/markdown_whitespace_processor.py → markdown_whitespace_processor.py} +0 -0
- /notionary/{blocks/mention/mention_models.py → page/reader/handler/context.py} +0 -0
- {notionary-0.2.18.dist-info → notionary-0.2.21.dist-info}/LICENSE +0 -0
- {notionary-0.2.18.dist-info → notionary-0.2.21.dist-info}/WHEEL +0 -0
@@ -1,102 +1,105 @@
|
|
1
1
|
from __future__ import annotations
|
2
|
-
from typing import Dict, Any, Optional, List, Set, Type
|
3
2
|
|
4
|
-
from
|
5
|
-
from notionary.page.markdown_syntax_prompt_generator import (
|
6
|
-
MarkdownSyntaxPromptGenerator,
|
7
|
-
)
|
8
|
-
from notionary.blocks import TextInlineFormatter
|
3
|
+
from typing import Optional, Type
|
9
4
|
|
10
|
-
from notionary.blocks import
|
5
|
+
from notionary.blocks.base_block_element import BaseBlockElement
|
6
|
+
from notionary.blocks.models import Block, BlockCreateResult
|
7
|
+
from notionary.blocks.registry.block_registry_builder import BlockRegistryBuilder
|
11
8
|
from notionary.telemetry import (
|
12
|
-
ProductTelemetry,
|
13
|
-
NotionMarkdownSyntaxPromptEvent,
|
14
9
|
MarkdownToNotionConversionEvent,
|
15
10
|
NotionToMarkdownConversionEvent,
|
11
|
+
ProductTelemetry,
|
16
12
|
)
|
17
13
|
|
18
14
|
|
19
15
|
class BlockRegistry:
|
20
16
|
"""Registry of elements that can convert between Markdown and Notion."""
|
21
17
|
|
22
|
-
def __init__(self,
|
18
|
+
def __init__(self, builder: Optional[BlockRegistryBuilder] = None):
|
23
19
|
"""
|
24
20
|
Initialize a new registry instance.
|
25
21
|
|
26
22
|
Args:
|
27
|
-
|
23
|
+
builder: BlockRegistryBuilder instance to delegate operations to
|
28
24
|
"""
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
for element in elements:
|
34
|
-
self.register(element)
|
25
|
+
# Import here to avoid circular imports
|
26
|
+
from notionary.blocks.registry.block_registry_builder import (
|
27
|
+
BlockRegistryBuilder,
|
28
|
+
)
|
35
29
|
|
30
|
+
self._builder: BlockRegistryBuilder = builder or BlockRegistryBuilder()
|
36
31
|
self.telemetry = ProductTelemetry()
|
37
32
|
|
38
33
|
@classmethod
|
39
34
|
def create_registry(cls) -> BlockRegistry:
|
40
35
|
"""
|
41
36
|
Create a registry with all standard elements in recommended order.
|
42
|
-
|
43
|
-
This uses the BlockRegistryBuilder internally to construct a complete
|
44
|
-
registry with all available block types.
|
45
|
-
|
46
|
-
Returns:
|
47
|
-
BlockRegistry: A fully configured registry with all standard elements
|
48
37
|
"""
|
49
|
-
from notionary.blocks import
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
38
|
+
from notionary.blocks.registry.block_registry_builder import (
|
39
|
+
BlockRegistryBuilder,
|
40
|
+
)
|
41
|
+
|
42
|
+
builder = BlockRegistryBuilder()
|
43
|
+
builder = (
|
44
|
+
builder.with_headings()
|
45
|
+
.with_callouts()
|
46
|
+
.with_code()
|
47
|
+
.with_dividers()
|
48
|
+
.with_tables()
|
49
|
+
.with_bulleted_list()
|
50
|
+
.with_numbered_list()
|
51
|
+
.with_toggles()
|
52
|
+
.with_toggleable_heading_element()
|
53
|
+
.with_quotes()
|
54
|
+
.with_todos()
|
55
|
+
.with_bookmarks()
|
56
|
+
.with_images()
|
57
|
+
.with_videos()
|
58
|
+
.with_embeds()
|
59
|
+
.with_audio()
|
60
|
+
.with_columns()
|
61
|
+
.with_equation()
|
62
|
+
.with_table_of_contents()
|
63
|
+
.with_breadcrumbs()
|
64
|
+
.with_paragraphs() # position here is important - its a fallback!
|
65
|
+
)
|
66
|
+
|
67
|
+
return cls(builder=builder)
|
68
|
+
|
69
|
+
@property
|
70
|
+
def builder(self) -> BlockRegistryBuilder:
|
71
|
+
return self._builder
|
72
|
+
|
73
|
+
def register(self, element_class: Type[BaseBlockElement]) -> bool:
|
54
74
|
"""
|
55
|
-
Register an element class.
|
56
|
-
|
57
|
-
Args:
|
58
|
-
element_class: The element class to register
|
59
|
-
|
60
|
-
Returns:
|
61
|
-
bool: True if element was added, False if it already existed
|
75
|
+
Register an element class via builder.
|
62
76
|
"""
|
63
|
-
|
64
|
-
|
77
|
+
initial_count = len(self._builder._elements)
|
78
|
+
self._builder._add_element(element_class)
|
79
|
+
return len(self._builder._elements) > initial_count
|
65
80
|
|
66
|
-
|
67
|
-
self._element_types.add(element_class)
|
68
|
-
return True
|
69
|
-
|
70
|
-
def deregister(self, element_class: Type[NotionBlockElement]) -> bool:
|
81
|
+
def deregister(self, element_class: Type[BaseBlockElement]) -> bool:
|
71
82
|
"""
|
72
|
-
Deregister an element class.
|
83
|
+
Deregister an element class via builder.
|
73
84
|
"""
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
return True
|
78
|
-
return False
|
85
|
+
initial_count = len(self._builder._elements)
|
86
|
+
self._builder.remove_element(element_class)
|
87
|
+
return len(self._builder._elements) < initial_count
|
79
88
|
|
80
|
-
def contains(self, element_class: Type[
|
89
|
+
def contains(self, element_class: Type[BaseBlockElement]) -> bool:
|
81
90
|
"""
|
82
91
|
Checks if a specific element is contained in the registry.
|
83
|
-
|
84
|
-
Args:
|
85
|
-
element_class: The element class to check.
|
86
|
-
|
87
|
-
Returns:
|
88
|
-
bool: True if the element is contained, otherwise False.
|
89
92
|
"""
|
90
|
-
return element_class in self._elements
|
93
|
+
return element_class.__name__ in self._builder._elements
|
91
94
|
|
92
|
-
def find_markdown_handler(self, text: str) -> Optional[Type[
|
95
|
+
def find_markdown_handler(self, text: str) -> Optional[Type[BaseBlockElement]]:
|
93
96
|
"""Find an element that can handle the given markdown text."""
|
94
|
-
for element in self._elements:
|
97
|
+
for element in self._builder._elements.values():
|
95
98
|
if element.match_markdown(text):
|
96
99
|
return element
|
97
100
|
return None
|
98
101
|
|
99
|
-
def markdown_to_notion(self, text: str) ->
|
102
|
+
def markdown_to_notion(self, text: str) -> "BlockCreateResult":
|
100
103
|
"""Convert markdown to Notion block using registered elements."""
|
101
104
|
handler = self.find_markdown_handler(text)
|
102
105
|
|
@@ -110,47 +113,28 @@ class BlockRegistry:
|
|
110
113
|
return handler.markdown_to_notion(text)
|
111
114
|
return None
|
112
115
|
|
113
|
-
def notion_to_markdown(self, block:
|
116
|
+
def notion_to_markdown(self, block: "Block") -> Optional[str]:
|
114
117
|
"""Convert Notion block to markdown using registered elements."""
|
115
118
|
handler = self._find_notion_handler(block)
|
116
119
|
|
117
|
-
if handler:
|
118
|
-
|
119
|
-
NotionToMarkdownConversionEvent(
|
120
|
-
handler_element_name=handler.__name__,
|
121
|
-
)
|
122
|
-
)
|
120
|
+
if not handler:
|
121
|
+
return None
|
123
122
|
|
124
|
-
|
125
|
-
|
123
|
+
self.telemetry.capture(
|
124
|
+
NotionToMarkdownConversionEvent(
|
125
|
+
handler_element_name=handler.__name__,
|
126
|
+
)
|
127
|
+
)
|
126
128
|
|
127
|
-
|
128
|
-
"""Get all registered multiline elements."""
|
129
|
-
return [element for element in self._elements if element.is_multiline()]
|
129
|
+
return handler.notion_to_markdown(block)
|
130
130
|
|
131
|
-
def get_elements(self) ->
|
131
|
+
def get_elements(self) -> list[Type[BaseBlockElement]]:
|
132
132
|
"""Get all registered elements."""
|
133
|
-
return self._elements.
|
134
|
-
|
135
|
-
def get_notion_markdown_syntax_prompt(self) -> str:
|
136
|
-
"""
|
137
|
-
Generates an LLM system prompt that describes the Markdown syntax of all registered elements.
|
138
|
-
"""
|
139
|
-
element_classes = self._elements.copy()
|
140
|
-
|
141
|
-
formatter_names = [e.__name__ for e in element_classes]
|
142
|
-
if "TextInlineFormatter" not in formatter_names:
|
143
|
-
element_classes = element_classes + [TextInlineFormatter]
|
144
|
-
|
145
|
-
self.telemetry.capture(NotionMarkdownSyntaxPromptEvent())
|
146
|
-
|
147
|
-
return MarkdownSyntaxPromptGenerator.generate_system_prompt(element_classes)
|
133
|
+
return list(self._builder._elements.values())
|
148
134
|
|
149
|
-
def _find_notion_handler(
|
150
|
-
self, block: Dict[str, Any]
|
151
|
-
) -> Optional[Type[NotionBlockElement]]:
|
135
|
+
def _find_notion_handler(self, block: Block) -> Optional[Type[BaseBlockElement]]:
|
152
136
|
"""Find an element that can handle the given Notion block."""
|
153
|
-
for element in self._elements:
|
137
|
+
for element in self._builder._elements.values():
|
154
138
|
if element.match_notion(block):
|
155
139
|
return element
|
156
140
|
return None
|
@@ -1,32 +1,33 @@
|
|
1
1
|
from __future__ import annotations
|
2
|
-
from typing import Type, TYPE_CHECKING, Self
|
3
|
-
from collections import OrderedDict
|
4
2
|
|
5
|
-
from
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
3
|
+
from collections import OrderedDict
|
4
|
+
from typing import TYPE_CHECKING, Self, Type
|
5
|
+
|
6
|
+
from notionary.blocks.audio import AudioElement
|
7
|
+
from notionary.blocks.base_block_element import BaseBlockElement
|
8
|
+
from notionary.blocks.bookmark import BookmarkElement
|
9
|
+
from notionary.blocks.breadcrumbs import BreadcrumbElement
|
10
|
+
from notionary.blocks.bulleted_list import BulletedListElement
|
11
|
+
from notionary.blocks.callout import CalloutElement
|
12
|
+
from notionary.blocks.code import CodeElement
|
13
|
+
from notionary.blocks.column import ColumnElement, ColumnListElement
|
14
|
+
from notionary.blocks.divider import DividerElement
|
15
|
+
from notionary.blocks.embed import EmbedElement
|
16
|
+
from notionary.blocks.equation import EquationElement
|
17
|
+
from notionary.blocks.heading import HeadingElement
|
18
|
+
from notionary.blocks.image_block import ImageElement
|
19
|
+
from notionary.blocks.numbered_list import NumberedListElement
|
20
|
+
from notionary.blocks.paragraph import ParagraphElement
|
21
|
+
from notionary.blocks.quote import QuoteElement
|
22
|
+
from notionary.blocks.table import TableElement
|
23
|
+
from notionary.blocks.table_of_contents import TableOfContentsElement
|
24
|
+
from notionary.blocks.todo import TodoElement
|
25
|
+
from notionary.blocks.toggle import ToggleElement
|
26
|
+
from notionary.blocks.toggleable_heading import ToggleableHeadingElement
|
27
|
+
from notionary.blocks.video import VideoElement
|
27
28
|
|
28
29
|
if TYPE_CHECKING:
|
29
|
-
from notionary.blocks import BlockRegistry
|
30
|
+
from notionary.blocks.registry.block_registry import BlockRegistry
|
30
31
|
|
31
32
|
|
32
33
|
class BlockRegistryBuilder:
|
@@ -63,13 +64,15 @@ class BlockRegistryBuilder:
|
|
63
64
|
.with_videos()
|
64
65
|
.with_embeds()
|
65
66
|
.with_audio()
|
66
|
-
.with_columns()
|
67
|
-
.with_mention()
|
68
67
|
.with_paragraphs()
|
69
68
|
.with_toggleable_heading_element()
|
69
|
+
.with_columns()
|
70
|
+
.with_equation()
|
71
|
+
.with_table_of_contents()
|
72
|
+
.with_breadcrumbs()
|
70
73
|
).build()
|
71
74
|
|
72
|
-
def remove_element(self, element_class: Type[
|
75
|
+
def remove_element(self, element_class: Type[BaseBlockElement]) -> Self:
|
73
76
|
"""
|
74
77
|
Remove an element class from the registry configuration.
|
75
78
|
|
@@ -84,92 +87,137 @@ class BlockRegistryBuilder:
|
|
84
87
|
|
85
88
|
# WITH methods (existing)
|
86
89
|
def with_paragraphs(self) -> Self:
|
87
|
-
"""Add support for paragraph elements."""
|
88
90
|
return self._add_element(ParagraphElement)
|
89
91
|
|
90
92
|
def with_headings(self) -> Self:
|
91
|
-
"""Add support for heading elements."""
|
92
93
|
return self._add_element(HeadingElement)
|
93
94
|
|
94
95
|
def with_callouts(self) -> Self:
|
95
|
-
"""Add support for callout elements."""
|
96
96
|
return self._add_element(CalloutElement)
|
97
97
|
|
98
98
|
def with_code(self) -> Self:
|
99
|
-
"""Add support for code blocks."""
|
100
99
|
return self._add_element(CodeElement)
|
101
100
|
|
102
101
|
def with_dividers(self) -> Self:
|
103
|
-
"""Add support for divider elements."""
|
104
102
|
return self._add_element(DividerElement)
|
105
103
|
|
106
104
|
def with_tables(self) -> Self:
|
107
|
-
"""Add support for tables."""
|
108
105
|
return self._add_element(TableElement)
|
109
106
|
|
110
107
|
def with_bulleted_list(self) -> Self:
|
111
|
-
"""Add support for bulleted list elements (unordered lists)."""
|
112
108
|
return self._add_element(BulletedListElement)
|
113
109
|
|
114
110
|
def with_numbered_list(self) -> Self:
|
115
|
-
"""Add support for numbered list elements (ordered lists)."""
|
116
111
|
return self._add_element(NumberedListElement)
|
117
112
|
|
118
113
|
def with_toggles(self) -> Self:
|
119
|
-
"""Add support for toggle elements."""
|
120
114
|
return self._add_element(ToggleElement)
|
121
115
|
|
122
116
|
def with_quotes(self) -> Self:
|
123
|
-
"""Add support for quote elements."""
|
124
117
|
return self._add_element(QuoteElement)
|
125
118
|
|
126
119
|
def with_todos(self) -> Self:
|
127
|
-
"""Add support for todo elements."""
|
128
120
|
return self._add_element(TodoElement)
|
129
121
|
|
130
122
|
def with_bookmarks(self) -> Self:
|
131
|
-
"""Add support for bookmark elements."""
|
132
123
|
return self._add_element(BookmarkElement)
|
133
124
|
|
134
125
|
def with_images(self) -> Self:
|
135
|
-
"""Add support for image elements."""
|
136
126
|
return self._add_element(ImageElement)
|
137
127
|
|
138
128
|
def with_videos(self) -> Self:
|
139
|
-
"""Add support for video elements."""
|
140
129
|
return self._add_element(VideoElement)
|
141
130
|
|
142
131
|
def with_embeds(self) -> Self:
|
143
|
-
"""Add support for embed elements."""
|
144
132
|
return self._add_element(EmbedElement)
|
145
133
|
|
146
134
|
def with_audio(self) -> Self:
|
147
|
-
"""Add support for audio elements."""
|
148
135
|
return self._add_element(AudioElement)
|
149
136
|
|
150
|
-
def with_mention(self) -> Self:
|
151
|
-
"""Add support for mention elements."""
|
152
|
-
return self._add_element(MentionElement)
|
153
|
-
|
154
137
|
def with_toggleable_heading_element(self) -> Self:
|
155
|
-
"""Add support for toggleable heading elements."""
|
156
138
|
return self._add_element(ToggleableHeadingElement)
|
157
139
|
|
158
140
|
def with_columns(self) -> Self:
|
159
|
-
|
160
|
-
|
141
|
+
self._add_element(ColumnListElement)
|
142
|
+
self._add_element(ColumnElement)
|
143
|
+
return self
|
144
|
+
|
145
|
+
def with_equation(self) -> Self:
|
146
|
+
return self._add_element(EquationElement)
|
147
|
+
|
148
|
+
def with_table_of_contents(self) -> Self:
|
149
|
+
return self._add_element(TableOfContentsElement)
|
150
|
+
|
151
|
+
def with_breadcrumbs(self) -> Self:
|
152
|
+
return self._add_element(BreadcrumbElement)
|
153
|
+
|
154
|
+
def without_headings(self) -> Self:
|
155
|
+
return self.remove_element(HeadingElement)
|
156
|
+
|
157
|
+
def without_callouts(self) -> Self:
|
158
|
+
return self.remove_element(CalloutElement)
|
159
|
+
|
160
|
+
def without_code(self) -> Self:
|
161
|
+
return self.remove_element(CodeElement)
|
162
|
+
|
163
|
+
def without_dividers(self) -> Self:
|
164
|
+
return self.remove_element(DividerElement)
|
165
|
+
|
166
|
+
def without_tables(self) -> Self:
|
167
|
+
return self.remove_element(TableElement)
|
168
|
+
|
169
|
+
def without_bulleted_list(self) -> Self:
|
170
|
+
return self.remove_element(BulletedListElement)
|
171
|
+
|
172
|
+
def without_numbered_list(self) -> Self:
|
173
|
+
return self.remove_element(NumberedListElement)
|
174
|
+
|
175
|
+
def without_toggles(self) -> Self:
|
176
|
+
return self.remove_element(ToggleElement)
|
177
|
+
|
178
|
+
def without_quotes(self) -> Self:
|
179
|
+
return self.remove_element(QuoteElement)
|
180
|
+
|
181
|
+
def without_todos(self) -> Self:
|
182
|
+
return self.remove_element(TodoElement)
|
183
|
+
|
184
|
+
def without_bookmarks(self) -> Self:
|
185
|
+
return self.remove_element(BookmarkElement)
|
186
|
+
|
187
|
+
def without_images(self) -> Self:
|
188
|
+
return self.remove_element(ImageElement)
|
189
|
+
|
190
|
+
def without_videos(self) -> Self:
|
191
|
+
return self.remove_element(VideoElement)
|
192
|
+
|
193
|
+
def without_embeds(self) -> Self:
|
194
|
+
return self.remove_element(EmbedElement)
|
195
|
+
|
196
|
+
def without_audio(self) -> Self:
|
197
|
+
return self.remove_element(AudioElement)
|
198
|
+
|
199
|
+
def without_toggleable_heading_element(self) -> Self:
|
200
|
+
return self.remove_element(ToggleableHeadingElement)
|
201
|
+
|
202
|
+
def without_columns(self) -> Self:
|
203
|
+
self.remove_element(ColumnListElement)
|
204
|
+
self.remove_element(ColumnElement)
|
205
|
+
return self
|
206
|
+
|
207
|
+
def without_equation(self) -> Self:
|
208
|
+
return self.remove_element(EquationElement)
|
209
|
+
|
210
|
+
def without_table_of_contents(self) -> Self:
|
211
|
+
return self.remove_element(TableOfContentsElement)
|
212
|
+
|
213
|
+
def without_breadcrumbs(self) -> Self:
|
214
|
+
return self.remove_element(BreadcrumbElement)
|
161
215
|
|
162
216
|
def build(self) -> BlockRegistry:
|
163
217
|
"""
|
164
218
|
Build and return the configured BlockRegistry instance.
|
165
|
-
|
166
|
-
This automatically ensures that ParagraphElement is at the end
|
167
|
-
of the registry as a fallback element.
|
168
|
-
|
169
|
-
Returns:
|
170
|
-
A configured BlockRegistry instance
|
171
219
|
"""
|
172
|
-
from notionary.blocks import BlockRegistry
|
220
|
+
from notionary.blocks.registry.block_registry import BlockRegistry
|
173
221
|
|
174
222
|
# Ensure ParagraphElement is always present and at the end
|
175
223
|
self._ensure_paragraph_at_end()
|
@@ -191,7 +239,7 @@ class BlockRegistryBuilder:
|
|
191
239
|
self._elements.pop(ParagraphElement.__name__, None)
|
192
240
|
self._elements[ParagraphElement.__name__] = ParagraphElement
|
193
241
|
|
194
|
-
def _add_element(self, element_class: Type[
|
242
|
+
def _add_element(self, element_class: Type[BaseBlockElement]) -> Self:
|
195
243
|
"""
|
196
244
|
Add an element class to the registry configuration.
|
197
245
|
If the element already exists, it's moved to the end.
|
@@ -0,0 +1,33 @@
|
|
1
|
+
"""Rich text handling for Notionary."""
|
2
|
+
|
3
|
+
from notionary.blocks.rich_text.rich_text_models import (
|
4
|
+
EquationObject,
|
5
|
+
LinkObject,
|
6
|
+
MentionDatabaseRef,
|
7
|
+
MentionDate,
|
8
|
+
MentionLinkPreview,
|
9
|
+
MentionObject,
|
10
|
+
MentionPageRef,
|
11
|
+
MentionTemplateMention,
|
12
|
+
MentionUserRef,
|
13
|
+
RichTextObject,
|
14
|
+
TextAnnotations,
|
15
|
+
TextContent,
|
16
|
+
)
|
17
|
+
from notionary.blocks.rich_text.text_inline_formatter import TextInlineFormatter
|
18
|
+
|
19
|
+
__all__ = [
|
20
|
+
"RichTextObject",
|
21
|
+
"TextAnnotations",
|
22
|
+
"LinkObject",
|
23
|
+
"TextContent",
|
24
|
+
"EquationObject",
|
25
|
+
"MentionUserRef",
|
26
|
+
"MentionPageRef",
|
27
|
+
"MentionDatabaseRef",
|
28
|
+
"MentionLinkPreview",
|
29
|
+
"MentionDate",
|
30
|
+
"MentionTemplateMention",
|
31
|
+
"MentionObject",
|
32
|
+
"TextInlineFormatter",
|
33
|
+
]
|