Claude
Skills
Sign in
Back

markdownlint-integration

Included with Lifetime
$97 forever

Integrate markdownlint into development workflows including CLI usage, programmatic API, CI/CD pipelines, and editor integration.

Backend & APIs

What this skill does


# Markdownlint Integration

Master integrating markdownlint into development workflows including CLI usage, programmatic API (sync/async/promise), CI/CD pipelines, pre-commit hooks, and editor integration.

## Overview

Markdownlint can be integrated into various parts of your development workflow to ensure consistent markdown quality. This includes command-line tools, programmatic usage in Node.js, continuous integration pipelines, Git hooks, and editor plugins.

## Command-Line Interface

### markdownlint-cli Installation

```bash
npm install -g markdownlint-cli
# or as dev dependency
npm install --save-dev markdownlint-cli
```

### Basic CLI Usage

```bash
# Lint all markdown files in current directory
markdownlint '**/*.md'

# Lint specific files
markdownlint README.md CONTRIBUTING.md

# Lint with configuration file
markdownlint -c .markdownlint.json '**/*.md'

# Ignore specific files
markdownlint '**/*.md' --ignore node_modules

# Fix violations automatically
markdownlint -f '**/*.md'

# Output to file
markdownlint '**/*.md' -o linting-results.txt
```

### Advanced CLI Options

```bash
# Use custom config
markdownlint --config config/markdown-lint.json docs/

# Ignore patterns from file
markdownlint --ignore-path .gitignore '**/*.md'

# Use multiple ignore patterns
markdownlint --ignore node_modules --ignore dist '**/*.md'

# Enable specific rules only
markdownlint --rules MD001,MD003,MD013 '**/*.md'

# Disable specific rules
markdownlint --disable MD013 '**/*.md'

# Show output in JSON format
markdownlint --json '**/*.md'

# Quiet mode (exit code only)
markdownlint -q '**/*.md'

# Verbose output
markdownlint --verbose '**/*.md'
```

### CLI Configuration File

`.markdownlint-cli.json`:

```json
{
  "config": {
    "default": true,
    "MD013": {
      "line_length": 100
    }
  },
  "files": ["**/*.md"],
  "ignores": [
    "node_modules/**",
    "dist/**",
    "build/**"
  ]
}
```

Use with:

```bash
markdownlint --config .markdownlint-cli.json
```

## Programmatic API

### Callback-Based API

```javascript
const markdownlint = require('markdownlint');

const options = {
  files: ['good.md', 'bad.md'],
  config: {
    default: true,
    'line-length': {
      line_length: 100
    }
  }
};

markdownlint(options, (err, result) => {
  if (!err) {
    console.log(result.toString());
  } else {
    console.error(err);
  }
});
```

### Promise-Based API

```javascript
import { lint as lintPromise } from 'markdownlint/promise';

const options = {
  files: ['README.md', 'docs/**/*.md'],
  config: {
    default: true,
    'no-inline-html': {
      allowed_elements: ['br', 'img']
    }
  }
};

try {
  const results = await lintPromise(options);
  console.dir(results, { colors: true, depth: null });
} catch (err) {
  console.error(err);
}
```

### Synchronous API

```javascript
import { lint as lintSync } from 'markdownlint/sync';

const options = {
  files: ['README.md'],
  strings: {
    'inline-content': '# Test\n\nContent here.'
  },
  config: {
    default: true
  }
};

const results = lintSync(options);
console.log(results.toString());
```

### Linting Strings

```javascript
const markdownlint = require('markdownlint');

const options = {
  strings: {
    'content-1': '# Heading\n\nParagraph text.',
    'content-2': '## Another heading\n\nMore content.'
  },
  config: {
    default: true,
    'first-line-heading': {
      level: 1
    }
  }
};

markdownlint(options, (err, result) => {
  if (!err) {
    const resultString = result.toString();
    console.log(resultString);
  }
});
```

### Working with Results

```javascript
import { lint } from 'markdownlint/promise';

const results = await lint({
  files: ['docs/**/*.md'],
  config: { default: true }
});

// Results is an object keyed by filename
Object.keys(results).forEach(file => {
  const fileResults = results[file];

  fileResults.forEach(result => {
    console.log(`${file}:${result.lineNumber} ${result.ruleNames.join('/')} ${result.ruleDescription}`);

    if (result.errorDetail) {
      console.log(`  Detail: ${result.errorDetail}`);
    }

    if (result.errorContext) {
      console.log(`  Context: ${result.errorContext}`);
    }
  });
});
```

### Reading Configuration

```javascript
const markdownlint = require('markdownlint');
const { readConfigSync } = require('markdownlint/sync');

// Read configuration from file
const config = readConfigSync('.markdownlint.json');

const options = {
  files: ['**/*.md'],
  config: config
};

const results = markdownlint.sync(options);
console.log(results.toString());
```

### Using Custom Rules

```javascript
const markdownlint = require('markdownlint');
const customRule = require('./custom-rules/heading-capitalization');

const options = {
  files: ['README.md'],
  config: {
    default: true,
    'heading-capitalization': true
  },
  customRules: [customRule]
};

markdownlint(options, (err, result) => {
  if (!err) {
    console.log(result.toString());
  }
});
```

## Applying Fixes Programmatically

### applyFix Function

```javascript
const { applyFix } = require('markdownlint');

const line = '  Text with extra spaces  ';
const fixInfo = {
  editColumn: 1,
  deleteCount: 2,
  insertText: ''
};

const fixed = applyFix(line, fixInfo);
console.log(fixed); // 'Text with extra spaces  '
```

### applyFixes Function

```javascript
const { applyFixes } = require('markdownlint');

const input = '# Heading\n\n\nParagraph';
const errors = [
  {
    lineNumber: 3,
    ruleNames: ['MD012'],
    ruleDescription: 'Multiple blank lines',
    fixInfo: {
      lineNumber: 3,
      deleteCount: -1
    }
  }
];

const fixed = applyFixes(input, errors);
console.log(fixed); // '# Heading\n\nParagraph'
```

### Auto-Fix Workflow

```javascript
const fs = require('fs');
const markdownlint = require('markdownlint');
const { applyFixes } = require('markdownlint');

const file = 'README.md';
const content = fs.readFileSync(file, 'utf8');

const options = {
  strings: {
    [file]: content
  },
  config: {
    default: true
  }
};

markdownlint(options, (err, result) => {
  if (!err) {
    const errors = result[file] || [];

    if (errors.length > 0) {
      const fixed = applyFixes(content, errors);
      fs.writeFileSync(file, fixed, 'utf8');
      console.log(`Fixed ${errors.length} issues in ${file}`);
    }
  }
});
```

## CI/CD Integration

### GitHub Actions

`.github/workflows/markdownlint.yml`:

```yaml
name: Markdownlint
user-invocable: false

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  lint:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18'

      - name: Install dependencies
        run: npm ci

      - name: Run markdownlint
        run: npx markdownlint '**/*.md' --ignore node_modules

      - name: Annotate PR with results
        if: failure()
        run: |
          npx markdownlint '**/*.md' --ignore node_modules -o markdownlint-results.txt
          cat markdownlint-results.txt
```

### GitHub Actions with markdownlint-cli2

```yaml
name: Markdownlint
user-invocable: false

on: [push, pull_request]

jobs:
  lint:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3

      - name: Run markdownlint-cli2
        uses: DavidAnson/markdownlint-cli2-action@v9
        with:
          paths: '**/*.md'
```

### GitLab CI

`.gitlab-ci.yml`:

```yaml
markdownlint:
  image: node:18-alpine
  stage: test
  before_script:
    - npm install -g markdownlint-cli
  script:
    - markdownlint '**/*.md' --ignore node_modules
  only:
    - merge_requests
    - main
  artifacts:
    when: on_failure
    paths:
      - markdownlint-results.txt
```

### CircleCI

`.circleci/config.yml`:

```yaml
version: 2.1

jobs:
  markdownlint:
    docker:
      - image: cimg/node:18.0
    steps:
      - checkout
      - run:
          name: Install markdownlint
    

Related in Backend & APIs