Skip to content

Conversation

@S-A-Adit
Copy link
Contributor

@S-A-Adit S-A-Adit commented Nov 22, 2025

This PR prevents remark-gfm from auto-linking strings like api\views\project.py, which incorrectly turn into <api\views\project.py> when pasted into Affine.

Key Changes

  • Added a custom unified plugin to detect and convert backslash-containing auto-links into plain text nodes.
  • Ensures Windows file paths are pasted and rendered correctly without unwanted angle brackets or link transformations.

Summary by CodeRabbit

  • Bug Fixes
    • Fixed incorrect autolinking of file paths in Markdown content, ensuring file path references are displayed as plain text rather than clickable links

✏️ Tip: You can customize this high-level summary in your review settings.

Added a custom plugin to disable autolinking of file paths in markdown.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 22, 2025

Walkthrough

A custom plugin is added to the Markdown parser to prevent autolinking of file paths. The plugin detects link nodes where the URL equals the text and contains backslashes, replacing them with plain text nodes. It integrates into the markdown-to-AST processing pipeline before remarkMath and remarkCallout.

Changes

Cohort / File(s) Summary
Markdown parser plugin
blocksuite/affine/shared/src/adapters/markdown/markdown.ts
Added custom plugin to disable autolinking of file paths in Markdown parsing pipeline. Plugin traverses MDAST, identifies backslash-containing links where URL matches text, and converts them to plain text nodes.

Sequence Diagram(s)

sequenceDiagram
    participant Parser as Markdown Parser
    participant Plugin as File Path Plugin
    participant remarkGfm as remark-gfm
    participant remarkMath as remarkMath
    participant AST as Output AST

    Parser->>remarkGfm: Parse markdown
    remarkGfm-->>Parser: Auto-linked nodes
    Parser->>Plugin: Process nodes
    Plugin->>Plugin: Detect file paths<br/>(URL == text, has backslashes)
    Plugin->>Plugin: Replace links with<br/>plain text nodes
    Plugin-->>Parser: Modified nodes
    Parser->>remarkMath: Continue pipeline
    remarkMath-->>Parser: Processed nodes
    Parser->>AST: Final AST
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • Plugin integration point: Verify the plugin is correctly wired into the unified processor pipeline before remarkMath and remarkCallout
  • Node matching logic: Confirm the detection logic (URL === text && contains backslashes) properly identifies file paths without false positives
  • Edge cases: Consider paths with forward slashes, URLs that happen to match text, and potential interactions with other Markdown features

Poem

🐰 A rabbit hops through markdown trails,
Where file paths once wore link's tails,
No more tangles, plain text's best—
Our fuzzy friend has cleaned this nest! 🌿

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Fix: Disable GFM auto-linking for Windows-style file paths' directly and clearly describes the main change - adding a plugin to prevent remark-gfm from auto-linking Windows-style file paths containing backslashes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

📝 Customizable high-level summaries are now available in beta!

You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.

  • Provide your own instructions using the high_level_summary_instructions setting.
  • Format the summary however you like (bullet lists, tables, multi-section layouts, contributor stats, etc.).
  • Use high_level_summary_in_walkthrough to move the summary from the description to the walkthrough section.

Example instruction:

"Divide the high-level summary into five sections:

  1. 📝 Description — Summarize the main change in 50–60 words, explaining what was done.
  2. 📓 References — List relevant issues, discussions, documentation, or related PRs.
  3. 📦 Dependencies & Requirements — Mention any new/updated dependencies, environment variable changes, or configuration updates.
  4. 📊 Contributor Summary — Include a Markdown table showing contributions:
    | Contributor | Lines Added | Lines Removed | Files Changed |
  5. ✔️ Additional Notes — Add any extra reviewer context.
    Keep each section concise (under 200 words) and use bullet or numbered lists for clarity."

Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later.


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
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: 0

🧹 Nitpick comments (1)
blocksuite/affine/shared/src/adapters/markdown/markdown.ts (1)

207-241: Autolink-disabling plugin behavior looks correct; a couple of small robustness nits.

The plugin correctly targets only “bare” links whose url equals the sole text child and contains a backslash, so it shouldn’t affect normal markdown links like [label](C:\foo\bar) or links with formatted contents. The recursive traversal also looks safe and will visit the whole tree.

Two minor, optional improvements:

  • To be slightly more defensive, you could guard children with an array check instead of relying on truthiness, and avoid any for the visitor node to keep typings tight:
const visitor = (node: Root | Parent) => {
  if (!Array.isArray((node as any).children)) return;
  // ...
};

(or import Parent from mdast and use that instead of any).

  • For readability and potential reuse, consider extracting this plugin into a named helper (e.g., remarkDisableWindowsPathAutolinks) alongside the other remark plugins, and .use(remarkDisableWindowsPathAutolinks) here, instead of the inline closure.

These are purely polish; current behavior matches the PR intent.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 1d9fe3b and 6aa2480.

📒 Files selected for processing (1)
  • blocksuite/affine/shared/src/adapters/markdown/markdown.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
blocksuite/affine/shared/src/adapters/markdown/markdown.ts (1)
blocksuite/affine/shared/src/adapters/markdown/type.ts (1)
  • Markdown (8-8)

child.children.length === 1 &&
child.children[0].type === 'text' &&
child.url === child.children[0].value &&
(child.url as string).includes('\\')
Copy link
Member

Choose a reason for hiding this comment

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

prefer typeof child.url === 'string'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

2 participants