Improve Android read aloud TTS handling
This commit is contained in:
1 parent
df90b4c36f
commit
8bb920caf8
11 files changed
+870
-71
No files matched your search
@@ -0,0 +1,181 @@
|
||||
# Russian Hyphenation Rules
|
||||
|
||||
This document defines the rule set for the Russian hyphenation plugin. The
|
||||
implementation should return the original word with soft hyphens inserted at
|
||||
preferred transfer points. Tests may render soft hyphens as `-` for readability.
|
||||
|
||||
The goal is not perfect dictionary hyphenation. The goal is a deterministic,
|
||||
readable rule set that avoids invalid transfers and produces better break points
|
||||
than the current vowel/consonant heuristic.
|
||||
|
||||
## Character Classes
|
||||
|
||||
Use lowercase character checks for classification.
|
||||
|
||||
- Vowels: `а е ё и о у ы э ю я`
|
||||
- Consonants: Russian letters except vowels, `ь`, `ъ`, and `й`
|
||||
- Non-syllabic letters: `ь ъ`
|
||||
- Semivowel: `й`
|
||||
|
||||
Only hyphenate words made of Russian letters. Leave mixed words, words with
|
||||
digits, existing soft hyphens, and abbreviations unchanged. Short words are
|
||||
hyphenated only when they pass the same legal side-length and vowel filters as
|
||||
longer words.
|
||||
|
||||
## Hard Legal Filters
|
||||
|
||||
A candidate break is illegal if any of these is true:
|
||||
|
||||
- Either side would have fewer than 2 letters.
|
||||
- Either side would contain no vowel.
|
||||
- The right side starts with `ь`, `ъ`, `й`, or `ы`.
|
||||
- The left side ends before `ь` or `ъ`; that is, do not split `под-ъезд` or
|
||||
`бол-ьшой`. Prefer `подъ-езд`, `боль-шой`.
|
||||
- The left side ends before `й`; that is, do not split `ма-йор` or `во-йна`.
|
||||
Prefer `май-ор`, `вой-на`.
|
||||
- The break separates a consonant from a following vowel: reject `люб-овь`,
|
||||
`паст-ух`, `реб-ята`. Prefer `лю-бовь`, `па-стух` or `пас-тух`, `ре-бята`
|
||||
or `ребя-та`.
|
||||
|
||||
## Candidate Generation
|
||||
|
||||
Work between adjacent vowel nuclei. For each span from one vowel to the next,
|
||||
choose preferred break candidates from the consonant cluster between them.
|
||||
|
||||
### Adjacent Vowels
|
||||
|
||||
If two vowels are adjacent, allow a break between them when both resulting parts
|
||||
pass the legal filters.
|
||||
|
||||
Examples:
|
||||
|
||||
- `поэт` -> `по-эт`
|
||||
- `академия` -> `ака-де-мия` and not `а-кадемия` or `академи-я`
|
||||
|
||||
### One Consonant Between Vowels
|
||||
|
||||
For `V C V`, break before the consonant.
|
||||
|
||||
Examples:
|
||||
|
||||
- `молоко` -> `мо-ло-ко`
|
||||
- `корова` -> `ко-ро-ва`
|
||||
- `переход` -> `пе-ре-ход`
|
||||
|
||||
### Two Consonants Between Vowels
|
||||
|
||||
For `V C C V`, prefer a break between the consonants.
|
||||
|
||||
Examples:
|
||||
|
||||
- `лампа` -> `лам-па`
|
||||
- `гордый` -> `гор-дый`
|
||||
- `письмо` -> `пись-мо`
|
||||
|
||||
If the cluster contains `й`, `ь`, or `ъ`, keep that letter on the left and break
|
||||
after it when legal.
|
||||
|
||||
Examples:
|
||||
|
||||
- `майор` -> `май-ор`
|
||||
- `подъезд` -> `подъ-езд`
|
||||
- `большой` -> `боль-шой`
|
||||
|
||||
### Three Or More Consonants Between Vowels
|
||||
|
||||
For longer clusters, prefer the latest break that still leaves a pronounceable
|
||||
left part, but keep common inseparable starts on the right:
|
||||
|
||||
- Keep `ст`, `ск`, `сп`, `сн`, `сл`, `см`, `св` together on the right when
|
||||
possible.
|
||||
- Keep stop/liquid pairs together on the right when possible: `бр`, `бл`,
|
||||
`вр`, `вл`, `гр`, `гл`, `др`, `тр`, `кр`, `кл`, `пр`, `пл`, `фр`, `фл`.
|
||||
- Otherwise prefer splitting before the last consonant in the cluster.
|
||||
|
||||
Examples:
|
||||
|
||||
- `сестра` -> `се-стра`
|
||||
- `острый` should not use `о-стрый`, because the left side is too short
|
||||
- `родство` -> `род-ство`
|
||||
- `чувство` -> `чув-ство`
|
||||
- `предложение` -> `пред-ло-же-ние`
|
||||
|
||||
## Double Consonants
|
||||
|
||||
When two identical consonants stand between vowels, prefer splitting between
|
||||
them.
|
||||
|
||||
Examples:
|
||||
|
||||
- `масса` -> `мас-са`
|
||||
- `длинный` -> `длин-ный`
|
||||
- `касса` -> `кас-са`
|
||||
|
||||
Do not force this rule when the double consonant starts a root after a prefix.
|
||||
Without a dictionary, this exception is hard to detect, so implementation may
|
||||
leave such words to the general cluster logic.
|
||||
|
||||
## Prefix-Like Boundaries
|
||||
|
||||
Without a morphology dictionary, treat these as preferred heuristics only.
|
||||
|
||||
If a word starts with a common prefix and the following part is legal, prefer a
|
||||
break after the prefix:
|
||||
|
||||
- `без`, `бес`, `воз`, `вос`, `вз`, `вс`, `из`, `ис`, `низ`, `нис`, `раз`,
|
||||
`рас`, `роз`, `рос`, `от`, `об`, `объ`, `под`, `подъ`, `пред`, `пере`,
|
||||
`при`, `про`, `над`, `сверх`, `меж`
|
||||
|
||||
Examples:
|
||||
|
||||
- `подбить` -> `под-бить`
|
||||
- `размах` -> `раз-мах`
|
||||
- `предложение` -> `пред-ло-же-ние`
|
||||
- `подъезд` -> `подъ-езд`
|
||||
|
||||
Do not create a right side starting with `ы`; prefer later legal breaks.
|
||||
|
||||
Examples:
|
||||
|
||||
- `разыскать` -> `ра-зыскать` or `разыс-кать`, not `раз-ыскать`
|
||||
- `розыгрыш` -> `ро-зыгрыш` or `розыг-рыш`, not `роз-ыгрыш`
|
||||
|
||||
## Ranking
|
||||
|
||||
A word may have several legal break points. The plugin should insert all good
|
||||
breaks, but it should avoid noisy low-quality breaks. Use this ranking:
|
||||
|
||||
1. Prefix boundary, if legal.
|
||||
2. Double consonant split between vowels.
|
||||
3. Syllable breaks from adjacent vowel and consonant-cluster rules.
|
||||
4. Longer-cluster fallback break before the last consonant.
|
||||
|
||||
Reject candidates that are legal but awkward when a better candidate is within
|
||||
one character and both candidates divide the same vowel-to-vowel span.
|
||||
|
||||
## Example Expectations
|
||||
|
||||
These strings use `-` where the implementation will insert `SoftHyphen`.
|
||||
|
||||
```text
|
||||
молоко -> мо-ло-ко
|
||||
корова -> ко-ро-ва
|
||||
яблоко -> яб-ло-ко
|
||||
повествование -> по-вест-во-ва-ние
|
||||
предложение -> пред-ло-же-ние
|
||||
компьютер -> компью-тер
|
||||
подъезд -> подъ-езд
|
||||
большой -> боль-шой
|
||||
майор -> май-ор
|
||||
масса -> мас-са
|
||||
длинный -> длин-ный
|
||||
разыскать -> ра-зыс-кать
|
||||
розыгрыш -> ро-зыг-рыш
|
||||
```
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- Full dictionary-level hyphenation.
|
||||
- Stress-aware syllabification.
|
||||
- Exact morpheme detection for every prefix/root boundary.
|
||||
- Hyphenating proper abbreviations and mixed-script technical identifiers.
|
||||
Reference in new issue
Block a user