diff --git a/src/backend/models/block.go b/src/backend/models/block.go index e6e62405..555adeaa 100644 --- a/src/backend/models/block.go +++ b/src/backend/models/block.go @@ -13,6 +13,7 @@ import ( type BlockType string const ( + CodeBlock BlockType = "code" TextBlock BlockType = "text" TaskBlock BlockType = "task" HeadingBlock BlockType = "header" diff --git a/src/frontend/lib/utils/attributed_text_utils.dart b/src/frontend/lib/utils/attributed_text_utils.dart index d1c69e39..b2b4e7b1 100644 --- a/src/frontend/lib/utils/attributed_text_utils.dart +++ b/src/frontend/lib/utils/attributed_text_utils.dart @@ -33,6 +33,7 @@ class AttributedTextUtils { // Use the same attribution types that SuperEditor uses in defaultStyleBuilder final attributions = [ + const NamedAttribution('code'), const NamedAttribution('bold'), const NamedAttribution('italics'), const NamedAttribution('underline'), @@ -157,6 +158,7 @@ class AttributedTextUtils { if (start >= 0 && end > start && end <= text.length) { // Apply attributions based on the type switch (type) { + case 'code': case 'bold': case 'italics': case 'underline': diff --git a/src/frontend/lib/utils/document_builder.dart b/src/frontend/lib/utils/document_builder.dart index e304804d..7f1a4a75 100644 --- a/src/frontend/lib/utils/document_builder.dart +++ b/src/frontend/lib/utils/document_builder.dart @@ -626,6 +626,8 @@ class DocumentBuilder { final levelStr = blockTypeStr.substring(6); final level = int.tryParse(levelStr) ?? 1; metadata['level'] = level; + } else if (blockType == 'code') { + metadata['code-block'] = node.metadata['code-block'] ?? 'plain'; } } else if (node is TaskNode) { content['text'] = node.text.toPlainText(); @@ -685,6 +687,8 @@ class DocumentBuilder { blockType = 'header'; final levelStr = blockType.substring(6); metadata['level'] = DataConverter.parseIntSafely(levelStr); + } else if (blockType == 'code') { + metadata['code-block'] = node.metadata['code-block'] ?? 'plain'; } } else if (node is TaskNode) { content['text'] = node.text.toPlainText(); @@ -699,11 +703,11 @@ class DocumentBuilder { // Extract spans for list items final spans = - _attributedTextUtils.extractSpansFromAttributedText(node.text); + _attributedTextUtils.extractSpansFromAttributedText(node.text); metadata['spans'] = spans; metadata['listType'] = - node.type == ListItemType.ordered ? 'ordered' : 'unordered'; + node.type == ListItemType.ordered ? 'ordered' : 'unordered'; } return {'content': content, 'metadata': metadata}; @@ -767,7 +771,29 @@ class DocumentBuilder { return [ HorizontalRuleNode( id: Editor.createNodeId(), - // metadata: metadata + ), + ]; + + case 'code': + final language = metadata != null + ? metadata['code-block']?.toString() ?? 'plain' + : 'plain'; + return [ + ParagraphNode( + id: Editor.createNodeId(), + text: _attributedTextUtils + .createAttributedTextFromContent(text, {'metadata': metadata}), + metadata: { + 'blockType': const NamedAttribution("code"), + 'code-block': language, + 'spans': [ + { + 'start': 1, + 'end': text.length, + 'type': 'code', + }, + ], + }, ), ];