{"id":50979788,"url":"https://github.com/srijanmukherjee/gomupdf","last_synced_at":"2026-07-14T23:03:09.561Z","repository":{"id":362153373,"uuid":"1257505097","full_name":"srijanmukherjee/gomupdf","owner":"srijanmukherjee","description":"The fast, idiomatic way to read, render, and write PDFs in Go.","archived":false,"fork":false,"pushed_at":"2026-06-03T07:01:54.000Z","size":1198,"stargazers_count":22,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-07-07T11:04:25.748Z","etag":null,"topics":["fitz","golang","golang-library","gomupdf","mupdf"],"latest_commit_sha":null,"homepage":"https://pkg.go.dev/github.com/srijanmukherjee/gomupdf","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/srijanmukherjee.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-02T18:37:57.000Z","updated_at":"2026-07-07T09:50:42.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/srijanmukherjee/gomupdf","commit_stats":null,"previous_names":["srijanmukherjee/gomupdf"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/srijanmukherjee/gomupdf","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/srijanmukherjee%2Fgomupdf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/srijanmukherjee%2Fgomupdf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/srijanmukherjee%2Fgomupdf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/srijanmukherjee%2Fgomupdf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/srijanmukherjee","download_url":"https://codeload.github.com/srijanmukherjee/gomupdf/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/srijanmukherjee%2Fgomupdf/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35482263,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-14T02:00:06.603Z","response_time":114,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fitz","golang","golang-library","gomupdf","mupdf"],"created_at":"2026-06-19T13:00:27.345Z","updated_at":"2026-07-14T23:03:09.544Z","avatar_url":"https://github.com/srijanmukherjee.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n# gomupdf\n\n**The fast, idiomatic way to read, render, and write PDFs in Go.**\n\nA focused [cgo](https://pkg.go.dev/cmd/cgo) binding over the battle-tested\n[MuPDF](https://mupdf.com/core) C core — text extraction, table detection,\nrendering, and full document assembly, behind a small, Go-shaped API.\n\n[![CI](https://github.com/srijanmukherjee/gomupdf/actions/workflows/ci.yml/badge.svg)](https://github.com/srijanmukherjee/gomupdf/actions/workflows/ci.yml)\n[![codecov](https://codecov.io/gh/srijanmukherjee/gomupdf/graph/badge.svg)](https://codecov.io/gh/srijanmukherjee/gomupdf)\n[![Go Reference](https://pkg.go.dev/badge/github.com/srijanmukherjee/gomupdf.svg)](https://pkg.go.dev/github.com/srijanmukherjee/gomupdf)\n[![Go Report Card](https://goreportcard.com/badge/github.com/srijanmukherjee/gomupdf)](https://goreportcard.com/report/github.com/srijanmukherjee/gomupdf)\n[![Built with Claude Code](https://img.shields.io/badge/Built%20with-Claude%20Code-D97757?logo=anthropic\u0026logoColor=white)](https://claude.com/claude-code)\n\n\u003c/div\u003e\n\n```go\ndoc, _ := gomupdf.Open(\"invoice.pdf\")\ndefer doc.Close()\n\ntext, _   := doc.Text()         // every page, in reading order\npage, _   := doc.LoadPage(0)\ntables, _ := page.FindTables()  // structured rows \u0026 columns\n\npm, _ := page.Pixmap()          // render the page…\n_ = pm.SavePNG(\"page.png\")      // …and save it as an image\n```\n\n---\n\n## Why gomupdf?\n\n- **One dependency, many formats.** PDF, XPS, EPUB, MOBI, FB2, CBZ, SVG, plain\n  text, and raster images — all open through the same `Document` API.\n- **Extraction that keeps geometry.** Plain text *and* word/span boxes,\n  reading-order reconstruction, and table detection with two strategies\n  (word-alignment and vector-ruling).\n- **Real writing, not just reading.** Create documents, insert text/images,\n  merge, set metadata/XMP, page labels, page boxes, and save with fine-grained\n  options including AES-256 encryption and incremental updates.\n- **Idiomatic Go.** `iter.Seq2` page ranges, typed geometry, `error` returns,\n  deterministic `Close()`, no hidden globals.\n- **Thin and honest.** A small layer over MuPDF — the credit for the engine\n  belongs upstream; gomupdf gives it a clean Go surface.\n\n## Table of contents\n\n- [Install](#install) · [Requirements](#requirements)\n- [60-second tour](#60-second-tour)\n- **Cookbook** — [Open](#open-anything) · [Text \u0026 geometry](#text--geometry) ·\n  [Tables](#tables) · [Search, outline \u0026 links](#search-outline--links) ·\n  [Render \u0026 images](#render--images) · [Pages \u0026 boxes](#pages-rotation--boxes) ·\n  [Metadata \u0026 labels](#metadata--page-labels) · [Write \u0026 assemble](#write--assemble) ·\n  [Save options](#save-options)\n- [API cheat-sheet](#api-cheat-sheet) · [Feature support](#feature-support)\n- [Concurrency \u0026 memory](#concurrency--memory) · [Subpackages](#subpackages)\n- [Acknowledgements](#acknowledgements) · [License](#license)\n\n---\n\n## Install\n\n```sh\ngo get github.com/srijanmukherjee/gomupdf\n```\n\n### Requirements\n\ngomupdf links against the MuPDF C library via cgo, so a **C toolchain** and\n**MuPDF (shared library + development headers)** must be present at build time.\n`CGO_ENABLED=1` is required (on by default for native builds).\n\n| Platform | Install MuPDF |\n|---|---|\n| macOS (Homebrew) | `brew install mupdf` |\n| Debian / Ubuntu | `sudo apt-get install libmupdf-dev mupdf-tools` |\n| Fedora / RHEL | `sudo dnf install mupdf-devel` |\n| Arch | `sudo pacman -S libmupdf` |\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eFrom source / custom prefix / Windows / troubleshooting\u003c/b\u003e\u003c/summary\u003e\n\n**From source** (any platform):\n\n```sh\ngit clone --recursive https://github.com/ArtifexSoftware/mupdf.git\ncd mupdf \u0026\u0026 make HAVE_X11=no HAVE_GLUT=no prefix=/usr/local install\n```\n\n**Custom install location.** The default cgo flags (in `mupdf.go`) target\n`/opt/homebrew` on darwin and the system paths on linux, linking `-lmupdf`\n(plus `-lmupdf-third` on linux). If MuPDF lives elsewhere, supplement via\nenvironment variables instead of editing source:\n\n```sh\nexport CGO_CFLAGS=\"-I/your/prefix/include\"\nexport CGO_LDFLAGS=\"-L/your/prefix/lib -lmupdf -lmupdf-third\"\ngo build ./...\n```\n\n**Windows** is not covered by the default flags; build with a MinGW/MSYS2\ntoolchain and set `CGO_CFLAGS` / `CGO_LDFLAGS` to your MuPDF install.\n\n**`ld: library 'mupdf' not found`** means MuPDF is not installed or not on the\nlibrary path — install it or set `CGO_LDFLAGS` as above.\n\n\u003c/details\u003e\n\n---\n\n## 60-second tour\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\n\t\"github.com/srijanmukherjee/gomupdf\"\n)\n\nfunc main() {\n\tdoc, err := gomupdf.Open(\"document.pdf\")\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tdefer doc.Close() // always Close; the finalizer is only a backstop\n\n\t// Encrypted? Unlock it (or use OpenWithPassword to do both in one call).\n\tif doc.NeedsPass() \u0026\u0026 !doc.Authenticate(\"secret\") {\n\t\tlog.Fatal(\"wrong password\")\n\t}\n\n\tfmt.Println(\"pages:\", doc.PageCount())\n\n\tfor i, page := range doc.Pages() { // ranges via iter.Seq2\n\t\ttext, err := page.GetText()\n\t\tif err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\t\tfmt.Printf(\"=== page %d ===\\n%s\\n\", i, text)\n\t}\n}\n```\n\n\u003e **Coordinates.** All geometry is in PDF points. The `geometry` package uses a\n\u003e top-left origin with y growing downward (`Rect{X0,Y0,X1,Y1}`).\n\n---\n\n## Cookbook\n\n### Open anything\n\n```go\n// PDF fast paths\ndoc, _ := gomupdf.Open(\"file.pdf\")                      // from a file\ndoc, _ := gomupdf.OpenStream(pdfBytes)                  // from memory\ndoc, _ := gomupdf.OpenWithPassword(\"file.pdf\", \"pw\")    // open + authenticate\ndoc, _ := gomupdf.OpenStreamWithPassword(b, \"pw\")\n\n// Any MuPDF-supported format (XPS, EPUB, MOBI, FB2, CBZ, SVG, TXT, images)\ndoc, _ := gomupdf.OpenAny(\"book.epub\")                  // format from extension\ndoc, _ := gomupdf.OpenAnyStream(pngBytes, \"png\")        // explicit format hint\n\n// Turn a non-PDF (or any) document into a writable PDF\npdf, _ := doc.ConvertToPDF()\ndefer pdf.Close()\n```\n\nNon-PDF documents open **read-only** (text, geometry, rendering all work); use\n`ConvertToPDF` to get a writable PDF `Document`.\n\n### Text \u0026 geometry\n\n```go\ntext, _   := doc.Text()            // whole document, pages joined by '\\f'\npages, _  := doc.TextByPage()      // []string, one per page\nlines, _  := doc.AllLines()        // flat lines: soft-hyphens stripped, blanks dropped\n\nwords, _  := page.Words()          // word boxes with character-level precision\nspans, _  := page.Spans()          // positioned fragments + font name/size\nblocks, _ := page.StructuredText() // []Block → []Span tree with bbox \u0026 baseline\nraw, _    := page.StructuredJSON() // the raw block/line/char JSON, your way\n```\n\n`Words` is the recommended input for layout work and table reconstruction — the\nboxes are unions of per-character quads, not span approximations.\n\n### Tables\n\nTwo strategies: **word-alignment** (`StrategyText`, the default) and\n**vector-ruling** (`StrategyLines`, follows drawn gridlines).\n\n```go\ntables, _ := page.FindTables() // default word-alignment strategy\ntables, _ := page.FindTables(gomupdf.TableSettings{\n\tStrategy:      gomupdf.StrategyLines,\n\tSnapTolerance: 3,\n})\n\nfor _, t := range tables {\n\tfmt.Println(t.NumRows(), \"x\", t.NumCols())\n\tfor _, row := range t.Rows {\n\t\tfmt.Println(row) // []string cells\n\t}\n}\n```\n\n### Search, outline \u0026 links\n\n```go\nquads, _ := page.Search(\"invoice\")       // oriented quads (great for highlights)\nrects, _ := page.SearchRects(\"invoice\")  // axis-aligned rects\ntoc, _   := doc.TOC()                     // flat, depth-first outline entries\nlinks, _ := page.Links()                  // clickable rects + target URIs\n```\n\n### Render \u0026 images\n\n```go\npm, _  := page.Pixmap(gomupdf.PixmapOptions{Zoom: 2.0}) // 144 DPI RGB raster\npng, _ := pm.PNG()                                       // encode to PNG bytes\n_ = pm.SavePNG(\"page.png\")\nimg, _ := pm.Image()                                     // a stdlib image.Image\npx := pm.Pixel(10, 10)                                   // raw component bytes\n\ninfos, _ := page.GetImages()       // each image's placement bbox + source dims\nraw, _   := page.ExtractImage(0)   // original encoded bytes (JPEG/PNG/…)\npaths, _ := page.GetDrawings()     // vector fill/stroke paths with color \u0026 width\n```\n\n### Pages, rotation \u0026 boxes\n\n```go\nn      := doc.PageCount()\npage, _ := doc.LoadPage(0)\n\nrot, _  := page.Rotation()           // 0, 90, 180, or 270\n_ = page.SetRotation(90)             // multiples of 90, normalized\n\nmb, _ := page.MediaBox()             // full physical page, unrotated points\ncb, _ := page.CropBox()              // visible region (defaults to MediaBox)\n_ = page.SetCropBox(geometry.Rect{X0: 10, Y0: 10, X1: 400, Y1: 600})\n```\n\n### Metadata \u0026 page labels\n\n```go\n// Read / write the standard info dictionary\nmeta, _ := doc.Metadata()            // map: title, author, producer, dates, …\n_ = doc.SetMetadata(map[string]string{\n\t\"title\":  \"Quarterly Report\",\n\t\"author\": \"Finance\",\n\t// an empty value clears a field; unknown keys are ignored\n})\n\n// XMP packet (Catalog /Metadata stream)\nxmp, _ := doc.XMP()\n_ = doc.SetXMP(xmlPacket)\n_ = doc.DeleteXMP()\n\n// Logical page numbering: front-matter as i, ii, iii then body 1, 2, 3 …\n_ = doc.SetPageLabels([]gomupdf.PageLabel{\n\t{StartPage: 0, Style: gomupdf.LabelRomanLower, Start: 1},\n\t{StartPage: 2, Style: gomupdf.LabelDecimal, Prefix: \"\", Start: 1},\n})\nlabel, _ := page.Label()             // resolved label, e.g. \"ii\" or \"A-3\"\nrules, _ := doc.PageLabels()          // read the rules back\n```\n\n### Write \u0026 assemble\n\n```go\ndoc, _ := gomupdf.NewPDF()\ndefer doc.Close()\n\ndoc.NewPage(595, 842)                 // A4 in points\np, _ := doc.LoadPage(0)\np.InsertText(72, 800, 12, \"Hello, gomupdf\")\np.InsertImage(geometry.NewRect(0, 0, 200, 200), imageBytes)\n\ndoc.InsertPDF(otherPDFBytes, \"\")      // append every page of another PDF\ndoc.DeletePage(3)\n```\n\n### Save options\n\n```go\ndata, _ := doc.SaveBytes(true)                     // quick: serialize (+garbage)\n_ = doc.EzSave(\"out.pdf\")                          // sensible defaults to a file\n\n// Fine-grained control\ndata, _ = doc.SaveBytesWithOptions(gomupdf.SaveOptions{\n\tGarbage:       3,     // 0–4 dead-object collection\n\tDeflate:       true,  // compress streams\n\tClean:         true,  // sanitize content streams\n\tLinear:        true,  // \"fast web view\"\n\tASCII:         true,  // escape binary to 7-bit\n})\n\n// AES-256 encryption\ndata, _ = doc.SaveBytesWithOptions(gomupdf.SaveOptions{\n\tEncrypt: true, UserPassword: \"open-me\", OwnerPassword: \"full\", Permissions: -1,\n})\ndata, _ = doc.SaveEncryptedBytes(\"user\", \"owner\")  // shorthand\n\n// Incremental update (file/stream-opened docs): appends changes after the\n// original bytes instead of rewriting the whole file.\n_ = doc.SaveIncremental(\"out.pdf\")\n```\n\n---\n\n## API cheat-sheet\n\n| Want to… | Call |\n|---|---|\n| Open a PDF | `Open` · `OpenStream` · `OpenWithPassword` |\n| Open EPUB/XPS/image/… | `OpenAny` · `OpenAnyStream` |\n| Convert to writable PDF | `doc.ConvertToPDF()` |\n| Count / load / iterate pages | `doc.PageCount` · `doc.LoadPage` · `doc.Pages` |\n| Extract text | `doc.Text` · `page.GetText` · `page.Lines` · `page.ExtractText` (clip+flags) |\n| Get positioned text | `page.Words` · `page.Spans` · `page.StructuredText` · `page.RawDict`/`Dict` |\n| Export markup | `page.HTML` · `page.XHTML` · `page.XML` |\n| Find tables | `page.FindTables` → `table.ToMarkdown` / `table.Header` |\n| Search | `page.Search` · `page.SearchRects` · `page.SearchWith` (clip, cap) |\n| Outline / links | `doc.TOC`/`SetTOC` · `page.Links`/`InsertLink`/`DeleteLink` |\n| Annotate | `page.AddHighlight`/`AddFreeText`/`AddLine`/`Annotations`/`DeleteAnnotation` |\n| Redact | `page.AddRedaction` → `page.ApplyRedactions` |\n| Forms | `page.Widgets` · `page.SetTextField` · `page.AddTextField` |\n| Page ops | `doc.CopyPage`/`MovePage`/`SelectPages`/`InsertPDFRange` |\n| Draw | `page.DrawRect`/`DrawLine`/`DrawCircle` · `page.InsertTextbox` |\n| Render | `page.Pixmap(PixmapOptions{DPI,CMYK,Clip…})` → `pm.PNG`/`JPEG`/`Save`/`Image` |\n| Pixmap ops | `pm.Invert` · `pm.Gamma` · `pm.Bytes` |\n| Fonts | `page.GetFonts` · `doc.ExtractFont` · `NewFont(…).TextLength` |\n| Images / drawings | `page.GetImages` · `page.ExtractImage` · `page.GetDrawings` |\n| Rotation / boxes | `page.Rotation`/`SetRotation` · `page.MediaBox`/`CropBox`/`Set…` |\n| Metadata / XMP | `doc.Metadata`/`SetMetadata` · `doc.XMP`/`SetXMP`/`DeleteXMP` |\n| Page labels | `doc.PageLabels`/`SetPageLabels` · `page.Label` |\n| Build / edit | `NewPDF` · `doc.NewPage` · `doc.DeletePage` · `doc.InsertPDF` |\n| Write content | `page.InsertText` · `page.InsertImage` · `page.AddRectAnnot` |\n| Save | `doc.SaveBytes` · `doc.EzSave` · `doc.SaveWithOptions` · `doc.SaveIncremental` |\n\nFull reference: **[pkg.go.dev/github.com/srijanmukherjee/gomupdf](https://pkg.go.dev/github.com/srijanmukherjee/gomupdf)**\n\n## Feature support\n\nLegend: ✅ supported · 🟡 partial · ⬜ not yet\n\n| Area | Capability | Status |\n|---|---|---|\n| Read | Open PDF (file / stream / password) | ✅ |\n| Read | Open XPS / EPUB / CBZ / SVG / images, convert to PDF | ✅ |\n| Read | Page count, load, iterate | ✅ |\n| Read | Plain \u0026 structured text, char-level word boxes | ✅ |\n| Read | dict/rawdict (per-char), HTML / XHTML / XML export | ✅ |\n| Read | Text extraction options (clip rect, stext flags) | ✅ |\n| Read | Geometry primitives (`geometry` pkg) | ✅ |\n| Read | Text search (quads \u0026 rects; region clip + hit cap) | ✅ |\n| Read | Tables — word-alignment \u0026 vector-ruling, → Markdown | ✅ |\n| Structure | Outline (TOC) read \u0026 write | ✅ |\n| Structure | Page links — read, insert, goto, delete | ✅ |\n| Structure | Page labels, page boxes, rotation | ✅ |\n| Structure | Metadata read/write + XMP | ✅ |\n| Structure | Embedded files, optional-content layers | ⬜ |\n| Render | Pixmap → raster (DPI, RGB/Gray/CMYK, clip, annot toggle) | ✅ |\n| Render | Pixmap ops (invert, gamma) + PNG/JPEG/PNM encode \u0026 save | ✅ |\n| Render | Extract images + placement bbox | ✅ |\n| Render | Vector drawings / paths | ✅ |\n| Read | Fonts — enumerate, extract embedded program, glyph metrics | ✅ |\n| Render | OCR, image masks | ⬜ |\n| Write | New PDF, page insert/delete/copy/move/select, merge \u0026 range-merge | ✅ |\n| Write | Insert text, images, word-wrapped text boxes | ✅ |\n| Write | Draw lines / rects / circles | ✅ |\n| Write | Annotations — markup, shapes, ink, free-text, sticky notes | ✅ |\n| Write | Redaction (mark + apply) | ✅ |\n| Write | Form widgets — read, fill, create text fields | 🟡 text/checkbox |\n| Write | Save options (deflate, clean, linear, ASCII, incremental) | ✅ |\n| Write | AES-256 encryption | ✅ |\n| Write | Digital signatures, full Shape API, OCG layers | ⬜ |\n\n\u003e gomupdf is actively working toward feature parity with PyMuPDF. The remaining\n\u003e remaining ⬜ items (digital signatures, full form types, OCR, optional-content layers) are on the\n\u003e roadmap.\n\n## Concurrency \u0026 memory\n\nA `Document` owns a single native MuPDF context and is **not** safe for\nconcurrent use; all of its methods are serialized internally by a mutex. To\nprocess documents in parallel, **open one `Document` per goroutine**.\n\n- Always `Close()` a document when done — the finalizer is only a backstop.\n- The in-memory bytes backing a streamed/opened document are held for its\n  lifetime (MuPDF reads from them lazily).\n- C resources are released deterministically in helper functions, so a Go-side\n  mistake cannot leak the underlying objects.\n\n## Backends\n\ngomupdf's public API is **backend-neutral**: every operation that touches a\nnative engine is delegated through an internal interface. The **MuPDF (cgo)**\nbackend is the default and is compiled in automatically — you don't need to do\nanything.\n\nBuilding with `-tags nomupdf` excludes all cgo (no C toolchain or MuPDF needed\nto compile); constructors then return a \"no backend\" error. This build tag is\nthe seam for alternative backends — e.g. a future cgo-free WASM or pure-Go\nengine slots in under the opposite tag with no change to the public API.\n\n```sh\ngo build ./...                 # default: MuPDF backend\ngo build -tags nomupdf ./...   # compile with the engine excluded\n```\n\n## Subpackages\n\n- **[`geometry`](./geometry)** — the 2D primitives (`Point`, `Rect`, `IRect`,\n  `Matrix`, `Quad`) used throughout the API, with full affine algebra.\n- **[`experimental`](./experimental)** — a higher-level, ergonomic layer:\n  lifecycle-managed documents, a row/word model for layout-aware extraction,\n  region and key/value queries (`ValueRightOf`, `ValueBelow`), located regex\n  search, and helpers for rendering, image extraction, and merging PDFs/images.\n\n## Acknowledgements\n\n- **[MuPDF](https://mupdf.com)** by [Artifex Software](https://artifex.com) is\n  the C library that does the heavy lifting — parsing, rendering, and text\n  extraction. gomupdf is a thin Go layer over it; all credit for the underlying\n  PDF engine belongs to the MuPDF authors.\n- **[PyMuPDF](https://github.com/pymupdf/PyMuPDF)** and\n  **[pdfplumber](https://github.com/jsvine/pdfplumber)** are the prior art that\n  shaped this library's extraction and table-detection design. Thank you to\n  their authors and maintainers.\n\n## License\n\nMuPDF is distributed under the **GNU AGPL-3.0**, and this package links against\nit, so the same license applies (see [LICENSE](./LICENSE)). Review its\nobligations before distributing binaries built with this package.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsrijanmukherjee%2Fgomupdf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsrijanmukherjee%2Fgomupdf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsrijanmukherjee%2Fgomupdf/lists"}