Skip to content

Add optional blank line preservation (MD_FLAG_PRESERVEBLANKLINES) - #385

Merged
mity merged 5 commits into
mity:masterfrom
eszlamczyk:feat/optional-flag-to-preserve-blank-lines
Aug 17, 2026
Merged

Add optional blank line preservation (MD_FLAG_PRESERVEBLANKLINES)#385
mity merged 5 commits into
mity:masterfrom
eszlamczyk:feat/optional-flag-to-preserve-blank-lines

Conversation

@eszlamczyk

Copy link
Copy Markdown
Contributor

Closes #384.

Motivation

When rendering from the MD4C callback stream (e.g. building a native view tree for a WYSIWYG-like editor), the number of blank lines the author typed between blocks is meaningful. CommonMark collapses any run of blank lines into a single block boundary, and MD4C discards this information in the process so it can't be recovered downstream without pre-processing the source. This adds an opt-in way to get that information from the parser.

What this does

Adds the flag MD_FLAG_PRESERVEBLANKLINES. When enabled, each run of blank lines separating two blocks is reported as a single new block MD_BLOCK_BLANK, whose detail MD_BLOCK_BLANK_DETAIL carries the number of blank lines:

  typedef struct MD_BLOCK_BLANK_DETAIL {
      unsigned count;   /* Count of blank lines forming the block separation */
  } MD_BLOCK_BLANK_DETAIL;

Following the discussion in #384, the run is coalesced into one block (the count is stored once, not one block per line), and all blank lines are reported - i.e. the arser reports "this block separation is made of N blank lines" and leaves the rendering decision to the application.

With the flag off, behaviour and output are byte-for-byte unchanged.

Semantics

  • One MD_BLOCK_BLANK per run; no MD_TEXT is sent.
  • Blank lines attach to the innermost open container and flush at the next block boundary, so runs split correctly across edges: blanks inside a block quote are reported inside it, blanks after it at the outer level (and vice versa).
  • Only genuinely empty lines are counted. Blank lines inside code blocks are verbatim content, and a few non-blank lines MD4C internally treats as blank (a closing code fence, an admonition tag) are excluded.

md2html gains --fpreserve-blank-lines; its renderer emits count non-breaking-space paragraphs so the count is visible/testable.

Note: Blank lines trailing a list's last item (before a dedented paragraph that ends the list) currently attach inside that last <li>, consistent with the "innermost open container" rule. Happy to tweak those semantics, if you'd prefer. Documented with a test in test/coverage.txt

Tests & docs

  • New test/spec-preserve-blank-lines.txt (10 examples, doubling as docs) plus harder paths in test/coverage.txt (closing-fence exclusion, HTML-end blank, loose lists, trailing-in-item, nested containers, whitespace-only lines).
  • Full suite green; -Werror Debug + Release clean. CRLF verified manually but not added as a spec test (the .txt files are LF-only).
  • README, CHANGELOG, md2html man page, and md4c.h doc comments updated.

@mity mity left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks as the right approach to me. There are some requested changes though.

Comment thread md2html/md2html.c Outdated
Comment thread src/md4c-html.c Outdated
Comment thread src/md4c.h Outdated
Comment thread src/md4c.c
@codecov

codecov Bot commented Aug 17, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 76.92308% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 78.87%. Comparing base (9de89d8) to head (5b5322b).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
src/md4c.c 75.00% 1 Missing and 4 partials ⚠️
src/md4c-html.c 80.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #385      +/-   ##
==========================================
+ Coverage   78.86%   78.87%   +0.01%     
==========================================
  Files           5        5              
  Lines        3794     3820      +26     
  Branches     1271     1279       +8     
==========================================
+ Hits         2992     3013      +21     
- Misses        297      298       +1     
- Partials      505      509       +4     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@mity
mity merged commit 3e17bae into mity:master Aug 17, 2026
7 of 8 checks passed
@eszlamczyk
eszlamczyk deleted the feat/optional-flag-to-preserve-blank-lines branch August 17, 2026 08:37
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.

Feature request: optional flag to preserve extra blank lines

2 participants