Git Product home page Git Product logo

markdownlint-rule-relative-links's Introduction

markdownlint-rule-relative-links

Custom rule for markdownlint to validate relative links.

CONTRIBUTING Licence MIT Contributor Covenant
Lint Test
Conventional Commits semantic-release npm version

๐Ÿ“œ About

markdownlint-rule-relative-links is a markdownlint custom rule to validate relative links.

It ensures that relative links (using file: protocol) are working and exists in the file system of the project that uses markdownlint.

Example

File structure:

โ”œโ”€โ”€ abc.txt
โ””โ”€โ”€ awesome.md

With awesome.md content:

[abc](./abc.txt)

[Invalid link](./invalid.txt)

Running markdownlint-cli2 with markdownlint-rule-relative-links will output:

awesome.md:3 relative-links Relative links should be valid ["./invalid.txt" should exist in the file system]

Additional features

  • Support images (e.g: ![Image](./image.png)).
  • Support links fragments similar to the built-in markdownlint rule - MD051 (e.g: [Link](./awesome.md#heading)).
  • Ignore external links and absolute paths as it only checks relative links (e.g: https://example.com/ or /absolute/path.png).

Limitations

  • Only images and links defined using markdown syntax are validated, html syntax is ignored (e.g: <a href="./link.txt" /> or <img src="./image.png" />).

Contributions are welcome to improve the rule, and to alleviate these limitations. See CONTRIBUTING.md for more information.

Related links

Prerequisites

Node.js >= 16.0.0

Installation

npm install --save-dev markdownlint-rule-relative-links

Configuration

There are various ways markdownlint can be configured using objects, config files etc. For more information on configuration refer to options.config.

We recommend configuring markdownlint-cli2 over markdownlint-cli for compatibility with the vscode-markdownlint extension.

.markdownlint-cli2.jsonc

{
  "config": {
    "default": true,
    "relative-links": true
  },
  "globs": ["**/*.md"],
  "ignores": ["**/node_modules"],
  "customRules": ["markdownlint-rule-relative-links"]
}

package.json

{
  "scripts": {
    "lint:markdown": "markdownlint-cli2"
  }
}

Usage

npm run lint:markdown

๐Ÿ’ก Contributing

Anyone can help to improve the project, submit a Feature Request, a bug report or even correct a simple spelling mistake.

The steps to contribute can be found in the CONTRIBUTING.md file.

๐Ÿ“„ License

MIT

markdownlint-rule-relative-links's People

Contributors

theoludwig avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

Forkers

igor-tsiglyar

markdownlint-rule-relative-links's Issues

[Feature] Support columns numbers in link fragments (e.g: #L30C11-L31C9)

Description

Since the following PR: DavidAnson/markdownlint#1117, the built-in markdownlint rule - MD051 supports links fragments with columns, e.g: [Link](#L30C11-L31C9).

Describe the solution you'd like

At least ignore those links fragments to not consider them as errors.

Or similarly as explained in #6 (comment), we could "do better than ignoring" and verify that the lines range is correct, and columns are correct too, for example #L30C11 means that at the line 30, there should be at least 11 characters (.length of the string greater or equal than 11).

Describe alternatives you've considered

Ignoring the rule with <!-- markdownlint-disable-next-line relative-links --> when necessary (usage of columns numbers in links fragments).

[Improvement] Rewrite in TypeScript

Type of Improvement

Refactoring code

Proposal

Rewrite the code in TypeScript.
The project wasn't started as TypeScript, as markdownlint types was light and often incorrect, but this changed, and greatly improved.
As the types improved, and are now "good", we use TypeScript to lint the JSDOC since this commit: 1ddcdc7.

As we're already using TypeScript, but to lint JavaScript, it makes sense, to instead directly use TypeScript syntax.

[Feature] Add html anchor support

Description

It seems that currently only links to markdown headers are processed, unlike https://github.com/DavidAnson/markdownlint/blob/main/doc/md051.md which also supports links to html anchors.

Describe the solution you'd like

Would be great to have the same processing logic as md051 so that this plugin is usable with anchors.

Describe alternatives you've considered

Current workaround is using https://github.com/tcort/markdown-link-check with the following config:

{
    "ignorePatterns": [
      {
        "pattern": "^#"
      }
    ]
}

This utility also does not work well with anchors so we can ignore all the links to them while links to files are being verified just fine.

[Bug] package cannot be imported when installed with `npm install -g`

I am trying to use markdownlint-cli2 as part of my CI GitHub workflow. To install this package it runs:

npm install -g [email protected]

However when I run the markdownlint-cli2 action it gives me

Run DavidAnson/markdownlint-cli2-action@ed4dec634fd2ef689c7061d5647371d8248064f1
  with:
    globs: markdown-test/index.md
    config: .markdownlint-cli2.jsonc
    separator: ,
markdownlint-cli2 v0.10.0 (markdownlint v0.31.1)
Error: Failed due to error: AggregateError: Unable to require or import module 'markdownlint-rule-relative-links'.

Steps To Reproduce

  1. Add the above command as a step in GitHub workflow
  2. Run the workflow

The current behavior

The markdownlint-cli cannot find the installed package.

The expected behavior

The action should run without error.

[Bug] false error on magnet links

bug: magnet links are treated as relative links

Steps To Reproduce

[some magnet link](magnet:?xt=urn:btih:asdf)

The current behavior

relative-links Relative links should be valid [Link "magnet:?xt=urn:btih:asdf" is dead]

currently, some external protcols are hard-coded

const EXTERNAL_PROTOCOLS = new Set([
  'http:',
  'https:',
  'mailto:',
  'tel:',
  'ftp:'
])
        if (hrefSrc != null) {
          const url = new URL(hrefSrc, pathToFileURL(params.name))
          url.hash = ''
          const isRelative =
            hrefSrc.startsWith('./') ||
            hrefSrc.startsWith('../') ||
            !EXTERNAL_PROTOCOLS.has(url.protocol)
          if (isRelative && !fs.existsSync(url.pathname)) {
            const detail = `Link "${hrefSrc}" is dead`
            addError(onError, lineNumber, detail)
          }
        }

The expected behavior

it should ignore magnet links

more generally, it should ignore all links with protocol except the file: protocol

$ node
> new URL("magnet:?xt=urn:btih:asdf").protocol
'magnet:'
> new URL("file:asdf").protocol
'file:'
> new URL("file:///asdf").protocol
'file:'
> new URL("asdf").protocol
Uncaught TypeError [ERR_INVALID_URL]: Invalid URL
> new URL("./asdf").protocol
Uncaught TypeError [ERR_INVALID_URL]: Invalid URL

[Feature] Stricter validation of heading fragments by being Case sensitive.

Description

Currently, the rule doesn't report an error for the following:

โ”œโ”€โ”€ file1.md
โ””โ”€โ”€ file2.md

With file1.md content:

## Existing Heading

With file2.md content:

[Link](./file1.md#ExistIng-Heading)

Whereas, we should report an error, to enforce consistency with the built-in markdownlint rule - MD051.
More explanations there: DavidAnson/markdownlint#1117 (comment)

Describe the solution you'd like

The rule should reports an error, saying that it's an invalid link fragment, as with the above example, the link should have been: [Link](./file1.md#existing-heading).

There is a test fixture to ensures that we don't consider as errors, the links fragments with mixed casing: https://github.com/theoludwig/markdownlint-rule-relative-links/tree/develop/test/fixtures/valid/existing-heading-case-insensitive, we should instead move it to "invalid", and make the test pass. However, this change should be considered as a BREAKING CHANGE.

Describe alternatives you've considered

Continue to consider heading links fragments valid even if the link fragment is not only in lowercase, with mixed case for example.

[Feature] Optionally validate the link anchor or ignore using line number as anchor

Description

GitHub markdown supports using line length as the anchor, for example:

[file](index.md#L7)

I don't want the linter to throw error on this.

Describe the solution you'd like

I don't know if there is a way to optionally turn on the anchor validation for a specific line, it seems a bit complex to implement.

Instead maybe just hardcode in the plugin to ignore that?

Describe alternatives you've considered

[Feature] Validate anchors

Description

It would be very useful to validate that anchors exist:

some.md:

[Link](other.md#existing)
[Link](other.md#not-existing)

other.md:

# Existing

This would give an error that other.md#not-existing is not a valid link.

This would be useful, because I moved a section from one file to another, and now I don't know what links I've broken. Similarly, I would like to know when renaming a header invalidates a link.

Describe the solution you'd like

A piece of config to specify whether to opt-out of this behavior, with it being on by default.

Describe alternatives you've considered

I considered switching to markdownlint-link-check, but they don't do it either.

The other alternative would be the current behavior, not linting for dead link fragments.

[Improvement] Usage of ESM imports instead of CommonJS

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.