Kramdown-compatible Block Quote + Notion API drift fixes#211
Merged
Conversation
The Block Quote export used <div custom-style="Block Quote"> without markdown="1", causing kramdown to skip markdown processing inside the div. Bold text (**text**) and other markdown rendered as literal text. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
EquationRichText previously emitted Math(InlineMath, expr), which pandoc's gfm writer renders as `$...$`. Kramdown (used by Jekyll) then processes underscores inside single-dollar math as emphasis markers, corrupting any equation containing subscripts or other underscores. Switching to DisplayMath emits `$$...$$`, which kramdown leaves intact and MathJax renders correctly. This matches how most Markdown-to-HTML toolchains expect equations to be delimited and avoids the underscore-eating bug.
- test_rich_text: equations are now Math(DisplayMath, ...) instead of Math(InlineMath, ...), and markdown output uses $$...$$ delimiters - test_blocks: Block Quote Div now carries markdown="1" attribute, which flows through to the generated pandoc fenced div in markdown output
…ocks Notion's API has tightened block-append and page-create validation since these tests last passed against the live API: 1. "Append block children" now rejects payloads containing read-only fields like `archived`, `id`, `parent`, `created_time`, `last_edited_time`, `has_children`, `url`, etc. Previously these were silently ignored. Add `_sanitize_block_for_append` so each child is stripped of read-only fields before being PATCHed. 2. "Create a page" / "Create a database" now reject the `archived` field (and similarly `in_trash`, `public_url`). Add those to the bad_keys lists in `copy_notion_database_children`, `_copy_notion_database_child_page`, and `_copy_notion_database_child_database`. 3. Notion added a new `transcription` block type used by meeting-notes pages, which previously raised NotImplementedError when encountered. Map it to UnsupportedBlock for now, matching how other unhandled types are treated.
…nges - Block Quote fenced div now carries the markdown="1" attribute - Equation rich-text now emits $$...$$ instead of $...$
Previously inline math was emitted as Math(InlineMath, expr), which the pandoc gfm writer renders as $...$. Kramdown (Jekyll's default Markdown processor) does not recognize $...$ as math, so it processes the inside as regular Markdown — turning underscores in subscripts into <em> tags and dropping the LaTeX before MathJax ever sees it. The previous attempt (this branch) switched to DisplayMath, which sidesteps Kramdown but loses inline semantics (every glyph becomes a centered block). Better fix: emit RawInline HTML with MathJax's standard inline delimiters \(...\), wrapped in <span markdown="0">…</span>. The span attribute tells Kramdown not to parse Markdown inside, so subscript underscores are preserved verbatim and MathJax renders the inline math correctly in place. Block-level equations (EquationBlock) continue to use DisplayMath, which is semantically correct — they should render as centered blocks.
Per review feedback: replacing semantic Math with RawInline(html) for
inline equations breaks non-HTML pandoc targets (DOCX, LaTeX, plain),
which silently drop raw HTML. The Kramdown workaround is downstream-
specific and belongs in a consumer-side n2y plugin, not in the core
EquationRichText that every consumer uses.
This leaves the PR scoped to two genuinely cross-cutting fixes:
- Block Quote Div gets markdown="1" so Kramdown processes its body
(no rendering impact for non-Kramdown targets, since markdown="1"
is just an attribute that travels through pandoc unchanged)
- Notion API drift: sanitize append/create payloads and add the new
"transcription" block type
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two cross-cutting fixes that benefit every n2y consumer, with no behavior regression for non-Markdown/non-HTML pandoc targets.
1. Block Quote
Div— addmarkdown="1"attributeThe
QuoteBlockimplementation wraps quoted content in a pandocDivwithcustom-style="Block Quote"(for DOCX round-tripping). Pandoc renders this as a fenced div:Without
markdown="1", Kramdown treats the body as raw HTML and skips Markdown processing inside — so inline links, emphasis, and rich text in block quotes are emitted literally instead of being parsed. Adding the attribute opts the body back into Markdown processing under Kramdown. For non-Kramdown pandoc writers (DOCX, LaTeX, plain) the attribute is just a benign div attribute and rendering is unchanged.2. Notion API drift — append/create payload sanitization + new
transcriptionblock typeNotion has tightened validation on the live API since these tests last passed:
archived,id,parent,created_time,last_edited_time,has_children,url, etc.). Added a_sanitize_block_for_appendhelper that strips those fields from each child before PATCH.archived(andin_trash,public_url). Added those to thebad_keyslists incopy_notion_database_children,_copy_notion_database_child_page, and_copy_notion_database_child_database.transcriptionblock type used by meeting-notes pages, which n2y didn't know about. Mapped it toUnsupportedBlockinDEFAULT_BLOCKSfor now, matching the convention for other unhandled types.Out of scope (intentionally)
An earlier revision of this PR also patched
EquationRichTextto emit raw HTML for Kramdown compatibility. That was reverted: replacing semanticMathwithRawInline(html)regresses non-HTML pandoc targets (DOCX, LaTeX, plain), which silently drop raw HTML. The Kramdown math workaround is downstream-specific and is better implemented as an n2y plugin in the consuming repo.Test plan
tests/test_rich_text.pypassestests/test_blocks.py::test_block_quotepasses