Skip to content

Fix Slate conversion defects from Plone → Volto migration (#31, #32, #33) - #34

Merged
ericof merged 3 commits into
mainfrom
uberlandia-fixes
Jun 1, 2026
Merged

Fix Slate conversion defects from Plone → Volto migration (#31, #32, #33)#34
ericof merged 3 commits into
mainfrom
uberlandia-fixes

Conversation

@ericof

@ericof ericof commented Jun 1, 2026

Copy link
Copy Markdown
Member

Summary

Three fixes for Slate conversion defects surfaced by a real-world Plone → Volto migration (Câmara Municipal de Uberlândia). Each defect produced output that either rendered incorrectly or could not be rendered by Volto at all.

Fixes

<span> text-decoration styling dropped (#32)

_span_ mapped font-weight/font-style/vertical-align to Slate inline types but ignored text-decoration. Now underlineu and line-throughs (substring match, so CSS shorthand like underline dotted red works). The style branches are collapsed into a small lookup table to stay under ruff's complexity limit.

Trailing text after an inline run split out of its paragraph (#31)

A run of consecutive inline elements (e.g. two adjacent <b> tags) followed by plain text had that text hoisted out of the parent <p> as a sibling block. Root cause: group_inline_nodes treated a plain text node as non-inline, breaking the inline run. Text nodes now continue the run (is_inline or is_simple_text).

Deeply-nested <div> structures produced non-renderable Slate (#33)

Nested <div> layouts generated invalid Slate — null entries, type-less {children: [...]} nodes, <p> inside <p>, and bare text mixed with block siblings — all surfacing only at nesting depth. Three changes:

  • _div_ now returns flatten_children(block_children), dropping None descendants and hoisting nested type-less nodes at any depth instead of hand-rolling child handling.
  • _group_top_level appends the final group with the last item's flag rather than a stale flags[i-1], so a trailing block node preceded by an inline node is no longer wrapped as inline (which produced <p> in <p>).
  • finalize_slate collapses runs of consecutive whitespace-only paragraphs to a single one (new collapse_blank_paragraphs helper) — an all-decorative section went from 34 empty paragraphs to 1.

Tests

  • New fixtures for each fix (underline/strikethrough spans, trailing-text-after-inline-run, blank-paragraph consolidation).
  • Updated the "nested divs" fixture to the cleaner output.
  • Full suite: 912 passing, lint 10/10, mypy clean.

Closes #31
Closes #32
Closes #33

ericof added 3 commits May 29, 2026 16:12
A <span> carrying text-decoration: underline (or line-through) had its
formatting silently dropped during conversion. Map underline to a slate
'u' element and line-through to 's', matching the behaviour of the
native <u>/<s> tags. The check uses a substring match so CSS shorthand
(e.g. 'underline dotted red') is handled as well.

The six style branches in _span_ are collapsed into a lookup table to
keep cyclomatic complexity under ruff's C901 threshold.
A run of consecutive inline elements (e.g. two adjacent <b> tags)
followed by plain text had that trailing text hoisted out of the parent
paragraph and emitted as a sibling block. The cause was group_inline_nodes
treating a plain text node as non-inline, which broke the inline run so its
wrapper survived as a nested block.

Treat plain text nodes as inline content (is_inline or is_simple_text) so
they continue the run, matching the predicate already used by
_group_top_level.
Deeply-nested <div> structures produced Slate that Volto cannot render:
null entries, type-less {children: [...]} nodes, <p> inside <p>, and bare
text mixed with block siblings. Source HTML full of spacers also generated
long runs of empty paragraphs.

- _div_ now flattens its assembled children (slate.flatten_children),
  dropping None descendants and hoisting nested type-less nodes at any
  depth instead of leaving them embedded in the value.
- _group_top_level appends the final group with the last item's flag
  rather than the loop's stale flags[i-1], so a trailing block node is no
  longer wrapped as inline (which produced <p> inside <p>).
- finalize_slate collapses runs of consecutive whitespace-only paragraphs
  to a single one via the new collapse_blank_paragraphs helper.

Updates the nested-divs fixture to the cleaner output and adds a
consolidation fixture.
@ericof
ericof merged commit 2ce7378 into main Jun 1, 2026
13 checks passed
@ericof
ericof deleted the uberlandia-fixes branch June 1, 2026 13:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant