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.pdfedicion.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

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dof2md-0.2.0.tar.gz (25.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dof2md-0.2.0-py3-none-any.whl (17.6 kB view details)

Uploaded Python 3

File details

Details for the file dof2md-0.2.0.tar.gz.

File metadata

  • Download URL: dof2md-0.2.0.tar.gz
  • Upload date:
  • Size: 25.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.14

File hashes

Hashes for dof2md-0.2.0.tar.gz
Algorithm Hash digest
SHA256 6f33a63e4256110dda21561affcb4bf405b1813c61f38db5a85d3968cac0bf92
MD5 72316b18252c2d0b25e02f51fc051fba
BLAKE2b-256 ba1b654956412a75dc3b8c9c79cb823f28e622d42a291a44051f750d50cdf12a

See more details on using hashes here.

File details

Details for the file dof2md-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: dof2md-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 17.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.14

File hashes

Hashes for dof2md-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7a13d071992f5e981600ac1eb2f945535620864606fb7e358741fc911335cda7
MD5 15ce105cc9570e869d640be971c11711
BLAKE2b-256 90848209569d514c5603a7ceade8f1fcfa7b06408c38b528ee23b64d84fe6d96

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 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