notionary 0.1.13__py3-none-any.whl → 0.1.14__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 (37) hide show
  1. notionary/__init__.py +2 -2
  2. notionary/{converters/elements → elements}/audio_element.py +1 -1
  3. notionary/{converters/registry → elements}/block_element_registry.py +2 -5
  4. notionary/elements/block_element_registry_builder.py +401 -0
  5. notionary/{converters/elements → elements}/bookmark_element.py +1 -1
  6. notionary/{converters/elements → elements}/callout_element.py +2 -2
  7. notionary/{converters/elements → elements}/code_block_element.py +1 -1
  8. notionary/{converters/elements → elements}/column_element.py +1 -1
  9. notionary/{converters/elements → elements}/divider_element.py +1 -1
  10. notionary/{converters/elements → elements}/embed_element.py +1 -1
  11. notionary/{converters/elements → elements}/heading_element.py +2 -2
  12. notionary/{converters/elements → elements}/image_element.py +1 -1
  13. notionary/{converters/elements → elements}/list_element.py +2 -2
  14. notionary/elements/mention_element.py +135 -0
  15. notionary/{converters/elements → elements}/paragraph_element.py +2 -2
  16. notionary/{converters/elements → elements}/qoute_element.py +1 -1
  17. notionary/{converters/elements → elements}/table_element.py +2 -2
  18. notionary/{converters/elements → elements}/todo_lists.py +2 -2
  19. notionary/{converters/elements → elements}/toggle_element.py +1 -1
  20. notionary/{converters/elements → elements}/video_element.py +1 -1
  21. notionary/notion_client.py +0 -1
  22. notionary/page/content/page_content_manager.py +4 -3
  23. notionary/{converters → page}/markdown_to_notion_converter.py +2 -4
  24. notionary/page/notion_page.py +23 -5
  25. notionary/page/notion_page_factory.py +1 -15
  26. notionary/page/notion_to_markdown_converter.py +245 -0
  27. {notionary-0.1.13.dist-info → notionary-0.1.14.dist-info}/METADATA +1 -1
  28. notionary-0.1.14.dist-info/RECORD +56 -0
  29. notionary/converters/__init__.py +0 -50
  30. notionary/converters/notion_to_markdown_converter.py +0 -45
  31. notionary/converters/registry/block_element_registry_builder.py +0 -284
  32. notionary-0.1.13.dist-info/RECORD +0 -56
  33. /notionary/{converters/elements → elements}/notion_block_element.py +0 -0
  34. /notionary/{converters/elements → elements}/text_inline_formatter.py +0 -0
  35. {notionary-0.1.13.dist-info → notionary-0.1.14.dist-info}/WHEEL +0 -0
  36. {notionary-0.1.13.dist-info → notionary-0.1.14.dist-info}/licenses/LICENSE +0 -0
  37. {notionary-0.1.13.dist-info → notionary-0.1.14.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 .converters.registry.block_element_registry import BlockElementRegistry
11
- from .converters.registry.block_element_registry_builder import (
10
+ from .elements.block_element_registry import BlockElementRegistry
11
+ from .elements.block_element_registry_builder import (
12
12
  BlockElementRegistryBuilder,
13
13
  )
14
14
 
@@ -1,6 +1,6 @@
1
1
  import re
2
2
  from typing import Dict, Any, Optional, List
3
- from notionary.converters.elements.notion_block_element import NotionBlockElement
3
+ from notionary.elements.notion_block_element import NotionBlockElement
4
4
 
5
5
 
6
6
  class AudioElement(NotionBlockElement):
@@ -1,7 +1,7 @@
1
1
  from typing import Dict, Any, Optional, List, Type
2
2
 
3
- from notionary.converters.elements.notion_block_element import NotionBlockElement
4
- from notionary.converters.elements.text_inline_formatter import TextInlineFormatter
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,401 @@
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) # add_element already handles this logic
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_rich_content(self) -> BlockElementRegistryBuilder:
313
+ """
314
+ Add support for rich content elements (callouts, toggles, etc.).
315
+
316
+ Returns:
317
+ Self for method chaining
318
+ """
319
+ return self.with_callouts().with_toggles().with_quotes()
320
+
321
+ def with_media_support(self) -> BlockElementRegistryBuilder:
322
+ """
323
+ Add support for media elements (images, videos, audio).
324
+
325
+ Returns:
326
+ Self for method chaining
327
+ """
328
+ return self.with_images().with_videos().with_audio()
329
+
330
+ def with_task_support(self) -> BlockElementRegistryBuilder:
331
+ """
332
+ Add support for task-related elements (todos).
333
+
334
+ Returns:
335
+ Self for method chaining
336
+ """
337
+ return self.with_todos()
338
+
339
+ def with_mention(self) -> BlockElementRegistryBuilder:
340
+ return self.add_element(MentionElement)
341
+
342
+ def build(self) -> BlockElementRegistry:
343
+ """
344
+ Build and return the configured BlockElementRegistry instance.
345
+
346
+ This automatically ensures that ParagraphElement is at the end
347
+ of the registry (if present) as a fallback element, unless
348
+ this behavior was explicitly disabled.
349
+
350
+ Returns:
351
+ A configured BlockElementRegistry instance
352
+ """
353
+ if ParagraphElement.__name__ not in self._elements:
354
+ # Add paragraph as fallback if not present
355
+ self.add_element(ParagraphElement)
356
+ else:
357
+ # Ensure it's at the end
358
+ self._ensure_paragraph_at_end()
359
+
360
+ registry = BlockElementRegistry()
361
+
362
+ # Add elements in the recorded order
363
+ for element_class in self._elements.values():
364
+ registry.register(element_class)
365
+
366
+ return registry
367
+
368
+ @classmethod
369
+ def create_standard_registry(cls) -> BlockElementRegistry:
370
+ """
371
+ Factory method to directly create a standard registry.
372
+
373
+ Returns:
374
+ A fully configured registry instance
375
+ """
376
+ return cls.start_standard().build()
377
+
378
+ @classmethod
379
+ def create_minimal_registry(cls) -> BlockElementRegistry:
380
+ """
381
+ Factory method to directly create a minimal registry.
382
+
383
+ Returns:
384
+ A minimal registry instance
385
+ """
386
+ return cls.start_minimal().build()
387
+
388
+ @classmethod
389
+ def create_custom_registry(
390
+ cls, element_classes: List[Type[NotionBlockElement]]
391
+ ) -> BlockElementRegistry:
392
+ """
393
+ Factory method to directly create a custom registry.
394
+
395
+ Args:
396
+ element_classes: List of element classes to register
397
+
398
+ Returns:
399
+ A custom configured registry instance
400
+ """
401
+ 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.converters.elements.notion_block_element import NotionBlockElement
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.converters.elements.text_inline_formatter import TextInlineFormatter
6
- from notionary.converters.elements.notion_block_element import NotionBlockElement
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.converters.elements.notion_block_element import NotionBlockElement
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.converters.elements.notion_block_element import NotionBlockElement
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.converters.elements.notion_block_element import NotionBlockElement
7
+ from notionary.elements.notion_block_element import NotionBlockElement
8
8
 
9
9
 
10
10
  class DividerElement(NotionBlockElement):
@@ -1,6 +1,6 @@
1
1
  import re
2
2
  from typing import Dict, Any, Optional, List
3
- from notionary.converters.elements.notion_block_element import NotionBlockElement
3
+ from notionary.elements.notion_block_element import NotionBlockElement
4
4
 
5
5
 
6
6
  class EmbedElement(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.converters.elements.notion_block_element import NotionBlockElement
6
- from notionary.converters.elements.text_inline_formatter import TextInlineFormatter
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.converters.elements.notion_block_element import NotionBlockElement
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.converters.elements.notion_block_element import NotionBlockElement
5
- from notionary.converters.elements.text_inline_formatter import TextInlineFormatter
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):
@@ -0,0 +1,135 @@
1
+ from typing import Dict, Any, Optional, List
2
+ from typing_extensions import override
3
+
4
+ from notionary.elements.notion_block_element import NotionBlockElement
5
+
6
+ class MentionElement(NotionBlockElement):
7
+ """
8
+ Handles conversion between Markdown mentions and Notion mention elements.
9
+
10
+ Markdown mention syntax:
11
+ - @[page-id] - Mention a page by its ID
12
+
13
+ Note: This element primarily supports Notion-to-Markdown conversion,
14
+ as page mentions in Markdown would typically require knowing internal page IDs.
15
+ """
16
+
17
+ @override
18
+ @staticmethod
19
+ def match_markdown(text: str) -> bool:
20
+ """Check if text is a markdown mention."""
21
+ return False
22
+
23
+ @override
24
+ @staticmethod
25
+ def match_notion(block: Dict[str, Any]) -> bool:
26
+ """Check if block contains a mention."""
27
+ if block.get("type") not in ["paragraph", "heading_1", "heading_2", "heading_3", "bulleted_list_item", "numbered_list_item"]:
28
+ return False
29
+
30
+ block_content = block.get(block.get("type"), {})
31
+ rich_text = block_content.get("rich_text", [])
32
+
33
+ for text_item in rich_text:
34
+ if text_item.get("type") == "mention":
35
+ return True
36
+
37
+ return False
38
+
39
+ @override
40
+ @staticmethod
41
+ def markdown_to_notion(text: str) -> Optional[Dict[str, Any]]:
42
+ """Convert markdown mention to Notion mention block."""
43
+ # This would be handled within rich text processing rather than as a standalone block
44
+ return None
45
+
46
+ @override
47
+ @staticmethod
48
+ def notion_to_markdown(block: Dict[str, Any]) -> Optional[str]:
49
+ """Extract mentions from Notion block and convert to markdown format."""
50
+ block_type = block.get("type")
51
+ if not block_type or block_type not in block:
52
+ return None
53
+
54
+ block_content = block.get(block_type, {})
55
+ rich_text = block_content.get("rich_text", [])
56
+
57
+ processed_text = MentionElement._process_rich_text_with_mentions(rich_text)
58
+
59
+ if MentionElement._is_only_mentions(rich_text):
60
+ return processed_text
61
+
62
+ return None
63
+
64
+ @staticmethod
65
+ def _process_rich_text_with_mentions(rich_text: List[Dict[str, Any]]) -> str:
66
+ """Process rich text array and convert any mentions to markdown format."""
67
+ result = []
68
+
69
+ for item in rich_text:
70
+ if item.get("type") == "mention":
71
+ mention = item.get("mention", {})
72
+ mention_type = mention.get("type")
73
+
74
+ if mention_type == "page":
75
+ page_id = mention.get("page", {}).get("id", "")
76
+ result.append(f"@[{page_id}]")
77
+ elif mention_type == "user":
78
+ user_id = mention.get("user", {}).get("id", "")
79
+ result.append(f"@user[{user_id}]")
80
+ elif mention_type == "date":
81
+ date_value = mention.get("date", {}).get("start", "")
82
+ result.append(f"@date[{date_value}]")
83
+ elif mention_type == "database":
84
+ db_id = mention.get("database", {}).get("id", "")
85
+ result.append(f"@db[{db_id}]")
86
+ else:
87
+ # Unknown mention type, fallback to plain text if available
88
+ result.append(item.get("plain_text", "@[unknown]"))
89
+ else:
90
+ # Regular text item
91
+ result.append(item.get("plain_text", ""))
92
+
93
+ return "".join(result)
94
+
95
+ @staticmethod
96
+ def _is_only_mentions(rich_text: List[Dict[str, Any]]) -> bool:
97
+ """Check if rich_text array contains only mentions."""
98
+ if not rich_text:
99
+ return False
100
+
101
+ for item in rich_text:
102
+ if item.get("type") != "mention":
103
+ return False
104
+
105
+ return True
106
+
107
+ @override
108
+ @staticmethod
109
+ def is_multiline() -> bool:
110
+ return False
111
+
112
+ @classmethod
113
+ def get_llm_prompt_content(cls) -> dict:
114
+ """
115
+ Returns a dictionary with all information needed for LLM prompts about this element.
116
+ """
117
+ return {
118
+ "description": "References to Notion pages, users, databases, or dates within text content.",
119
+ "when_to_use": "Mentions are typically part of rich text content rather than standalone elements. They're used to link to other Notion content or users.",
120
+ "syntax": [
121
+ "@[page-id] - Reference to a Notion page",
122
+ "@user[user-id] - Reference to a Notion user",
123
+ "@date[YYYY-MM-DD] - Reference to a date",
124
+ "@db[database-id] - Reference to a Notion database"
125
+ ],
126
+ "examples": [
127
+ "Check the meeting notes at @[1a6389d5-7bd3-80c5-9a87-e90b034989d0]",
128
+ "Please review this with @user[d3dbbbd7-ec00-4204-94d9-e4a46e4928db]",
129
+ "Deadline is @date[2023-12-31]"
130
+ ],
131
+ "limitations": [
132
+ "Mentions are typically created through Notion's UI rather than direct markdown input",
133
+ "When converting Notion content to markdown, mentions are represented with their internal IDs"
134
+ ]
135
+ }
@@ -1,8 +1,8 @@
1
1
  from typing import Dict, Any, Optional
2
2
  from typing_extensions import override
3
3
 
4
- from notionary.converters.elements.notion_block_element import NotionBlockElement
5
- from notionary.converters.elements.text_inline_formatter import TextInlineFormatter
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 ParagraphElement(NotionBlockElement):