Skip to content

Add spoiler span extension - #308

Merged
mity merged 3 commits into
mity:masterfrom
hryhoriiK97:feature/spoiler-spans-upstream
May 1, 2026
Merged

mity merged 3 commits into
mity:masterfrom
hryhoriiK97:feature/spoiler-spans-upstream

Conversation

@hryhoriiK97

@hryhoriiK97 hryhoriiK97 commented Apr 30, 2026 •

Copy link
Copy Markdown
Contributor

Summary

This PR adds an opt-in spoiler span extension to MD4C.

The new syntax is:

||hidden text||

When MD_FLAG_SPOILER is enabled, MD4C emits a new MD_SPAN_SPOILER span. The bundled HTML renderer outputs spoilers as:

  • <x-spoiler>hidden text</x-spoiler>
  • md2html also gets a new --fspoiler option.

Motivation

We use MD4C in the react-native-enriched-markdown library, where spoiler spans are already supported.

Since spoilers are a common Markdown extension in messaging-style products, including Telegram and Discord, it would be useful to have first-class support in MD4C itself instead of maintaining this behavior only in downstream forks.

The extension is fully opt-in and does not change default CommonMark behavior.

Made-with: Cursor
@codecov

codecov Bot commented Apr 30, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 86.48649% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 78.94%. Comparing base (472c417) to head (52df1ca).
⚠️ Report is 2 commits behind head on master.

Files with missing lines Patch % Lines
src/md4c.c 85.29% 0 Missing and 5 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #308      +/-   ##
==========================================
+ Coverage   78.82%   78.94%   +0.12%     
==========================================
  Files           5        5              
  Lines        3367     3401      +34     
  Branches     1121     1138      +17     
==========================================
+ Hits         2654     2685      +31     
+ Misses        276      275       -1     
- Partials      437      441       +4     

☔ View full report in Codecov by Sentry.
📢 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 commented Apr 30, 2026

Copy link
Copy Markdown
Owner

Hmm, there seems to be something broken, as per the fuzzing action report.

I was able to reproduce locally:

  1. Download https://github.com/mity/md4c/actions/runs/25162450101/artifacts/6732195072
  2. Unpack the file timeout-550931c2743b15329ef9dad5d39530dc81a5eaea from it.
  3. Build a debug build from this PR's branch.
  4. Run md2html --github --fspoiler timeout-550931c2743b15329ef9dad5d39530dc81a5eaea

I'm getting an assertion, which I'm unable to reproduce on master branch and/or without the --fspoiler flag.

@mity

mity commented Apr 30, 2026

Copy link
Copy Markdown
Owner

Minimized the testcase into this:

x
|-
||||||||||

Probably some stupid interaction between the table and spoiler parsing but I don't have time now to dig into it.

@hryhoriiK97

hryhoriiK97 commented Apr 30, 2026 •

Copy link
Copy Markdown
Contributor Author

Minimized the testcase into this:

x
|-
||||||||||

Probably some stupid interaction between the table and spoiler parsing but I don't have time now to dig into it.

@mity thanks for the minimized testcase. You were right, this was an interaction between table cell boundary detection and spoiler parsing.

I updated the parser so that table boundary scanning only treats unresolved single | marks as cell boundaries. Double-pipe || marks are ignored during the table boundary pass and are parsed later inside the table cell contents. This also preserves existing wiki-link separators inside tables by skipping already resolved | marks.

I added your minimized case to test/spec-spoiler.txt:

x
|-
||||||||||

@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.

The code looks good to me, there are just few formal details.

Comment thread md2html/md2html.c Outdated
{ 0, "fpermissive-email-autolinks", '@', 0 },
{ 0, "fpermissive-url-autolinks", 'U', 0 },
{ 0, "fpermissive-www-autolinks", '.', 0 },
{ 0, "fspoiler", 'P', 0 },

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.

Please change the option to plural, --fspoilers. Sadly we're not entirely consistent, but the plural dominates.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Sure! Done - 52df1ca

Comment thread src/md4c.h Outdated
#define MD_FLAG_WIKILINKS 0x2000 /* Enable wiki links extension. */
#define MD_FLAG_UNDERLINE 0x4000 /* Enable underline extension (and disables '_' for normal emphasis). */
#define MD_FLAG_HARD_SOFT_BREAKS 0x8000 /* Force all soft breaks to act as hard breaks. */
#define MD_FLAG_SPOILER 0x10000 /* Enable ||hidden text|| spoiler spans. */

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.

Ditto, MD_FLAG_SPOILERS.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Comment thread test/spec-spoiler.txt Outdated

## Interaction with other extensions

### Wiki links (requires MD_FLAG_WIKILINKS)

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.

Put the flag into a code span, `MD_FLAG_WIKILINKS`

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done - 52df1ca

Comment thread test/spec-spoilers.txt
@@ -0,0 +1,419 @@

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.

Also pls rename the file to spec-spoilers.txt.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@hryhoriiK97

hryhoriiK97 commented May 1, 2026 •

Copy link
Copy Markdown
Contributor Author

The code looks good to me, there are just few formal details.

@mity thank you for the review! I've addressed all your comments.

@hryhoriiK97
hryhoriiK97 requested a review from mity May 1, 2026 17:31
@mity
mity merged commit 1e82998 into mity:master May 1, 2026
8 checks passed
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