fix(inventory): handle parenthetical descriptions with newlines in item parser

Updated parseItems() to intelligently collapse newlines within parentheses:
- Tracks parentheses depth to handle nested parens
- Replaces newlines with spaces only when inside parentheses
- Preserves newlines outside parentheses
- Prevents double spaces after newline replacement

Example fix:
- Input: 'Books (various magical tomes\n\nhistorical texts)\n\nAlchemy Ingredients'
- Before: ['Books (various magical tomes', 'historical texts)', 'Alchemy Ingredients']
- After: ['Books (various magical tomes historical texts)', 'Alchemy Ingredients']
This commit is contained in:
Lucas 'Paperboy' Rose-Winters
2025-10-17 17:42:27 +11:00
parent de43e84cd0
commit 5342ea01ee
+30 -1
View File
@@ -6,12 +6,14 @@
/** /**
* Parses a comma-separated item string into an array of trimmed item names. * Parses a comma-separated item string into an array of trimmed item names.
* Filters out empty strings and handles "None" gracefully. * Filters out empty strings and handles "None" gracefully.
* Smart handling: collapses newlines inside parentheses, preserves them outside.
* *
* @param {string} itemString - Comma-separated items (e.g., "Sword, Shield, 3x Potions") * @param {string} itemString - Comma-separated items (e.g., "Sword, Shield, 3x Potions")
* @returns {string[]} Array of item names, or empty array if none * @returns {string[]} Array of item names, or empty array if none
* *
* @example * @example
* parseItems("Sword, Shield, 3x Potions") // ["Sword", "Shield", "3x Potions"] * parseItems("Sword, Shield, 3x Potions") // ["Sword", "Shield", "3x Potions"]
* parseItems("Books (magical\ntomes), Sword") // ["Books (magical tomes)", "Sword"]
* parseItems("None") // [] * parseItems("None") // []
* parseItems("") // [] * parseItems("") // []
* parseItems(null) // [] * parseItems(null) // []
@@ -28,8 +30,35 @@ export function parseItems(itemString) {
return []; return [];
} }
// Collapse newlines inside parentheses
let processed = '';
let parenDepth = 0;
for (let i = 0; i < trimmed.length; i++) {
const char = trimmed[i];
if (char === '(') {
parenDepth++;
processed += char;
} else if (char === ')') {
parenDepth--;
processed += char;
} else if ((char === '\n' || char === '\r') && parenDepth > 0) {
// Inside parentheses: replace newline with space
// Skip if previous char was already a space
if (processed[processed.length - 1] !== ' ') {
processed += ' ';
}
} else {
processed += char;
}
}
// Clean up multiple consecutive spaces
processed = processed.replace(/\s+/g, ' ');
// Split by comma, trim each item, filter empties // Split by comma, trim each item, filter empties
return itemString return processed
.split(',') .split(',')
.map(item => item.trim()) .map(item => item.trim())
.filter(item => item !== '' && item.toLowerCase() !== 'none'); .filter(item => item !== '' && item.toLowerCase() !== 'none');