Sandhi
Tone sandhi is applied to the syllable array rather than to a string, so it can be switched off, works across word boundaries, and cannot be confused by the spelling.
import { applySandhi, readWord } from "@kensio/pinyinjs";
const buShi = readWord("bùshì") ?? [];applySandhi(buShi); // bú shì — 不 flattens before a fourth toneapplySandhi(buShi, { yiBu: false }); // unchanged
const niHao = readWord("nǐhǎo") ?? [];applySandhi(niHao); // unchanged by defaultapplySandhi(niHao, { thirdTone: true }); // ní hǎoThe dictionary stores underlying tones — the source data has sandhi baked in,
and the build normalises it out — which is what makes any of this optional.
A package that stored 不 as bú could never give you bù back.
一 and 不
Section titled “一 and 不”On by default.
不 is bù, and flattens to bú before a fourth tone:
convert(dictionary, "不是"); // "bú shì"convert(dictionary, "不对"); // "bú duì"convert(dictionary, "不行"); // "bùxíng" — 行 is second tone here, so no change一 is yī, and becomes yì before tones 1, 2 and 3, yí before tone 4,
and stays yī in ordinals and in final position:
convert(dictionary, "一天"); // "yì tiān" — before first toneconvert(dictionary, "一起"); // "yìqǐ" — before third toneconvert(dictionary, "一个"); // "yí gè" — before fourth toneconvert(dictionary, "一样"); // "yíyàng"convert(dictionary, "第一"); // "dìyī" — ordinal, unchangedTurn both off with sandhi: { yiBu: false }, or --no-sandhi at the command
line.
Third tone
Section titled “Third tone”Off by default.
A third tone before another third tone is said as a second tone, so 你好 is
spoken ní hǎo. Standard orthography writes the underlying tones anyway, which
is why this is not on:
convert(dictionary, "好好"); // "hǎohǎo"convert(dictionary, "好好", { sandhi: { thirdTone: true } }); // "háohǎo"Turn it on when you are transcribing how something is said — a pronunciation guide, a speech exercise, subtitles for a listening task — and leave it off when you are writing pinyin as text.
const henHao = readWord("hěnhǎo") ?? [];applySandhi(henHao); // hěn hǎoapplySandhi(henHao, { thirdTone: true }); // hén hǎoAcross word boundaries
Section titled “Across word boundaries”Because the pass runs over the syllable array rather than per word, a sandhi trigger works across a boundary the decoder put in. 不 followed by a fourth tone in the next word still flattens.
Options
Section titled “Options”applySandhi(syllables, options?) takes the same object as the sandhi field
of ConvertOptions:
| Field | Default | Does |
|---|---|---|
yiBu |
true |
一 and 不 tone changes |
thirdTone |
false |
third tone before third tone |
It is merged with the defaults, so { thirdTone: true } leaves yiBu on.
What is not implemented
Section titled “What is not implemented”儿化 is handled, but as a dictionary fact rather than as a sandhi rule — see orthography. The half-third-tone allophone (a third tone before a non-third tone, said as a low fall with no rise) is not written, because it has no distinct pinyin spelling to write.
From the command line
Section titled “From the command line”$ pinyinjs sandhi bùshìbùshì bú shì
$ pinyinjs sandhi --third-tone nǐhǎonǐhǎo ní hǎosandhi takes written pinyin and needs no dictionary. The same two flags —
--no-sandhi and --third-tone — also work on convert, html and
explain.
