README.md

@cutticat/md-url-map

Rewrite URL destinations in Markdown through a mapper. Relative links stay in git; pack turns them into GitFlic, GitHub, or GitLab URLs for npm. Inline images point at the raw file. Links and reference definitions stay on the blob page.

Table of Contents

Overview

map(markdown, mapper) walks [text](href), images, and reference definitions with micromark and calls mapper for each destination. Return the same string to leave it unchanged. Replacements are written as <url>. Code spans, fences, and the rest of the file stay as they are.

Compose with when(isRelative, toGitFlic({ ... })) so only file-relative hrefs (./a.md, docs/a.md) are rewritten. A link becomes a blob URL. An inline image (![alt](./logo.png)) becomes a raw URL, which npmjs can display. Hash, /rooted, //host, and https: are left alone. Other predicates: isAbsolute, isHash, isRootRelative, isProtocolRelative. toBase({ base }) resolves like a browser: new URL(href, base). The destination type is ignored there.

The md-url-map CLI is the same composition: map for one file (--host or --base), pack for a prepack hook that reads package.json repository and rewrites README.md.

Installation

pnpm i @cutticat/md-url-map

CLI

After install, the md-url-map binary is on PATH via pnpm exec. In this repository, pnpm run md-url-map map ….

map

Rewrite relative destinations in one file. Default: stdout.

Pass --base or --host, not both. --base resolves relative hrefs against a document URL (WHATWG new URL(href, base)). --host writes git blob URLs for links and raw URLs for inline images.

--file is the Markdown path from the git root (inferred from .git when you pass a real path). Required when reading stdin with --host. Unused with --base.

md-url-map map README.md --base https://example.com/docs/README.md
md-url-map map README.md --host gitflic --owner cutticat-npm --project uuids
md-url-map map README.md --host gitflic --owner cutticat-npm --project uuids -i
md-url-map map README.md --host github --owner acme --repo app -o out.md
md-url-map map README.md --host gitlab --project-path group/app --ref v1.0.0
cat README.md | md-url-map map - --file README.md --host gitflic --owner o --project p
Flag Meaning
--base Document URL for relative destinations
--host gitflic, github, or gitlab
--owner GitFlic / GitHub owner
--project GitFlic project slug
--repo GitHub repository name
--project-path GitLab group/project
--ref Git ref (default main)
--file Path of this Markdown file from the git root
--origin Host origin (self-hosted)
-o, --output Write a file instead of stdout
-i, --in-place Overwrite the input file

pack

Read package.json repository in the current directory (or -C), rewrite README.md in place. Infers GitFlic / GitHub / GitLab from the URL. file for URL resolve is the README path from the git root (walks up to .git).

repository.url may be https://, git+https://, ssh://, git+ssh://, git://, or git@host:path. SSH and git:// remotes get an https:// origin. GitFlic HTTPS is /project/{owner}/{project}; the SSH clone git@gitflic.ru:owner/project works too.

An inline image becomes a raw URL on the same origin:

  • GitHub: /{owner}/{repo}/raw/{ref}/{path}
  • GitLab: /{project}/-/raw/{ref}/{path}
  • GitFlic: /project/{owner}/{project}/blob/raw?branch={ref}&file={path}

A link to the same file stays a blob URL. So does a reference definition ([id]: ./logo.png): one definition is shared by links and images.

Use from prepack. Restore the working tree in postpack yourself (git checkout -- README.md). This package does that for its own README.

md-url-map pack
md-url-map pack -C ./packages/plugin --ref main
Flag Meaning
-C, --directory Package directory (default .)
--readme README path relative to the package (default README.md)
--ref Git ref (default main)
--file Override the git-root-relative Markdown path
--origin Override origin from the repository URL
--host Force gitflic, github, or gitlab when the host is unknown
-q, --quiet Do not print the rewritten path

Quick start

import { isRelative, map, toBase, toGitFlic, when } from "@cutticat/md-url-map"

map(
  markdown,
  when(
    isRelative,
    toGitFlic({
      owner: "cutticat-npm",
      project: "uuids",
      ref: "main",
      file: "README.md",
    })
  )
)

map(markdown, when(isRelative, toBase({ base: "https://example.com/docs/README.md" })))
import { map } from "@cutticat/md-url-map"

map("[site](https://old.example)", href =>
  href === "https://old.example" ? "https://new.example" : href
)
// [site](<https://new.example>)

API

  • map(markdown, mapper) — walk destinations, return a new string
  • when(predicate, mapper) — run mapper only when predicate is true
  • isAbsolute(href) — scheme URLs (https:, mailto:)
  • isHash(href) — hash-only (#overview)
  • isProtocolRelative(href) — protocol-relative (//cdn.example/x)
  • isRelative(href) — file-relative destinations (./a.md, docs/a.md)
  • isRootRelative(href) — root-relative (/docs/a.md)
  • toBase({ base }) — new URL(href, base) (document URL)
  • toGitFlic({ owner, project, ref, file, origin? })
  • toGitHub({ owner, repo, ref, file, origin? })
  • toGitLab({ projectPath, ref, file, origin? })
  • HrefType — "image" for ![alt](href), "other" for links and definitions
  • HrefMapper — (href, type) => string
  • HrefPredicate — (href, type) => boolean

file is the Markdown path from the git root (README.md, packages/plugin/README.md).

Replacements use source offsets. Surrounding Markdown is not reformatted.

Documentation

Requirements

  • Node.js >= 22.18.0
  • pnpm >= 10.17.0
  • TypeScript >= 5.9.0
Описание
Map every URL destination in Markdown through a callback
Конвейеры
4 успешных
0 с ошибкой
Разработчики