Skip to content

Commit

Permalink
Update code and documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
jakeboone02 committed Feb 12, 2021
1 parent 37b3743 commit 2841479
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 17 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
[![downloads](https://img.shields.io/npm/dm/parse-ingredient.svg)](http://npm-stat.com/charts.html?package=parse-ingredient&from=2015-08-01)
[![MIT License](https://img.shields.io/npm/l/parse-ingredient.svg)](http://opensource.org/licenses/MIT)

Parses a string, which can include mixed numbers or vulgar fractions (thanks to [numeric-quantity](https://www.npmjs.com/package/numeric-quantity)), into an array of ingredient objects with the following signature:
Parses a string, which can include mixed numbers or vulgar fractions (thanks to [numeric-quantity](https://www.npmjs.com/package/numeric-quantity)), into an array of recipe ingredient objects with the following signature:

```ts
interface Ingredient {
Expand All @@ -33,7 +33,7 @@ interface Ingredient {
}
```

For the `isGroupHeader` attribute to be `true`, the ingredient string must not start with a number, and must either start with `'For'` or end with `':'`.
For the `isGroupHeader` attribute to be `true`, the ingredient string must not start with a number, and must either start with `'For '` or end with `':'`.

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`).

Expand Down
36 changes: 21 additions & 15 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,11 @@ const UOM_LIST = [
'liter','liters','l'
];

// Originally from lodash: https://github.com/lodash/lodash/blob/4.17.15/lodash.js#L6874
/**
* Removes falsy values from an array
*
* Originally from lodash: https://github.com/lodash/lodash/blob/4.17.15/lodash.js#L6874
*/
const compactArray = <T>(array: T[]) => {
let index = -1;
const length = array.length;
Expand All @@ -56,17 +60,19 @@ const compactArray = <T>(array: T[]) => {
return result;
};

/**
* Parses a string into an array of recipe ingredient objects
* @param ingText The ingredient text
*/
const parseIngredient = (ingText: string): Ingredient[] => {
const arrRaw = compactArray(
ingText
.replace(/\n{2,}/g, '\n')
.split('\n')
.map(ing => ing.trim())
);
const arrIngs = [];
const arrRawLen = arrRaw.length;

for (var i = 0; i < arrRawLen; i++) {
const arrIngs = arrRaw.map(line => {
const oIng: Ingredient = {
quantity: null,
quantity2: null,
Expand All @@ -76,11 +82,11 @@ const parseIngredient = (ingText: string): Ingredient[] => {
};

// Check if the first character is numeric.
let nqResult = numericQuantity(arrRaw[i].substring(0, 1));
const nqResultFirstChar = numericQuantity(line.substring(0, 1));

// If the first character is not numeric, the entire line is the description.
if (isNaN(nqResult)) {
oIng.description = arrRaw[i];
if (isNaN(nqResultFirstChar)) {
oIng.description = line;

// If the line ends with ":" or starts with "For ", then it is assumed to be a group header.
if (
Expand All @@ -94,14 +100,14 @@ const parseIngredient = (ingText: string): Ingredient[] => {
// constitute a single value. This will be `quantity`.
} else {
let lenNum = 6;
nqResult = NaN;
let nqResult = NaN;

while (lenNum > 0 && isNaN(nqResult)) {
nqResult = numericQuantity(arrRaw[i].substring(0, lenNum).trim());
nqResult = numericQuantity(line.substring(0, lenNum).trim());

if (nqResult > -1) {
oIng.quantity = nqResult;
oIng.description = arrRaw[i].substring(lenNum).trim();
oIng.description = line.substring(lenNum).trim();
}

lenNum--;
Expand All @@ -113,16 +119,16 @@ const parseIngredient = (ingText: string): Ingredient[] => {
// characters just like we did for `quantity`.
const firstChar = oIng.description.substring(0, 1);
if (firstChar === '-' || firstChar === '\u2013' || firstChar === '\u2014') {
nqResult = numericQuantity(
const nqResultFirstChar = numericQuantity(
oIng.description
.substring(1)
.trim()
.substring(0, 1)
);

if (!isNaN(nqResult)) {
if (!isNaN(nqResultFirstChar)) {
let lenNum = 6;
nqResult = NaN;
let nqResult = NaN;

while (lenNum > 0 && isNaN(nqResult)) {
nqResult = numericQuantity(oIng.description.substring(1, lenNum));
Expand All @@ -145,8 +151,8 @@ const parseIngredient = (ingText: string): Ingredient[] => {
oIng.description = oIng.description.substring(firstSpace + 1);
}

arrIngs.push(oIng);
}
return oIng;
});

return arrIngs;
};
Expand Down

0 comments on commit 2841479

Please sign in to comment.