Skip to main content

dof2md

Converts a PDF or a set of scanned page images from Mexico's official gazette (DOF, Diario Oficial de la Federación) — or any other document — into Markdown, optionally cropped down to a single note. It's a wrapper around mineru for the OCR/layout analysis itself; dof2md's own contribution is:

  • Keeping mineru's mineru-api server warm across a batch of documents, instead of paying its startup (and model-loading) cost once per document.
  • Stitching the OCR of a list of page images (several scanned pages of the same note) into one continuous Markdown document.
  • Rewriting the raw HTML tables mineru falls back to (rowspan/colspan) into Markdown tables, so the output is Markdown all the way through.
  • Cropping the result down to a single note, by locating its title and the next note's title in the OCR'd text — useful because a scanned page usually holds the tail of one note and the head of the next.
  • Downloading a DOF edition's PDF directly, by date and edition.

Part of the LegalIA monorepo.

Install

pip install -e ".[test]"

Usage

CLI

dof2md takes exactly one input source — a date, a local PDF, or a set of local page images — and converts it to Markdown, unless --download-only is given with a date, in which case it stops after the download.

Given a date, it downloads that edition's PDF from the DOF site and converts it:

dof2md 2010-01-05                     # morning edition (default)
dof2md 2010-01-05 --edition VES       # evening edition
dof2md 2010-01-05 --outdir my_folder  # output directory

--download-only stops after the download, without converting — useful when only the PDF itself is needed (e.g. to archive it, or convert it later with --pdf):

dof2md 2010-01-05 --download-only     # writes only 05012010-MAT.pdf

This writes <date>-<edition>.pdf and <date>-<edition>.md to the output directory. Since one edition's PDF holds every note published that day, --titulo/--titulo-siguiente crop the resulting Markdown down to just one note — its own title, and the next note's title, as they appear in the gazette's own index:

dof2md 2010-01-05 \
    --titulo "ACUERDO por el que se..." \
    --titulo-siguiente "DECRETO por el que se..."

Title matching is fuzzy (OCR text rarely matches an index title exactly), so a match below --min-confidence (default 0.6) is treated as not found and the crop falls back to keeping more text rather than dropping content. Other flags:

  • --keep-pages — also keep the uncropped Markdown, as <outdir>/<pdf stem>.full.md.
  • --keep-mineru-output — keep mineru's own raw output (layout/model JSON, rendered PDFs...) in <outdir>/<pdf stem>_mineru/ instead of discarding it; useful when a conversion looks wrong and mineru's own read of the page is the first thing worth inspecting.

A date always downloads from the DOF site; to convert a document you already have, use --pdf or --images instead — no download involved:

dof2md --pdf edicion.pdf   # a local PDF

dof2md --images pagina-1.jpg pagina-2.jpg \
    --filename out.md      # scanned pages, in order

--filename sets the output Markdown's name; with --pdf it defaults to the PDF's own name (edicion.pdf → edicion.md), but with --images it's required, since a set of images has no single name to derive one from. --titulo/--titulo-siguiente and the other flags above work the same way regardless of the input source.

Python: batch conversion

Converting many documents in one run is where mineru's startup cost starts to matter. BatchConverter keeps a single mineru-api server warm across the whole batch instead of restarting it per document:

from dof2md import BatchConverter

jobs = [
    ("a.pdf", "output", "a.md"),
    (["b-p1.jpg", "b-p2.jpg"], "output", "b.md"),
]

with BatchConverter() as convert:
    for path_or_paths, outdir, filename in jobs:
        convert(path_or_paths, outdir, filename)

Each call takes a single PDF path, or a list of image paths for a document spanning several scanned pages, and writes the result to outdir/filename. The same titulo/titulo_siguiente, min_confidence, keep_pages and keep_mineru_output options the CLI exposes are also its keyword arguments — see BatchConverter.__call__'s docstring for the full signature.

nota2md.legal_provisions accepts an already-__enter__'d BatchConverter as its own converter parameter, so a batch of DOF legal provisions can share the same warm server too.

Tests

pytest -v

Metadata

Release files for dof2md 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for dof2md 0.2.0
File Size Uploaded
dof2md-0.2.0.tar.gz 25.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for dof2md 0.2.0
File Interpreter ABI Platform
dof2md-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 42.6 kB

Release files / dof2md-0.2.0.tar.gz

Download URL dof2md-0.2.0.tar.gz
Size 25.0 kB
Tags Source
SHA-256 checksum
How to use checksums
6f33a63e4256110dda21561affcb4bf405b1813c61f38db5a85d3968cac0bf92
BLAKE2b-256 checksum
How to use checksums
ba1b654956412a75dc3b8c9c79cb823f28e622d42a291a44051f750d50cdf12a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.14

Release files / dof2md-0.2.0-py3-none-any.whl

Download URL dof2md-0.2.0-py3-none-any.whl
Size 17.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7a13d071992f5e981600ac1eb2f945535620864606fb7e358741fc911335cda7
BLAKE2b-256 checksum
How to use checksums
90848209569d514c5603a7ceade8f1fcfa7b06408c38b528ee23b64d84fe6d96
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.14

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page