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

pinyin-tone2

v1.2.0

Published

Convert between numbered pinyin and diacritic pinyin, in both directions.

Readme

pinyin-tone2

Convert between numbered pinyin and diacritic pinyin, in both directions.

This package is adapted from the pinyin-tone package by @mrchenguozheng

huar1  ⟺  huār
chu1 yin1 wei4 lai2  ⟺  chū yīn wèi lái

Installation

npm install pinyin-tone2

API

import {
    toPinyinToneNumbers,
    fromPinyinToneNumbers,
    splitUnspacedSyllables,
    convertUnspacedPinyin,
    markSinglePinyinVowel,
} from 'pinyin-tone2';

fromPinyinToneNumbers(input, options?) — numbered → diacritics

Both 0 and 5 are accepted as the neutral tone (no diacritic applied).

fromPinyinToneNumbers('chu1 yin1 wei4 lai2')        // → 'chū yīn wèi lái'
fromPinyinToneNumbers('xun2 yin1 liu2 ge1')         // → 'xún yīn liú gē'
fromPinyinToneNumbers('an1 vn2 ong3 uen4')          // → 'ān ǘn ǒng uèn'
fromPinyinToneNumbers('b p m f')                    // → 'b p m f'
fromPinyinToneNumbers('ma0')                        // → 'ma'  (neutral tone)
fromPinyinToneNumbers('ma5')                        // → 'ma'  (neutral tone)

// Erhua — r-number format (default)
fromPinyinToneNumbers('huar1 renr2 shuir3 yuer4')   // → 'huār rénr shuǐr yuèr'

// Erhua — number-r format
fromPinyinToneNumbers('hua1r ren2r', { erhua: 'number-r' })  // → 'huār rénr'

toPinyinToneNumbers(input, options?) — diacritics → numbered

Neutral-tone syllables (no diacritic marks) have no number suffix by default. Use the neutralToneNumber option to append '0' or '5' instead.

toPinyinToneNumbers('chū yīn wèi lái')          // → 'chu1 yin1 wei4 lai2'
toPinyinToneNumbers('xún yīn liú gē')           // → 'xun2 yin1 liu2 ge1'
toPinyinToneNumbers('ān ǘn ǒng uèn')            // → 'an1 vn2 ong3 uen4'

// Neutral tone — no suffix (default)
toPinyinToneNumbers('nǐ hǎo ma')                // → 'ni3 hao3 ma'

// Neutral tone — append 0
toPinyinToneNumbers('nǐ hǎo ma', { neutralToneNumber: '0' })  // → 'ni3 hao3 ma0'

// Neutral tone — append 5
toPinyinToneNumbers('nǐ hǎo ma', { neutralToneNumber: '5' })  // → 'ni3 hao3 ma5'

// Erhua — r-number output (default)
toPinyinToneNumbers('huār rénr shuǐr yuèr')     // → 'huar1 renr2 shuir3 yuer4'

// Erhua — number-r output
toPinyinToneNumbers('huār rénr', { erhua: 'number-r' })  // → 'hua1r ren2r'

Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | erhua | 'r-number' \| 'number-r' | 'r-number' | Position of the tone digit relative to the erhua r. 'r-number'huar1; 'number-r'hua1r. | | neutralToneNumber | '0' \| '5' \| 'none' | 'none' | Tone number appended to neutral-tone syllables by toPinyinToneNumbers. 'none' omits the suffix entirely. |

splitUnspacedSyllables(text) — insert spaces after tone digits

splitUnspacedSyllables('han4yu3pin1yin1')  // → 'han4 yu3 pin1 yin1'

convertUnspacedPinyin(input) — unspaced numbered → unspaced diacritics

convertUnspacedPinyin('han4yu3pin1yin1')  // → 'hànyǔpīnyīn'
convertUnspacedPinyin('han4 yu3pin1yin1') // → 'hànyǔpīnyīn'

markSinglePinyinVowel(input) — mark a single vowel

Marks a single vowel character (a o e i u v) with a tone number (0–5). Both 0 and 5 are treated as the neutral tone.

markSinglePinyinVowel('a1')  // → 'ā'
markSinglePinyinVowel('v3')  // → 'ǚ'   (v is the ASCII alias for ü)
markSinglePinyinVowel('u4')  // → 'ù'
markSinglePinyinVowel('a5')  // → 'a'   (neutral tone)

Interjection syllables

The rare syllabic-consonant interjections (m̄ ḿ m̌ m̀, n̄ ń ň ǹ, n̄g ńg ňg ǹg, hḿ, hńg) and the standalone vowel ê (ê̄ ế ê̌ ề) round-trip too:

toPinyinToneNumbers('ḿ')    // → 'm2'        (呒 / 嘸)
toPinyinToneNumbers('ǹ')    // → 'n4'        (嗯)
toPinyinToneNumbers('ňg')   // → 'ng3'       (嗯)
toPinyinToneNumbers('ế')    // → 'e^2'       (欸)
toPinyinToneNumbers('ê̄')    // → 'e^1'       (combining-mark form)

fromPinyinToneNumbers('e^2') // → 'ế'
fromPinyinToneNumbers('ng3') // → 'ňg'

e^ is used as the ASCII alias for ê in numbered input/output, mirroring how v is used for ü.

Notes

  • v is used as the ASCII alias for ü in numbered input/output (e.g. vn2ǘn).
  • e^ is used as the ASCII alias for ê (e.g. e^2ế).
  • Combining-diacritic and precomposed forms (ê̄ and ế, and ḿ, etc.) are both accepted as input and normalised via NFC.
  • Both 0 and 5 are accepted as the neutral tone number in all functions.
  • Non-pinyin tokens are passed through unchanged.
  • The package is ESM-only.

License

MIT © Leon Si