Skip to content

Latest commit

 

History

4 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PDF ViewEdit

Android document viewer/editor in the spirit of Okular. Views and edits PDF, Markdown (.md), and Word (.docx) documents, and can import from / export to any of those formats.

Features

  • View PDFs (rendered pages; pinch zoom, double-tap zoom/reset, zoom buttons, page indicator, go-to-page), Markdown, and DOCX (rendered rich text).
  • Search in any document — highlighted matches with prev/next in md/docx, page-jump matching in PDFs (pdfbox text extraction).
  • OCR scanned PDFs on-device (ML Kit, offline) — result opens in the editor.
  • Print and share any document (md/docx print via PDF conversion).
  • Settings: theme (system/light/dark), keep-screen-on, editor text size.
  • Edit Markdown and DOCX in a markdown editor with a formatting toolbar (bold, italic, heading, bullet list) and live preview. PDFs open in the editor via text extraction (layout/images are not preserved).
  • Export any open document to PDF, DOCX, or Markdown.
  • Plain text.txt files open and are shown verbatim, without markdown parsing. Internally they are handled as Markdown.
  • Recent-documents list on the home screen (long-press to remove).
  • Registers as a handler for pdf/md/docx VIEW intents from other apps.
  • Material 3, light/dark (DayNight), same palette as Sift.

Conversion model

Markdown is the canonical editable representation. There is no direct PDF → DOCX or DOCX → PDF path; every conversion is source → markdown → target.

  • MD ↔ text file directly.
  • DOCX → markdown via a built-in OOXML parser (headings, bold/italic, bullets); markdown → DOCX via a built-in minimal OOXML writer.
  • Markdown → PDF via Markwon + the platform PdfDocument (A4 pagination).
  • PDF → text via pdfbox-android text extraction.

Because markdown is the hub, anything a format can express that markdown cannot is dropped at load time, before an export target is even chosen. In particular DOCX images, tables, numbering, hyperlink targets, headers/footers and any style beyond Heading1Heading6/Title do not survive a round trip.

Your original files are never overwritten with a lossy conversion. Saving a .docx that the app did not itself write prompts for a new file and explains what the conversion drops; the original is left untouched. Once you have saved to a file the app wrote, its contents are exactly the markdown in the editor, so later saves write to it in place. PDFs opened in the editor are likewise forced through Save As.

Fenced code blocks survive a markdown → DOCX → markdown round trip: they are written as monospace Code-styled paragraphs and read back as fences, with no markdown parsing applied to their contents. The round trip is idempotent — it converges after one pass rather than drifting.

Building

Requirements (same as Sift):

  • JDK 17
  • Android SDK platform 35, build-tools 34.0.0 (create local.properties with sdk.dir=/path/to/android-sdk)
  • Gradle wrapper 8.11.1 / AGP 8.7.3 (included)
export JAVA_HOME=/path/to/jdk-17
./gradlew :app:assembleRelease
# output: app/build/outputs/apk/release/app-release.apk

Signing uses keystore.properties + a .jks keystore in the project root (V2+V3 signing, V1 off). Both are gitignored — create your own keystore and a keystore.properties with storeFile, storePassword, keyAlias, keyPassword. If they are absent the build still succeeds and produces an unsigned APK, so check the output rather than assuming.

Note that the release signing config is applied to both build types, so debug APKs are signed with the production key and install over release builds. That is deliberate, but it means a debug APK is not safe to distribute.

Testing needs an ARM device or system image. ML Kit ships native OCR libraries and abiFilters is restricted to arm64-v8a and armeabi-v7a to keep the APK small, so the app will not run on an x86/x86_64 emulator.

Version numbering lives in app/build.gradle. versionCode and versionName are not in step — the first release was versionCode 2 / versionName "1.1". Bump both when releasing, and record the change in CHANGELOG.md.

Stack

  • Java 17, Android Views/XML (no Kotlin/Compose), single :app module
  • com.pdfviewedit.app, minSdk 26, targetSdk 35
  • Material 1.11.0, AppCompat 1.6.1, RecyclerView 1.3.2, Preference 1.2.1
  • Markwon 4.6.2 (markdown rendering), pdfbox-android 2.0.27.0 (PDF text extraction)
  • ML Kit text-recognition 16.0.1 (bundled on-device OCR; ARM ABIs only)

Structure

app/src/main/java/com/pdfviewedit/app/
├── PveApp.java   Application — applies the saved theme at startup
├── format/   DocType, Converter, Markdowns (shared Markwon factory),
│             DocxReader, DocxWriter, PdfExporter, PdfImporter
├── ui/       MainActivity (recents/open/new), ViewerActivity, EditorActivity,
│             PdfPageAdapter, SettingsActivity
└── util/     UriUtils, RecentStore, Prefs, PdfPrintAdapter

ViewerActivity is the largest file by a wide margin — it carries PDF rendering, zoom, both search implementations, OCR, print and share. It declares configChanges="orientation|screenSize|keyboardHidden", so it is never recreated on rotation and holds no saved instance state.

There are currently no automated testsapp/src/ contains only main.

Changelog

See CHANGELOG.md.

About

Android viewer/editor for PDF, Markdown, and DOCX with cross-format import/export, search, on-device OCR, and print — Material 3

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages