notionary 0.2.26__py3-none-any.whl → 0.2.28__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 +5 -20
- notionary/blocks/client.py +87 -215
- notionary/blocks/enums.py +167 -0
- notionary/blocks/rich_text/markdown_rich_text_converter.py +266 -0
- notionary/blocks/rich_text/models.py +164 -0
- notionary/blocks/rich_text/name_id_resolver/__init__.py +11 -0
- notionary/blocks/rich_text/name_id_resolver/database.py +31 -0
- notionary/blocks/rich_text/name_id_resolver/page.py +34 -0
- notionary/blocks/rich_text/name_id_resolver/person.py +37 -0
- notionary/blocks/rich_text/name_id_resolver/port.py +11 -0
- notionary/blocks/rich_text/rich_text_markdown_converter.py +132 -0
- notionary/blocks/rich_text/rich_text_patterns.py +39 -0
- notionary/blocks/schemas.py +746 -0
- notionary/comments/client.py +52 -187
- notionary/comments/factory.py +40 -0
- notionary/comments/models.py +5 -127
- notionary/comments/schemas.py +240 -0
- notionary/comments/service.py +34 -0
- notionary/data_source/http/client.py +11 -0
- notionary/data_source/http/data_source_instance_client.py +94 -0
- notionary/data_source/properties/models.py +406 -0
- notionary/data_source/query/builder.py +429 -0
- notionary/data_source/query/resolver.py +114 -0
- notionary/data_source/query/schema.py +304 -0
- notionary/data_source/query/validator.py +73 -0
- notionary/data_source/schemas.py +27 -0
- notionary/data_source/service.py +353 -0
- notionary/database/client.py +30 -135
- notionary/database/database_metadata_update_client.py +19 -0
- notionary/database/schemas.py +29 -0
- notionary/database/service.py +169 -0
- notionary/exceptions/__init__.py +33 -0
- notionary/exceptions/api.py +41 -0
- notionary/exceptions/base.py +2 -0
- notionary/exceptions/block_parsing.py +16 -0
- notionary/exceptions/data_source/__init__.py +6 -0
- notionary/exceptions/data_source/builder.py +182 -0
- notionary/exceptions/data_source/properties.py +34 -0
- notionary/exceptions/properties.py +58 -0
- notionary/exceptions/search.py +33 -0
- notionary/file_upload/client.py +18 -30
- notionary/file_upload/models.py +7 -8
- notionary/file_upload/{notion_file_upload.py → service.py} +29 -64
- notionary/http/client.py +205 -0
- notionary/http/models.py +49 -0
- notionary/page/blocks/client.py +1 -0
- notionary/page/content/factory.py +68 -0
- notionary/page/content/markdown/__init__.py +5 -0
- notionary/page/content/markdown/builder.py +304 -0
- notionary/page/content/markdown/nodes/__init__.py +54 -0
- notionary/page/content/markdown/nodes/audio.py +23 -0
- notionary/page/content/markdown/nodes/base.py +12 -0
- notionary/page/content/markdown/nodes/bookmark.py +25 -0
- notionary/page/content/markdown/nodes/breadcrumb.py +14 -0
- notionary/page/content/markdown/nodes/bulleted_list.py +18 -0
- notionary/page/content/markdown/nodes/callout.py +32 -0
- notionary/page/content/markdown/nodes/code.py +30 -0
- notionary/page/content/markdown/nodes/columns.py +51 -0
- notionary/page/content/markdown/nodes/divider.py +14 -0
- notionary/page/content/markdown/nodes/embed.py +23 -0
- notionary/page/content/markdown/nodes/equation.py +19 -0
- notionary/page/content/markdown/nodes/file.py +23 -0
- notionary/page/content/markdown/nodes/heading.py +16 -0
- notionary/page/content/markdown/nodes/image.py +23 -0
- notionary/page/content/markdown/nodes/mixins/caption.py +12 -0
- notionary/page/content/markdown/nodes/numbered_list.py +15 -0
- notionary/page/content/markdown/nodes/paragraph.py +14 -0
- notionary/page/content/markdown/nodes/pdf.py +23 -0
- notionary/page/content/markdown/nodes/quote.py +15 -0
- notionary/page/content/markdown/nodes/space.py +14 -0
- notionary/page/content/markdown/nodes/table.py +45 -0
- notionary/page/content/markdown/nodes/table_of_contents.py +14 -0
- notionary/page/content/markdown/nodes/todo.py +22 -0
- notionary/page/content/markdown/nodes/toggle.py +28 -0
- notionary/page/content/markdown/nodes/toggleable_heading.py +35 -0
- notionary/page/content/markdown/nodes/video.py +23 -0
- notionary/page/content/parser/context.py +49 -0
- notionary/page/content/parser/factory.py +219 -0
- notionary/page/content/parser/parsers/__init__.py +60 -0
- notionary/page/content/parser/parsers/audio.py +40 -0
- notionary/page/content/parser/parsers/base.py +30 -0
- notionary/page/content/parser/parsers/bookmark.py +33 -0
- notionary/page/content/parser/parsers/breadcrumb.py +33 -0
- notionary/page/content/parser/parsers/bulleted_list.py +41 -0
- notionary/page/content/parser/parsers/callout.py +129 -0
- notionary/page/content/parser/parsers/caption.py +55 -0
- notionary/page/content/parser/parsers/code.py +81 -0
- notionary/page/content/parser/parsers/column.py +117 -0
- notionary/page/content/parser/parsers/column_list.py +81 -0
- notionary/page/content/parser/parsers/divider.py +33 -0
- notionary/page/content/parser/parsers/embed.py +33 -0
- notionary/page/content/parser/parsers/equation.py +65 -0
- notionary/page/content/parser/parsers/file.py +42 -0
- notionary/page/content/parser/parsers/heading.py +58 -0
- notionary/page/content/parser/parsers/image.py +42 -0
- notionary/page/content/parser/parsers/numbered_list.py +45 -0
- notionary/page/content/parser/parsers/paragraph.py +36 -0
- notionary/page/content/parser/parsers/pdf.py +42 -0
- notionary/page/content/parser/parsers/quote.py +65 -0
- notionary/page/content/parser/parsers/space.py +35 -0
- notionary/page/content/parser/parsers/table.py +144 -0
- notionary/page/content/parser/parsers/table_of_contents.py +32 -0
- notionary/page/content/parser/parsers/todo.py +58 -0
- notionary/page/content/parser/parsers/toggle.py +127 -0
- notionary/page/content/parser/parsers/toggleable_heading.py +150 -0
- notionary/page/content/parser/parsers/video.py +42 -0
- notionary/page/content/parser/post_processing/handlers/__init__.py +5 -0
- notionary/page/content/parser/post_processing/handlers/rich_text_length.py +93 -0
- notionary/page/content/parser/post_processing/handlers/rich_text_length_truncation.py +93 -0
- notionary/page/content/parser/post_processing/port.py +9 -0
- notionary/page/content/parser/post_processing/service.py +16 -0
- notionary/page/content/parser/pre_processsing/handlers/__init__.py +9 -0
- notionary/page/content/parser/pre_processsing/handlers/column_syntax.py +80 -0
- notionary/page/content/parser/pre_processsing/handlers/port.py +7 -0
- notionary/page/content/parser/pre_processsing/handlers/whitespace.py +68 -0
- notionary/page/content/parser/pre_processsing/service.py +15 -0
- notionary/page/content/parser/service.py +69 -0
- notionary/page/content/renderer/context.py +48 -0
- notionary/page/content/renderer/factory.py +240 -0
- notionary/page/content/renderer/post_processing/handlers/__init__.py +5 -0
- notionary/page/content/renderer/post_processing/handlers/numbered_list_placeholdere.py +62 -0
- notionary/page/content/renderer/post_processing/port.py +7 -0
- notionary/page/content/renderer/post_processing/service.py +15 -0
- notionary/page/content/renderer/renderers/__init__.py +57 -0
- notionary/page/content/renderer/renderers/audio.py +31 -0
- notionary/page/content/renderer/renderers/base.py +31 -0
- notionary/page/content/renderer/renderers/bookmark.py +25 -0
- notionary/page/content/renderer/renderers/breadcrumb.py +21 -0
- notionary/page/content/renderer/renderers/bulleted_list.py +48 -0
- notionary/page/content/renderer/renderers/callout.py +65 -0
- notionary/page/content/renderer/renderers/captioned_block.py +58 -0
- notionary/page/content/renderer/renderers/code.py +34 -0
- notionary/page/content/renderer/renderers/column.py +44 -0
- notionary/page/content/renderer/renderers/column_list.py +31 -0
- notionary/page/content/renderer/renderers/divider.py +22 -0
- notionary/page/content/renderer/renderers/embed.py +25 -0
- notionary/page/content/renderer/renderers/equation.py +37 -0
- notionary/page/content/renderer/renderers/fallback.py +24 -0
- notionary/page/content/renderer/renderers/file.py +40 -0
- notionary/page/content/renderer/renderers/heading.py +69 -0
- notionary/page/content/renderer/renderers/image.py +31 -0
- notionary/page/content/renderer/renderers/numbered_list.py +41 -0
- notionary/page/content/renderer/renderers/paragraph.py +40 -0
- notionary/page/content/renderer/renderers/pdf.py +31 -0
- notionary/page/content/renderer/renderers/quote.py +49 -0
- notionary/page/content/renderer/renderers/table.py +115 -0
- notionary/page/content/renderer/renderers/table_of_contents.py +26 -0
- notionary/page/content/renderer/renderers/table_row.py +17 -0
- notionary/page/content/renderer/renderers/todo.py +56 -0
- notionary/page/content/renderer/renderers/toggle.py +53 -0
- notionary/page/content/renderer/renderers/toggleable_heading.py +78 -0
- notionary/page/content/renderer/renderers/video.py +31 -0
- notionary/page/content/renderer/service.py +50 -0
- notionary/page/content/service.py +65 -0
- notionary/page/content/syntax/models.py +68 -0
- notionary/page/content/syntax/service.py +453 -0
- notionary/page/page_context.py +7 -16
- notionary/page/page_http_client.py +15 -0
- notionary/page/page_metadata_update_client.py +19 -0
- notionary/page/properties/client.py +144 -0
- notionary/page/properties/factory.py +26 -0
- notionary/page/properties/models.py +307 -0
- notionary/page/properties/service.py +257 -0
- notionary/page/schemas.py +13 -0
- notionary/page/service.py +222 -0
- notionary/shared/entity/client.py +29 -0
- notionary/shared/entity/dto_parsers.py +53 -0
- notionary/shared/entity/entity_metadata_update_client.py +41 -0
- notionary/shared/entity/schemas.py +45 -0
- notionary/shared/entity/service.py +171 -0
- notionary/shared/models/cover.py +20 -0
- notionary/shared/models/file.py +21 -0
- notionary/shared/models/icon.py +28 -0
- notionary/shared/models/parent.py +41 -0
- notionary/shared/properties/type.py +30 -0
- notionary/user/__init__.py +4 -8
- notionary/user/base.py +89 -0
- notionary/user/bot.py +70 -0
- notionary/user/client.py +22 -111
- notionary/user/person.py +41 -0
- notionary/user/schemas.py +67 -0
- notionary/user/service.py +65 -0
- notionary/utils/async_retry.py +39 -0
- notionary/utils/date.py +51 -0
- notionary/utils/fuzzy.py +56 -0
- notionary/{util/logging_mixin.py → utils/mixins/logging.py} +4 -16
- notionary/utils/pagination.py +50 -0
- notionary/utils/singleton.py +13 -0
- notionary/utils/uuid_utils.py +20 -0
- notionary/workspace/__init__.py +3 -0
- notionary/workspace/client.py +62 -0
- notionary/workspace/query/builder.py +60 -0
- notionary/workspace/query/models.py +60 -0
- notionary/workspace/query/service.py +93 -0
- notionary/workspace/schemas.py +21 -0
- notionary/workspace/service.py +116 -0
- {notionary-0.2.26.dist-info → notionary-0.2.28.dist-info}/METADATA +54 -49
- notionary-0.2.28.dist-info/RECORD +200 -0
- {notionary-0.2.26.dist-info → notionary-0.2.28.dist-info}/WHEEL +1 -1
- {notionary-0.2.26.dist-info → notionary-0.2.28.dist-info/licenses}/LICENSE +9 -9
- notionary/base_notion_client.py +0 -219
- notionary/blocks/__init__.py +0 -5
- notionary/blocks/_bootstrap.py +0 -271
- notionary/blocks/audio/__init__.py +0 -11
- notionary/blocks/audio/audio_element.py +0 -158
- notionary/blocks/audio/audio_markdown_node.py +0 -24
- notionary/blocks/audio/audio_models.py +0 -10
- notionary/blocks/base_block_element.py +0 -42
- notionary/blocks/bookmark/__init__.py +0 -12
- notionary/blocks/bookmark/bookmark_element.py +0 -83
- notionary/blocks/bookmark/bookmark_markdown_node.py +0 -28
- notionary/blocks/bookmark/bookmark_models.py +0 -15
- notionary/blocks/breadcrumbs/__init__.py +0 -15
- notionary/blocks/breadcrumbs/breadcrumb_element.py +0 -39
- notionary/blocks/breadcrumbs/breadcrumb_markdown_node.py +0 -13
- notionary/blocks/breadcrumbs/breadcrumb_models.py +0 -12
- notionary/blocks/bulleted_list/__init__.py +0 -15
- notionary/blocks/bulleted_list/bulleted_list_element.py +0 -74
- notionary/blocks/bulleted_list/bulleted_list_markdown_node.py +0 -20
- notionary/blocks/bulleted_list/bulleted_list_models.py +0 -17
- notionary/blocks/callout/__init__.py +0 -12
- notionary/blocks/callout/callout_element.py +0 -99
- notionary/blocks/callout/callout_markdown_node.py +0 -19
- notionary/blocks/callout/callout_models.py +0 -33
- notionary/blocks/child_database/__init__.py +0 -14
- notionary/blocks/child_database/child_database_element.py +0 -59
- notionary/blocks/child_database/child_database_models.py +0 -12
- notionary/blocks/child_page/__init__.py +0 -9
- notionary/blocks/child_page/child_page_element.py +0 -94
- notionary/blocks/child_page/child_page_models.py +0 -12
- notionary/blocks/code/__init__.py +0 -11
- notionary/blocks/code/code_element.py +0 -149
- notionary/blocks/code/code_markdown_node.py +0 -80
- notionary/blocks/code/code_models.py +0 -94
- notionary/blocks/column/__init__.py +0 -25
- notionary/blocks/column/column_element.py +0 -65
- notionary/blocks/column/column_list_element.py +0 -52
- notionary/blocks/column/column_list_markdown_node.py +0 -34
- notionary/blocks/column/column_markdown_node.py +0 -42
- notionary/blocks/column/column_models.py +0 -26
- notionary/blocks/divider/__init__.py +0 -12
- notionary/blocks/divider/divider_element.py +0 -41
- notionary/blocks/divider/divider_markdown_node.py +0 -11
- notionary/blocks/divider/divider_models.py +0 -12
- notionary/blocks/embed/__init__.py +0 -12
- notionary/blocks/embed/embed_element.py +0 -98
- notionary/blocks/embed/embed_markdown_node.py +0 -19
- notionary/blocks/embed/embed_models.py +0 -14
- notionary/blocks/equation/__init__.py +0 -13
- notionary/blocks/equation/equation_element.py +0 -133
- notionary/blocks/equation/equation_element_markdown_node.py +0 -23
- notionary/blocks/equation/equation_models.py +0 -11
- notionary/blocks/file/__init__.py +0 -23
- notionary/blocks/file/file_element.py +0 -133
- notionary/blocks/file/file_element_markdown_node.py +0 -24
- notionary/blocks/file/file_element_models.py +0 -39
- notionary/blocks/heading/__init__.py +0 -19
- notionary/blocks/heading/heading_element.py +0 -112
- notionary/blocks/heading/heading_markdown_node.py +0 -16
- notionary/blocks/heading/heading_models.py +0 -29
- notionary/blocks/image_block/__init__.py +0 -11
- notionary/blocks/image_block/image_element.py +0 -130
- notionary/blocks/image_block/image_markdown_node.py +0 -25
- notionary/blocks/image_block/image_models.py +0 -10
- notionary/blocks/markdown/markdown_builder.py +0 -525
- notionary/blocks/markdown/markdown_document_model.py +0 -0
- notionary/blocks/markdown/markdown_node.py +0 -25
- notionary/blocks/mixins/captions/__init__.py +0 -4
- notionary/blocks/mixins/captions/caption_markdown_node_mixin.py +0 -31
- notionary/blocks/mixins/captions/caption_mixin.py +0 -92
- notionary/blocks/mixins/file_upload/__init__.py +0 -3
- notionary/blocks/mixins/file_upload/file_upload_mixin.py +0 -320
- notionary/blocks/models.py +0 -174
- notionary/blocks/numbered_list/__init__.py +0 -16
- notionary/blocks/numbered_list/numbered_list_element.py +0 -65
- notionary/blocks/numbered_list/numbered_list_markdown_node.py +0 -17
- notionary/blocks/numbered_list/numbered_list_models.py +0 -17
- notionary/blocks/paragraph/__init__.py +0 -15
- notionary/blocks/paragraph/paragraph_element.py +0 -58
- notionary/blocks/paragraph/paragraph_markdown_node.py +0 -16
- notionary/blocks/paragraph/paragraph_models.py +0 -16
- notionary/blocks/pdf/__init__.py +0 -11
- notionary/blocks/pdf/pdf_element.py +0 -146
- notionary/blocks/pdf/pdf_markdown_node.py +0 -24
- notionary/blocks/pdf/pdf_models.py +0 -11
- notionary/blocks/quote/__init__.py +0 -14
- notionary/blocks/quote/quote_element.py +0 -75
- notionary/blocks/quote/quote_markdown_node.py +0 -16
- notionary/blocks/quote/quote_models.py +0 -18
- notionary/blocks/registry/__init__.py +0 -3
- notionary/blocks/registry/block_registry.py +0 -150
- notionary/blocks/rich_text/__init__.py +0 -33
- notionary/blocks/rich_text/rich_text_models.py +0 -221
- notionary/blocks/rich_text/text_inline_formatter.py +0 -456
- notionary/blocks/syntax_prompt_builder.py +0 -137
- notionary/blocks/table/__init__.py +0 -19
- notionary/blocks/table/table_element.py +0 -225
- notionary/blocks/table/table_markdown_node.py +0 -42
- notionary/blocks/table/table_models.py +0 -28
- notionary/blocks/table_of_contents/__init__.py +0 -17
- notionary/blocks/table_of_contents/table_of_contents_element.py +0 -80
- notionary/blocks/table_of_contents/table_of_contents_markdown_node.py +0 -21
- notionary/blocks/table_of_contents/table_of_contents_models.py +0 -18
- notionary/blocks/todo/__init__.py +0 -12
- notionary/blocks/todo/todo_element.py +0 -81
- notionary/blocks/todo/todo_markdown_node.py +0 -21
- notionary/blocks/todo/todo_models.py +0 -18
- notionary/blocks/toggle/__init__.py +0 -12
- notionary/blocks/toggle/toggle_element.py +0 -112
- notionary/blocks/toggle/toggle_markdown_node.py +0 -31
- notionary/blocks/toggle/toggle_models.py +0 -17
- notionary/blocks/toggleable_heading/__init__.py +0 -11
- notionary/blocks/toggleable_heading/toggleable_heading_element.py +0 -115
- notionary/blocks/toggleable_heading/toggleable_heading_markdown_node.py +0 -34
- notionary/blocks/types.py +0 -130
- notionary/blocks/video/__init__.py +0 -11
- notionary/blocks/video/video_element.py +0 -187
- notionary/blocks/video/video_element_models.py +0 -10
- notionary/blocks/video/video_markdown_node.py +0 -26
- notionary/comments/__init__.py +0 -26
- notionary/database/__init__.py +0 -4
- notionary/database/database.py +0 -480
- notionary/database/database_filter_builder.py +0 -173
- notionary/database/database_provider.py +0 -227
- notionary/database/exceptions.py +0 -13
- notionary/database/factory.py +0 -0
- notionary/database/models.py +0 -337
- notionary/database/notion_database.py +0 -487
- notionary/file_upload/__init__.py +0 -7
- notionary/page/client.py +0 -124
- notionary/page/markdown_whitespace_processor.py +0 -129
- notionary/page/models.py +0 -322
- notionary/page/notion_page.py +0 -674
- notionary/page/page_content_deleting_service.py +0 -117
- notionary/page/page_content_writer.py +0 -80
- notionary/page/property_formatter.py +0 -99
- notionary/page/reader/handler/__init__.py +0 -19
- notionary/page/reader/handler/base_block_renderer.py +0 -44
- notionary/page/reader/handler/block_processing_context.py +0 -35
- notionary/page/reader/handler/block_rendering_context.py +0 -48
- notionary/page/reader/handler/column_list_renderer.py +0 -51
- notionary/page/reader/handler/column_renderer.py +0 -60
- notionary/page/reader/handler/equation_renderer.py +0 -0
- notionary/page/reader/handler/line_renderer.py +0 -73
- notionary/page/reader/handler/numbered_list_renderer.py +0 -85
- notionary/page/reader/handler/toggle_renderer.py +0 -69
- notionary/page/reader/handler/toggleable_heading_renderer.py +0 -89
- notionary/page/reader/page_content_retriever.py +0 -81
- notionary/page/search_filter_builder.py +0 -132
- notionary/page/utils.py +0 -60
- notionary/page/writer/handler/__init__.py +0 -24
- notionary/page/writer/handler/code_handler.py +0 -72
- notionary/page/writer/handler/column_handler.py +0 -141
- notionary/page/writer/handler/column_list_handler.py +0 -139
- notionary/page/writer/handler/equation_handler.py +0 -74
- notionary/page/writer/handler/line_handler.py +0 -35
- notionary/page/writer/handler/line_processing_context.py +0 -54
- notionary/page/writer/handler/regular_line_handler.py +0 -86
- notionary/page/writer/handler/table_handler.py +0 -66
- notionary/page/writer/handler/toggle_handler.py +0 -159
- notionary/page/writer/handler/toggleable_heading_handler.py +0 -174
- notionary/page/writer/markdown_to_notion_converter.py +0 -139
- notionary/page/writer/markdown_to_notion_converter_context.py +0 -30
- notionary/page/writer/markdown_to_notion_text_length_post_processor.py +0 -0
- notionary/page/writer/notion_text_length_processor.py +0 -150
- notionary/schemas/__init__.py +0 -3
- notionary/schemas/base.py +0 -73
- notionary/shared/__init__.py +0 -3
- notionary/shared/name_to_id_resolver.py +0 -203
- notionary/telemetry/__init__.py +0 -19
- notionary/telemetry/service.py +0 -136
- notionary/telemetry/views.py +0 -73
- notionary/user/base_notion_user.py +0 -53
- notionary/user/models.py +0 -84
- notionary/user/notion_bot_user.py +0 -226
- notionary/user/notion_user.py +0 -255
- notionary/user/notion_user_manager.py +0 -101
- notionary/util/__init__.py +0 -15
- notionary/util/concurrency_limiter.py +0 -0
- notionary/util/factory_decorator.py +0 -0
- notionary/util/factory_only.py +0 -37
- notionary/util/fuzzy.py +0 -75
- notionary/util/page_id_utils.py +0 -27
- notionary/util/singleton.py +0 -18
- notionary/util/singleton_metaclass.py +0 -22
- notionary/workspace.py +0 -105
- notionary-0.2.26.dist-info/RECORD +0 -202
@@ -1,21 +0,0 @@
|
|
1
|
-
from pydantic import Field
|
2
|
-
from notionary.blocks.markdown.markdown_node import MarkdownNode
|
3
|
-
|
4
|
-
|
5
|
-
class TodoMarkdownNode(MarkdownNode):
|
6
|
-
"""
|
7
|
-
Enhanced Todo node with Pydantic integration.
|
8
|
-
Programmatic interface for creating Markdown todo items (checkboxes).
|
9
|
-
Supports checked and unchecked states.
|
10
|
-
Example: - [ ] Task, - [x] Done
|
11
|
-
"""
|
12
|
-
|
13
|
-
text: str
|
14
|
-
checked: bool = False
|
15
|
-
marker: str = Field(default="-")
|
16
|
-
|
17
|
-
def to_markdown(self) -> str:
|
18
|
-
# Validate marker in to_markdown to ensure it's valid
|
19
|
-
valid_marker = self.marker if self.marker in {"-", "*", "+"} else "-"
|
20
|
-
checkbox = "[x]" if self.checked else "[ ]"
|
21
|
-
return f"{valid_marker} {checkbox} {self.text}"
|
@@ -1,18 +0,0 @@
|
|
1
|
-
from typing import Literal, Optional
|
2
|
-
|
3
|
-
from pydantic import BaseModel
|
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
|
-
|
15
|
-
|
16
|
-
class CreateToDoBlock(BaseModel):
|
17
|
-
type: Literal["to_do"] = "to_do"
|
18
|
-
to_do: ToDoBlock
|
@@ -1,12 +0,0 @@
|
|
1
|
-
from notionary.blocks.toggle.toggle_element import ToggleElement
|
2
|
-
from notionary.blocks.toggle.toggle_markdown_node import (
|
3
|
-
ToggleMarkdownNode,
|
4
|
-
)
|
5
|
-
from notionary.blocks.toggle.toggle_models import CreateToggleBlock, ToggleBlock
|
6
|
-
|
7
|
-
__all__ = [
|
8
|
-
"ToggleElement",
|
9
|
-
"ToggleBlock",
|
10
|
-
"CreateToggleBlock",
|
11
|
-
"ToggleMarkdownNode",
|
12
|
-
]
|
@@ -1,112 +0,0 @@
|
|
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, BlockType
|
9
|
-
from notionary.blocks.rich_text.rich_text_models import RichTextObject
|
10
|
-
from notionary.blocks.rich_text.text_inline_formatter import TextInlineFormatter
|
11
|
-
from notionary.blocks.toggle.toggle_models import CreateToggleBlock, ToggleBlock
|
12
|
-
from notionary.blocks.types import BlockColor
|
13
|
-
|
14
|
-
|
15
|
-
class ToggleElement(BaseBlockElement):
|
16
|
-
"""
|
17
|
-
Simplified ToggleElement class that works with the stack-based converter.
|
18
|
-
Children are automatically handled by the StackBasedMarkdownConverter.
|
19
|
-
"""
|
20
|
-
|
21
|
-
# Updated pattern for ultra-simplified +++ Title syntax (no quotes!)
|
22
|
-
TOGGLE_PATTERN = re.compile(r"^[+]{3}\s+(.+)$", re.IGNORECASE)
|
23
|
-
TRANSCRIPT_TOGGLE_PATTERN = re.compile(r"^[+]{3}\s+Transcript$", re.IGNORECASE)
|
24
|
-
|
25
|
-
@classmethod
|
26
|
-
def match_notion(cls, block: Block) -> bool:
|
27
|
-
"""Check if the block is a Notion toggle block."""
|
28
|
-
return block.type == BlockType.TOGGLE
|
29
|
-
|
30
|
-
@classmethod
|
31
|
-
async def markdown_to_notion(cls, text: str) -> BlockCreateResult:
|
32
|
-
"""
|
33
|
-
Convert markdown toggle line to Notion ToggleBlock.
|
34
|
-
Children are automatically handled by the StackBasedMarkdownConverter.
|
35
|
-
"""
|
36
|
-
if not (match := cls.TOGGLE_PATTERN.match(text.strip())):
|
37
|
-
return None
|
38
|
-
|
39
|
-
title = match.group(1).strip()
|
40
|
-
rich_text = await TextInlineFormatter.parse_inline_formatting(title)
|
41
|
-
|
42
|
-
# Create toggle block with empty children - they will be populated automatically
|
43
|
-
toggle_content = ToggleBlock(
|
44
|
-
rich_text=rich_text, color=BlockColor.DEFAULT, children=[]
|
45
|
-
)
|
46
|
-
|
47
|
-
return CreateToggleBlock(toggle=toggle_content)
|
48
|
-
|
49
|
-
@classmethod
|
50
|
-
async def notion_to_markdown(cls, block: Block) -> Optional[str]:
|
51
|
-
"""
|
52
|
-
Converts a Notion toggle block into markdown using the ultra-simplified +++ syntax.
|
53
|
-
"""
|
54
|
-
if block.type != BlockType.TOGGLE:
|
55
|
-
return None
|
56
|
-
|
57
|
-
if not block.toggle:
|
58
|
-
return None
|
59
|
-
|
60
|
-
toggle_data = block.toggle
|
61
|
-
|
62
|
-
# Extract title from rich_text
|
63
|
-
title = cls._extract_text_content(toggle_data.rich_text or [])
|
64
|
-
|
65
|
-
# Create toggle line with ultra-simplified syntax (no quotes!)
|
66
|
-
toggle_line = f"+++ {title}"
|
67
|
-
|
68
|
-
# Process children if available
|
69
|
-
children = toggle_data.children or []
|
70
|
-
if not children:
|
71
|
-
return toggle_line + "\n+++"
|
72
|
-
|
73
|
-
# Add a placeholder line for each child
|
74
|
-
child_lines = ["[Nested content]" for _ in children]
|
75
|
-
|
76
|
-
return toggle_line + "\n" + "\n".join(child_lines) + "\n+++"
|
77
|
-
|
78
|
-
@classmethod
|
79
|
-
def _extract_text_content(cls, rich_text: list[RichTextObject]) -> str:
|
80
|
-
"""Extracts plain text content from Notion rich_text blocks."""
|
81
|
-
result = ""
|
82
|
-
for text_obj in rich_text:
|
83
|
-
if hasattr(text_obj, "plain_text"):
|
84
|
-
result += text_obj.plain_text or ""
|
85
|
-
elif (
|
86
|
-
hasattr(text_obj, "type")
|
87
|
-
and text_obj.type == "text"
|
88
|
-
and hasattr(text_obj, "text")
|
89
|
-
):
|
90
|
-
result += text_obj.text.content or ""
|
91
|
-
# Fallback for dict-style access (backward compatibility)
|
92
|
-
elif isinstance(text_obj, dict):
|
93
|
-
if text_obj.get("type") == "text":
|
94
|
-
result += text_obj.get("text", {}).get("content", "")
|
95
|
-
elif "plain_text" in text_obj:
|
96
|
-
result += text_obj.get("plain_text", "")
|
97
|
-
return result
|
98
|
-
|
99
|
-
@classmethod
|
100
|
-
@classmethod
|
101
|
-
def get_system_prompt_information(cls) -> Optional[BlockElementMarkdownInformation]:
|
102
|
-
"""Get system prompt information for toggle blocks."""
|
103
|
-
return BlockElementMarkdownInformation(
|
104
|
-
block_type=cls.__name__,
|
105
|
-
description="Toggle blocks create collapsible sections with expandable content",
|
106
|
-
syntax_examples=[
|
107
|
-
"+++Title\nContent goes here\n+++",
|
108
|
-
"+++Details\nMore information\nAdditional content\n+++",
|
109
|
-
"+++FAQ\nFrequently asked questions\n+++",
|
110
|
-
],
|
111
|
-
usage_guidelines="Use for collapsible content sections. Start with +++Title, add content, end with +++. Great for FAQs, details, or organizing long content.",
|
112
|
-
)
|
@@ -1,31 +0,0 @@
|
|
1
|
-
from notionary.blocks.markdown.markdown_node import MarkdownNode
|
2
|
-
|
3
|
-
|
4
|
-
class ToggleMarkdownNode(MarkdownNode):
|
5
|
-
"""
|
6
|
-
Enhanced Toggle node with Pydantic integration.
|
7
|
-
Clean programmatic interface for creating Notion-style Markdown toggle blocks
|
8
|
-
with the simplified +++ "Title" syntax.
|
9
|
-
|
10
|
-
Example:
|
11
|
-
+++ "Advanced Details"
|
12
|
-
Content here
|
13
|
-
More content
|
14
|
-
+++
|
15
|
-
"""
|
16
|
-
|
17
|
-
title: str
|
18
|
-
children: list[MarkdownNode] = []
|
19
|
-
|
20
|
-
def to_markdown(self) -> str:
|
21
|
-
result = f"+++ {self.title}"
|
22
|
-
|
23
|
-
if not self.children:
|
24
|
-
result += "\n+++"
|
25
|
-
return result
|
26
|
-
|
27
|
-
# Convert children to markdown
|
28
|
-
content_parts = [child.to_markdown() for child in self.children]
|
29
|
-
content_text = "\n\n".join(content_parts)
|
30
|
-
|
31
|
-
return result + "\n" + content_text + "\n+++"
|
@@ -1,17 +0,0 @@
|
|
1
|
-
from pydantic import BaseModel, Field
|
2
|
-
from typing_extensions import Literal
|
3
|
-
|
4
|
-
from notionary.blocks.models import Block
|
5
|
-
from notionary.blocks.rich_text.rich_text_models import RichTextObject
|
6
|
-
from notionary.blocks.types import BlockColor
|
7
|
-
|
8
|
-
|
9
|
-
class ToggleBlock(BaseModel):
|
10
|
-
rich_text: list[RichTextObject]
|
11
|
-
color: BlockColor = BlockColor.DEFAULT
|
12
|
-
children: list[Block] = Field(default_factory=list)
|
13
|
-
|
14
|
-
|
15
|
-
class CreateToggleBlock(BaseModel):
|
16
|
-
type: Literal["toggle"] = "toggle"
|
17
|
-
toggle: ToggleBlock
|
@@ -1,11 +0,0 @@
|
|
1
|
-
from notionary.blocks.toggleable_heading.toggleable_heading_element import (
|
2
|
-
ToggleableHeadingElement,
|
3
|
-
)
|
4
|
-
from notionary.blocks.toggleable_heading.toggleable_heading_markdown_node import (
|
5
|
-
ToggleableHeadingMarkdownNode,
|
6
|
-
)
|
7
|
-
|
8
|
-
__all__ = [
|
9
|
-
"ToggleableHeadingElement",
|
10
|
-
"ToggleableHeadingMarkdownNode",
|
11
|
-
]
|
@@ -1,115 +0,0 @@
|
|
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.heading.heading_models import (
|
8
|
-
CreateHeading1Block,
|
9
|
-
CreateHeading2Block,
|
10
|
-
CreateHeading3Block,
|
11
|
-
HeadingBlock,
|
12
|
-
)
|
13
|
-
from notionary.blocks.syntax_prompt_builder import BlockElementMarkdownInformation
|
14
|
-
from notionary.blocks.models import Block, BlockCreateResult, BlockType
|
15
|
-
from notionary.blocks.rich_text.text_inline_formatter import TextInlineFormatter
|
16
|
-
|
17
|
-
|
18
|
-
class ToggleableHeadingElement(BaseBlockElement):
|
19
|
-
"""
|
20
|
-
Simplified ToggleableHeadingElement that works with the stack-based converter.
|
21
|
-
Children are automatically handled by the StackBasedMarkdownConverter.
|
22
|
-
"""
|
23
|
-
|
24
|
-
# Updated pattern for simplified +++# Title syntax (no quotes!)
|
25
|
-
PATTERN = re.compile(r"^[+]{3}(?P<level>#{1,3})\s+(.+)$", re.IGNORECASE)
|
26
|
-
|
27
|
-
@staticmethod
|
28
|
-
def match_notion(block: Block) -> bool:
|
29
|
-
"""Check if block is a Notion toggleable heading."""
|
30
|
-
# Use BlockType enum for matching heading blocks
|
31
|
-
if block.type not in (
|
32
|
-
BlockType.HEADING_1,
|
33
|
-
BlockType.HEADING_2,
|
34
|
-
BlockType.HEADING_3,
|
35
|
-
):
|
36
|
-
return False
|
37
|
-
|
38
|
-
if block.heading_1 and block.heading_1.is_toggleable:
|
39
|
-
return True
|
40
|
-
if block.heading_2 and block.heading_2.is_toggleable:
|
41
|
-
return True
|
42
|
-
if block.heading_3 and block.heading_3.is_toggleable:
|
43
|
-
return True
|
44
|
-
|
45
|
-
@classmethod
|
46
|
-
async def markdown_to_notion(cls, text: str) -> BlockCreateResult:
|
47
|
-
"""
|
48
|
-
Convert markdown collapsible heading to a toggleable Notion HeadingBlock.
|
49
|
-
Children are automatically handled by the StackBasedMarkdownConverter.
|
50
|
-
"""
|
51
|
-
if not (match := cls.PATTERN.match(text.strip())):
|
52
|
-
return None
|
53
|
-
|
54
|
-
level = len(match.group("level")) # Count # characters
|
55
|
-
content = match.group(2).strip() # group(2) is the title (no quotes needed)
|
56
|
-
|
57
|
-
if level < 1 or level > 3 or not content:
|
58
|
-
return None
|
59
|
-
|
60
|
-
rich_text = await TextInlineFormatter.parse_inline_formatting(content)
|
61
|
-
|
62
|
-
heading_content = HeadingBlock(
|
63
|
-
rich_text=rich_text, color="default", is_toggleable=True, children=[]
|
64
|
-
)
|
65
|
-
|
66
|
-
if level == 1:
|
67
|
-
return CreateHeading1Block(heading_1=heading_content)
|
68
|
-
elif level == 2:
|
69
|
-
return CreateHeading2Block(heading_2=heading_content)
|
70
|
-
else:
|
71
|
-
return CreateHeading3Block(heading_3=heading_content)
|
72
|
-
|
73
|
-
@staticmethod
|
74
|
-
async def notion_to_markdown(block: Block) -> Optional[str]:
|
75
|
-
"""Convert Notion toggleable heading block to markdown collapsible heading."""
|
76
|
-
# Only handle heading blocks via BlockType enum
|
77
|
-
if block.type not in (
|
78
|
-
BlockType.HEADING_1,
|
79
|
-
BlockType.HEADING_2,
|
80
|
-
BlockType.HEADING_3,
|
81
|
-
):
|
82
|
-
return None
|
83
|
-
|
84
|
-
# Determine heading level from enum
|
85
|
-
if block.type == BlockType.HEADING_1:
|
86
|
-
level = 1
|
87
|
-
elif block.type == BlockType.HEADING_2:
|
88
|
-
level = 2
|
89
|
-
else:
|
90
|
-
level = 3
|
91
|
-
|
92
|
-
heading_content = getattr(block, block.type.value)
|
93
|
-
if not isinstance(heading_content, HeadingBlock):
|
94
|
-
return None
|
95
|
-
|
96
|
-
text = await TextInlineFormatter.extract_text_with_formatting(
|
97
|
-
heading_content.rich_text
|
98
|
-
)
|
99
|
-
prefix = "#" * level
|
100
|
-
|
101
|
-
return f'+++{prefix} {text or ""}'
|
102
|
-
|
103
|
-
@classmethod
|
104
|
-
def get_system_prompt_information(cls) -> Optional[BlockElementMarkdownInformation]:
|
105
|
-
"""Get system prompt information for toggleable heading blocks."""
|
106
|
-
return BlockElementMarkdownInformation(
|
107
|
-
block_type=cls.__name__,
|
108
|
-
description="Toggleable heading blocks create collapsible sections with heading-style titles",
|
109
|
-
syntax_examples=[
|
110
|
-
"+++# Main Section\nContent goes here\n+++",
|
111
|
-
"+++## Subsection\nSubsection content\n+++",
|
112
|
-
"+++### Details\nDetailed information\n+++",
|
113
|
-
],
|
114
|
-
usage_guidelines="Use for collapsible sections with heading structure. Combines heading levels (1-3) with toggle functionality. Great for organizing hierarchical expandable content.",
|
115
|
-
)
|
@@ -1,34 +0,0 @@
|
|
1
|
-
from pydantic import Field
|
2
|
-
|
3
|
-
from notionary.blocks.markdown.markdown_node import MarkdownNode
|
4
|
-
|
5
|
-
|
6
|
-
class ToggleableHeadingMarkdownNode(MarkdownNode):
|
7
|
-
"""
|
8
|
-
Enhanced Toggleable Heading node with Pydantic integration.
|
9
|
-
Clean programmatic interface for creating collapsible Markdown headings (toggleable headings)
|
10
|
-
with pipe-prefixed nested content using MarkdownNode children.
|
11
|
-
|
12
|
-
Example syntax for a level-2 toggleable heading:
|
13
|
-
+++## Advanced Section
|
14
|
-
some content
|
15
|
-
+++
|
16
|
-
"""
|
17
|
-
|
18
|
-
text: str
|
19
|
-
level: int = Field(ge=1, le=3)
|
20
|
-
children: list[MarkdownNode] = []
|
21
|
-
|
22
|
-
def to_markdown(self) -> str:
|
23
|
-
prefix = "+++" + ("#" * self.level)
|
24
|
-
result = f"{prefix} {self.text}"
|
25
|
-
|
26
|
-
if not self.children:
|
27
|
-
result += "\n+++"
|
28
|
-
return result
|
29
|
-
|
30
|
-
# Convert children to markdown
|
31
|
-
content_parts = [child.to_markdown() for child in self.children]
|
32
|
-
content_text = "\n\n".join(content_parts)
|
33
|
-
|
34
|
-
return result + "\n" + content_text + "\n+++"
|
notionary/blocks/types.py
DELETED
@@ -1,130 +0,0 @@
|
|
1
|
-
from __future__ import annotations
|
2
|
-
|
3
|
-
from enum import Enum
|
4
|
-
|
5
|
-
from typing import Protocol, TYPE_CHECKING
|
6
|
-
|
7
|
-
if TYPE_CHECKING:
|
8
|
-
from notionary.blocks.models import BlockCreateRequest
|
9
|
-
from notionary.blocks.rich_text.rich_text_models import RichTextObject
|
10
|
-
|
11
|
-
|
12
|
-
class BlockColor(str, Enum):
|
13
|
-
BLUE = "blue"
|
14
|
-
BLUE_BACKGROUND = "blue_background"
|
15
|
-
BROWN = "brown"
|
16
|
-
BROWN_BACKGROUND = "brown_background"
|
17
|
-
DEFAULT = "default"
|
18
|
-
GRAY = "gray"
|
19
|
-
GRAY_BACKGROUND = "gray_background"
|
20
|
-
GREEN = "green"
|
21
|
-
GREEN_BACKGROUND = "green_background"
|
22
|
-
ORANGE = "orange"
|
23
|
-
ORANGE_BACKGROUND = "orange_background"
|
24
|
-
YELLOW = "yellow"
|
25
|
-
YELLOW_BACKGROUND = "yellow_background"
|
26
|
-
PINK = "pink"
|
27
|
-
PINK_BACKGROUND = "pink_background"
|
28
|
-
PURPLE = "purple"
|
29
|
-
PURPLE_BACKGROUND = "purple_background"
|
30
|
-
RED = "red"
|
31
|
-
RED_BACKGROUND = "red_background"
|
32
|
-
DEFAULT_BACKGROUND = "default_background"
|
33
|
-
|
34
|
-
|
35
|
-
class BlockType(str, Enum):
|
36
|
-
BOOKMARK = "bookmark"
|
37
|
-
BREADCRUMB = "breadcrumb"
|
38
|
-
BULLETED_LIST_ITEM = "bulleted_list_item"
|
39
|
-
CALLOUT = "callout"
|
40
|
-
CHILD_DATABASE = "child_database"
|
41
|
-
CHILD_PAGE = "child_page"
|
42
|
-
COLUMN = "column"
|
43
|
-
COLUMN_LIST = "column_list"
|
44
|
-
CODE = "code"
|
45
|
-
DIVIDER = "divider"
|
46
|
-
EMBED = "embed"
|
47
|
-
EQUATION = "equation"
|
48
|
-
FILE = "file"
|
49
|
-
HEADING_1 = "heading_1"
|
50
|
-
HEADING_2 = "heading_2"
|
51
|
-
HEADING_3 = "heading_3"
|
52
|
-
IMAGE = "image"
|
53
|
-
LINK_PREVIEW = "link_preview"
|
54
|
-
LINK_TO_PAGE = "link_to_page"
|
55
|
-
NUMBERED_LIST_ITEM = "numbered_list_item"
|
56
|
-
PARAGRAPH = "paragraph"
|
57
|
-
PDF = "pdf"
|
58
|
-
QUOTE = "quote"
|
59
|
-
SYNCED_BLOCK = "synced_block"
|
60
|
-
TABLE = "table"
|
61
|
-
TABLE_OF_CONTENTS = "table_of_contents"
|
62
|
-
TABLE_ROW = "table_row"
|
63
|
-
TO_DO = "to_do"
|
64
|
-
TOGGLE = "toggle"
|
65
|
-
UNSUPPORTED = "unsupported"
|
66
|
-
VIDEO = "video"
|
67
|
-
AUDIO = "audio"
|
68
|
-
|
69
|
-
|
70
|
-
class MarkdownBlockType(str, Enum):
|
71
|
-
"""
|
72
|
-
Extended block types for the MarkdownBuilder.
|
73
|
-
Includes all BlockType values and adds user-friendly aliases
|
74
|
-
for blocks with no direct Notion API counterpart.
|
75
|
-
"""
|
76
|
-
|
77
|
-
# All BlockType values
|
78
|
-
BOOKMARK = "bookmark"
|
79
|
-
BREADCRUMB = "breadcrumb"
|
80
|
-
BULLETED_LIST_ITEM = "bulleted_list_item"
|
81
|
-
CALLOUT = "callout"
|
82
|
-
CHILD_DATABASE = "child_database"
|
83
|
-
CHILD_PAGE = "child_page"
|
84
|
-
COLUMN = "column"
|
85
|
-
COLUMN_LIST = "column_list"
|
86
|
-
CODE = "code"
|
87
|
-
DIVIDER = "divider"
|
88
|
-
EMBED = "embed"
|
89
|
-
EQUATION = "equation"
|
90
|
-
FILE = "file"
|
91
|
-
HEADING_1 = "heading_1"
|
92
|
-
HEADING_2 = "heading_2"
|
93
|
-
HEADING_3 = "heading_3"
|
94
|
-
IMAGE = "image"
|
95
|
-
LINK_PREVIEW = "link_preview"
|
96
|
-
LINK_TO_PAGE = "link_to_page"
|
97
|
-
NUMBERED_LIST_ITEM = "numbered_list_item"
|
98
|
-
PARAGRAPH = "paragraph"
|
99
|
-
PDF = "pdf"
|
100
|
-
QUOTE = "quote"
|
101
|
-
SYNCED_BLOCK = "synced_block"
|
102
|
-
TABLE = "table"
|
103
|
-
TABLE_OF_CONTENTS = "table_of_contents"
|
104
|
-
TABLE_ROW = "table_row"
|
105
|
-
TO_DO = "to_do"
|
106
|
-
TOGGLE = "toggle"
|
107
|
-
UNSUPPORTED = "unsupported"
|
108
|
-
VIDEO = "video"
|
109
|
-
AUDIO = "audio"
|
110
|
-
|
111
|
-
# Markdown-specific aliases
|
112
|
-
HEADING = "heading"
|
113
|
-
BULLETED_LIST = "bulleted_list"
|
114
|
-
NUMBERED_LIST = "numbered_list"
|
115
|
-
TODO = "todo"
|
116
|
-
TOGGLEABLE_HEADING = "toggleable_heading"
|
117
|
-
COLUMNS = "columns"
|
118
|
-
SPACE = "space"
|
119
|
-
|
120
|
-
|
121
|
-
class HasRichText(Protocol):
|
122
|
-
"""Protocol for objects that have a rich_text attribute."""
|
123
|
-
|
124
|
-
rich_text: list[RichTextObject]
|
125
|
-
|
126
|
-
|
127
|
-
class HasChildren(Protocol):
|
128
|
-
"""Protocol for objects that have children blocks."""
|
129
|
-
|
130
|
-
children: list[BlockCreateRequest]
|
@@ -1,11 +0,0 @@
|
|
1
|
-
from notionary.blocks.video.video_element import VideoElement
|
2
|
-
from notionary.blocks.video.video_element_models import CreateVideoBlock
|
3
|
-
from notionary.blocks.video.video_markdown_node import (
|
4
|
-
VideoMarkdownNode,
|
5
|
-
)
|
6
|
-
|
7
|
-
__all__ = [
|
8
|
-
"VideoElement",
|
9
|
-
"CreateVideoBlock",
|
10
|
-
"VideoMarkdownNode",
|
11
|
-
]
|