//#region src/types.d.ts /** * Metadata about the parsed ingredient line. */ interface IngredientMeta { /** * The source text of the ingredient line before parsing. */ sourceText: string; /** * The source index (line number) of the ingredient in the input. * Zero-based index relative to the order of non-empty lines. */ sourceIndex: number; } /** * Ingredient properties. */ interface Ingredient { /** * The primary quantity (the lower quantity in a range, if applicable) */ quantity: number | null; /** * The secondary quantity (the upper quantity in a range, or `null` if not applicable) */ quantity2: number | null; /** * The unit of measure identifier */ unitOfMeasureID: string | null; /** * The unit of measure */ unitOfMeasure: string | null; /** * The description */ description: string; /** * Whether the "ingredient" is actually a group header, e.g. "For icing:" */ isGroupHeader: boolean; /** * Metadata about the parsed ingredient line. * Only included when the `includeMeta` option is `true`. */ meta?: IngredientMeta; } /** * The type of measurement. */ type UnitType = 'volume' | 'mass' | 'length' | 'count' | 'other'; /** * The measurement system. */ type UnitSystem = 'us' | 'imperial' | 'metric'; /** * Conversion factor that differs between measurement systems. */ interface MultiSystemConversionFactor { us?: number; imperial?: number; metric?: number; } /** * Unit of measure properties. */ interface UnitOfMeasure { /** * Abbreviation or short name for the unit. */ short: string; /** * Full name of the unit used when quantity is greater than one. */ plural: string; /** * List of all known alternate spellings, abbreviations, etc. */ alternates: string[]; /** * The type of measurement (volume, mass, length, count, or other). */ type?: UnitType; /** * Conversion factor to base unit (ml for volume, g for mass, mm for length). * A number means the same factor applies to all systems. * An object with `us`, `imperial`, and/or `metric` keys means the factor differs by system. */ conversionFactor?: number | MultiSystemConversionFactor; } type UnitOfMeasureDefinitions = Record; /** * Options available to {@link parseIngredient}. */ interface ParseIngredientOptions { /** * Converts the unit of measure (`unitOfMeasure` property) of each * ingredient to its long, singular form. For example, "ml" becomes * "milliliter" and "cups" becomes "cup". * * @default false */ normalizeUOM?: boolean; /** * An object that matches the format of {@link unitsOfMeasure}. Keys that * match any in {@link unitsOfMeasure} will be used instead of the default, * and any others will be added to the list of known units of measure * when parsing ingredients. * * @default {} */ additionalUOMs?: UnitOfMeasureDefinitions; /** * An array of strings to ignore as units of measure when parsing ingredients. * * @example * * ```ts * parseIngredient('2 small eggs', { * ignoreUOMs: ['small', 'medium', 'large'] * }) * // [ * // { * // quantity: 2, * // quantity2: null, * // unitOfMeasure: null, * // unitOfMeasureID: null, * // description: 'small eggs', * // isGroupHeader: false, * // } * // ] * ``` * * @default [] */ ignoreUOMs?: string[]; /** * If `true`, ingredient descriptions that start with "of " will not be * modified. (By default, a leading "of " will be removed from all descriptions.) * * @default false */ allowLeadingOf?: boolean; /** * The character used as a decimal separator in numeric quantities. * Use `","` for European-style decimal commas (e.g., "1,5" for 1.5). * * @default "." */ decimalSeparator?: '.' | ','; /** * Patterns to identify group headers (e.g., "For the icing:"). * Strings are treated as prefix patterns (matched at the start of the line followed by whitespace). * RegExp patterns are used as-is for more complex matching. * * @default ['For'] * @example ['For', 'Für', /^Pour\s/iu] */ groupHeaderPatterns?: (string | RegExp)[]; /** * Words or patterns to identify ranges between quantities (e.g., "1 to 2", "1 or 2"). * Strings are matched as whole words followed by whitespace. * RegExp patterns are used as-is for more complex matching. * * @default ['to', 'or'] * @example ['to', 'or', 'bis', 'oder', 'à'] */ rangeSeparators?: (string | RegExp)[]; /** * Words or patterns to strip from the beginning of ingredient descriptions. * Commonly used to remove "of" from phrases like "1 cup of sugar". * Strings are matched as whole words followed by whitespace. * RegExp patterns are used as-is for more complex matching (e.g., French elisions). * * @default ['of'] * @example ['of', 'de', /d[eu]?\s/iu, new RegExp("de\\s+l[ae']?\\s*", "iu")] */ descriptionStripPrefixes?: (string | RegExp)[]; /** * Words that indicate a trailing quantity extraction context. * Used to identify patterns like "Juice of 3 lemons" or "Peels from 5 oranges". * * @default ['from', 'of'] * @example ['from', 'of', 'von', 'de'] */ trailingQuantityContext?: string[]; /** * Words or patterns to strip from the beginning of a quantity expression. * Useful for approximation prefixes like "about 2 cups", "ca. 200 g", or * range modifiers like "bis zu 3 EL". * * List longer/more-specific patterns before shorter ones (e.g., `['ca.', 'ca']` * instead of `['ca', 'ca.']`) since regex alternation matches left-to-right. * * @default [] * @example ['about', 'approx.', 'ca.', 'etwa', 'bis zu'] */ leadingQuantityPrefixes?: (string | RegExp)[]; /** * If `true`, include a `meta` property on each ingredient containing * the original text, original index, and other metadata. * * @default false */ includeMeta?: boolean; /** * When `true`, if normal whitespace-based parsing fails to identify a unit * of measure, the parser scans the description for known UOM strings * registered via `additionalUOMs`. Useful for CJK languages where words * are not separated by spaces. * * @default false */ partialUnitMatching?: boolean; } //#endregion //#region src/constants.d.ts /** * Escapes special regex characters in a string. */ declare const escapeRegex: (str: string) => string; /** * Builds a regex that matches any of the given patterns at the start of a string, * followed by whitespace. Strings are escaped and treated as literal prefixes. * RegExp patterns have their source extracted and combined. */ declare const buildPrefixPatternRegex: (patterns: (string | RegExp)[]) => RegExp | null; /** * Builds a regex source string for range separators (dashes and word separators). * Always includes dash characters (-, –, —), plus any custom word separators. */ declare const buildRangeSeparatorSource: (words: (string | RegExp)[]) => string; /** * Builds a regex that matches range separators at the start of a string. */ declare const buildRangeSeparatorRegex: (words: (string | RegExp)[]) => RegExp; /** * Builds a regex that matches any of the given words or patterns at the start of a string. * Strings are matched as whole words followed by whitespace. * RegExp patterns are used as-is for more complex matching (e.g., French elisions). */ declare const buildStripPrefixRegex: (patterns: (string | RegExp)[]) => RegExp | null; /** * Builds a regex that matches approximation/modifier prefixes at the start of * quantity expressions (e.g., "about", "ca.", "bis zu"), followed by optional whitespace. */ declare const buildLeadingQuantityPrefixRegex: (patterns: (string | RegExp)[]) => RegExp | null; /** * Builds a regex that matches any of the given words at the end of a string, * preceded by whitespace. Used for trailing quantity context like "from" or "of". */ declare const buildTrailingContextRegex: (words: string[]) => RegExp; /** * Default group header prefixes (e.g., "For the icing:"). */ declare const defaultGroupHeaderPatterns: readonly ['For']; /** * Default range separator words (e.g., "1 to 2", "1 or 2"). */ declare const defaultRangeSeparators: readonly ['or', 'to']; /** * Default words to strip from the beginning of descriptions. */ declare const defaultDescriptionStripPrefixes: readonly ['of']; /** * Default words that indicate trailing quantity context. */ declare const defaultTrailingQuantityContext: readonly ['from', 'of']; /** * Default words/patterns that are stripped from the beginning of quantity expressions. */ declare const defaultLeadingQuantityPrefixes: readonly []; /** * Default options for {@link parseIngredient}. */ declare const defaultOptions: Required; /** * List of "for" equivalents. * @deprecated Use `defaultGroupHeaderPatterns` instead. */ declare const fors: typeof defaultGroupHeaderPatterns; /** * Regex to capture "for" equivalents. * @deprecated Build dynamically using `buildPrefixPatternRegex(options.groupHeaderPatterns)`. */ declare const forsRegEx: RegExp; /** * List of range separators. * @deprecated Use `defaultRangeSeparators` instead. */ declare const rangeSeparatorWords: typeof defaultRangeSeparators; /** * Regex to capture range separators. * @deprecated Build dynamically using `buildRangeSeparatorRegex(options.rangeSeparators)`. */ declare const rangeSeparatorRegEx: RegExp; /** * Regex to capture the first word of a description to check if it's a unit of measure. */ declare const firstWordRegEx: RegExp; /** * Builds a regex to capture trailing quantity and unit of measure, * using the provided range separator words. */ declare const buildTrailingQuantityRegex: (rangeSeparators: (string | RegExp)[]) => RegExp; /** * Regex to capture trailing quantity and unit of measure. * @deprecated Build dynamically using `buildTrailingQuantityRegex(options.rangeSeparators)`. */ declare const trailingQuantityRegEx: RegExp; /** * List of "of" equivalents. * @deprecated Use `defaultDescriptionStripPrefixes` instead. */ declare const ofs: typeof defaultDescriptionStripPrefixes; /** * Regex to capture "of" equivalents at the beginning of a string. * @deprecated Build dynamically using `buildStripPrefixRegex(options.descriptionStripPrefixes)`. */ declare const ofRegEx: RegExp; /** * List of "from" equivalents. * @deprecated Use `defaultTrailingQuantityContext` instead. */ declare const froms: typeof defaultTrailingQuantityContext; /** * Regex to capture "from" equivalents at the end of a string. * @deprecated Build dynamically using `buildTrailingContextRegex(options.trailingQuantityContext)`. */ declare const fromRegEx: RegExp; /** * Default unit of measure specifications. */ declare const unitsOfMeasure: UnitOfMeasureDefinitions; //#endregion //#region src/convertUnit.d.ts type IdentifyUnitOptions = Pick; /** * Identifies a unit of measure from a string, returning the canonical unit ID. * Matches against the unit ID, short form, plural form, and all alternates. * Case-sensitive matches are tried first (e.g., 'T' = tablespoon, 't' = teaspoon), * then falls back to case-insensitive matching. * * @returns The canonical unit ID (e.g., 'cup'), or `null` if the unit is not recognized * or is in the `ignoreUOMs` list. * * @example * ```ts * identifyUnit('cups') // 'cup' * identifyUnit('c') // 'cup' * identifyUnit('T') // 'tablespoon' * identifyUnit('t') // 'teaspoon' * identifyUnit('tbsp') // 'tablespoon' * identifyUnit('unknown') // null * identifyUnit('large', { ignoreUOMs: ['large'] }) // null * ``` */ declare const identifyUnit: (unit: string, options?: IdentifyUnitOptions) => string | null; /** * Options for {@link convertUnit}. */ interface ConvertUnitOptions { /** * The measurement system to use when units have different US/Imperial conversion factors. * * @default 'us' */ fromSystem?: UnitSystem; /** * The measurement system to use when units have different US/Imperial conversion factors. * * @default 'us' */ toSystem?: UnitSystem; /** * Additional unit definitions to use for conversion. * These are merged with the default {@link unitsOfMeasure}. */ additionalUOMs?: UnitOfMeasureDefinitions; } /** * Converts a value from one unit to another. * * @returns The converted value, or `null` if conversion is not possible * (incompatible types, missing conversion factors, or unknown units). * * @example * ```ts * convertUnit(1, 'cup', 'milliliter') // ~236.588 (US) * convertUnit(1, 'cup', 'milliliter', { fromSystem: 'imperial' }) // ~284.131 * convertUnit(1, 'pound', 'gram') // ~453.592 * convertUnit(1, 'cup', 'gram') // null (incompatible types) * ``` */ declare const convertUnit: (value: number, fromUnit: string, toUnit: string, options?: ConvertUnitOptions) => number | null; //#endregion //#region src/parseIngredient.d.ts /** * Parses a string or array of strings into an array of recipe ingredient objects */ declare const parseIngredient: (ingredientText: string | string[], options?: ParseIngredientOptions) => Ingredient[]; //#endregion export { ConvertUnitOptions, IdentifyUnitOptions, Ingredient, IngredientMeta, MultiSystemConversionFactor, ParseIngredientOptions, UnitOfMeasure, UnitOfMeasureDefinitions, UnitSystem, UnitType, buildLeadingQuantityPrefixRegex, buildPrefixPatternRegex, buildRangeSeparatorRegex, buildRangeSeparatorSource, buildStripPrefixRegex, buildTrailingContextRegex, buildTrailingQuantityRegex, convertUnit, defaultDescriptionStripPrefixes, defaultGroupHeaderPatterns, defaultLeadingQuantityPrefixes, defaultOptions, defaultRangeSeparators, defaultTrailingQuantityContext, escapeRegex, firstWordRegEx, fors, forsRegEx, fromRegEx, froms, identifyUnit, ofRegEx, ofs, parseIngredient, rangeSeparatorRegEx, rangeSeparatorWords, trailingQuantityRegEx, unitsOfMeasure }; //# sourceMappingURL=parse-ingredient.cjs.development.d.ts.map