Files
bentopdf/src/js/compare/reporting/build-report.ts
T
alam00000 1d68691331 refactor: update PDF comparison types and enhance UI for better usability
- Refactored CompareState to import from a centralized type definition.
- Enhanced the compare-pdfs.html layout with improved styles for overlay and side-by-side modes.
- Added new CSS styles for various UI components including panels, buttons, and highlights.
- Implemented a new sidebar for displaying change summaries and filters.
- Created unit tests for text comparison logic, including diffing text runs and page pairing.
- Added tests for text normalization functions to ensure proper handling of punctuation and character normalization.
2026-03-08 23:55:33 +05:30

78 lines
2.8 KiB
TypeScript

import type { ComparePagePair, ComparePageResult } from '../types.ts';
function escapeHtml(text: string) {
return text
.replace(/&/g, '&')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#039;');
}
export function buildCompareReport(
fileName1: string,
fileName2: string,
pairs: ComparePagePair[],
results: ComparePageResult[]
) {
const totals = results.reduce(
(summary, result) => {
summary.added += result.summary.added;
summary.removed += result.summary.removed;
summary.modified += result.summary.modified;
return summary;
},
{ added: 0, removed: 0, modified: 0 }
);
const rows = results
.map((result, index) => {
const pair = pairs[index];
const changes = result.changes
.map(
(change) =>
`<li><strong>${escapeHtml(change.type)}</strong>: ${escapeHtml(change.description)}</li>`
)
.join('');
return `
<section class="pair-card">
<h2>Comparison ${pair?.pairIndex || index + 1}</h2>
<p class="meta">PDF 1 page: ${pair?.leftPageNumber ?? 'none'} | PDF 2 page: ${pair?.rightPageNumber ?? 'none'} | Confidence: ${((pair?.confidence || 0) * 100).toFixed(0)}%</p>
<p class="meta">Status: ${escapeHtml(result.status)}${result.usedOcr ? ' | OCR used' : ''}</p>
<p class="meta">Added: ${result.summary.added} | Removed: ${result.summary.removed} | Modified: ${result.summary.modified}</p>
<ul>${changes || '<li>No semantic changes detected.</li>'}</ul>
</section>
`;
})
.join('');
return `<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Compare report</title>
<style>
body { font-family: ui-sans-serif, system-ui, sans-serif; margin: 0; padding: 2rem; background: #111827; color: #e5e7eb; }
.summary { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1rem; margin: 1.5rem 0; }
.card, .pair-card { background: #1f2937; border: 1px solid #374151; border-radius: 12px; padding: 1rem 1.25rem; }
.pair-card { margin-bottom: 1rem; }
.meta { color: #9ca3af; font-size: 0.95rem; }
h1, h2 { margin: 0 0 0.75rem 0; }
ul { margin: 0.75rem 0 0 1.25rem; }
</style>
</head>
<body>
<h1>PDF Compare Report</h1>
<p class="meta">PDF 1: ${escapeHtml(fileName1)} | PDF 2: ${escapeHtml(fileName2)}</p>
<div class="summary">
<div class="card"><div class="meta">Added</div><div>${totals.added}</div></div>
<div class="card"><div class="meta">Removed</div><div>${totals.removed}</div></div>
<div class="card"><div class="meta">Modified</div><div>${totals.modified}</div></div>
</div>
${rows}
</body>
</html>`;
}