AI refac
LanguagesMarkdown

بِسْمِ ٱللَّهِ ٱلرَّحْمَـٰنِ ٱلرَّحِيمِ

Limits & Gaps

What the Markdown backend does not treat as a link, the boundaries of a move, and the style limits.

  • Wiki-links such as [[Page]]. They are a separate link model that is resolved by note name, as Obsidian does.
  • Imports and expressions in MDX, such as import Logo from './logo.png' and <Image src={logo} />, and JSX props other than href, src, poster, and srcset. Their text is code.
  • Front matter, code, and comments. Links in YAML or TOML front matter (image: ./cover.png), in code blocks and spans, in HTML comments, and inside <pre>, <code>, <script>, <style>, and <textarea> are left alone. Front matter is skipped on purpose. If a site generator reads paths from it, update those by hand.
  • Paths inside other file types, such as the href of an SVG, CSS url(...), HTML files, and JSON or YAML configuration that names a Markdown file. Only Markdown files are rewritten.
  • Routes and templates. Site-root paths (/docs/a.md), routes without an extension (./guide in a docs-site generator), and paths that contain template syntax, a backslash, or an HTML entity are left as they are rather than guessed.

Boundaries of a move

  • Folders with code. A folder with code of a language refac does not move by folder is refused. Move its files one by one with their own backend. TypeScript, JavaScript, and Kotlin have their own folder moves.
  • Ignored files. Files ignored by .gitignore or .ignore files in the project, .git/, and node_modules/ are not searched, so a link in an ignored file is not updated. A file or folder that is itself moved is always read, ignored or not.
  • Go packages. Go moves whole packages, and the other .go files that gopls moves along are not known to the Markdown pass. Markdown links to them are not updated. The response already lists those files.
  • The project path. Links are measured against the project path. A target outside it is fine, but Markdown files outside it are not searched.
  • No cross-language transaction. If the TypeScript batch fails after the Markdown batch has run, the Markdown batch stays done. Each batch is atomic on its own.
  • Preview. --dry-run plans the documents and the links to other languages' files as one set. The real move runs two passes, one for the documents and one for the links to the other languages' files, and the preview counts a link in a moved page to a moved source file once.

Style

  • A link that had to climb out of a folder loses a ./ prefix, and moving it back cannot know the prefix was there. Moving a file out and back restores every byte unless a ./ link was involved. The links lead to the same files either way.
  • refac never normalises a spelling it does not have to change. docs//a.md and x/../a.md stay until their file or target moves.

Parsing model

A CommonMark parser (pulldown-cmark, with GFM tables and footnotes, and YAML and TOML front matter) decides what is a link, an image, or a reference definition, and where it sits. Raw HTML is read by a small scanner that keeps its place across lines and knows comments and raw-text elements. refac itself only reads the destination and replaces those bytes, so any structure it does not expect is an error and not a guess.

It updates destinations. It does not rename link text, headings, or anchors. Renaming a heading together with the #slug links to it is not implemented, and it could inshallah follow later.

How it is tested

The suite covers a documentation-site fixture moved as a file, a rename, a folder, a deeper folder, an image, and a batch, with exact text, an independent link-graph check, and round trips. It also pins 13 common link shapes exactly, covers links to TypeScript, Python, Go, and Dart files and to a TypeScript folder, and covers ignore rules, non-UTF-8 files, line endings, refusals, and rollback. A project of 3,000 files moves one folder in well under a second.

On this page