Skip to content

fix: Swig tag at line start breaks Markdown processing on the same line#5752

Closed
KentarouTakeda wants to merge 2 commits into
hexojs:masterfrom
KentarouTakeda:fix/inline-swig-placeholder
Closed

fix: Swig tag at line start breaks Markdown processing on the same line#5752
KentarouTakeda wants to merge 2 commits into
hexojs:masterfrom
KentarouTakeda:fix/inline-swig-placeholder

Conversation

@KentarouTakeda

Copy link
Copy Markdown
Contributor

What does it do?

Problem

When a Swig/Nunjucks tag appears at the beginning of a line, Markdown syntax on the rest of that line is not processed.

Input:

{% post_link my-post 'My Post' %} and [link](https://example.com)

Expected: link becomes a clickable link.
Actual: [link](https://example.com) is rendered as plain text.

Cause

Hexo replaces Swig tags with HTML comment placeholders (<!--swigN-->) before Markdown rendering. When this placeholder starts a line, it triggers an HTML block (type 2) per the CommonMark spec — the entire line is treated as raw HTML and no Markdown processing occurs (see Example 177).

Fix

A single placeholder format cannot satisfy both requirements:

  • Block-level tags (e.g. {% blockquote %}) need the HTML comment placeholder to trigger HTML block parsing, which prevents the Markdown renderer from wrapping the output in <p> tags.
  • Inline tags with trailing content (e.g. {% post_link %} [link](url)) must not trigger HTML block parsing, or the rest of the line loses Markdown processing.

This PR adds an inline placeholder format (swigN) that uses U+FFFC (Object Replacement Character) as delimiters instead of HTML comments. U+FFFC is already used in the existing block placeholder format and is safe for this purpose — it has no special meaning in HTML or Markdown, does not appear in normal text, and survives Markdown rendering unchanged.

The state machine in escapeAllSwigTags looks ahead after each closing %} / }}: if non-whitespace content follows on the same line, the inline format is used; otherwise the existing block format (<!--swigN-->) is used.

Pull request tasks

  • Add test cases for the changes.
  • Passed the CI test.

@github-actions

github-actions Bot commented Apr 3, 2026

Copy link
Copy Markdown

How to test

git clone -b fix/inline-swig-placeholder https://github.com/KentarouTakeda/hexojs-hexo.git
cd hexo
npm install
npm test

@VibhorGautam VibhorGautam left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I ran the focused post-render tests locally against test/scripts/hexo/post.ts and got 120 passing / 1 pending.

The inline U+FFFC placeholder approach makes sense to me because it avoids the HTML-comment placeholder being parsed as a CommonMark HTML block at the start of a line. The existing comment near hasTrailingContentOnLine helps explain that.

Non-blocking: would it be worth adding one regression test where a full block tag closing is followed by Markdown on the same line, e.g. {% blockquote %}...{% endblockquote %} [link](https://example.com)? Thanks for the thorough test coverage.

@KentarouTakeda KentarouTakeda force-pushed the fix/inline-swig-placeholder branch from 6f57603 to ac29a47 Compare June 13, 2026 13:08
@KentarouTakeda

Copy link
Copy Markdown
Contributor Author

@VibhorGautam Thanks for the review and the suggestion! Adding that regression test actually surfaced a real bug: Markdown right after a block tag's closing on the same line (e.g. {% endblockquote %} [link](...)) wasn't processed, because the full-block-tag escape path didn't pass the inline-placeholder flag (same root cause as the original fix). Fixed in ac29a47, and the new test now passes. 🙏

@KentarouTakeda

Copy link
Copy Markdown
Contributor Author

Superseded by #5785.

I accidentally closed this PR — a force-push during a rebase auto-closed it — and GitHub no longer lets me reopen it (state cannot be changed. The repository may be missing relevant data). I've recreated it as #5785 with the same changes, plus the regression test and fix suggested in the review above. Sorry for the noise, and thanks again @VibhorGautam!

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