notionary 0.2.19__py3-none-any.whl → 0.2.22__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 +271 -0
- notionary/blocks/audio/__init__.py +8 -2
- notionary/blocks/audio/audio_element.py +69 -106
- notionary/blocks/audio/audio_markdown_node.py +13 -5
- notionary/blocks/audio/audio_models.py +6 -55
- notionary/blocks/base_block_element.py +42 -0
- notionary/blocks/bookmark/__init__.py +9 -2
- notionary/blocks/bookmark/bookmark_element.py +49 -139
- notionary/blocks/bookmark/bookmark_markdown_node.py +19 -18
- 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 +55 -53
- 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 +53 -86
- notionary/blocks/callout/callout_markdown_node.py +3 -1
- notionary/blocks/callout/callout_models.py +33 -0
- notionary/blocks/child_database/__init__.py +14 -0
- notionary/blocks/child_database/child_database_element.py +61 -0
- notionary/blocks/child_database/child_database_models.py +12 -0
- notionary/blocks/child_page/__init__.py +9 -0
- notionary/blocks/child_page/child_page_element.py +94 -0
- notionary/blocks/child_page/child_page_models.py +12 -0
- notionary/blocks/{shared/block_client.py → client.py} +54 -54
- notionary/blocks/code/__init__.py +6 -2
- notionary/blocks/code/code_element.py +96 -181
- notionary/blocks/code/code_markdown_node.py +64 -13
- notionary/blocks/code/code_models.py +94 -0
- notionary/blocks/column/__init__.py +25 -1
- notionary/blocks/column/column_element.py +44 -312
- notionary/blocks/column/column_list_element.py +52 -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 +18 -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 +65 -111
- 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 +133 -0
- notionary/blocks/equation/equation_element_markdown_node.py +35 -0
- notionary/blocks/equation/equation_models.py +11 -0
- notionary/blocks/file/__init__.py +25 -0
- notionary/blocks/file/file_element.py +112 -0
- notionary/blocks/file/file_element_markdown_node.py +37 -0
- notionary/blocks/file/file_element_models.py +39 -0
- notionary/blocks/guards.py +22 -0
- notionary/blocks/heading/__init__.py +16 -2
- notionary/blocks/heading/heading_element.py +83 -69
- 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 +89 -0
- notionary/blocks/{image → image_block}/image_markdown_node.py +13 -6
- notionary/blocks/image_block/image_models.py +10 -0
- notionary/blocks/mixins/captions/__init__.py +4 -0
- notionary/blocks/mixins/captions/caption_markdown_node_mixin.py +31 -0
- notionary/blocks/mixins/captions/caption_mixin.py +92 -0
- notionary/blocks/models.py +174 -0
- notionary/blocks/numbered_list/__init__.py +12 -2
- notionary/blocks/numbered_list/numbered_list_element.py +48 -56
- 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 +40 -66
- 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 +97 -0
- notionary/blocks/pdf/pdf_markdown_node.py +37 -0
- notionary/blocks/pdf/pdf_models.py +11 -0
- notionary/blocks/quote/__init__.py +11 -2
- notionary/blocks/quote/quote_element.py +45 -62
- notionary/blocks/quote/quote_markdown_node.py +6 -3
- notionary/blocks/quote/quote_models.py +18 -0
- notionary/blocks/registry/__init__.py +4 -0
- notionary/blocks/registry/block_registry.py +60 -121
- notionary/blocks/registry/block_registry_builder.py +115 -59
- notionary/blocks/rich_text/__init__.py +33 -0
- notionary/blocks/rich_text/name_to_id_resolver.py +205 -0
- notionary/blocks/rich_text/rich_text_models.py +221 -0
- notionary/blocks/rich_text/text_inline_formatter.py +456 -0
- notionary/blocks/syntax_prompt_builder.py +137 -0
- notionary/blocks/table/__init__.py +16 -2
- notionary/blocks/table/table_element.py +136 -228
- 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 +68 -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 +52 -92
- 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 +69 -260
- notionary/blocks/toggle/toggle_markdown_node.py +25 -15
- notionary/blocks/toggle/toggle_models.py +17 -0
- notionary/blocks/toggleable_heading/__init__.py +6 -2
- notionary/blocks/toggleable_heading/toggleable_heading_element.py +86 -241
- notionary/blocks/toggleable_heading/toggleable_heading_markdown_node.py +26 -18
- notionary/blocks/types.py +130 -0
- notionary/blocks/video/__init__.py +8 -2
- notionary/blocks/video/video_element.py +70 -141
- notionary/blocks/video/video_element_models.py +10 -0
- notionary/blocks/video/video_markdown_node.py +13 -6
- notionary/database/client.py +26 -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 +3 -2
- notionary/file_upload/notion_file_upload.py +2 -3
- notionary/markdown/markdown_builder.py +729 -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 +34 -15
- notionary/page/models.py +327 -0
- notionary/page/notion_page.py +136 -58
- notionary/page/{content/page_content_writer.py → page_content_deleting_service.py} +25 -59
- notionary/page/page_content_writer.py +177 -0
- notionary/page/page_context.py +65 -0
- notionary/page/reader/handler/__init__.py +19 -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 +48 -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 +73 -0
- notionary/page/reader/handler/numbered_list_renderer.py +85 -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 +81 -0
- notionary/page/search_filter_builder.py +2 -1
- notionary/page/writer/handler/__init__.py +24 -0
- notionary/page/writer/handler/code_handler.py +72 -0
- notionary/page/writer/handler/column_handler.py +141 -0
- notionary/page/writer/handler/column_list_handler.py +139 -0
- notionary/page/writer/handler/equation_handler.py +74 -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 +86 -0
- notionary/page/writer/handler/table_handler.py +66 -0
- notionary/page/writer/handler/toggle_handler.py +155 -0
- notionary/page/writer/handler/toggleable_heading_handler.py +173 -0
- notionary/page/writer/markdown_to_notion_converter.py +95 -0
- notionary/page/writer/markdown_to_notion_converter_context.py +30 -0
- notionary/page/writer/markdown_to_notion_formatting_post_processor.py +73 -0
- notionary/page/writer/notion_text_length_processor.py +150 -0
- notionary/telemetry/__init__.py +2 -2
- notionary/telemetry/service.py +3 -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 +23 -95
- 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 +6 -5
- notionary-0.2.22.dist-info/METADATA +237 -0
- notionary-0.2.22.dist-info/RECORD +200 -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/models.py +0 -713
- 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/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/markdown_whitespace_processor.py +0 -80
- notionary/page/content/notion_text_length_utils.py +0 -87
- notionary/page/content/page_content_retriever.py +0 -60
- 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/user/notion_user_provider.py +0 -1
- notionary-0.2.19.dist-info/METADATA +0 -225
- notionary-0.2.19.dist-info/RECORD +0 -150
- /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/{blocks/mention/mention_models.py → page/reader/handler/equation_renderer.py} +0 -0
- /notionary/{blocks/shared/__init__.py → page/writer/markdown_to_notion_post_processor.py} +0 -0
- /notionary/{blocks/toggleable_heading/toggleable_heading_models.py → page/writer/markdown_to_notion_text_length_post_processor.py} +0 -0
- /notionary/{elements/__init__.py → util/concurrency_limiter.py} +0 -0
- {notionary-0.2.19.dist-info → notionary-0.2.22.dist-info}/LICENSE +0 -0
- {notionary-0.2.19.dist-info → notionary-0.2.22.dist-info}/WHEEL +0 -0
@@ -0,0 +1,68 @@
|
|
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.syntax_prompt_builder import BlockElementMarkdownInformation
|
8
|
+
from notionary.blocks.models import Block, BlockCreateResult
|
9
|
+
from notionary.blocks.table_of_contents.table_of_contents_models import (
|
10
|
+
CreateTableOfContentsBlock,
|
11
|
+
TableOfContentsBlock,
|
12
|
+
)
|
13
|
+
from notionary.blocks.types import BlockType
|
14
|
+
|
15
|
+
|
16
|
+
class TableOfContentsElement(BaseBlockElement):
|
17
|
+
"""
|
18
|
+
Handles conversion between Markdown [toc] syntax and Notion table_of_contents blocks.
|
19
|
+
|
20
|
+
Markdown syntax:
|
21
|
+
- [toc] → default color
|
22
|
+
- [toc](blue) → custom color
|
23
|
+
- [toc](blue_background) → custom background color
|
24
|
+
"""
|
25
|
+
|
26
|
+
PATTERN = re.compile(r"^\[toc\](?:\((?P<color>[a-z_]+)\))?$", re.IGNORECASE)
|
27
|
+
|
28
|
+
@classmethod
|
29
|
+
def match_notion(cls, block: Block) -> bool:
|
30
|
+
return block.type == BlockType.TABLE_OF_CONTENTS and block.table_of_contents
|
31
|
+
|
32
|
+
@classmethod
|
33
|
+
async def markdown_to_notion(cls, text: str) -> BlockCreateResult:
|
34
|
+
if not (input_match := cls.PATTERN.match(text.strip())):
|
35
|
+
return None
|
36
|
+
|
37
|
+
color = (input_match.group("color") or "default").lower()
|
38
|
+
return CreateTableOfContentsBlock(
|
39
|
+
table_of_contents=TableOfContentsBlock(color=color)
|
40
|
+
)
|
41
|
+
|
42
|
+
@classmethod
|
43
|
+
async def notion_to_markdown(cls, block: Block) -> Optional[str]:
|
44
|
+
# Fix: Use 'or' instead of 'and'
|
45
|
+
if block.type != BlockType.TABLE_OF_CONTENTS or not block.table_of_contents:
|
46
|
+
return None
|
47
|
+
|
48
|
+
color = block.table_of_contents.color.value
|
49
|
+
|
50
|
+
if color == "default":
|
51
|
+
return "[toc]"
|
52
|
+
return f"[toc]({color})"
|
53
|
+
|
54
|
+
@classmethod
|
55
|
+
@classmethod
|
56
|
+
def get_system_prompt_information(cls) -> Optional[BlockElementMarkdownInformation]:
|
57
|
+
"""Get system prompt information for table of contents blocks."""
|
58
|
+
return BlockElementMarkdownInformation(
|
59
|
+
block_type=cls.__name__,
|
60
|
+
description="Table of contents blocks automatically generate navigation for page headings",
|
61
|
+
syntax_examples=[
|
62
|
+
"[toc]",
|
63
|
+
"[toc](blue)",
|
64
|
+
"[toc](blue_background)",
|
65
|
+
"[toc](gray_background)",
|
66
|
+
],
|
67
|
+
usage_guidelines="Use to automatically generate a clickable table of contents from page headings. Optional color parameter changes the appearance. Default color is gray.",
|
68
|
+
)
|
@@ -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
|
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,16 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
1
3
|
import re
|
2
|
-
from typing import
|
4
|
+
from typing import TYPE_CHECKING, Optional
|
3
5
|
|
4
|
-
from notionary.blocks import
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
)
|
10
|
-
from notionary.blocks.shared.text_inline_formatter import TextInlineFormatter
|
6
|
+
from notionary.blocks.base_block_element import BaseBlockElement
|
7
|
+
from notionary.blocks.syntax_prompt_builder import BlockElementMarkdownInformation
|
8
|
+
from notionary.blocks.models import Block, BlockCreateResult, BlockType
|
9
|
+
from notionary.blocks.rich_text.text_inline_formatter import TextInlineFormatter
|
10
|
+
from notionary.blocks.todo.todo_models import CreateToDoBlock, ToDoBlock
|
11
11
|
|
12
12
|
|
13
|
-
class TodoElement(
|
13
|
+
class TodoElement(BaseBlockElement):
|
14
14
|
"""
|
15
15
|
Handles conversion between Markdown todo items and Notion to_do blocks.
|
16
16
|
|
@@ -21,101 +21,61 @@ class TodoElement(NotionBlockElement):
|
|
21
21
|
+ [ ] Also works with plus sign
|
22
22
|
"""
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
DONE_PATTERN = re.compile(r"^\s*[-*+]\s+\[x\]\s+(.+)$")
|
27
|
-
|
28
|
-
@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
|
-
)
|
24
|
+
PATTERN = re.compile(r"^\s*[-*+]\s+\[ \]\s+(.+)$")
|
25
|
+
DONE_PATTERN = re.compile(r"^\s*[-*+]\s+\[x\]\s+(.+)$", re.IGNORECASE)
|
34
26
|
|
35
27
|
@classmethod
|
36
|
-
def match_notion(cls, block:
|
37
|
-
|
38
|
-
return block.get("type") == "to_do"
|
28
|
+
def match_notion(cls, block: Block) -> bool:
|
29
|
+
return block.type == BlockType.TO_DO and block.to_do
|
39
30
|
|
40
31
|
@classmethod
|
41
|
-
def markdown_to_notion(cls, text: str) ->
|
42
|
-
"""Convert markdown todo item to Notion to_do block."""
|
43
|
-
|
44
|
-
if
|
45
|
-
|
46
|
-
|
32
|
+
async def markdown_to_notion(cls, text: str) -> BlockCreateResult:
|
33
|
+
"""Convert markdown todo or done item to Notion to_do block."""
|
34
|
+
m_done = cls.DONE_PATTERN.match(text)
|
35
|
+
m_todo = None if m_done else cls.PATTERN.match(text)
|
36
|
+
|
37
|
+
if m_done:
|
38
|
+
content = m_done.group(1)
|
39
|
+
checked = True
|
40
|
+
elif m_todo:
|
41
|
+
content = m_todo.group(1)
|
42
|
+
checked = False
|
43
|
+
else:
|
44
|
+
return None
|
47
45
|
|
48
|
-
|
49
|
-
|
50
|
-
content = todo_match.group(1)
|
51
|
-
return TodoElement._create_todo_block(content, False)
|
46
|
+
# build rich text
|
47
|
+
rich = await TextInlineFormatter.parse_inline_formatting(content)
|
52
48
|
|
53
|
-
|
49
|
+
todo_content = ToDoBlock(
|
50
|
+
rich_text=rich,
|
51
|
+
checked=checked,
|
52
|
+
color="default",
|
53
|
+
)
|
54
|
+
return CreateToDoBlock(to_do=todo_content)
|
54
55
|
|
55
56
|
@classmethod
|
56
|
-
def notion_to_markdown(cls, block:
|
57
|
+
async def notion_to_markdown(cls, block: Block) -> Optional[str]:
|
57
58
|
"""Convert Notion to_do block to markdown todo item."""
|
58
|
-
if block.
|
59
|
+
if block.type != BlockType.TO_DO or not block.to_do:
|
59
60
|
return None
|
60
61
|
|
61
|
-
|
62
|
-
|
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 "[ ]"
|
62
|
+
td = block.to_do
|
63
|
+
content = await TextInlineFormatter.extract_text_with_formatting(td.rich_text)
|
64
|
+
checkbox = "[x]" if td.checked else "[ ]"
|
70
65
|
return f"- {checkbox} {content}"
|
71
66
|
|
72
67
|
@classmethod
|
73
|
-
def
|
74
|
-
"""
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
"
|
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()
|
68
|
+
def get_system_prompt_information(cls) -> Optional[BlockElementMarkdownInformation]:
|
69
|
+
"""Get system prompt information for todo blocks."""
|
70
|
+
return BlockElementMarkdownInformation(
|
71
|
+
block_type=cls.__name__,
|
72
|
+
description="Todo blocks create interactive checkboxes for task management",
|
73
|
+
syntax_examples=[
|
74
|
+
"- [ ] Unchecked todo item",
|
75
|
+
"- [x] Checked todo item",
|
76
|
+
"* [ ] Todo with asterisk",
|
77
|
+
"+ [ ] Todo with plus sign",
|
78
|
+
"- [x] Completed task",
|
79
|
+
],
|
80
|
+
usage_guidelines="Use for task lists and checkboxes. [ ] for unchecked, [x] for checked items. Supports -, *, or + as bullet markers. Interactive in Notion interface.",
|
121
81
|
)
|
@@ -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
|
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__ = [
|
8
|
+
__all__ = [
|
9
|
+
"ToggleElement",
|
10
|
+
"ToggleBlock",
|
11
|
+
"CreateToggleBlock",
|
12
|
+
"ToggleMarkdownNode",
|
13
|
+
"ToggleMarkdownBlockParams",
|
14
|
+
]
|