···102102void appendApostropheContractionBreaks(const std::vector<CodepointInfo>& cps,
103103 std::vector<Hyphenator::BreakInfo>& outBreaks) {
104104 constexpr size_t kMinLeftSegmentLen = 3;
105105- constexpr size_t kMinRightSegmentLen = 2;
105105+ constexpr size_t kMinRightSegmentLen = 3;
106106 size_t segmentStart = 0;
107107108108 for (size_t i = 0; i < cps.size(); ++i) {
···123123 }
124124 }
125125126126- // Avoid stranding short clitics like "l'"/"d'" or tiny suffixes like "'t".
126126+ // Avoid stranding short clitics like "l'"/"d'" or contraction tails like "'ve"/"'re"/"'ll".
127127 if (leftPrefixLen >= kMinLeftSegmentLen && rightSuffixLen >= kMinRightSegmentLen) {
128128 outBreaks.push_back({cps[i + 1].byteOffset, false});
129129 }
+2-2
lib/Epub/Epub/hyphenation/Hyphenator.h
···2626 // 2. Apostrophe contractions between letters (e.g. all'improvviso).
2727 // Liang patterns are run per alphabetic segment around apostrophes.
2828 // A direct break at the apostrophe boundary is allowed only when the left
2929- // segment has at least 3 letters and the right segment has at least 2 letters,
3030- // avoiding short clitics (e.g. l', d') and short contraction tails (e.g. can't).
2929+ // segment has at least 3 letters and the right segment has at least 3 letters,
3030+ // avoiding short clitics (e.g. l', d') and contraction tails (e.g. 've, 're, 'll).
3131 // 3. Language-specific Liang patterns (e.g. German de_patterns).
3232 // Example: "Quadratkilometer" -> Qua|drat|ki|lo|me|ter.
3333 // 4. Fallback every-N-chars splitting (only when includeFallback is true AND no