UNPKG

parse-ingredient

Version:

Recipe ingredient parser with support for mixed numbers and vulgar fractions

2 lines 5.06 kB
import{numericQuantity as o}from"numeric-quantity";import{numericRegex as D}from"numeric-quantity";var R={additionalUOMs:{},allowLeadingOf:!1,normalizeUOM:!1,ignoreUOMs:[]},v=["For"],k=new RegExp(`^(?:${v.join("|")})\\s`,"i"),L=["or","to"],w=`(-|\u2013|\u2014|(?:${L.join("|")})\\s)`,N=new RegExp(`^${w}`,"i"),I=/^(fl(?:uid)?(?:\s+|-)(?:oz|ounces?)|\w+[-.]?)(.+)?/,q=D.source.replace(/^\^/,"").replace(/\$$/,""),O=new RegExp(`(,|:|-|\u2013|\u2014|x|\u2A2F)?\\s*((${q})\\s*(${w}))?\\s*(${q})\\s*(fl(?:uid)?(?:\\s+|-)(?:oz|ounces?)|\\w+)?$`,"i"),Q=["of"],E=new RegExp(`^(?:${Q.join("|")})\\s+`,"i"),W=["from","of"],U=new RegExp(`\\s+(?:${W.join("|")})$`,"i"),$={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:["l."]},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","pkgs."]},piece:{short:"piece",plural:"pieces",alternates:["pc","pc.","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.","Tbsp"]},teaspoon:{short:"tsp",plural:"teaspoons",alternates:["tsp.","t"]},yard:{short:"yd",plural:"yards",alternates:["yd.","yds."]}};var j=/\r?\n/,A=([g,f])=>({id:g,...f}),H=(g,f=R)=>{let l={...R,...f},z={...$,...l.additionalUOMs},m=Object.entries(z).map(A),b=m.length;return g.split(j).map(a=>a.trim()).filter(Boolean).map(a=>{let s={quantity:null,quantity2:null,unitOfMeasureID:null,unitOfMeasure:null,description:"",isGroupHeader:!1};if(isNaN(o(a[0]))){let t=O.exec(a);if(t&&l.ignoreUOMs.includes(t.at(-1)??""))s.description=a;else if(t){s.description=a.replace(O,"").trim();let r=t[3],i=t[12];r?(s.quantity=o(r),s.quantity2=o(i)):s.quantity=o(i);let e=t.at(-1);if(e){let n="",p="",u=-1;for(;++u<b&&!n;){let{alternates:h,id:c,short:M,plural:x}=m[u];[...h,c,M,x].includes(e)&&(n=e,p=c)}n?(s.unitOfMeasureID=p,s.unitOfMeasure=l.normalizeUOM?p:n):s.description.match(U)&&(s.description+=` ${e}`)}}else s.description=a,(s.description.endsWith(":")||k.test(s.description))&&(s.isGroupHeader=!0)}else{let t=6,r=NaN;for(;t>0&&isNaN(r);)r=o(a.substring(0,t).trim()),r>-1&&(s.quantity=r,s.description=a.substring(t).trim()),t--}let y=N.exec(s.description);if(y){let t=y[1].length,r=o(s.description.substring(t).trim()[0]);if(!isNaN(r)){let i=7,e=NaN;for(;--i>0&&isNaN(e);)e=o(s.description.substring(t,i)),isNaN(e)||(s.quantity2=e,s.description=s.description.substring(i).trim())}}let d=I.exec(s.description);if(d){let t=d[1].replace(/\s+/g," "),r=(d[2]??"").trim();if(r){let i="",e="",n=-1;for(;++n<b&&!i;){let{alternates:p,id:u,short:h,plural:c}=m[n];[...p,u,h,c].filter(x=>!l.ignoreUOMs.includes(x)).includes(t)&&(i=t,e=u)}i&&(s.unitOfMeasureID=e,s.unitOfMeasure=l.normalizeUOM?e:i,s.description=r)}}return!l.allowLeadingOf&&s.description.match(E)&&(s.description=s.description.replace(E,"")),s})};export{R as defaultOptions,I as firstWordRegEx,v as fors,k as forsRegEx,U as fromRegEx,W as froms,E as ofRegEx,Q as ofs,H as parseIngredient,N as rangeSeparatorRegEx,L as rangeSeparatorWords,O as trailingQuantityRegEx,$ as unitsOfMeasure}; //# sourceMappingURL=parse-ingredient.production.mjs.map