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,7 +1,8 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from pydantic import BaseModel
4
- from notionary.blocks.markdown_node import MarkdownNode
4
+
5
+ from notionary.markdown.markdown_node import MarkdownNode
5
6
 
6
7
 
7
8
  class TableMarkdownBlockParams(BaseModel):
@@ -0,0 +1,28 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Literal
4
+
5
+ from pydantic import BaseModel
6
+
7
+ from notionary.blocks.rich_text.rich_text_models import RichTextObject
8
+
9
+
10
+ class TableBlock(BaseModel):
11
+ table_width: int
12
+ has_column_header: bool = False
13
+ has_row_header: bool = False
14
+ children: list[CreateTableRowBlock] = []
15
+
16
+
17
+ class TableRowBlock(BaseModel):
18
+ cells: list[list[RichTextObject]]
19
+
20
+
21
+ class CreateTableRowBlock(BaseModel):
22
+ type: Literal["table_row"] = "table_row"
23
+ table_row: TableRowBlock
24
+
25
+
26
+ class CreateTableBlock(BaseModel):
27
+ type: Literal["table"] = "table"
28
+ table: TableBlock
@@ -0,0 +1,19 @@
1
+ from notionary.blocks.table_of_contents.table_of_contents_element import (
2
+ TableOfContentsElement,
3
+ )
4
+ from notionary.blocks.table_of_contents.table_of_contents_markdown_node import (
5
+ TableOfContentsMarkdownBlockParams,
6
+ TableOfContentsMarkdownNode,
7
+ )
8
+ from notionary.blocks.table_of_contents.table_of_contents_models import (
9
+ CreateTableOfContentsBlock,
10
+ TableOfContentsBlock,
11
+ )
12
+
13
+ __all__ = [
14
+ "TableOfContentsElement",
15
+ "TableOfContentsBlock",
16
+ "CreateTableOfContentsBlock",
17
+ "TableOfContentsMarkdownNode",
18
+ "TableOfContentsMarkdownBlockParams",
19
+ ]
@@ -0,0 +1,51 @@
1
+ from __future__ import annotations
2
+
3
+ import re
4
+ from typing import Optional
5
+
6
+ from notionary.blocks.base_block_element import BaseBlockElement
7
+ from notionary.blocks.models import Block, BlockCreateResult
8
+ from notionary.blocks.table_of_contents.table_of_contents_models import (
9
+ CreateTableOfContentsBlock,
10
+ TableOfContentsBlock,
11
+ )
12
+ from notionary.blocks.types import BlockType
13
+
14
+
15
+ class TableOfContentsElement(BaseBlockElement):
16
+ """
17
+ Handles conversion between Markdown [toc] syntax and Notion table_of_contents blocks.
18
+
19
+ Markdown syntax:
20
+ - [toc] → default color
21
+ - [toc](blue) → custom color
22
+ - [toc](blue_background) → custom background color
23
+ """
24
+
25
+ PATTERN = re.compile(r"^\[toc\](?:\((?P<color>[a-z_]+)\))?$", re.IGNORECASE)
26
+
27
+ @classmethod
28
+ def match_notion(cls, block: Block) -> bool:
29
+ return block.type == BlockType.TABLE_OF_CONTENTS and block.table_of_contents
30
+
31
+ @classmethod
32
+ def markdown_to_notion(cls, text: str) -> BlockCreateResult:
33
+ if not (input_match := cls.PATTERN.match(text.strip())):
34
+ return None
35
+
36
+ color = (input_match.group("color") or "default").lower()
37
+ return CreateTableOfContentsBlock(
38
+ table_of_contents=TableOfContentsBlock(color=color)
39
+ )
40
+
41
+ @classmethod
42
+ def notion_to_markdown(cls, block: Block) -> Optional[str]:
43
+ # Fix: Use 'or' instead of 'and'
44
+ if block.type != BlockType.TABLE_OF_CONTENTS or not block.table_of_contents:
45
+ return None
46
+
47
+ color = block.table_of_contents.color.value
48
+
49
+ if color == "default":
50
+ return "[toc]"
51
+ return f"[toc]({color})"
@@ -0,0 +1,35 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Optional
4
+
5
+ from pydantic import BaseModel
6
+
7
+ from notionary.markdown.markdown_node import MarkdownNode
8
+
9
+
10
+ class TableOfContentsMarkdownBlockParams(BaseModel):
11
+ color: Optional[str] = "default"
12
+
13
+
14
+ class TableOfContentsMarkdownNode(MarkdownNode):
15
+ """
16
+ Programmatic interface for creating Markdown table of contents blocks.
17
+ Example:
18
+ [toc]
19
+ [toc](blue)
20
+ [toc](blue_background)
21
+ """
22
+
23
+ def __init__(self, color: Optional[str] = "default"):
24
+ self.color = color or "default"
25
+
26
+ @classmethod
27
+ def from_params(
28
+ cls, params: TableOfContentsMarkdownBlockParams
29
+ ) -> TableOfContentsMarkdownNode:
30
+ return cls(color=params.color)
31
+
32
+ def to_markdown(self) -> str:
33
+ if self.color == "default":
34
+ return "[toc]"
35
+ return f"[toc]({self.color})"
@@ -0,0 +1,18 @@
1
+ from typing import Literal
2
+
3
+ from pydantic import BaseModel
4
+
5
+ from notionary.blocks.types import BlockColor
6
+
7
+
8
+ class TableOfContentsBlock(BaseModel):
9
+ """Inneres Payload-Objekt: { table_of_contents: { color: ... } }"""
10
+
11
+ color: BlockColor = BlockColor.DEFAULT
12
+
13
+
14
+ class CreateTableOfContentsBlock(BaseModel):
15
+ """Create-Payload für den Block: { type: 'table_of_contents', table_of_contents: {...} }"""
16
+
17
+ type: Literal["table_of_contents"] = "table_of_contents"
18
+ table_of_contents: TableOfContentsBlock
@@ -1,7 +1,14 @@
1
- from .todo_element import TodoElement
2
- from .todo_markdown_node import TodoMarkdownNode
1
+ from notionary.blocks.todo.todo_element import TodoElement
2
+ from notionary.blocks.todo.todo_markdown_node import (
3
+ TodoMarkdownBlockParams,
4
+ TodoMarkdownNode,
5
+ )
6
+ from notionary.blocks.todo.todo_models import CreateToDoBlock, ToDoBlock
3
7
 
4
8
  __all__ = [
5
9
  "TodoElement",
10
+ "ToDoBlock",
11
+ "CreateToDoBlock",
6
12
  "TodoMarkdownNode",
13
+ "TodoMarkdownBlockParams",
7
14
  ]
@@ -1,16 +1,15 @@
1
+ from __future__ import annotations
2
+
1
3
  import re
2
- from typing import Dict, Any, Optional
4
+ from typing import TYPE_CHECKING, Optional
3
5
 
4
- from notionary.blocks import (
5
- ElementPromptContent,
6
- ElementPromptBuilder,
7
- NotionBlockResult,
8
- NotionBlockElement,
9
- )
10
- from notionary.blocks.shared.text_inline_formatter import TextInlineFormatter
6
+ from notionary.blocks.base_block_element import BaseBlockElement
7
+ from notionary.blocks.models import Block, BlockCreateResult, BlockType
8
+ from notionary.blocks.rich_text.text_inline_formatter import TextInlineFormatter
9
+ from notionary.blocks.todo.todo_models import CreateToDoBlock, ToDoBlock
11
10
 
12
11
 
13
- class TodoElement(NotionBlockElement):
12
+ class TodoElement(BaseBlockElement):
14
13
  """
15
14
  Handles conversion between Markdown todo items and Notion to_do blocks.
16
15
 
@@ -21,101 +20,45 @@ class TodoElement(NotionBlockElement):
21
20
  + [ ] Also works with plus sign
22
21
  """
23
22
 
24
- # Patterns for detecting Markdown todo items
25
- TODO_PATTERN = re.compile(r"^\s*[-*+]\s+\[\s?\]\s+(.+)$")
26
- DONE_PATTERN = re.compile(r"^\s*[-*+]\s+\[x\]\s+(.+)$")
23
+ PATTERN = re.compile(r"^\s*[-*+]\s+\[ \]\s+(.+)$")
24
+ DONE_PATTERN = re.compile(r"^\s*[-*+]\s+\[x\]\s+(.+)$", re.IGNORECASE)
27
25
 
28
26
  @classmethod
29
- def match_markdown(cls, text: str) -> bool:
30
- """Check if text is a markdown todo item."""
31
- return bool(
32
- TodoElement.TODO_PATTERN.match(text) or TodoElement.DONE_PATTERN.match(text)
33
- )
27
+ def match_notion(cls, block: Block) -> bool:
28
+ return block.type == BlockType.TO_DO and block.to_do
34
29
 
35
30
  @classmethod
36
- def match_notion(cls, block: Dict[str, Any]) -> bool:
37
- """Check if block is a Notion to_do block."""
38
- return block.get("type") == "to_do"
39
-
40
- @classmethod
41
- def markdown_to_notion(cls, text: str) -> NotionBlockResult:
42
- """Convert markdown todo item to Notion to_do block."""
43
- done_match = TodoElement.DONE_PATTERN.match(text)
44
- if done_match:
45
- content = done_match.group(1)
46
- return TodoElement._create_todo_block(content, True)
31
+ def markdown_to_notion(cls, text: str) -> BlockCreateResult:
32
+ """Convert markdown todo or done item to Notion to_do block."""
33
+ m_done = cls.DONE_PATTERN.match(text)
34
+ m_todo = None if m_done else cls.PATTERN.match(text)
35
+
36
+ if m_done:
37
+ content = m_done.group(1)
38
+ checked = True
39
+ elif m_todo:
40
+ content = m_todo.group(1)
41
+ checked = False
42
+ else:
43
+ return None
47
44
 
48
- todo_match = TodoElement.TODO_PATTERN.match(text)
49
- if todo_match:
50
- content = todo_match.group(1)
51
- return TodoElement._create_todo_block(content, False)
45
+ # build rich text
46
+ rich = TextInlineFormatter.parse_inline_formatting(content)
52
47
 
53
- return None
48
+ todo_content = ToDoBlock(
49
+ rich_text=rich,
50
+ checked=checked,
51
+ color="default",
52
+ )
53
+ return CreateToDoBlock(to_do=todo_content)
54
54
 
55
55
  @classmethod
56
- def notion_to_markdown(cls, block: Dict[str, Any]) -> Optional[str]:
56
+ def notion_to_markdown(cls, block: Block) -> Optional[str]:
57
57
  """Convert Notion to_do block to markdown todo item."""
58
- if block.get("type") != "to_do":
58
+ if block.type != BlockType.TO_DO or not block.to_do:
59
59
  return None
60
60
 
61
- todo_data = block.get("to_do", {})
62
- checked = todo_data.get("checked", False)
63
-
64
- # Extract text content
65
- rich_text = todo_data.get("rich_text", [])
66
- content = TextInlineFormatter.extract_text_with_formatting(rich_text)
67
-
68
- # Format as markdown todo item
69
- checkbox = "[x]" if checked else "[ ]"
61
+ td = block.to_do
62
+ content = TextInlineFormatter.extract_text_with_formatting(td.rich_text)
63
+ checkbox = "[x]" if td.checked else "[ ]"
70
64
  return f"- {checkbox} {content}"
71
-
72
- @classmethod
73
- def _create_todo_block(cls, content: str, checked: bool) -> Dict[str, Any]:
74
- """
75
- Create a Notion to_do block.
76
-
77
- Args:
78
- content: The text content of the todo item
79
- checked: Whether the todo item is checked
80
-
81
- Returns:
82
- Notion to_do block dictionary
83
- """
84
- return {
85
- "type": "to_do",
86
- "to_do": {
87
- "rich_text": TextInlineFormatter.parse_inline_formatting(content),
88
- "checked": checked,
89
- "color": "default",
90
- },
91
- }
92
-
93
- @classmethod
94
- def is_multiline(cls) -> bool:
95
- return False
96
-
97
- @classmethod
98
- def get_llm_prompt_content(cls) -> ElementPromptContent:
99
- """
100
- Returns structured LLM prompt metadata for the todo element.
101
- """
102
- return (
103
- ElementPromptBuilder()
104
- .with_description(
105
- "Creates interactive to-do items with checkboxes that can be marked as complete."
106
- )
107
- .with_usage_guidelines(
108
- "Use to-do items for task lists, checklists, or tracking progress on items that need to be completed. "
109
- "Todo items are interactive in Notion and can be checked/unchecked directly."
110
- )
111
- .with_syntax("- [ ] Task to complete")
112
- .with_examples(
113
- [
114
- "- [ ] Draft project proposal",
115
- "- [x] Create initial timeline",
116
- "* [ ] Review code changes",
117
- "+ [x] Finalize handoff checklist",
118
- ]
119
- )
120
- .build()
121
- )
@@ -1,7 +1,8 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from pydantic import BaseModel
4
- from notionary.blocks.markdown_node import MarkdownNode
4
+
5
+ from notionary.markdown.markdown_node import MarkdownNode
5
6
 
6
7
 
7
8
  class TodoMarkdownBlockParams(BaseModel):
@@ -0,0 +1,19 @@
1
+ from typing import Literal
2
+
3
+ from pydantic import BaseModel, Field
4
+
5
+ from notionary.blocks.models import Block
6
+ from notionary.blocks.rich_text.rich_text_models import RichTextObject
7
+ from notionary.blocks.types import BlockColor
8
+
9
+
10
+ class ToDoBlock(BaseModel):
11
+ rich_text: list[RichTextObject]
12
+ checked: bool = False
13
+ color: BlockColor = BlockColor.DEFAULT
14
+ children: list[Block] = Field(default_factory=list)
15
+
16
+
17
+ class CreateToDoBlock(BaseModel):
18
+ type: Literal["to_do"] = "to_do"
19
+ to_do: ToDoBlock
@@ -1,4 +1,14 @@
1
- from .toggle_element import ToggleElement
2
- from .toggle_markdown_node import ToggleMarkdownNode, ToggleMarkdownBlockParams
1
+ from notionary.blocks.toggle.toggle_element import ToggleElement
2
+ from notionary.blocks.toggle.toggle_markdown_node import (
3
+ ToggleMarkdownBlockParams,
4
+ ToggleMarkdownNode,
5
+ )
6
+ from notionary.blocks.toggle.toggle_models import CreateToggleBlock, ToggleBlock
3
7
 
4
- __all__ = ["ToggleElement", "ToggleMarkdownNode", "ToggleMarkdownBlockParams"]
8
+ __all__ = [
9
+ "ToggleElement",
10
+ "ToggleBlock",
11
+ "CreateToggleBlock",
12
+ "ToggleMarkdownNode",
13
+ "ToggleMarkdownBlockParams",
14
+ ]