diff --git a/olmocr/bench/report.py b/olmocr/bench/report.py index 16547ee..939d38e 100644 --- a/olmocr/bench/report.py +++ b/olmocr/bench/report.py @@ -13,7 +13,7 @@ def generate_html_report( test_results_by_candidate: Dict[str, Dict[str, Dict[int, List[Tuple[BasePDFTest, bool, str]]]]], pdf_folder: str, output_file: str ) -> None: """ - Generate an enhanced HTML report of test results. + Generate a simple static HTML report of test results. Args: test_results_by_candidate: Dictionary mapping candidate name to dictionary mapping PDF name to dictionary @@ -30,590 +30,198 @@ def generate_html_report( OLMOCR Bench Test Report - - - -
-
-

OLMOCR Bench Test Report

-
-
- -
-
-

Summary

- - - - - - - - - - - +

OLMOCR Bench Test Report

""" - # Calculate summary statistics for each candidate - print("Calculating summary statistics...") + # Process all candidates + print("Generating test report...") for candidate in candidates: - total_tests = 0 - passed_tests = 0 + html += f"

Candidate: {candidate}

\n" - for pdf_name in test_results_by_candidate[candidate]: - for page in test_results_by_candidate[candidate][pdf_name]: - for test, passed, _ in test_results_by_candidate[candidate][pdf_name][page]: - total_tests += 1 - if passed: - passed_tests += 1 + # Get all PDFs for this candidate + all_pdfs = sorted(test_results_by_candidate[candidate].keys()) - failed_tests = total_tests - passed_tests - pass_rate = (passed_tests / total_tests * 100) if total_tests > 0 else 0 - - html += f""" - - - - - - -""" - - html += """ -
CandidatePass RatePassed TestsFailed TestsTotal Tests
{candidate}{pass_rate:.1f}%{passed_tests}{failed_tests}{total_tests}
-
- -
-""" - - # Create tabs for each candidate - for i, candidate in enumerate(candidates): - html += f"""
{candidate}
-""" - - html += """
-""" - - # Create content for each candidate - print("Generating candidate content...") - for i, candidate in enumerate(candidates): - html += f"""
-""" - - all_pdfs = set() - for c in test_results_by_candidate.values(): - all_pdfs.update(c.keys()) - - for pdf_name in tqdm(sorted(all_pdfs), desc="Rendering report pages"): - if pdf_name not in test_results_by_candidate[candidate]: - continue - - html += f"""

PDF: {pdf_name}

-""" - - # Create page tabs for this PDF + for pdf_name in tqdm(all_pdfs, desc=f"Processing {candidate}"): pages = sorted(test_results_by_candidate[candidate][pdf_name].keys()) - html += f"""
-""" - for j, page in enumerate(pages): - html += f"""
- Page {page} -
-""" - html += """
-""" - - # Create content for each page - for j, page in enumerate(pages): - html += f"""
-
-
-

PDF Page {page}

-""" - - # Convert PDF page to embedded image - pdf_path = os.path.join(pdf_folder, pdf_name) - try: - image_data = render_pdf_to_base64webp(pdf_path, page, 2048) - html += f""" PDF Page {page} -""" - except Exception as e: - html += f"""
Error rendering PDF: {str(e)}
-""" - - html += """
-
-

Tests for Page {page}

-""" - - # Get the Markdown file and content for this page - md_file_path = None - md_content = None - try: - md_base = os.path.splitext(pdf_name)[0] - md_files = list(glob.glob(os.path.join(os.path.dirname(pdf_folder), candidate, f"{md_base}_pg{page}_repeat*.md"))) - if md_files: - md_file_path = md_files[0] # Use the first repeat as an example - with open(md_file_path, "r", encoding="utf-8") as f: - md_content = f.read() - except Exception as e: - md_content = f"Error loading Markdown content: {str(e)}" - - # Add a button to toggle the Markdown content display - if md_content: - html += f""" - -""" + for page in pages: + # Get tests for this PDF page tests = test_results_by_candidate[candidate][pdf_name][page] + for test, passed, explanation in tests: result_class = "pass" if passed else "fail" + status_text = "PASSED" if passed else "FAILED" + status_class = "pass-status" if passed else "fail-status" - # Start test div - html += f"""
-
-
Test ID: {test.id}
-
{test.type}
- {'Passed' if passed else 'Failed'} -
+ # Begin test block + html += f""" +
+

Test ID: {test.id} {status_text}

+

PDF: {pdf_name} | Page: {page} | Type: {test.type}

+ +
""" - # Add specific test details based on test type + # Add test details based on type test_type = getattr(test, "type", "").lower() - if test_type == "present" and hasattr(test, "text"): text = getattr(test, "text", "") - html += f"""
Text to find: "{text[:100]}{"..." if len(text) > 100 else ""}"
-""" + html += f"""

Text to find: "{text}"

\n""" elif test_type == "absent" and hasattr(test, "text"): text = getattr(test, "text", "") - html += f"""
Text should not appear: "{text[:100]}{"..." if len(text) > 100 else ""}"
-""" + html += f"""

Text should not appear: "{text}"

\n""" elif test_type == "order" and hasattr(test, "before") and hasattr(test, "after"): before = getattr(test, "before", "") after = getattr(test, "after", "") - html += f"""
Text order: "{before[:50]}{"..." if len(before) > 50 else ""}" should appear before "{after[:50]}{"..." if len(after) > 50 else ""}"
-""" + html += f"""

Text order: "{before}" should appear before "{after}"

\n""" elif test_type == "table": if hasattr(test, "cell"): cell = getattr(test, "cell", "") - html += f"""
Table cell: "{cell}"
-""" + html += f"""

Table cell: "{cell}"

\n""" if hasattr(test, "up") and getattr(test, "up", None): up = getattr(test, "up") - html += f"""
Above: "{up}"
-""" + html += f"""

Above: "{up}"

\n""" if hasattr(test, "down") and getattr(test, "down", None): down = getattr(test, "down") - html += f"""
Below: "{down}"
-""" + html += f"""

Below: "{down}"

\n""" if hasattr(test, "left") and getattr(test, "left", None): left = getattr(test, "left") - html += f"""
Left: "{left}"
-""" + html += f"""

Left: "{left}"

\n""" if hasattr(test, "right") and getattr(test, "right", None): right = getattr(test, "right") - html += f"""
Right: "{right}"
-""" + html += f"""

Right: "{right}"

\n""" elif test_type == "math" and hasattr(test, "math"): math = getattr(test, "math", "") - html += f"""
Math equation:
-
-""" + html += f"""

Math equation: {math}

\n""" + + html += """
\n""" # Add explanation for failed tests if not passed: - html += f"""
Explanation: {explanation}
-""" + html += f"""
+ Explanation: {explanation} +
\n""" - html += """
-""" + # Render PDF page + pdf_path = os.path.join(pdf_folder, pdf_name) + try: + html += """

PDF Render:

\n""" + image_data = render_pdf_to_base64webp(pdf_path, page, 1024) + html += f""" PDF Page {page}\n""" + except Exception as e: + html += f"""

Error rendering PDF: {str(e)}

\n""" - html += """
-
-
-""" + # Get the Markdown content for this page + md_content = None + try: + md_base = os.path.splitext(pdf_name)[0] + md_files = list(glob.glob(os.path.join(os.path.dirname(pdf_folder), candidate, f"{md_base}_pg{page}_repeat*.md"))) + if md_files: + md_file_path = md_files[0] # Use the first repeat as an example + with open(md_file_path, "r", encoding="utf-8") as f: + md_content = f.read() + except Exception as e: + md_content = f"Error loading Markdown content: {str(e)}" - html += """
-""" + if md_content: + html += """

Markdown Content:

\n""" + html += f"""
{md_content}
\n""" - html += """
- - - + # End test block + html += """
\n""" + + # Add separator between pages + html += """
\n""" + + # Close HTML + html += """ """ with open(output_file, "w", encoding="utf-8") as f: f.write(html) - print(f"Enhanced HTML report generated: {output_file}") + print(f"Simple HTML report generated: {output_file}") diff --git a/olmocr/version.py b/olmocr/version.py index 6aed28e..3e5d004 100644 --- a/olmocr/version.py +++ b/olmocr/version.py @@ -2,7 +2,7 @@ _MAJOR = "0" _MINOR = "1" # On main and in a nightly release the patch should be one ahead of the last # released build. -_PATCH = "65" +_PATCH = "66" # This is mainly for nightly builds which have the suffix ".dev$DATE". See # https://semver.org/#is-v123-a-semantic-version for the semantics. _SUFFIX = ""