cleanup title and formatting

This commit is contained in:
2026-01-20 22:14:33 -05:00
parent 96223b81e6
commit e66df13edd
2 changed files with 173 additions and 86 deletions

View File

@@ -129,19 +129,19 @@ export function dungeonTemplate(data) {
page-break-inside: avoid;
}
.room h3 {
margin: 0.1em 0 0.05em;
font-size: 0.95em;
margin: 0.08em 0 0.03em;
font-size: 0.9em;
font-weight: bold;
color: #1a1a1a;
}
.room p {
margin: 0 0 0.25em;
font-size: 0.85em;
margin: 0 0 0.15em;
font-size: 0.8em;
font-weight: normal;
line-height: 1.3em;
line-height: 1.25em;
}
.encounter, .npc, .treasure, .plot-resolution {
margin: 0 0 0.35em;
margin: 0 0 0.25em;
break-inside: avoid;
page-break-inside: avoid;
font-size: 0.85em;
@@ -252,14 +252,54 @@ export function dungeonTemplate(data) {
${data.randomEvents && data.randomEvents.length > 0 ? `
<div class="section-block random-events">
<h2>Random Events (d6)</h2>
<table>
<table class="encounters-table">
<tbody>
${data.randomEvents.map((event, index) => `
${data.randomEvents.map((event, index) => {
// Handle both object format {name, description} and string format
let eventName = '';
let eventDesc = '';
if (typeof event === 'object' && event.name && event.description) {
eventName = event.name;
eventDesc = event.description;
} else if (typeof event === 'string') {
// Try to parse "Event Name: Description" format
const colonMatch = event.match(/^([^:]+):\s*(.+)$/);
if (colonMatch) {
eventName = colonMatch[1].trim();
eventDesc = colonMatch[2].trim();
} else {
// Fallback: use first few words as name, rest as description
const words = event.split(/\s+/);
if (words.length > 3) {
eventName = words.slice(0, 2).join(' ');
eventDesc = words.slice(2).join(' ');
} else {
eventName = `Event ${index + 1}`;
eventDesc = event;
}
}
} else {
eventName = `Event ${index + 1}`;
eventDesc = String(event || '');
}
// Truncate description to prevent overflow (similar to encounters)
if (eventDesc.length > 200) {
eventDesc = eventDesc.substring(0, 197).trim();
const lastPeriod = eventDesc.lastIndexOf('.');
if (lastPeriod > 150) {
eventDesc = eventDesc.substring(0, lastPeriod + 1);
} else {
eventDesc += '...';
}
}
return `
<tr>
<td>${index + 1}</td>
<td>${escapeHtml(event)}</td>
<td><strong>${escapeHtml(eventName)}</strong></td>
<td>${escapeHtml(eventDesc)}</td>
</tr>
`).join('')}
`;
}).join('')}
</tbody>
</table>
</div>
@@ -270,16 +310,16 @@ export function dungeonTemplate(data) {
<h2>Locations</h2>
${data.rooms.map(room => {
let desc = room.description || '';
// Truncate to 2 sentences max
// Truncate to 1 sentence max to prevent overflow
const sentences = desc.match(/[^.!?]+[.!?]+/g) || [desc];
if (sentences.length > 2) {
desc = sentences.slice(0, 2).join(' ').trim();
if (sentences.length > 1) {
desc = sentences.slice(0, 1).join(' ').trim();
}
// Also limit by character count (~150 chars)
if (desc.length > 150) {
desc = desc.substring(0, 147).trim();
// Also limit by character count (~100 chars for tighter fit)
if (desc.length > 100) {
desc = desc.substring(0, 97).trim();
const lastPeriod = desc.lastIndexOf('.');
if (lastPeriod > 100) {
if (lastPeriod > 70) {
desc = desc.substring(0, lastPeriod + 1);
} else {
desc += '...';
@@ -347,9 +387,7 @@ export function dungeonTemplate(data) {
</table>
</div>
` : ''}
</div>
<div class="col">
${data.treasure && data.treasure.length > 0 ? `
<div class="section-block">
<h2>Treasure</h2>
@@ -368,7 +406,9 @@ export function dungeonTemplate(data) {
}).filter(Boolean).join('')}
</div>
` : ''}
</div>
<div class="col">
${data.npcs && data.npcs.length > 0 ? `
<div class="section-block">
<h2>NPCs</h2>
@@ -392,19 +432,19 @@ export function dungeonTemplate(data) {
<div class="section-block">
<h2>Plot Resolutions</h2>
${data.plotResolutions.map(resolution => {
// Truncate to 2 sentences max to prevent overflow
// Truncate to 1 sentence max to prevent overflow (more aggressive)
let text = resolution || '';
// Split into sentences and keep only first 2
// Split into sentences and keep only first 1
const sentences = text.match(/[^.!?]+[.!?]+/g) || [text];
if (sentences.length > 2) {
text = sentences.slice(0, 2).join(' ').trim();
if (sentences.length > 1) {
text = sentences.slice(0, 1).join(' ').trim();
}
// Also limit by character count as fallback (max ~150 chars)
if (text.length > 150) {
text = text.substring(0, 147).trim();
// Also limit by character count as fallback (max ~120 chars for tighter fit)
if (text.length > 120) {
text = text.substring(0, 117).trim();
// Try to end at a sentence boundary
const lastPeriod = text.lastIndexOf('.');
if (lastPeriod > 100) {
if (lastPeriod > 90) {
text = text.substring(0, lastPeriod + 1);
} else {
text += '...';