Table Inline Formatting

April 15, 2026 · View on GitHub

Problem

Inline markdown formatting (bold, italic, strikethrough, code) was silently stripped from table cells. Two distinct issues:

  1. Serialization loss: text_content() stripped all formatting markers during round-trip serialization, so ~~strikethrough~~ became strikethrough when switching views or editing.
  2. No rendered display: Table cells rendered as plain TextEdit widgets with no inline formatting — bold, italic, and strikethrough markers appeared as literal text in the rendered view.

Fix: Serialization Preservation

Replaced cell.text_content() with serialize_inline_content(cell) in two call sites in src/markdown/widgets.rs:

  • serialize_table() — markdown serialization output
  • TableData::from_node() — editable table data model population

The serialize_inline_content() function already existed and correctly handles all inline node types recursively.

Fix: Rendered View Formatting

Added a click-to-edit display model for table cells:

  • Display mode (cell not focused): Renders a rich text Label using build_cell_layout_job() which parses inline markdown and builds an egui LayoutJob with proper formatting.
  • Edit mode (cell focused): Shows the raw TextEdit with markdown syntax visible, as before.

Inline Markdown Parser

parse_inline_markdown() is a recursive descent parser that handles:

SyntaxRenderingNotes
***text***Bold + italicChecked before ** to avoid ambiguity
**text**BoldUses get_styled_font_family() for correct font variant
*text*ItalicTextFormat.italics = true
~~text~~StrikethroughTextFormat.strikethrough stroke
`text`Inline codeMonospace font with background color

Nesting is fully supported (e.g., **~~bold struck~~**, ***~~all three~~***).

Header row cells render with bold as the base style.

Editor Font Threading

editor_font: &EditorFont is threaded from render_noderender_table()EditableTable.editor_font() so the table widget uses the correct bold/italic font variants (Inter-Bold, JetBrains-Bold, etc.).

Files Changed

FileChange
src/markdown/widgets.rsserialize_table() and TableData::from_node(): use serialize_inline_content()
src/markdown/widgets.rsNew: build_cell_layout_job(), parse_inline_markdown(), helper functions
src/markdown/widgets.rsEditableTable: added editor_font field, click-to-edit cell rendering
src/markdown/editor.rsrender_table(): added editor_font parameter, passed to EditableTable

Verification

Tables with inline formatting now render correctly and round-trip:

| Style | Example |
|-------|---------|
| Bold | **strong** |
| Italic | *slanted* |
| Strikethrough | ~~removed~~ |
| Bold + italic | ***both*** |
| Nested | **~~bold struck~~** |
| Triple | ***~~all three~~*** |