notionary 0.2.27__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.27.dist-info → notionary-0.2.28.dist-info}/METADATA +54 -49
- notionary-0.2.28.dist-info/RECORD +200 -0
- {notionary-0.2.27.dist-info → notionary-0.2.28.dist-info}/WHEEL +1 -1
- {notionary-0.2.27.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 -712
- 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.27.dist-info/RECORD +0 -202
@@ -1,141 +0,0 @@
|
|
1
|
-
from __future__ import annotations
|
2
|
-
|
3
|
-
import re
|
4
|
-
|
5
|
-
from notionary.blocks.column.column_element import ColumnElement
|
6
|
-
from notionary.page.writer.handler.line_handler import (
|
7
|
-
LineHandler,
|
8
|
-
LineProcessingContext,
|
9
|
-
)
|
10
|
-
from notionary.page.writer.handler.line_processing_context import ParentBlockContext
|
11
|
-
|
12
|
-
|
13
|
-
class ColumnHandler(LineHandler):
|
14
|
-
"""Handles single column elements - both start and end.
|
15
|
-
Syntax:
|
16
|
-
::: column # Start individual column (can have optional parameters)
|
17
|
-
Content here
|
18
|
-
::: # End column
|
19
|
-
"""
|
20
|
-
|
21
|
-
def __init__(self):
|
22
|
-
super().__init__()
|
23
|
-
self._start_pattern = re.compile(r"^:::\s*column(\s+.*?)?\s*$", re.IGNORECASE)
|
24
|
-
self._end_pattern = re.compile(r"^:::\s*$")
|
25
|
-
|
26
|
-
def _can_handle(self, context: LineProcessingContext) -> bool:
|
27
|
-
return self._is_column_start(context) or self._is_column_end(context)
|
28
|
-
|
29
|
-
async def _process(self, context: LineProcessingContext) -> None:
|
30
|
-
if self._is_column_start(context):
|
31
|
-
await self._start_column(context)
|
32
|
-
self._mark_processed(context)
|
33
|
-
return
|
34
|
-
|
35
|
-
if self._is_column_end(context):
|
36
|
-
await self._finalize_column(context)
|
37
|
-
self._mark_processed(context)
|
38
|
-
|
39
|
-
def _is_column_start(self, context: LineProcessingContext) -> bool:
|
40
|
-
"""Check if line starts a column (::: column)."""
|
41
|
-
return self._start_pattern.match(context.line.strip()) is not None
|
42
|
-
|
43
|
-
def _is_column_end(self, context: LineProcessingContext) -> bool:
|
44
|
-
"""Check if we need to end a single column (:::)."""
|
45
|
-
if not self._end_pattern.match(context.line.strip()):
|
46
|
-
return False
|
47
|
-
|
48
|
-
if not context.parent_stack:
|
49
|
-
return False
|
50
|
-
|
51
|
-
# Check if top of stack is a Column (not ColumnList)
|
52
|
-
current_parent = context.parent_stack[-1]
|
53
|
-
return issubclass(current_parent.element_type, ColumnElement)
|
54
|
-
|
55
|
-
async def _start_column(self, context: LineProcessingContext) -> None:
|
56
|
-
"""Start a new column."""
|
57
|
-
# Create Column block directly - much more efficient!
|
58
|
-
column_element = ColumnElement()
|
59
|
-
result = await column_element.markdown_to_notion(context.line)
|
60
|
-
if not result:
|
61
|
-
return
|
62
|
-
|
63
|
-
block = result
|
64
|
-
|
65
|
-
# Push to parent stack
|
66
|
-
parent_context = ParentBlockContext(
|
67
|
-
block=block,
|
68
|
-
element_type=ColumnElement,
|
69
|
-
child_lines=[],
|
70
|
-
)
|
71
|
-
context.parent_stack.append(parent_context)
|
72
|
-
|
73
|
-
async def _finalize_column(self, context: LineProcessingContext) -> None:
|
74
|
-
"""Finalize a single column and add it to the column list or result."""
|
75
|
-
column_context = context.parent_stack.pop()
|
76
|
-
await self._assign_column_children_if_any(column_context, context)
|
77
|
-
|
78
|
-
if context.parent_stack:
|
79
|
-
parent = context.parent_stack[-1]
|
80
|
-
from notionary.blocks.column.column_list_element import ColumnListElement
|
81
|
-
|
82
|
-
if issubclass(parent.element_type, ColumnListElement):
|
83
|
-
# Add to parent using the new system
|
84
|
-
parent.add_child_block(column_context.block)
|
85
|
-
return
|
86
|
-
|
87
|
-
# Fallback: no parent or parent is not ColumnList
|
88
|
-
context.result_blocks.append(column_context.block)
|
89
|
-
|
90
|
-
async def _assign_column_children_if_any(
|
91
|
-
self, column_context: ParentBlockContext, context: LineProcessingContext
|
92
|
-
) -> None:
|
93
|
-
"""Collect and assign any children blocks inside this column."""
|
94
|
-
all_children = []
|
95
|
-
|
96
|
-
# Process text lines
|
97
|
-
if column_context.child_lines:
|
98
|
-
children_text = "\n".join(column_context.child_lines)
|
99
|
-
text_blocks = await self._convert_children_text(
|
100
|
-
children_text, context.block_registry
|
101
|
-
)
|
102
|
-
all_children.extend(text_blocks)
|
103
|
-
|
104
|
-
# Add direct child blocks (like processed toggles)
|
105
|
-
if column_context.child_blocks:
|
106
|
-
all_children.extend(column_context.child_blocks)
|
107
|
-
|
108
|
-
column_context.block.column.children = all_children
|
109
|
-
|
110
|
-
def _try_add_to_parent_column_list(
|
111
|
-
self, column_context: ParentBlockContext, context: LineProcessingContext
|
112
|
-
) -> bool:
|
113
|
-
"""If the previous stack element is a ColumnList, append column and return True."""
|
114
|
-
if not context.parent_stack:
|
115
|
-
return False
|
116
|
-
|
117
|
-
parent = context.parent_stack[-1]
|
118
|
-
from notionary.blocks.column.column_list_element import ColumnListElement
|
119
|
-
|
120
|
-
if not issubclass(parent.element_type, ColumnListElement):
|
121
|
-
return False
|
122
|
-
|
123
|
-
parent.block.column_list.children.append(column_context.block)
|
124
|
-
return True
|
125
|
-
|
126
|
-
async def _convert_children_text(self, text: str, block_registry) -> list:
|
127
|
-
"""Convert children text to blocks."""
|
128
|
-
from notionary.page.writer.markdown_to_notion_converter import (
|
129
|
-
MarkdownToNotionConverter,
|
130
|
-
)
|
131
|
-
|
132
|
-
if not text.strip():
|
133
|
-
return []
|
134
|
-
|
135
|
-
child_converter = MarkdownToNotionConverter(block_registry)
|
136
|
-
return await child_converter.process_lines(text)
|
137
|
-
|
138
|
-
def _mark_processed(self, context: LineProcessingContext) -> None:
|
139
|
-
"""Mark context as processed and signal to continue."""
|
140
|
-
context.was_processed = True
|
141
|
-
context.should_continue = True
|
@@ -1,139 +0,0 @@
|
|
1
|
-
from __future__ import annotations
|
2
|
-
|
3
|
-
import re
|
4
|
-
|
5
|
-
from notionary.blocks.column.column_list_element import ColumnListElement
|
6
|
-
from notionary.page.writer.handler.line_handler import (
|
7
|
-
LineHandler,
|
8
|
-
LineProcessingContext,
|
9
|
-
)
|
10
|
-
from notionary.page.writer.handler.line_processing_context import ParentBlockContext
|
11
|
-
|
12
|
-
|
13
|
-
class ColumnListHandler(LineHandler):
|
14
|
-
"""Handles column list elements - both start and end.
|
15
|
-
Syntax:
|
16
|
-
::: columns # Start column list
|
17
|
-
::: column # Individual column
|
18
|
-
Content here
|
19
|
-
::: # End column
|
20
|
-
::: column # Another column
|
21
|
-
More content
|
22
|
-
::: # End column
|
23
|
-
::: # End column list
|
24
|
-
"""
|
25
|
-
|
26
|
-
def __init__(self):
|
27
|
-
super().__init__()
|
28
|
-
self._start_pattern = re.compile(r"^:::\s*columns?\s*$", re.IGNORECASE)
|
29
|
-
self._end_pattern = re.compile(r"^:::\s*$")
|
30
|
-
|
31
|
-
def _can_handle(self, context: LineProcessingContext) -> bool:
|
32
|
-
return self._is_column_list_start(context) or self._is_column_list_end(context)
|
33
|
-
|
34
|
-
async def _process(self, context: LineProcessingContext) -> None:
|
35
|
-
if self._is_column_list_start(context):
|
36
|
-
await self._start_column_list(context)
|
37
|
-
context.was_processed = True
|
38
|
-
context.should_continue = True
|
39
|
-
return
|
40
|
-
|
41
|
-
if self._is_column_list_end(context):
|
42
|
-
await self._finalize_column_list(context)
|
43
|
-
context.was_processed = True
|
44
|
-
context.should_continue = True
|
45
|
-
|
46
|
-
def _is_column_list_start(self, context: LineProcessingContext) -> bool:
|
47
|
-
"""Check if line starts a column list (::: columns)."""
|
48
|
-
return self._start_pattern.match(context.line.strip()) is not None
|
49
|
-
|
50
|
-
def _is_column_list_end(self, context: LineProcessingContext) -> bool:
|
51
|
-
"""Check if we need to end a column list (:::)."""
|
52
|
-
if not self._end_pattern.match(context.line.strip()):
|
53
|
-
return False
|
54
|
-
|
55
|
-
if not context.parent_stack:
|
56
|
-
return False
|
57
|
-
|
58
|
-
# Check if top of stack is a ColumnList
|
59
|
-
current_parent = context.parent_stack[-1]
|
60
|
-
return issubclass(current_parent.element_type, ColumnListElement)
|
61
|
-
|
62
|
-
async def _start_column_list(self, context: LineProcessingContext) -> None:
|
63
|
-
"""Start a new column list."""
|
64
|
-
# Create ColumnList block using the element from registry
|
65
|
-
column_list_element = None
|
66
|
-
for element in context.block_registry.get_elements():
|
67
|
-
if issubclass(element, ColumnListElement):
|
68
|
-
column_list_element = element
|
69
|
-
break
|
70
|
-
|
71
|
-
if not column_list_element:
|
72
|
-
return
|
73
|
-
|
74
|
-
# Create the block
|
75
|
-
result = await column_list_element.markdown_to_notion(context.line)
|
76
|
-
if not result:
|
77
|
-
return
|
78
|
-
|
79
|
-
block = result
|
80
|
-
|
81
|
-
# Push to parent stack
|
82
|
-
parent_context = ParentBlockContext(
|
83
|
-
block=block,
|
84
|
-
element_type=column_list_element,
|
85
|
-
child_lines=[],
|
86
|
-
)
|
87
|
-
context.parent_stack.append(parent_context)
|
88
|
-
|
89
|
-
async def _finalize_column_list(self, context: LineProcessingContext) -> None:
|
90
|
-
"""Finalize a column list and add it to result_blocks."""
|
91
|
-
column_list_context = context.parent_stack.pop()
|
92
|
-
await self._assign_column_list_children_if_any(column_list_context, context)
|
93
|
-
|
94
|
-
# Check if we have a parent context to add this column_list to
|
95
|
-
if context.parent_stack:
|
96
|
-
# Add this column_list as a child block to the parent (like Toggle)
|
97
|
-
parent_context = context.parent_stack[-1]
|
98
|
-
parent_context.add_child_block(column_list_context.block)
|
99
|
-
|
100
|
-
else:
|
101
|
-
# No parent, add to top level
|
102
|
-
context.result_blocks.append(column_list_context.block)
|
103
|
-
|
104
|
-
async def _assign_column_list_children_if_any(
|
105
|
-
self, column_list_context: ParentBlockContext, context: LineProcessingContext
|
106
|
-
) -> None:
|
107
|
-
"""Collect and assign any column children blocks inside this column list."""
|
108
|
-
all_children = []
|
109
|
-
|
110
|
-
# Process text lines
|
111
|
-
if column_list_context.child_lines:
|
112
|
-
children_text = "\n".join(column_list_context.child_lines)
|
113
|
-
children_blocks = await self._convert_children_text(
|
114
|
-
children_text, context.block_registry
|
115
|
-
)
|
116
|
-
all_children.extend(children_blocks)
|
117
|
-
|
118
|
-
if column_list_context.child_blocks:
|
119
|
-
all_children.extend(column_list_context.child_blocks)
|
120
|
-
|
121
|
-
# Filter only column blocks
|
122
|
-
column_children = [
|
123
|
-
block
|
124
|
-
for block in all_children
|
125
|
-
if hasattr(block, "column") and getattr(block, "type", None) == "column"
|
126
|
-
]
|
127
|
-
column_list_context.block.column_list.children = column_children
|
128
|
-
|
129
|
-
async def _convert_children_text(self, text: str, block_registry) -> list:
|
130
|
-
"""Convert children text to blocks."""
|
131
|
-
from notionary.page.writer.markdown_to_notion_converter import (
|
132
|
-
MarkdownToNotionConverter,
|
133
|
-
)
|
134
|
-
|
135
|
-
if not text.strip():
|
136
|
-
return []
|
137
|
-
|
138
|
-
child_converter = MarkdownToNotionConverter(block_registry)
|
139
|
-
return await child_converter.process_lines(text)
|
@@ -1,74 +0,0 @@
|
|
1
|
-
import re
|
2
|
-
|
3
|
-
from notionary.blocks.equation.equation_element import EquationElement
|
4
|
-
from notionary.page.writer.handler.line_handler import (
|
5
|
-
LineHandler,
|
6
|
-
LineProcessingContext,
|
7
|
-
)
|
8
|
-
|
9
|
-
|
10
|
-
class EquationHandler(LineHandler):
|
11
|
-
r"""Handles equation block specific logic with batching.
|
12
|
-
|
13
|
-
Markdown syntax:
|
14
|
-
$$
|
15
|
-
\sum_{i=1}^n i = \frac{n(n+1)}{2} \\
|
16
|
-
\sum_{i=1}^n i^2 = \frac{n(n+1)(2n+1)}{6} \\
|
17
|
-
\sum_{i=1}^n i^3 = \left(\frac{n(n+1)}{2}\right)^2
|
18
|
-
$$
|
19
|
-
"""
|
20
|
-
|
21
|
-
def __init__(self):
|
22
|
-
super().__init__()
|
23
|
-
self._equation_start_pattern = re.compile(r"^\$\$\s*$")
|
24
|
-
self._equation_end_pattern = re.compile(r"^\$\$\s*$")
|
25
|
-
|
26
|
-
def _can_handle(self, context: LineProcessingContext) -> bool:
|
27
|
-
if self._is_inside_parent_context(context):
|
28
|
-
return False
|
29
|
-
return self._is_equation_start(context)
|
30
|
-
|
31
|
-
async def _process(self, context: LineProcessingContext) -> None:
|
32
|
-
if self._is_equation_start(context):
|
33
|
-
await self._process_complete_equation_block(context)
|
34
|
-
self._mark_processed(context)
|
35
|
-
|
36
|
-
def _is_equation_start(self, context: LineProcessingContext) -> bool:
|
37
|
-
"""Check if this line starts an equation block."""
|
38
|
-
return self._equation_start_pattern.match(context.line.strip()) is not None
|
39
|
-
|
40
|
-
def _is_inside_parent_context(self, context: LineProcessingContext) -> bool:
|
41
|
-
"""Check if we're currently inside any parent context (toggle, heading, etc.)."""
|
42
|
-
return len(context.parent_stack) > 0
|
43
|
-
|
44
|
-
async def _process_complete_equation_block(
|
45
|
-
self, context: LineProcessingContext
|
46
|
-
) -> None:
|
47
|
-
"""Process the entire equation block in one go using EquationElement."""
|
48
|
-
equation_lines, lines_to_consume = self._collect_equation_lines(context)
|
49
|
-
|
50
|
-
block = EquationElement.create_from_markdown_block(
|
51
|
-
opening_line=context.line, equation_lines=equation_lines
|
52
|
-
)
|
53
|
-
|
54
|
-
if block:
|
55
|
-
context.lines_consumed = lines_to_consume
|
56
|
-
context.result_blocks.append(block)
|
57
|
-
|
58
|
-
def _collect_equation_lines(
|
59
|
-
self, context: LineProcessingContext
|
60
|
-
) -> tuple[list[str], int]:
|
61
|
-
"""Collect lines until closing $$ fence and return (lines, count_to_consume)."""
|
62
|
-
lines = []
|
63
|
-
for idx, ln in enumerate(context.get_remaining_lines()):
|
64
|
-
if self._equation_end_pattern.match(ln.strip()):
|
65
|
-
return lines, idx + 1
|
66
|
-
lines.append(ln)
|
67
|
-
# No closing fence: consume all remaining
|
68
|
-
rem = context.get_remaining_lines()
|
69
|
-
return rem, len(rem)
|
70
|
-
|
71
|
-
def _mark_processed(self, context: LineProcessingContext) -> None:
|
72
|
-
"""Mark context as processed and continue."""
|
73
|
-
context.was_processed = True
|
74
|
-
context.should_continue = True
|
@@ -1,35 +0,0 @@
|
|
1
|
-
from __future__ import annotations
|
2
|
-
|
3
|
-
from abc import ABC, abstractmethod
|
4
|
-
from typing import Optional
|
5
|
-
|
6
|
-
from notionary.page.writer.handler.line_processing_context import LineProcessingContext
|
7
|
-
|
8
|
-
|
9
|
-
class LineHandler(ABC):
|
10
|
-
"""Abstract base class for line handlers."""
|
11
|
-
|
12
|
-
def __init__(self):
|
13
|
-
self._next_handler: Optional[LineHandler] = None
|
14
|
-
|
15
|
-
def set_next(self, handler: LineHandler) -> LineHandler:
|
16
|
-
"""Set the next handler in the chain."""
|
17
|
-
self._next_handler = handler
|
18
|
-
return handler
|
19
|
-
|
20
|
-
async def handle(self, context: LineProcessingContext) -> None:
|
21
|
-
"""Handle the line or pass to next handler."""
|
22
|
-
if self._can_handle(context):
|
23
|
-
await self._process(context)
|
24
|
-
elif self._next_handler:
|
25
|
-
await self._next_handler.handle(context)
|
26
|
-
|
27
|
-
@abstractmethod
|
28
|
-
def _can_handle(self, context: LineProcessingContext) -> bool:
|
29
|
-
"""Check if this handler can process the current line."""
|
30
|
-
pass
|
31
|
-
|
32
|
-
@abstractmethod
|
33
|
-
async def _process(self, context: LineProcessingContext) -> None:
|
34
|
-
"""Process the line and update context."""
|
35
|
-
pass
|
@@ -1,54 +0,0 @@
|
|
1
|
-
from __future__ import annotations
|
2
|
-
|
3
|
-
from dataclasses import dataclass, field
|
4
|
-
from typing import Optional
|
5
|
-
|
6
|
-
from notionary.blocks.base_block_element import BaseBlockElement
|
7
|
-
from notionary.blocks.models import BlockCreateRequest
|
8
|
-
from notionary.blocks.registry.block_registry import BlockRegistry
|
9
|
-
|
10
|
-
|
11
|
-
@dataclass
|
12
|
-
class ParentBlockContext:
|
13
|
-
"""Context for a block that expects children."""
|
14
|
-
|
15
|
-
block: BlockCreateRequest
|
16
|
-
element_type: BaseBlockElement
|
17
|
-
child_lines: list[str]
|
18
|
-
child_blocks: list[BlockCreateRequest] = field(default_factory=list)
|
19
|
-
|
20
|
-
def add_child_line(self, content: str):
|
21
|
-
"""Adds a child line."""
|
22
|
-
self.child_lines.append(content)
|
23
|
-
|
24
|
-
def add_child_block(self, block: BlockCreateRequest):
|
25
|
-
"""Adds a processed child block."""
|
26
|
-
self.child_blocks.append(block)
|
27
|
-
|
28
|
-
def has_children(self) -> bool:
|
29
|
-
"""Checks if children have been collected."""
|
30
|
-
return len(self.child_lines) > 0 or len(self.child_blocks) > 0
|
31
|
-
|
32
|
-
|
33
|
-
@dataclass
|
34
|
-
class LineProcessingContext:
|
35
|
-
"""Context that gets passed through the handler chain."""
|
36
|
-
|
37
|
-
line: str
|
38
|
-
result_blocks: list[BlockCreateRequest]
|
39
|
-
parent_stack: list[ParentBlockContext]
|
40
|
-
block_registry: BlockRegistry
|
41
|
-
|
42
|
-
all_lines: Optional[list[str]] = None
|
43
|
-
current_line_index: Optional[int] = None
|
44
|
-
lines_consumed: int = 0
|
45
|
-
|
46
|
-
# Result indicators
|
47
|
-
was_processed: bool = False
|
48
|
-
should_continue: bool = False
|
49
|
-
|
50
|
-
def get_remaining_lines(self) -> list[str]:
|
51
|
-
"""Get all remaining lines from current position."""
|
52
|
-
if self.all_lines is None or self.current_line_index is None:
|
53
|
-
return []
|
54
|
-
return self.all_lines[self.current_line_index + 1 :]
|
@@ -1,86 +0,0 @@
|
|
1
|
-
from notionary.blocks.column.column_element import ColumnElement
|
2
|
-
from notionary.blocks.column.column_list_element import ColumnListElement
|
3
|
-
from notionary.page.writer.handler import LineHandler, LineProcessingContext
|
4
|
-
|
5
|
-
|
6
|
-
class RegularLineHandler(LineHandler):
|
7
|
-
"""Handles regular lines - respects parent contexts like columns."""
|
8
|
-
|
9
|
-
def _can_handle(self, context: LineProcessingContext) -> bool:
|
10
|
-
return context.line.strip()
|
11
|
-
|
12
|
-
async def _process(self, context: LineProcessingContext) -> None:
|
13
|
-
if self._is_in_column_context(context):
|
14
|
-
self._add_to_column_context(context)
|
15
|
-
context.was_processed = True
|
16
|
-
context.should_continue = True
|
17
|
-
return
|
18
|
-
|
19
|
-
block_created = await self._process_single_line_content(context)
|
20
|
-
if not block_created:
|
21
|
-
await self._process_as_paragraph(context)
|
22
|
-
|
23
|
-
context.was_processed = True
|
24
|
-
|
25
|
-
def _is_in_column_context(self, context: LineProcessingContext) -> bool:
|
26
|
-
"""Check if we're inside a Column/ColumnList context."""
|
27
|
-
if not context.parent_stack:
|
28
|
-
return False
|
29
|
-
|
30
|
-
current_parent = context.parent_stack[-1]
|
31
|
-
return issubclass(
|
32
|
-
current_parent.element_type, (ColumnListElement, ColumnElement)
|
33
|
-
)
|
34
|
-
|
35
|
-
def _add_to_column_context(self, context: LineProcessingContext) -> None:
|
36
|
-
"""Add line as child to the current Column context."""
|
37
|
-
context.parent_stack[-1].add_child_line(context.line)
|
38
|
-
|
39
|
-
async def _process_single_line_content(
|
40
|
-
self, context: LineProcessingContext
|
41
|
-
) -> bool:
|
42
|
-
"""Process a regular line for simple elements (lists, etc.)."""
|
43
|
-
specialized_elements = self._get_specialized_elements()
|
44
|
-
|
45
|
-
for element in context.block_registry.get_elements():
|
46
|
-
|
47
|
-
if issubclass(element, specialized_elements):
|
48
|
-
continue
|
49
|
-
|
50
|
-
result = await element.markdown_to_notion(context.line)
|
51
|
-
if not result:
|
52
|
-
continue
|
53
|
-
|
54
|
-
context.result_blocks.append(result)
|
55
|
-
|
56
|
-
return True
|
57
|
-
|
58
|
-
return False
|
59
|
-
|
60
|
-
async def _process_as_paragraph(self, context: LineProcessingContext) -> None:
|
61
|
-
"""Process a line as a paragraph."""
|
62
|
-
from notionary.blocks.paragraph.paragraph_element import ParagraphElement
|
63
|
-
|
64
|
-
paragraph_element = ParagraphElement()
|
65
|
-
result = await paragraph_element.markdown_to_notion(context.line)
|
66
|
-
|
67
|
-
if result:
|
68
|
-
context.result_blocks.append(result)
|
69
|
-
|
70
|
-
def _get_specialized_elements(self):
|
71
|
-
"""Get tuple of elements that have specialized handlers."""
|
72
|
-
from notionary.blocks.code import CodeElement
|
73
|
-
from notionary.blocks.paragraph import ParagraphElement
|
74
|
-
from notionary.blocks.table import TableElement
|
75
|
-
from notionary.blocks.toggle import ToggleElement
|
76
|
-
from notionary.blocks.toggleable_heading import ToggleableHeadingElement
|
77
|
-
|
78
|
-
return (
|
79
|
-
ColumnListElement,
|
80
|
-
ColumnElement,
|
81
|
-
ToggleElement,
|
82
|
-
ToggleableHeadingElement,
|
83
|
-
TableElement,
|
84
|
-
CodeElement,
|
85
|
-
ParagraphElement,
|
86
|
-
)
|
@@ -1,66 +0,0 @@
|
|
1
|
-
import re
|
2
|
-
|
3
|
-
from notionary.blocks.table.table_element import TableElement
|
4
|
-
from notionary.page.writer.handler import LineHandler, LineProcessingContext
|
5
|
-
|
6
|
-
|
7
|
-
class TableHandler(LineHandler):
|
8
|
-
"""Handles table specific logic with batching."""
|
9
|
-
|
10
|
-
def __init__(self):
|
11
|
-
super().__init__()
|
12
|
-
self._table_row_pattern = re.compile(r"^\s*\|(.+)\|\s*$")
|
13
|
-
self._separator_pattern = re.compile(r"^\s*\|([\s\-:|]+)\|\s*$")
|
14
|
-
|
15
|
-
def _can_handle(self, context: LineProcessingContext) -> bool:
|
16
|
-
if self._is_inside_parent_context(context):
|
17
|
-
return False
|
18
|
-
return self._is_table_start(context)
|
19
|
-
|
20
|
-
async def _process(self, context: LineProcessingContext) -> None:
|
21
|
-
if not self._is_table_start(context):
|
22
|
-
return
|
23
|
-
|
24
|
-
await self._process_complete_table(context)
|
25
|
-
context.was_processed = True
|
26
|
-
context.should_continue = True
|
27
|
-
|
28
|
-
def _is_inside_parent_context(self, context: LineProcessingContext) -> bool:
|
29
|
-
"""Check if we're currently inside any parent context (toggle, heading, etc.)."""
|
30
|
-
return len(context.parent_stack) > 0
|
31
|
-
|
32
|
-
def _is_table_start(self, context: LineProcessingContext) -> bool:
|
33
|
-
"""Check if this line starts a table."""
|
34
|
-
return self._table_row_pattern.match(context.line.strip()) is not None
|
35
|
-
|
36
|
-
async def _process_complete_table(self, context: LineProcessingContext) -> None:
|
37
|
-
"""Process the entire table in one go using TableElement."""
|
38
|
-
# Collect all table lines (including the current one)
|
39
|
-
table_lines = [context.line]
|
40
|
-
remaining_lines = context.get_remaining_lines()
|
41
|
-
lines_to_consume = 0
|
42
|
-
|
43
|
-
# Find all consecutive table rows
|
44
|
-
for i, line in enumerate(remaining_lines):
|
45
|
-
line_stripped = line.strip()
|
46
|
-
if not line_stripped:
|
47
|
-
# Empty line - continue to allow for spacing in tables
|
48
|
-
table_lines.append(line)
|
49
|
-
continue
|
50
|
-
|
51
|
-
if self._table_row_pattern.match(
|
52
|
-
line_stripped
|
53
|
-
) or self._separator_pattern.match(line_stripped):
|
54
|
-
table_lines.append(line)
|
55
|
-
else:
|
56
|
-
# Not a table line - stop here
|
57
|
-
lines_to_consume = i
|
58
|
-
break
|
59
|
-
else:
|
60
|
-
lines_to_consume = len(remaining_lines)
|
61
|
-
|
62
|
-
block = await TableElement.create_from_markdown_table(table_lines)
|
63
|
-
|
64
|
-
if block:
|
65
|
-
context.lines_consumed = lines_to_consume
|
66
|
-
context.result_blocks.append(block)
|