Skip to content

fix: preserve backtick spans in markdown#1608

Merged
danielroe merged 4 commits intonpmx-dev:mainfrom
vmrjnvc:fix/short-description-text-not-getting-escaped-correctly
Feb 23, 2026
Merged

fix: preserve backtick spans in markdown#1608
danielroe merged 4 commits intonpmx-dev:mainfrom
vmrjnvc:fix/short-description-text-not-getting-escaped-correctly

Conversation

@vmrjnvc
Copy link
Copy Markdown
Contributor

@vmrjnvc vmrjnvc commented Feb 23, 2026

🔗 Linked issue

Resolves #1478

📚 Description

This update fixes an issue with package descriptions containing code snippets wrapped in backticks. Previously, the HTML stripping function removed HTML tags no matter if they were wrapped with backticks. Because of that short description of packages was broken when code snippets with html tags were processed.

@vercel
Copy link
Copy Markdown

vercel bot commented Feb 23, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
npmx.dev Ready Ready Preview, Comment Feb 23, 2026 5:38pm
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
docs.npmx.dev Ignored Ignored Preview Feb 23, 2026 5:38pm
npmx-lunaria Ignored Ignored Feb 23, 2026 5:38pm

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 23, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0160faf and 80aeb7c.

📒 Files selected for processing (1)
  • app/composables/useMarkdown.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/composables/useMarkdown.ts

📝 Walkthrough

Walkthrough

Replaces HTML-stripping regexes in app/composables/useMarkdown.ts so they match either backtick-enclosed code spans or HTML (tags and comments); when a backtick span is matched it is preserved, otherwise HTML tags/comments are removed. Adds a regression test suite test/nuxt/composables/use-markdown.spec.ts verifying HTML inside backtick code spans is preserved/escaped and HTML outside backticks (including comments) is stripped.

Possibly related PRs

Suggested reviewers

  • whitep4nth3r
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description check ✅ Passed The pull request description clearly relates to the changeset, explaining that HTML stripping in markdown now preserves backtick-wrapped code spans to fix broken package descriptions.
Linked Issues check ✅ Passed The PR successfully addresses issue #1478 by modifying HTML stripping logic to preserve backtick-wrapped code spans, preventing HTML tags inside code snippets from being stripped.
Out of Scope Changes check ✅ Passed All changes are directly scoped to the issue: modifications to useMarkdown.ts HTML stripping logic and corresponding regression tests for backtick code span preservation.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
app/composables/useMarkdown.ts (1)

36-41: LGTM — the alternation correctly prioritises backtick spans over HTML tags.

A few confirmatory notes on the implementation:

  • Operator choice: codeSpan ?? '' is the right choice over || — it distinguishes an undefined capture (second branch matched) from a genuine empty code span string, and is semantically precise.
  • Security: backtick-preserved spans still pass through the HTML entity-escaping block (lines 60–64) before output, so <, > etc. inside code spans are correctly escaped to &lt;/&gt;. No XSS surface is introduced.
  • i flag: the flag has no effect on the backtick branch (backtick characters have no case), and correctly makes HTML tag matching case-insensitive for the second branch (<DIV>, <Br/>, etc.).

Optional edge case to be aware of: the backtick pattern `[^`]*` recognises only single-backtick code spans. A double-backtick span such as `` code with <tag> inside `` ` would be parsed as two empty single-backtick spans — the HTML tags in between would still be stripped. This is a pre-existing limitation of the simple inline parser and out of scope for this fix, but worth documenting if double-backtick spans are ever encountered in package descriptions.

📝 Optional: extend the pattern to handle double-backtick spans
-    /(`[^`]*`)|<\/?[a-z][^>]*>/gi,
+    /(``[^`].*?``|`[^`]*`)|<\/?[a-z][^>]*>/gi,

This would match `` … `` spans first (greedy enough to skip embedded single backticks), then fall back to the single-backtick branch.


ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c9e9821 and 06823e5.

📒 Files selected for processing (1)
  • app/composables/useMarkdown.ts

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
test/nuxt/composables/use-markdown.spec.ts (1)

354-398: Consider adding a test for an unclosed backtick span containing an HTML tag.

No test covers the scenario where a backtick is opened but never closed, e.g., 'Use `<div> for layout' (missing closing backtick). Depending on the regex in useMarkdown.ts, the entire trailing content could be swallowed as code rather than having the <div> stripped — a subtle regression surface.

💡 Suggested additional test case
+    it('handles unclosed backtick span with HTML tag gracefully', () => {
+      // No closing backtick — the <div> should still be stripped as bare HTML
+      const processed = useMarkdown({ text: 'Use `<div> for layout' })
+      expect(processed.value).not.toContain('<div>')
+    })

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 06823e5 and af01957.

📒 Files selected for processing (2)
  • app/composables/useMarkdown.ts
  • test/nuxt/composables/use-markdown.spec.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/composables/useMarkdown.ts

@danielroe danielroe enabled auto-merge February 23, 2026 17:36
@danielroe danielroe changed the title fix: enhance HTML stripping in markdown to preserve backtick spans fix: preserve backtick spans in markdown Feb 23, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
app/composables/useMarkdown.ts (1)

38-48: Prefix the unused match parameter with _ in both replace callbacks.

match is never referenced in either callback body. Prefixing it signals intentional non-use and avoids lint warnings.

♻️ Proposed fix
  stripped = stripped.replace(
    /(`[^`]*`)|<\/?[a-z][^>]*>/gi,
-   (match, codeSpan: string | undefined) => codeSpan ?? '',
+   (_match, codeSpan: string | undefined) => codeSpan ?? '',
  )

  // Strip HTML comments: <!-- ... --> (including unclosed comments from truncation)
  stripped = stripped.replace(
    /(`[^`]*`)|<!--[\s\S]*?(-->|$)/g,
-   (match, codeSpan: string | undefined) => codeSpan ?? '',
+   (_match, codeSpan: string | undefined) => codeSpan ?? '',
  )

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between af01957 and 0160faf.

📒 Files selected for processing (1)
  • app/composables/useMarkdown.ts

@danielroe danielroe added this pull request to the merge queue Feb 23, 2026
Merged via the queue into npmx-dev:main with commit 4e6e168 Feb 23, 2026
17 checks passed
@github-actions
Copy link
Copy Markdown

Thanks for your first contribution, @vmrjnvc! 🥳

We'd love to welcome you to the npmx community. Come and say hi on Discord! And once you've joined, visit npmx.wamellow.com to claim the contributor role.

@codecov
Copy link
Copy Markdown

codecov bot commented Feb 23, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

alex-key pushed a commit to alex-key/npmx.dev that referenced this pull request Feb 25, 2026
Co-authored-by: Daniel Roe <daniel@roe.dev>
farisaziz12 pushed a commit to farisaziz12/npmx.dev that referenced this pull request Feb 28, 2026
farisaziz12 pushed a commit to farisaziz12/npmx.dev that referenced this pull request Feb 28, 2026
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.

Short description text not getting escaped correctly

2 participants