You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 4-6.RSVP
Socket
Book a DemoInstallSign in
Socket

parse-ingredient

Package Overview
Dependencies
Maintainers
1
Versions
19
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

parse-ingredient - npm Package Compare versions

Comparing version

to
0.6.0

dist/constants.d.ts

62

dist/index.d.ts

@@ -1,59 +0,3 @@

export 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;
}
export interface UnitOfMeasure {
short: string;
plural: string;
alternates: string[];
}
export declare type UnitOfMeasureDefinitions = Record<string, UnitOfMeasure>;
export 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".
*/
normalizeUOM?: boolean;
/**
* An object that matches the format of `unitsOfMeasure`. Keys that
* match any in `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.
*/
additionalUOMs?: UnitOfMeasureDefinitions;
/**
* If `true`, ingredient descriptions that start with "of " will not be
* modified. (By default, a leading "of " will be removed all descriptions.)
*/
allowLeadingOf?: boolean;
}
export declare const unitsOfMeasure: UnitOfMeasureDefinitions;
/**
* Parses a string into an array of recipe ingredient objects
* @param ingText The ingredient text
* @param options Configuration options
*/
export declare const parseIngredient: (ingText: string, options?: ParseIngredientOptions | undefined) => Ingredient[];
export * from './parseIngredient';
export * from './constants';
export * from './types';

@@ -1,4 +0,169 @@

"use strict";var N=Object.defineProperty;var b=Object.getOwnPropertySymbols;var M=Object.prototype.hasOwnProperty,O=Object.prototype.propertyIsEnumerable;var q=(r,t,s)=>t in r?N(r,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):r[t]=s,p=(r,t)=>{for(var s in t||(t={}))M.call(t,s)&&q(r,s,t[s]);if(b)for(var s of b(t))O.call(t,s)&&q(r,s,t[s]);return r};Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});var v=require("numeric-quantity");function z(r){return r&&typeof r=="object"&&"default"in r?r:{default:r}}var d=z(v);const y={bag:{short:"bag",plural:"bags",alternates:[]},box:{short:"box",plural:"boxes",alternates:[]},bunch:{short:"bunch",plural:"bunches",alternates:[]},can:{short:"can",plural:"cans",alternates:[]},carton:{short:"carton",plural:"cartons",alternates:[]},centimeter:{short:"cm",plural:"centimeters",alternates:["cm."]},clove:{short:"clove",plural:"cloves",alternates:[]},container:{short:"container",plural:"containers",alternates:[]},cup:{short:"c",plural:"cups",alternates:["c.","C"]},dash:{short:"dash",plural:"dashes",alternates:[]},drop:{short:"drop",plural:"drops",alternates:[]},ear:{short:"ear",plural:"ears",alternates:[]},"fluid ounce":{short:"fl oz",plural:"fluid ounces",alternates:["fluidounce","floz","fl-oz","fluid-ounce","fluid-ounces","fluidounces","fl ounce","fl ounces","fl-ounce","fl-ounces","fluid oz","fluid-oz"]},foot:{short:"ft",plural:"feet",alternates:["ft."]},gallon:{short:"gal",plural:"gallons",alternates:["gal."]},gram:{short:"g",plural:"grams",alternates:["g."]},head:{short:"head",plural:"heads",alternates:[]},inch:{short:"in",plural:"inches",alternates:["in."]},kilogram:{short:"kg",plural:"kilograms",alternates:["kg."]},liter:{short:"l",plural:"liters",alternates:[]},meter:{short:"m",plural:"meters",alternates:["m."]},milligram:{short:"mg",plural:"milligrams",alternates:["mg."]},milliliter:{short:"ml",plural:"milliliters",alternates:["mL","ml.","mL."]},millimeter:{short:"mm",plural:"millimeters",alternates:["mm."]},ounce:{short:"oz",plural:"ounces",alternates:["oz."]},pack:{short:"pack",plural:"packs",alternates:[]},package:{short:"pkg",plural:"packages",alternates:["pkg.","pkgs"]},piece:{short:"piece",plural:"pieces",alternates:["pcs","pcs."]},pinch:{short:"pinch",plural:"pinches",alternates:[]},pint:{short:"pt",plural:"pints",alternates:["pt."]},pound:{short:"lb",plural:"pounds",alternates:["lb.","lbs","lbs."]},quart:{short:"qt",plural:"quarts",alternates:["qt.","qts","qts."]},sprig:{short:"sprig",plural:"sprigs",alternates:[]},stick:{short:"stick",plural:"sticks",alternates:[]},tablespoon:{short:"tbsp",plural:"tablespoons",alternates:["tbsp.","T"]},teaspoon:{short:"tsp",plural:"teaspoons",alternates:["tsp.","t"]},yard:{short:"yd",plural:"yards",alternates:["yd.","yds."]}},I=r=>{let t=-1;const s=r.length;let i=0;const h=[];for(;++t<s;){const f=r[t];f&&(h[i++]=f)}return h},R=(r,t)=>{const s=p(p({},y),t==null?void 0:t.additionalUOMs),i=Object.keys(s).map(l=>p({id:l},s[l]));return I(r.replace(/\n{2,}/g,`
`).split(`
`).map(l=>l.trim())).map(l=>{const e={quantity:null,quantity2:null,unitOfMeasureID:null,unitOfMeasure:null,description:"",isGroupHeader:!1},k=d.default(l.substring(0,1));if(isNaN(k))e.description=l,(/:$/.test(e.description)||/^For /i.test(e.description))&&(e.isGroupHeader=!0);else{let a=6,u=NaN;for(;a>0&&isNaN(u);)u=d.default(l.substring(0,a).trim()),u>-1&&(e.quantity=u,e.description=l.substring(a).trim()),a--}const g=/^(-|–|—|to )/i.exec(e.description);if(g){const a=g[1].length,u=d.default(e.description.substring(a).trim().substring(0,1));if(!isNaN(u)){let n=6,o=NaN;for(;n>0&&isNaN(o);)o=d.default(e.description.substring(a,n)),isNaN(o)||(e.quantity2=o,e.description=e.description.substring(n).trim()),n--}}const m=/^(fl(?:uid)?(?:\s+|-)(?:oz|ounces?)|[a-zA-Z.]+)\b(.+)/.exec(e.description);if(m){const a=m[1].replace(/\s+/g," "),u=m[2];let n="",o="",c=0;for(;c<i.length&&!n;)[...i[c].alternates,i[c].id,i[c].short,i[c].plural].includes(a)&&(n=a,o=i[c].id),c++;n&&(e.unitOfMeasureID=o,t!=null&&t.normalizeUOM?e.unitOfMeasure=o:e.unitOfMeasure=n,e.description=u.trim())}return!(t!=null&&t.allowLeadingOf)&&e.description.match(/^of\s+/i)&&(e.description=e.description.replace(/^of\s+/i,"")),e})};exports.parseIngredient=R;exports.unitsOfMeasure=y;
"use strict";
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
const numericQuantity = require("numeric-quantity");
const _interopDefaultLegacy = (e) => e && typeof e === "object" && "default" in e ? e : { default: e };
const numericQuantity__default = /* @__PURE__ */ _interopDefaultLegacy(numericQuantity);
const fors = ["For"];
const forsRegEx = new RegExp(`^(?:${fors.join("|")})\\s`, "i");
const rangeSeparatorWords = ["or", "to"];
const rangeSeparatorRegEx = new RegExp(
`^(-|\u2013|\u2014|(?:${rangeSeparatorWords.join("|")})\\s)`,
"i"
);
const firstWordRegEx = /^(fl(?:uid)?(?:\s+|-)(?:oz|ounces?)|\w+[-.]?)(.+)/;
const ofs = ["of"];
const ofRegEx = new RegExp(`^(?:${ofs.join("|")})\\s+`, "i");
const unitsOfMeasure = {
bag: { short: "bag", plural: "bags", alternates: [] },
box: { short: "box", plural: "boxes", alternates: [] },
bunch: { short: "bunch", plural: "bunches", alternates: [] },
can: { short: "can", plural: "cans", alternates: [] },
carton: { short: "carton", plural: "cartons", alternates: [] },
centimeter: { short: "cm", plural: "centimeters", alternates: ["cm."] },
clove: { short: "clove", plural: "cloves", alternates: [] },
container: { short: "container", plural: "containers", alternates: [] },
cup: { short: "c", plural: "cups", alternates: ["c.", "C"] },
dash: { short: "dash", plural: "dashes", alternates: [] },
drop: { short: "drop", plural: "drops", alternates: [] },
ear: { short: "ear", plural: "ears", alternates: [] },
"fluid ounce": { short: "fl oz", plural: "fluid ounces", alternates: ["fluidounce", "floz", "fl-oz", "fluid-ounce", "fluid-ounces", "fluidounces", "fl ounce", "fl ounces", "fl-ounce", "fl-ounces", "fluid oz", "fluid-oz"] },
foot: { short: "ft", plural: "feet", alternates: ["ft."] },
gallon: { short: "gal", plural: "gallons", alternates: ["gal."] },
gram: { short: "g", plural: "grams", alternates: ["g."] },
head: { short: "head", plural: "heads", alternates: [] },
inch: { short: "in", plural: "inches", alternates: ["in."] },
kilogram: { short: "kg", plural: "kilograms", alternates: ["kg."] },
large: { short: "lg", plural: "large", alternates: ["lg", "lg."] },
liter: { short: "l", plural: "liters", alternates: [] },
medium: { short: "md", plural: "medium", alternates: ["med", "med.", "md."] },
meter: { short: "m", plural: "meters", alternates: ["m."] },
milligram: { short: "mg", plural: "milligrams", alternates: ["mg."] },
milliliter: { short: "ml", plural: "milliliters", alternates: ["mL", "ml.", "mL."] },
millimeter: { short: "mm", plural: "millimeters", alternates: ["mm."] },
ounce: { short: "oz", plural: "ounces", alternates: ["oz."] },
pack: { short: "pack", plural: "packs", alternates: [] },
package: { short: "pkg", plural: "packages", alternates: ["pkg.", "pkgs"] },
piece: { short: "piece", plural: "pieces", alternates: ["pcs", "pcs."] },
pinch: { short: "pinch", plural: "pinches", alternates: [] },
pint: { short: "pt", plural: "pints", alternates: ["pt."] },
pound: { short: "lb", plural: "pounds", alternates: ["lb.", "lbs", "lbs."] },
quart: { short: "qt", plural: "quarts", alternates: ["qt.", "qts", "qts."] },
small: { short: "sm", plural: "small", alternates: ["sm."] },
sprig: { short: "sprig", plural: "sprigs", alternates: [] },
stick: { short: "stick", plural: "sticks", alternates: [] },
tablespoon: { short: "tbsp", plural: "tablespoons", alternates: ["tbsp.", "T", "Tbsp."] },
teaspoon: { short: "tsp", plural: "teaspoons", alternates: ["tsp.", "t"] },
yard: { short: "yd", plural: "yards", alternates: ["yd.", "yds."] }
};
const compactArray = (array) => {
let index = -1;
const length = array.length;
let resIndex = 0;
const result = [];
while (++index < length) {
const value = array[index];
if (value) {
result[resIndex++] = value;
}
}
return result;
};
const parseIngredient = (ingText, options) => {
const mergedUOMs = { ...unitsOfMeasure, ...options == null ? void 0 : options.additionalUOMs };
const uomArray = Object.keys(mergedUOMs).map((uom) => ({ id: uom, ...mergedUOMs[uom] }));
const arrRaw = compactArray(
ingText.replace(/\n{2,}/g, "\n").split("\n").map((ing) => ing.trim())
);
const arrIngs = arrRaw.map((line) => {
const oIng = {
quantity: null,
quantity2: null,
unitOfMeasureID: null,
unitOfMeasure: null,
description: "",
isGroupHeader: false
};
const nqResultFirstChar = numericQuantity__default.default(line.substring(0, 1));
if (isNaN(nqResultFirstChar)) {
oIng.description = line;
if (/:$/.test(oIng.description) || forsRegEx.test(oIng.description)) {
oIng.isGroupHeader = true;
}
} else {
let lenNum = 6;
let nqResult = NaN;
while (lenNum > 0 && isNaN(nqResult)) {
nqResult = numericQuantity__default.default(line.substring(0, lenNum).trim());
if (nqResult > -1) {
oIng.quantity = nqResult;
oIng.description = line.substring(lenNum).trim();
}
lenNum--;
}
}
const q2reMatch = rangeSeparatorRegEx.exec(oIng.description);
if (q2reMatch) {
const q2reMatchLen = q2reMatch[1].length;
const nqResultFirstChar2 = numericQuantity__default.default(
oIng.description.substring(q2reMatchLen).trim().substring(0, 1)
);
if (!isNaN(nqResultFirstChar2)) {
let lenNum = 6;
let nqResult = NaN;
while (lenNum > 0 && isNaN(nqResult)) {
nqResult = numericQuantity__default.default(oIng.description.substring(q2reMatchLen, lenNum));
if (!isNaN(nqResult)) {
oIng.quantity2 = nqResult;
oIng.description = oIng.description.substring(lenNum).trim();
}
lenNum--;
}
}
}
const firstWordREMatches = firstWordRegEx.exec(oIng.description);
if (firstWordREMatches) {
const firstWord = firstWordREMatches[1].replace(/\s+/g, " ");
const remainingDesc = firstWordREMatches[2];
let uom = "";
let uomID = "";
let i = 0;
while (i < uomArray.length && !uom) {
const versions = [
...uomArray[i].alternates,
uomArray[i].id,
uomArray[i].short,
uomArray[i].plural
];
if (versions.includes(firstWord)) {
uom = firstWord;
uomID = uomArray[i].id;
}
i++;
}
if (uom) {
oIng.unitOfMeasureID = uomID;
if (options == null ? void 0 : options.normalizeUOM) {
oIng.unitOfMeasure = uomID;
} else {
oIng.unitOfMeasure = uom;
}
oIng.description = remainingDesc.trim();
}
}
if (!(options == null ? void 0 : options.allowLeadingOf) && oIng.description.match(ofRegEx)) {
oIng.description = oIng.description.replace(ofRegEx, "");
}
return oIng;
});
return arrIngs;
};
exports.firstWordRegEx = firstWordRegEx;
exports.fors = fors;
exports.forsRegEx = forsRegEx;
exports.ofRegEx = ofRegEx;
exports.ofs = ofs;
exports.parseIngredient = parseIngredient;
exports.rangeSeparatorRegEx = rangeSeparatorRegEx;
exports.rangeSeparatorWords = rangeSeparatorWords;
exports.unitsOfMeasure = unitsOfMeasure;
//# sourceMappingURL=parse-ingredient.cjs.js.map

@@ -1,18 +0,12 @@

var __defProp = Object.defineProperty;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
import numericQuantity from "numeric-quantity";
const fors = ["For"];
const forsRegEx = new RegExp(`^(?:${fors.join("|")})\\s`, "i");
const rangeSeparatorWords = ["or", "to"];
const rangeSeparatorRegEx = new RegExp(
`^(-|\u2013|\u2014|(?:${rangeSeparatorWords.join("|")})\\s)`,
"i"
);
const firstWordRegEx = /^(fl(?:uid)?(?:\s+|-)(?:oz|ounces?)|\w+[-.]?)(.+)/;
const ofs = ["of"];
const ofRegEx = new RegExp(`^(?:${ofs.join("|")})\\s+`, "i");
const unitsOfMeasure = {

@@ -38,3 +32,5 @@ bag: { short: "bag", plural: "bags", alternates: [] },

kilogram: { short: "kg", plural: "kilograms", alternates: ["kg."] },
large: { short: "lg", plural: "large", alternates: ["lg", "lg."] },
liter: { short: "l", plural: "liters", alternates: [] },
medium: { short: "md", plural: "medium", alternates: ["med", "med.", "md."] },
meter: { short: "m", plural: "meters", alternates: ["m."] },

@@ -52,5 +48,6 @@ milligram: { short: "mg", plural: "milligrams", alternates: ["mg."] },

quart: { short: "qt", plural: "quarts", alternates: ["qt.", "qts", "qts."] },
small: { short: "sm", plural: "small", alternates: ["sm."] },
sprig: { short: "sprig", plural: "sprigs", alternates: [] },
stick: { short: "stick", plural: "sticks", alternates: [] },
tablespoon: { short: "tbsp", plural: "tablespoons", alternates: ["tbsp.", "T"] },
tablespoon: { short: "tbsp", plural: "tablespoons", alternates: ["tbsp.", "T", "Tbsp."] },
teaspoon: { short: "tsp", plural: "teaspoons", alternates: ["tsp.", "t"] },

@@ -73,7 +70,7 @@ yard: { short: "yd", plural: "yards", alternates: ["yd.", "yds."] }

const parseIngredient = (ingText, options) => {
const mergedUOMs = __spreadValues(__spreadValues({}, unitsOfMeasure), options == null ? void 0 : options.additionalUOMs);
const uomArray = Object.keys(mergedUOMs).map((uom) => __spreadValues({
id: uom
}, mergedUOMs[uom]));
const arrRaw = compactArray(ingText.replace(/\n{2,}/g, "\n").split("\n").map((ing) => ing.trim()));
const mergedUOMs = { ...unitsOfMeasure, ...options == null ? void 0 : options.additionalUOMs };
const uomArray = Object.keys(mergedUOMs).map((uom) => ({ id: uom, ...mergedUOMs[uom] }));
const arrRaw = compactArray(
ingText.replace(/\n{2,}/g, "\n").split("\n").map((ing) => ing.trim())
);
const arrIngs = arrRaw.map((line) => {

@@ -91,3 +88,3 @@ const oIng = {

oIng.description = line;
if (/:$/.test(oIng.description) || /^For /i.test(oIng.description)) {
if (/:$/.test(oIng.description) || forsRegEx.test(oIng.description)) {
oIng.isGroupHeader = true;

@@ -107,7 +104,8 @@ }

}
const q2re = /^(-|–|—|to )/i;
const q2reMatch = q2re.exec(oIng.description);
const q2reMatch = rangeSeparatorRegEx.exec(oIng.description);
if (q2reMatch) {
const q2reMatchLen = q2reMatch[1].length;
const nqResultFirstChar2 = numericQuantity(oIng.description.substring(q2reMatchLen).trim().substring(0, 1));
const nqResultFirstChar2 = numericQuantity(
oIng.description.substring(q2reMatchLen).trim().substring(0, 1)
);
if (!isNaN(nqResultFirstChar2)) {

@@ -126,4 +124,3 @@ let lenNum = 6;

}
const firstWordRE = /^(fl(?:uid)?(?:\s+|-)(?:oz|ounces?)|[a-zA-Z.]+)\b(.+)/;
const firstWordREMatches = firstWordRE.exec(oIng.description);
const firstWordREMatches = firstWordRegEx.exec(oIng.description);
if (firstWordREMatches) {

@@ -158,4 +155,4 @@ const firstWord = firstWordREMatches[1].replace(/\s+/g, " ");

}
if (!(options == null ? void 0 : options.allowLeadingOf) && oIng.description.match(/^of\s+/i)) {
oIng.description = oIng.description.replace(/^of\s+/i, "");
if (!(options == null ? void 0 : options.allowLeadingOf) && oIng.description.match(ofRegEx)) {
oIng.description = oIng.description.replace(ofRegEx, "");
}

@@ -166,3 +163,13 @@ return oIng;

};
export { parseIngredient, unitsOfMeasure };
export {
firstWordRegEx,
fors,
forsRegEx,
ofRegEx,
ofs,
parseIngredient,
rangeSeparatorRegEx,
rangeSeparatorWords,
unitsOfMeasure
};
//# sourceMappingURL=parse-ingredient.es.js.map

@@ -1,4 +0,172 @@

var v=Object.defineProperty;var N=Object.getOwnPropertySymbols;var R=Object.prototype.hasOwnProperty,x=Object.prototype.propertyIsEnumerable;var M=(t,r,s)=>r in t?v(t,r,{enumerable:!0,configurable:!0,writable:!0,value:s}):t[r]=s,m=(t,r)=>{for(var s in r||(r={}))R.call(r,s)&&M(t,s,r[s]);if(N)for(var s of N(r))x.call(r,s)&&M(t,s,r[s]);return t};(function(t,r){typeof exports=="object"&&typeof module!="undefined"?r(exports,require("numeric-quantity")):typeof define=="function"&&define.amd?define(["exports","numeric-quantity"],r):(t=typeof globalThis!="undefined"?globalThis:t||self,r(t.ParseIngredient={},t.numericQuantity))})(this,function(t,r){"use strict";function s(l){return l&&typeof l=="object"&&"default"in l?l:{default:l}}var f=s(r);const y={bag:{short:"bag",plural:"bags",alternates:[]},box:{short:"box",plural:"boxes",alternates:[]},bunch:{short:"bunch",plural:"bunches",alternates:[]},can:{short:"can",plural:"cans",alternates:[]},carton:{short:"carton",plural:"cartons",alternates:[]},centimeter:{short:"cm",plural:"centimeters",alternates:["cm."]},clove:{short:"clove",plural:"cloves",alternates:[]},container:{short:"container",plural:"containers",alternates:[]},cup:{short:"c",plural:"cups",alternates:["c.","C"]},dash:{short:"dash",plural:"dashes",alternates:[]},drop:{short:"drop",plural:"drops",alternates:[]},ear:{short:"ear",plural:"ears",alternates:[]},"fluid ounce":{short:"fl oz",plural:"fluid ounces",alternates:["fluidounce","floz","fl-oz","fluid-ounce","fluid-ounces","fluidounces","fl ounce","fl ounces","fl-ounce","fl-ounces","fluid oz","fluid-oz"]},foot:{short:"ft",plural:"feet",alternates:["ft."]},gallon:{short:"gal",plural:"gallons",alternates:["gal."]},gram:{short:"g",plural:"grams",alternates:["g."]},head:{short:"head",plural:"heads",alternates:[]},inch:{short:"in",plural:"inches",alternates:["in."]},kilogram:{short:"kg",plural:"kilograms",alternates:["kg."]},liter:{short:"l",plural:"liters",alternates:[]},meter:{short:"m",plural:"meters",alternates:["m."]},milligram:{short:"mg",plural:"milligrams",alternates:["mg."]},milliliter:{short:"ml",plural:"milliliters",alternates:["mL","ml.","mL."]},millimeter:{short:"mm",plural:"millimeters",alternates:["mm."]},ounce:{short:"oz",plural:"ounces",alternates:["oz."]},pack:{short:"pack",plural:"packs",alternates:[]},package:{short:"pkg",plural:"packages",alternates:["pkg.","pkgs"]},piece:{short:"piece",plural:"pieces",alternates:["pcs","pcs."]},pinch:{short:"pinch",plural:"pinches",alternates:[]},pint:{short:"pt",plural:"pints",alternates:["pt."]},pound:{short:"lb",plural:"pounds",alternates:["lb.","lbs","lbs."]},quart:{short:"qt",plural:"quarts",alternates:["qt.","qts","qts."]},sprig:{short:"sprig",plural:"sprigs",alternates:[]},stick:{short:"stick",plural:"sticks",alternates:[]},tablespoon:{short:"tbsp",plural:"tablespoons",alternates:["tbsp.","T"]},teaspoon:{short:"tsp",plural:"teaspoons",alternates:["tsp.","t"]},yard:{short:"yd",plural:"yards",alternates:["yd.","yds."]}},O=l=>{let a=-1;const h=l.length;let o=0;const g=[];for(;++a<h;){const b=l[a];b&&(g[o++]=b)}return g},z=(l,a)=>{const h=m(m({},y),a==null?void 0:a.additionalUOMs),o=Object.keys(h).map(i=>m({id:i},h[i]));return O(l.replace(/\n{2,}/g,`
`).split(`
`).map(i=>i.trim())).map(i=>{const e={quantity:null,quantity2:null,unitOfMeasureID:null,unitOfMeasure:null,description:"",isGroupHeader:!1},I=f.default(i.substring(0,1));if(isNaN(I))e.description=i,(/:$/.test(e.description)||/^For /i.test(e.description))&&(e.isGroupHeader=!0);else{let n=6,c=NaN;for(;n>0&&isNaN(c);)c=f.default(i.substring(0,n).trim()),c>-1&&(e.quantity=c,e.description=i.substring(n).trim()),n--}const k=/^(-|–|—|to )/i.exec(e.description);if(k){const n=k[1].length,c=f.default(e.description.substring(n).trim().substring(0,1));if(!isNaN(c)){let u=6,p=NaN;for(;u>0&&isNaN(p);)p=f.default(e.description.substring(n,u)),isNaN(p)||(e.quantity2=p,e.description=e.description.substring(u).trim()),u--}}const q=/^(fl(?:uid)?(?:\s+|-)(?:oz|ounces?)|[a-zA-Z.]+)\b(.+)/.exec(e.description);if(q){const n=q[1].replace(/\s+/g," "),c=q[2];let u="",p="",d=0;for(;d<o.length&&!u;)[...o[d].alternates,o[d].id,o[d].short,o[d].plural].includes(n)&&(u=n,p=o[d].id),d++;u&&(e.unitOfMeasureID=p,a!=null&&a.normalizeUOM?e.unitOfMeasure=p:e.unitOfMeasure=u,e.description=c.trim())}return!(a!=null&&a.allowLeadingOf)&&e.description.match(/^of\s+/i)&&(e.description=e.description.replace(/^of\s+/i,"")),e})};t.parseIngredient=z,t.unitsOfMeasure=y,Object.defineProperties(t,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
(function(global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("numeric-quantity")) : typeof define === "function" && define.amd ? define(["exports", "numeric-quantity"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.ParseIngredient = {}, global.numericQuantity));
})(this, function(exports2, numericQuantity) {
"use strict";
const _interopDefaultLegacy = (e) => e && typeof e === "object" && "default" in e ? e : { default: e };
const numericQuantity__default = /* @__PURE__ */ _interopDefaultLegacy(numericQuantity);
const fors = ["For"];
const forsRegEx = new RegExp(`^(?:${fors.join("|")})\\s`, "i");
const rangeSeparatorWords = ["or", "to"];
const rangeSeparatorRegEx = new RegExp(
`^(-|\u2013|\u2014|(?:${rangeSeparatorWords.join("|")})\\s)`,
"i"
);
const firstWordRegEx = /^(fl(?:uid)?(?:\s+|-)(?:oz|ounces?)|\w+[-.]?)(.+)/;
const ofs = ["of"];
const ofRegEx = new RegExp(`^(?:${ofs.join("|")})\\s+`, "i");
const unitsOfMeasure = {
bag: { short: "bag", plural: "bags", alternates: [] },
box: { short: "box", plural: "boxes", alternates: [] },
bunch: { short: "bunch", plural: "bunches", alternates: [] },
can: { short: "can", plural: "cans", alternates: [] },
carton: { short: "carton", plural: "cartons", alternates: [] },
centimeter: { short: "cm", plural: "centimeters", alternates: ["cm."] },
clove: { short: "clove", plural: "cloves", alternates: [] },
container: { short: "container", plural: "containers", alternates: [] },
cup: { short: "c", plural: "cups", alternates: ["c.", "C"] },
dash: { short: "dash", plural: "dashes", alternates: [] },
drop: { short: "drop", plural: "drops", alternates: [] },
ear: { short: "ear", plural: "ears", alternates: [] },
"fluid ounce": { short: "fl oz", plural: "fluid ounces", alternates: ["fluidounce", "floz", "fl-oz", "fluid-ounce", "fluid-ounces", "fluidounces", "fl ounce", "fl ounces", "fl-ounce", "fl-ounces", "fluid oz", "fluid-oz"] },
foot: { short: "ft", plural: "feet", alternates: ["ft."] },
gallon: { short: "gal", plural: "gallons", alternates: ["gal."] },
gram: { short: "g", plural: "grams", alternates: ["g."] },
head: { short: "head", plural: "heads", alternates: [] },
inch: { short: "in", plural: "inches", alternates: ["in."] },
kilogram: { short: "kg", plural: "kilograms", alternates: ["kg."] },
large: { short: "lg", plural: "large", alternates: ["lg", "lg."] },
liter: { short: "l", plural: "liters", alternates: [] },
medium: { short: "md", plural: "medium", alternates: ["med", "med.", "md."] },
meter: { short: "m", plural: "meters", alternates: ["m."] },
milligram: { short: "mg", plural: "milligrams", alternates: ["mg."] },
milliliter: { short: "ml", plural: "milliliters", alternates: ["mL", "ml.", "mL."] },
millimeter: { short: "mm", plural: "millimeters", alternates: ["mm."] },
ounce: { short: "oz", plural: "ounces", alternates: ["oz."] },
pack: { short: "pack", plural: "packs", alternates: [] },
package: { short: "pkg", plural: "packages", alternates: ["pkg.", "pkgs"] },
piece: { short: "piece", plural: "pieces", alternates: ["pcs", "pcs."] },
pinch: { short: "pinch", plural: "pinches", alternates: [] },
pint: { short: "pt", plural: "pints", alternates: ["pt."] },
pound: { short: "lb", plural: "pounds", alternates: ["lb.", "lbs", "lbs."] },
quart: { short: "qt", plural: "quarts", alternates: ["qt.", "qts", "qts."] },
small: { short: "sm", plural: "small", alternates: ["sm."] },
sprig: { short: "sprig", plural: "sprigs", alternates: [] },
stick: { short: "stick", plural: "sticks", alternates: [] },
tablespoon: { short: "tbsp", plural: "tablespoons", alternates: ["tbsp.", "T", "Tbsp."] },
teaspoon: { short: "tsp", plural: "teaspoons", alternates: ["tsp.", "t"] },
yard: { short: "yd", plural: "yards", alternates: ["yd.", "yds."] }
};
const compactArray = (array) => {
let index = -1;
const length = array.length;
let resIndex = 0;
const result = [];
while (++index < length) {
const value = array[index];
if (value) {
result[resIndex++] = value;
}
}
return result;
};
const parseIngredient = (ingText, options) => {
const mergedUOMs = { ...unitsOfMeasure, ...options == null ? void 0 : options.additionalUOMs };
const uomArray = Object.keys(mergedUOMs).map((uom) => ({ id: uom, ...mergedUOMs[uom] }));
const arrRaw = compactArray(
ingText.replace(/\n{2,}/g, "\n").split("\n").map((ing) => ing.trim())
);
const arrIngs = arrRaw.map((line) => {
const oIng = {
quantity: null,
quantity2: null,
unitOfMeasureID: null,
unitOfMeasure: null,
description: "",
isGroupHeader: false
};
const nqResultFirstChar = numericQuantity__default.default(line.substring(0, 1));
if (isNaN(nqResultFirstChar)) {
oIng.description = line;
if (/:$/.test(oIng.description) || forsRegEx.test(oIng.description)) {
oIng.isGroupHeader = true;
}
} else {
let lenNum = 6;
let nqResult = NaN;
while (lenNum > 0 && isNaN(nqResult)) {
nqResult = numericQuantity__default.default(line.substring(0, lenNum).trim());
if (nqResult > -1) {
oIng.quantity = nqResult;
oIng.description = line.substring(lenNum).trim();
}
lenNum--;
}
}
const q2reMatch = rangeSeparatorRegEx.exec(oIng.description);
if (q2reMatch) {
const q2reMatchLen = q2reMatch[1].length;
const nqResultFirstChar2 = numericQuantity__default.default(
oIng.description.substring(q2reMatchLen).trim().substring(0, 1)
);
if (!isNaN(nqResultFirstChar2)) {
let lenNum = 6;
let nqResult = NaN;
while (lenNum > 0 && isNaN(nqResult)) {
nqResult = numericQuantity__default.default(oIng.description.substring(q2reMatchLen, lenNum));
if (!isNaN(nqResult)) {
oIng.quantity2 = nqResult;
oIng.description = oIng.description.substring(lenNum).trim();
}
lenNum--;
}
}
}
const firstWordREMatches = firstWordRegEx.exec(oIng.description);
if (firstWordREMatches) {
const firstWord = firstWordREMatches[1].replace(/\s+/g, " ");
const remainingDesc = firstWordREMatches[2];
let uom = "";
let uomID = "";
let i = 0;
while (i < uomArray.length && !uom) {
const versions = [
...uomArray[i].alternates,
uomArray[i].id,
uomArray[i].short,
uomArray[i].plural
];
if (versions.includes(firstWord)) {
uom = firstWord;
uomID = uomArray[i].id;
}
i++;
}
if (uom) {
oIng.unitOfMeasureID = uomID;
if (options == null ? void 0 : options.normalizeUOM) {
oIng.unitOfMeasure = uomID;
} else {
oIng.unitOfMeasure = uom;
}
oIng.description = remainingDesc.trim();
}
}
if (!(options == null ? void 0 : options.allowLeadingOf) && oIng.description.match(ofRegEx)) {
oIng.description = oIng.description.replace(ofRegEx, "");
}
return oIng;
});
return arrIngs;
};
exports2.firstWordRegEx = firstWordRegEx;
exports2.fors = fors;
exports2.forsRegEx = forsRegEx;
exports2.ofRegEx = ofRegEx;
exports2.ofs = ofs;
exports2.parseIngredient = parseIngredient;
exports2.rangeSeparatorRegEx = rangeSeparatorRegEx;
exports2.rangeSeparatorWords = rangeSeparatorWords;
exports2.unitsOfMeasure = unitsOfMeasure;
Object.defineProperties(exports2, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
});
//# sourceMappingURL=parse-ingredient.umd.js.map
{
"name": "parse-ingredient",
"author": "Jake Boone",
"version": "0.5.0",
"version": "0.6.0",
"license": "MIT",

@@ -36,2 +36,3 @@ "description": "Recipe ingredient parser with support for mixed numbers and vulgar fractions",

"test": "jest --coverage",
"pretty-print": "prettier --write src",
"publish:npm": "np",

@@ -42,16 +43,17 @@ "publish:demo": "node gh-pages.publish.js",

"devDependencies": {
"@babel/core": "^7.17.8",
"@babel/preset-env": "^7.16.11",
"@babel/preset-typescript": "^7.16.7",
"@types/jest": "^27.4.1",
"gh-pages": "^3.1.0",
"jest": "^27.5.1",
"np": "^7.3.0",
"prettier": "^2.6.0",
"typescript": "^4.1.5",
"vite": "^2.8.6"
"@babel/core": "^7.19.3",
"@babel/preset-env": "^7.19.4",
"@babel/preset-typescript": "^7.18.6",
"@types/jest": "^29.1.2",
"gh-pages": "^4.0.0",
"jest": "^29.2.0",
"np": "^7.6.2",
"prettier": "^2.7.1",
"typescript": "^4.8.4",
"vite": "^3.1.8"
},
"dependencies": {
"numeric-quantity": "^1.0.2"
}
"numeric-quantity": "^1.0.4"
},
"packageManager": "yarn@3.2.3"
}

@@ -42,3 +42,3 @@ # parse-ingredient

This library pairs nicely with [format-quantity](https://www.npmjs.com/package/format-quantity) which can display numeric values as imperial measurements (e.g. `'1 1/2'` instead of `1.5`).
For a complimentary library that handles the inverse operation, displaying numeric values as imperial measurements (e.g. `'1 1/2'` instead of `1.5`), see [format-quantity](https://www.npmjs.com/package/format-quantity).

@@ -65,3 +65,3 @@ If present (i.e. not `null`), the `unitOfMeasureID` property corresponds to a key from the exported `unitsOfMeasure` object which defines short, plural, and other alternate versions of known units of measure. To extend the list of units, use the [`additionalUOMs` option](#additionaluoms) and/or or submit a [pull request](https://github.com/jakeboone02/parse-ingredient/pulls) to add new units to this library's default list.

In the browser, available as a global function `parseIngredient`. Remember to first include `numeric-quantity`.
In the browser, all exports including the `parseIngredient` function are available on the global object `ParseIngredient`. (Remember to first include `numeric-quantity`.)

@@ -210,1 +210,11 @@ ```html

```
## Other exports
| Name | Type | Description |
| -------------------------- | ----------- | ------------------------------------------------------------------------------------- |
| `unitsOfMeasure` | `object` | Information about natively-supported units of measure (see `UnitOfMeasure` interface) |
| `ParseIngredientOptions` | `interface` | Shape of the second parameter to the `parseIngredient` function |
| `Ingredient` | `interface` | Interface describing the shape of each element in the returned ingredient array |
| `UnitOfMeasure` | `interface` | Interface including short, plural, and alternate forms of a unit of measure |
| `UnitOfMeasureDefinitions` | `type` | Object with keys representing a `unitOfMeasureID` and values of type `UnitOfMeasure` |

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet