Skip to content

fix: convert br html nodes to hardbreak in md preview - #712

Draft
pengfeixx wants to merge 1 commit into
linuxdeepin:masterfrom
pengfeixx:agent/agent/033552a838d1
Draft

pengfeixx wants to merge 1 commit into
linuxdeepin:masterfrom
pengfeixx:agent/agent/033552a838d1

Conversation

@pengfeixx

@pengfeixx pengfeixx commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

Root Cause Analysis

remark-parse parses inline HTML tags like <br> as type: "html" mdast nodes. In Milkdown's read-only preview mode, htmlSchema.toDOM renders html nodes via span.textContent, which outputs the raw tag as literal text instead of a line break. The preview pipeline had no transformation step to convert <br> html nodes into proper break nodes.

Fix Approach

Added a self-implemented remark plugin remarkTransformBrToHardbreak that walks the mdast tree and replaces html nodes matching /^<br\s*\/?>$/i with type: "break" nodes. Break nodes are rendered by Milkdown's hardbreakSchema as <br> HTML elements, producing the expected line break. No third-party remark plugins were introduced. The fix is applied in both main.js (source) and main.bundle.js (committed build artifact).

Change Safety Assessment

Code Safety

  • Risk Level: Low
  • New self-contained plugin function; no existing function signatures modified, no public APIs changed
  • Plugin registered as independent .use() in boot chain, does not alter existing plugin ordering or behavior

Business Impact Scope

Only affects <br> tag rendering in Markdown preview: previously displayed as literal text <br>, now displays as a line break. [[...]] wiki links remain as literal text (out of scope). Standard Markdown syntax (headings, code blocks, tables, bold, links) rendering is unaffected.

Verification Suggestion

  1. Open a Markdown file containing <br> tags and verify they render as line breaks in preview
  2. Test <br/>, <br />, <BR> variants all render as line breaks
  3. Verify <br> text inside code blocks is not converted
  4. Verify standard Markdown syntax renders correctly

根因分析

remark-parse 将内联 HTML 标签(如 <br>)解析为 type: "html" 的 mdast 节点。在 Milkdown 只读预览模式下,htmlSchema.toDOM 通过 span.textContent 渲染 html 节点,将原始标签作为字面文本输出而非换行。预览管线中缺少将 <br> html 节点转换为 break 节点的转换步骤。

修复方案

新增自实现的 remark 插件 remarkTransformBrToHardbreak,遍历 mdast 树,将匹配 /^<br\s*\/?>$/i 的 html 节点替换为 type: "break" 节点。break 节点由 Milkdown 的 hardbreakSchema 渲染为 <br> HTML 元素,实现换行效果。未引入任何第三方 remark 插件。修复同时应用于 main.js(源码)和 main.bundle.js(已提交的构建产物)。

改动安全评估

代码安全评估

  • 风险等级: 低风险
  • 新增自包含插件函数,不修改任何已有函数签名,不改变公开 API
  • 插件作为独立的 .use() 注册在 boot 链中,不改变已有插件的注册顺序或行为

业务影响范围

仅影响 Markdown 预览中 <br> 标签的渲染行为:之前显示为字面文本 <br>,修复后显示为换行。[[...]] wiki 链接保持字面文本显示(不在修复范围)。标准 Markdown 语法(标题、代码块、表格、加粗、链接等)渲染行为不受影响。

验证建议

  1. 打开包含 <br> 标签的 Markdown 文件,确认预览中显示为换行
  2. 测试 <br/>、<br />、<BR> 等变体均正确渲染为换行
  3. 确认代码块内的 <br> 文本不被转换
  4. 确认标准 Markdown 语法渲染正常

Summary by Sourcery

Convert standalone <br> HTML nodes into Markdown hard breaks so previews display line breaks instead of literal tags.

Bug Fixes:

  • Render <br> HTML tags as line breaks in the Markdown read-only preview, including common casing and spacing variants.

Build:

  • Update the committed preview bundle to include the <br> rendering fix.

1. Root cause: remark-parse parses <br> as html nodes, Milkdown's
   htmlSchema.toDOM renders them as literal text via textContent
2. Fix: add remarkTransformBrToHardbreak plugin that converts <br>
   html nodes to mdast break nodes, rendered as <br> elements
3. Impact: <br> tags now display as line breaks in preview; other
   markdown syntax unaffected

Log: fix br tag display as literal text in markdown preview

Influence:
1. Test <br> tag renders as line break in markdown preview
2. Test <br/> and <br /> variants also render as line breaks
3. Verify standard markdown syntax (code, tables, headings) unaffected

fix: md预览中将br标签转换为hardbreak节点

1. 根因:remark-parse将<br>解析为html节点,Milkdown的htmlSchema.toDOM
   通过textContent将其渲染为字面文本而非换行
2. 方案:添加remarkTransformBrToHardbreak插件,将<br>的html节点
   转换为mdast break节点,由hardbreakSchema渲染为<br>元素
3. 影响:<br>标签在预览中显示为换行;其余markdown语法不受影响

Log: 修复markdown预览中br标签显示为字面文本的问题

Influence:
1. 测试<br>标签在markdown预览中渲染为换行
2. 测试<br/>和<br />变体也渲染为换行
3. 验证标准markdown语法(代码、表格、标题)不受影响

PMS: BUG-378211
@sourcery-ai

sourcery-ai Bot commented Nov 3, 2026

Copy link
Copy Markdown

Sorry @pengfeixx, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 1 hour and 53 minutes by commenting @sourcery-ai review. Upgrade to get a review now.

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: pengfeixx

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@pengfeixx
pengfeixx marked this pull request as draft November 3, 2026 02:03
@sourcery-ai

sourcery-ai Bot commented Nov 3, 2026

Copy link
Copy Markdown

Reviewer's Guide

The preview Markdown pipeline now transforms standalone <br> HTML nodes into Milkdown hardbreak nodes, so supported tag variants render as line breaks instead of literal text while code-block content and other Markdown behavior remain unchanged.

Flow diagram for converting br HTML to preview hardbreaks

flowchart LR
    A[Markdown source] --> B[remark-parse]
    B --> C{html node matches br variant}
    C -->|yes| D[remarkTransformBrToHardbreak]
    D --> E[mdast break node]
    E --> F[Milkdown hardbreakSchema]
    F --> G[Rendered line break]
    C -->|no| H[Existing Markdown pipeline]
    H --> I[Existing preview rendering]
Loading

File-Level Changes

Change Details Files
Convert standalone HTML <br> nodes into mdast hardbreak nodes during Markdown parsing.
  • Traverse the mdast tree recursively, including nested containers.
  • Match case-insensitive <br>, <br/>, and <br /> forms and replace matching html nodes with { type: "break" }.
  • Register the custom remark plugin in Milkdown's preview boot chain after code-block trailing-line trimming.
  • Mirror the source change in the committed bundle artifact.
src/editor/markdown/web/main.js
src/editor/markdown/web/build/main.bundle.js

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

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