bidi-js: Unicode Bidirectional Algorithm

1.0.3 · active · verified Tue Apr 21

The `bidi-js` package provides a pure JavaScript implementation of the Unicode Bidirectional Algorithm (UAX #9) version 13.0.0. It aims for correctness, small bundle size, and performance, having passed all Unicode conformance tests. Currently at version 1.0.3, it offers a stable API for calculating embedding levels, reordering segments, and identifying mirrored characters in mixed-direction text. It ships as ES5 compatible and has no external dependencies, making it suitable for both browser and Node.js environments. The library differentiates itself by providing a factory function for module initialization, allowing for flexible deployment, such as within web workers, and ensuring a self-contained module without closure dependencies.

Common errors

Warnings

Install

Imports

Quickstart

Demonstrates installation, factory initialization, and usage of core methods like `getEmbeddingLevels`, `getReorderSegments`, and `getMirroredCharactersMap` with a mixed-direction string to illustrate the Unicode Bidirectional Algorithm.

import bidiFactory from 'bidi-js';

// In a Node.js environment or a browser with ESM support
async function runBidiExample() {
  // 1. Initialize the bidi object by invoking the factory function
  const bidi = bidiFactory();

  // Example text with mixed directions (English and Hebrew)
  const text = "Hello אֲנִי World, this is a test."; // Hebrew for "I"
  const explicitDirection = "ltr"; // Optional, if you want to force base direction

  console.log("Original Text:", text);

  // 2. Calculate bidi embedding levels for each character
  const embeddingLevels = bidi.getEmbeddingLevels(text, explicitDirection);
  const { levels, paragraphs } = embeddingLevels;
  console.log("Embedding Levels (Uint8Array):");
  console.log(levels.join(', '));
  console.log("Paragraphs:", paragraphs);

  // 3. Calculate character reorderings (segments to reverse)
  const flips = bidi.getReorderSegments(text, embeddingLevels);
  console.log("Reorder Flips (ranges [start, end] to reverse):", flips);

  // 4. Apply reordering to get the visual order of characters
  let reorderedTextArray = Array.from(text);
  flips.forEach(range => {
    const [start, end] = range;
    // Reverse the segment in place
    let segment = reorderedTextArray.slice(start, end + 1);
    segment.reverse();
    reorderedTextArray.splice(start, segment.length, ...segment);
  });
  console.log("Reordered Text (visual order):
", reorderedTextArray.join(''));

  // 5. Identify characters that need to be mirrored (e.g., parentheses)
  const mirroredCharactersMap = bidi.getMirroredCharactersMap(text, embeddingLevels);
  console.log("Mirrored Characters Map (index -> replacement):", Array.from(mirroredCharactersMap.entries()));
}

runBidiExample();

view raw JSON →