feat: Implement site-specific recipe parsers for ICA and generic fallback
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* Bas-parser för receptsidor
|
||||
* Alla site-specifika parsers bör extenda denna
|
||||
*/
|
||||
export interface ParsedRecipe {
|
||||
name: string;
|
||||
description?: string;
|
||||
ingredients: Array<{
|
||||
quantity: number;
|
||||
unit: string;
|
||||
name: string;
|
||||
}>;
|
||||
instructions?: string;
|
||||
}
|
||||
|
||||
export abstract class RecipeParser {
|
||||
/**
|
||||
* Kontrollera om denna parser kan hantera denna URL
|
||||
*/
|
||||
abstract canHandle(url: string): boolean;
|
||||
|
||||
/**
|
||||
* Parsa HTML och extrahera receptdata
|
||||
*/
|
||||
abstract parse(html: string): ParsedRecipe;
|
||||
|
||||
/**
|
||||
* Hjälpfunktion: parsa ingrediens-rad
|
||||
*/
|
||||
protected parseIngredientLine(line: string): {
|
||||
quantity: number;
|
||||
unit: string;
|
||||
name: string;
|
||||
} | null {
|
||||
const cleaned = line.replace(/<[^>]+>/g, '').trim();
|
||||
if (!cleaned) return null;
|
||||
|
||||
const match = cleaned.match(/^([\d.,]+)?\s*([a-zåäö]*)\s*(.+)$/i);
|
||||
if (!match) {
|
||||
return {
|
||||
quantity: 0,
|
||||
unit: 'st',
|
||||
name: cleaned,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
quantity: match[1] ? parseFloat(match[1].replace(',', '.')) : 0,
|
||||
unit: (match[2] || 'st').toLowerCase().trim(),
|
||||
name: match[3].trim(),
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user