The zh pair's other direction, and a rule pack that mostly says no
`pair_lang` had always been answering a second question nobody asked: it says which two languages, and every surface built on it assumed English was the one being learned. That is why hanzi is never tokenized, never spell-checked, never glossed — correct for a Mandarin native practising English, backwards for an English native practising Mandarin. `users.direction` (migration 0016) separates the two questions; a `zh-learner` pair code would have been cheaper and would have made two directions of one pair look like two unrelated languages to every query. Segmentation is what replaces `wordAt` where there are no spaces: a shortest-path walk over log-probabilities, 232 ms and 14 MB for 188,522 words. The browser gets the word list because segmentation runs on hover; the server keeps the whole dictionary. Their coverage gates come out opposite on purpose — the client list is frequency-gated because the segmentation is measurably identical without the tail, and the dictionary is gated by nothing, because its only power is to explain and the word a learner stops on is the rare one. The 错别字 pack is 24 confusable pairs behind two mechanical gates. One admits a pair only if the wrong form is not a dictionary word and the right form is, which is why it refuses 自已 for 自己 — a real error whose wrong form is a headword. The other asks the segmenter whether the two characters already belong to two different words, without which 自己经常, 睡觉的时候 and 不知到底 would all be corrupted silently into text still made of real characters. Not deployed (this carries a migration), not seen in a browser, and no account has ever been in the learner direction. The IME composition guards were in scope and are not done — see BUILD_PLAN Phase 26.
This commit is contained in:
@@ -15,6 +15,17 @@ export const zh: Pack = {
|
||||
nativeName: '中文',
|
||||
locale: 'zh-CN',
|
||||
|
||||
// The zh pair is the only one Petal can be *learned* toward, because it is the
|
||||
// only one with a word list and a Chinese→English dictionary (Phase 26). The
|
||||
// two labels are each written for the person who would pick them: she reads
|
||||
// the first, and the English speaker learning her language reads the second.
|
||||
learner: {
|
||||
label: '我在学 · I am learning',
|
||||
toEn: '英文',
|
||||
toPair: 'Chinese 中文',
|
||||
failed: '没能换成功 · Couldn’t switch — nothing changed',
|
||||
},
|
||||
|
||||
app: {
|
||||
duplicateTitle: (title) => `${title} (副本)`,
|
||||
garden: '词汇花园',
|
||||
|
||||
@@ -39,6 +39,29 @@ export interface Pack {
|
||||
// Portuguese voice anyone reaches for is Brazilian.
|
||||
locale: string
|
||||
|
||||
// Copy for turning this pair around — a writer who is native in English and
|
||||
// learning X, rather than the other way round.
|
||||
//
|
||||
// Optional, and its presence is the pack's half of the same fact
|
||||
// auth.learnerPairs holds server-side: a pair can only be learned toward if
|
||||
// Petal has a word list to segment it with and a dictionary that reads from it
|
||||
// into English. Chinese has both; the Latin pairs have neither yet, so their
|
||||
// packs simply leave this out and the control does not render.
|
||||
//
|
||||
// Each label is written in the language of the person who would *choose* it,
|
||||
// for the same reason the pair buttons name themselves: someone on the wrong
|
||||
// side of this switch cannot read the side they are trying to reach.
|
||||
learner?: {
|
||||
// The heading over the two choices.
|
||||
label: string
|
||||
// "I am practising English" — read by the writer who is native in X.
|
||||
toEn: string
|
||||
// "I am learning X" — read by the writer who is native in English.
|
||||
toPair: string
|
||||
// Shown when the server refuses the change.
|
||||
failed: string
|
||||
}
|
||||
|
||||
app: {
|
||||
// A duplicated document's title. A function, not a suffix: where the marker
|
||||
// goes is the pack's business.
|
||||
|
||||
Reference in New Issue
Block a user