Textlint Utility: AST Paragraph to String with SourceMap

3.3.4 · active · verified Tue Apr 21

textlint-util-to-string is a utility library within the textlint ecosystem designed to convert Text Abstract Syntax Tree (TxtAST) 'Paragraph' nodes into plain text strings. Its primary distinguishing feature is the integrated SourceMap functionality, which allows developers to accurately map positions in the generated plain text back to their corresponding original positions within the AST. This is crucial for tools like textlint and textstat that require precise error reporting and manipulation based on the original source. The current stable version is 3.3.4, and the package demonstrates an active release cadence with frequent patch and minor updates addressing bug fixes and introducing new features, such as the `replacer` option for text transformation during string conversion. This library serves as a foundational component for building advanced text processing and linting tools.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to instantiate `StringSource` with a `TxtParagraphNode`, convert it to plain text, use the `replacer` option to mask specific node types, and retrieve original AST positions from the generated string using source map functionality.

import { StringSource } from "textlint-util-to-string";
import { TxtParagraphNode, TxtCodeNode, TxtTextNode } from "@textlint/ast-node-types";

// Simulate a textlint paragraph node with nested content
const paragraphNode: TxtParagraphNode = {
  type: "Paragraph",
  loc: {
    start: { line: 1, column: 0 },
    end: { line: 1, column: 27 },
  },
  range: [0, 27],
  raw: "This is a `code` example.",
  children: [
    {
      type: "Str",
      value: "This is a ",
      loc: { start: { line: 1, column: 0 }, end: { line: 1, column: 10 } },
      range: [0, 10],
      raw: "This is a ",
    } as TxtTextNode,
    {
      type: "Code",
      value: "code",
      loc: { start: { line: 1, column: 11 }, end: { line: 1, column: 15 } },
      range: [11, 15],
      raw: "`code`",
    } as TxtCodeNode,
    {
      type: "Str",
      value: " example.",
      loc: { start: { line: 1, column: 17 }, end: { line: 1, column: 26 } },
      range: [17, 26],
      raw: " example.",
    } as TxtTextNode,
  ],
};

// 1. Basic conversion to plain text
const source = new StringSource(paragraphNode);
console.log("Plain text:", source.toString());
// Expected output: "Plain text: This is a code example."

// 2. Conversion with a replacer function to mask specific node types
const maskedSource = new StringSource(paragraphNode, {
  replacer: ({ node, maskValue }) => {
    if (node.type === "Code") {
      return maskValue("_"); // Masks "code" to "____"
    }
    return undefined; // No change for other node types
  },
});
console.log("Masked text:", maskedSource.toString());
// Expected output: "Masked text: This is a ____ example."

// 3. Demonstrate source map functionality (mapping back from generated string to original AST index)
const plainText = source.toString();
const codeStartIndexInPlainText = plainText.indexOf("code"); // "code" starts at index 10 in "This is a code example."
if (codeStartIndexInPlainText !== -1) {
    const originalIndex = source.originalIndexFromIndex(codeStartIndexInPlainText);
    console.log(`'code' starts at plain text index ${codeStartIndexInPlainText}, original AST index: ${originalIndex}`);
    // Expected: 'code' starts at plain text index 10, original AST index: 11
}

view raw JSON →