notionary 0.2.19__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.
Files changed (205) hide show
  1. notionary/__init__.py +8 -4
  2. notionary/base_notion_client.py +3 -1
  3. notionary/blocks/__init__.py +2 -91
  4. notionary/blocks/_bootstrap.py +263 -0
  5. notionary/blocks/audio/__init__.py +8 -2
  6. notionary/blocks/audio/audio_element.py +42 -104
  7. notionary/blocks/audio/audio_markdown_node.py +3 -1
  8. notionary/blocks/audio/audio_models.py +6 -55
  9. notionary/blocks/base_block_element.py +30 -0
  10. notionary/blocks/bookmark/__init__.py +9 -2
  11. notionary/blocks/bookmark/bookmark_element.py +46 -139
  12. notionary/blocks/bookmark/bookmark_markdown_node.py +3 -1
  13. notionary/blocks/bookmark/bookmark_models.py +15 -0
  14. notionary/blocks/breadcrumbs/__init__.py +17 -0
  15. notionary/blocks/breadcrumbs/breadcrumb_element.py +39 -0
  16. notionary/blocks/breadcrumbs/breadcrumb_markdown_node.py +32 -0
  17. notionary/blocks/breadcrumbs/breadcrumb_models.py +12 -0
  18. notionary/blocks/bulleted_list/__init__.py +12 -2
  19. notionary/blocks/bulleted_list/bulleted_list_element.py +40 -55
  20. notionary/blocks/bulleted_list/bulleted_list_markdown_node.py +2 -1
  21. notionary/blocks/bulleted_list/bulleted_list_models.py +18 -0
  22. notionary/blocks/callout/__init__.py +9 -2
  23. notionary/blocks/callout/callout_element.py +40 -89
  24. notionary/blocks/callout/callout_markdown_node.py +3 -1
  25. notionary/blocks/callout/callout_models.py +33 -0
  26. notionary/blocks/child_database/__init__.py +7 -0
  27. notionary/blocks/child_database/child_database_models.py +19 -0
  28. notionary/blocks/child_page/__init__.py +9 -0
  29. notionary/blocks/child_page/child_page_models.py +12 -0
  30. notionary/blocks/{shared/block_client.py → client.py} +55 -54
  31. notionary/blocks/code/__init__.py +6 -2
  32. notionary/blocks/code/code_element.py +53 -187
  33. notionary/blocks/code/code_markdown_node.py +13 -13
  34. notionary/blocks/code/code_models.py +94 -0
  35. notionary/blocks/column/__init__.py +25 -1
  36. notionary/blocks/column/column_element.py +40 -314
  37. notionary/blocks/column/column_list_element.py +37 -0
  38. notionary/blocks/column/column_list_markdown_node.py +50 -0
  39. notionary/blocks/column/column_markdown_node.py +59 -0
  40. notionary/blocks/column/column_models.py +26 -0
  41. notionary/blocks/divider/__init__.py +9 -2
  42. notionary/blocks/divider/divider_element.py +26 -49
  43. notionary/blocks/divider/divider_markdown_node.py +2 -1
  44. notionary/blocks/divider/divider_models.py +12 -0
  45. notionary/blocks/embed/__init__.py +9 -2
  46. notionary/blocks/embed/embed_element.py +47 -114
  47. notionary/blocks/embed/embed_markdown_node.py +3 -1
  48. notionary/blocks/embed/embed_models.py +14 -0
  49. notionary/blocks/equation/__init__.py +14 -0
  50. notionary/blocks/equation/equation_element.py +80 -0
  51. notionary/blocks/equation/equation_element_markdown_node.py +36 -0
  52. notionary/blocks/equation/equation_models.py +11 -0
  53. notionary/blocks/file/__init__.py +25 -0
  54. notionary/blocks/file/file_element.py +93 -0
  55. notionary/blocks/file/file_element_markdown_node.py +35 -0
  56. notionary/blocks/file/file_element_models.py +39 -0
  57. notionary/blocks/heading/__init__.py +16 -2
  58. notionary/blocks/heading/heading_element.py +67 -72
  59. notionary/blocks/heading/heading_markdown_node.py +2 -1
  60. notionary/blocks/heading/heading_models.py +29 -0
  61. notionary/blocks/image_block/__init__.py +13 -0
  62. notionary/blocks/image_block/image_element.py +84 -0
  63. notionary/blocks/{image → image_block}/image_markdown_node.py +3 -1
  64. notionary/blocks/image_block/image_models.py +10 -0
  65. notionary/blocks/models.py +172 -0
  66. notionary/blocks/numbered_list/__init__.py +12 -2
  67. notionary/blocks/numbered_list/numbered_list_element.py +33 -58
  68. notionary/blocks/numbered_list/numbered_list_markdown_node.py +3 -1
  69. notionary/blocks/numbered_list/numbered_list_models.py +17 -0
  70. notionary/blocks/paragraph/__init__.py +12 -2
  71. notionary/blocks/paragraph/paragraph_element.py +27 -69
  72. notionary/blocks/paragraph/paragraph_markdown_node.py +2 -1
  73. notionary/blocks/paragraph/paragraph_models.py +16 -0
  74. notionary/blocks/pdf/__init__.py +13 -0
  75. notionary/blocks/pdf/pdf_element.py +91 -0
  76. notionary/blocks/pdf/pdf_markdown_node.py +35 -0
  77. notionary/blocks/pdf/pdf_models.py +11 -0
  78. notionary/blocks/quote/__init__.py +11 -2
  79. notionary/blocks/quote/quote_element.py +31 -65
  80. notionary/blocks/quote/quote_markdown_node.py +4 -1
  81. notionary/blocks/quote/quote_models.py +18 -0
  82. notionary/blocks/registry/__init__.py +4 -0
  83. notionary/blocks/registry/block_registry.py +75 -91
  84. notionary/blocks/registry/block_registry_builder.py +107 -59
  85. notionary/blocks/rich_text/__init__.py +33 -0
  86. notionary/blocks/rich_text/rich_text_models.py +188 -0
  87. notionary/blocks/rich_text/text_inline_formatter.py +125 -0
  88. notionary/blocks/table/__init__.py +16 -2
  89. notionary/blocks/table/table_element.py +48 -241
  90. notionary/blocks/table/table_markdown_node.py +2 -1
  91. notionary/blocks/table/table_models.py +28 -0
  92. notionary/blocks/table_of_contents/__init__.py +19 -0
  93. notionary/blocks/table_of_contents/table_of_contents_element.py +51 -0
  94. notionary/blocks/table_of_contents/table_of_contents_markdown_node.py +35 -0
  95. notionary/blocks/table_of_contents/table_of_contents_models.py +18 -0
  96. notionary/blocks/todo/__init__.py +9 -2
  97. notionary/blocks/todo/todo_element.py +38 -95
  98. notionary/blocks/todo/todo_markdown_node.py +2 -1
  99. notionary/blocks/todo/todo_models.py +19 -0
  100. notionary/blocks/toggle/__init__.py +13 -3
  101. notionary/blocks/toggle/toggle_element.py +57 -264
  102. notionary/blocks/toggle/toggle_markdown_node.py +24 -14
  103. notionary/blocks/toggle/toggle_models.py +17 -0
  104. notionary/blocks/toggleable_heading/__init__.py +6 -2
  105. notionary/blocks/toggleable_heading/toggleable_heading_element.py +74 -244
  106. notionary/blocks/toggleable_heading/toggleable_heading_markdown_node.py +26 -18
  107. notionary/blocks/types.py +61 -0
  108. notionary/blocks/video/__init__.py +8 -2
  109. notionary/blocks/video/video_element.py +67 -143
  110. notionary/blocks/video/video_element_models.py +10 -0
  111. notionary/blocks/video/video_markdown_node.py +3 -1
  112. notionary/database/client.py +3 -8
  113. notionary/database/database.py +13 -14
  114. notionary/database/database_filter_builder.py +2 -2
  115. notionary/database/database_provider.py +5 -4
  116. notionary/database/models.py +337 -0
  117. notionary/database/notion_database.py +6 -7
  118. notionary/file_upload/client.py +5 -7
  119. notionary/file_upload/models.py +2 -1
  120. notionary/file_upload/notion_file_upload.py +2 -3
  121. notionary/markdown/markdown_builder.py +722 -0
  122. notionary/markdown/markdown_document_model.py +228 -0
  123. notionary/{blocks → markdown}/markdown_node.py +1 -0
  124. notionary/models/notion_database_response.py +0 -338
  125. notionary/page/client.py +9 -10
  126. notionary/page/models.py +327 -0
  127. notionary/page/notion_page.py +99 -52
  128. notionary/page/notion_text_length_utils.py +119 -0
  129. notionary/page/{content/page_content_writer.py → page_content_writer.py} +88 -38
  130. notionary/page/reader/handler/__init__.py +17 -0
  131. notionary/page/reader/handler/base_block_renderer.py +44 -0
  132. notionary/page/reader/handler/block_processing_context.py +35 -0
  133. notionary/page/reader/handler/block_rendering_context.py +43 -0
  134. notionary/page/reader/handler/column_list_renderer.py +51 -0
  135. notionary/page/reader/handler/column_renderer.py +60 -0
  136. notionary/page/reader/handler/line_renderer.py +60 -0
  137. notionary/page/reader/handler/toggle_renderer.py +69 -0
  138. notionary/page/reader/handler/toggleable_heading_renderer.py +89 -0
  139. notionary/page/reader/page_content_retriever.py +69 -0
  140. notionary/page/search_filter_builder.py +2 -1
  141. notionary/page/writer/handler/__init__.py +22 -0
  142. notionary/page/writer/handler/code_handler.py +100 -0
  143. notionary/page/writer/handler/column_handler.py +141 -0
  144. notionary/page/writer/handler/column_list_handler.py +139 -0
  145. notionary/page/writer/handler/line_handler.py +35 -0
  146. notionary/page/writer/handler/line_processing_context.py +54 -0
  147. notionary/page/writer/handler/regular_line_handler.py +92 -0
  148. notionary/page/writer/handler/table_handler.py +130 -0
  149. notionary/page/writer/handler/toggle_handler.py +153 -0
  150. notionary/page/writer/handler/toggleable_heading_handler.py +167 -0
  151. notionary/page/writer/markdown_to_notion_converter.py +76 -0
  152. notionary/telemetry/__init__.py +2 -2
  153. notionary/telemetry/service.py +4 -3
  154. notionary/user/__init__.py +2 -2
  155. notionary/user/base_notion_user.py +2 -1
  156. notionary/user/client.py +2 -3
  157. notionary/user/models.py +1 -0
  158. notionary/user/notion_bot_user.py +4 -5
  159. notionary/user/notion_user.py +3 -4
  160. notionary/user/notion_user_manager.py +3 -2
  161. notionary/user/notion_user_provider.py +1 -1
  162. notionary/util/__init__.py +3 -2
  163. notionary/util/fuzzy.py +2 -1
  164. notionary/util/logging_mixin.py +2 -2
  165. notionary/util/singleton_metaclass.py +1 -1
  166. notionary/workspace.py +3 -2
  167. {notionary-0.2.19.dist-info → notionary-0.2.21.dist-info}/METADATA +12 -8
  168. notionary-0.2.21.dist-info/RECORD +185 -0
  169. notionary/blocks/document/__init__.py +0 -7
  170. notionary/blocks/document/document_element.py +0 -102
  171. notionary/blocks/document/document_markdown_node.py +0 -31
  172. notionary/blocks/image/__init__.py +0 -7
  173. notionary/blocks/image/image_element.py +0 -151
  174. notionary/blocks/markdown_builder.py +0 -356
  175. notionary/blocks/mention/__init__.py +0 -7
  176. notionary/blocks/mention/mention_element.py +0 -229
  177. notionary/blocks/mention/mention_markdown_node.py +0 -38
  178. notionary/blocks/prompts/element_prompt_builder.py +0 -83
  179. notionary/blocks/prompts/element_prompt_content.py +0 -41
  180. notionary/blocks/shared/__init__.py +0 -0
  181. notionary/blocks/shared/models.py +0 -713
  182. notionary/blocks/shared/notion_block_element.py +0 -37
  183. notionary/blocks/shared/text_inline_formatter.py +0 -262
  184. notionary/blocks/shared/text_inline_formatter_new.py +0 -139
  185. notionary/blocks/toggleable_heading/toggleable_heading_models.py +0 -0
  186. notionary/database/models/page_result.py +0 -10
  187. notionary/elements/__init__.py +0 -0
  188. notionary/models/notion_block_response.py +0 -264
  189. notionary/models/notion_page_response.py +0 -78
  190. notionary/models/search_response.py +0 -0
  191. notionary/page/__init__.py +0 -0
  192. notionary/page/content/notion_text_length_utils.py +0 -87
  193. notionary/page/content/page_content_retriever.py +0 -60
  194. notionary/page/formatting/line_processor.py +0 -153
  195. notionary/page/formatting/markdown_to_notion_converter.py +0 -153
  196. notionary/page/markdown_syntax_prompt_generator.py +0 -114
  197. notionary/page/notion_to_markdown_converter.py +0 -179
  198. notionary/page/properites/property_value_extractor.py +0 -0
  199. notionary-0.2.19.dist-info/RECORD +0 -150
  200. /notionary/{blocks/document/document_models.py → markdown/___init__.py} +0 -0
  201. /notionary/{blocks/image/image_models.py → markdown/makdown_document_model.py} +0 -0
  202. /notionary/page/{content/markdown_whitespace_processor.py → markdown_whitespace_processor.py} +0 -0
  203. /notionary/{blocks/mention/mention_models.py → page/reader/handler/context.py} +0 -0
  204. {notionary-0.2.19.dist-info → notionary-0.2.21.dist-info}/LICENSE +0 -0
  205. {notionary-0.2.19.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 notionary.blocks import NotionBlockElement
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 NotionBlockElement
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, elements=None):
18
+ def __init__(self, builder: Optional[BlockRegistryBuilder] = None):
23
19
  """
24
20
  Initialize a new registry instance.
25
21
 
26
22
  Args:
27
- elements: Initial elements to register
23
+ builder: BlockRegistryBuilder instance to delegate operations to
28
24
  """
29
- self._elements: List[NotionBlockElement] = []
30
- self._element_types: Set[Type[NotionBlockElement]] = set()
31
-
32
- if elements:
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 BlockRegistryBuilder
50
-
51
- return BlockRegistryBuilder.create_registry()
52
-
53
- def register(self, element_class: Type[NotionBlockElement]) -> bool:
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
- if element_class in self._element_types:
64
- return False
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
- self._elements.append(element_class)
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
- if element_class in self._element_types:
75
- self._elements.remove(element_class)
76
- self._element_types.remove(element_class)
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[NotionBlockElement]) -> bool:
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[NotionBlockElement]]:
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) -> Optional[Dict[str, Any]]:
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: Dict[str, Any]) -> Optional[str]:
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
- self.telemetry.capture(
119
- NotionToMarkdownConversionEvent(
120
- handler_element_name=handler.__name__,
121
- )
122
- )
120
+ if not handler:
121
+ return None
123
122
 
124
- return handler.notion_to_markdown(block)
125
- return None
123
+ self.telemetry.capture(
124
+ NotionToMarkdownConversionEvent(
125
+ handler_element_name=handler.__name__,
126
+ )
127
+ )
126
128
 
127
- def get_multiline_elements(self) -> List[Type[NotionBlockElement]]:
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) -> List[Type[NotionBlockElement]]:
131
+ def get_elements(self) -> list[Type[BaseBlockElement]]:
132
132
  """Get all registered elements."""
133
- return self._elements.copy()
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 notionary.blocks import (
6
- ParagraphElement,
7
- AudioElement,
8
- BulletedListElement,
9
- CalloutElement,
10
- CodeElement,
11
- ColumnElement,
12
- DividerElement,
13
- EmbedElement,
14
- HeadingElement,
15
- ImageElement,
16
- MentionElement,
17
- NumberedListElement,
18
- TableElement,
19
- TodoElement,
20
- ToggleElement,
21
- ToggleableHeadingElement,
22
- VideoElement,
23
- BookmarkElement,
24
- QuoteElement,
25
- NotionBlockElement,
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[NotionBlockElement]) -> Self:
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
- """Add support for column elements."""
160
- return self._add_element(ColumnElement)
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[NotionBlockElement]) -> Self:
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
+ ]