From 33af492456de485b5be45b745de4cdb886005a88 Mon Sep 17 00:00:00 2001 From: myhloli Date: Wed, 27 May 2026 16:42:15 +0800 Subject: [PATCH] feat: add client-side title leveling option and integrate regeneration of title leveled outputs --- mineru/cli/gradio_app.py | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/mineru/cli/gradio_app.py b/mineru/cli/gradio_app.py index 1157c9d6..debd8955 100644 --- a/mineru/cli/gradio_app.py +++ b/mineru/cli/gradio_app.py @@ -39,6 +39,7 @@ from mineru.cli.common import ( ) from mineru.cli import api_client as _api_client from mineru.cli.output_paths import resolve_parse_dir +from mineru.cli.title_level_postprocess import regenerate_title_leveled_outputs from mineru.cli.vlm_preload import resolve_gradio_local_api_cli_args from mineru.cli.visualization import VisualizationJob, run_visualization_job @@ -827,6 +828,11 @@ def is_image_analysis_option_visible(backend): return backend.startswith("vlm") or backend.startswith("hybrid") +def should_use_client_side_title_leveling(file_suffix, client_side_title_leveling): + """判断当前 Gradio 任务是否需要执行客户端标题分级后处理。""" + return client_side_title_leveling and file_suffix not in office_suffixes + + def create_gradio_run_paths(file_path, output_root="./output"): run_id = f"{time.strftime('%y%m%d_%H%M%S')}_{uuid.uuid4().hex[:8]}_{safe_stem(Path(file_path).stem)}" run_root = Path(output_root) / "gradio" / run_id @@ -959,6 +965,7 @@ async def _run_to_markdown_job( backend="pipeline", url=None, api_url=None, + client_side_title_leveling=False, status_callback: Callable[[str], None] | None = None, ): if file_path is None: @@ -971,6 +978,10 @@ async def _run_to_markdown_job( normalized_language = normalize_language(language) file_path = str(file_path) file_suffix = Path(file_path).suffix.lower().lstrip('.') + use_client_side_title_leveling = should_use_client_side_title_leveling( + file_suffix, + client_side_title_leveling, + ) parse_method = resolve_parse_method(file_path, is_ocr, backend) run_root, extract_root, archive_zip_path = create_gradio_run_paths(file_path) run_root.mkdir(parents=True, exist_ok=True) @@ -985,10 +996,10 @@ async def _run_to_markdown_job( server_url=url, start_page_id=0, end_page_id=end_pages - 1, - return_md=True, + return_md=not use_client_side_title_leveling, return_middle_json=True, - return_model_output=True, - return_content_list=True, + return_model_output=not use_client_side_title_leveling, + return_content_list=not use_client_side_title_leveling, return_images=True, response_format_zip=True, return_original_file=True, @@ -1062,6 +1073,9 @@ async def _run_to_markdown_job( parse_method, allow_office_fallback=True, ) + if use_client_side_title_leveling: + regenerate_title_leveled_outputs(local_md_dir, file_name) + preview_pdf_path = maybe_generate_local_preview( extract_root=extract_root, file_name=file_name, @@ -1101,6 +1115,7 @@ async def stream_to_markdown( backend="pipeline", url=None, api_url=None, + client_side_title_leveling=False, ): status_state = StatusPanelState() job_task: asyncio.Task | None = None @@ -1130,6 +1145,7 @@ async def stream_to_markdown( backend=backend, url=url, api_url=api_url, + client_side_title_leveling=client_side_title_leveling, status_callback=enqueue_status, ) ) @@ -1489,6 +1505,13 @@ def update_doc_show(file_path): help="Preload the local VLM model when gradio starts a local mineru-api service.", default=False, ) +@click.option( + '--client-side-title-leveling', + 'client_side_title_leveling', + type=bool, + help="Enable local title leveling after receiving finalized PDF middle json from the API service.", + default=False, +) @click.option( '--latex-delimiters-type', 'latex_delimiters_type', @@ -1501,7 +1524,8 @@ def main(ctx, example_enable, http_client_enable, api_enable, max_convert_pages, - server_name, server_port, api_url, enable_vlm_preload, latex_delimiters_type, **kwargs + server_name, server_port, api_url, enable_vlm_preload, + client_side_title_leveling, latex_delimiters_type, **kwargs ): # 创建 i18n 实例,支持中英文 @@ -1731,6 +1755,7 @@ def main(ctx, backend=backend, url=url, api_url=api_url, + client_side_title_leveling=client_side_title_leveling, ): update = ( render_status_steps_html(update[0], i18n, locale=request_locale),