Skip to content

feat(block): add GFM table and inline formatting support#10

Merged
4ier merged 5 commits into4ier:mainfrom
ahnbu:main
Mar 15, 2026
Merged

feat(block): add GFM table and inline formatting support#10
4ier merged 5 commits into4ier:mainfrom
ahnbu:main

Conversation

@ahnbu
Copy link
Contributor

@ahnbu ahnbu commented Mar 14, 2026

Summary

  • GFM table → Notion table block: parseMarkdownToBlocks() now detects pipe-delimited tables and converts them to table / table_row blocks per Notion API spec (table.children, not top-level children)
  • Inline formatting: parseInlineFormatting() tokenizes **bold**, *italic*, _italic_, `code`, ~~strike~~, [link](url) into rich_text annotation arrays — applied to all block types including table cells
  • Reverse rendering: renderBlockMarkdown() gains table / table_row cases that output GFM-style markdown with separator row
  • Helpers: isTableSeparator(), splitTableRow(), buildTableBlock(), richTextToMarkdown(), richTextItemToMarkdown()

Motivation

Uploading markdown documents with tables via block append --file previously silently dropped or mangled table rows. This makes tables a first-class citizen, consistent with Notion API's native table support.

Test plan

  • TestParseMarkdownTable — basic table, alignment markers, no-separator fallback, mixed content
  • TestParseInlineFormatting — bold, italic (* and _), code, strikethrough, link, mixed
  • TestIsTableSeparator — various separator patterns including :---:, ---:
  • All existing tests pass (go test ./...)
  • Live Notion API test: 156-line markdown with multiple tables uploaded successfully in ~3.6s

Notes

  • Alignment markers in separator rows are accepted but not forwarded to Notion (API ignores column alignment)
  • Rows with fewer cells than table_width are padded; extra cells are trimmed
  • Inline formatting applied inside table cells as well

ahnbu and others added 5 commits March 14, 2026 19:53
- parseMarkdownToBlocks(): detect pipe-delimited tables, build Notion
  table/table_row block structure (table_width, has_column_header)
- parseInlineFormatting(): tokenize **bold**, *italic*, _italic_,
  \`code\`, ~~strike~~, [link](url) → rich_text annotations array
- makeTextBlock(): now uses parseInlineFormatting instead of plain text
- renderBlockMarkdown(): add table/table_row cases with GFM separator
- richTextToMarkdown(), richTextItemToMarkdown(): helpers for rendering
  annotated rich_text back to markdown
- isTableSeparator(), splitTableRow(), buildTableBlock(): table helpers
- block_test.go: TestParseMarkdownTable, TestParseInlineFormatting,
  TestIsTableSeparator test suites added; all existing tests pass

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Notion API validation requires table_row blocks inside table.children
(not at block top-level). Fixes 'table.children should be defined' error.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Windows build artifact — should not be tracked alongside the unix binary.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@ahnbu ahnbu closed this Mar 14, 2026
@ahnbu ahnbu reopened this Mar 14, 2026
@4ier 4ier merged commit f043629 into 4ier:main Mar 15, 2026
8 checks passed
@4ier
Copy link
Owner

4ier commented Mar 15, 2026

Merged — thanks for the solid work on this! GFM table parsing + inline formatting is a much-needed addition. The approach of building proper table blocks with children (instead of top-level) is exactly right per the Notion API spec. Tests look thorough too. 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants