UNPKG

parse-ingredient

Version:

Recipe ingredient parser with support for mixed numbers and vulgar fractions

2 lines 10.5 kB
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`numeric-quantity`);const t=e=>e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`),n=e=>{if(e.length===0)return null;let n=e.map(e=>e instanceof RegExp?`(?:${e.source})`:`(?:${t(e)})\\s`);return RegExp(`^(?:${n.join(`|`)})`,`iu`)},r=e=>`(-|–|—|(?:${e.map(e=>e instanceof RegExp?`(?:${e.source})`:`(?:${t(e)})`).join(`|`)})\\s)`,i=e=>RegExp(`^${r(e)}`,`iu`),a=e=>{if(e.length===0)return null;let n=e.map(e=>e instanceof RegExp?`(?:${e.source})`:`(?:${t(e)})\\s+`);return RegExp(`^(?:${n.join(`|`)})`,`iu`)},o=e=>{if(e.length===0)return null;let n=e.map(e=>e instanceof RegExp?`(?:${e.source})\\s*`:`(?:${t(e)})\\s*`);return RegExp(`^(?:${n.join(`|`)})`,`iu`)},s=e=>RegExp(`\\s+(?:${e.map(t).join(`|`)})$`,`iu`),c=[`For`],l=[`or`,`to`],u=[`of`],d=[`from`,`of`],f=[],p={additionalUOMs:{},allowLeadingOf:!1,normalizeUOM:!1,ignoreUOMs:[],decimalSeparator:`.`,groupHeaderPatterns:c,rangeSeparators:l,descriptionStripPrefixes:u,trailingQuantityContext:d,leadingQuantityPrefixes:f,includeMeta:!1,partialUnitMatching:!1},m=c,h=n(c),g=l,_=i(l),v=/^(fl(?:uid)?(?:\s+|-)(?:oz|ounces?)|[\p{L}\p{N}_]+(?:[./-][\p{L}\p{N}_]+|\([\p{L}\p{N}_]+\))*[-.]?)(.+)?/iu,y=e.numericRegex.source.replace(`^`,``).replace(/\$$/,``),b=e=>{let t=r(e);return RegExp(`(,|:|-|–|—|x|⨯)?\\s*((${y})\\s*(${t}))?\\s*(${y})\\s*(fl(?:uid)?(?:\\s+|-)(?:oz|ounces?)|[\\p{L}\\p{N}_]+(?:[./-][\\p{L}\\p{N}_]+|\\([\\p{L}\\p{N}_]+\\))*[-.]?)?$`,`iu`)},x=b(l),S=u,C=a(u),w=d,T=s(d),E={bag:{short:`bag`,plural:`bags`,alternates:[],type:`count`},box:{short:`box`,plural:`boxes`,alternates:[],type:`count`},bunch:{short:`bunch`,plural:`bunches`,alternates:[],type:`count`},can:{short:`can`,plural:`cans`,alternates:[],type:`count`},carton:{short:`carton`,plural:`cartons`,alternates:[],type:`count`},clove:{short:`clove`,plural:`cloves`,alternates:[],type:`count`},container:{short:`container`,plural:`containers`,alternates:[],type:`count`},dozen:{short:`dz`,plural:`dozen`,alternates:[`dz.`],type:`count`},ear:{short:`ear`,plural:`ears`,alternates:[],type:`count`},head:{short:`head`,plural:`heads`,alternates:[],type:`count`},pack:{short:`pack`,plural:`packs`,alternates:[],type:`count`},package:{short:`pkg`,plural:`packages`,alternates:[`pkg.`,`pkgs`,`pkgs.`],type:`count`},piece:{short:`piece`,plural:`pieces`,alternates:[`pc`,`pc.`,`pcs`,`pcs.`],type:`count`},sprig:{short:`sprig`,plural:`sprigs`,alternates:[],type:`count`},stick:{short:`stick`,plural:`sticks`,alternates:[],type:`count`},large:{short:`lg`,plural:`large`,alternates:[`lg`,`lg.`],type:`other`},medium:{short:`md`,plural:`medium`,alternates:[`med`,`med.`,`md.`],type:`other`},small:{short:`sm`,plural:`small`,alternates:[`sm.`],type:`other`},centimeter:{short:`cm`,plural:`centimeters`,alternates:[`cm.`],type:`length`,conversionFactor:10},foot:{short:`ft`,plural:`feet`,alternates:[`ft.`],type:`length`,conversionFactor:304.8},inch:{short:`in`,plural:`inches`,alternates:[`in.`],type:`length`,conversionFactor:25.4},meter:{short:`m`,plural:`meters`,alternates:[`m.`],type:`length`,conversionFactor:1e3},millimeter:{short:`mm`,plural:`millimeters`,alternates:[`mm.`],type:`length`,conversionFactor:1},yard:{short:`yd`,plural:`yards`,alternates:[`yd.`,`yds.`],type:`length`,conversionFactor:914.4},gram:{short:`g`,plural:`grams`,alternates:[`g.`],type:`mass`,conversionFactor:1},kilogram:{short:`kg`,plural:`kilograms`,alternates:[`kg.`],type:`mass`,conversionFactor:1e3},milligram:{short:`mg`,plural:`milligrams`,alternates:[`mg.`],type:`mass`,conversionFactor:.001},ounce:{short:`oz`,plural:`ounces`,alternates:[`oz.`],type:`mass`,conversionFactor:28.349523},pound:{short:`lb`,plural:`pounds`,alternates:[`lb.`,`lbs`,`lbs.`],type:`mass`,conversionFactor:453.59237},cup:{short:`c`,plural:`cups`,alternates:[`c.`,`C`],type:`volume`,conversionFactor:{us:236.58824,imperial:284.13063,metric:250}},deciliter:{short:`dl`,plural:`deciliters`,alternates:[`dl.`],type:`volume`,conversionFactor:100},"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`],type:`volume`,conversionFactor:{us:29.57353,imperial:28.413063}},gallon:{short:`gal`,plural:`gallons`,alternates:[`gal.`],type:`volume`,conversionFactor:{us:3785.4118,imperial:4546.09}},liter:{short:`l`,plural:`liters`,alternates:[`l.`],type:`volume`,conversionFactor:1e3},milliliter:{short:`ml`,plural:`milliliters`,alternates:[`mL`,`ml.`,`mL.`],type:`volume`,conversionFactor:1},pint:{short:`pt`,plural:`pints`,alternates:[`pt.`],type:`volume`,conversionFactor:{us:473.17647,imperial:568.26125}},quart:{short:`qt`,plural:`quarts`,alternates:[`qt.`,`qts`,`qts.`],type:`volume`,conversionFactor:{us:946.35295,imperial:1136.5225}},tablespoon:{short:`tbsp`,plural:`tablespoons`,alternates:[`tbsp.`,`T`,`Tbsp.`,`Tbsp`,`tablespoonful`],type:`volume`,conversionFactor:{us:14.786765,imperial:15,metric:15}},teaspoon:{short:`tsp`,plural:`teaspoons`,alternates:[`tsp.`,`t`,`teaspoonful`],type:`volume`,conversionFactor:{us:4.9289216,imperial:5,metric:5}},dash:{short:`dash`,plural:`dashes`,alternates:[],type:`volume`},drop:{short:`drop`,plural:`drops`,alternates:[],type:`volume`},pinch:{short:`pinch`,plural:`pinches`,alternates:[],type:`volume`}},D=(e={})=>{let t=new Map,n=new Map,r=(e,r)=>{let i=[e,r.short,r.plural,...r.alternates];for(let r of i)t.set(r,e),n.set(r.toLowerCase(),e)};for(let[e,t]of Object.entries(E))r(e,t);for(let[t,n]of Object.entries(e))r(t,n);return{caseSensitive:t,caseInsensitive:n}},O=(e,t)=>{var n,r;return(n=(r=t.caseSensitive.get(e))==null?t.caseInsensitive.get(e.toLowerCase()):r)==null?null:n};let k=null;const A=()=>{var e;return(e=k)==null?k=D():e},j=e=>{let t=[...e.caseSensitive.keys()];return t.sort((e,t)=>t.length-e.length),t},M=(e,t={})=>{let{additionalUOMs:n={},ignoreUOMs:r=[]}=t;if(r.length>0){let t=e.toLowerCase();if(r.some(e=>e.toLowerCase()===t))return null}return O(e,Object.keys(n).length>0?D(n):A())},N=(e,t)=>{var n;return e===void 0?null:typeof e==`number`?e:(n=e[t])==null?null:n},P=(e,t,n,r={})=>{let{fromSystem:i=`us`,toSystem:a=`us`,additionalUOMs:o={}}=r,s=i.toLowerCase(),c=a.toLowerCase(),l={...E,...o},u=M(t,{additionalUOMs:o}),d=M(n,{additionalUOMs:o});if(!u||!d)return null;if(u===d&&s===c)return e;let f=l[u],p=l[d];if(!f.type||!p.type||f.type!==p.type)return null;let m=N(f.conversionFactor,s),h=N(p.conversionFactor,c);if(m===null||h===null)return null;let g=e*m/h;return Math.round(g*1e6)/1e6},F=/\r?\n/,I=/^([\p{L}\p{N}_]+(?:[.-]?[\p{L}\p{N}_]+)*[-.]?)(?:\s+|$)/iu,L=(e,t)=>{if(!e||!t)return e;let n=e.trimStart();for(;n;){let e=t.exec(n);if(!e||!e[0])break;n=n.slice(e[0].length).trimStart()}return n},R=(t,r=p)=>{let c={...p,...r},l=c.decimalSeparator===`,`?{decimalSeparator:`,`}:void 0,u=c.ignoreUOMs.map(e=>e.toLowerCase()),d=n(c.groupHeaderPatterns),f=i(c.rangeSeparators),m=a(c.descriptionStripPrefixes),h=s(c.trailingQuantityContext),g=b(c.rangeSeparators),_=o(c.leadingQuantityPrefixes),y=c.partialUnitMatching?j(Object.keys(c.additionalUOMs).length>0?D(c.additionalUOMs):A()):[];return(Array.isArray(t)?t:t.split(F)).map((e,t)=>({line:e.trim(),sourceIndex:t})).filter(({line:e})=>!!e).map(({line:t,sourceIndex:n})=>{let i=L(t,_),a={quantity:null,quantity2:null,unitOfMeasureID:null,unitOfMeasure:null,description:``,isGroupHeader:!1};if(c.includeMeta&&(a.meta={sourceText:t,sourceIndex:n}),i&&(!isNaN((0,e.numericQuantity)(i[0],l))||i[0]===c.decimalSeparator&&!isNaN((0,e.numericQuantity)(i.slice(0,2),l)))){let t=6,n=NaN;for(;t>0&&isNaN(n);)n=(0,e.numericQuantity)(i.substring(0,t).trim(),l),n>-1&&(a.quantity=n,a.description=i.substring(t).trim()),t--}else{var o;let t=g.exec(i),n=t==null||(o=t.at(-1))==null?void 0:o.toLowerCase();if(n&&u.includes(n))a.description=i;else if(t){a.description=i.replace(g,``).trim();let n=t[3],o=t[12];n?(a.quantity=(0,e.numericQuantity)(n,l),a.quantity2=(0,e.numericQuantity)(o,l)):a.quantity=(0,e.numericQuantity)(o,l);let s=t.at(-1);if(s){let e=null,t=s;if(a.description){let n=a.description.trim().split(/\s+/);if(n.length>=1){let i=n[n.length-1]+` `+s,o=M(i,r);o&&(e=o,t=i,a.description=n.slice(0,-1).join(` `))}}e||(e=M(s,r),t=s),e?(a.unitOfMeasureID=e,a.unitOfMeasure=c.normalizeUOM?e:t):a.description.match(h)&&(a.description+=` ${s}`)}}else a.description=i,(a.description.endsWith(`:`)||d!=null&&d.test(a.description))&&(a.isGroupHeader=!0)}let s=f.exec(a.description);if(s){let t=s[1].length,n=L(a.description.substring(t).trim(),_);if(n){let t=(0,e.numericQuantity)(n[0],l);if(!isNaN(t)){let t=7,r=NaN;for(;--t>0&&isNaN(r);)r=(0,e.numericQuantity)(n.substring(0,t),l),isNaN(r)||(a.quantity2=r,a.description=n.substring(t).trim())}}}let p=v.exec(a.description);if(p){var b;let e=p[1].replace(/\s+/g,` `),t=((b=p[2])==null?``:b).trim();if(t){let n=M(e,r),i=e,o=t,s=t.match(I);if(s){let c=e+` `+s[1],l=M(c,r),u=t.substring(s[0].length).trim();l&&(a.quantity!==null||u)&&(n=l,i=c,o=u)}n&&(a.unitOfMeasureID=n,a.unitOfMeasure=c.normalizeUOM?n:i,a.description=o)}}if(!a.unitOfMeasureID&&c.partialUnitMatching&&a.description){let e=a.description.toLowerCase();for(let t of y){let n=e.indexOf(t.toLowerCase());if(n===-1)continue;let i=a.description.substring(n,n+t.length),o=M(i,r);if(!o)continue;let s=[a.description.substring(0,n).trim(),a.description.substring(n+t.length).trim()].filter(Boolean).join(` `);if(s){a.unitOfMeasureID=o,a.unitOfMeasure=c.normalizeUOM?o:i,a.description=s;break}}}return!c.allowLeadingOf&&m&&a.description.match(m)&&(a.description=a.description.replace(m,``)),a})};exports.buildLeadingQuantityPrefixRegex=o,exports.buildPrefixPatternRegex=n,exports.buildRangeSeparatorRegex=i,exports.buildRangeSeparatorSource=r,exports.buildStripPrefixRegex=a,exports.buildTrailingContextRegex=s,exports.buildTrailingQuantityRegex=b,exports.convertUnit=P,exports.defaultDescriptionStripPrefixes=u,exports.defaultGroupHeaderPatterns=c,exports.defaultLeadingQuantityPrefixes=f,exports.defaultOptions=p,exports.defaultRangeSeparators=l,exports.defaultTrailingQuantityContext=d,exports.escapeRegex=t,exports.firstWordRegEx=v,exports.fors=m,exports.forsRegEx=h,exports.fromRegEx=T,exports.froms=w,exports.identifyUnit=M,exports.ofRegEx=C,exports.ofs=S,exports.parseIngredient=R,exports.rangeSeparatorRegEx=_,exports.rangeSeparatorWords=g,exports.trailingQuantityRegEx=x,exports.unitsOfMeasure=E; //# sourceMappingURL=parse-ingredient.cjs.production.js.map