48 lines
2.0 KiB
Dart
48 lines
2.0 KiB
Dart
/// Shared English-singularization used to fold plural ingredient and unit
|
|
/// strings onto one canonical token (`eggs` → `egg`, `lbs` → `lb`,
|
|
/// `chicken breasts` → `chicken breast`).
|
|
///
|
|
/// Rules are intentionally conservative and applied identically to both sides
|
|
/// of a comparison (recipe line vs. pantry row), so even imperfect results
|
|
/// still match as long as they are consistent.
|
|
String singularizeWord(String word) {
|
|
if (word.length <= 2) return word;
|
|
// berries → berry.
|
|
if (word.endsWith('ies') && word.length > 4) {
|
|
return '${word.substring(0, word.length - 3)}y';
|
|
}
|
|
// class / glass — never strip a double s.
|
|
if (word.endsWith('ss')) return word;
|
|
// bunches → bunch, boxes → box, buses → bus, tomatoes → tomato.
|
|
if (word.endsWith('ches') ||
|
|
word.endsWith('shes') ||
|
|
word.endsWith('xes') ||
|
|
word.endsWith('zes') ||
|
|
word.endsWith('ses') ||
|
|
word.endsWith('oes')) {
|
|
return word.substring(0, word.length - 2);
|
|
}
|
|
// status / asparagus keep their s.
|
|
if (word.endsWith('us') || word.endsWith('is')) return word;
|
|
// eggs → egg.
|
|
if (word.endsWith('s')) return word.substring(0, word.length - 1);
|
|
return word;
|
|
}
|
|
|
|
/// Canonical, lowercase ingredient key used for fuzzy pantry ↔ recipe
|
|
/// matching (e.g. `Chicken Breast (boneless)` → `chicken breast`).
|
|
///
|
|
/// The pipeline: trim/lowercase → drop parenthetical qualifiers → collapse
|
|
/// punctuation to spaces → singularize each token.
|
|
String canonicalIngredientName(String raw) {
|
|
var text = raw.trim().toLowerCase();
|
|
if (text.isEmpty) return '';
|
|
// Drop parenthetical qualifiers: "chicken breast (boneless)" → "chicken breast".
|
|
text = text.replaceAll(RegExp(r'\([^)]*\)'), ' ');
|
|
// Collapse punctuation so "chicken-breast" and "chicken, breast" still
|
|
// match the plain "chicken breast" pantry key.
|
|
text = text.replaceAll(RegExp(r'[^a-z0-9]+'), ' ');
|
|
text = text.replaceAll(RegExp(r'\s+'), ' ').trim();
|
|
if (text.isEmpty) return '';
|
|
return text.split(' ').map(singularizeWord).join(' ');
|
|
} |