Chinese learning material often stores pinyin with tone numbers (ni3 hao3) because it is easy to type and to store. Learners, however, need to see tone marks (nǐ hǎo). Converting between the two looks trivial until you meet ü, the neutral tone and the placement rules. Here is a small, dependency-free converter.
Where does the tone mark go?
The rule fits in three lines:
- If the syllable has an a or an e, the mark goes on it.
- If it has ou, the mark goes on the o.
- Otherwise, the mark goes on the last vowel (so
gui4becomesguìandliu2becomesliú).
Two more details: v or u: are common ASCII stand-ins for ü, and tone 5 (or 0) is the neutral tone, which has no mark.
Code
const MARKS = { a: 'āáǎà', e: 'ēéěè', i: 'īíǐì', o: 'ōóǒò', u: 'ūúǔù', ü: 'ǖǘǚǜ' };
function syllable(s) {
const m = s.match(/^([a-zü:v]+)([0-5])$/i);
if (!m) return s;
let [, base, tone] = m;
base = base.replace(/u:|v/g, 'ü');
tone = Number(tone);
if (tone === 0 || tone === 5) return base; // neutral tone
const lower = base.toLowerCase();
let idx;
if (lower.includes('a')) idx = lower.indexOf('a');
else if (lower.includes('e')) idx = lower.indexOf('e');
else if (lower.includes('ou')) idx = lower.indexOf('o');
else {
// last vowel
for (let i = lower.length - 1; i >= 0; i--) if ('iouü'.includes(lower[i])) { idx = i; break; }
}
if (idx === undefined) return base;
const ch = lower[idx];
return base.slice(0, idx) + MARKS[ch][tone - 1] + base.slice(idx + 1);
}
const toMarks = text => text.replace(/[a-zü:v]+[0-5]/gi, syllable);
toMarks('ni3 hao3'); // nǐ hǎo
toMarks('lv4 se4'); // lǜ sè
toMarks('xue2 sheng5'); // xué sheng
toMarks('gui4 liu2 dou1'); // guì liú dōu
What this does not handle
-
Tone sandhi. Pinyin is written with the original tones: two third tones in a row (
nǐ hǎo) are written as 3-3 but spoken as 2-3. Showing the spoken tone is a separate, display-level decision. -
Erhua (
rsuffix) works as long as the number comes after the whole syllable, e.g.huar1. - Capital letters keep working for the first letter, but the vowel lookup is lower-case only.
If you want to see pinyin with tone marks used for teaching, the Vietnamese course for learning Chinese (học tiếng Trung, Vietnamese for "learn Chinese") on Tu Vung 123 shows every word with characters, tone-marked pinyin and a Vietnamese meaning.
Top comments (0)