Skip to content

fix: Swig tag breaks Markdown processing on the same line#5785

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

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

Conversation

@KentarouTakeda

@KentarouTakeda KentarouTakeda commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Note: This PR recreates #5752. I accidentally closed that PR — a force-push during a rebase auto-closed it — and GitHub no longer allows it to be reopened ("the repository may be missing relevant data"), so I'm recreating it here with the same changes. Original review thread: #5752. cc @VibhorGautam — thanks again for the suggestion, which is now included as a fix below.

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.

Additional fix: trailing Markdown after a block tag's closing

Following @VibhorGautam's review suggestion on #5752, I added a regression test for a full block tag whose closing is followed by Markdown on the same line:

{% blockquote %}quote{% endblockquote %} [link](https://example.com)

The test surfaced a real bug: the same-line Markdown was not processed, because the full-block-tag branch in escapeAllSwigTags was the only escape path that didn't pass the inline-placeholder flag — the same root cause as above, on the closing side. Fixed by applying the same hasTrailingContentOnLine look-ahead there. All post.ts tests pass (121 passing / 1 pending).

Pull request tasks

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

@github-actions

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

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.

1 participant