Fix parser to support both text and emoji formats for Info Box and Present Characters trackers

This commit is contained in:
Spicy_Marinara
2025-10-20 14:49:30 +02:00
parent bbc07c9326
commit 776d0823a2
8 changed files with 320 additions and 91 deletions
+15 -8
View File
@@ -66,35 +66,42 @@ export function renderInfoBox() {
for (const line of lines) {
// console.log('[RPG Companion] Processing line:', line);
if (line.includes('🗓️:')) {
// Support both new text format (Date:) and legacy emoji format (🗓️:)
if (line.startsWith('Date:') || line.includes('🗓️:')) {
// console.log('[RPG Companion] → Matched DATE');
const dateStr = line.replace('🗓️:', '').trim();
const dateStr = line.replace('Date:', '').replace('🗓️:', '').trim();
// Parse format: "Weekday, Month Day, Year" or "Weekday, Month, Year"
const dateParts = dateStr.split(',').map(p => p.trim());
data.weekday = dateParts[0] || '';
data.month = dateParts[1] || '';
data.year = dateParts[2] || '';
data.date = dateStr;
} else if (line.includes('🌡️:')) {
} else if (line.startsWith('Temperature:') || line.includes('🌡️:')) {
// console.log('[RPG Companion] → Matched TEMPERATURE');
const tempStr = line.replace('🌡️:', '').trim();
const tempStr = line.replace('Temperature:', '').replace('🌡️:', '').trim();
data.temperature = tempStr;
// Extract numeric value
const tempMatch = tempStr.match(/(-?\d+)/);
if (tempMatch) {
data.tempValue = parseInt(tempMatch[1]);
}
} else if (line.includes('🕒:')) {
} else if (line.startsWith('Time:') || line.includes('🕒:')) {
// console.log('[RPG Companion] → Matched TIME');
const timeStr = line.replace('🕒:', '').trim();
const timeStr = line.replace('Time:', '').replace('🕒:', '').trim();
data.time = timeStr;
// Parse "HH:MM → HH:MM" format
const timeParts = timeStr.split('→').map(t => t.trim());
data.timeStart = timeParts[0] || '';
data.timeEnd = timeParts[1] || '';
} else if (line.includes('🗺️:')) {
} else if (line.startsWith('Location:') || line.includes('🗺️:')) {
// console.log('[RPG Companion] → Matched LOCATION');
data.location = line.replace('🗺️:', '').trim();
data.location = line.replace('Location:', '').replace('🗺️:', '').trim();
} else if (line.startsWith('Weather:')) {
// New text format: Weather: [Emoji], [Forecast]
const weatherStr = line.replace('Weather:', '').trim();
const weatherParts = weatherStr.split(',').map(p => p.trim());
data.weatherEmoji = weatherParts[0] || '';
data.weatherForecast = weatherParts[1] || '';
} else {
// Check if it's a weather line
// Since \p{Emoji} doesn't work reliably, use a simpler approach
+38 -5
View File
@@ -71,6 +71,7 @@ export function renderThoughts() {
// console.log('[RPG Companion] Split into lines:', lines);
// Parse format: [Emoji]: [Name, Status, Demeanor] | [Relationship] | [Thoughts]
// Also supports 4-part format: [Emoji]: [Name, Status] | [Demeanor] | [Relationship] | [Thoughts]
for (const line of lines) {
// Skip empty lines, headers, dividers, and code fences
if (line.trim() &&
@@ -89,17 +90,40 @@ export function renderThoughts() {
if (emojiMatch) {
const emoji = emojiMatch[1].trim();
const info = emojiMatch[2].trim();
const relationship = parts[1].trim(); // Enemy/Neutral/Friend/Lover
const thoughts = parts[2] ? parts[2].trim() : '';
// Handle both 3-part and 4-part formats
let relationship, thoughts, traits;
if (parts.length === 3) {
// 3-part format: Emoji:Name,traits | Relationship | Thoughts
relationship = parts[1].trim();
thoughts = parts[2].trim();
const infoParts = info.split(',').map(p => p.trim());
traits = infoParts.slice(1).join(', ');
} else if (parts.length >= 4) {
// 4-part format: Emoji:Name,traits | Demeanor | Relationship | Thoughts
// Add the demeanor to traits and use last two parts for relationship/thoughts
const demeanor = parts[1].trim();
relationship = parts[2].trim();
thoughts = parts[3].trim();
const infoParts = info.split(',').map(p => p.trim());
const baseTraits = infoParts.slice(1).join(', ');
traits = baseTraits ? `${baseTraits}, ${demeanor}` : demeanor;
} else {
// Fallback for 2-part format
relationship = parts[1].trim();
thoughts = '';
const infoParts = info.split(',').map(p => p.trim());
traits = infoParts.slice(1).join(', ');
}
// Parse name from info (first part before comma)
const infoParts = info.split(',').map(p => p.trim());
const name = infoParts[0] || '';
const traits = infoParts.slice(1).join(', ');
if (name && name.toLowerCase() !== 'unavailable') {
presentCharacters.push({ emoji, name, traits, relationship, thoughts });
// console.log('[RPG Companion] Parsed character:', { name, relationship });
// console.log('[RPG Companion] Parsed character:', { name, relationship, thoughts });
}
}
}
@@ -429,6 +453,7 @@ export function updateChatThoughts() {
const parts = line.split('|').map(p => p.trim());
// console.log('[RPG Companion] Line parts:', parts);
// Handle both 3-part and 4-part formats
if (parts.length >= 3) {
const firstPart = parts[0].trim();
const emojiMatch = firstPart.match(/^(.+?):\s*(.+)$/);
@@ -436,7 +461,15 @@ export function updateChatThoughts() {
if (emojiMatch) {
const emoji = emojiMatch[1].trim();
const info = emojiMatch[2].trim();
const thoughts = parts[2] ? parts[2].trim() : '';
let thoughts;
if (parts.length === 3) {
// 3-part format: Emoji:Name,traits | Relationship | Thoughts
thoughts = parts[2].trim();
} else if (parts.length >= 4) {
// 4-part format: Emoji:Name,traits | Demeanor | Relationship | Thoughts
thoughts = parts[3].trim();
}
const infoParts = info.split(',').map(p => p.trim());
const name = infoParts[0] || '';
+31 -1
View File
@@ -55,8 +55,12 @@ export function renderUserStats() {
const html = `
<div class="rpg-stats-content">
<div class="rpg-stats-left">
<div style="display: flex; gap: clamp(4px, 0.8vh, 8px); align-items: center; justify-content: center; flex-shrink: 0;">
<div class="rpg-user-info-row">
<img src="${userPortrait}" alt="${userName}" class="rpg-user-portrait" onerror="this.style.opacity='0.5';this.onerror=null;" />
<span class="rpg-user-name">${userName}</span>
<span style="opacity: 0.5;">|</span>
<span class="rpg-level-label">LVL</span>
<span class="rpg-level-value rpg-editable" contenteditable="true" data-field="level" title="Click to edit level">${extensionSettings.level}</span>
</div>
<div class="rpg-stats-grid">
<div class="rpg-stat-row">
@@ -236,4 +240,30 @@ export function renderUserStats() {
saveChatData();
updateMessageSwipeData();
});
// Add event listener for level editing
$('.rpg-level-value.rpg-editable').on('blur', function() {
let value = parseInt($(this).text().trim());
if (isNaN(value) || value < 1) {
value = 1;
}
// Set reasonable max level
value = Math.min(100, value);
extensionSettings.level = value;
saveSettings();
saveChatData();
updateMessageSwipeData();
// Re-render to update the display
renderUserStats();
});
// Prevent line breaks in level field
$('.rpg-level-value.rpg-editable').on('keydown', function(e) {
if (e.key === 'Enter') {
e.preventDefault();
$(this).blur();
}
});
}