notionary 0.2.18__py3-none-any.whl → 0.2.21__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- notionary/__init__.py +8 -4
- notionary/base_notion_client.py +3 -1
- notionary/blocks/__init__.py +2 -91
- notionary/blocks/_bootstrap.py +263 -0
- notionary/blocks/audio/__init__.py +8 -2
- notionary/blocks/audio/audio_element.py +42 -104
- notionary/blocks/audio/audio_markdown_node.py +3 -1
- notionary/blocks/audio/audio_models.py +6 -55
- notionary/blocks/base_block_element.py +30 -0
- notionary/blocks/bookmark/__init__.py +9 -2
- notionary/blocks/bookmark/bookmark_element.py +46 -139
- notionary/blocks/bookmark/bookmark_markdown_node.py +3 -1
- notionary/blocks/bookmark/bookmark_models.py +15 -0
- notionary/blocks/breadcrumbs/__init__.py +17 -0
- notionary/blocks/breadcrumbs/breadcrumb_element.py +39 -0
- notionary/blocks/breadcrumbs/breadcrumb_markdown_node.py +32 -0
- notionary/blocks/breadcrumbs/breadcrumb_models.py +12 -0
- notionary/blocks/bulleted_list/__init__.py +12 -2
- notionary/blocks/bulleted_list/bulleted_list_element.py +40 -55
- notionary/blocks/bulleted_list/bulleted_list_markdown_node.py +2 -1
- notionary/blocks/bulleted_list/bulleted_list_models.py +18 -0
- notionary/blocks/callout/__init__.py +9 -2
- notionary/blocks/callout/callout_element.py +40 -89
- notionary/blocks/callout/callout_markdown_node.py +3 -1
- notionary/blocks/callout/callout_models.py +33 -0
- notionary/blocks/child_database/__init__.py +7 -0
- notionary/blocks/child_database/child_database_models.py +19 -0
- notionary/blocks/child_page/__init__.py +9 -0
- notionary/blocks/child_page/child_page_models.py +12 -0
- notionary/blocks/{shared/block_client.py → client.py} +55 -54
- notionary/blocks/code/__init__.py +6 -2
- notionary/blocks/code/code_element.py +53 -187
- notionary/blocks/code/code_markdown_node.py +13 -13
- notionary/blocks/code/code_models.py +94 -0
- notionary/blocks/column/__init__.py +25 -1
- notionary/blocks/column/column_element.py +40 -314
- notionary/blocks/column/column_list_element.py +37 -0
- notionary/blocks/column/column_list_markdown_node.py +50 -0
- notionary/blocks/column/column_markdown_node.py +59 -0
- notionary/blocks/column/column_models.py +26 -0
- notionary/blocks/divider/__init__.py +9 -2
- notionary/blocks/divider/divider_element.py +26 -49
- notionary/blocks/divider/divider_markdown_node.py +2 -1
- notionary/blocks/divider/divider_models.py +12 -0
- notionary/blocks/embed/__init__.py +9 -2
- notionary/blocks/embed/embed_element.py +47 -114
- notionary/blocks/embed/embed_markdown_node.py +3 -1
- notionary/blocks/embed/embed_models.py +14 -0
- notionary/blocks/equation/__init__.py +14 -0
- notionary/blocks/equation/equation_element.py +80 -0
- notionary/blocks/equation/equation_element_markdown_node.py +36 -0
- notionary/blocks/equation/equation_models.py +11 -0
- notionary/blocks/file/__init__.py +25 -0
- notionary/blocks/file/file_element.py +93 -0
- notionary/blocks/file/file_element_markdown_node.py +35 -0
- notionary/blocks/file/file_element_models.py +39 -0
- notionary/blocks/heading/__init__.py +16 -2
- notionary/blocks/heading/heading_element.py +67 -72
- notionary/blocks/heading/heading_markdown_node.py +2 -1
- notionary/blocks/heading/heading_models.py +29 -0
- notionary/blocks/image_block/__init__.py +13 -0
- notionary/blocks/image_block/image_element.py +84 -0
- notionary/blocks/{image → image_block}/image_markdown_node.py +3 -1
- notionary/blocks/image_block/image_models.py +10 -0
- notionary/blocks/models.py +172 -0
- notionary/blocks/numbered_list/__init__.py +12 -2
- notionary/blocks/numbered_list/numbered_list_element.py +33 -58
- notionary/blocks/numbered_list/numbered_list_markdown_node.py +3 -1
- notionary/blocks/numbered_list/numbered_list_models.py +17 -0
- notionary/blocks/paragraph/__init__.py +12 -2
- notionary/blocks/paragraph/paragraph_element.py +27 -69
- notionary/blocks/paragraph/paragraph_markdown_node.py +2 -1
- notionary/blocks/paragraph/paragraph_models.py +16 -0
- notionary/blocks/pdf/__init__.py +13 -0
- notionary/blocks/pdf/pdf_element.py +91 -0
- notionary/blocks/pdf/pdf_markdown_node.py +35 -0
- notionary/blocks/pdf/pdf_models.py +11 -0
- notionary/blocks/quote/__init__.py +11 -2
- notionary/blocks/quote/quote_element.py +31 -65
- notionary/blocks/quote/quote_markdown_node.py +4 -1
- notionary/blocks/quote/quote_models.py +18 -0
- notionary/blocks/registry/__init__.py +4 -0
- notionary/blocks/registry/block_registry.py +75 -91
- notionary/blocks/registry/block_registry_builder.py +107 -59
- notionary/blocks/rich_text/__init__.py +33 -0
- notionary/blocks/rich_text/rich_text_models.py +188 -0
- notionary/blocks/rich_text/text_inline_formatter.py +125 -0
- notionary/blocks/table/__init__.py +16 -2
- notionary/blocks/table/table_element.py +48 -241
- notionary/blocks/table/table_markdown_node.py +2 -1
- notionary/blocks/table/table_models.py +28 -0
- notionary/blocks/table_of_contents/__init__.py +19 -0
- notionary/blocks/table_of_contents/table_of_contents_element.py +51 -0
- notionary/blocks/table_of_contents/table_of_contents_markdown_node.py +35 -0
- notionary/blocks/table_of_contents/table_of_contents_models.py +18 -0
- notionary/blocks/todo/__init__.py +9 -2
- notionary/blocks/todo/todo_element.py +38 -95
- notionary/blocks/todo/todo_markdown_node.py +2 -1
- notionary/blocks/todo/todo_models.py +19 -0
- notionary/blocks/toggle/__init__.py +13 -3
- notionary/blocks/toggle/toggle_element.py +57 -264
- notionary/blocks/toggle/toggle_markdown_node.py +24 -14
- notionary/blocks/toggle/toggle_models.py +17 -0
- notionary/blocks/toggleable_heading/__init__.py +6 -2
- notionary/blocks/toggleable_heading/toggleable_heading_element.py +74 -244
- notionary/blocks/toggleable_heading/toggleable_heading_markdown_node.py +26 -18
- notionary/blocks/types.py +61 -0
- notionary/blocks/video/__init__.py +8 -2
- notionary/blocks/video/video_element.py +67 -143
- notionary/blocks/video/video_element_models.py +10 -0
- notionary/blocks/video/video_markdown_node.py +3 -1
- notionary/database/client.py +3 -8
- notionary/database/database.py +13 -14
- notionary/database/database_filter_builder.py +2 -2
- notionary/database/database_provider.py +5 -4
- notionary/database/models.py +337 -0
- notionary/database/notion_database.py +6 -7
- notionary/file_upload/client.py +5 -7
- notionary/file_upload/models.py +2 -1
- notionary/file_upload/notion_file_upload.py +2 -3
- notionary/markdown/markdown_builder.py +722 -0
- notionary/markdown/markdown_document_model.py +228 -0
- notionary/{blocks → markdown}/markdown_node.py +1 -0
- notionary/models/notion_database_response.py +0 -338
- notionary/page/client.py +9 -10
- notionary/page/models.py +327 -0
- notionary/page/notion_page.py +99 -52
- notionary/page/notion_text_length_utils.py +119 -0
- notionary/page/{content/page_content_writer.py → page_content_writer.py} +88 -38
- notionary/page/reader/handler/__init__.py +17 -0
- notionary/page/reader/handler/base_block_renderer.py +44 -0
- notionary/page/reader/handler/block_processing_context.py +35 -0
- notionary/page/reader/handler/block_rendering_context.py +43 -0
- notionary/page/reader/handler/column_list_renderer.py +51 -0
- notionary/page/reader/handler/column_renderer.py +60 -0
- notionary/page/reader/handler/line_renderer.py +60 -0
- notionary/page/reader/handler/toggle_renderer.py +69 -0
- notionary/page/reader/handler/toggleable_heading_renderer.py +89 -0
- notionary/page/reader/page_content_retriever.py +69 -0
- notionary/page/search_filter_builder.py +2 -1
- notionary/page/writer/handler/__init__.py +22 -0
- notionary/page/writer/handler/code_handler.py +100 -0
- notionary/page/writer/handler/column_handler.py +141 -0
- notionary/page/writer/handler/column_list_handler.py +139 -0
- notionary/page/writer/handler/line_handler.py +35 -0
- notionary/page/writer/handler/line_processing_context.py +54 -0
- notionary/page/writer/handler/regular_line_handler.py +92 -0
- notionary/page/writer/handler/table_handler.py +130 -0
- notionary/page/writer/handler/toggle_handler.py +153 -0
- notionary/page/writer/handler/toggleable_heading_handler.py +167 -0
- notionary/page/writer/markdown_to_notion_converter.py +76 -0
- notionary/telemetry/__init__.py +2 -2
- notionary/telemetry/service.py +4 -3
- notionary/user/__init__.py +2 -2
- notionary/user/base_notion_user.py +2 -1
- notionary/user/client.py +2 -3
- notionary/user/models.py +1 -0
- notionary/user/notion_bot_user.py +4 -5
- notionary/user/notion_user.py +3 -4
- notionary/user/notion_user_manager.py +3 -2
- notionary/user/notion_user_provider.py +1 -1
- notionary/util/__init__.py +3 -2
- notionary/util/fuzzy.py +2 -1
- notionary/util/logging_mixin.py +2 -2
- notionary/util/singleton_metaclass.py +1 -1
- notionary/workspace.py +3 -2
- {notionary-0.2.18.dist-info → notionary-0.2.21.dist-info}/METADATA +12 -8
- notionary-0.2.21.dist-info/RECORD +185 -0
- notionary/blocks/document/__init__.py +0 -7
- notionary/blocks/document/document_element.py +0 -102
- notionary/blocks/document/document_markdown_node.py +0 -31
- notionary/blocks/image/__init__.py +0 -7
- notionary/blocks/image/image_element.py +0 -151
- notionary/blocks/markdown_builder.py +0 -356
- notionary/blocks/mention/__init__.py +0 -7
- notionary/blocks/mention/mention_element.py +0 -229
- notionary/blocks/mention/mention_markdown_node.py +0 -38
- notionary/blocks/prompts/element_prompt_builder.py +0 -83
- notionary/blocks/prompts/element_prompt_content.py +0 -41
- notionary/blocks/shared/__init__.py +0 -0
- notionary/blocks/shared/models.py +0 -710
- notionary/blocks/shared/notion_block_element.py +0 -37
- notionary/blocks/shared/text_inline_formatter.py +0 -262
- notionary/blocks/shared/text_inline_formatter_new.py +0 -139
- notionary/blocks/toggleable_heading/toggleable_heading_models.py +0 -0
- notionary/database/models/page_result.py +0 -10
- notionary/models/notion_block_response.py +0 -264
- notionary/models/notion_page_response.py +0 -78
- notionary/models/search_response.py +0 -0
- notionary/page/__init__.py +0 -0
- notionary/page/content/notion_text_length_utils.py +0 -87
- notionary/page/content/page_content_retriever.py +0 -52
- notionary/page/formatting/line_processor.py +0 -153
- notionary/page/formatting/markdown_to_notion_converter.py +0 -153
- notionary/page/markdown_syntax_prompt_generator.py +0 -114
- notionary/page/notion_to_markdown_converter.py +0 -179
- notionary/page/properites/property_value_extractor.py +0 -0
- notionary-0.2.18.dist-info/RECORD +0 -149
- /notionary/{blocks/document/document_models.py → markdown/___init__.py} +0 -0
- /notionary/{blocks/image/image_models.py → markdown/makdown_document_model.py} +0 -0
- /notionary/page/{content/markdown_whitespace_processor.py → markdown_whitespace_processor.py} +0 -0
- /notionary/{blocks/mention/mention_models.py → page/reader/handler/context.py} +0 -0
- {notionary-0.2.18.dist-info → notionary-0.2.21.dist-info}/LICENSE +0 -0
- {notionary-0.2.18.dist-info → notionary-0.2.21.dist-info}/WHEEL +0 -0
@@ -1,153 +0,0 @@
|
|
1
|
-
from notionary.blocks import ColumnElement, BlockRegistry
|
2
|
-
from notionary.page.formatting.line_processor import LineProcessor
|
3
|
-
|
4
|
-
|
5
|
-
class MarkdownToNotionConverter:
|
6
|
-
"""Clean converter focused on block identification and conversion"""
|
7
|
-
|
8
|
-
def __init__(self, block_registry: BlockRegistry):
|
9
|
-
self._block_registry = block_registry
|
10
|
-
self._pipe_content_pattern = r"^\|\s?(.*)$"
|
11
|
-
self._toggle_element_types = ["ToggleElement", "ToggleableHeadingElement"]
|
12
|
-
|
13
|
-
# Setup column element callback if available
|
14
|
-
if self._block_registry.contains(ColumnElement):
|
15
|
-
ColumnElement.set_converter_callback(self.convert)
|
16
|
-
|
17
|
-
def convert(self, markdown_text: str) -> list[dict[str, any]]:
|
18
|
-
"""Convert markdown text to Notion API block format"""
|
19
|
-
if not markdown_text:
|
20
|
-
return []
|
21
|
-
|
22
|
-
# Main conversion pipeline
|
23
|
-
blocks_with_positions = self._identify_all_blocks(markdown_text)
|
24
|
-
blocks_with_positions.sort(key=lambda x: x[0]) # Sort by position
|
25
|
-
|
26
|
-
# Flatten blocks (some elements return lists of blocks)
|
27
|
-
result = []
|
28
|
-
for _, _, block in blocks_with_positions:
|
29
|
-
if isinstance(block, list):
|
30
|
-
result.extend(block)
|
31
|
-
else:
|
32
|
-
result.append(block)
|
33
|
-
return result
|
34
|
-
|
35
|
-
def _identify_all_blocks(
|
36
|
-
self, markdown_text: str
|
37
|
-
) -> list[tuple[int, int, dict[str, any]]]:
|
38
|
-
"""Main block identification pipeline"""
|
39
|
-
all_blocks = []
|
40
|
-
|
41
|
-
# 1. Process complex multiline blocks first (toggles, etc.)
|
42
|
-
toggleable_blocks = self._find_toggleable_blocks(markdown_text)
|
43
|
-
all_blocks.extend(toggleable_blocks)
|
44
|
-
|
45
|
-
# 2. Process other multiline blocks
|
46
|
-
multiline_blocks = self._find_multiline_blocks(markdown_text, toggleable_blocks)
|
47
|
-
all_blocks.extend(multiline_blocks)
|
48
|
-
|
49
|
-
# 3. Process remaining text line by line
|
50
|
-
processed_blocks = toggleable_blocks + multiline_blocks
|
51
|
-
line_blocks = self._process_remaining_lines(markdown_text, processed_blocks)
|
52
|
-
all_blocks.extend(line_blocks)
|
53
|
-
|
54
|
-
return all_blocks
|
55
|
-
|
56
|
-
def _find_toggleable_blocks(
|
57
|
-
self, text: str
|
58
|
-
) -> list[tuple[int, int, dict[str, any]]]:
|
59
|
-
"""Find all toggleable blocks (Toggle and ToggleableHeading)"""
|
60
|
-
toggleable_elements = self._get_elements_by_type(
|
61
|
-
self._toggle_element_types, multiline_only=True
|
62
|
-
)
|
63
|
-
|
64
|
-
blocks = []
|
65
|
-
for element in toggleable_elements:
|
66
|
-
matches = element.find_matches(text, self.convert, context_aware=True)
|
67
|
-
if matches:
|
68
|
-
blocks.extend(matches)
|
69
|
-
|
70
|
-
return blocks
|
71
|
-
|
72
|
-
def _find_multiline_blocks(
|
73
|
-
self, text: str, exclude_blocks: list[tuple[int, int, dict[str, any]]]
|
74
|
-
) -> list[tuple[int, int, dict[str, any]]]:
|
75
|
-
"""Find all multiline blocks except toggleable ones"""
|
76
|
-
multiline_elements = [
|
77
|
-
element
|
78
|
-
for element in self._block_registry.get_multiline_elements()
|
79
|
-
if element.__name__ not in self._toggle_element_types
|
80
|
-
]
|
81
|
-
|
82
|
-
excluded_ranges = self._create_excluded_ranges(exclude_blocks)
|
83
|
-
|
84
|
-
blocks = []
|
85
|
-
for element in multiline_elements:
|
86
|
-
matches = element.find_matches(text)
|
87
|
-
|
88
|
-
for start_pos, end_pos, block in matches:
|
89
|
-
if not self._overlaps_with_ranges(start_pos, end_pos, excluded_ranges):
|
90
|
-
# Handle multiple blocks from single element
|
91
|
-
element_blocks = self._normalize_to_list(block)
|
92
|
-
|
93
|
-
current_pos = start_pos
|
94
|
-
for i, single_block in enumerate(element_blocks):
|
95
|
-
blocks.append((current_pos, end_pos, single_block))
|
96
|
-
# Increment position for subsequent blocks
|
97
|
-
current_pos = end_pos + i + 1
|
98
|
-
|
99
|
-
return blocks
|
100
|
-
|
101
|
-
def _process_remaining_lines(
|
102
|
-
self, text: str, exclude_blocks: list[tuple[int, int, dict[str, any]]]
|
103
|
-
) -> list[tuple[int, int, dict[str, any]]]:
|
104
|
-
"""Process text line by line, excluding already processed ranges"""
|
105
|
-
if not text:
|
106
|
-
return []
|
107
|
-
|
108
|
-
excluded_ranges = self._create_excluded_ranges(exclude_blocks)
|
109
|
-
processor = LineProcessor(
|
110
|
-
block_registry=self._block_registry,
|
111
|
-
excluded_ranges=excluded_ranges,
|
112
|
-
pipe_pattern=self._pipe_content_pattern,
|
113
|
-
)
|
114
|
-
|
115
|
-
return processor.process_lines(text)
|
116
|
-
|
117
|
-
def _get_elements_by_type(
|
118
|
-
self, type_names: list[str], multiline_only: bool = False
|
119
|
-
) -> list[any]:
|
120
|
-
"""Get elements from registry by type names"""
|
121
|
-
elements = (
|
122
|
-
self._block_registry.get_multiline_elements()
|
123
|
-
if multiline_only
|
124
|
-
else self._block_registry.get_elements()
|
125
|
-
)
|
126
|
-
|
127
|
-
return [
|
128
|
-
element
|
129
|
-
for element in elements
|
130
|
-
if element.__name__ in type_names and hasattr(element, "match_markdown")
|
131
|
-
]
|
132
|
-
|
133
|
-
def _create_excluded_ranges(
|
134
|
-
self, exclude_blocks: list[tuple[int, int, dict[str, any]]]
|
135
|
-
) -> set[int]:
|
136
|
-
"""Create set of excluded positions from block ranges"""
|
137
|
-
excluded_positions = set()
|
138
|
-
for start_pos, end_pos, _ in exclude_blocks:
|
139
|
-
excluded_positions.update(range(start_pos, end_pos + 1))
|
140
|
-
return excluded_positions
|
141
|
-
|
142
|
-
def _overlaps_with_ranges(
|
143
|
-
self, start_pos: int, end_pos: int, excluded_ranges: set[int]
|
144
|
-
) -> bool:
|
145
|
-
"""Check if a range overlaps with excluded positions"""
|
146
|
-
return any(pos in excluded_ranges for pos in range(start_pos, end_pos + 1))
|
147
|
-
|
148
|
-
@staticmethod
|
149
|
-
def _normalize_to_list(result) -> list[dict[str, any]]:
|
150
|
-
"""Normalize Union[list[dict], dict] to list[dict]"""
|
151
|
-
if result is None:
|
152
|
-
return []
|
153
|
-
return result if isinstance(result, list) else [result]
|
@@ -1,114 +0,0 @@
|
|
1
|
-
from typing import Type, List
|
2
|
-
from notionary.blocks import NotionBlockElement
|
3
|
-
|
4
|
-
|
5
|
-
class MarkdownSyntaxPromptGenerator:
|
6
|
-
"""
|
7
|
-
Generator for LLM system prompts that describe Notion-Markdown syntax.
|
8
|
-
|
9
|
-
This class extracts information about supported Markdown patterns
|
10
|
-
and formats them optimally for LLMs.
|
11
|
-
"""
|
12
|
-
|
13
|
-
SYSTEM_PROMPT_TEMPLATE = """
|
14
|
-
You create content for Notion pages using Markdown syntax with special Notion extensions.
|
15
|
-
|
16
|
-
# Understanding Notion Blocks
|
17
|
-
|
18
|
-
Notion documents are composed of individual blocks. Each block has a specific type (paragraph, heading, list item, etc.) and format.
|
19
|
-
The Markdown syntax you use directly maps to these Notion blocks.
|
20
|
-
|
21
|
-
{element_docs}
|
22
|
-
|
23
|
-
CRITICAL USAGE GUIDELINES:
|
24
|
-
|
25
|
-
1. Do NOT start content with a level 1 heading (# Heading). In Notion, the page title is already displayed in the metadata, so starting with an H1 heading is redundant. Begin with H2 (## Heading) or lower for section headings.
|
26
|
-
|
27
|
-
2. BACKTICK HANDLING - EXTREMELY IMPORTANT:
|
28
|
-
- NEVER wrap entire content or responses in triple backticks (```).
|
29
|
-
- DO NOT use triple backticks (```) for anything except CODE BLOCKS or DIAGRAMS.
|
30
|
-
- DO NOT use triple backticks to mark or highlight regular text or examples.
|
31
|
-
- USE triple backticks ONLY for actual programming code, pseudocode, or specialized notation.
|
32
|
-
- For inline code, use single backticks (`code`).
|
33
|
-
- When showing Markdown syntax examples, use inline code formatting with single backticks.
|
34
|
-
|
35
|
-
3. CONTENT FORMATTING - CRITICAL:
|
36
|
-
- DO NOT include introductory phrases like "I understand that..." or "Here's the content...".
|
37
|
-
- Provide ONLY the requested content directly without any prefacing text or meta-commentary.
|
38
|
-
- Generate just the content itself, formatted according to these guidelines.
|
39
|
-
- USE INLINE FORMATTING to enhance readability:
|
40
|
-
- Use *italic* for emphasis, terminology, and definitions
|
41
|
-
- Use `code` for technical terms, file paths, variables, and commands
|
42
|
-
- Use **bold** sparingly for truly important information
|
43
|
-
- Use appropriate inline formatting naturally throughout the content, but don't overuse it
|
44
|
-
|
45
|
-
4. USER INSTRUCTIONS - VERY IMPORTANT:
|
46
|
-
- Follow the user's formatting instructions EXACTLY and in the specified order
|
47
|
-
- When the user requests specific elements (e.g., "first a callout, then 4 bullet points"), create them in that precise sequence
|
48
|
-
- Adhere strictly to any structural requirements provided by the user
|
49
|
-
- Do not deviate from or reinterpret the user's formatting requests
|
50
|
-
|
51
|
-
5. ADD EMOJIS TO HEADINGS - REQUIRED UNLESS EXPLICITLY TOLD NOT TO:
|
52
|
-
- ALWAYS add appropriate emojis at the beginning of headings to improve structure and readability
|
53
|
-
- Choose emojis that represent the content or theme of each section
|
54
|
-
- Format as: ## 🚀 Heading Text (with space after emoji)
|
55
|
-
- Only omit emojis if the user explicitly instructs you not to use them
|
56
|
-
"""
|
57
|
-
|
58
|
-
@staticmethod
|
59
|
-
def generate_element_doc(element_class: Type[NotionBlockElement]) -> str:
|
60
|
-
"""
|
61
|
-
Generates documentation for a specific NotionBlockElement in a compact format.
|
62
|
-
Uses the element's get_llm_prompt_content method if available.
|
63
|
-
"""
|
64
|
-
class_name = element_class.__name__
|
65
|
-
element_name = class_name.replace("Element", "")
|
66
|
-
|
67
|
-
content = element_class.get_llm_prompt_content()
|
68
|
-
|
69
|
-
doc_parts = [
|
70
|
-
f"## {element_name}",
|
71
|
-
f"{content.description}",
|
72
|
-
f"**Syntax:** {content.syntax}",
|
73
|
-
]
|
74
|
-
|
75
|
-
if content.examples:
|
76
|
-
doc_parts.append("**Examples:**")
|
77
|
-
for example in content.examples:
|
78
|
-
doc_parts.append(example)
|
79
|
-
|
80
|
-
doc_parts.append(f"**When to use:** {content.when_to_use}")
|
81
|
-
|
82
|
-
if content.avoid:
|
83
|
-
doc_parts.append(f"**Avoid:** {content.avoid}")
|
84
|
-
|
85
|
-
return "\n".join([part for part in doc_parts if part])
|
86
|
-
|
87
|
-
@classmethod
|
88
|
-
def generate_element_docs(
|
89
|
-
cls, element_classes: List[Type[NotionBlockElement]]
|
90
|
-
) -> str:
|
91
|
-
"""
|
92
|
-
Generates complete documentation for all provided element classes.
|
93
|
-
"""
|
94
|
-
docs = [
|
95
|
-
"# Markdown Syntax for Notion Blocks",
|
96
|
-
"The following Markdown patterns are supported for creating Notion blocks:",
|
97
|
-
]
|
98
|
-
|
99
|
-
# Generate docs for each element
|
100
|
-
for element in element_classes:
|
101
|
-
docs.append("\n" + cls.generate_element_doc(element))
|
102
|
-
|
103
|
-
return "\n".join(docs)
|
104
|
-
|
105
|
-
@classmethod
|
106
|
-
def generate_system_prompt(
|
107
|
-
cls,
|
108
|
-
element_classes: List[Type[NotionBlockElement]],
|
109
|
-
) -> str:
|
110
|
-
"""
|
111
|
-
Generates a complete system prompt for LLMs.
|
112
|
-
"""
|
113
|
-
element_docs = cls.generate_element_docs(element_classes)
|
114
|
-
return cls.SYSTEM_PROMPT_TEMPLATE.format(element_docs=element_docs)
|
@@ -1,179 +0,0 @@
|
|
1
|
-
from typing import Dict, Any
|
2
|
-
|
3
|
-
|
4
|
-
class NotionToMarkdownConverter:
|
5
|
-
"""Converts Notion blocks to Markdown text with support for nested structures."""
|
6
|
-
|
7
|
-
TOGGLE_ELEMENT_TYPES = ["toggle", "toggleable_heading"]
|
8
|
-
LIST_ITEM_TYPES = ["numbered_list_item", "bulleted_list_item"]
|
9
|
-
|
10
|
-
def __init__(self, block_registry):
|
11
|
-
"""
|
12
|
-
Initialize the NotionToMarkdownConverter.
|
13
|
-
"""
|
14
|
-
self._block_registry = block_registry
|
15
|
-
|
16
|
-
def convert(self, blocks: list[Dict[str, Any]]) -> str:
|
17
|
-
"""
|
18
|
-
Convert Notion blocks to Markdown text, handling nested structures.
|
19
|
-
"""
|
20
|
-
if not blocks:
|
21
|
-
return ""
|
22
|
-
|
23
|
-
markdown_parts = []
|
24
|
-
|
25
|
-
for block in blocks:
|
26
|
-
block_markdown = self._convert_single_block_with_children(block)
|
27
|
-
if block_markdown:
|
28
|
-
markdown_parts.append(block_markdown)
|
29
|
-
|
30
|
-
return "\n\n".join(filter(None, markdown_parts))
|
31
|
-
|
32
|
-
def _convert_single_block_with_children(self, block: Dict[str, Any]) -> str:
|
33
|
-
"""
|
34
|
-
Process a single block, including any children.
|
35
|
-
"""
|
36
|
-
if not block:
|
37
|
-
return ""
|
38
|
-
|
39
|
-
block_markdown = self._block_registry.notion_to_markdown(block)
|
40
|
-
|
41
|
-
if not self._has_children(block):
|
42
|
-
return block_markdown
|
43
|
-
|
44
|
-
children_markdown = self.convert(block["children"])
|
45
|
-
if not children_markdown:
|
46
|
-
return block_markdown
|
47
|
-
|
48
|
-
block_type = block.get("type", "")
|
49
|
-
|
50
|
-
if block_type in self.TOGGLE_ELEMENT_TYPES:
|
51
|
-
return self._format_toggle_with_children(block_markdown, children_markdown)
|
52
|
-
|
53
|
-
if block_type in self.LIST_ITEM_TYPES:
|
54
|
-
return self._format_list_item_with_children(
|
55
|
-
block_markdown, children_markdown
|
56
|
-
)
|
57
|
-
|
58
|
-
return self._format_standard_block_with_children(
|
59
|
-
block_markdown, children_markdown
|
60
|
-
)
|
61
|
-
|
62
|
-
def _has_children(self, block: Dict[str, Any]) -> bool:
|
63
|
-
"""
|
64
|
-
Check if block has children that need processing.
|
65
|
-
"""
|
66
|
-
return block.get("has_children", False) and "children" in block
|
67
|
-
|
68
|
-
def _format_toggle_with_children(
|
69
|
-
self, toggle_markdown: str, children_markdown: str
|
70
|
-
) -> str:
|
71
|
-
"""
|
72
|
-
Format toggle or toggleable_heading block with its children content.
|
73
|
-
"""
|
74
|
-
indented_children = self._indent_text(children_markdown)
|
75
|
-
return f"{toggle_markdown}\n{indented_children}"
|
76
|
-
|
77
|
-
def _format_list_item_with_children(
|
78
|
-
self, item_markdown: str, children_markdown: str
|
79
|
-
) -> str:
|
80
|
-
"""
|
81
|
-
Format list item with its children content.
|
82
|
-
"""
|
83
|
-
indented_children = self._indent_text(children_markdown)
|
84
|
-
return f"{item_markdown}\n{indented_children}"
|
85
|
-
|
86
|
-
def _format_standard_block_with_children(
|
87
|
-
self, block_markdown: str, children_markdown: str
|
88
|
-
) -> str:
|
89
|
-
"""
|
90
|
-
Format standard block with its children content.
|
91
|
-
"""
|
92
|
-
return f"{block_markdown}\n\n{children_markdown}"
|
93
|
-
|
94
|
-
def _indent_text(self, text: str, spaces: int = 4) -> str:
|
95
|
-
"""
|
96
|
-
Indent each line of text with specified number of spaces.
|
97
|
-
"""
|
98
|
-
indent = " " * spaces
|
99
|
-
return "\n".join([f"{indent}{line}" for line in text.split("\n")])
|
100
|
-
|
101
|
-
def extract_toggle_content(self, blocks: list[Dict[str, Any]]) -> str:
|
102
|
-
"""
|
103
|
-
Extract only the content of toggles from blocks.
|
104
|
-
"""
|
105
|
-
if not blocks:
|
106
|
-
return ""
|
107
|
-
|
108
|
-
toggle_contents = []
|
109
|
-
|
110
|
-
for block in blocks:
|
111
|
-
self._extract_toggle_content_recursive(block, toggle_contents)
|
112
|
-
|
113
|
-
return "\n".join(toggle_contents)
|
114
|
-
|
115
|
-
def _extract_toggle_content_recursive(
|
116
|
-
self, block: Dict[str, Any], result: list[str]
|
117
|
-
) -> None:
|
118
|
-
"""
|
119
|
-
Recursively extract toggle content from a block and its children.
|
120
|
-
"""
|
121
|
-
if self._is_toggle_or_heading_with_children(block):
|
122
|
-
self._add_toggle_header_to_result(block, result)
|
123
|
-
self._add_toggle_children_to_result(block, result)
|
124
|
-
|
125
|
-
if self._has_children(block):
|
126
|
-
for child in block["children"]:
|
127
|
-
self._extract_toggle_content_recursive(child, result)
|
128
|
-
|
129
|
-
def _is_toggle_or_heading_with_children(self, block: Dict[str, Any]) -> bool:
|
130
|
-
"""
|
131
|
-
Check if block is a toggle or toggleable_heading with children.
|
132
|
-
"""
|
133
|
-
return block.get("type") in self.TOGGLE_ELEMENT_TYPES and "children" in block
|
134
|
-
|
135
|
-
def _add_toggle_header_to_result(
|
136
|
-
self, block: Dict[str, Any], result: list[str]
|
137
|
-
) -> None:
|
138
|
-
"""
|
139
|
-
Add toggle header text to result list.
|
140
|
-
"""
|
141
|
-
block_type = block.get("type")
|
142
|
-
rich_text = None
|
143
|
-
|
144
|
-
if block_type == "toggle":
|
145
|
-
rich_text = block.get("toggle", {}).get("rich_text", [])
|
146
|
-
elif block_type == "toggleable_heading":
|
147
|
-
rich_text = block.get("toggleable_heading", {}).get("rich_text", [])
|
148
|
-
|
149
|
-
toggle_text = self._extract_text_from_rich_text(rich_text or [])
|
150
|
-
|
151
|
-
if toggle_text:
|
152
|
-
result.append(f"### {toggle_text}")
|
153
|
-
|
154
|
-
def _add_toggle_children_to_result(
|
155
|
-
self, block: Dict[str, Any], result: list[str]
|
156
|
-
) -> None:
|
157
|
-
"""
|
158
|
-
Add formatted toggle children to result list.
|
159
|
-
"""
|
160
|
-
for child in block.get("children", []):
|
161
|
-
child_type = child.get("type")
|
162
|
-
if not (child_type and child_type in child):
|
163
|
-
continue
|
164
|
-
|
165
|
-
child_text = self._extract_text_from_rich_text(
|
166
|
-
child.get(child_type, {}).get("rich_text", [])
|
167
|
-
)
|
168
|
-
|
169
|
-
if child_text:
|
170
|
-
result.append(f"- {child_text}")
|
171
|
-
|
172
|
-
def _extract_text_from_rich_text(self, rich_text: list[Dict[str, Any]]) -> str:
|
173
|
-
"""
|
174
|
-
Extract plain text from Notion's rich text array.
|
175
|
-
"""
|
176
|
-
if not rich_text:
|
177
|
-
return ""
|
178
|
-
|
179
|
-
return "".join([rt.get("plain_text", "") for rt in rich_text])
|
File without changes
|
@@ -1,149 +0,0 @@
|
|
1
|
-
notionary/__init__.py,sha256=klSdVgq1HZ6OU8bPo3YsyG7RTKCth5MjM8SkI7EH7Is,534
|
2
|
-
notionary/base_notion_client.py,sha256=WIAIKZeGCeAwtHWnL4Kfcmzv2TBlxvz7cfGF26i89y0,7067
|
3
|
-
notionary/blocks/__init__.py,sha256=CzHZg3ml2HD96fXRIgu-WXlH86UfQrlV77NdXN1C6UI,3155
|
4
|
-
notionary/blocks/audio/__init__.py,sha256=0GSTSbjAu4RV56qm22_xd7JkDRvrJNRDgGPTJT1leIQ,158
|
5
|
-
notionary/blocks/audio/audio_element.py,sha256=sjKTJR23whKTdp5pzkphTmd4q2hIFMwQvo6Qyoov3c0,5344
|
6
|
-
notionary/blocks/audio/audio_markdown_node.py,sha256=y0-qgrUM06XUFLdHhszC5OChhSRHpHKYXmOhEXrtetQ,831
|
7
|
-
notionary/blocks/audio/audio_models.py,sha256=rMNzvvhj8gYFKNALCT1oDdmuI6I5zlJgmVyENzij21s,1472
|
8
|
-
notionary/blocks/bookmark/__init__.py,sha256=ewtAXUCrqzY3VZ30A3SJf3lf5x_aX1K7u_HGDj0mVR8,176
|
9
|
-
notionary/blocks/bookmark/bookmark_element.py,sha256=OrDRXdCO6VzIY6OuNj9BNJuobEoGM3IUoO1fVjz_SoM,6148
|
10
|
-
notionary/blocks/bookmark/bookmark_markdown_node.py,sha256=39Uh518tTutU4_UDFQlpAY8lHgiCLW0_a9Kt7EMhsvg,1440
|
11
|
-
notionary/blocks/bookmark/bookmark_models.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
12
|
-
notionary/blocks/bulleted_list/__init__.py,sha256=7hlIuGEp29mCZX_HOA2LksJr1wOUggwGKe-g08WxadY,202
|
13
|
-
notionary/blocks/bulleted_list/bulleted_list_element.py,sha256=g6nYmLisJh8zhXTPZO6DPsNZK4NaeZp8fqB2YJ89Pqo,2639
|
14
|
-
notionary/blocks/bulleted_list/bulleted_list_markdown_node.py,sha256=B7MP6dwCgwoyaeGmbGdvCsPNUhLHUl7oElV8-h-rzhY,823
|
15
|
-
notionary/blocks/bulleted_list/bulleted_list_models.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
16
|
-
notionary/blocks/callout/__init__.py,sha256=PQnqH15cj1u5GVvbGm6jsWA_zN9SH7maSNNPP7quiUg,170
|
17
|
-
notionary/blocks/callout/callout_element.py,sha256=jn8DOCW86fuavZrjRu3AvW3aEj_P0jXmOyc7Av4tfVs,4553
|
18
|
-
notionary/blocks/callout/callout_markdown_node.py,sha256=sRy-F5kXPQRQU1HEnOPbZaJZ-nxDD8XmLHBIQFQOUDE,942
|
19
|
-
notionary/blocks/callout/callout_models.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
20
|
-
notionary/blocks/code/__init__.py,sha256=24uLJhL8tcGXWX1eNT9YYzZ6qKobQnxYoe5lASTOwzc,152
|
21
|
-
notionary/blocks/code/code_element.py,sha256=EV21-3VhW6ItrGq497bAgG_SKl65YuXb486XjixJIes,8732
|
22
|
-
notionary/blocks/code/code_markdown_node.py,sha256=DxWeiovmO9aP4eTX98ihMNQfwdZeItXOgO2J0YfkNf0,1191
|
23
|
-
notionary/blocks/code/code_models.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
24
|
-
notionary/blocks/column/__init__.py,sha256=QAC1nPTy8fQIBke1liI5sILFCyvN92yrjBTIRnVd6lE,83
|
25
|
-
notionary/blocks/column/column_element.py,sha256=MU6fY0WdzJz5XI8MHe-Nl_vadSXWHCrHXQKWgvEnVAY,11615
|
26
|
-
notionary/blocks/column/column_models.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
27
|
-
notionary/blocks/divider/__init__.py,sha256=gxDX3HtNXSjqqyu3j7LcpcxnxobTjKlS2nj_Zf9VSpc,170
|
28
|
-
notionary/blocks/divider/divider_element.py,sha256=RGM0X7Y_mQnBnPC2rRb9rdlYuHDhaiCRurHkaGJf4H8,2443
|
29
|
-
notionary/blocks/divider/divider_markdown_node.py,sha256=PtUyYSDGAiGBfP7AKEpAP3XERpEi75qyz2_MFZ0U4jk,579
|
30
|
-
notionary/blocks/divider/divider_models.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
31
|
-
notionary/blocks/document/__init__.py,sha256=KF_7ISXLqvEESomvERpLFwUxy2g5IYWR-uuZajfjt0Y,176
|
32
|
-
notionary/blocks/document/document_element.py,sha256=7gEOpv3CeryxkOQ5mrJI-yVKYFq8nzq7d5af0qVEmAo,4022
|
33
|
-
notionary/blocks/document/document_markdown_node.py,sha256=vtqTgyZ2xnxbIocpfg2UYCGffx4aCp7Ng9mvK14v9DA,1058
|
34
|
-
notionary/blocks/document/document_models.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
35
|
-
notionary/blocks/embed/__init__.py,sha256=7fEUdAsekiE3wc2YjbUOEFXqD77602q22KyPKqP9ns0,158
|
36
|
-
notionary/blocks/embed/embed_element.py,sha256=A0hX_wBbvEbq0yd5pcWpNQIOcNBVn0JDBC1p3HJ9_2U,5080
|
37
|
-
notionary/blocks/embed/embed_markdown_node.py,sha256=HFh9lMjV3zQz0HPEG7ib77i2PKt6PwZIXpokcjrdh8U,902
|
38
|
-
notionary/blocks/embed/embed_models.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
39
|
-
notionary/blocks/heading/__init__.py,sha256=OUFLp3Oketw4BTiqqxld9Hp-I-_oUWYL630IltZK6xA,170
|
40
|
-
notionary/blocks/heading/heading_element.py,sha256=BQDjSwnd9vpu-qxaKgOb0TBqfy8koT5YH6BTDgtbXm0,3447
|
41
|
-
notionary/blocks/heading/heading_markdown_node.py,sha256=XIfoxPdBihykAySQTfV94-WIU0cMsUxtfbhgiEIiP7Y,877
|
42
|
-
notionary/blocks/heading/heading_models.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
43
|
-
notionary/blocks/image/__init__.py,sha256=4ky2S6bYkrsfswati_bRwrl6IVaFqCJlLDJROS7IvOA,158
|
44
|
-
notionary/blocks/image/image_element.py,sha256=5MjO3ZaJTh2ld8J5f9JlgSU9O4mqmKV8-ztBqTSGppY,5432
|
45
|
-
notionary/blocks/image/image_markdown_node.py,sha256=hxSASo5lXEBbFHXXu9U8xPz5Z7wpWGLJqSu-RRIRhWE,1029
|
46
|
-
notionary/blocks/image/image_models.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
47
|
-
notionary/blocks/markdown_builder.py,sha256=HJKN1mmxBO_zI3D9JPPKXX10brdN1bf8Q2FEJg1ay4Q,10387
|
48
|
-
notionary/blocks/markdown_node.py,sha256=ZIbdok878aCMHnMh6k1kAftcPexQgiWFyHcSMNWepZo,715
|
49
|
-
notionary/blocks/mention/__init__.py,sha256=C6l5WqMjrD8MrA_rE0e22U-gSddlVWNVtGg8lcYfFyk,170
|
50
|
-
notionary/blocks/mention/mention_element.py,sha256=wEmw6l65CIin9rfrM4Hnb9kraRA5US0LKB-SpstjlqA,8155
|
51
|
-
notionary/blocks/mention/mention_markdown_node.py,sha256=zcKMRIWXHJzPg8C8nj5U_r2Q-WZrIPmNMcTwC-pTU60,1325
|
52
|
-
notionary/blocks/mention/mention_models.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
53
|
-
notionary/blocks/numbered_list/__init__.py,sha256=T7IMAp542u56X8vooRbs1NcbggMRDQ778QSCxMyifbA,202
|
54
|
-
notionary/blocks/numbered_list/numbered_list_element.py,sha256=UA_VKldZ8bxRSe4qnikvTMcTyIM5BsRZf5QOlmAZxo8,2630
|
55
|
-
notionary/blocks/numbered_list/numbered_list_markdown_node.py,sha256=BTyfhoInvTcw-6zSRtIzBNjIOpQvHPtqoXBp3bKrkgY,779
|
56
|
-
notionary/blocks/numbered_list/numbered_list_models.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
57
|
-
notionary/blocks/paragraph/__init__.py,sha256=XudhEdGaD2uIdJM4saygESClU5w3TBIq38kpR8huLps,182
|
58
|
-
notionary/blocks/paragraph/paragraph_element.py,sha256=mBYiRP-pqCQuDGr9hz1qpqXNeSwbE6uoAkjOaaCsbns,3228
|
59
|
-
notionary/blocks/paragraph/paragraph_markdown_node.py,sha256=-7e5hyGVaIU3G9nqyyqlANoGjRRZKZIWKGCIAExl6vs,665
|
60
|
-
notionary/blocks/paragraph/paragraph_models.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
61
|
-
notionary/blocks/prompts/element_prompt_builder.py,sha256=rYMKPmpEFyk26JFZlwcTzMHATpvHnn4Dn284vewFog0,2953
|
62
|
-
notionary/blocks/prompts/element_prompt_content.py,sha256=ItnhGwKsHGnnY9E_LGgZZeTCT9ZfnkJY8xad4wFViWk,1567
|
63
|
-
notionary/blocks/quote/__init__.py,sha256=rZ8-t7a2TAN57flHXkaynodRat8vLZ07y2Rz3rpbur0,158
|
64
|
-
notionary/blocks/quote/quote_element.py,sha256=KuRi22nMC621JtYCCxItGJSTSkYrxZqaxUFXviX7xV4,3174
|
65
|
-
notionary/blocks/quote/quote_markdown_node.py,sha256=XNlo-8rm3s6k08dy4m-kQ7llo5jdm_EKSicN9xcK2Z0,636
|
66
|
-
notionary/blocks/quote/quote_models.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
67
|
-
notionary/blocks/registry/block_registry.py,sha256=O0yo3B6QIZa-a6gClt_rzaxO_ijwsYc5clv2B0NLCQw,5366
|
68
|
-
notionary/blocks/registry/block_registry_builder.py,sha256=r7wVIjvfCRZWby9RabX9zBSeH_BuoqrRNCl-8yHwt5I,6551
|
69
|
-
notionary/blocks/shared/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
70
|
-
notionary/blocks/shared/block_client.py,sha256=EF2xYcrpJ2pF5LYSc9UNDw74Izf25gw5a05-P4CRmZE,8997
|
71
|
-
notionary/blocks/shared/models.py,sha256=UfKWmFo3e_GoDU27rrDqyi1DHVnCm-dsFayH7TWx0_I,17905
|
72
|
-
notionary/blocks/shared/notion_block_element.py,sha256=pKsGRPrSa_IqZHmer4HL5DCzFuhqo34vYXptXoXToX0,1443
|
73
|
-
notionary/blocks/shared/text_inline_formatter.py,sha256=mCqFS05oJwSU5fPoUUHVeud_hU8G4Z5mYFx7KeMY-s8,8564
|
74
|
-
notionary/blocks/shared/text_inline_formatter_new.py,sha256=nYmoFQVuAkfouCpGYULxFr4hHVCnRgvf3zxoiHBxIKg,4665
|
75
|
-
notionary/blocks/table/__init__.py,sha256=mul3r3dU5U9Z1hqa1QMlQc9aIwHM-9yKru9-RbLmWs8,158
|
76
|
-
notionary/blocks/table/table_element.py,sha256=oZV0p7gIbm7344SzSz-fKmQYmA5KS4-lcZiD8ZvxBH8,11479
|
77
|
-
notionary/blocks/table/table_markdown_node.py,sha256=pzdegpxB5bYRXsWQd7oUy-p2YjuEFdWd7NeHSd4PrRI,1398
|
78
|
-
notionary/blocks/table/table_models.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
79
|
-
notionary/blocks/todo/__init__.py,sha256=4hbX7RIqbFn1H2Tz9mb2jkmSbav6AMdleTYKfVhGGIc,152
|
80
|
-
notionary/blocks/todo/todo_element.py,sha256=WFA9chSa9Nvh0MgMObeh4DXkjTBBGJpYmMFKjQikkhI,4075
|
81
|
-
notionary/blocks/todo/todo_markdown_node.py,sha256=X578oPFA_KBzqCeY5-Be3_5TZ45QEyWayzt0MitIli8,992
|
82
|
-
notionary/blocks/todo/todo_models.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
83
|
-
notionary/blocks/toggle/__init__.py,sha256=N_-3QGKf4RPBmCF6GmYqbbmcY7K7KD10KpwsMLWAp1Y,206
|
84
|
-
notionary/blocks/toggle/toggle_element.py,sha256=Oj1Pmvdik7RmliME_maa0FfdoMM6Hvy5cS2aFyFQ114,11026
|
85
|
-
notionary/blocks/toggle/toggle_markdown_node.py,sha256=joEPiUQoC-D0fhypeJF3GaZHOYw4vuyry5OGSEZF4tY,1065
|
86
|
-
notionary/blocks/toggle/toggle_models.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
87
|
-
notionary/blocks/toggleable_heading/__init__.py,sha256=rn-8AsL9Fp04k4dA7ugmhZ0RxLJ1vuqdCHAORcvt6Ns,243
|
88
|
-
notionary/blocks/toggleable_heading/toggleable_heading_element.py,sha256=_5Acptg4wFDhxSyMm3C0UJkSv8bssS0J7p_TmNfA6Pg,9909
|
89
|
-
notionary/blocks/toggleable_heading/toggleable_heading_markdown_node.py,sha256=KFX1Xba4zW60zQf6_AWZG0YPbERZq1f7CmTqQgGNnQo,1409
|
90
|
-
notionary/blocks/toggleable_heading/toggleable_heading_models.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
91
|
-
notionary/blocks/video/__init__.py,sha256=kEhoKaHblyDyapIYj4DFhFlKm_0aQy3SCVyI5WmavJQ,158
|
92
|
-
notionary/blocks/video/video_element.py,sha256=fSPZ8yfFw6njFyZP0mGwxmHZXvM4m9Ayjb4ACc6MmhQ,6452
|
93
|
-
notionary/blocks/video/video_markdown_node.py,sha256=v4KgYJPLFy75a1d-ETya2JDf_JHy79QiQJNLw1l_jMU,903
|
94
|
-
notionary/database/__init__.py,sha256=4tdML0fBzkOCpiWT6q-L--5NELFLbTPD0IUA_E8yZno,155
|
95
|
-
notionary/database/client.py,sha256=ZcfydeYlpgGJt6wV1ib33KeXUiL-cGNJ1qraQZ4RVRc,4775
|
96
|
-
notionary/database/database.py,sha256=7KBe6DWbtsakPvjUO45eCphD2sq0ZKuYHY3kXJsk4P8,16582
|
97
|
-
notionary/database/database_filter_builder.py,sha256=PCnq3M9REt-NHRgBIfSrTCIPykUqBs5RqZK13WOAHKA,5950
|
98
|
-
notionary/database/database_provider.py,sha256=MveBSMkYG8nLUzKTS7KjbFVH8H-vLdH0t6yGArs-vPQ,8976
|
99
|
-
notionary/database/exceptions.py,sha256=jwFdxoIQHLO3mO3p5t890--1FjbTX60fNyqBAe-sszo,452
|
100
|
-
notionary/database/factory.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
101
|
-
notionary/database/models/page_result.py,sha256=Vmm5_oYpYAkIIJVoTd1ZZGloeC3cmFLMYP255mAmtaw,233
|
102
|
-
notionary/database/notion_database.py,sha256=wSqPfVtOnDL-aKRrE9BSMP1cpHe0_8RYyfCMxrlJSNo,16746
|
103
|
-
notionary/file_upload/__init__.py,sha256=7TNyiIgLMD_IGRXTwRiAmStokF3rLoG4zXPwNb9KQqk,168
|
104
|
-
notionary/file_upload/client.py,sha256=qlxgu7_Ia0wbBflInoGki4mR8Po_RZgfLjO2wa279jY,8581
|
105
|
-
notionary/file_upload/models.py,sha256=0mYtuGkZ_eh_YmX0uxqye5vg3wWgqWuwOupAmLJXMUY,1625
|
106
|
-
notionary/file_upload/notion_file_upload.py,sha256=kUwFOoYclwbyesfPWPOJPbANFJORskzUvSgC8fsn8VM,13175
|
107
|
-
notionary/models/notion_block_response.py,sha256=gzL4C6K9QPcaMS6NbAZaRceSEnMbNwYBVVzxysza5VU,6002
|
108
|
-
notionary/models/notion_database_response.py,sha256=3kvADIP1dSxgITSK4n8Ex3QpF8n_Lxnu_IXbPVGcq4o,7648
|
109
|
-
notionary/models/notion_page_response.py,sha256=7ZwDYhlyK-avix_joQpGuNQZopjlQFI8jS3nvNNumoc,1544
|
110
|
-
notionary/models/search_response.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
111
|
-
notionary/page/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
112
|
-
notionary/page/client.py,sha256=XQ72lOEwn-gO8fmhKSKHqSHs3hRmoKH0TkJ3TtblcAg,4030
|
113
|
-
notionary/page/content/markdown_whitespace_processor.py,sha256=azsYau4eDrFN9CY7kzlG-ketoVKSkqSTc1bFq_i7ggQ,2942
|
114
|
-
notionary/page/content/notion_text_length_utils.py,sha256=RZqlcolvBBR1krlTMGS8q9xiZYYDGTyxZAjKhhONQyk,2757
|
115
|
-
notionary/page/content/page_content_retriever.py,sha256=9LP7DNQLcNdGCMj-18r0VPLXqlJvRB5iwDGsAbp6bYo,1581
|
116
|
-
notionary/page/content/page_content_writer.py,sha256=0evYwdR7dSWECer_nHGAQsXbbkcbpnGQuacNXp14nG8,5656
|
117
|
-
notionary/page/formatting/line_processor.py,sha256=zr1P2zG0lSGgBlP1KbFvcnazOUTHGnF_uQeFUtLakfw,5404
|
118
|
-
notionary/page/formatting/markdown_to_notion_converter.py,sha256=8UyAkkCbubkasBfV9lat1l-2Wkn6S8DwiSPJaDewslI,6027
|
119
|
-
notionary/page/markdown_syntax_prompt_generator.py,sha256=uHCPNV9aQi3GzLVimyUKwza29hfxu6DTMVIa_QevJbk,4987
|
120
|
-
notionary/page/notion_page.py,sha256=5RbKxlA2RBoGiNXjO4bvgV9OMIIKwsTPbM3XolDOU2w,19026
|
121
|
-
notionary/page/notion_to_markdown_converter.py,sha256=3zvP1HSnUp3YlvK3PfIqh8GUi7xAuVWGQB0c38uK5VU,6117
|
122
|
-
notionary/page/properites/property_value_extractor.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
123
|
-
notionary/page/property_formatter.py,sha256=_978ViH83gfcr-XtDscWTfyBI2srGW2hzC-gzgp5NR8,3788
|
124
|
-
notionary/page/search_filter_builder.py,sha256=wZpW_KHmPXql3sNIyQd9EzZ2-ERy2i0vYNdoLkoBUfc,4597
|
125
|
-
notionary/page/utils.py,sha256=2nfBrWeczBdPH13R3q8dKP4OY4MwEdfKbcs2UJ9kg1o,2041
|
126
|
-
notionary/telemetry/__init__.py,sha256=Y7KyXeN4PiA6GtzV3NnwoH4hJnPwdjikWP22ckPYuHM,511
|
127
|
-
notionary/telemetry/service.py,sha256=DD7RbkSN0HWRK2YpOJTgFD7PeXGhSe9KrLkhiVIaC7Y,4763
|
128
|
-
notionary/telemetry/views.py,sha256=FgFZGYaxP7pRYx-9wg18skMh_MJAwf4W3rCfe9JOZe4,1796
|
129
|
-
notionary/user/__init__.py,sha256=D8r_WtQimdT-l3P1wd8O9Iki5JXF7jg2KV_hOgzWraw,281
|
130
|
-
notionary/user/base_notion_user.py,sha256=QB1701CfQTeu1ZNWOHYnGvTSHZuiritr6xYNMqyVg_U,1500
|
131
|
-
notionary/user/client.py,sha256=v8-lpyKzY_gSWPdWkBEjqxEPSg1WCy9AYSAJLXRrfKA,4563
|
132
|
-
notionary/user/models.py,sha256=3WPUysO96hMZUZYUWoCH5cdqNvnWgdiw5Qd7QKOv2UY,2063
|
133
|
-
notionary/user/notion_bot_user.py,sha256=cwrwmfst5RbAgppIjoFMJjExms1epfRM9VBd-S-3y5Q,7784
|
134
|
-
notionary/user/notion_user.py,sha256=l0GOMakk_xzsUUt7SsDJ5j-3dbtX64cUyyQPxn0r0Zc,8512
|
135
|
-
notionary/user/notion_user_manager.py,sha256=JQddAvbKJiLCLCn0mfxmvoi5uLW95vHhMWEYZD_F9zk,6339
|
136
|
-
notionary/user/notion_user_provider.py,sha256=7ImQ7T76g88W4YyHGOoO0aUJQfdGlhbh1fMT9PzR1mU,19
|
137
|
-
notionary/util/__init__.py,sha256=Bu2yGFd3xPasBrMRMk-6DcmMXfkdXn-KfFRETApBcP8,351
|
138
|
-
notionary/util/factory_decorator.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
139
|
-
notionary/util/factory_only.py,sha256=q-ZXUEvQ8lsuD1JQwx-ai6e9Lhie65waRE1BcRhCR_4,1235
|
140
|
-
notionary/util/fuzzy.py,sha256=lTlWuYEs0lhLa7QIRre3GVJ8-biIV_NmcJnMzBYFF5U,2061
|
141
|
-
notionary/util/logging_mixin.py,sha256=t08dx3nhSJq2-6_N8G39aydPEkQ76D4MlRfymxCsCVM,1690
|
142
|
-
notionary/util/page_id_utils.py,sha256=AA00kRO-g3Cc50tf_XW_tb5RBuPKLuBxRa0D8LYhLXg,736
|
143
|
-
notionary/util/singleton.py,sha256=CKAvykndwPRZsA3n3MAY_XdCR59MBjjKP0vtm2BcvF0,428
|
144
|
-
notionary/util/singleton_metaclass.py,sha256=uNeHiqS6TwhljvG1RE4NflIp2HyMuMmrCg2xI-vxmHE,809
|
145
|
-
notionary/workspace.py,sha256=hp5JPVT_aQsZNuxg2R-DiODobcGlVP4CusxNhzpnxKw,3813
|
146
|
-
notionary-0.2.18.dist-info/LICENSE,sha256=zOm3cRT1qD49eg7vgw95MI79rpUAZa1kRBFwL2FkAr8,1120
|
147
|
-
notionary-0.2.18.dist-info/METADATA,sha256=AmwT7ZFt4QDIojNXfiD-DNAT6byaofyDMd8IrXmZ0Hw,6867
|
148
|
-
notionary-0.2.18.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
149
|
-
notionary-0.2.18.dist-info/RECORD,,
|
File without changes
|
File without changes
|
/notionary/page/{content/markdown_whitespace_processor.py → markdown_whitespace_processor.py}
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|