Skip to content

jericho909/ocr-now

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

37 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ocr-now

Thin Bun CLI over Tesseract. Takes PDFs and images, dumps text. Defaults to Turkish.

Requirements

  • Bun
  • Tesseract + language data
  • Poppler (for pdftoppm, pdfinfo, pdftotext, pdfimages)

Tested on macOS and Linux. Windows isn't tested but shouldn't be architecturally blocked. Bun supports Windows natively and Tesseract and Poppler are both available there. The --copy flag is the only piece that won't work on non-macOS (uses pbcopy).

macOS

brew install tesseract tesseract-lang poppler

Linux

sudo apt install tesseract-ocr tesseract-ocr-all poppler-utils

On Fedora the package names are tesseract, tesseract-langpack-*, and poppler-utils. On Arch they're tesseract, tesseract-data-*, and poppler. tesseract-ocr-all (or installing every langpack-*) pulls every supported language; swap for specific ones if you'd rather keep the footprint small.

Install

git clone https://github.com/jericho909/ocr-now.git
cd ocr-now
bun install
bun link

ocr-now is now on your PATH.

Usage

ocr-now start [opts]                       # batch project's input/ folder
ocr-now <file> [opts]                      # OCR a single file in place
ocr-now config [list|get|set|unset] ...    # inspect or change settings
ocr-now langs                              # list installed tesseract languages
ocr-now -h | --help                        # show help
ocr-now -v | --version                     # print version

PDF pages are processed in a streaming pipeline: rasterization and OCR run concurrently, so OCR begins on early pages while later pages are still being rasterized. Both phases are capped at 6 workers or your CPU core count, whichever is lower. Page order in the output is preserved regardless of completion order.

If a PDF has embedded text on the selected pages, ocr-now extracts it directly via pdftotext and skips OCR for those pages. A 144-page fully text-embedded PDF goes from ~75s to <1s. Hybrid PDFs (e.g., a scanned page inserted into an otherwise digital doc) mix the two paths: text pages extracted directly, scanned pages OCR'd. Fully scanned PDFs go through the full OCR pipeline.

Batch mode

Drop PDFs/images into input/, then:

ocr-now start

Writes one combined file to output/ocr-now <LANG> <timestamp>.txt. The input/ and output/ folders are created automatically on first run.

Single-file mode

ocr-now ~/Downloads/invoice.pdf

Writes ocr-now <LANG> invoice.txt next to the source file.

Filenames with spaces or special chars: quote them, or use tab completion.

Flags

Flag Purpose
--lang=xxx Tesseract lang code. Multi-language with +: --lang=tur+eng. Use auto to detect
--dpi=N Rasterize PDFs at N dpi. Range 72–600. Default 300
--pages=1-3,7 PDF only. OCR a subset of pages. Non-contiguous allowed
--out=<path> Override output. Treated as a directory if it ends in / or already exists as one; otherwise as a file path
--copy Also copy result to clipboard. macOS only (uses pbcopy)
--stdout Write result to stdout instead of a file. Status logs go to stderr so output pipes cleanly: ocr-now foo.pdf --stdout | grep keyword
--quiet Suppress progress, spinner, and the final "wrote" line. Errors still print to stderr
--json Emit structured JSON instead of the plain-text section format. Output file extension switches to .json. Pipes cleanly: ocr-now foo.pdf --json --stdout | jq .pages[0]

All stackable. Example:

ocr-now ~/Downloads/long.pdf --pages=1-2,5 --dpi=400 --copy

Config

Persistent settings live in config.json at the project root.

ocr-now config list
ocr-now config get defaultLang
ocr-now config set defaultLang eng
ocr-now config set defaultDpi 400
ocr-now config unset defaultDpi

Valid keys:

Key Default Notes
defaultLang tur Tesseract code, multi-language with +, or auto
defaultDpi 300 Integer in 72..600
autoMinConfidence 0.2 Min franc score to accept the detected language; below this, fall back to the baseline
autoMinSampleChars 20 Min sample-text length before franc is consulted at all

Resolution order: flag → config → built-in default.

defaultLang accepts auto as a special value. See below.

Auto language detection

ocr-now ~/Downloads/foo.pdf --lang=auto
ocr-now config set defaultLang auto

Auto mode runs a quick low-DPI sample pass, runs franc-min on the resulting text, then re-OCRs with the detected language. Cost: ~1–3s extra per file.

Sample-pass baseline picks your configured defaultLang if set (so Turkish diacritics survive when reading Turkish docs), otherwise eng, otherwise the first installed language. The baseline is also used as the fallback when detection fails.

Notes:

  • Picks the single best match. If your doc is genuinely bilingual, pass --lang=tur+eng explicitly. Single-pass detection isn't suited to multi-language inference.
  • Falls back to the baseline if the sample text is too short, no installed language matches, or detection confidence is below the autoMinConfidence threshold (default 0.2).
  • Detected language is shown per file and used in the output filename. Batch-mode combined output uses AUTO in the filename since files may differ; the per-file section header ([LANG]) shows what was actually used.

Languages

Tesseract uses ISO 639-2/T codes: eng, tur, deu, fra, spa, ita, por, rus, ara, chi_sim, jpn, kor, etc. Run tesseract --list-langs to see what's installed.

If you pass a code that isn't installed, ocr-now aborts and prints your installed list before doing any work.

Output format

One file per run. Each source file gets a section:

========== filename [TUR] ==========
--- Page 1 ---
<text>

--- Page 2 ---
<text>

The [LANG] suffix in the section header shows the language actually used for that file (useful with --lang=auto).

Single-file mode skips the ======== header (single source).

Third-party tools

ocr-now is a thin wrapper. The actual work is done by:

Tool License Link
Tesseract Apache 2.0 invoked as a subprocess
Poppler (pdftoppm, pdfinfo, pdftotext, pdfimages) GPL invoked as a subprocess
franc-min MIT npm dependency

License

MIT. See LICENSE.

About

Lightweight Bun CLI for OCR'ing PDFs and images. Skips OCR on text-embedded pages, runs rasterization and recognition in parallel, auto-detects language.

Topics

Resources

License

Stars

1 star

Watchers

0 watching

Forks

Packages

 
 
 

Contributors