SuperAPI AI Directory

ocr_kb

Writing & research

View repository

Updated 10-16 10:19

About this skill

Complete Workflow for Paper Typesetting and Organization (Iterative OCR & Typesetting Pipeline)

0. Directory Convention

All intermediate files and final artifacts must strictly follow the directory structure below,Placing any generated files in the project root directory is prohibited:

项目根目录/
├── resources/
│   ├── pages/          # 切分出的单页 PNG 图片
│   ├── figures/        # 从页面中裁剪出的独立科研配图(全局编号)
│   ├── md/             # 每页的 Markdown 提取结果 (page_1.md, page_2.md, ...)
│   ├── scripts/        # 所有 Python 辅助脚本(可跨任务复用,清理时不删除)
│   ├── compiled_paper.md  # 最终汇总的完整 Markdown
│   ├── config.json     # 任务配置(源 PDF、格式规范),整个任务期间不变
│   └── checkpoint.json # 运行时进度(当前页、计数器、失败页),随处理更新
├── outputs/
│   ├── <name>_checkpoint_p<N>.docx   # 核查点中间版本
│   └── <name>_final_<date>.docx      # 最终交付版本
├── ocr_kb/
│   └── SKILL.md        # 本文件
└── <source>.pdf        # 用户提供的原始 PDF

0.5 resources/config.json Specification (Task Configuration)

Created at the start of each new task,not modified throughout the entire task. When continuing work, read it directly. All pipelines share the same schema.

{
  "source_file": "2103.10360v2.pdf",
  "source_type": "pdf",
  "pipeline": "A",
  "format_style": "IEEE",
  "template_file": null,
  "total_units": 16,
  "unit_type": "page",
  "created_at": "2026-04-02T13:00:00+08:00"
}
Field Description
source_file Source file name specified by the user (PDF / DOC / DOCX / MD)
source_type File type:"pdf" / "doc" / "docx" / "md"
pipeline Pipeline type:"A"(OCR)/ "B"(re-typesetting) / "C"(direct MD conversion)
format_style Typesetting format (IEEE / APA / user-defined / ...)
template_file User-provided .docx template path, or if none, null
total_units Total number of processing units (Pipeline A = number of pages, Pipeline B/C = number of sections)
unit_type Progress unit:"page"(Pipeline A)/ "section"(Pipeline B/C)
created_at Task creation time

[!NOTE] Pipeline A always uses source_type: "pdf", pipeline: "A", unit_type: "page"。


0.6 resources/checkpoint.json Specification (Runtime Checkpoint)

Updated after each completed unit (page or section) of extraction + DOCX append. **This is the sole basis for checkpoint recovery.** All pipelines share the same schema.

{
  "current_unit": 7,
  "unit_type": "page",
  "last_verified_unit": 6,
  "total_units": 16,
  "docx_path": "outputs/GLM_checkpoint_p6.docx",
  "global_figure_count": 4,
  "global_table_count": 2,
  "global_equation_count": 15,
  "needs_review": [3],
  "completed_units": [1, 2, 3, 4, 5, 6],
  "status": "suspended"
}
Field Description
current_unit Number of the next unit to process
unit_type Unit type:"page"(Pipeline A)/ "section"(Pipeline B/C)
last_verified_unit Number of the last unit that passed quality check
total_units Total number of units (synchronized from config.json)
docx_path Path to the current latest intermediate DOCX version
global_figure_count Global figure counter (only increases, never decreases)
global_table_count Global table counter (only increases, never decreases)
global_equation_count Global formula counter (only increases, never decreases)
needs_review List of unit numbers marked as "needs review"
completed_units List of unit numbers whose extraction has been completed
status "running" / "suspended" / "completed"

Update timing(taking Pipeline A as an example; B/C replace "page" with "section"):

  • Each time a unit is completed: update current_unit、completed_units, counters
  • After every 2 units are checked: update last_verified_unit
  • If a problem is found during quality check: add the unit number to needs_review add the unit number
  • Before suspending every 4 units: set status = "suspended", save the intermediate DOCX version
  • After all are completed: set status = "completed"

Pipeline A intermediate version naming: use _checkpoint_p<N> to indicate the page number. Pipeline B/C use _checkpoint_s<N> to indicate the section.


0.7 Script Contracts

[!IMPORTANT] If the following scripts already exist in resources/scripts/ ,reuse them directly; do not regenerate them. Create them only when they do not exist, and they must strictly follow the interfaces below.

split_pdf.py

用法: python resources/scripts/split_pdf.py <pdf_path> <output_dir> [--dpi 300]
输入: PDF 文件路径,输出目录路径
输出: output_dir/page_1.png, page_2.png, ..., page_N.png
退出码: 0 成功,非 0 失败
stdout: 最后一行输出 "TOTAL_PAGES=N"

extract_figures.py

用法: python resources/scripts/extract_figures.py <page_image> <page_num> <coords_json> <output_dir> <start_index>
输入:
  - page_image: 单页 PNG 路径
  - page_num: 页码(用于日志)
  - coords_json: JSON 字符串,格式 [{"x0%": 10, "y0%": 30, "x1%": 90, "y1%": 70, "caption": "Figure N: ..."}]
  - output_dir: 输出目录
  - start_index: 全局起始编号(从 checkpoint.global_figure_count + 1 开始)
输出: output_dir/figure_<start_index>.png, figure_<start_index+1>.png, ...
退出码: 0 成功,非 0 失败
stdout: 最后一行输出 "FIGURES_EXTRACTED=K"

generate_docx.py

用法: python resources/scripts/generate_docx.py <compiled_md> <config_json> <output_path>
输入:
  - compiled_md: 汇总后的 Markdown 文件路径
  - config_json: 任务配置文件路径(读取 format_style 等信息)
  - output_path: 输出 DOCX 文件路径
输出: 指定路径的 .docx 文件
退出码: 0 成功,非 0 失败

latex_to_omml.py

用法: python ocr_kb/scripts/latex_to_omml.py <latex_string> [--inline]
输入:
  - latex_string: LaTeX 公式字符串(不含 $ 定界符)
  - --inline: 可选标志,输出行内 <m:oMath> 而非块级 <m:oMathPara>
输出: 标准输出打印完整的 OMML XML 片段
  - 无 --inline时: <m:oMathPara>...</m:oMathPara>
  - 有 --inline时: <m:oMath>...</m:oMath>
退出码: 0 成功,非 0 失败
stderr: 转换失败时输出错误信息(不支持的 LaTeX 命令等)
支持范围: 基础运算、分式(\frac)、上下标、根号(\sqrt)、
  希腊字母、求和/积分(\sum/\int)、矩阵(\matrix/\pmatrix)、
  常用数学符号(\leq/\geq/\neq/\approx/\infty 等)

[!NOTE] This script is located in ocr_kb/scripts/(not in resources/scripts/), because it is a tool built into the Skill rather than a temporary script generated by the task. All pipelines share this script.


1. Page-by-Page Close Reading and Append Writing (Page-by-Page Extraction)

For each single-page image that has been split (resources/pages/page_N.png), perform the following operations:

1.1 Plain Text Reading

Read the image closely page by page using visual capabilities, and extract the text exactly as it is.

[!CAUTION] Heading Format Specification: Never retain redundant or incorrect Markdown heading symbols in the text (such as #### 3.2.3). When the DOCX is finally generated, the formatting script will automatically map to the target template (such as IEEE's Roman numerals I, II, A, B, etc.). The extracted Markdown must use extremely clean # levels (such as ## for level-one headings,### for level-two headings),absolutely forbiddenfor the original document's old numbering or redundant # symbols to remain in the final body text.

1.2 Formula Transcription

Standalone formulas or inline formulas on the page (including individual mathematical symbols in tables and figure captions such as $d_{model}$),mustall be read into standard LaTeX syntax (use $ $for inline, use $$ $$for standalone blocks). Each standalone formula increments checkpoint.json of global_equation_count。

[!IMPORTANT] This is to ensure that when the DOCX is finally generated, the Python script can precisely capture these two types of boundaries through regular expressions and call latex_to_omml.py to mount them all as native Word OMML formulas (<m:oMath> or <m:oMathPara>). Never omit the wrapping of variables, otherwise they can only be rendered as plain text.

1.3 Illustration Recognition and Intelligent Cropping

[!IMPORTANT] Forbiddento directly insert a full-page screenshot as an image into Markdown. It is necessary toprecisely identify and crop out independent scientific figures。

Specific process:

  1. Identify: When visually reading the current page, determine whether there is an independent scientific figure (Figure) or an independent table image (Table presented in image form) on the page.
  2. Locate: Determine the approximate percentage coordinates of the figure's position on the page (x0%, y0%, x1%, y1%)。
  3. Global numbering: From checkpoint.json read global_figure_count, new figures on this page start numbering from global_figure_count + 1 . After cropping is complete, update global_figure_count. Tables likewise use global_table_count。
  4. Crop: Use resources/scripts/extract_figures.py or PyMuPDF 's page.get_pixmap(clip=Rect(...)) method to crop from the high-resolution page rendering according to the coordinatesseparatefigures, and save them to resources/figures/figure_N.png(N is the global number).
  5. Reference: In Markdown, use the path of the cropped independent image:
    ![Figure 4: 图注说明](resources/figures/figure_4.png)
    

1.4 Write

Write the extraction result of the current page to resources/md/page_N.md。

1.5 Update Checkpoint

After each page_N.md is written and appended to the DOCX, immediately update checkpoint.json:

  • current_unit += 1
  • completed_units add the current page number
  • Update global_figure_count / global_table_count / global_equation_count

2. Page-by-Page DOCX Generation and Two-Page Verification (Incremental DOCX Generation)

[!IMPORTANT] No longer wait until all pages have been extracted to generate the DOCX all at once.As soon as the extraction of one page of MD is completed, immediately append that page's content to the DOCX file being built。

2.1 Single-Page Process

读一页图片 → 写 page_N.md → 将 page_N.md 内容追加到 DOCX → 更新 checkpoint.json

2.2 Two-page verification (every 2 pages)

After completing the DOCX append of every 2 pages, aself-check verification:

  1. Review the typesetting effect of the 2 pages just appended in the DOCX (fonts, formulas, figure placement, heading levels).
  2. Compare against the original page images to confirm there is no information loss or formatting corruption.
  3. Verification passed: update checkpoint.json in last_verified_unit。
  4. Verification failed:
    • in checkpoint.json 's needs_review array, record the problematic page numbers.
    • Try to fix immediately. If the fix succeeds, remove the page number from needs_review .
    • If it cannot be fixed,do not block subsequent page processing, but before the final summary needs_review must be cleared to zero.

2.3 Context limit protection

  • After continuously processing 4 pages, you must actively suspend:
    1. Set checkpoint.json 's status to "suspended"。
    2. Save the current intermediate DOCX version to outputs/(naming rules see §2.4).
    3. Use notify_user to notify the user to send "continue" to refresh the context window.
  • After resuming, read checkpoint.json, and continue from current_unit .

2.4 Intermediate version naming rules

Type Naming format Example
Checkpoint intermediate version outputs/<原文件名>_checkpoint_p<最后完成页码>.docx outputs/GLM_checkpoint_p6.docx
Final delivery version outputs/<原文件名>_final_<YYYYMMDD>.docx outputs/GLM_final_20260402.docx

[!NOTE] Each time a new checkpoint version is saved,keep the previous versiondo not delete it, so that you can roll back if problems occur.


3. Final Typesetting

3.1 needs_review zero-clearing check

Before entering finalization, check checkpoint.json 's needs_review:

  • is not empty: list all page numbers pending review, re-verify and fix them page by page. Only continue after all are fixed.
  • is empty: proceed directly to the summary.

3.2 Summary

Merge resources/md/page_1.md ~ page_N.md in order into resources/compiled_paper.md。

3.3 Generate the final DOCX

Use resources/scripts/generate_docx.py, according to config.json generate the final typesetting file with the format specification specified in it, and save it to outputs/。

3.4 Applying typesetting formats

Typesetting parameters are read from config.json 's format_params (parsed and written at startup by the main SKILL.md §2.2).

The complete parameter tables for specific format presets (IEEE / APA / Chinese dissertations, etc.) are defined inmain SKILL.md §6 Typesetting Format Specification Libraryand are not repeated in this file.

DOCX generation method for Pipeline A: Use docx/SKILL.md use docx-js to create a new document, or use the unpack-edit-pack method to edit based on a template.

For detailed typesetting rules on images, tables, headers and footers, columns, and formulas, seemain SKILL.md §5 General Typesetting Rules。

3.5 Update Checkpoint

Set checkpoint.json 's status = "completed", and record the final file path.


4. Execution Triggers

4.1 New Task

When the user sends "format this PDF according to a certain format" (the main SKILL.md routes to Pipeline A):

  1. Cleanup confirmation: Perform environment cleanup confirmation per main SKILL.md §1.1.
  2. Select source file: Per main SKILL.md §1.2, confirm the source PDF and select Pipeline A.
  3. Create configuration: Write resources/config.json(pipeline: "A", unit_type: "page")。
  4. Split images: Run resources/scripts/split_pdf.py。
  5. Establish progress: Create resources/checkpoint.json(current_unit = 1, unit_type: "page", all counters reset to zero).
  6. Page-by-page loop: Execute per §1 and §2.
  7. Aggregate and finalize: Execute per §3.
  8. Output report: Output the completion report per main SKILL.md §5.

4.2 Resume from Breakpoint

When the user sends "continue":

  1. Read resources/checkpoint.json。
  2. From current_unit specified page number, continue the page-by-page loop.
  3. All global counters are restored from the checkpoint and are not reset.

4.3 Partial Rerun

When the user sends "rerun page N" or "rerun page N":

  1. Read resources/checkpoint.json, confirm that page N is in completed_units .
  2. Re-read resources/pages/page_N.png, re-execute the extraction process of §1.
  3. Overwrite resources/md/page_N.md。
  4. Note: If the page has figures, the corresponding figure_*.pngmust be updated, butdo not change the global numbering—reuse the original numbering.
  5. From needs_review remove N (if it exists).
  6. Regenerate the final DOCX (re-execute §3.2 ~ §3.3).

4.4 Batch Rerun

When the user sends "rerun pages X-Y":

Per §4.3, execute a rerun for each page in the range one by one.


5. Completion Report

[!IMPORTANT] After all pages have been processed and the final DOCX has been generated,mustoutput the following summary; it cannot be omitted.

【完成报告】
源文件:<config.source_file>
输入类型:<config.source_type>
处理管道:Pipeline <config.pipeline>
格式规范:<config.format_style>
总单元数:<checkpoint.total_units>(<config.unit_type>)
提取公式数:<checkpoint.global_equation_count>
裁剪配图数:<checkpoint.global_figure_count>
提取表格数:<checkpoint.global_table_count>
核查点版本数:<outputs/ 中 checkpoint 文件的数量>
最终文件:outputs/<最终文件名>.docx
遗留问题:<needs_review 中的单元编号 / 无>