or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-remark-lint-maximum-line-length

remark-lint rule to warn when lines are too long

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/remark-lint-maximum-line-length@4.1.x

To install, run

npx @tessl/cli install tessl/npm-remark-lint-maximum-line-length@4.1.0

index.mddocs/

remark-lint-maximum-line-length

remark-lint-maximum-line-length is a specialized lint rule for the unified/remark ecosystem that validates maximum line length in Markdown documents. It intelligently handles various Markdown constructs by ignoring non-wrappable elements and provides detailed error reporting with precise character counts and removal suggestions.

Package Information

  • Package Name: remark-lint-maximum-line-length
  • Package Type: npm
  • Language: JavaScript (ES Modules)
  • Installation: npm install remark-lint-maximum-line-length
  • Dependencies: pluralize, mdast-util-mdx, unified-lint-rule, unist-util-position, unist-util-visit

Core Imports

import remarkLintMaximumLineLength from 'remark-lint-maximum-line-length';

For use with the unified processor:

import remarkLint from 'remark-lint';
import remarkLintMaximumLineLength from 'remark-lint-maximum-line-length';
import remarkParse from 'remark-parse';
import remarkStringify from 'remark-stringify';
import { unified } from 'unified';

Basic Usage

import remarkLint from 'remark-lint';
import remarkLintMaximumLineLength from 'remark-lint-maximum-line-length';
import remarkParse from 'remark-parse';
import remarkStringify from 'remark-stringify';
import { read } from 'to-vfile';
import { unified } from 'unified';
import { reporter } from 'vfile-reporter';

const file = await read('example.md');

await unified()
  .use(remarkParse)
  .use(remarkLint)
  .use(remarkLintMaximumLineLength) // Default: 60 characters
  .use(remarkStringify)
  .process(file);

console.error(reporter(file));

With custom configuration:

// Configure maximum line length to 120 characters
await unified()
  .use(remarkParse)
  .use(remarkLint)
  .use(remarkLintMaximumLineLength, 120)
  .use(remarkStringify)
  .process(file);

// Configure with options object
await unified()
  .use(remarkParse)
  .use(remarkLint)
  .use(remarkLintMaximumLineLength, {
    size: 100,
    stringLength: (value) => value.length // Custom length calculation
  })
  .use(remarkStringify)
  .process(file);

Architecture

The lint rule follows the unified ecosystem patterns:

  • Lint Rule Integration: Built with unified-lint-rule framework for seamless integration
  • AST Processing: Uses mdast (Markdown Abstract Syntax Tree) for intelligent content analysis
  • Smart Ignoring: Automatically excludes non-wrappable content (code blocks, HTML, headings, tables, definitions, math, MDX)
  • Inline Element Handling: Special logic for inline code, images, and links that span across line boundaries
  • Error Reporting: Leverages unified's VFile messaging system for detailed diagnostics

Capabilities

Line Length Validation

Validates that lines in Markdown documents don't exceed a specified character limit with intelligent content-aware processing.

/**
 * remark-lint rule to warn when lines are too long
 * @param options - Configuration options (number or Options object)
 * @returns Transform function for unified processor
 */
function remarkLintMaximumLineLength(
  options?: Options | number
): Transformer<Root, Root>;

Parameters:

  • options (Options | number, optional): Configuration options (default: 60)

Behavior:

  • Ignores non-wrappable elements: code blocks, HTML, headings, tables, definitions, math expressions, MDX
  • Handles inline elements (code, images, links) that cross line boundaries intelligently
  • Reports violations with exact character counts and removal suggestions
  • Supports custom string length calculation functions

Configuration Options

Configure the maximum line length and string measurement behavior.

/**
 * Configuration options for line length validation
 */
interface Options {
  /**
   * Preferred maximum line length in characters
   * @default 60
   */
  size?: number;
  
  /**
   * Custom function to calculate string length
   * Useful for Unicode handling or visual width calculation
   * @param value - The string to measure
   * @returns The calculated length
   */
  stringLength?: (value: string) => number;
}

Usage Examples:

Simple numeric configuration:

// Set maximum line length to 120 characters  
.use(remarkLintMaximumLineLength, 120)

Options object configuration:

// Advanced configuration with custom string length function
.use(remarkLintMaximumLineLength, {
  size: 100,
  stringLength: (value) => {
    // Example: Use visual width for CJK characters
    return Array.from(value).length;
  }
})

Error Messages

The rule generates detailed error messages for lines that exceed the maximum length.

Error Message Format:

Unexpected `{actualLength}` character line, expected at most `{maxLength}` characters, remove `{difference}` character{s}

Example Output:

1:24: Unexpected `23` character line, expected at most `20` characters, remove `3` characters
4:37: Unexpected `36` character line, expected at most `20` characters, remove `16` characters

Smart Content Handling

The rule intelligently handles different Markdown constructs:

Ignored Elements (Non-wrappable):

  • Code blocks (fenced and indented)
  • HTML elements
  • Headings
  • Tables
  • Definitions/reference links
  • Math expressions (with remark-math)
  • MDX elements: mdxjsEsm, mdxFlowExpression, mdxTextExpression (with remark-mdx)
  • YAML/TOML frontmatter

Special Handling (Inline Elements):

  • Inline code spans
  • Images
  • Links and autolinks

These elements are allowed to exceed the line limit when they:

  1. Start before the maximum column and end after it
  2. Contain no internal whitespace
  3. Don't have following content with break opportunities on the same line

Types

/**
 * Root node type from mdast
 */
interface Root {
  type: 'root';
  children: Array<Content>;
}

/**
 * Transformer function type from unified
 */
type Transformer<In, Out> = (tree: In, file: VFile) => Out | undefined | void;

/**
 * Virtual file type from unified ecosystem
 */
interface VFile {
  // Core VFile properties and methods
  message(reason: string, position?: Position): VFileMessage;
  fail(reason: string, position?: Position): never;
}

/**
 * Position information for error reporting
 */
interface Position {
  line: number;
  column: number;
  offset?: number;
}

Integration Examples

CLI Usage

# Basic usage with remark CLI
remark --frail --use remark-lint --use remark-lint-maximum-line-length .

# With custom configuration in package.json
{
  "remarkConfig": {
    "plugins": [
      "remark-lint",
      ["remark-lint-maximum-line-length", 120]
    ]
  }
}

Programmatic Usage with Configuration

import { unified } from 'unified';
import remarkParse from 'remark-parse';
import remarkLint from 'remark-lint';
import remarkLintMaximumLineLength from 'remark-lint-maximum-line-length';
import { read } from 'to-vfile';
import { reporter } from 'vfile-reporter';

// Process multiple files with different configurations
const files = ['README.md', 'CHANGELOG.md', 'docs/api.md'];

for (const filePath of files) {
  const file = await read(filePath);
  
  const processor = unified()
    .use(remarkParse)
    .use(remarkLint)
    .use(remarkLintMaximumLineLength, {
      size: filePath.includes('CHANGELOG') ? 120 : 60,
      stringLength: (value) => {
        // Custom logic for different file types
        return Array.from(value).length;
      }
    });
    
  await processor.process(file);
  
  if (file.messages.length > 0) {
    console.error(`Issues in ${filePath}:`);
    console.error(reporter(file));
  }
}

Integration with Other remark-lint Rules

import { unified } from 'unified';
import remarkParse from 'remark-parse';
import remarkLint from 'remark-lint';
import remarkLintMaximumLineLength from 'remark-lint-maximum-line-length';
import remarkLintNoHeadingPunctuation from 'remark-lint-no-heading-punctuation';
import remarkLintListItemIndent from 'remark-lint-list-item-indent';

const processor = unified()
  .use(remarkParse)
  .use(remarkLint)
  .use(remarkLintMaximumLineLength, {
    size: 100,
    stringLength: (line) => {
      // Account for tab characters as 4 spaces
      return line.replace(/\t/g, '    ').length;
    }
  })
  .use(remarkLintNoHeadingPunctuation)
  .use(remarkLintListItemIndent, 'space');