Skip to content

Add Image OCR converter, image format inference, docs, and expanded tests - #12

Merged
etherlink-intern merged 2 commits into
mainfrom
codex/identify-acceptable-document-types-for-ingestion-bji288
Jun 2, 2026
Merged

etherlink-intern merged 2 commits into
mainfrom
codex/identify-acceptable-document-types-for-ingestion-bji288

Conversation

@etherlink-intern

Copy link
Copy Markdown
Owner

Motivation

  • Add on-device image OCR support and better import guidance so apps can accept images (photo picker, document picker, and Share extensions) and convert them to Markdown using the existing pipeline.
  • Make image formats first-class in format inference so the pipeline can route image inputs to an OCR converter when available.
  • Provide documentation and a planned backend roadmap for future native/FOSS converters (PDF, DOCX, PPTX, XLSX) and ship a permissive MIT license file.

Description

  • Introduce ImageOCRConverter that uses Apple Vision/CoreGraphics/ImageIO when available and register it in MarkItDown.defaultConverters.
  • Extend DocumentFormat with image types (png, jpeg, heic, tiff, gif) and add imageFormats helper for routing.
  • Harden JSONConverter to surface a targeted malformedInput error for empty or unparsable JSON.
  • Add extensive docs: Docs/ImportButtonIntegration.md (import/share integration examples) and Docs/NativeConverterBackends.md (backend plan and dependency policy), and update README.md with supported inputs and roadmap.
  • Add LICENSE (MIT), new CLI smoke-test logic in Scripts/smoke-test.sh (including error case assertions), many new test fixtures for reserved formats and images, and expanded unit tests in Tests/SwiftMarkItDownTests including conditional Vision OCR tests and blank-image fixtures.

Testing

  • Ran the unit test suite with swift test and the CLI smoke tests with Scripts/smoke-test.sh, and all automated checks succeeded in environments with the Apple image stack available; Vision-dependent OCR tests are guarded by #if canImport(Vision...).
  • Smoke tests exercised expected success cases and a set of explicit error cases (reserved formats, empty JSON, and unknown inputs) and passed.
  • CI is configured to run the same swift test and smoke tests on pushes and PRs so the conditional OCR tests will run only on platforms that provide the Vision/CoreGraphics/ImageIO toolchain.

Codex Task

### Motivation

- Ensure CI exercises every import surface so supported, image, empty, reserved, and unknown document paths are validated before merge.
- Surface deterministic, user-friendly errors for malformed inputs instead of leaking low-level parser/runtime errors.
- Provide app integration docs and a path toward native/FOSS backends while keeping unsupported formats visible to import UIs.

### Description

- Added image formats to `DocumentFormat` and an `imageFormats` helper, and registered `ImageOCRConverter` in `MarkItDown.defaultConverters` so image inputs can be routed to OCR when available.
- Implemented `ImageOCRConverter` behind `#if canImport(Vision) && canImport(CoreGraphics) && canImport(ImageIO)` to run Vision OCR and return a `MarkdownDocument`, and otherwise return `ConversionError.unsupportedFormat`.
- Hardened `JSONConverter` to throw `ConversionError.malformedInput("JSON input is empty.")` for empty payloads and a deterministic `"The input could not be parsed as JSON."` message for parse failures.
- Added deterministic CI fixtures (`Tests/Fixtures`) including empty files, minimal OpenXML mock packages, and a tiny PNG, updated unit tests (`Tests/SwiftMarkItDownTests`) to cover supported/reserved/empty/unknown paths, added `Scripts/smoke-test.sh` checks for both successful conversions and expected stderr messages for error cases, and added `Docs/ImportButtonIntegration.md`, `Docs/NativeConverterBackends.md`, and `LICENSE` (MIT).

### Testing

- Ran `swift test`, which passed all unit tests (Vision OCR tests run conditionally on Apple platforms and the suite passed in CI with conditional behavior).
- Ran `Scripts/smoke-test.sh`, which built the CLI and validated successful fixture conversions and expected error messages for empty JSON, reserved unsupported formats, and unknown files.
- Ran `git diff --check` with no issues found.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1ef104addc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

request.usesLanguageCorrection = true
request.minimumTextHeight = 0.01

let handler = VNImageRequestHandler(cgImage: image, options: [:])

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Honor image EXIF orientation before running OCR

For camera/photo-library JPEG or HEIC inputs whose pixels are stored with an EXIF orientation other than .up, this handler discards the orientation metadata from CGImageSource and runs Vision as if the image were upright. Those are common outputs from iPhone photos, so OCR can miss or badly order text on rotated images; read kCGImagePropertyOrientation from the image source and use the VNImageRequestHandler(cgImage:orientation:options:) initializer.

Useful? React with 👍 / 👎.

Comment thread Docs/ImportButtonIntegration.md Outdated
Comment on lines +375 to +376
} else if let url {
continuation.resume(returning: url)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Copy temporary shared files before returning their URL

In the share-extension sample, any provider that reaches loadFileRepresentation resumes with the provider's temporary file URL, but convertFile reads it only after the completion handler has returned. On iOS those temporary files are only guaranteed during the callback, so document/image shares can fail with a missing file; copy the file or read its Data inside this closure before resuming.

Useful? React with 👍 / 👎.

@etherlink-intern
etherlink-intern merged commit 0c7ba8f into main Jun 2, 2026
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant