Fix appendages parsing to handle multiple appendages
This commit is contained in:
@@ -298,9 +298,86 @@ function decodeSimpleTag(label, tag, descriptions) {
|
||||
};
|
||||
}
|
||||
|
||||
// Decode a single appendage
|
||||
function decodeSingleAppendage(appendage) {
|
||||
const baseDescription = TAG_DESCRIPTIONS.appendages.base[appendage.baseType];
|
||||
|
||||
if (!baseDescription) {
|
||||
return appendage.baseType;
|
||||
}
|
||||
|
||||
// If no modifiers, return base description
|
||||
if (!appendage.modifiers || appendage.modifiers.length === 0) {
|
||||
return baseDescription;
|
||||
}
|
||||
|
||||
// Check for modifier
|
||||
const modifier = appendage.modifiers[0];
|
||||
const modifierDescription = TAG_DESCRIPTIONS.appendages.modifiers[modifier];
|
||||
|
||||
if (modifierDescription) {
|
||||
// Replace placeholders in modifier description
|
||||
let value = modifierDescription;
|
||||
|
||||
// Determine singular and plural forms
|
||||
let singular = baseDescription.toLowerCase().replace(/^a pair of /, '').replace(/^a /, '');
|
||||
let plural = singular;
|
||||
|
||||
// Handle specific cases
|
||||
if (singular === 'legs' || singular === 'wings' || singular === 'arms') {
|
||||
// already plural
|
||||
} else if (singular === 'head') {
|
||||
plural = 'heads';
|
||||
singular = 'head';
|
||||
} else if (singular === 'tail') {
|
||||
plural = 'tails';
|
||||
singular = 'tail';
|
||||
} else if (singular.endsWith('limbs')) {
|
||||
plural = singular;
|
||||
singular = singular.replace(/s$/, '');
|
||||
}
|
||||
|
||||
value = value.replace(/{type}/g, singular);
|
||||
value = value.replace(/{plural}/g, plural.charAt(0).toUpperCase() + plural.slice(1));
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
return baseDescription;
|
||||
}
|
||||
|
||||
// Decode appendages
|
||||
function decodeAppendages(appendages) {
|
||||
// Get base description
|
||||
// Handle new multi-appendage structure
|
||||
if (appendages.appendages && Array.isArray(appendages.appendages)) {
|
||||
const decodedAppendages = appendages.appendages.map((app, index) => {
|
||||
const decoded = decodeSingleAppendage(app);
|
||||
// Lowercase the first letter for all items after the first
|
||||
if (index > 0 && decoded) {
|
||||
return decoded.charAt(0).toLowerCase() + decoded.slice(1);
|
||||
}
|
||||
return decoded;
|
||||
});
|
||||
|
||||
// Combine with commas and "and"
|
||||
let value;
|
||||
if (decodedAppendages.length === 1) {
|
||||
value = decodedAppendages[0];
|
||||
} else if (decodedAppendages.length === 2) {
|
||||
value = decodedAppendages.join(' and ');
|
||||
} else {
|
||||
const lastAppendage = decodedAppendages.pop();
|
||||
value = decodedAppendages.join(', ') + ', and ' + lastAppendage;
|
||||
}
|
||||
|
||||
return {
|
||||
label: 'Appendages',
|
||||
value: value,
|
||||
tag: appendages.raw
|
||||
};
|
||||
}
|
||||
|
||||
// Legacy support for old structure
|
||||
const baseDescription = TAG_DESCRIPTIONS.appendages.base[appendages.baseType];
|
||||
|
||||
if (!baseDescription) {
|
||||
|
||||
43
js/parser.js
43
js/parser.js
@@ -486,23 +486,42 @@ function parseAppendages(token) {
|
||||
// Remove 'P' prefix
|
||||
let content = token.substring(1);
|
||||
|
||||
// Check for Pw' (wings as arms) special case
|
||||
if (content.startsWith("w'")) {
|
||||
const modifiers = content.substring(2);
|
||||
return {
|
||||
baseType: "w'",
|
||||
modifiers: modifiers,
|
||||
raw: token
|
||||
const appendagesList = [];
|
||||
let i = 0;
|
||||
|
||||
while (i < content.length) {
|
||||
let appendage = {
|
||||
baseType: null,
|
||||
modifiers: ''
|
||||
};
|
||||
|
||||
// Check for Pw' (wings as arms) special case
|
||||
if (content.substring(i, i + 2) === "w'") {
|
||||
appendage.baseType = "w'";
|
||||
i += 2;
|
||||
} else {
|
||||
// Get base type (single character)
|
||||
appendage.baseType = content[i];
|
||||
i++;
|
||||
}
|
||||
|
||||
// Get base type (first character after P)
|
||||
const baseType = content[0];
|
||||
const modifiers = content.substring(1);
|
||||
// Collect modifiers for this appendage (until we hit another letter that's a base type)
|
||||
while (i < content.length) {
|
||||
const char = content[i];
|
||||
// Check if this is a new appendage base type (a, f, h, k, l, p, t, v, w)
|
||||
if ('afhklptvw'.includes(char.toLowerCase())) {
|
||||
break;
|
||||
}
|
||||
// Otherwise it's a modifier
|
||||
appendage.modifiers += char;
|
||||
i++;
|
||||
}
|
||||
|
||||
appendagesList.push(appendage);
|
||||
}
|
||||
|
||||
return {
|
||||
baseType: baseType,
|
||||
modifiers: modifiers,
|
||||
appendages: appendagesList,
|
||||
raw: token
|
||||
};
|
||||
}
|
||||
|
||||
@@ -404,7 +404,8 @@ const TEST_CASES = {
|
||||
{ code: 'Ph+', expected: 'One more head than normal - \'I got ahead in advertising!\'' },
|
||||
{ code: 'Pw-', expected: 'One less wing than normal - \'I have only one wing!\'' },
|
||||
{ code: 'Pl!', expected: 'Many legs - \'I am a millipede!\'' },
|
||||
{ code: 'Pl^', expected: 'Legs end in webbed feet - \'Don\'t call me a frog!\'' }
|
||||
{ code: 'Pl^', expected: 'Legs end in webbed feet - \'Don\'t call me a frog!\'' },
|
||||
{ code: 'Phvwalt', expected: 'A head, a pair of horns or spines on the head, a pair of wings, a pair of arms, a pair of legs, and a tail' }
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user