npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

vietnamese-glyph-generator

v0.1.3

Published

A small TypeScript library to generate Vietnamese glyph placeholders (starter template).

Readme

Vietnamese Glyph Generator

A TypeScript library for generating Vietnamese font glyphs with tone marks, circumflex, breve, horn combinations, and OpenType features.

Features

  • Object-based API - Structured results instead of string concatenation
  • 🚀 High Performance - Optimized batch processing (1,100+ variants/ms)
  • 🎯 Type Safe - Full TypeScript support with comprehensive interfaces
  • 🔧 Flexible Configuration - Customizable accent glyphs and OpenType features
  • 📊 Rich Results - Direct access to variants with input->output mapping

Installation

npm install vietnamese-glyph-generator

Quick Start

import { VietnameseGlyphGenerator } from 'vietnamese-glyph-generator';

const generator = new VietnameseGlyphGenerator();

const options = {
  graveAccentGlyph: 'grave',
  acuteAccentGlyph: 'acute',
  openTypeFeature: 'ss01',
  shouldCreateHorn: true,
  shouldCreateDotlessI: true
};

// Generate glyphs for multiple characters
const result = generator.generateGlyphs('A.ss01/E.ss01/O.ss01', options);

// Access structured results
console.log('Base glyphs:', result.getAllBaseGlyphs());
console.log('A variants:', result.getVariants('A.ss01'));
console.log('Input pattern:', result.getInputPattern('A.ss01', 'Agrave.ss01'));

## API Reference

### Basic Usage

```typescript
// Single character generation
const result = generator.generateGlyphs('A.ss01', options);

// Multiple characters (batch processing)
const result = generator.generateGlyphs('A.ss01/E.ss01/O.ss01/U.ss01', options);

// Legacy string output (for backward compatibility)
const stringResult = generator.generateGlyphsAsString('A.ss01', options);

Configuration Options

const options = {
  // Primary accent glyphs
  graveAccentGlyph: 'grave',           // ` (grave accent)
  acuteAccentGlyph: 'acute',           // ´ (acute accent)  
  tildeGlyph: 'tilde',                 // ~ (tilde)
  hookAboveGlyph: 'hookabovecomb',     // ̉ (hook above)
  dotBelowGlyph: 'dotbelowcomb',       // ̣ (dot below)
  
  // Diacritic combination glyphs
  circumflexGlyph: 'circumflex',       // ^ (circumflex)
  breveGlyph: 'breve',                 // ̆ (breve)
  
  // Horn glyphs for Ơ/Ư characters
  hornGlyphUppercase: 'horn',          // Horn for O, U
  hornGlyphLowercase: 'horn',          // Horn for o, u
  
  // Secondary accents (for combinations like â + `)
  secondaryGraveGlyph: 'grave.secondary',
  secondaryAcuteGlyph: 'acute.secondary',
  secondaryTildeGlyph: 'tilde.secondary', 
  secondaryHookAboveGlyph: 'hookabovecomb.secondary',
  
  // Special characters
  dotlessIGlyph: 'dotlessi',           // Dotless i base
  dStrokeUppercaseGlyph: 'hyphen.case', // Đ stroke
  dStrokeLowercaseGlyph: 'hyphen.case', // đ stroke
  
  // OpenType features
  openTypeFeature: 'ss01',             // Stylistic set
  characterStyle: 'A',                 // Character style context
  
  // Generation flags
  shouldCreateHorn: true,              // Generate horn combinations
  shouldCreateDotlessI: true           // Generate dotless i variants
};

Result Interface

// Main result object
interface GlyphGenerationResult {
  getAllBaseGlyphs(): string[];                    // Get all base glyph names
  getVariants(baseGlyph: string): string[];       // Get variants for a base glyph
  getInputPattern(baseGlyph: string, variant: string): string; // Get input pattern
  toString(): string;                              // Convert to string format
}

// Individual generation result
interface GenerationResult {
  addVariant(output: string, input: string): void; // Add variant mapping
  getVariants(): Map<string, string>;              // Get all variants
  toString(): string;                               // String representation
}

Examples

Vietnamese Tone Marks

// Generate all tone marks for letter A
const result = generator.generateGlyphs('A.ss01', options);

console.log(result.getVariants('A.ss01'));
// Output: ['Agrave.ss01', 'Aacute.ss01', 'Atilde.ss01', 'Ahoi.ss01', 'Adotbelow.ss01', ...]

// Check how a variant is constructed
console.log(result.getInputPattern('A.ss01', 'Agrave.ss01'));
// Output: 'A.ss01+grave'

Circumflex Combinations (Â)

const result = generator.generateGlyphs('A.ss01', options);

// Circumflex + tone marks
console.log('Circumflex variants:');
result.getVariants('A.ss01')
  .filter(v => v.includes('circumflex'))
  .forEach(variant => {
    const input = result.getInputPattern('A.ss01', variant);
    console.log(`${variant} <- ${input}`);
  });

// Output:
// Acircumflex.ss01 <- A.ss01+circumflex
// Acircumflexgrave.ss01 <- A.ss01+circumflex+grave
// Acircumflexacute.ss01 <- A.ss01+circumflex+acute
// Acircumflextilde.ss01 <- A.ss01+circumflex+tilde
// ...

Horn Combinations (Ơ, Ư)

const result = generator.generateGlyphs('O.ss01/U.ss01', {
  ...options,
  shouldCreateHorn: true,
  hornGlyphUppercase: 'horn'
});

// Horn + tone combinations
console.log('Horn variants for O:');
result.getVariants('O.ss01')
  .filter(v => v.includes('horn'))
  .forEach(variant => {
    const input = result.getInputPattern('O.ss01', variant);
    console.log(`${variant} <- ${input}`);
  });

// Output:
// Ohorn.ss01 <- O.ss01+horn
// Ohorngrave.ss01 <- O.ss01+horn+grave
// Ohornacute.ss01 <- O.ss01+horn+acute
// ...

Dotless I Processing

const result = generator.generateGlyphs('i.ss01', {
  ...options,
  shouldCreateDotlessI: true,
  dotlessIGlyph: 'dotlessi'
});

console.log('Dotless i variants:');
result.getVariants('i.ss01').forEach(variant => {
  const input = result.getInputPattern('i.ss01', variant);
  console.log(`${variant} <- ${input}`);
});

// Output:
// igrave.ss01 <- dotlessi.ss01+grave
// iacute.ss01 <- dotlessi.ss01+acute
// itilde.ss01 <- dotlessi.ss01+tilde
// ...

Batch Processing

// Process multiple characters efficiently
const input = 'A.ss01/E.ss01/O.ss01/U.ss01/a.ss01/e.ss01/o.ss01/u.ss01';
const result = generator.generateGlyphs(input, options);

console.log(`Generated ${result.getAllBaseGlyphs().length} base glyphs`);

// Count total variants
let totalVariants = 0;
result.getAllBaseGlyphs().forEach(baseGlyph => {
  totalVariants += result.getVariants(baseGlyph).length;
});

console.log(`Total variants: ${totalVariants}`);
// Output: Total variants: 112+ (depending on configuration)

Legacy String Output

// For backward compatibility with string-based APIs
const stringOutput = generator.generateGlyphsAsString('A.ss01', options);
console.log(stringOutput);

// Output:
// Agrave.ss01=A.ss01+grave
// Aacute.ss01=A.ss01+acute
// Atilde.ss01=A.ss01+tilde
// ...

Special Character Filters

// Generate only dotless i variants
const dotlessI = generator.filterI('i.ss01/i.ss02');
console.log(dotlessI);

// Generate only horn characters
const hornGlyphs = generator.filterHorn('O.ss01/U.ss01/o.ss01/u.ss01', options, true);
console.log(hornGlyphs);

Performance

The library is optimized for high-performance batch processing:

// Performance test
const startTime = Date.now();
const iterations = 1000;

for (let i = 0; i < iterations; i++) {
  generator.generateGlyphs('A.ss01/E.ss01/O.ss01/U.ss01', options);
}

const totalTime = Date.now() - startTime;
console.log(`${(totalTime / iterations).toFixed(2)}ms per iteration`);
// Typical output: ~0.10ms per iteration (1,100+ variants/ms)

Character Support

| Character | Tone Marks | Circumflex | Breve | Horn | Special | |-----------|------------|------------|-------|------|---------| | A, a | ✓ | ✓ | ✓ | ✗ | - | | E, e | ✓ | ✓ | ✗ | ✗ | - | | I, i | ✓ | ✗ | ✗ | ✗ | Dotless | | O, o | ✓ | ✓ | ✗ | ✓ | - | | U, u | ✓ | ✗ | ✗ | ✓ | - | | Y, y | ✓ | ✗ | ✗ | ✗ | - | | D, d | ✗ | ✗ | ✗ | ✗ | Stroke |

Tone Marks: ` (grave), ´ (acute), ~ (tilde), ̉ (hook above), ̣ (dot below)

Migration from String API

If upgrading from a string-based API:

// Old way (string concatenation)
const oldResult = someStringBasedGenerator(input);
const lines = oldResult.split('\n');

// New way (structured object)
const newResult = generator.generateGlyphs(input, options);
const baseGlyph = 'A.ss01';
const variants = newResult.getVariants(baseGlyph);
const inputPattern = newResult.getInputPattern(baseGlyph, 'Agrave.ss01');

Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

MIT License - see LICENSE file for details

TypeScript Support

This library is written in TypeScript and provides full type definitions. No additional @types packages needed!

import { 
  VietnameseGlyphGenerator,
  GlyphOptions,
  GlyphGenerationResult,
  GenerationResult 
} from 'vietnamese-glyph-generator';