Repository Analysis

PDFMathTranslate/PDFMathTranslate

[EMNLP 2025 Demo] PDF scientific paper translation with preserved formats - 基于 AI 完整保留排版的 PDF 文档全文双语翻译,支持 Google/DeepL/Ollama/OpenAI 等服务,提供 CLI/GUI/MCP/Docker/Zotero

15.0 Moderate AI signal View on GitHub

Analysis Overview

This report presents the forensic synthetic code analysis of PDFMathTranslate/PDFMathTranslate, a Python project with 35,558 GitHub stars. SynthScan v2.0 examined 11,455 lines of code across 56 source files, recording 128 pattern matches distributed across 11 syntactic categories. The overall adjusted score of 15.0 places this repository in the Moderate AI signal band.

The scanner applied 160+ deterministic lexical heuristics, multi-line block detectors, abstract syntax tree depth profilers, and a cross-file Jaccard similarity matrix to construct a statistically normalised synthetic code estimate. All matches are individually weighted by severity coefficient and contextual multiplier before summation, and the resulting headline score is temporally discounted to account for the repository's development history relative to the commercial emergence of large language model coding tooling (November 2022 onward).

15.0
Adjusted Score
15.0
Raw Score
100%
Time Factor
2026-05-25
Last Push
35.6K
Stars
Python
Language
11.5K
Lines of Code
56
Files
128
Pattern Hits
2026-07-14
Scan Date
0.18
HC Hit Rate

What These Metrics Mean

Adjusted Score
Primary synthetic code indicator. Raw score normalised per 1,000 lines of code and multiplied by the temporal discount factor. This is the definitive comparative metric — use it to rank repositories by AI authorship density.
Raw Score
The unmodified sum of all severity-weighted, context-multiplied pattern match scores before temporal discounting. Reflects the absolute signal strength independent of when the repository was last active.
Time Factor
The temporal discount multiplier (0–100%) applied to the raw score. Repositories last updated before ChatGPT's launch (Nov 2022) receive a 5% factor. Full signal is only assigned to repositories active in the post-adoption era (Jan 2024+).
Pattern Hits
Total count of individual pattern matches across all files and categories. A high hit count with a low score may indicate a very large codebase with isolated AI snippets; a low count with a high score indicates dense, concentrated AI signatures.
HC Hit Rate
High+Critical pattern hits per file, averaged across the repository. This orthogonal signal catches repositories where a few files are densely packed with high-severity AI tells — a strong indicator even when the normalised score appears moderate due to codebase size.
Lines of Code / Files
Total lines and files analysed. The scanner examines 94 file extensions. These denominators are used to normalise the score, enabling fair comparison between repositories of vastly different sizes.

Score History

This chart maps the temporal evolution of the adjusted synthetic code score across successive scan runs. An upward trajectory indicates ongoing incorporation of AI-generated code or expanding LLM-assisted scaffolding; a stable or declining trajectory may reflect active human refactoring, code removal, or the adoption of stricter authorship policies. The dashed secondary line (right axis) independently tracks total raw pattern hit count, which can diverge from the normalised score when codebase size changes significantly between scans.

Severity Breakdown

Classifies detected patterns by their diagnostic confidence and structural impact. CRITICAL patterns (coefficient 10) represent definitive synthetic signatures — hallucinated imports, explicit LLM attribution metadata — virtually never produced by human authors. HIGH (5) indicates strong structural tells such as cross-file repetition or cross-linguistic idioms. MEDIUM (2) covers recognisable conversational padding and AI-specific vocabulary. LOW (1) captures subtle indicators like tautological comments and generic boilerplate that require density to carry independent signal.

CRITICAL 0HIGH 10MEDIUM 6LOW 112

Directory Score Breakdown

This horizontal bar chart decomposes the repository's raw synthetic code score by top-level directory, allowing you to pinpoint precisely which modules or components carry the highest AI authorship density. Directories with disproportionately high scores relative to their size warrant targeted manual review: concentrated AI signatures often trace back to mass-generated configuration layers, auto-ported test suites, LLM-scaffolded boilerplate classes, or entire subsystems authored under heavy copilot assistance. Use this view to prioritise your human code-review effort.

Pattern Findings

The scanner identified 128 distinct pattern matches across 11 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a statistically significant AI authorship indicator. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.

Reading the findings table: The Severity column indicates the diagnostic confidence level (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — comment-context matches receive a ×1.5 weight because LLMs systematically over-annotate. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier as dense clusters constitute far stronger evidence of synthetic authorship than isolated hits.

Hyper-Verbose Identifiers54 hits · 51 pts
SeverityFileLineSnippetContext
LOWtest/test_translator.py52 def test_add_cache_impact_parameters(self):CODE
LOWtest/test_translator.py80 def test_base_translator_throw(self):CODE
LOWtest/test_translator.py94 def test_missing_base_url_raises_error(self):CODE
LOWtest/test_translator.py103 def test_missing_model_raises_error(self):CODE
LOWtest/test_translator.py116 def test_initialization_with_valid_envs(self):CODE
LOWtest/test_translator.py135 def test_default_api_key_fallback(self):CODE
LOWtest/test_kernel.py319 def test_legacy_version_matches_package(self):CODE
LOWtest/test_kernel.py326 def test_experimental_version_is_string(self):CODE
LOWtest/test_kernel.py334 def test_experimental_version_semver_when_available(self):CODE
LOWtest/test_kernel.py17 def test_translate_request_defaults(self):CODE
LOWtest/test_kernel.py29 def test_translate_result_defaults(self):CODE
LOWtest/test_kernel.py37 def test_translate_result_with_paths(self):CODE
LOWtest/test_kernel.py73 def test_get_nonexistent_raises(self):CODE
LOWtest/test_kernel.py79 def test_switch_and_active_name(self):CODE
LOWtest/test_kernel.py90 def test_switch_unavailable_raises(self):CODE
LOWtest/test_kernel.py101 def test_available_filters_correctly(self):CODE
LOWtest/test_kernel.py149 def test_is_available_without_venv(self):CODE
LOWtest/test_kernel.py198 def test_cli_args_vfont_vchar(self):CODE
LOWtest/test_kernel.py226 def test_cli_args_ignore_cache(self):CODE
LOWtest/test_kernel.py245 def test_cli_args_service_model_split(self):CODE
LOWtest/test_kernel.py253 def test_service_name_mapping(self):CODE
LOWtest/test_kernel.py266 def test_request_to_env_maps_envs(self):CODE
LOWtest/test_kernel.py282 def test_request_to_env_service_model(self):CODE
LOWtest/test_kernel.py351 def test_translate_single_file(self, mock_model_inst, mock_onnx, mock_translate):CODE
LOWtest/test_kernel.py370 def test_translate_passes_all_params(CODE
LOWtest/test_kernel.py405 def test_translate_with_prompt_wraps_template(CODE
LOWtest/test_kernel.py434 def test_translate_single_file(self, mock_venv, mock_avail, mock_popen):CODE
LOWtest/test_kernel.py464 def test_translate_subprocess_failure_raises(self, mock_venv, mock_popen):CODE
LOWtest/test_kernel.py488 def test_translate_progress_callback(self, mock_venv, mock_avail, mock_popen):CODE
LOWtest/test_kernel.py531 def test_all_services_produce_cli_flag(self):CODE
LOWtest/test_kernel.py601 def test_output_defaults_to_input_parent(self):CODE
LOWtest/test_kernel.py611 def test_output_resolved_to_absolute_path(self):CODE
LOWtest/test_kernel.py623 def test_explicit_output_resolved_to_absolute(self):CODE
LOWtest/test_kernel.py643 def test_cli_fast_mode_routes_through_kernel(CODE
LOWtest/test_kernel.py664 def test_cli_precise_mode_routes_through_kernel(CODE
LOWtest/test_kernel.py685 def test_cli_service_model_syntax_passed_through(CODE
LOWtest/test_doclayout.py31 def test_resize_and_pad_image(self):CODE
LOWtest/test_converter.py56 def test_translator_initialization(self):CODE
LOWtest/test_converter.py83 def test_receive_layout_with_complex_formula(self):CODE
LOWtest/test_converter.py98 def test_invalid_translation_service(self):CODE
LOWtest/test_cli.py16 def test_importing_package_does_not_eagerly_load_translation_pipeline(self):CODE
LOWtest/test_cli.py22 def test_version_flag_exits_before_loading_heavy_modules(self):CODE
LOWtest/test_cache.py90 def test_consistent_param_serialization(self):CODE
LOWtest/test_cache.py122 def test_cache_with_sorted_params(self):CODE
LOWpdf2zh/config.py62 def _remove_circular_references(self, obj, seen=None):CODE
LOWpdf2zh/config.py155 def get_env_by_translatername(cls, translater_name, name, default=None):CODE
LOWpdf2zh/pdf2zh.py231def find_all_files_in_directory(directory_path):CODE
LOWpdf2zh/translator.py35def remove_control_characters(s):CODE
LOWpdf2zh/translator.py81 def add_cache_impact_parameters(self, k: str, v):CODE
LOWpdf2zh/translator.py154 def get_rich_text_left_placeholder(self, id: int):CODE
LOWpdf2zh/translator.py157 def get_rich_text_right_placeholder(self, id: int):CODE
LOWpdf2zh/translator.py496 def get_rich_text_left_placeholder(self, id: int):CODE
LOWpdf2zh/translator.py499 def get_rich_text_right_placeholder(self, id: int):CODE
LOWpdf2zh/kernel/v2_worker.py22def _redirect_stdout_to_stderr():CODE
Magic Placeholder Names9 hits · 45 pts
SeverityFileLineSnippetContext
HIGHdocs/PROXY_CONFIGURATION.md22 "GROK_API_KEY": "your-api-key",CODE
HIGHdocs/PROXY_CONFIGURATION.md56 "OPENAILIKED_API_KEY": "your-api-key",CODE
HIGHdocs/PROXY_CONFIGURATION.md70 "OPENAI_API_KEY": "your-api-key",CODE
HIGHdocs/PROXY_CONFIGURATION.md86 -H "Authorization: Bearer your-api-key"CODE
HIGHdocs/PROXY_CONFIGURATION.md168export GROK_API_KEY="your-api-key"CODE
HIGHdocs/PROXY_CONFIGURATION.md189 "GROK_API_KEY": "your-api-key",CODE
HIGHdocs/PROXY_CONFIGURATION.md198 "OPENAILIKED_API_KEY": "your-api-key",CODE
HIGHdocs/ADVANCED.md251 "GROK_API_KEY": "your-api-key",CODE
HIGHdocs/ADVANCED.md310 "GROK_API_KEY": "your-api-key",CODE
Excessive Try-Catch Wrapping21 hits · 22 pts
SeverityFileLineSnippetContext
LOWpdf2zh/pdfinterp.py244 except Exception:CODE
LOWpdf2zh/high_level.py228 except Exception:CODE
LOWpdf2zh/high_level.py353 except Exception as e:CODE
LOWpdf2zh/high_level.py390 except Exception:CODE
LOWpdf2zh/pdf2zh.py317 except Exception:CODE
LOWpdf2zh/pdf2zh.py413 except Exception:CODE
LOWpdf2zh/cache.py89 except Exception as e:STRING
LOWpdf2zh/converter.py419 except Exception:CODE
LOWpdf2zh/converter.py429 except Exception:CODE
LOWpdf2zh/translator.py130 except Exception:CODE
LOWpdf2zh/translator.py395 except Exception as e:CODE
LOWpdf2zh/translator.py917 except Exception:CODE
MEDIUMpdf2zh/translator.py617def do_translate(self, text) -> str:CODE
LOWpdf2zh/gui.py192 except Exception: # filename from urlCODE
MEDIUMpdf2zh/gui.py838 print(f"Error: File '{file_path[1]}' not found.")STRING
MEDIUMpdf2zh/gui.py845 print(f"Error: File '{file_path[0]}' not found.")STRING
LOWpdf2zh/gui.py902 except Exception:CODE
LOWpdf2zh/kernel/v2_worker.py92 except Exception as e:CODE
LOWpdf2zh/kernel/precise.py56 except Exception:CODE
LOWpdf2zh/kernel/precise.py112 except Exception:CODE
LOWpdf2zh/kernel/precise.py172 except Exception:CODE
Modern Structural Boilerplate12 hits · 12 pts
SeverityFileLineSnippetContext
LOWpdf2zh/doclayout.py21logger = logging.getLogger(__name__)CODE
LOWpdf2zh/doclayout.py32def set_backend(name: str) -> None:CODE
LOWpdf2zh/high_level.py36logger = logging.getLogger(__name__)CODE
LOWpdf2zh/pdf2zh.py18logger = logging.getLogger(__name__)CODE
LOWpdf2zh/cache.py9logger = logging.getLogger(__name__)CODE
LOWpdf2zh/__init__.py7__all__ = ["translate", "translate_stream"]CODE
LOWpdf2zh/converter_docx.py9logger = logging.getLogger(__name__)CODE
LOWpdf2zh/translator.py32logger = logging.getLogger(__name__)CODE
LOWpdf2zh/gui.py52logger = logging.getLogger(__name__)CODE
LOWpdf2zh/kernel/legacy.py12logger = logging.getLogger(__name__)CODE
LOWpdf2zh/kernel/__init__.py12__all__ = ["KernelRegistry"]CODE
LOWpdf2zh/kernel/precise.py17logger = logging.getLogger(__name__)CODE
Deep Nesting10 hits · 10 pts
SeverityFileLineSnippetContext
LOWpdf2zh/pdfinterp.py67CODE
LOWpdf2zh/pdfinterp.py301CODE
LOWpdf2zh/config.py155CODE
LOWpdf2zh/high_level.py72CODE
LOWpdf2zh/high_level.py171CODE
LOWpdf2zh/high_level.py304CODE
LOWpdf2zh/converter.py170CODE
LOWpdf2zh/gui.py172CODE
LOWpdf2zh/kernel/v2_worker.py36CODE
LOWpdf2zh/kernel/precise.py122CODE
Unused Imports9 hits · 8 pts
SeverityFileLineSnippetContext
LOWtest/test_kernel.py336CODE
LOWpdf2zh/pdf2zh.py6CODE
LOWpdf2zh/translator.py926CODE
LOWpdf2zh/kernel/v2_bridge.py8CODE
LOWpdf2zh/kernel/legacy.py3CODE
LOWpdf2zh/kernel/registry.py3CODE
LOWpdf2zh/kernel/protocol.py3CODE
LOWpdf2zh/kernel/v2_worker.py13CODE
LOWpdf2zh/kernel/precise.py3CODE
Self-Referential Comments3 hits · 7 pts
SeverityFileLineSnippetContext
MEDIUMtest/test_doclayout.py32 # Create a dummy image (100x200)COMMENT
MEDIUMtest/test_doclayout.py62 # Create a dummy imageCOMMENT
MEDIUMpdf2zh/gui.py567# The following code creates the GUISTRING
Redundant / Tautological Comments3 hits · 6 pts
SeverityFileLineSnippetContext
LOWpdf2zh/pdf2zh.py238 # Check if the provided path is a directoryCOMMENT
LOWpdf2zh/pdf2zh.py247 # Check if the file is a PDFCOMMENT
LOWpdf2zh/gui.py123# Check if this is a public demo, which has resource limitsCOMMENT
Cross-Language Confusion1 hit · 5 pts
SeverityFileLineSnippetContext
HIGHpdf2zh/pdfinterp.py364 self.push(obj)CODE
AI Structural Patterns4 hits · 4 pts
SeverityFileLineSnippetContext
LOWpdf2zh/high_level.py72CODE
LOWpdf2zh/high_level.py171CODE
LOWpdf2zh/high_level.py304CODE
LOWpdf2zh/converter.py133CODE
Over-Commented Block2 hits · 2 pts
SeverityFileLineSnippetContext
LOWtest/test_cache.py161 # cache_instance = cache.TranslationCache("test_engine")COMMENT
LOWtest/test_cache.py181 # # Read operation - verify our own writeCOMMENT