Copy disabled (too large)
Download .txt
Showing preview only (10,477K chars total). Download the full file to get everything.
Repository: rk700/PyMuPDF
Branch: main
Commit: ae19b1ad6ce0
Files: 589
Total size: 9.1 MB
Directory structure:
gitextract_dv05yjlp/
├── .gitattributes
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.yml
│ │ └── feature_request.md
│ └── workflows/
│ ├── build_wheels.yml
│ ├── cla.yml
│ ├── test-valgrind.yml
│ ├── test.yml
│ ├── test_multiple.yml
│ ├── test_pyodide.yml
│ ├── test_quick.yml
│ └── test_sysinstall.yml
├── .gitignore
├── .python-version
├── .readthedocs.yaml
├── .vs/
│ ├── ProjectSettings.json
│ ├── PyMuPDF/
│ │ └── v15/
│ │ └── .suo
│ └── VSWorkspaceState.json
├── COPYING
├── README.md
├── READMEb.md
├── READMEd.md
├── changes.txt
├── docs/
│ ├── 404.rst
│ ├── README.md
│ ├── _static/
│ │ ├── custom.css
│ │ └── prism/
│ │ ├── prism.css
│ │ ├── prism.html
│ │ └── prism.js
│ ├── about-feature-matrix.rst
│ ├── about-performance.rst
│ ├── about.rst
│ ├── algebra.rst
│ ├── annot.rst
│ ├── app1.rst
│ ├── app2.rst
│ ├── app3.rst
│ ├── app4.rst
│ ├── archive-class.rst
│ ├── changes.rst
│ ├── classes.rst
│ ├── colors.rst
│ ├── colorspace.rst
│ ├── conf.py
│ ├── converting-files.rst
│ ├── coop_low.rst
│ ├── device.rst
│ ├── displaylist.rst
│ ├── document-writer-class.rst
│ ├── document.rst
│ ├── extensions/
│ │ ├── __init__.py
│ │ ├── fulltoc.py
│ │ └── searchrepair.py
│ ├── faq/
│ │ └── index.rst
│ ├── faq.rst
│ ├── font.rst
│ ├── footer.rst
│ ├── functions.rst
│ ├── glossary.rst
│ ├── header-404.rst
│ ├── header.rst
│ ├── how-to-open-a-file.rst
│ ├── identity.rst
│ ├── index.rst
│ ├── installation.rst
│ ├── irect.rst
│ ├── link.rst
│ ├── linkdest.rst
│ ├── locales/
│ │ ├── ja/
│ │ │ ├── .readthedocs.yaml
│ │ │ └── LC_MESSAGES/
│ │ │ ├── 404.mo
│ │ │ ├── 404.po
│ │ │ ├── about-feature-matrix.mo
│ │ │ ├── about-feature-matrix.po
│ │ │ ├── about-performance.mo
│ │ │ ├── about-performance.po
│ │ │ ├── about.mo
│ │ │ ├── about.po
│ │ │ ├── algebra.mo
│ │ │ ├── algebra.po
│ │ │ ├── annot.mo
│ │ │ ├── annot.po
│ │ │ ├── app1.mo
│ │ │ ├── app1.po
│ │ │ ├── app2.mo
│ │ │ ├── app2.po
│ │ │ ├── app3.mo
│ │ │ ├── app3.po
│ │ │ ├── app4.mo
│ │ │ ├── app4.po
│ │ │ ├── archive-class.mo
│ │ │ ├── archive-class.po
│ │ │ ├── changes.mo
│ │ │ ├── changes.po
│ │ │ ├── classes.mo
│ │ │ ├── classes.po
│ │ │ ├── colors.mo
│ │ │ ├── colors.po
│ │ │ ├── colorspace.mo
│ │ │ ├── colorspace.po
│ │ │ ├── converting-files.mo
│ │ │ ├── converting-files.po
│ │ │ ├── coop_low.mo
│ │ │ ├── coop_low.po
│ │ │ ├── deprecated.mo
│ │ │ ├── deprecated.po
│ │ │ ├── device.mo
│ │ │ ├── device.po
│ │ │ ├── displaylist.mo
│ │ │ ├── displaylist.po
│ │ │ ├── document-writer-class.mo
│ │ │ ├── document-writer-class.po
│ │ │ ├── document.mo
│ │ │ ├── document.po
│ │ │ ├── faq.mo
│ │ │ ├── faq.po
│ │ │ ├── font.mo
│ │ │ ├── font.po
│ │ │ ├── footer.mo
│ │ │ ├── footer.po
│ │ │ ├── functions.mo
│ │ │ ├── functions.po
│ │ │ ├── glossary.mo
│ │ │ ├── glossary.po
│ │ │ ├── header-404.mo
│ │ │ ├── header-404.po
│ │ │ ├── header.mo
│ │ │ ├── header.po
│ │ │ ├── how-to-open-a-file.mo
│ │ │ ├── how-to-open-a-file.po
│ │ │ ├── identity.mo
│ │ │ ├── identity.po
│ │ │ ├── index.mo
│ │ │ ├── index.po
│ │ │ ├── installation.mo
│ │ │ ├── installation.po
│ │ │ ├── intro.mo
│ │ │ ├── intro.po
│ │ │ ├── irect.mo
│ │ │ ├── irect.po
│ │ │ ├── link.mo
│ │ │ ├── link.po
│ │ │ ├── linkdest.mo
│ │ │ ├── linkdest.po
│ │ │ ├── lowlevel.mo
│ │ │ ├── lowlevel.po
│ │ │ ├── matrix.mo
│ │ │ ├── matrix.po
│ │ │ ├── module.mo
│ │ │ ├── module.po
│ │ │ ├── outline.mo
│ │ │ ├── outline.po
│ │ │ ├── packaging.mo
│ │ │ ├── packaging.po
│ │ │ ├── page.mo
│ │ │ ├── page.po
│ │ │ ├── pixmap.mo
│ │ │ ├── pixmap.po
│ │ │ ├── point.mo
│ │ │ ├── point.po
│ │ │ ├── pymupdf-layout/
│ │ │ │ ├── index.mo
│ │ │ │ └── index.po
│ │ │ ├── pymupdf-pro/
│ │ │ │ ├── index.mo
│ │ │ │ └── index.po
│ │ │ ├── pymupdf-pro.mo
│ │ │ ├── pymupdf-pro.po
│ │ │ ├── pymupdf4llm/
│ │ │ │ ├── api.mo
│ │ │ │ ├── api.po
│ │ │ │ ├── index.mo
│ │ │ │ └── index.po
│ │ │ ├── pyodide.mo
│ │ │ ├── pyodide.po
│ │ │ ├── quad.mo
│ │ │ ├── quad.po
│ │ │ ├── rag.mo
│ │ │ ├── rag.po
│ │ │ ├── recipes-annotations.mo
│ │ │ ├── recipes-annotations.po
│ │ │ ├── recipes-common-issues-and-their-solutions.mo
│ │ │ ├── recipes-common-issues-and-their-solutions.po
│ │ │ ├── recipes-drawing-and-graphics.mo
│ │ │ ├── recipes-drawing-and-graphics.po
│ │ │ ├── recipes-images.mo
│ │ │ ├── recipes-images.po
│ │ │ ├── recipes-journalling.mo
│ │ │ ├── recipes-journalling.po
│ │ │ ├── recipes-low-level-interfaces.mo
│ │ │ ├── recipes-low-level-interfaces.po
│ │ │ ├── recipes-multiprocessing.mo
│ │ │ ├── recipes-multiprocessing.po
│ │ │ ├── recipes-ocr.mo
│ │ │ ├── recipes-ocr.po
│ │ │ ├── recipes-optional-content.mo
│ │ │ ├── recipes-optional-content.po
│ │ │ ├── recipes-stories.mo
│ │ │ ├── recipes-stories.po
│ │ │ ├── recipes-text.mo
│ │ │ ├── recipes-text.po
│ │ │ ├── recipes.mo
│ │ │ ├── recipes.po
│ │ │ ├── rect.mo
│ │ │ ├── rect.po
│ │ │ ├── resources.mo
│ │ │ ├── resources.po
│ │ │ ├── shape.mo
│ │ │ ├── shape.po
│ │ │ ├── story-class.mo
│ │ │ ├── story-class.po
│ │ │ ├── supported-files-table.mo
│ │ │ ├── supported-files-table.po
│ │ │ ├── textpage.mo
│ │ │ ├── textpage.po
│ │ │ ├── textwriter.mo
│ │ │ ├── textwriter.po
│ │ │ ├── the-basics.mo
│ │ │ ├── the-basics.po
│ │ │ ├── tools.mo
│ │ │ ├── tools.po
│ │ │ ├── tutorial.mo
│ │ │ ├── tutorial.po
│ │ │ ├── vars.mo
│ │ │ ├── vars.po
│ │ │ ├── version.mo
│ │ │ ├── version.po
│ │ │ ├── widget.mo
│ │ │ ├── widget.po
│ │ │ ├── xml-class.mo
│ │ │ ├── xml-class.po
│ │ │ ├── znames.mo
│ │ │ └── znames.po
│ │ └── ko/
│ │ ├── .readthedocs.yaml
│ │ └── LC_MESSAGES/
│ │ ├── 404.mo
│ │ ├── 404.po
│ │ ├── about-feature-matrix.mo
│ │ ├── about-feature-matrix.po
│ │ ├── about-performance.mo
│ │ ├── about-performance.po
│ │ ├── about.mo
│ │ ├── about.po
│ │ ├── algebra.mo
│ │ ├── algebra.po
│ │ ├── annot.mo
│ │ ├── annot.po
│ │ ├── app1.mo
│ │ ├── app1.po
│ │ ├── app2.mo
│ │ ├── app2.po
│ │ ├── app3.mo
│ │ ├── app3.po
│ │ ├── app4.mo
│ │ ├── app4.po
│ │ ├── archive-class.mo
│ │ ├── archive-class.po
│ │ ├── changes.mo
│ │ ├── changes.po
│ │ ├── classes.mo
│ │ ├── classes.po
│ │ ├── colors.mo
│ │ ├── colors.po
│ │ ├── colorspace.mo
│ │ ├── colorspace.po
│ │ ├── converting-files.mo
│ │ ├── converting-files.po
│ │ ├── coop_low.mo
│ │ ├── coop_low.po
│ │ ├── device.mo
│ │ ├── device.po
│ │ ├── displaylist.mo
│ │ ├── displaylist.po
│ │ ├── document-writer-class.mo
│ │ ├── document-writer-class.po
│ │ ├── document.mo
│ │ ├── document.po
│ │ ├── faq.mo
│ │ ├── faq.po
│ │ ├── font.mo
│ │ ├── font.po
│ │ ├── footer.mo
│ │ ├── footer.po
│ │ ├── functions.mo
│ │ ├── functions.po
│ │ ├── glossary.mo
│ │ ├── glossary.po
│ │ ├── header-404.mo
│ │ ├── header-404.po
│ │ ├── header.mo
│ │ ├── header.po
│ │ ├── how-to-open-a-file.mo
│ │ ├── how-to-open-a-file.po
│ │ ├── identity.mo
│ │ ├── identity.po
│ │ ├── index.mo
│ │ ├── index.po
│ │ ├── installation.mo
│ │ ├── installation.po
│ │ ├── irect.mo
│ │ ├── irect.po
│ │ ├── link.mo
│ │ ├── link.po
│ │ ├── linkdest.mo
│ │ ├── linkdest.po
│ │ ├── lowlevel.mo
│ │ ├── lowlevel.po
│ │ ├── matrix.mo
│ │ ├── matrix.po
│ │ ├── module.mo
│ │ ├── module.po
│ │ ├── outline.mo
│ │ ├── outline.po
│ │ ├── packaging.mo
│ │ ├── packaging.po
│ │ ├── page.mo
│ │ ├── page.po
│ │ ├── pixmap.mo
│ │ ├── pixmap.po
│ │ ├── point.mo
│ │ ├── point.po
│ │ ├── pymupdf-layout/
│ │ │ ├── index.mo
│ │ │ └── index.po
│ │ ├── pymupdf-pro/
│ │ │ ├── index.mo
│ │ │ └── index.po
│ │ ├── pymupdf4llm/
│ │ │ ├── api.mo
│ │ │ ├── api.po
│ │ │ ├── index.mo
│ │ │ └── index.po
│ │ ├── pyodide.mo
│ │ ├── pyodide.po
│ │ ├── quad.mo
│ │ ├── quad.po
│ │ ├── rag.mo
│ │ ├── rag.po
│ │ ├── recipes-annotations.mo
│ │ ├── recipes-annotations.po
│ │ ├── recipes-common-issues-and-their-solutions.mo
│ │ ├── recipes-common-issues-and-their-solutions.po
│ │ ├── recipes-drawing-and-graphics.mo
│ │ ├── recipes-drawing-and-graphics.po
│ │ ├── recipes-images.mo
│ │ ├── recipes-images.po
│ │ ├── recipes-journalling.mo
│ │ ├── recipes-journalling.po
│ │ ├── recipes-low-level-interfaces.mo
│ │ ├── recipes-low-level-interfaces.po
│ │ ├── recipes-multiprocessing.mo
│ │ ├── recipes-multiprocessing.po
│ │ ├── recipes-ocr.mo
│ │ ├── recipes-ocr.po
│ │ ├── recipes-optional-content.mo
│ │ ├── recipes-optional-content.po
│ │ ├── recipes-stories.mo
│ │ ├── recipes-stories.po
│ │ ├── recipes-text.mo
│ │ ├── recipes-text.po
│ │ ├── recipes.mo
│ │ ├── recipes.po
│ │ ├── rect.mo
│ │ ├── rect.po
│ │ ├── resources.mo
│ │ ├── resources.po
│ │ ├── shape.mo
│ │ ├── shape.po
│ │ ├── story-class.mo
│ │ ├── story-class.po
│ │ ├── supported-files-table.mo
│ │ ├── supported-files-table.po
│ │ ├── textpage.mo
│ │ ├── textpage.po
│ │ ├── textwriter.mo
│ │ ├── textwriter.po
│ │ ├── the-basics.mo
│ │ ├── the-basics.po
│ │ ├── tools.mo
│ │ ├── tools.po
│ │ ├── tutorial.mo
│ │ ├── tutorial.po
│ │ ├── vars.mo
│ │ ├── vars.po
│ │ ├── version.mo
│ │ ├── version.po
│ │ ├── widget.mo
│ │ ├── widget.po
│ │ ├── xml-class.mo
│ │ ├── xml-class.po
│ │ ├── znames.mo
│ │ └── znames.po
│ ├── lowlevel.rst
│ ├── matrix.rst
│ ├── module.rst
│ ├── ocr/
│ │ └── tesseract-language-packs.rst
│ ├── outline.rst
│ ├── packaging.rst
│ ├── page.rst
│ ├── pixmap.rst
│ ├── point.rst
│ ├── pymupdf-pro/
│ │ └── index.rst
│ ├── pymupdf4llm/
│ │ ├── api.rst
│ │ ├── index.rst
│ │ └── ocr-plugins.rst
│ ├── pyodide.rst
│ ├── quad.rst
│ ├── rag.rst
│ ├── recipes-annotations.rst
│ ├── recipes-common-issues-and-their-solutions.rst
│ ├── recipes-drawing-and-graphics.rst
│ ├── recipes-images.rst
│ ├── recipes-journalling.rst
│ ├── recipes-low-level-interfaces.rst
│ ├── recipes-multiprocessing.rst
│ ├── recipes-ocr.rst
│ ├── recipes-optional-content.rst
│ ├── recipes-stories.rst
│ ├── recipes-text.rst
│ ├── recipes.rst
│ ├── rect.rst
│ ├── requirements.txt
│ ├── resources.rst
│ ├── samples/
│ │ ├── annotations-freetext1.py
│ │ ├── annotations-freetext2.py
│ │ ├── annotations-ink.py
│ │ ├── code-printer.py
│ │ ├── filmfestival-sql.py
│ │ ├── json-example.py
│ │ ├── multiprocess-gui.py
│ │ ├── multiprocess-render.py
│ │ ├── national-capitals.py
│ │ ├── new-annots.py
│ │ ├── quickfox-image-no-go.py
│ │ ├── quickfox.py
│ │ ├── showpdf-page.py
│ │ ├── simple-grid.py
│ │ ├── story-write-stabilized-links.py
│ │ ├── story-write-stabilized.py
│ │ ├── story-write.py
│ │ ├── table01.py
│ │ └── text-lister.py
│ ├── shape.rst
│ ├── story-class.rst
│ ├── supported-files-table.rst
│ ├── textpage.rst
│ ├── textwriter.rst
│ ├── the-basics.rst
│ ├── tools.rst
│ ├── tutorial.rst
│ ├── vars.rst
│ ├── version.rst
│ ├── widget.rst
│ ├── xml-class.rst
│ └── znames.rst
├── pyproject.toml
├── pytest.ini
├── scripts/
│ ├── gh_release.py
│ ├── sysinstall.py
│ └── test.py
├── setup.py
├── src/
│ ├── __init__.py
│ ├── __main__.py
│ ├── _apply_pages.py
│ ├── _wxcolors.py
│ ├── extra.i
│ ├── fitz___init__.py
│ ├── fitz_table.py
│ ├── fitz_utils.py
│ ├── pipcl.py
│ ├── pymupdf.py
│ ├── table.py
│ ├── utils.py
│ └── wdev.py
├── src_classic/
│ ├── __init__.py
│ ├── __main__.py
│ ├── _config.h
│ ├── fitz_old.i
│ ├── helper-annot.i
│ ├── helper-convert.i
│ ├── helper-defines.i
│ ├── helper-devices.i
│ ├── helper-fields.i
│ ├── helper-fileobj.i
│ ├── helper-geo-c.i
│ ├── helper-geo-py.i
│ ├── helper-globals.i
│ ├── helper-other.i
│ ├── helper-pdfinfo.i
│ ├── helper-pixmap.i
│ ├── helper-portfolio.i
│ ├── helper-python.i
│ ├── helper-select.i
│ ├── helper-stext.i
│ ├── helper-xobject.i
│ ├── utils.py
│ └── version.i
├── tests/
│ ├── README.md
│ ├── conftest.py
│ ├── gentle_compare.py
│ ├── resources/
│ │ ├── Bezier.epub
│ │ ├── PragmaticaC.otf
│ │ ├── chinese-tables.pickle
│ │ ├── cython.pickle
│ │ ├── full_toc.txt
│ │ ├── metadata.txt
│ │ ├── simple_toc.txt
│ │ ├── symbols.txt
│ │ ├── test_2608_expected
│ │ ├── test_2608_expected_1.26
│ │ ├── test_2608_expected_1.28
│ │ ├── test_3493.epub
│ │ ├── test_3615.epub
│ │ ├── test_3654.docx
│ │ ├── test_3687-3.epub
│ │ ├── test_3687.epub
│ │ ├── test_3842_expected_1.28.txt
│ │ ├── test_3842_partial.txt
│ │ ├── test_4496.hwpx
│ │ ├── test_open2.cbz
│ │ ├── test_open2.doc
│ │ ├── test_open2.docx
│ │ ├── test_open2.epub
│ │ ├── test_open2.fb2
│ │ ├── test_open2.html
│ │ ├── test_open2.mobi
│ │ ├── test_open2.xhtml
│ │ ├── test_open2.xml
│ │ ├── test_open2.xps
│ │ └── test_open2_expected.json
│ ├── run_compound.py
│ ├── test_2548.py
│ ├── test_2634.py
│ ├── test_2904.py
│ ├── test_2907.py
│ ├── test_4141.py
│ ├── test_4503.py
│ ├── test_4505.py
│ ├── test_4520.py
│ ├── test_4614.py
│ ├── test_4716.py
│ ├── test_4767.py
│ ├── test_4942.py
│ ├── test_annots.py
│ ├── test_badfonts.py
│ ├── test_balance_count.py
│ ├── test_barcode.py
│ ├── test_clip_page.py
│ ├── test_cluster_drawings.py
│ ├── test_codespell.py
│ ├── test_crypting.py
│ ├── test_docs_samples.py
│ ├── test_drawings.py
│ ├── test_embeddedfiles.py
│ ├── test_extractimage.py
│ ├── test_flake8.py
│ ├── test_font.py
│ ├── test_general.py
│ ├── test_geometry.py
│ ├── test_imagebbox.py
│ ├── test_imagemasks.py
│ ├── test_import.py
│ ├── test_insertimage.py
│ ├── test_insertpdf.py
│ ├── test_linebreaks.py
│ ├── test_linequad.py
│ ├── test_memory.py
│ ├── test_metadata.py
│ ├── test_mupdf_regressions.py
│ ├── test_named_links.py
│ ├── test_nonpdf.py
│ ├── test_object_manipulation.py
│ ├── test_objectstreams.py
│ ├── test_optional_content.py
│ ├── test_page_links.py
│ ├── test_pagedelete.py
│ ├── test_pagelabels.py
│ ├── test_pixmap.py
│ ├── test_pylint.py
│ ├── test_release.py
│ ├── test_remove-rotation.py
│ ├── test_rewrite_images.py
│ ├── test_rtl.py
│ ├── test_showpdfpage.py
│ ├── test_spikes.py
│ ├── test_story.py
│ ├── test_tables.py
│ ├── test_tesseract.py
│ ├── test_textbox.py
│ ├── test_textextract.py
│ ├── test_textsearch.py
│ ├── test_threads.py
│ ├── test_toc.py
│ ├── test_typing.py
│ ├── test_widgets.py
│ ├── test_word_delimiters.py
│ └── util.py
└── valgrind.supp
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitattributes
================================================
*.pdf binary
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.yml
================================================
name: Bug Report
description: Create a bug report for PyMuPDF
# We omit `title: "..."` so that the field defaults to blank. If we set it to
# empty string, Github seems to reject this .yml file.
body:
- type: textarea
id: description
attributes:
label: Description of the bug
description: |
A clear and concise description of the bug.
validations:
required: true
- type: textarea
id: reproduce
attributes:
label: How to reproduce the bug
# Should not word-wrap this description here.
description: |
* Explain the steps required to reproduce the bug.
* Include required code snippets, example files, etc.
* Describe what you expected to happen (if not obvious).
* If applicable, add screenshots to help explain the problem.
* Include any other information that could be relevant, for example information about the Python environment.
For problems when building or installing PyMuPDF:
* Give the **exact** build/install commands that were run.
* Give the **complete** output from these commands.
validations:
required: true
# - type: markdown
# attributes:
# value: |
# # The information below is required.
- type: dropdown
id: version
attributes:
label: PyMuPDF version
options:
- 1.27.2.3
- 1.27.2.2
- 1.27.2
- 1.27.1
- 1.27.0
- 1.26.x or earlier
- Built from source
description: |
* For example from `pymupdf.pymupdf_version`.
* We generally only look at bugs in the most recent release of PyMuPDF.
validations:
required: true
- type: dropdown
id: os_name
attributes:
label: Operating system
#multiple: true
options:
-
- Windows
- Linux
- MacOS
- OpenBSD
- Other
validations:
required: true
- type: dropdown
id: python_version
attributes:
label: Python version
#multiple: true
# Need quotes around `3.10` otherwise it is treated as a number and shows as `3.1`.
options:
-
- "3.14"
- "3.13"
- "3.12"
- "3.11"
- "3.10"
- "3.9"
validations:
required: true
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: enhancement
assignees:
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Potentially add an issue reference.
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
Are there several options for how your request could be met?
**Additional context**
Add any other context or screenshots about the feature request here.
================================================
FILE: .github/workflows/build_wheels.yml
================================================
name: Build wheels
on:
workflow_dispatch:
inputs:
flavours:
description: 'If set, we build separate PyMuPDF and PyMuPDFb wheels.'
type: boolean
default: false
sdist:
type: boolean
default: true
wheels_linux_aarch64:
type: boolean
default: true
wheels_linux_auto:
type: boolean
default: true
wheels_linux_pyodide:
type: boolean
default: false
wheels_windows_auto:
type: boolean
default: true
wheels_macos_auto:
type: boolean
default: true
wheels_cps:
description: 'wheels_cps: sets $CIBW_BUILD, E.g. "cp310* cp311*".'
type: string
PYMUPDF_SETUP_MUPDF_BUILD:
description: 'Value for PYMUPDF_SETUP_MUPDF_BUILD, e.g.: git:--branch master https://github.com/ArtifexSoftware/mupdf.git'
type: string
default: '-'
#PYMUPDF_SETUP_MUPDF_BUILD_TYPE:
# description: 'Value for PYMUPDF_SETUP_MUPDF_BUILD, e.g. debug.'
# type: string
# default: '-'
# We can't currently have more than 10 inputs
PYMUPDF_SETUP_PY_LIMITED_API:
description: 'If not "0", we build a single wheel for each platform.'
type: string
default: ''
jobs:
build_sdist:
if: ${{ inputs.sdist }}
name: Build sdist
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build sdist
env:
inputs_wheels_default: 0
inputs_sdist: 1
inputs_flavours: ${{inputs.flavours}}
inputs_PYMUPDF_SETUP_MUPDF_BUILD: ${{inputs.PYMUPDF_SETUP_MUPDF_BUILD}}
run:
python scripts/gh_release.py
- uses: actions/upload-artifact@v4
with:
name: sdist-${{ matrix.os }}
path: dist/*.tar.gz
build_wheels:
#if: ${{ inputs.wheels }}
name: Build wheels on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
# 2024-05-08: Need to specify macos-15-intel/14 to get x86_64/arm64.
os: [ubuntu-latest, windows-2019, macos-15-intel, macos-14]
# Avoid cancelling of all cibuildwheel runs after a single failure.
fail-fast: false
steps:
- uses: actions/checkout@v4
# Get Python 3.12 x32 and x64 on Windows. (As of 2023-10-12 these are not
# always available by default.)
#
- name: Install Python 3.12 x32 on Windows.
if: runner.os == 'Windows'
uses: actions/setup-python@v5
with:
python-version: '3.12'
architecture: x86
- name: Install Python 3.12 x64 on Windows.
if: runner.os == 'Windows'
uses: actions/setup-python@v5
with:
python-version: '3.12'
# Get Python for running cibuildwheel. This also ensures that 'python'
# works on MacOS, where it seems only 'python3' is available by default.
#
# Note that it seem to be important on MacOS not to specify a
# Python version here with `python-version: '3.12'` - this makes
# `python-config3` return settings for Python-3.12, instead of for
# whatever Python is being used by cibuildwheel.
#
- uses: actions/setup-python@v5
# On Linux, get qemu so we can build for aarch64.
#
- name: Set up QEMU
if: runner.os == 'Linux'
uses: docker/setup-qemu-action@v1
with:
platforms: all
- name: gh_release
# Doesn't seem to be a way to passing inputs.* on command
# line, so we set environment instead. E.g. see:
# https://github.com/orgs/community/discussions/27088
#
env:
inputs_flavours: ${{inputs.flavours}}
inputs_sdist: ${{inputs.sdist}}
inputs_wheels_linux_aarch64: ${{inputs.wheels_linux_aarch64}}
inputs_wheels_linux_auto: ${{inputs.wheels_linux_auto}}
inputs_wheels_linux_pyodide: ${{inputs.wheels_linux_pyodide}}
#inputs_wheels_macos_arm64: ${{inputs.wheels_macos_arm64}}
inputs_wheels_macos_auto: ${{inputs.wheels_macos_auto}}
inputs_wheels_windows_auto: ${{inputs.wheels_windows_auto}}
inputs_PYMUPDF_SETUP_MUPDF_BUILD: ${{inputs.PYMUPDF_SETUP_MUPDF_BUILD}}
#inputs_PYMUPDF_SETUP_MUPDF_BUILD_TYPE: ${{inputs.PYMUPDF_SETUP_MUPDF_BUILD_TYPE}}
inputs_wheels_cps: ${{inputs.wheels_cps}}
PYMUPDF_SETUP_PY_LIMITED_API: ${{inputs.PYMUPDF_SETUP_PY_LIMITED_API}}
run:
python scripts/gh_release.py
# Upload generated wheels, to be accessible from github Actions page.
#
- uses: actions/upload-artifact@v4
with:
name: wheels-${{ matrix.os }}
path: ./wheelhouse/*.whl
================================================
FILE: .github/workflows/cla.yml
================================================
name: "CLA Assistant"
on:
pull_request_target:
types: [opened,closed,synchronize]
jobs:
CLAAssistant:
runs-on: ubuntu-latest
steps:
- name: "CLA Assistant"
if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target'
# Beta Release
uses: contributor-assistant/github-action@v2.4.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# the below token should have repo scope and must be manually added by you in the repository's secret
PERSONAL_ACCESS_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
with:
path-to-signatures: 'signatures/version1/cla.json'
path-to-document: 'https://artifex.com/documents/Artifex%20Contributor%20License%20Agreement.pdf'
# branch should not be protected
branch: 'CLA'
allowlist:
# the following are the optional inputs - If the optional inputs are not given, then default values will be taken
#remote-organization-name: enter the remote organization name where the signatures should be stored (Default is storing the signatures in the same repository)
#remote-repository-name: enter the remote repository name where the signatures should be stored (Default is storing the signatures in the same repository)
#create-file-commit-message: 'For example: Creating file for storing CLA Signatures'
#signed-commit-message: 'For example: $contributorName has signed the CLA in #$pullRequestNo'
#custom-notsigned-prcomment: 'pull request comment with Introductory message to ask new contributors to sign'
#custom-pr-sign-comment: 'The signature to be committed in order to sign the CLA'
#custom-allsigned-prcomment: 'pull request comment when all contributors has signed, defaults to **CLA Assistant Lite bot** All Contributors have signed the CLA.'
#lock-pullrequest-aftermerge: false - if you don't want this bot to automatically lock the pull request after merging (default - true)
#use-dco-flag: true - If you are using DCO instead of CLA
================================================
FILE: .github/workflows/test-valgrind.yml
================================================
name: Test valgrind
on:
workflow_dispatch:
schedule:
- cron: '13 6 * * *'
jobs:
valgrind:
name: valgrind
runs-on: ubuntu-latest
strategy:
matrix:
args: [
'',
'-m "git:--branch master https://github.com/ArtifexSoftware/mupdf"',
'-m "git:--branch 1.27.x https://github.com/ArtifexSoftware/mupdf"',
]
fail-fast: false
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
- name: valgrind
run:
python scripts/test.py ${{matrix.args}} -P 1 -T valgrind build test
================================================
FILE: .github/workflows/test.yml
================================================
# Run scripts/test.py directly on multiple Github servers. Instead of
# specifying individual inputs, we support a single string input which is used
# for the command line directly.
#
# This ensures we behave exactly like scripts/test.py, without confusion caused
# by having to translate between differing APIs.
name: Tests
on:
#schedule:
# - cron: '47 4 * * *'
#pull_request:
# branches: [main]
workflow_dispatch:
inputs:
args:
type: string
default: ''
description: 'Arguments to pass to scripts/test.py'
jobs:
test:
name: Test
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-2022, macos-15-intel, macos-14]
# Avoid cancelling of all runs after a single failure.
fail-fast: false
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
# https://github.com/pypa/cibuildwheel/issues/2114
# https://cibuildwheel.pypa.io/en/stable/faq/#emulation
#
- name: Set up QEMU
if: runner.os == 'Linux' && runner.arch == 'X64'
uses: docker/setup-qemu-action@v3
with:
platforms: all
- name: test
env:
PYMUPDF_test_args: ${{inputs.args}}
run:
python scripts/test.py -a PYMUPDF_test_args
# Upload generated wheels, to be accessible from github Actions page.
#
- uses: actions/upload-artifact@v4
with:
path: |
wheelhouse/pymupdf*.whl
wheelhouse/pymupdf*.tar.gz
name: artifact-${{ matrix.os }}
================================================
FILE: .github/workflows/test_multiple.yml
================================================
# Run scripts/test.py on multiple OS's (Windows, Linux, MacOS x64, MacOS arm64)
# and with multiple specifications of MuPDF (PyMuPDF's hard-coded default,
# master branch, release branch).
name: multiple
on:
workflow_dispatch:
inputs:
args:
type: string
default: ''
description: 'Additional arguments to scripts/test.py'
schedule:
- cron: '13 6 * * *'
jobs:
multiple:
name: multiple
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-2022, macos-15-intel, macos-14]
args: [
'',
'-m "git:--branch master https://github.com/ArtifexSoftware/mupdf"',
'-m "git:--branch 1.27.x https://github.com/ArtifexSoftware/mupdf"',
]
fail-fast: false
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
- name: multiple
env:
PYMUPDF_test_args: ${{inputs.args}}
run:
python scripts/test.py ${{matrix.args}} wheel test -a PYMUPDF_test_args
================================================
FILE: .github/workflows/test_pyodide.yml
================================================
name: Test pyodide
# Build and test pyodide wheels using cibuildwheel.
on:
workflow_dispatch:
schedule:
- cron: '13 5 * * *'
jobs:
pyodide:
name: pyodide
runs-on: ubuntu-latest
strategy:
matrix:
# 2025-09-05: We don't test with default mupdf because mupdf-1.26.7
# does not have the required pyodide rpath changes.
args: [
# '',
'-m "git:--branch master https://github.com/ArtifexSoftware/mupdf"',
'-m "git:--branch 1.27.x https://github.com/ArtifexSoftware/mupdf"',
]
fail-fast: false
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: 3.12
- name: pyodide
run:
python scripts/test.py ${{matrix.args}} --cibw-pyodide 1 cibw
# We do not use upload-artifact@v4 because it fails due to us creating
# identically-named wheels.
#- uses: actions/upload-artifact@v4
# with:
# path: ./wheelhouse/*.whl
================================================
FILE: .github/workflows/test_quick.yml
================================================
name: test_quick
on:
pull_request:
branches: [main]
workflow_dispatch:
inputs:
args:
type: string
default: ''
description: 'Additional arguments to scripts/test.py'
jobs:
master:
name: mupdf master
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
fail-fast: false
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
- name: mupdf master
env:
PYMUPDF_test_args: ${{inputs.args}}
run:
python scripts/test.py build test -m 'git:--branch master https://github.com/ArtifexSoftware/mupdf.git' -a PYMUPDF_test_args
release:
name: mupdf release
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
fail-fast: false
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
- name: mupdf release
env:
PYMUPDF_test_args: ${{inputs.args}}
run:
python scripts/test.py build test -m 'git:--branch 1.27.x https://github.com/ArtifexSoftware/mupdf.git' -a PYMUPDF_test_args
================================================
FILE: .github/workflows/test_sysinstall.yml
================================================
name: Test sysinstall
on:
schedule:
- cron: '13 4 * * *'
workflow_dispatch:
inputs:
args:
description: 'Extra args for scripts/sysinstall.py.'
jobs:
sysinstall:
name: Test sysinstall
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v4
# It seems to be important not to install a custom python here,
# because `sudo` (which we need to use when installing to /usr/local
# etc) always ends up running the default python, even if we set
# $PATH etc. So for example we can end up with mupdf files and
# pymupdf files being installed into .../python3.11/site-packages and
# .../python3.10/site-packages, and tests all fail to import pymupdf.
#
#- uses: actions/setup-python@v5
#with:
# # 3.12 doesn't have setuptools. As of 2024-01-03, MuPDF build requires setuptools before it
# # sees `--venv` and defers to a venv, so we currently have to force use of python 3.11.
# python-version: '3.11'
- name: sysinstall_venv
env:
PYMUDF_SCRIPTS_SYSINSTALL_ARGS_POST: ${{inputs.args}}
run:
# Use venv.
python3 scripts/sysinstall.py --mupdf-git '--branch master https://github.com/ArtifexSoftware/mupdf.git'
- name: sysinstall_sudo
env:
PYMUDF_SCRIPTS_SYSINSTALL_ARGS_POST: ${{inputs.args}}
run:
# Do not use a venv, instead install required packages with sudo.
python3 scripts/sysinstall.py --mupdf-git '--branch master https://github.com/ArtifexSoftware/mupdf.git' --pip sudo --root /
================================================
FILE: .gitignore
================================================
*.pyc
*.so
*.o
*.swp
build/
demo/README.rst
docs/build
docs/_build
================================================
FILE: .python-version
================================================
3.12
================================================
FILE: .readthedocs.yaml
================================================
# .readthedocs.yaml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
# Set the version of Python and other tools you might need
build:
os: ubuntu-20.04
tools:
python: "3.13" # let's use the default Python version provided by Read the Docs
# You can also specify other tool versions:
# nodejs: "16"
# rust: "1.55"
# golang: "1.17"
# Build documentation in the docs/ directory with Sphinx
sphinx:
configuration: docs/conf.py
# If using Sphinx, optionally build your docs in additional formats such as PDF
formats: all
# Optionally declare the Python requirements required to build your docs
python:
install:
- requirements: docs/requirements.txt
================================================
FILE: .vs/ProjectSettings.json
================================================
{
"CurrentProjectSetting": ""
}
================================================
FILE: .vs/VSWorkspaceState.json
================================================
{
"ExpandedNodes": [
""
],
"SelectedNode": "",
"PreviewInSolutionExplorer": false
}
================================================
FILE: COPYING
================================================
GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
our General Public Licenses are intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.
A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate. Many developers of free software are heartened and
encouraged by the resulting cooperation. However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.
The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community. It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server. Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.
An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals. This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU Affero General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Remote Network Interaction; Use with the GNU General Public License.
Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software. This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the work with which it is combined will remain governed by version
3 of the GNU General Public License.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU Affero General Public License from time to time. Such new versions
will be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU Affero General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU Affero General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU Affero General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source. For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code. There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for the
specific requirements.
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see
<http://www.gnu.org/licenses/>.
================================================
FILE: README.md
================================================
<p align="center">
<a href="https://github.com/pymupdf/PyMuPDF/">
<img loading="lazy" alt="PyMuPDF" src="https://pymupdf.pro/images/py-mupdf-github-icon.png" width="100px"/>
</a>
</p>
# PyMuPDF
<p align="center">
<a href="https://trendshift.io/repositories/11536" target="_blank"><img src="https://trendshift.io/api/badge/repositories/11536" alt="pymupdf%2FPyMuPDF | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
</p>
[](https://pymupdf.readthedocs.io)
[](https://pypi.org/project/PyMuPDF/)
[](https://pypi.org/project/pymupdf/)
[](https://github.com/pymupdf/PyMuPDF/blob/master/COPYING)
[](https://pepy.tech/projects/pymupdf)
[](https://github.com/pymupdf/PyMuPDF/stargazers)
[](https://pymupdf.io/discord/artifex/)
[](https://forum.mupdf.com/c/general/4)
[](https://x.com/pymupdf4llm)
[](https://huggingface.co/artifex-software)
[](https://demo.pymupdf.io)
**The PDF engine behind over 50 million monthly downloads, powering AI pipelines worldwide.**
**PyMuPDF is a high-performance Python library for data extraction, analysis, conversion, rendering and manipulation of PDF (and other) documents.** Built on top of MuPDF — a lightweight, fast C engine — PyMuPDF gives you precise, low-level control over documents alongside high-level convenience APIs. No mandatory external dependencies.
[](https://github.com/pymupdf/PyMuPDF/)
---
## Why PyMuPDF?
- **Fast** — powered by [MuPDF](https://mupdf.com/), a best-in-class C rendering engine
- **Accurate** — pixel-perfect text extraction with font, color, and position metadata
- **Versatile** — read, write, annotate, redact, merge, split, and convert documents
- **LLM-ready** — native Markdown output via [PyMuPDF4LLM](https://pypi.org/project/pymupdf4llm/) for RAG and AI pipelines
- **No mandatory dependencies** — `pip install pymupdf` and you're done
---
## Installation
```bash
pip install pymupdf
```
Wheels are available for **Windows**, **macOS**, and **Linux** on Python 3.10–3.14. If no pre-built wheel exists for your platform, pip will compile from source (requires a C/C++ toolchain).
### Optional extras
| Package | Purpose |
|---|---|
| `pymupdf-fonts` | Extended font collection for text output |
| `pymupdf4llm` | LLM/RAG-optimised Markdown and JSON extraction |
| `pymupdfpro` | Adds Office document support |
| `tesseract-ocr` | OCR for scanned pages and images (separate install) |
```bash
# More fonts
pip install pymupdf-fonts
# LLM-ready extraction
pip install pymupdf4llm
# Office support
pip install pymupdfpro
# OCR (Tesseract must be installed separately)
# macOS
brew install tesseract
# Ubuntu / Debian
sudo apt install tesseract-ocr
```
---
## Supported File Formats
### Input
| Category | Formats |
|---|---|
| PDF & derivatives | PDF, XPS, EPUB, CBZ, MOBI, FB2, SVG, TXT |
| Images | PNG, JPEG, BMP, TIFF, GIF, and more |
| Microsoft Office *(Pro)* | DOC, DOCX, XLS, XLSX, PPT, PPTX |
| Korean Office *(Pro)* | HWP, HWPX |
### Output
| Format | Notes |
|---|---|
| PDF | Full fidelity conversion from Office formats |
| SVG | Vector page rendering |
| Image (PNG, JPEG, …) | Page rasterisation at any DPI |
| Markdown | Structure-aware, LLM-ready |
| JSON | Bounding boxes, layout data, per-element detail |
| Plain text | Fast, lightweight extraction |
---
## Quick start
### Extract text
```python
import pymupdf
doc = pymupdf.open("document.pdf")
for page in doc:
print(page.get_text())
```
### Extract text with layout metadata
```python
import pymupdf
doc = pymupdf.open("document.pdf")
page = doc[0]
blocks = page.get_text("dict")["blocks"]
for block in blocks:
if block["type"] == 0: # text block
for line in block["lines"]:
for span in line["spans"]:
print(f"{span['text']!r} font={span['font']} size={span['size']:.1f}")
```
### Extract tables
```python
import pymupdf
doc = pymupdf.open("spreadsheet.pdf")
page = doc[0]
tables = page.find_tables()
for table in tables:
print(table.to_markdown())
# or get as Pandas DataFrame
df = table.to_pandas()
```
### Render a page to an image
```python
import pymupdf
doc = pymupdf.open("document.pdf")
page = doc[0]
pixmap = page.get_pixmap(dpi=150)
pixmap.save("page_0.png")
```
### OCR a scanned document
```python
import pymupdf
doc = pymupdf.open("scanned.pdf")
page = doc[0]
# Requires Tesseract installed and on PATH
text = page.get_textpage_ocr(language="eng").extractText()
print(text)
```
### Convert to Markdown for LLMs
```python
import pymupdf4llm
md = pymupdf4llm.to_markdown("report.pdf")
# Pass directly to your LLM or vector store
print(md)
```
### Annotate and redact
```python
import pymupdf
doc = pymupdf.open("contract.pdf")
page = doc[0]
# Add a highlight annotation
rect = pymupdf.Rect(72, 100, 400, 120)
page.add_highlight_annot(rect)
# Add a redaction and apply it
page.add_redact_annot(rect)
page.apply_redactions()
doc.save("contract_redacted.pdf")
```
### Merge PDFs
```python
import pymupdf
merger = pymupdf.open()
for path in ["part1.pdf", "part2.pdf", "part3.pdf"]:
merger.insert_pdf(pymupdf.open(path))
merger.save("merged.pdf")
```
### Convert an Office document to PDF
```python
import pymupdf.pro
pymupdf.pro.unlock("YOUR-LICENSE-KEY")
doc = pymupdf.open("presentation.pptx")
pdf_bytes = doc.convert_to_pdf()
with open("output.pdf", "wb") as f:
f.write(pdf_bytes)
```
### Extract LLM-ready Markdown from a Word document
```python
import pymupdf4llm
import pymupdf.pro
pymupdf.pro.unlock("YOUR-LICENSE-KEY")
md = pymupdf4llm.to_markdown("document.docx")
print(md)
```
---
## Features
### Core capabilities
| Feature | Description |
|---|---|
| **Text extraction** | Plain text, rich dict (font, size, color, bbox), HTML, XML, raw blocks |
| **Table detection** | `find_tables()` — locate, extract, and export tables as Markdown or structured data |
| **Image extraction** | Extract embedded images and render any page to a high-resolution `Pixmap` |
| **Rendering** | Render PDF pages to images or `Pixmap` data for use in UI or other workflows |
| **OCR** | Tesseract integration — full-page or partial OCR, configurable language |
| **Annotations** | Read and write highlights, underlines, squiggly lines, sticky notes, free text, ink, stamps |
| **Redaction** | Add and permanently apply redaction annotations |
| **Forms** | Read and fill PDF AcroForm fields |
| **PDF editing** | Insert, delete, and reorder pages; set metadata; merge and split documents |
| **Drawing** | Draw lines, curves, rectangles, and circles; insert HTML boxes |
| **Encryption** | Open password-protected PDFs; save with RC4 or AES encryption |
| **Links** | Extract hyperlinks, internal cross-references, and URI targets |
| **Bookmarks** | Read and write the outline / table of contents tree |
| **Metadata** | Title, author, creation date, producer, subject, and custom entries |
| **Color spaces** | RGB, CMYK, greyscale; color space conversion |
### LLM & AI output (via PyMuPDF4LLM)
| Output | API |
|---|---|
| Markdown | `pymupdf4llm.to_markdown(path)` |
| JSON | `pymupdf4llm.to_json(path)` |
| Plain text | `pymupdf4llm.to_text(path)` |
Supports multi-column layouts, natural reading order and page chunking.
[](https://demo.pymupdf.io)
---
## Supported Python versions
Python **3.10 – 3.14** (as of v1.27.x). Wheels ship for:
- `manylinux` x86\_64 and aarch64
- `musllinux` x86\_64
- macOS x86\_64 and arm64
- Windows x86 and x86\_64
---
## Performance
PyMuPDF is built on MuPDF — one of the fastest PDF rendering engines available. Typical benchmarks against pure-Python PDF libraries show **10–50× speed improvements** for text extraction and **100× or more** for page rendering, with a minimal memory footprint.
For AI workloads, PyMuPDF4LLM processes documents **without a GPU**, cutting infrastructure costs significantly compared to vision-based LLM approaches.
---
## Recipes
<details>
<summary>Extract all images from a PDF</summary>
```python
import pymupdf
from pathlib import Path
doc = pymupdf.open("document.pdf")
out = Path("images")
out.mkdir(exist_ok=True)
for page_index, page in enumerate(doc):
for img_index, img in enumerate(page.get_images()):
xref = img[0]
pix = pymupdf.Pixmap(doc, xref)
if pix.n > 4: # convert CMYK
pix = pymupdf.Pixmap(pymupdf.csRGB, pix)
pix.save(out / f"page{page_index}_img{img_index}.png")
```
</details>
<details>
<summary>Search for text across a document</summary>
```python
import pymupdf
doc = pymupdf.open("document.pdf")
needle = "confidential"
for page in doc:
hits = page.search_for(needle)
if hits:
print(f"Page {page.number}: {len(hits)} occurrence(s)")
for rect in hits:
page.add_highlight_annot(rect)
doc.save("highlighted.pdf")
```
</details>
<details>
<summary>Split a PDF into individual pages</summary>
```python
import pymupdf
doc = pymupdf.open("document.pdf")
for i, page in enumerate(doc):
out = pymupdf.open()
out.insert_pdf(doc, from_page=i, to_page=i)
out.save(f"page_{i + 1}.pdf")
```
</details>
<details>
<summary>Insert a watermark on every page</summary>
```python
import pymupdf
doc = pymupdf.open("document.pdf")
for page in doc:
page.insert_text(
point=pymupdf.Point(72, page.rect.height / 2),
text="DRAFT",
fontsize=72,
color=(0.8, 0.8, 0.8),
rotate=45,
)
doc.save("watermarked.pdf")
```
</details>
---
## Office Document Processing
PyMuPDF can be extended with PyMuPDF Pro. This adds a conversion layer that handles Microsoft and Korean Office formats natively — no Office installation, no COM interop, no LibreOffice subprocess.
Once unlocked, `pymupdf.open()` accepts Office files exactly like PDFs:
```python
import pymupdf.pro
pymupdf.pro.unlock("YOUR-LICENSE-KEY")
# Works identically regardless of format
for fmt in ["contract.docx", "data.xlsx", "deck.pptx", "report.hwpx"]:
doc = pymupdf.open(fmt)
for page in doc:
print(page.get_text())
```
[Get a trial license key for PyMuPDF Pro](https://pymupdf.pro/try-pro)
**What you can do with Office documents:**
- Extract text and images page-by-page
- Convert to PDF with `doc.convert_to_pdf()`
- Rasterise pages to PNG/JPEG for visual inspection
- Feed directly into PyMuPDF4LLM for AI-ready output
### Restrictions Without a License Key
When `pymupdf.pro.unlock()` is called **without** a key, the following restrictions apply:
| Restriction | Detail |
|---|---|
| Page limit | Only the **first 3 pages** of any document are accessible |
| Time limit | Evaluation period — functionality expires after a set duration |
All other Pro features work normally within these constraints, making it straightforward to prototype before purchasing a license.
---
## Frequently Asked Questions
### Can I use PyMuPDF, PyMuPDF4LLM and PyMuPDF Pro without sending data to the cloud?
Yes, absolutely — and this is one of PyMuPDF's most significant advantages.
PyMuPDF runs entirely locally. It is a native Python library built on top of the MuPDF C engine. When you call `pymupdf.open()`, `page.get_text()`, `page.find_tables()`, or any other method, everything executes in-process on your own machine. No data is transmitted anywhere.
There are no telemetry calls, no licence validation callbacks, no cloud dependencies of any kind in the open-source AGPL build or the commercial build. Once the package is installed, it works fully air-gapped.
This makes PyMuPDF well-suited for:
- Regulated industries — healthcare (HIPAA), finance, legal, government, where documents cannot leave a controlled environment
- On-premise deployments — servers with no outbound internet access
- Air-gapped systems — classified or sensitive environments
- Self-hosted RAG pipelines — processing confidential documents locally before feeding an on-premise LLM
- Saving on token costs for document pre-processing before sending data to your LLM
The only thing you need an internet connection for is the initial `pip install`. After that, the package and all its capabilities are entirely self-contained.
### Should I `import pymupdf` or `import fitz`?
Use `import pymupdf`. The `fitz` name is a legacy alias that still works as of v1.24.0+, but `import pymupdf` is the recommended and future-proof approach. The two are interchangeable in existing code:
```python
import pymupdf # recommended
# import fitz # legacy alias — still works but avoid for new code
```
### Does PyMuPDF work with Korean, Japanese, or Chinese documents?
Yes — PyMuPDF has solid CJK support
### How do I extract Markdown from PDF for LLM?
Let PyMuPDF4LLM do everything (recommended for RAG).
PyMuPDF4LLM is a high-level wrapper that outputs standard text and table content together in an integrated Markdown-formatted string across all document pages PyMuPDF — tables are detected, converted to GitHub-compatible Markdown, and interleaved with surrounding text in the correct reading order. This is the best starting point for feeding an LLM or building a RAG pipeline.
```python
import pymupdf4llm
md = pymupdf4llm.to_markdown("report.pdf")
print(md)
# Tables appear as Markdown | col1 | col2 | ... inline with the text
```
### Text extraction returns garbled characters or empty output. Why?
This usually means the PDF uses custom font encodings without a proper character map (CMAP). The font's glyphs are present but cannot be mapped back to Unicode. In these cases:
- Use OCR as a fallback (`page.get_textpage_ocr()`)
- Consider that scanned PDFs will always need OCR — text extraction on scans returns nothing
### How do I extract text from a specific area of a page?
Pass a `clip` rectangle to `get_text()`:
```python
import pymupdf
doc = pymupdf.open("input.pdf")
page = doc[0]
# Define the area you want (x0, y0, x1, y1) in points
clip = pymupdf.Rect(50, 100, 400, 300)
text = page.get_text("text", clip=clip)
```
### How do I search for text and find its location on the page?
```python
import pymupdf
doc = pymupdf.open("input.pdf")
page = doc[0]
# Returns a list of Rect objects surrounding each match
locations = page.search_for("invoice number")
for rect in locations:
print(rect) # e.g. Rect(72.0, 120.5, 210.0, 134.0)
```
### `get_images` shows no images but I can clearly see charts in the PDF. Why?
Charts and diagrams created by tools like matplotlib, Excel, or R are typically rendered as vector graphics (PDF drawing commands), not raster images. `get_images` only lists embedded raster image objects and will not detect vector graphics. To capture these, rasterise the entire page with `page.get_pixmap()`.
### How does OCR work in PyMuPDF? Does it require a separate Tesseract installation?
PyMuPDF uses MuPDF's built-in Tesseract-based OCR support, so there is no Python-level `pytesseract` dependency. However, PyMuPDF still needs access to the **Tesseract language data files** (`tessdata`), and automatic tessdata discovery may invoke the `tesseract` executable (for example, to list available languages) if you do not explicitly provide a tessdata path. In practice, the recommended setup is to either install Tesseract so discovery works automatically, or configure the tessdata location yourself via the `tessdata` parameter or the `TESSDATA_PREFIX` environment variable. Over 100 languages are supported.
```python
import pymupdf
doc = pymupdf.open("scanned.pdf")
page = doc[0]
# Get a text page using OCR
tp = page.get_textpage_ocr(language="eng")
text = page.get_text(textpage=tp)
print(text)
```
### How do I run OCR on a standalone image file (not a PDF)?
```python
import pymupdf
pix = pymupdf.Pixmap("image.png")
if pix.alpha:
pix = pymupdf.Pixmap(pix, 0) # remove alpha channel — required for OCR
# Wrap in a 1-page PDF and OCR it
doc = pymupdf.open()
page = doc.new_page(width=pix.width, height=pix.height)
page.insert_image(page.rect, pixmap=pix)
tp = page.get_textpage_ocr()
text = page.get_text(textpage=tp)
```
### How do I highlight text in a PDF?
```python
import pymupdf
doc = pymupdf.open("input.pdf")
page = doc[0]
# Use quads=True for accurate highlights on non-horizontal text
quads = page.search_for("important term", quads=True)
page.add_highlight_annot(quads)
doc.save("highlighted.pdf")
```
PyMuPDF supports all standard PDF text markers: highlight, underline, strikeout, and squiggly.
### How do I permanently redact (remove) content from a PDF?
Redaction is a deliberate two-step process so you can review before committing:
```python
import pymupdf
doc = pymupdf.open("input.pdf")
page = doc[0]
# Step 1: Mark the area(s) to redact
rect = page.search_for("confidential")[0]
page.add_redact_annot(rect, fill=(1, 1, 1)) # white fill
# Step 2: Apply — permanently removes the underlying content
page.apply_redactions()
doc.save("redacted.pdf")
```
After `apply_redactions()`, the original content is gone. It cannot be recovered from the saved file.
### How do I read form field values from a PDF?
```python
import pymupdf
doc = pymupdf.open("form.pdf")
page = doc[0]
for field in page.widgets():
print(f"{field.field_name}: {field.field_value}")
```
### How do I fill in a PDF form programmatically?
```python
import pymupdf
doc = pymupdf.open("form.pdf")
page = doc[0]
for field in page.widgets():
if field.field_name == "First Name":
field.field_value = "Ada"
field.update()
doc.save("filled_form.pdf")
```
### Can I use multithreading with PyMuPDF?
No. PyMuPDF does not support multithreaded use, even with Python's newer free-threading mode. The underlying MuPDF library only provides partial thread safety, and a fully thread-safe PyMuPDF implementation would still impose a single-threaded overhead — negating the benefit.
**Use multiprocessing instead.** Each process opens the file independently and works on its own page range:
```python
from multiprocessing import Pool
import pymupdf
def process_pages(args):
path, start, end = args
doc = pymupdf.open(path) # each process opens its own handle
results = []
for i in range(start, end):
results.append(doc[i].get_text())
return results
with Pool(4) as pool:
chunks = [("input.pdf", 0, 25), ("input.pdf", 25, 50), ...]
all_results = pool.map(process_pages, chunks)
```
### How can I speed up repeated text extraction on the same page?
Reuse a `TextPage` object. Creating a `TextPage` is the expensive part — once created, switching between extraction formats is cheap:
```python
import pymupdf
page = doc[0]
tp = page.get_textpage() # create once
text = page.get_text("text", textpage=tp)
words = page.get_text("words", textpage=tp)
data = page.get_text("dict", textpage=tp)
```
This can reduce execution time by 50–95% for repeated extractions on the same page.
### How do I read and write PDF metadata?
```python
import pymupdf
doc = pymupdf.open("input.pdf")
# Read
print(doc.metadata)
# {'title': '...', 'author': '...', 'subject': '...', 'keywords': '...', ...}
# Write
doc.set_metadata({
"title": "Annual Report 2025",
"author": "Finance Team",
"keywords": "annual, finance, 2025"
})
doc.save("output.pdf")
```
### How do I read or set the table of contents / bookmarks?
```python
import pymupdf
doc = pymupdf.open("input.pdf")
# Read — returns a list of [level, title, page_number] entries
toc = doc.get_toc()
for level, title, page in toc:
print(" " * level, title, "→ page", page)
# Write
new_toc = [
[1, "Introduction", 1],
[1, "Methods", 5],
[2, "Data sources", 6],
]
doc.set_toc(new_toc)
doc.save("output.pdf")
```
---
## Documentation
Full installation guide, API reference, cookbook, and tutorial at **[pymupdf.readthedocs.io](https://pymupdf.readthedocs.io)**.
- [Installation guide](https://pymupdf.readthedocs.io/en/latest/installation.html)
- [API reference](https://pymupdf.readthedocs.io/en/latest/classes.html)
- [Cookbook](https://pymupdf.readthedocs.io/en/latest/the-basics.html)
- [Tutorial](https://pymupdf.readthedocs.io/en/latest/tutorial.html)
- [Changelog](https://pymupdf.readthedocs.io/en/latest/changes.html)
- [PyMuPDF4LLM docs](https://pymupdf.readthedocs.io/en/latest/pymupdf4llm/)
- [PyMuPDF Pro docs](https://pymupdf.readthedocs.io/en/latest/pymupdf-pro/index.html)
---
## Related projects
| Project | Description |
|---|---|
| [PyMuPDF4LLM](https://github.com/pymupdf/pymupdf4llm) | LLM/RAG-optimised Markdown and JSON extraction |
| [PyMuPDF Pro](https://pymupdf.io/pro) | Adds Office and HWP document support |
| [pymupdf-fonts](https://pypi.org/project/pymupdf-fonts/) | Extended font collection for PyMuPDF text output |
---
## Licensing
PyMuPDF and MuPDF are maintained by [Artifex Software, Inc.](https://artifex.com)
- **Open source** — [GNU AGPL v3](https://www.gnu.org/licenses/agpl-3.0.html). Free for open-source projects.
- **Commercial** — separate commercial licences available from [Artifex](https://artifex.com/licensing) for proprietary applications.
---
## Contributing
Contributions are welcome. Please open an issue before submitting large pull requests.
- [Issue tracker](https://github.com/pymupdf/PyMuPDF/issues)
- [Discord community](https://pymupdf.pro/discord/artifex/)
## ⭐ Support this project
If you find this useful, please consider giving it a star — it helps others discover it!
[](https://github.com/pymupdf/PyMuPDF/)
================================================
FILE: READMEb.md
================================================
# PyMuPDFb
This wheel contains [MuPDF](https://mupdf.readthedocs.io/) shared libraries for
use by [PyMuPDF](https://pymupdf.readthedocs.io/).
This wheel is shared by PyMuPDF wheels that are specific to different Python
versions, significantly reducing the total size of a release.
================================================
FILE: READMEd.md
================================================
# PyMuPDFd
This wheel contains [MuPDF](https://mupdf.readthedocs.io/) build-time files
that were used to build [PyMuPDF](https://pymupdf.readthedocs.io/).
================================================
FILE: changes.txt
================================================
Change Log
==========
**Changes in version 1.27.2.3** (2026-04-24)
* Fixed issues:
* **Fixed** `4928 <https://github.com/pymupdf/PyMuPDF/issues/4928>`_: pymupdf.Document.scrub raises AttributeError for a document with annotations
* **Fixed** `4942 <https://github.com/pymupdf/PyMuPDF/issues/4942>`_: bug: IndexError for Page.get_links after Page.clip_to_rect
* **Fixed** `4954 <https://github.com/pymupdf/PyMuPDF/issues/4954>`_: get_drawings() returns incorrect lineJoin and width
* **Fixed** `4958 <https://github.com/pymupdf/PyMuPDF/issues/4958>`_: bug: inserting rotated pages to another document messes up link coordinates
* Other:
* Fixed incorrect generation of `lineJoin j` in PDF content, introduced in 1.27.2.2.
* Allow build to (incorrectly) claim to be thread-safe, for #4760. See setup.py for details.
* Use pypi.org's pipcl package instead of our own pipcl.py file.
**Changes in version 1.27.2.2** (2026-03-20)
* Fixed issues:
* **Fixed** `4902 <https://github.com/pymupdf/PyMuPDF/issues/4902>`_: Incorrect linewidth in elements returned by Page.get_texttrace()
* **Fixed** `4932 <https://github.com/pymupdf/PyMuPDF/issues/4932>`_: "Page" has no attribute "find_tables" in PyMuPDF 1.27
* Other:
* Added `Annot.__bool__()`.
**Changes in version 1.27.2.** (2026-03-10)
* Use MuPDF-1.27.2.
* Fixed issues:
* **Fixed** `4903 <https://github.com/pymupdf/PyMuPDF/issues/4903>`_: Typing broken because of `*_forward_decl`
* Other:
* Retrospectively marked #4907 as fixed in pymupdf-1.27.1.
* Improved `get_textpage_ocr()`.
For partial OCR, **all** page areas outside legible text are now OCRed, not
just those within images. This means that OCR will now also be performed
for vector graphics, and for text containing illegible characters.
* Provide a Linux wheel for free-threading python,
specifically cp314-cp314t-manylinux_2_28_x86_64.
**Changes in version 1.27.1** (2026-02-11)
* Use MuPDF-1.27.1.
* Fixed issues:
* **Fixed** `4599 <https://github.com/pymupdf/PyMuPDF/issues/4599>`_: page.cluster_drawings extract a lot of small clusters once upgraded to 1.26
* **Fixed** `4751 <https://github.com/pymupdf/PyMuPDF/issues/4751>`_: Memory leaking in page.widgets()
* **Fixed** `4762 <https://github.com/pymupdf/PyMuPDF/issues/4762>`_: Importing pymupdf make pillow segmentation fault for converting jp2 file on ArchLinux
* **Fixed** `4790 <https://github.com/pymupdf/PyMuPDF/issues/4790>`_: Problem to delete pages on PDF
* **Fixed** `4857 <https://github.com/pymupdf/PyMuPDF/issues/4857>`_: Package is missing py.typed file required for type checking
* **Fixed** `4886 <https://github.com/pymupdf/PyMuPDF/issues/4886>`_: <IMG> width attribute behaviour seems wrong
* **Fixed** `4907 <https://github.com/pymupdf/PyMuPDF/issues/4907>`_: signal 11:SIGSEGV while using display_list.get_textpage()
* Other:
* Added `pymupdf.TEXT_CLIP`.
* Removed support for mupdf < 1.26.
* New arg `raise_on_repair` in `Document.save()`.
* New method `Document.repair()`.
**Changes in version 1.26.7** (2025-12-11)
* Use MuPDF-1.26.12.
* **Fixed** `4801 <https://github.com/pymupdf/PyMuPDF/issues/4801>`_: Build failure dumping all environment variables
Other:
* Retrospectively mark `4756 <https://github.com/pymupdf/PyMuPDF/issues/4756>`_ as fixed in 1.26.6.
* Improved safety of `pymupdf embed-extract`. This now refuses to write to
an existing file or outside current directory, unless `-output` or new flag
`-unsafe` is specified.
**Changes in version 1.26.6** (2025-11-05)
* Use MuPDF-1.26.11.
* Supported Python versions are now 3.10-3.14.
* Fixed issues:
* **Fixed** `4699 <https://github.com/pymupdf/PyMuPDF/issues/4699>`_: cannot find ExtGState resource
* **Fixed** `4712 <https://github.com/pymupdf/PyMuPDF/issues/4712>`_: Crash with "corrupted double-linked list"
* **Fixed** `4720 <https://github.com/pymupdf/PyMuPDF/issues/4720>`_: Memory leaking in rewrite_images?
* **Fixed** `4742 <https://github.com/pymupdf/PyMuPDF/issues/4742>`_: 'Rect' object has no attribute 'get_area'
* **Fixed** `4746 <https://github.com/pymupdf/PyMuPDF/issues/4746>`_: Document.__init__() got an unexpected keyword argument 'encoding'
* **Fixed** `4756 <https://github.com/pymupdf/PyMuPDF/issues/4756>`_: swig --version doesn't work in all versions of swig; -version should be used instead
**Changes in version 1.26.5** (2025-10-10)
* Use MuPDF-1.26.10.
* Fixed issues:
* **Fixed** `2883 <https://github.com/pymupdf/PyMuPDF/issues/2883>`_: Improve the Python type annotations for fitz_new
* **Fixed** `4507 <https://github.com/pymupdf/PyMuPDF/issues/4507>`_: Bugs in pyodide
* **Fixed** `4613 <https://github.com/pymupdf/PyMuPDF/issues/4613>`_: Thai and number blocks are not auto-scaled and get wrong hyphen when using in insert_htmlbox
* **Fixed** `4700 <https://github.com/pymupdf/PyMuPDF/issues/4700>`_: pymupdf.open() processes .zip file without raising
* **Fixed** `4716 <https://github.com/pymupdf/PyMuPDF/issues/4716>`_: Problems with unreadable characters
* Other:
* Supported Python versions are now 3.9-3.14.
* We now define all class methods explicitly instead of with dynamic assignment; this improves type hints.
* Removed `pymupdf.utils.Shape` class, was duplicate of `pymupdf.Shape`.
* Allow use of cibuildwheel to build and test on Pyodide.
* Fixed various Pyodide bugs.
* In documentation, added section about Linux wheels and glibc compatibility.
* Improved documentation of pymupdf.open()'s <filetype> arg.
* Retrospectively mark `4544 <https://github.com/pymupdf/PyMuPDF/issues/4544>`_ as fixed in 1.26.4.
**Changes in version 1.26.4 (2025-08-25)**
* Use MuPDF-1.26.7.
* Fixed issues:
* **Fixed** `3806 <https://github.com/pymupdf/PyMuPDF/issues/3806>`_: pdf to image rendering ignore optional content offs
* **Fixed** `4388 <https://github.com/pymupdf/PyMuPDF/issues/4388>`_: Incorrect PixMap from page due to cached data from other PDF
* **Fixed** `4457 <https://github.com/pymupdf/PyMuPDF/issues/4457>`_: Wrong characters displayed after font subsetting (w/ native method)
* **Fixed** `4462 <https://github.com/pymupdf/PyMuPDF/issues/4462>`_: delete_pages() does not accept a single int
* **Fixed** `4533 <https://github.com/pymupdf/PyMuPDF/issues/4533>`_: Open PDF error segmentation fault
* **Fixed** `4544 <https://github.com/pymupdf/PyMuPDF/issues/4544>`_: About pdf_clip_page
* **Fixed** `4565 <https://github.com/pymupdf/PyMuPDF/issues/4565>`_: MacOS uses Tesseract and not Tesseract-OCR
* **Fixed** `4571 <https://github.com/pymupdf/PyMuPDF/issues/4571>`_: Broken merged pdfs.
* **Fixed** `4590 <https://github.com/pymupdf/PyMuPDF/issues/4590>`_: TypeError in utils.py scrub(): annot.update_file(buffer=...) is invalid
* **Fixed** `4614 <https://github.com/pymupdf/PyMuPDF/issues/4614>`_: Intercept bad widgets when inserting to another PDF
* **Fixed** `4639 <https://github.com/pymupdf/PyMuPDF/issues/4639>`_: pymupdf.mupdf.FzErrorGeneric: code=1: Director error: <class 'AttributeError'>: 'JM_new_bbox_device_Device' object has no attribute 'layer_name'
* Other:
* Check that #4392 `Segfault when running with pytest and -Werror` is fixed if PyMuPDF is built with swig>=4.4.
* Add `Page.clip_to_rect()`.
* Improved search for Tesseract data.
* Retrospectively mark #4496 as fixed in 1.26.1.
* Retrospectively mark #4503 as fixed in 1.26.3.
* Added experimental support for Graal.
**Changes in version 1.26.3 (2025-07-02)**
* Use MuPDF-1.26.3.
* Fixed issues:
* **Fixed** `4462 <https://github.com/pymupdf/PyMuPDF/issues/4462>`_: delete_pages() does not accept a single int
* **Fixed** `4503 <https://github.com/pymupdf/PyMuPDF/issues/4503>`_: Undetected character styles
* **Fixed** `4527 <https://github.com/pymupdf/PyMuPDF/issues/4527>`_: Rect.intersects() is much slower than necessary
* **Fixed** `4564 <https://github.com/pymupdf/PyMuPDF/issues/4564>`_: Possible encoding issue in PDF metadata
* **Fixed** `4575 <https://github.com/pymupdf/PyMuPDF/issues/4575>`_: Bug with IRect contains method
* Other:
* Class Shape is now available as pymupdf.Shape.
* Added table cell markdown support.
**Changes in version 1.26.2**
[Skipped.]
**Changes in version 1.26.1 (2025-06-11)**
* Use MuPDF-1.26.2.
* Fixed issues:
* **Fixed** `4520 <https://github.com/pymupdf/PyMuPDF/issues/4520>`_: show_pdf_page does not like empty pages created by new_page
* **Fixed** `4524 <https://github.com/pymupdf/PyMuPDF/issues/4524>`_: fitz.get_text ignores 'pages' kwarg
* **Fixed** `4412 <https://github.com/pymupdf/PyMuPDF/issues/4412>`_: Regression? Spurious error? in insert_pdf in v1.25.4
* **Fixed** `4496 <https://github.com/pymupdf/PyMuPDF/issues/4496>`_: pymupdf4llm with pymupdfpro
* Other:
* Partial fix for `4503 <https://github.com/pymupdf/PyMuPDF/issues/4503>`_: Undetected character styles
* New method `Document.rewrite_images()`, useful for reducing file size, changing image formats, or converting color spaces.
* `Page.get_text()`: restrict positional args to match docs.
* Removed bogus definition of class `Shape`.
* Removed release date from module, docs and changelog.
* `pymupdf.pymupdf_date` and `pymupdf.VersionDate` are now both None.
* They will be removed in a future release.
**Changes in version 1.26.0 (2025-05-22)**
* Use MuPDF-1.26.1.
* Fixed issues:
* **Fixed** `4324 <https://github.com/pymupdf/PyMuPDF/issues/4324>`_: cluster_drawings() fails to cluster horizontal and vertical thin lines
* **Fixed** `4363 <https://github.com/pymupdf/PyMuPDF/issues/4363>`_: Trouble with searching
* **Fixed** `4404 <https://github.com/pymupdf/PyMuPDF/issues/4404>`_: IndexError in page.get_links()
* **Fixed** `4412 <https://github.com/pymupdf/PyMuPDF/issues/4412>`_: Regression? Spurious error? in insert_pdf in v1.25.4
* **Fixed** `4423 <https://github.com/pymupdf/PyMuPDF/issues/4423>`_: pymupdf.mupdf.FzErrorFormat: code=7: cannot find object in xref error encountered after version 1.25.3
* **Fixed** `4435 <https://github.com/pymupdf/PyMuPDF/issues/4435>`_: get_pixmap method stuck on one page
* **Fixed** `4439 <https://github.com/pymupdf/PyMuPDF/issues/4439>`_: New Xml class from data does not work - bug in code
* **Fixed** `4445 <https://github.com/pymupdf/PyMuPDF/issues/4445>`_: Broken XREF table incorrectly repaired
* **Fixed** `4447 <https://github.com/pymupdf/PyMuPDF/issues/4447>`_: Stroke color of annotations cannot be correctly set
* **Fixed** `4479 <https://github.com/pymupdf/PyMuPDF/issues/4479>`_: set_layer_ui_config() toggles all layers rather than just one
* **Fixed** `4505 <https://github.com/pymupdf/PyMuPDF/issues/4505>`_: Follow Widget flag values up its parent structure
* Other:
* Partial fixed for `4457 <https://github.com/pymupdf/PyMuPDF/issues/4457>`_: Wrong characters displayed after font subsetting (w/ native method)
* Support image stamp annotations.
* Support recoloring pages.
* Added example of using Django's file storage API to open files with pymupdf.
* Clarified FreeText annotation color options.
We now raise an exception if an attempt is made to set attributes that can not be supported.
* Fixed potential segv in Pixmap.is_unicolor().
* Added runtime assert that that PyMuPDF and MuPDF were built with compatible
NDEBUG settings (related to `4390 <https://github.com/pymupdf/PyMuPDF/issues/4390>`_).
* Simplified handling of filename/filetype when opening documents.
* Removed PDF linearization support.
* Calls to `Document.save()` with `linear` set to true will now raise an exception.
* See https://artifex.com/blog/mupdf-removes-linearisation for more information.
**Changes in version 1.25.5 (2025-03-31)**
* Fixed issues:
* **Fixed** `4372 <https://github.com/pymupdf/PyMuPDF/issues/4372>`_: Text insertion fails due to missing /Resources object
* **Fixed** `4400 <https://github.com/pymupdf/PyMuPDF/issues/4400>`_: Infinite loop in fill_textbox
* **Fixed** `4403 <https://github.com/pymupdf/PyMuPDF/issues/4403>`_: Unable to get_text() - layer/clip nesting too deep
* **Fixed** `4415 <https://github.com/pymupdf/PyMuPDF/issues/4415>`_: PDF page is mirrored, origin is at bottom-left
* Other:
* Use MuPDF-1.25.6.
* Fixed MuPDF SEGV on MacOS with particular fonts.
* Fixed `Annot.get_textpage()`'s `clip` arg.
* Fixed Python-3.14 (pre-release) build error.
**Changes in version 1.25.4 (2025-03-14)**
* Use MuPDF-1.25.5.
* Fixed issues:
* **Fixed** `4079 <https://github.com/pymupdf/PyMuPDF/issues/4079>`_: Unexpected result for apply_redactions()
* **Fixed** `4224 <https://github.com/pymupdf/PyMuPDF/issues/4224>`_: MuPDF error: format error: negative code in 1d faxd
* **Fixed** `4303 <https://github.com/pymupdf/PyMuPDF/issues/4303>`_: page.get_image_info() returns outdated cached results after replacing image
* **Fixed** `4309 <https://github.com/pymupdf/PyMuPDF/issues/4309>`_: FzErrorFormat Error When Deleting First Page
* **Fixed** `4336 <https://github.com/pymupdf/PyMuPDF/issues/4336>`_: Major Performance Regression: pix.color_count is 150x slower in version 1.25.3 compared to 1.23.8
* **Fixed** `4341 <https://github.com/pymupdf/PyMuPDF/issues/4341>`_: Invalid label retrieval when /Kids is an array of multiple /Nums
* Other:
* Fixed handling of duplicate widget names when joining PDFs (PR #4347).
* Improved Pyodide build.
* Avoid SWIG-related build errors with Python-3.13 by disabling PY_LIMITED_API.
**Changes in version 1.25.3 (2025-02-06)**
* Use MuPDF-1.25.4.
* Fixed issues:
* **Fixed** `4139 <https://github.com/pymupdf/PyMuPDF/issues/4139>`_: Text color numbers change between 1.24.14 and 1.25.0
* **Fixed** `4141 <https://github.com/pymupdf/PyMuPDF/issues/4141>`_: Some insertion methods fails for pages without a /Resources object
* **Fixed** `4180 <https://github.com/pymupdf/PyMuPDF/issues/4180>`_: Search problems
* **Fixed** `4182 <https://github.com/pymupdf/PyMuPDF/issues/4182>`_: Text coordinate extraction error
* **Fixed** `4245 <https://github.com/pymupdf/PyMuPDF/issues/4245>`_: Highlighting issue distorted on recent versions
* **Fixed** `4254 <https://github.com/pymupdf/PyMuPDF/issues/4254>`_: add_freetext_annot is drawing text outside the annotation box
* Other:
* In annotations:
* Added support for subtype FreeTextCallout.
* Added support for rich text.
* Added miter_limit arg to insert_text*() to allow suppression of spikes caused by long miters.
* Add Widget Support to `Document.insert_pdf()`.
* Add `bibi` to span dicts.
* Add `synthetic' to char dict.
* Fixed Pyodide builds.
**Changes in version 1.25.2 (2025-01-17)**
* Fixed issues:
* **Fixed** `4055 <https://github.com/pymupdf/PyMuPDF/issues/4055>`_: "Yes" for all checkboxes does not work for all PDF rendering engines.
* **Fixed** `4155 <https://github.com/pymupdf/PyMuPDF/issues/4155>`_: samples_mv is unsafe
* **Fixed** `4162 <https://github.com/pymupdf/PyMuPDF/issues/4162>`_: Got AttributeError, when tried to add Signature field
* **Fixed** `4186 <https://github.com/pymupdf/PyMuPDF/issues/4186>`_: Incorrect handling of JPEG with color space CMYK image extraction
* **Fixed** `4195 <https://github.com/pymupdf/PyMuPDF/issues/4195>`_: Pixmaps that are inverted and have an alpha channel are not rendered properly
* **Fixed** `4225 <https://github.com/pymupdf/PyMuPDF/issues/4225>`_: pixmap.pil_save() fails due to colorspace definition
* **Fixed** `4232 <https://github.com/pymupdf/PyMuPDF/issues/4232>`_: Incorrect Font style and Size
* Other:
* Use Python's built-in glyphname <> unicode conversion.
* Improve speed of pixmap color inversion.
* Add new `char_flags` member to span dictionary, for example allows detection of invisible text.
* Detect image masks in TextPage output.
* Added `Pixmap.pil_image()`.
**Changes in version 1.25.1 (2024-12-11)**
* Use MuPDF-1.25.2.
* Fixed issues:
* **Fixed** `4125 <https://github.com/pymupdf/PyMuPDF/issues/4125>`_: memory leak while convert Pixmap's colorspace
* **Fixed** `4034 <https://github.com/pymupdf/PyMuPDF/issues/4034>`_: Possible regression in pdf cleaning during save.
**Changes in version 1.25.0 (2024-12-05)**
* Use MuPDF-1.25.1.
* Fixed issues:
* **Fixed** `4026 <https://github.com/pymupdf/PyMuPDF/issues/4026>`_: page.get_text('blocks') output two piece of very similar text with different bbox
* **Fixed** `4004 <https://github.com/pymupdf/PyMuPDF/issues/4004>`_: Segmentation Fault When Updating PDF Form Field Value
* **Fixed** `3887 <https://github.com/pymupdf/PyMuPDF/issues/3887>`_: Subset Fonts problem using Fallback Font
* **Fixed** `3886 <https://github.com/pymupdf/PyMuPDF/issues/3886>`_: Another issue with destroying PDF when inserting html
* **Fixed** `3751 <https://github.com/pymupdf/PyMuPDF/issues/3751>`_: apply_redactions causes part of the page content to be hidden / transparent
.. codespell:ignore-begin
**Changes in version 1.24.14 (2024-11-19)**
* Use MuPDF-1.24.11.
* Fixed issues:
* **Fixed** `3448 <https://github.com/pymupdf/PyMuPDF/issues/3448>`_: get_pixmap function removes the table and leaves just the content behind
* **Fixed** `3758 <https://github.com/pymupdf/PyMuPDF/issues/3758>`_: Got "malloc(): unaligned tcache chunk detected Aborted (core dumped)" while using add_redact_annot/apply_redactions
* **Fixed** `3813 <https://github.com/pymupdf/PyMuPDF/issues/3813>`_: Stories: Ordered list count broken with nested unordered list
* **Fixed** `3933 <https://github.com/pymupdf/PyMuPDF/issues/3933>`_: font.valid_codepoints() - malfunction
* **Fixed** `4018 <https://github.com/pymupdf/PyMuPDF/issues/4018>`_: PyMuPDF hangs when iterating over zero page PDF pages backwards
* **Fixed** `4043 <https://github.com/pymupdf/PyMuPDF/issues/4043>`_: fullcopypage bug
* **Fixed** `4047 <https://github.com/pymupdf/PyMuPDF/issues/4047>`_: Segmentation Fault in add_redact_annot
* **Fixed** `4050 <https://github.com/pymupdf/PyMuPDF/issues/4050>`_: Content of dict returned by doc.embfile_info() does not fit to documentation
* Other:
* Ensure that words from `Page.get_text()` never contain RTL/LTR char mixtures.
* Fix building with system MuPDF.
* Add dot product for points and vectors.
**Changes in version 1.24.13 (2024-10-29)**
* Fixed issues:
* **Fixed** `3848 <https://github.com/pymupdf/PyMuPDF/issues/3848>`_: Piximap program crash
* **Fixed** `3950 <https://github.com/pymupdf/PyMuPDF/issues/3950>`_: Unable to consistently extract field labels from PDFs
* **Fixed** `3981 <https://github.com/pymupdf/PyMuPDF/issues/3981>`_: PyMuPDF 1.24.12 with pyinstaller throws error.
* **Fixed** `3994 <https://github.com/pymupdf/PyMuPDF/issues/3994>`_: pix.color_topusage raise Segmentation fault (core dumped)
**Changes in version 1.24.12 (2024-10-21)**
* Fixed issues:
* **Fixed** `3914 <https://github.com/pymupdf/PyMuPDF/issues/3914>`_: Ability to print MuPDF errors to logging instead of stdout
* **Fixed** `3916 <https://github.com/pymupdf/PyMuPDF/issues/3916>`_: insert_htmlbox error: int too large to convert to float
* **Fixed** `3950 <https://github.com/pymupdf/PyMuPDF/issues/3950>`_: Unable to consistently extract field labels from PDFs
* Supported Python versions are now 3.9-3.13.
* Dropped support for Python-3.8 because end-of-life.
* Added support for Python-3.13 because now released.
* See: https://devguide.python.org/versions/
**Changes in version 1.24.11 (2024-10-03)**
* Use MuPDF-1.24.10.
* Fixed issues:
* **Fixed** `3624 <https://github.com/pymupdf/PyMuPDF/issues/3624>`_: Pdf file transform to image have a black block
* **Fixed** `3859 <https://github.com/pymupdf/PyMuPDF/issues/3859>`_: doc.need_appearances() fails with "AttributeError: module 'pymupdf.mupdf' has no attribute 'PDF_TRUE' "
* **Fixed** `3863 <https://github.com/pymupdf/PyMuPDF/issues/3863>`_: apply_redactions() does not work as expected
* **Fixed** `3905 <https://github.com/pymupdf/PyMuPDF/issues/3905>`_: open stream can raise a FzErrorFormat error instead of FileDataError
* Wheels now use the Python Stable ABI:
* There is one PyMuPDF wheel for each platform.
* Each wheel works with all supported Python versions.
* Each wheel is built using the oldest supported Python version (currently 3.8).
* There is no PyMuPDFb wheel.
* Other:
* Improvements to get_text_words() with sort=True.
* Tests now always get the latest versions of required Python packages.
* Removed dependency on setuptools.
* Added item to PyMuPDF-1.24.10 changes below - fix of #3630.
**Changes in version 1.24.10 (2024-09-02)**
* Use MuPDF-1.24.9.
* Fixed issues:
* **Fixed** `3450 <https://github.com/pymupdf/PyMuPDF/issues/3450>`_: get_pixmap function takes too long to process
* **Fixed** `3569 <https://github.com/pymupdf/PyMuPDF/issues/3569>`_: Invalid OCGs not ignored by SVG image creation
* **Fixed** `3603 <https://github.com/pymupdf/PyMuPDF/issues/3603>`_: ObjStm compression and PDF linearization doesn't work together
* **Fixed** `3650 <https://github.com/pymupdf/PyMuPDF/issues/3650>`_: Linebreak inserted between each letter
* **Fixed** `3661 <https://github.com/pymupdf/PyMuPDF/issues/3661>`_: Update Document to check the /XYZ len
* **Fixed** `3698 <https://github.com/pymupdf/PyMuPDF/issues/3698>`_: documentation issue - old code in the annotations documentation
* **Fixed** `3705 <https://github.com/pymupdf/PyMuPDF/issues/3705>`_: Document.select() behaves weirdly in some particular kind of pdf files
* **Fixed** `3706 <https://github.com/pymupdf/PyMuPDF/issues/3706>`_: extend Document.__getitem__ type annotation to reflect that the method also accepts slices
* **Fixed** `3727 <https://github.com/pymupdf/PyMuPDF/issues/3727>`_: Method get_pixmap() make the program exit without any exceptions or messages
* **Fixed** `3767 <https://github.com/pymupdf/PyMuPDF/issues/3767>`_: Cannot get Tessdata with Tesseract-OCR 5
* **Fixed** `3773 <https://github.com/pymupdf/PyMuPDF/issues/3773>`_: Link.set_border gives TypeError: '<' not supported between instances of 'NoneType' and 'int'
* **Fixed** `3774 <https://github.com/pymupdf/PyMuPDF/issues/3774>`_: fitz.__version__` does not work anymore
* **Fixed** `3789 <https://github.com/pymupdf/PyMuPDF/issues/3789>`_: ValueError: not enough values to unpack (expected 3, got 2) is thrown when call insert_pdf
* **Fixed** `3820 <https://github.com/pymupdf/PyMuPDF/issues/3820>`_: class improves namedDest handling
* **Fixed** `3630 <https://github.com/pymupdf/PyMuPDF/issues/3630>`_: page.apply_redactions gives unwanted black rectangle
* Other:
* Object streams and linearization cannot be used together; attempting to do
so will raise an exception. (#3603)
* Fixed handling of non-existing /Contents object.
**Changes in version 1.24.9 (2024-07-24)**
* Use MuPDF-1.24.8.
**Changes in version 1.24.8 (2024-07-22)**
* Fixed issues:
* **Fixed** `3636 <https://github.com/pymupdf/PyMuPDF/issues/3636>`_: API documentation for the open function is not obvious to find.
* **Fixed** `3654 <https://github.com/pymupdf/PyMuPDF/issues/3654>`_: docx parsing was broken in 1.24.7
* **Fixed** `3677 <https://github.com/pymupdf/PyMuPDF/issues/3677>`_: Unable to extract subset font name using the newer versions of PyMuPDF : 1.24.6 and 1.24.7.
* **Fixed** `3687 <https://github.com/pymupdf/PyMuPDF/issues/3687>`_: Page.get_text results in AssertionError for epub files
Other:
* Fixed various spelling mistakes spotted by codespell.
* Improved how we modify MuPDF's default configuration on Windows.
* Make text search to work with ligatures.
**Changes in version 1.24.7 (2024-06-26)**
* Fixed issues:
* **Fixed** `3615 <https://github.com/pymupdf/PyMuPDF/issues/3615>`_: Document.pagemode or Document.pagelayout crashes for epub files
* **Fixed** `3616 <https://github.com/pymupdf/PyMuPDF/issues/3616>`_: not last version reported
**Changes in version 1.24.6 (2024-06-25)**
* Use MuPDF-1.24.4
* Fixed issues:
* **Fixed** `3599 <https://github.com/pymupdf/PyMuPDF/issues/3599>`_: Story.fit_width() has a weird line
* **Fixed** `3594 <https://github.com/pymupdf/PyMuPDF/issues/3594>`_: Garbled extraction for Amazon Sustainability Report
* **Fixed** `3591 <https://github.com/pymupdf/PyMuPDF/issues/3591>`_: 'width' in Page.get_drawings() returns width equal as 0
* **Fixed** `3561 <https://github.com/pymupdf/PyMuPDF/issues/3561>`_: ZeroDivisionError: float division by zero with page.apply_redactions()
* **Fixed** `3559 <https://github.com/pymupdf/PyMuPDF/issues/3559>`_: SegFault 11 when empty H1 H2 H3 H4 etc element is used in insert_htmlbox
* **Fixed** `3539 <https://github.com/pymupdf/PyMuPDF/issues/3539>`_: Add dotted gridline detection to table recognition
* **Fixed** `3519 <https://github.com/pymupdf/PyMuPDF/issues/3519>`_: get_toc(simple=False) AttributeError: 'Outline' object has no attribute 'rect'
* **Fixed** `3510 <https://github.com/pymupdf/PyMuPDF/issues/3510>`_: page.get_label() gets wrong label on the first page of doc
* **Fixed** `3494 <https://github.com/pymupdf/PyMuPDF/issues/3494>`_: 1.24.2/1.24.3: spurious characters introduced when using subset_fonts and insert_pdf
* **Fixed** `3470 <https://github.com/pymupdf/PyMuPDF/issues/3470>`_: subset_fonts error exit without exception/warning
* **Fixed** `3400 <https://github.com/pymupdf/PyMuPDF/issues/3400>`_: set_toc alters link coordinates for some rotated pages on pymupdf 1.24.2
* **Fixed** `3347 <https://github.com/pymupdf/PyMuPDF/issues/3347>`_: Incorrect links to points on pages having different heights
* **Fixed** `3237 <https://github.com/pymupdf/PyMuPDF/issues/3237>`_: Set_metadata() does not work
* **Fixed** `3493 <https://github.com/pymupdf/PyMuPDF/discussions/3493>`_: Isolate PyMuPDF from other libraries; issues when PyMuPDF is loaded with other libraries like GdkPixbuf
* Other:
* Fixed concurrent use of PyMuPDF caused by use of constant temporary filenames.
* Add musllinux x86_64 wheels to release.
* Added clearer version information:
* `pymupdf.pymupdf_version`.
* `pymupdf.mupdf_version`.
* `pymupdf.pymupdf_date`.
**Changes in version 1.24.5 (2024-05-30)**
* Fixed issues:
* **Fixed** `3479 <https://github.com/pymupdf/PyMuPDF/issues/3479>`_: regression: fill_textbox: IndexError: pop from empty list
* **Fixed** `3488 <https://github.com/pymupdf/PyMuPDF/issues/3488>`_: set_toc method error
* Other:
* Some more fixes to use MuPDF floating formatting.
* Removed/disabled some unnecessary diagnostics.
* Fixed utils.do_links() crash.
* Experimental new functions `pymupdf.apply_pages()` and `pymupdf.get_text()`.
* Addresses wrong label generation for label styles "a" and "A".
**Changes in version 1.24.4 (2024-05-16)**
* **Fixed** `3418 <https://github.com/pymupdf/PyMuPDF/issues/3418>`_: Re-introduced bug, text align add_redact_annot
* **Fixed** `3472 <https://github.com/pymupdf/PyMuPDF/issues/3472>`_: insert_pdf gives SystemError
* Other:
* Fixed sysinstall test failing to remove all of prior installation before
new install.
* Fixed `utils.do_links()` crash.
* Correct `TextPage` creation Code.
* Unified various diagnostics.
* Fix bug in `page_merge()`.
**Changes in version 1.24.3 (2024-05-09)**
*
The Python module is now called `pymupdf`. `fitz` is still supported for
backwards compatibility.
* Use MuPDF-1.24.2.
* Fixed issues:
* **Fixed** `3357 <https://github.com/pymupdf/PyMuPDF/issues/3357>`_: PyMuPDF==1.24.0 will hanging when using page.get_text("text")
* **Fixed** `3376 <https://github.com/pymupdf/PyMuPDF/issues/3376>`_: Redacting results are not as expected in 1.24.x.
* **Fixed** `3379 <https://github.com/pymupdf/PyMuPDF/issues/3379>`_: Documentation mismatch for get_text_blocks return value order.
* **Fixed** `3381 <https://github.com/pymupdf/PyMuPDF/issues/3381>`_: Contents stream contains floats in scientific notation
* **Fixed** `3402 <https://github.com/pymupdf/PyMuPDF/issues/3402>`_: Cannot add Widgets containing inter-field-calculation JavaScript
* **Fixed** `3414 <https://github.com/pymupdf/PyMuPDF/issues/3414>`_: missing attribute set_dpi()
* **Fixed** `3430 <https://github.com/pymupdf/PyMuPDF/issues/3430>`_: page.get_text() cause process freeze with certain pdf on v1.24.2
* Other:
* New/modified methods:
* `Page.remove_rotation()`: new, set page rotation to zero while keeping appearance.
* Fixed some problems when checking for PDF properties.
* Fixed pip builds from sdist
(see discussion `3360 <https://github.com/pymupdf/PyMuPDF/discussions/3360>`_:
Alpine linux docker build failing "No matching distribution found for pymupdfb==1.24.1").
**Changes in version 1.24.2 (2024-04-17)**
* Removed obsolete classic implementation from releases
(previously available as module `fitz_old`).
* Fixed issues:
* **Fixed** `3331 <https://github.com/pymupdf/PyMuPDF/issues/3331>`_: Document.pages() is incorrectly type-hinted
* **Fixed** `3354 <https://github.com/pymupdf/PyMuPDF/issues/3354>`_: PyMuPDF==1.24.1: AttributeError: property 'metadata' of 'Document' object has no setter
* Other:
* New/modified methods:
* `Document.bake()`: new, make annotations / fields permanent content.
* `Page.cluster_drawings()`: new, identifies drawing items
(i.e. vector graphics or line-art)
that belong together based on their geometrical vicinity.
* `Page.apply_redactions()`: added new parameter `text`.
* `Document.subset_fonts()`: use MuPDF's `pdf_subset_fonts()` instead of PyMuPDF code.
* The `Document` class now supports page numbers specified as slices.
* Avoid causing MuPDF warnings.
**Changes in version 1.24.1 (2024-04-02)**
* Fixed issues:
* **Fixed** `3278 <https://github.com/pymupdf/PyMuPDF/issues/3278>`_: apply_redactions moves some unredacted text
* **Fixed** `3301 <https://github.com/pymupdf/PyMuPDF/issues/3301>`_: Be more permissive when classifying links as kind LINK_URI
* **Fixed** `3306 <https://github.com/pymupdf/PyMuPDF/issues/3306>`_: Text containing capital 'ET' not appearing as annotation
* Other:
* Use MuPDF-1.24.1.
* Support ObjStm Compression.
Methods `Document.save()`, `Document.ez_save()` and `Document.write()`
now support new parameters `use_objstm`, compression_effort` and
`preserve_metadata`.
**Changes in version 1.24.0 (2024-03-21)**
* Fixed issues:
* **Fixed** `3281 <https://github.com/pymupdf/PyMuPDF/issues/3281>`_: Preparing metadata (pyproject.toml) did not run successfully
* **Fixed** `3279 <https://github.com/pymupdf/PyMuPDF/issues/3279>`_: PyMuPDF no longer builds in Alpine Linux
* **Fixed** `3257 <https://github.com/pymupdf/PyMuPDF/issues/3257>`_: apply_redactions() deleting text outside of annotated box
* **Fixed** `3216 <https://github.com/pymupdf/PyMuPDF/issues/3216>`_: AttributeError: 'Annot' object has no attribute '__del__'
* **Fixed** `3207 <https://github.com/pymupdf/PyMuPDF/issues/3207>`_: get_drawings's items is missing line from h path operator
* **Fixed** `3201 <https://github.com/pymupdf/PyMuPDF/issues/3201>`_: Memory leaks when merging PDFs
* **Fixed** `3197 <https://github.com/pymupdf/PyMuPDF/issues/3197>`_: page.get_text() returns hexadecimal text for some characters
* **Fixed** `3196 <https://github.com/pymupdf/PyMuPDF/issues/3196>`_: Remove text not working in 1.23.25 version vs 1.20.2
* **Fixed** `3172 <https://github.com/pymupdf/PyMuPDF/issues/3172>`_: PDF's 45º lines disappearing in png conversion
* **Fixed** `3135 <https://github.com/pymupdf/PyMuPDF/issues/3135>`_: Do not log warnings to stdout
* **Fixed** `3125 <https://github.com/pymupdf/PyMuPDF/issues/3125>`_: get_pixmap method stuck on one page and runs forever
* **Fixed** `2964 <https://github.com/pymupdf/PyMuPDF/issues/2964>`_: There is an issue with the image generated by the page.get_pixmap() function
* Other:
* Use MuPDF-1.24.0.
* Add support for redacting vector graphics.
* Several fixes for table module
* Add new method for outputting the table as a markdown string.
* Address errors in computing the table header object:
We now allow None as the cell value, because this will be resolved where
needed (e.g. in the pandas DataFrame).
We previously tried to enforce rect-like tuples in all header cell
bboxes, however this fails for tables with all-None columns. This fix
enables this and constructs an empty string in the corresponding cell
string.
We now correctly include start / stop points of lines in the bbox of the
clustered graphic. We previously joined the line's rectangle - which had
no effect because this is always empty.
* Improved exception text if we fail to open document.
* Fixed build with new libclang 18.
**Changes in version 1.23.26 (2024-02-29)**
* Fixed issues:
* **Fixed** `3199 <https://github.com/pymupdf/PyMuPDF/issues/3199>`_: Add entry_points to setuptools configuration to provide command-line console scripts
* **Fixed** `3209 <https://github.com/pymupdf/PyMuPDF/issues/3209>`_: Empty vertices in ink annotation
* Other:
* Improvements to table detection:
* Improved check for empty tables, fixes bugs when determining table headers.
* Improved computation of enveloping vector graphic rectangles.
* Ignore more meaningless "pseudo" tables
* Install command-line 'pymupdf' command that runs fitz/__main__.py.
* Don't overwrite MuPDF's config.h when building on non-Windows.
* Fix `Story` constructor's `archive` arg to match docs - now accepts a single `Archive` constructor arg.
* Do not include MuPDF source in sdist; will be downloaded automatically when building.
**Changes in version 1.23.25 (2024-02-20)**
* Fixed issues:
* **Fixed** `3182 <https://github.com/pymupdf/PyMuPDF/issues/3182>`_: Pixmap.invert_irect argument type error
* **Fixed** `3186 <https://github.com/pymupdf/PyMuPDF/issues/3186>`_: extractText() extracts broken text from pdf
* **Fixed** `3191 <https://github.com/pymupdf/PyMuPDF/issues/3191>`_: Error on .find_tables()
* Other:
* When building, be able to specify python-config directly, with environment
variable `PIPCL_PYTHON_CONFIG`.
**Changes in version 1.23.24 (2024-02-19)**
* Fixed issues:
* **Fixed** `3148 <https://github.com/pymupdf/PyMuPDF/issues/3148>`_: Table extraction - vertical text not handled correctly
* **Fixed** `3179 <https://github.com/pymupdf/PyMuPDF/issues/3179>`_: Table Detection: Incorrect Separation of Vector Graphics Clusters
* **Fixed** `3180 <https://github.com/pymupdf/PyMuPDF/issues/3180>`_: Cannot show optional content group: AttributeError: module 'fitz.mupdf' has no attribute 'pdf_array_push_drop'
* Other:
* Be able to test system install using `sudo pip install` instead of a venv.
**Changes in version 1.23.23 (2024-02-18)**
* Fixed issues:
* **Fixed** `3126 <https://github.com/pymupdf/PyMuPDF/issues/3126>`_: Initialising Archive with a pathlib.Path fails.
* **Fixed** `3131 <https://github.com/pymupdf/PyMuPDF/issues/3131>`_: Calling the next attribute of an Annot raises a "No attribute .parent" warning
* **Fixed** `3134 <https://github.com/pymupdf/PyMuPDF/issues/3134>`_: Using an IRect as clip parameter in Page.get_pixmap no longer works since 1.23.9
* **Fixed** `3140 <https://github.com/pymupdf/PyMuPDF/issues/3140>`_: PDF document stays in use after closing
* **Fixed** `3150 <https://github.com/pymupdf/PyMuPDF/issues/3150>`_: doc.select() hangs on this doc.
* **Fixed** `3163 <https://github.com/pymupdf/PyMuPDF/issues/3163>`_: AssertionError on using fitz.IRect
* **Fixed** `3177 <https://github.com/pymupdf/PyMuPDF/issues/3177>`_: fitz.Pixmap(None, pix) Unrecognised args for constructing Pixmap
* Other:
*
Improved `Document.select() by using new MuPDF function
`pdf_rearrange_pages()`. This is a more complete (and faster)
implementation of what needs to be done here in that not only pages will
be rearranged, but also consequential changes will be made to the table
of contents, links to removed pages and affected entries in the Optional
Content definitions.
* `TextWriter.appendv()`: added `small_caps` arg.
* Fixed some valgrind errors with MuPDF master.
* Fixed `Document.insert_image()` when build with MuPDF master.
**Changes in version 1.23.22 (2024-02-12)**
* Fixed issues:
* **Fixed** `3143 <https://github.com/pymupdf/PyMuPDF/issues/3143>`_: Difference in decoding of OCGs names between doc.get_ocgs() and page.get_drawings()
* **Fixed** `3139 <https://github.com/pymupdf/PyMuPDF/issues/3139>`_: Pixmap resizing needs positional arg "clip" - even if None.
* Other:
* Removed the use of MuPDF function `fz_image_size()` from PyMuPDF.
**Changes in version 1.23.21 (2024-02-01)**
* Fixed issues:
* Other:
* Fixed bug in set_xml_metadata(), PR `3112 <https://github.com/pymupdf/PyMuPDF/pull/3112>`_: Fix pdf_add_stream metadata error
* Fixed lack of `.parent` member in `TextPage` from `Annot.get_textpage()`.
* Fixed bug in `Page.add_widget()`.
**Changes in version 1.23.20 (2024-01-29)**
* Bug fixes:
* **Fixed** `3100 <https://github.com/pymupdf/PyMuPDF/issues/3100>`_: Wrong internal property accessed in get_xml_metadata
* Other:
* Significantly improved speed of `Document.get_toc()`.
**Changes in version 1.23.19 (2024-01-25)**
* Bug fixes:
* **Fixed** `3087 <https://github.com/pymupdf/PyMuPDF/issues/3087>`_: Exception in insert_image with mask specified
* **Fixed** `3094 <https://github.com/pymupdf/PyMuPDF/issues/3094>`_: TypeError: '<' not supported between instances of 'FzLocation' and 'int' in doc.delete_pages
* Other:
* When finding tables:
* Allow addition of user-defined "virtual" vector graphics when finding tables.
* Confirm that the enveloping bboxes of vector graphics are inside the clip rectangle.
* Avoid slow finding of rectangle intersections.
* Added `Font.bbox` property.
**Changes in version 1.23.18 (2024-01-23)**
* Bug fixes:
* **Fixed** `3081 <https://github.com/pymupdf/PyMuPDF/issues/3081>`_: doc.close() not closing the document
* Other:
* Reduced size of sdist to fit on pypi.org (by reducing size of two test files).
* Fix `Annot.file_info()` if no `Desc` item.
**Changes in version 1.23.17 (2024-01-22)**
* Bug fixes:
* **Fixed** `3062 <https://github.com/pymupdf/PyMuPDF/issues/3062>`_: page_rotation_reset does not return page to original rotation
* **Fixed** `3070 <https://github.com/pymupdf/PyMuPDF/issues/3070>`_: update_link(): AttributeError: 'Page' object has no attribute 'super'
* Other:
* Fixed bug in `Page.links()` (PR #3075).
* Fixed bug in `Page.get_bboxlog()` with layers.
* Add support for timeouts in scripts/ and tests/run_compound.py.
**Changes in version 1.23.16 (2024-01-18)**
* Bug fixes:
* **Fixed** `3058 <https://github.com/pymupdf/PyMuPDF/issues/3058>`_: Pixmap created from CMYK JPEG delivers RGB format
* Other:
* In table detection strategy "lines_strict", exclude fill-only vector graphics.
* Fixed sysinstall test failure.
* In documentation, update feature matrix with item about text writing.
**Changes in version 1.23.15 (2024-01-16)**
* Bug fixes:
* **Fixed** `3050 <https://github.com/pymupdf/PyMuPDF/issues/3050>`_: python3.9 pix.set_pixel has something wrong in c.append( ord(i))
* Other:
* Improved docs for Page.find_tables().
**Changes in version 1.23.14 (2024-01-15)**
* Bug fixes:
* **Fixed** `3038 <https://github.com/pymupdf/PyMuPDF/issues/3038>`_: JM_pixmap_from_display_list > Assertion Error : Checking for wrong type
* **Fixed** `3039 <https://github.com/pymupdf/PyMuPDF/issues/3039>`_: Issue with doc.close() not closing the document in PyMuPDF
* Other:
* Ensure valid "re" rectangles in `Page.get_drawings()` with derotated pages.
**Changes in version 1.23.13 (2024-01-15)**
* Bug fixes:
* **Fixed** `2979 <https://github.com/pymupdf/PyMuPDF/issues/2979>`_: list index out of range in to_pandas()
* **Fixed** `3001 <https://github.com/pymupdf/PyMuPDF/issues/3001>`_: Calling find_tables() on one document alters the bounding boxes of a subsequent document
* Other:
* Fixed `Rect.height` and `Rect.width` to never return negative values.
* Fixed `TextPage.extractIMGINFO()`'s returned `dictkey_yres` value.
**Changes in version 1.23.12 (2024-01-12)**
* * **Fixed** `3027 <https://github.com/pymupdf/PyMuPDF/issues/3027>`_: Page.get_text throws Attribute Error for 'parent'
**Changes in version 1.23.11 (2024-01-12)**
* Fixed some Pixmap construction bugs.
* Fixed Pixmap.yres().
**Changes in version 1.23.10 (2024-01-12)**
* Bug fixes:
* **Fixed** `3020 <https://github.com/pymupdf/PyMuPDF/issues/3020>`_: Can't resize a PixMap
* Other:
* Fixed Page.delete_image().
**Changes in version 1.23.9 (2024-01-11)**
* Default to new "rebased" implementation.
* The old "classic" implementation is available with `import fitz_old as fitz`.
* For more information about why we are changing to the rebased implementation,
see: https://github.com/pymupdf/PyMuPDF/discussions/2680
* Use MuPDF-1.23.9.
* Bug fixes (rebased implementation only):
* **Fixed** `2911 <https://github.com/pymupdf/PyMuPDF/issues/2911>`_: Page.derotation_matrix returns a tuple instead of a Matrix with rebased implementation
* **Fixed** `2919 <https://github.com/pymupdf/PyMuPDF/issues/2919>`_: Rebased version: KeyError in resolve_names when merging pdfs
* **Fixed** `2922 <https://github.com/pymupdf/PyMuPDF/issues/2922>`_: New feature that allows inserting named-destination links doesn't work
* **Fixed** `2943 <https://github.com/pymupdf/PyMuPDF/issues/2943>`_: ZeroDivisionError: float division by zero when use apply_redactions()
* **Fixed** `2950 <https://github.com/pymupdf/PyMuPDF/issues/2950>`_: Shelling out to pip during tests is problematic
* **Fixed** `2954 <https://github.com/pymupdf/PyMuPDF/issues/2954>`_: Replacement unicode character in text extraction
* **Fixed** `2957 <https://github.com/pymupdf/PyMuPDF/issues/2957>`_: apply_redactions() moving text
* **Fixed** `2961 <https://github.com/pymupdf/PyMuPDF/issues/2961>`_: Passing a string as a page number raises IndexError instead of TypeError.
* **Fixed** `2969 <https://github.com/pymupdf/PyMuPDF/issues/2969>`_: annot.next throws AttributeError
* **Fixed** `2978 <https://github.com/pymupdf/PyMuPDF/issues/2978>`_: 1.23.9rc1: module 'fitz.mupdf' has no attribute 'fz_copy_pixmap_rect'
* **Fixed** `2907 <https://github.com/pymupdf/PyMuPDF/issues/2907>`_: segfault trying to call clean_contents on certain pdfs with python 3.12
* **Fixed** `2905 <https://github.com/pymupdf/PyMuPDF/issues/2905>`_: SystemError: <built-in function TextPage_extractIMGINFO> returned a result with an exception set
* **Fixed** `2742 <https://github.com/pymupdf/PyMuPDF/issues/2742>`_: Segmentation Fault when inserting three (but not two) copies of the same source page into one destination page
* Other:
* Add optional setting of opacity to `Page.insert_htmlbox()`.
* Fixed issue with add_redact_annot() mentioned in #2934.
* Fixed `Page.rotation()` to return 0 for non-PDF documents instead of raising an exception.
* Fixed internal quad detection to cope with any Python sequence.
* Fixed rebased `fitz.pymupdf_version_tuple` - was previously set to mupdf version.
* Improved support for Linux system installs, including adding regular testing on Github.
* Add missing `flake8` to `scripts/gh_release.py:test_packages`.
* Use newly public functions in MuPDF-1.23.8.
* Improved `scripts/test.py` to help investigation of MuPDF issues.
**Changes in version 1.23.8 (2023-12-19)**
* Bug fixes (rebased implementation only):
* **Fixed** `2634 <https://github.com/pymupdf/PyMuPDF/issues/2634>`_: get_toc and set_toc do not behave consistently for rotated pages
* **Fixed** `2861 <https://github.com/pymupdf/PyMuPDF/issues/2861>`_: AttributeError in getLinkDict during PDF Merge
* **Fixed** `2871 <https://github.com/pymupdf/PyMuPDF/issues/2871>`_: KeyError in getLinkDict during PDF merge
* **Fixed** `2886 <https://github.com/pymupdf/PyMuPDF/issues/2886>`_: Error in Skeleton for Named Link Destinations
* Bug fixes (rebased and classic implementations):
* **Fixed** `2885 <https://github.com/pymupdf/PyMuPDF/issues/2885>`_: pymupdf find tables too slow
* Other:
* Rebased implementation:
* `Page.insert_htmlbox()`: new, much more powerful alternative to `Page.insert_textbox()` or `TextWriter.fill_textbox()`, using `Story`.
* `Story.fit*()`: new methods for fitting a Story into an expanded rect.
* `Story.write_with_links()`: add support for external links.
* `Document.language()`: fixed to use MuPDF's new `mupdf.fz_string_from_text_language2()`.
* `Document.subset_fonts()` - fixed.
* Fixed internal `Archive._add_treeitem()` method.
* Fixed `fitz_new.__doc__` to contain PyMuPDF and Python version information, and OS name.
* Removed use of `(*args, **kwargs)` in API, we now specify keyword args explicitly.
* Work with new MuPDF Python exception classes.
* Fixed bug where `button_states()` returns None when `/AP` points to an indirect object.
* Fixed pillow test to not ignore all errors, and install pillow when testing.
* Added test for `fitz.css_for_pymupdf_font()` (uses package `pymupdf-fonts`).
* Simplified Github Actions test specifications.
* Updated `tests/README.md`.
**Changes in version 1.23.7 (2023-11-30)**
* Bug fixes in rebased implementation, not fixed in classic implementation:
* **Fixed** `2232 <https://github.com/pymupdf/PyMuPDF/issues/2232>`_: Geometry helper classes should support keyword arguments
* **Fixed** `2788 <https://github.com/pymupdf/PyMuPDF/issues/2788>`_: Problem with get_toc in pymupdf 1.23.6
* **Fixed** `2791 <https://github.com/pymupdf/PyMuPDF/issues/2791>`_: Experiencing small memory leak in save()
* Bug fixes (rebased and classic implementations):
* **Fixed** `2736 <https://github.com/pymupdf/PyMuPDF/issues/2736>`_: Failure when set cropbox with mediabox negative value
* **Fixed** `2749 <https://github.com/pymupdf/PyMuPDF/issues/2749>`_: RuntimeError: cycle in structure tree
* **Fixed** `2753 <https://github.com/pymupdf/PyMuPDF/issues/2753>`_: Story.write_with_links will ignore everything after the first "page break" in the HTML.
* **Fixed** `2812 <https://github.com/pymupdf/PyMuPDF/issues/2812>`_: find_tables on landscape page generates reversed text
* **Fixed** `2829 <https://github.com/pymupdf/PyMuPDF/issues/2829>`_: [cannot create /Annot for kind] is still printed despite #2345 is closed.
* **Fixed** `2841 <https://github.com/pymupdf/PyMuPDF/issues/2841>`_: Unexpected KeyError when using scrub with fitz_new
* Use MuPDF-1.23.7.
* Other:
* Rebased implementation:
* Added flake8 code checking to test suite, and made various fixes.
* Disable diagnostics during Document constructor to match classic implementation.
* Additional fix to `2553 <https://github.com/pymupdf/PyMuPDF/issues/2553>`_: Invalid characters in versions >= 1.22
* Fixed `MuPDF Bug 707324 <https://bugs.ghostscript.com/show_bug.cgi?id=707324>`_: Story: HTML table row background color repeated incorrectly
* Added `scripts/test.py`, for simple build+test of PyMuPDF git checkout.
* Added `fitz.pymupdf_version_tuple`, e.g. `(1, 23, 6)`.
* Restored mistakenly-reverted fix for `2345 <https://github.com/pymupdf/PyMuPDF/issues/2345>`_: Turn off print statements in utils.py
* Include any trailing `... repeated <N> times...` text in warnings returned by `mupdf_warnings()` (rebased only).
**Changes in version 1.23.6 (2023-11-06)**
* Bug fixes:
* **Fixed** `2553 <https://github.com/pymupdf/PyMuPDF/issues/2553>`_: Invalid characters in versions >= 1.22
* **Fixed** `2608 <https://github.com/pymupdf/PyMuPDF/issues/2608>`_: Incorrect utf32 text extraction (high & low surrogates are split)
* **Fixed** `2710 <https://github.com/pymupdf/PyMuPDF/issues/2710>`_: page.rect and text location wrong / differing from older version
* **Fixed** `2774 <https://github.com/pymupdf/PyMuPDF/issues/2774>`_: wrong encoding for "\?" character when sort=True
* **Fixed** `2775 <https://github.com/pymupdf/PyMuPDF/issues/2775>`_: fitz_new does not work with python3.10 or earlier
* **Fixed** `2777 <https://github.com/pymupdf/PyMuPDF/issues/2777>`_: With fitz_new, wrong type for Page.mediabox
* Other:
* Use MuPDF-1.23.5.
* Added Document.resolve_names() (rebased implementation only).
**Changes in version 1.23.5 (2023-10-11)**
* Bug fixes:
* **Fixed** `2341 <https://github.com/pymupdf/PyMuPDF/issues/2341>`_: Handling negative values in the zoom section for LINK_GOTO in linkDest
* **Fixed** `2522 <https://github.com/pymupdf/PyMuPDF/issues/2522>`_: Typo in set_layer() - NameError: name 'f' is not defined
* **Fixed** `2548 <https://github.com/pymupdf/PyMuPDF/issues/2548>`_: Fitz freezes on some PDFs when calling the fitz.Page.get_text_blocks method.
* **Fixed** `2596 <https://github.com/pymupdf/PyMuPDF/issues/2596>`_: save(garbage=3) breaks get_pixmap() with side effect
* **Fixed** `2635 <https://github.com/pymupdf/PyMuPDF/issues/2635>`_: "clean=True" makes objects invisible in the pdf
* **Fixed** `2637 <https://github.com/pymupdf/PyMuPDF/issues/2637>`_: Page.insert_textbox incorrectly handles the last word if it starts a new line
* **Fixed** `2699 <https://github.com/pymupdf/PyMuPDF/issues/2699>`_: extract paragraph with below table
* **Fixed** `2703 <https://github.com/pymupdf/PyMuPDF/issues/2703>`_: Wrong fontsize calculation in corner cases ("page.get_texttrace()")
* **Fixed** `2710 <https://github.com/pymupdf/PyMuPDF/issues/2710>`_: page.rect and text location wrong / differing from older version
* **Fixed** `2723 <https://github.com/pymupdf/PyMuPDF/issues/2723>`_: When will a Python 3.12 wheel be available?
* **Fixed** `2730 <https://github.com/pymupdf/PyMuPDF/issues/2730>`_: persistent get_text() formatting
* Other:
* Use MuPDF-1.23.4.
* Fix optimisation flags with system installs.
* Fixed the problem that the clip parameter does not take effect during table recognition
* Support Pillow mode "RGBa"
* Support extra word delimiters
* Support checking valid PDF name objects
**Changes in version 1.23.4 (2023-09-26)**
* Improved build instructions.
* Fixed Tesseract in rebased implementation.
* Improvements to build/install with system MuPDF.
* Fixed Pyodide builds.
* Fixed rebased bug in _insert_image().
* Bug fixes:
* **Fixed** `2556 <https://github.com/pymupdf/PyMuPDF/issues/2556>`_: Segmentation fault at calling get_cdrawings(extended=True)
* **Fixed** `2637 <https://github.com/pymupdf/PyMuPDF/issues/2637>`_: Page.insert_textbox incorrectly handles the last word if it starts a new line
* **Fixed** `2683 <https://github.com/pymupdf/PyMuPDF/issues/2683>`_: Windows sdist build failure - non-quoting of path and using UNIX which command
* **Fixed** `2691 <https://github.com/pymupdf/PyMuPDF/issues/2691>`_: Page.get_textpage_ocr() bug in rebased fitz_new version
* **Fixed** `2692 <https://github.com/pymupdf/PyMuPDF/issues/2692>`_: Page.get_pixmap(clip=Rect()) bug in rebased fitz_new version
**Changes in version 1.23.3 (2023-08-31)**
* Fixed use of Tesseract for OCR.
**Changes in version 1.23.2 (2023-08-28)**
* **Fixed** `#2613 <https://github.com/pymupdf/PyMuPDF/issues/2613>`_: release 1.23.0 not MacOS-arm64 compatible
**Changes in version 1.23.1 (2023-08-24)**
* Updated README and package summary description.
*
Fixed a problem on some Linux installations with Python-3.10
(and possibly earlier versions) where `import fitz` failed with
`ImportError: libcrypt.so.2: cannot open shared object file: No such
file or directory`.
*
Fixed `incompatible architecture` error on MacOS arm64.
*
Fixed installation warning from Poetry about missing entry in wheels'
RECORD files.
**Changes in version 1.23.0 (2023-08-22)**
* Add method `find_tables()` to the `Page` object.
This allows locating tables on any supported document page, and
extracting table content by cell.
* New "rebased" implementation of PyMuPDF.
The rebased implementation is available as Python module
`fitz_new`. It can be used as a drop-in replacement with `import
fitz_new as fitz`.
*
Python-independent MuPDF libraries are now in a second wheel called
`PyMuPDFb` that will be automatically installed by pip.
This is to save space on pypi.org - a full release only needs one
`PyMuPDFb` wheel for each OS.
* Bug fixes:
* **Fixed** `#2542 <https://github.com/pymupdf/PyMuPDF/issues/2542>`_: fitz.utils.scrub AttributeError Annot object has no attribute fileUpd inside
* **Fixed** `#2533 <https://github.com/pymupdf/PyMuPDF/issues/2533>`_: get_texttrace returned a incorrect character bbox
* **Fixed** `#2537 <https://github.com/pymupdf/PyMuPDF/issues/2537>`_: Validation when setting a grouped RadioButton throws a RuntimeError: path to 'V' has indirects
* Other changes:
* Dropped support for Python-3.7.
* Fix for wrong page / annot `/Contents` cleaning.
We need to set `pdf_filter_options::no_update` to zero.
* Added new function get_tessdata().
* Cope with problem `/Annot` arrays.
When copying page annotations in method Document.insert_pdf we
previously did not check the validity of members of the `/Annots`
array. For faulty members (like null or non-dictionary items) this
could cause unnecessary exceptions. This fix implements more checks
and skips such array items.
* Additional annotation type checks.
We did not previously check for annotation type when getting /
setting annotation border properties. This is now checked in
accordance with MuPDF.
* Increase fault tolerance.
Avoid exceptions in method `insert_pdf()` when source pages contains
invalid items in the `/Annots` array.
* Return empty border dict for applicable annots.
We previously were returning a non-empty border dictionary even for
non-applicable annotation types. We now return the empty dictionary
`{}` in these cases. This requires some corresponding changes in the
annotation `.update()` method, namely for dashes and border width.
* Restrict `set_rect` to applicable annot types.
We were insufficiently excluding non-applicable annotation types
from `set_rect()` method. We now let MuPDF catch unsupported
annotations and return `False` in these cases.
* Wrong fontsize computation in `page.get_texttrace()`.
When computing the font size we were using the final text
transformation matrix, where we should have taken `span->trm`
instead. This is corrected here.
* Updates to cope with changes to latest MuPDF.
`pdf_lookup_anchor()` has been removed.
* Update fill_textbox to better respect rect.width
The function norm_words in fill_textbox had a bug in its last
loop, appending n+1 characters when actually measuring width of n
characters. It led to a bug in fill_texbox when you tried to write
a single word mostly composed of "wide" letters (M,m, W, w...),
causing the written text to exceed the given rect.
The fix was just to replace n+1 by n.
* Add `script_focus` and `script_blur` options to widget.
**Changes in version 1.22.5 (2023-06-21)**
* This release uses ``MuPDF-1.22.2``.
* Bug fixes:
* **Fixed** `#2365 <https://github.com/pymupdf/PyMuPDF/issues/2365>`_: Incorrect dictionary values for type "fs" drawings.
* **Fixed** `#2391 <https://github.com/pymupdf/PyMuPDF/issues/2391>`_: Check box automatically uncheck when we update same checkbox more than 1 times.
* **Fixed** `#2400 <https://github.com/pymupdf/PyMuPDF/issues/2400>`_: Gaps within text of same line not filled with spaces.
* **Fixed** `#2404 <https://github.com/pymupdf/PyMuPDF/issues/2404>`_: Blacklining an image in PDF won't remove underlying content in version 1.22.X.
* **Fixed** `#2430 <https://github.com/pymupdf/PyMuPDF/issues/2430>`_: Incorrectly reducing ref count of Py_None.
* **Fixed** `#2450 <https://github.com/pymupdf/PyMuPDF/issues/2450>`_: Empty fill color and fill opacity for paths with fill and stroke operations with 1.22.*
* **Fixed** `#2462 <https://github.com/pymupdf/PyMuPDF/issues/2462>`_: Error at "get_drawing(extended=True )"
* **Fixed** `#2468 <https://github.com/pymupdf/PyMuPDF/issues/2468>`_: Decode error when trying to get drawings
* **Fixed** `#2710 <https://github.com/pymupdf/PyMuPDF/issues/2710>`_: page.rect and text location wrong / differing from older version
* **Fixed** `#2723 <https://github.com/pymupdf/PyMuPDF/issues/2723>`_: When will a Python 3.12 wheel be available?
* New features:
* **Changed** Annotations now support "cloudy" borders.
The :attr:`Annot.border` property has the new item `clouds`,
and method :meth:`Annot.set_border` supports the corresponding `clouds` argument.
* **Changed** Radio button widgets in the same RB group
are now consistently updated **if the group is defined in the standard way**.
* **Added** Support for the `/Locked` key in PDF Optional Content.
This array inside the catalog entry `/OCProperties` can now be extracted and set.
* **Added** Support for new parameter `tessdata` in OCR functions.
New function :meth:`get_tessdata` locates the language support folder if Tesseract is installed.
**Changes in version 1.22.3 (2023-05-10)**
* This release uses ``MuPDF-1.22.0``.
* Bug fixes:
* **Fixed** `#2333 <https://github.com/pymupdf/PyMuPDF/issues/2333>`_: Unable to set any of button radio group in form
**Changes in version 1.22.2 (2023-04-26)**
* This release uses ``MuPDF-1.22.0``.
* Bug fixes:
* **Fixed** `#2369 <https://github.com/pymupdf/PyMuPDF/issues/2369>`_: Image extraction bugs with newer versions
**Changes in version 1.22.1 (2023-04-18)**
* This release uses ``MuPDF-1.22.0``.
* Bug fixes:
* **Fixed** `#2345 <https://github.com/pymupdf/PyMuPDF/issues/2345>`_: Turn off print statements in utils.py
* **Fixed** `#2348 <https://github.com/pymupdf/PyMuPDF/issues/2348>`_: extract_image returns an extension "flate" instead of "png"
* **Fixed** `#2350 <https://github.com/pymupdf/PyMuPDF/issues/2350>`_: Can not make widget (checkbox) to read-only by adding flags PDF_FIELD_IS_READ_ONLY
* **Fixed** `#2355 <https://github.com/pymupdf/PyMuPDF/issues/2355>`_: 1.22.0 error when using get_toc (AttributeError: 'SwigPyObject' object has no attribute)
**Changes in version 1.22.0 (2023-04-14)**
* This release uses ``MuPDF-1.22.0``.
* Behavioural changes:
* Text extraction now includes glyphs that overlap with clip rect; previously
they were included only if they were entirely contained within the clip
rect.
* Bug fixes:
* **Fixed** `#1763 <https://github.com/pymupdf/PyMuPDF/issues/1763>`_: Interactive(smartform) form PDF calculation not working in pymupdf
* **Fixed** `#1995 <https://github.com/pymupdf/PyMuPDF/issues/1995>`_: RuntimeError: image is too high for a long paged pdf file when trying
* **Fixed** `#2093 <https://github.com/pymupdf/PyMuPDF/issues/2093>`_: Image in pdf changes color after applying redactions
* **Fixed** `#2108 <https://github.com/pymupdf/PyMuPDF/issues/2108>`_: Redaction removing more text than expected
* **Fixed** `#2141 <https://github.com/pymupdf/PyMuPDF/issues/2141>`_: Failed to read JPX header when trying to get blocks
* **Fixed** `#2144 <https://github.com/pymupdf/PyMuPDF/issues/2144>`_: Replace image throws an error
* **Fixed** `#2146 <https://github.com/pymupdf/PyMuPDF/issues/2146>`_: Wrong Handling of Reference Count of "None" Object
* **Fixed** `#2161 <https://github.com/pymupdf/PyMuPDF/issues/2161>`_: Support adding images as pages directly
* **Fixed** `#2168 <https://github.com/pymupdf/PyMuPDF/issues/2168>`_: ``page.add_highlight_annot(start=pointa, stop=pointb)`` not working
* **Fixed** `#2173 <https://github.com/pymupdf/PyMuPDF/issues/2173>`_: Double free of ``Colorspace`` used in ``Pixmap``
* **Fixed** `#2179 <https://github.com/pymupdf/PyMuPDF/issues/2179>`_: Incorrect documentation for ``pixmap.tint_with()``
* **Fixed** `#2208 <https://github.com/pymupdf/PyMuPDF/issues/2208>`_: Pushbutton widget appears as check box
* **Fixed** `#2210 <https://github.com/pymupdf/PyMuPDF/issues/2210>`_: ``apply_redactions()`` move pdf text to right after redaction
* **Fixed** `#2220 <https://github.com/pymupdf/PyMuPDF/issues/2220>`_: ``Page.delete_image()`` | object has no attribute ``is_image``
* **Fixed** `#2228 <https://github.com/pymupdf/PyMuPDF/issues/2228>`_: open some pdf cost too much time
* **Fixed** `#2238 <https://github.com/pymupdf/PyMuPDF/issues/2238>`_: Bug - can not extract data from file in the newest version 1.21.1
* **Fixed** `#2242 <https://github.com/pymupdf/PyMuPDF/issues/2242>`_: Python quits silently in ``Story.element_positions()`` if callback function prototype is wrong
* **Fixed** `#2246 <https://github.com/pymupdf/PyMuPDF/issues/2246>`_: TextWriter write text in a wrong position
* **Fixed** `#2248 <https://github.com/pymupdf/PyMuPDF/issues/2248>`_: After redacting the content, the position of the remaining text changes
* **Fixed** `#2250 <https://github.com/pymupdf/PyMuPDF/issues/2250>`_: docs: unclear or broken link in page.rst
* **Fixed** `#2251 <https://github.com/pymupdf/PyMuPDF/issues/2251>`_: mupdf_display_errors does not apply to Pixmap when loading broken image
* **Fixed** `#2270 <https://github.com/pymupdf/PyMuPDF/issues/2270>`_: ``Annot.get_text("words")`` - doesn't return the first line of words
* **Fixed** `#2275 <https://github.com/pymupdf/PyMuPDF/issues/2275>`_: insert_image: document that rotations are counterclockwise
* **Fixed** `#2278 <https://github.com/pymupdf/PyMuPDF/issues/2278>`_: Can not make widget (checkbox) to read-only by adding flags PDF_FIELD_IS_READ_ONLY
* **Fixed** `#2290 <https://github.com/pymupdf/PyMuPDF/issues/2290>`_: Different image format/data from Page.get_text("dict") and Fitz.get_page_images()
* **Fixed** `#2293 <https://github.com/pymupdf/PyMuPDF/issues/2293>`_: 68 failed tests when installing from sdist on my box
* **Fixed** `#2300 <https://github.com/pymupdf/PyMuPDF/issues/2300>`_: Too much recursion in tree (parents), makes program terminate
* **Fixed** `#2322 <https://github.com/pymupdf/PyMuPDF/issues/2322>`_: add_highlight_annot using clip generates "A Number is Out of Range" error in PDF
* Other:
* Add key "/AS (Yes)" to the underlying annot object of a selected button form field.
* Remove unused ``Document`` methods ``has_xref_streams()`` and
``has_old_style_xrefs()`` as MuPDF equivalents have been removed.
* Add new ``Document`` methods and properties for getting/setting
``/PageMode``, ``/PageLayout`` and ``/MarkInfo``.
* New ``Document`` property ``version_count``, which contains the number of
incremental saves plus one.
* New ``Document`` property ``is_fast_webaccess`` which tells whether the
document is linearized.
* ``DocumentWriter`` is now a context manager.
* Add support for ``Pixmap`` JPEG output.
* Add support for drawing rectangles with rounded corners.
* ``get_drawings()``: added optional ``extended`` arg.
* Fixed issue where trace devices' state was not being initialised
correctly; data returned from things like ``fitz.Page.get_texttrace()``
might be slightly altered, e.g. ``linewidth`` values.
* Output warning to ``stderr`` if it looks like we are being used with
current directory containing an invalid ``fitz/`` directory, because
this can break import of ``fitz`` module. For example this happens
if one attempts to use ``fitz`` when current directory is a PyMuPDF
checkout.
* Documentation:
* General rework:
* Introduces a new home page and new table of contents.
* Structural update to include new About section.
* Comparison & performance graphing.
* Includes performance methodology in appendix.
* Updates conf.py to understand single back-ticks as code.
* Converts double back-ticks to single back-ticks.
* Removes redundant files.
* Improve ``insert_file()`` documentation.
* ``get_bboxlog()``: added optional ``layers`` to ``get_bboxlog()``.
* ``Page.get_texttrace()``: add new dictionary key ``layer``, name of Optional Content Group.
* Mention use of Python venv in installation documentation.
* Added missing fix for #2057 to release 1.21.1's changelog.
* Fixes many links to the PyMuPDF-Utilities repo scripts.
* Avoid duplication of ``changes.txt`` and ``docs/changes.rst``.
* Build
* Added ``pyproject.toml`` file to improve builds using pip etc.
**Changes in Version 1.21.1 (2022-12-13)**
* This release uses ``MuPDF-1.21.1``.
* Bug fixes:
* **Fixed** `#2110 <https://github.com/pymupdf/PyMuPDF/issues/2110>`_: Fully embedded font is extracted only partially if it occupies more than one object
* **Fixed** `#2094 <https://github.com/pymupdf/PyMuPDF/issues/2094>`_: Rectangle Detection Logic
* **Fixed** `#2088 <https://github.com/pymupdf/PyMuPDF/issues/2088>`_: Destination point not set for named links in toc
* **Fixed** `#2087 <https://github.com/pymupdf/PyMuPDF/issues/2087>`_: Image with Filter "[/FlateDecode/JPXDecode]" not extracted
* **Fixed** `#2086 <https://github.com/pymupdf/PyMuPDF/issues/2086>`_: Document.save() owner_pw & user_pw has buffer overflow bug
* **Fixed** `#2076 <https://github.com/pymupdf/PyMuPDF/issues/2076>`_: Segfault in fitz.py
* **Fixed** `#2057 <https://github.com/pymupdf/PyMuPDF/issues/2057>`_: Document.save garbage parameter not working in PyMuPDF 1.21.0
* **Fixed** `#2051 <https://github.com/pymupdf/PyMuPDF/issues/2051>`_: Missing DPI Parameter
* **Fixed** `#2048 <https://github.com/pymupdf/PyMuPDF/issues/2048>`_: Invalid size of TextPage and bbox with newest version 1.21.0
* **Fixed** `#2045 <https://github.com/pymupdf/PyMuPDF/issues/2045>`_: SystemError: <built-in function Page_get_texttrace> returned a result with an error set
* **Fixed** `#2039 <https://github.com/pymupdf/PyMuPDF/issues/2039>`_: 1.21.0 fails to build against system libmupdf
* **Fixed** `#2036 <https://github.com/pymupdf/PyMuPDF/issues/2036>`_: Archive::Archive defined twice
* Other
* Swallow "&zoom=nan" in link uri strings.
* Add new Page utility methods ``Page.replace_image()`` and ``Page.delete_image()``.
* Documentation:
* `#2040 <https://github.com/pymupdf/PyMuPDF/issues/2040>`_: Added note about test failure with non-default build of MuPDF, to ``tests/README.md``.
* `#2037 <https://github.com/pymupdf/PyMuPDF/issues/2037>`_: In ``docs/installation.rst``, mention incompatibility with chocolatey.org on Windows.
* `#2061 <https://github.com/pymupdf/PyMuPDF/issues/2061>`_: Fixed description of ``Annot.file_info``.
* `#2065 <https://github.com/pymupdf/PyMuPDF/issues/2065>`_: Show how to insert internal PDF link.
* Improved description of building from source without an sdist.
* Added information about running tests.
* `#2084 <https://github.com/pymupdf/PyMuPDF/issues/2084>`_: Fixed broken link to PyMuPDF-Utilities.
**Changes in Version 1.21.0 (2022-11-8)**
* This release uses ``MuPDF-1.21.0``.
* New feature: Stories.
* Added wheels for Python-3.11.
* Bug fixes:
* **Fixed** `#1701 <https://github.com/pymupdf/PyMuPDF/issues/1701>`_: Broken custom image insertion.
* **Fixed** `#1854 <https://github.com/pymupdf/PyMuPDF/issues/1854>`_: `Document.delete_pages()` declines keyword arguments.
* **Fixed** `#1868 <https://github.com/pymupdf/PyMuPDF/issues/1868>`_: Access Violation Error at `page.apply_redactions()`.
* **Fixed** `#1909 <https://github.com/pymupdf/PyMuPDF/issues/1909>`_: Adding text with `fontname="Helvetica"` can silently fail.
* **Fixed** `#1913 <https://github.com/pymupdf/PyMuPDF/issues/1913>`_: `draw_rect()`: does not respect width if color is not specified.
* **Fixed** `#1917 <https://github.com/pymupdf/PyMuPDF/issues/1917>`_: `subset_fonts()`: make it possible to silence the stdout.
* **Fixed** `#1936 <https://github.com/pymupdf/PyMuPDF/issues/1936>`_: Rectangle detection can be incorrect producing wrong output.
* **Fixed** `#1945 <https://github.com/pymupdf/PyMuPDF/issues/1945>`_: Segmentation fault when saving with `clean=True`.
* **Fixed** `#1965 <https://github.com/pymupdf/PyMuPDF/issues/1965>`_: `pdfocr_save()` Hard Crash.
* **Fixed** `#1971 <https://github.com/pymupdf/PyMuPDF/issues/1971>`_: Segmentation fault when using `get_drawings()`.
* **Fixed** `#1946 <https://github.com/pymupdf/PyMuPDF/issues/1946>`_: `block_no` and `block_type` switched in `get_text()` docs.
* **Fixed** `#2013 <https://github.com/pymupdf/PyMuPDF/issues/2013>`_: AttributeError: 'Widget' object has no attribute '_annot' in delete widget.
* Misc changes to core code:
* Fixed various compiler warnings and a sequence-point bug.
* Added support for Memento builds.
* Fixed leaks detected by Memento in test suite.
* Fixed handling of exceptions in set_name() and set_rect().
* Allow build with latest MuPDF, for regular testing of PyMuPDF master.
* Cope with new MuPDF exceptions when setting rect for some Annot types.
* Reduced cosmetic differences between MuPDF's config.h and PyMuPDF's _config.h.
* Cope with various changes to MuPDF API.
* Other:
* Fixed various broken links and typos in docs.
* Mention install of `swig-python` on MacOS for #875.
* Added (untested) wheels for macos-arm64.
**Changes in Version 1.20.2**
* This release uses ``MuPDF-1.20.3``.
* **Fixed** `#1787 <https://github.com/pymupdf/PyMuPDF/issues/1787>`_.
Fix linking issues on Unix systems.
* **Fixed** `#1824 <https://github.com/pymupdf/PyMuPDF/issues/1824>`_.
SegFault when applying redactions overlapping a transparent image. (Fixed
in ``MuPDF-1.20.3``.)
* Improvements to documentation:
* Improved information about building from source in ``docs/installation.rst``.
* Clarified memory allocation setting ``JM_MEMORY` in ``docs/tools.rst``.
* Fixed link to PDF Reference manual in ``docs/app3.rst``.
* Fixed building of html documentation on OpenBSD.
* Moved old ``docs/faq.rst`` into separate ``docs/recipes-*`` files.
* Removed some unused files and directories:
* ``installation/``
* ``docs/wheelnames.txt``
**Changes in Version 1.20.1**
* **Fixed** `#1724 <https://github.com/pymupdf/PyMuPDF/issues/1724>`_.
Fix for building on FreeBSD.
* **Fixed** `#1771 <https://github.com/pymupdf/PyMuPDF/issues/1771>`_.
`linkDest()` had a broken call to `re.match()`, introduced in 1.20.0.
* **Fixed** `#1751 <https://github.com/pymupdf/PyMuPDF/issues/1751>`_.
`get_drawings()` and `get_cdrawings()` previously always returned with `closePath=False`.
* **Fixed** `#1645 <https://github.com/pymupdf/PyMuPDF/issues/1645>`_.
Default FreeText annotation text color is now black.
* Improvements to sphinx-generated documentation:
* Use readthedocs theme with enhancements.
* Renamed the `.txt` files to have `.rst` suffixes.
------
**Changes in Version 1.20.0**
This release uses ``MuPDF-1.20.0``, released 2022-06-15.
* Cope with new MuPDF link uri format, changed from ``#<int>,<int>,<int>`` to ``#page=<int>&zoom=<float>,<float>,<float>``.
* In ``tests/test_insertpdf.py``, use new reference output ``joined-1.20.pdf``. We also check that new output values are approximately the same as the old ones.
* **Fixed** `#1738 <https://github.com/pymupdf/PyMuPDF/issues/1738>`_. Leak of `pdf_graft_map`.
Also fixed a SEGV issue that this seemed to expose, caused by incorrect freeing of underlying fz_document.
* **Fixed** `#1733 <https://github.com/pymupdf/PyMuPDF/issues/1733>`_. Fixed ownership of `Annotation.get_pixmap()`.
Changes to build/release process:
* If pip builds from source because an appropriate wheel is not available, we no longer require MuPDF to be pre-installed. Instead the required MuPDF source is embedded in the sdist and automatically built into PyMuPDF.
* Various changes to ``setup.py`` to download the required MuPDF release as required. See comments at start of setup.py for details.
* Added ``.github/workflows/build_wheels.yml`` to control building of wheels on Github.
------
**Changes in Version 1.19.6**
* **Fixed** `#1620 <https://github.com/pymupdf/PyMuPDF/issues/1620>`_. The :ref:`TextPage` created by :meth:`Page.get_textpage` will now be freed correctly (removed memory leak).
* **Fixed** `#1601 <https://github.com/pymupdf/PyMuPDF/issues/1601>`_. Document open errors should now be more concise and easier to interpret. In the course of this, two PyMuPDF-specific Python exceptions have been **added:**
- ``EmptyFileError`` -- raised when trying to create a :ref:`Document` (``fitz.open()``) from an empty file or zero-length memory.
- ``FileDataError`` -- raised when MuPDF encounters irrecoverable document structure issues.
* **Added** :meth:`Page.load_widget` given a PDF field's xref.
* **Added** Dictionary :attr:`pdfcolor` which provide the about 500 colors defined as PDF color values with the lower case color name as key.
* **Added** algebra functionality to the :ref:`Quad` class. These objects can now also be added and subtracted among themselves, and be multiplied by numbers and matrices.
* **Added** new constants defining the default text extraction flags for more comfortable handling. Their naming convention is like :data:`TEXTFLAGS_WORDS` for ``page.get_text("words")``. See :ref:`text_extraction_flags`.
* **Changed** :meth:`Page.annots` and :meth:`Page.widgets` to detect and prevent reloading the page (illegally) inside the iterator loops via :meth:`Document.reload_page`. Doing this brings down the interpreter. Documented clean ways to do annotation and widget mass updates within properly designed loops.
* **Changed** several internal utility functions to become standalone ("SWIG inline") as opposed to be part of the :ref:`Tools` class. This, among other things, increases the performance of geometry object creation.
* **Changed** :meth:`Document.update_stream` to always accept stream updates - whether or not the dictionary object behind the xref already is a stream. Thus the former ``new`` parameter is now ignored and will be removed in v1.20.0.
------
**Changes in Version 1.19.5**
* **Fixed** `#1518 <https://github.com/pymupdf/PyMuPDF/issues/1518>`_. A limited "fix": in some cases, rectangles and quadrupels were not correctly encoded to support re-drawing by :ref:`Shape`.
* **Fixed** `#1521 <https://github.com/pymupdf/PyMuPDF/issues/1521>`_. This had the same ultimate reason behind issue #1510.
* **Fixed** `#1513 <https://github.com/pymupdf/PyMuPDF/issues/1513>`_. Some Optional Content functions did not support non-ASCII characters.
* **Fixed** `#1510 <https://github.com/pymupdf/PyMuPDF/issues/1510>`_. Support more soft-mask image subtypes.
* **Fixed** `#1507 <https://github.com/pymupdf/PyMuPDF/issues/1507>`_. Immunize against items in the outlines chain, that are ``"null"`` objects.
* **Fixed** re-opened `#1417 <https://github.com/pymupdf/PyMuPDF/issues/1417>`_. ("too many open files"). This was due to insufficient calls to MuPDF's ``fz_drop_document()``. This also fixes `#1550 <https://github.com/pymupdf/PyMuPDF/issues/1550>`_.
* **Fixed** several undocumented issues in relation to incorrectly setting the text span origin :data:`point_like`.
* **Fixed** undocumented error computing the character bbox in method :meth:`Page.get_texttrace` when text is **flipped** (as opposed to just rotated).
* **Added** items to the dictionary returned by :meth:`image_properties`: ``orientation`` and ``transform`` report the natural image orientation (EXIF data).
* **Added** method :meth:`Document.xref_copy`. It will make a given target PDF object an exact copy of a source object.
------
**Changes in Version 1.19.4**
* **Fixed** `#1505 <https://github.com/pymupdf/PyMuPDF/issues/1505>`_. Immunize against circular outline items.
* **Fixed** `#1484 <https://github.com/pymupdf/PyMuPDF/issues/1484>`_. Correct CropBox coordinates are now returned in all situations.
* **Fixed** `#1479 <https://github.com/pymupdf/PyMuPDF/issues/1479>`_.
* **Fixed** `#1474 <https://github.com/pymupdf/PyMuPDF/issues/1474>`_. TextPage objects are now properly deleted again.
* **Added** :ref:`Page` methods and attributes for PDF ``/ArtBox``, ``/BleedBox``, ``/TrimBox``.
* **Added** global attribute :attr:`TESSDATA_PREFIX` for easy checking of OCR support.
* **Changed** :meth:`Document.xref_set_key` such that dictionary keys will physically be removed if set to value ``"null"``.
* **Changed** :meth:`Document.extract_font` to optionally return a dictionary (instead of a tuple).
------
**Changes in Version 1.19.3**
This patch version implements minor improvements for :ref:`Pixmap` and also some important fixes.
* **Fixed** `#1351 <https://github.com/pymupdf/PyMuPDF/discussions/1351>`_. Reverted code that introduced the memory growth in v1.18.15.
* **Fixed** `#1417 <https://github.com/pymupdf/PyMuPDF/discussions/1417>`_. Developed circumvention for growth of open file handles using :meth:`Document.insert_pdf`.
* **Fixed** `#1418 <https://github.com/pymupdf/PyMuPDF/discussions/1418>`_. Developed circumvention for memory growth using :meth:`Document.insert_pdf`.
* **Fixed** `#1430 <https://github.com/pymupdf/PyMuPDF/discussions/1430>`_. Developed circumvention for mass pixmap generations of document pages.
* **Fixed** `#1433 <https://github.com/pymupdf/PyMuPDF/discussions/1433>`_. Solves a bbox error for some Type 3 font in PyMuPDF text processing.
* **Added** :meth:`Pixmap.color_topusage` to determine the share of the most frequently used color. Solves `#1397 <https://github.com/pymupdf/PyMuPDF/discussions/1397>`_.
* **Added** :meth:`Pixmap.warp` which makes a new pixmap from a given arbitrary convex quad inside the pixmap.
* **Added** :attr:`Annot.irt_xref` and :meth:`Annot.set_irt_xref` to inquire or set the `/IRT` ("In Response To") property of an annotation. Implements `#1450 <https://github.com/pymupdf/PyMuPDF/discussions/1450>`_.
* **Added** :meth:`Rect.torect` and :meth:`IRect.torect` which compute a matrix that transforms to a given other rectangle.
* **Changed** :meth:`Pixmap.color_count` to also return the count of each color.
* **Changed** :meth:`Page.get_texttrace` to also return correct span and character bboxes if ``span["dir"] != (1, 0)``.
------
**Changes in Version 1.19.2**
This patch version implements minor improvements for :meth:`Page.get_drawings` and also some important fixes.
* **Fixed** `#1388 <https://github.com/pymupdf/PyMuPDF/discussions/1388>`_. Fixed intermittent memory corruption when insert or updating annotations.
* **Fixed** `#1375 <https://github.com/pymupdf/PyMuPDF/discussions/1375>`_. Inconsistencies between line numbers as returned by the "words" and the "dict" options of :meth:`Page.get_text` have been corrected.
* **Fixed** `#1364 <https://github.com/pymupdf/PyMuPDF/issues/1342>`_. The check for being a ``"rawdict"`` span in :meth:`recover_span_quad` now works correctly.
* **Fixed** `#1342 <https://github.com/pymupdf/PyMuPDF/issues/1364>`_. Corrected the check for rectangle infiniteness in :meth:`Page.show_pdf_page`.
* **Changed** :meth:`Page.get_drawings`, :meth:`Page.get_cdrawings` to return an indicator on the area orientation covered by a rectangle. This implements `#1355 <https://github.com/pymupdf/PyMuPDF/issues/1355>`_. Also, the recognition rate for rectangles and quads has been significantly improved.
* **Changed** all text search and extraction methods to set the new ``flags`` option ``TEXT_MEDIABOX_CLIP`` to ON by default. That bit causes the automatic suppression of all characters that are completely outside a page's mediabox (in as far as that notion is supported for a document type). This eliminates the need for using ``clip=page.rect`` or similar for omitting text outside the visible area.
* **Added** parameter ``"dpi"`` to :meth:`Page.get_pixmap` and :meth:`Annot.get_pixmap`. When given, parameter ``"matrix"`` is ignored, and a :ref:`Pixmap` with the desired dots per inch is created.
* **Added** attributes :attr:`Pixmap.is_monochrome` and :attr:`Pixmap.is_unicolor` allowing fast checks of pixmap properties. Addresses `#1397 <https://github.com/pymupdf/PyMuPDF/discussions/1397>`_.
* **Added** method :meth:`Pixmap.color_count` to determine the unique colors in the pixmap.
* **Added** boolean parameter ``"compress"`` to PDF document method :meth:`Document.update_stream`. Addresses / enables solution for `#1408 <https://github.com/pymupdf/PyMuPDF/discussions/1408>`_.
------
**Changes in Version 1.19.1**
This is the first patch version to support MuPDF v1.19.0. Apart from one bug fix, it includes important improvements for OCR support and the option to **sort extracted text** to the standard reading order "from top-left to bottom-right".
* **Fixed** `#1328 <https://github.com/pymupdf/PyMuPDF/issues/1328>`_. "words" text extraction again returns correct ``(x0, y0)`` coordinates.
* **Changed** :meth:`Page.get_textpage_ocr`: it now supports parameter ``dpi`` to control OCR quality. It is also possible to choose whether the **full page** should be OCRed or **only the images displayed** by the page.
* **Changed** :meth:`Page.get_drawings` and :meth:`Page.get_cdrawings` to automatically convert colors to RGB color tuples. Implements `#1332 <https://github.com/pymupdf/PyMuPDF/discussions/1332>`_. Similar change was applied to :meth:`Page.get_texttrace`.
* **Changed** :meth:`Page.get_text` to support a parameter ``sort``. If set to ``True`` the output is conveniently sorted.
------
**Changes in Version 1.19.0**
This is the first version supporting MuPDF 1.19.*, published 2021-10-05. It introduces many new features compared to the previous version 1.18.*.
PyMuPDF has now picked up integrated Tesseract OCR support, which was already present in MuPDF v1.18.0.
* Supported images can be OCRed via their :ref:`Pixmap` which results in a 1-page PDF with a text layer.
* All supported document pages (i.e. not only PDFs), can be OCRed using specialized text extraction methods. The result is a mixture of standard and OCR text (depending on which part of the page was deemed to require OCRing) that can be searched and extracted without restrictions.
* All this requires an independent installation of Tesseract. MuPDF actually (only) needs the location of Tesseract's ``"tessdata"`` folder, where its language support data are stored. This location must be available as environment variable ``TESSDATA_PREFIX``.
A new MuPDF feature is **journalling PDF updates**, which is also supported by this PyMuPDF version. Changes may be logged, rolled back or replayed, allowing to implement a whole new level of control over PDF document integrity -- similar to functions present in modern database systems.
A third feature (unrelated to the new MuPDF version) includes the ability to detect when page **objects cover or hide each other**. It is now e.g. possible to see that text is covered by a drawing or an image.
* **Changed** terminology and meaning of important geometry concepts: Rectangles are now characterized as *finite*, *valid* or *empty*, while the definitions of these terms have also changed. Rectangles specifically are now thought of being "open": not all corners and sides are considered part of the rectangle. Please do read the :ref:`Rect` section for details.
* **Added** new parameter `"no_new_id"` to :meth:`Document.save` / :meth:`Document.tobytes` methods. Use it to suppress updating the second item of the document ``/ID`` which in PDF indicates that the original file has been updated. If the PDF has no ``/ID`` at all yet, then no new one will be created either.
* **Added** a **journalling facility** for PDF updates. This allows logging changes, undoing or redoing them, or saving the journal for later use. Refer to :meth:`Document.journal_enable` and friends.
* **Added** new :ref:`Pixmap` methods :meth:`Pixmap.pdfocr_save` and :meth:`Pixmap.pdfocr_tobytes`, which generate a 1-page PDF containing the pixmap as PNG image with OCR text layer.
* **Added** :meth:`Page.get_textpage_ocr` which executes optical character recognition for the page, then extracts the results and stores them together with "normal" page content in a :ref:`TextPage`. Use or reuse this object in subsequent text extractions and text searches to avoid multiple efforts. The existing text search and text extraction methods have been extended to support a separately created textpage -- see next item.
* **Added** a new parameter ``textpage`` to text extraction and text search methods. This allows reuse of a previously created :ref:`TextPage` and thus achieves significant runtime benefits -- which is especially important for the new OCR features. But "normal" text extractions can definitely also benefit.
* **Added** :meth:`Page.get_texttrace`, a technical method delivering low-level text character properties. It was present before as a private method, but the author felt it now is mature enough to be officially available. It specifically includes a "sequence number" which indicates the page appearance build operation that painted the text.
* **Added** :meth:`Page.get_bboxlog` which delivers the list of rectangles of page objects like text, images or drawings. Its significance lies in its sequence: rectangles intersecting areas with a lower index are covering or hiding them.
* **Changed** methods :meth:`Page.get_drawings` and :meth:`Page.get_cdrawings` to include a "sequence number" indicating the page appearance build operation that created the drawing.
* **Fixed** `#1311 <https://github.com/pymupdf/PyMuPDF/issues/1311>`_. Field values in comboboxes should now be handled correctly.
* **Fixed** `#1290 <https://github.com/pymupdf/PyMuPDF/issues/1290>`_. Error was caused by incorrect rectangle emptiness check, which is fixed due to new geometry logic of this version.
* **Fixed** `#1286 <https://github.com/pymupdf/PyMuPDF/issues/1286>`_. Text alignment for redact annotations is working again.
* **Fixed** `#1287 <https://github.com/pymupdf/PyMuPDF/issues/1287>`_. Infinite loop issue for non-Windows systems when applying some redactions has been resolved.
* **Fixed** `#1284 <https://github.com/pymupdf/PyMuPDF/issues/1284>`_. Text layout destruction after applying redactions in some cases has been resolved.
------
**Changes in Version 1.18.18 / 1.18.19**
* **Fixed** issue `#1266 <https://github.com/pymupdf/PyMuPDF/issues/1266>`_. Failure to set :attr:`Pixmap.samples` in important cases, was hotfixed in a new version 1.18.19.
* **Fixed** issue `#1257 <https://github.com/pymupdf/PyMuPDF/issues/1257>`_. Removing the read-only flag from PDF fields is now possible.
* **Fixed** issue `#1252 <https://github.com/pymupdf/PyMuPDF/issues/1252>`_. Now correctly specifying the ``zoom`` value for PDF link annotations.
* **Fixed** issue `#1244 <https://github.com/pymupdf/PyMuPDF/issues/1244>`_. Now correctly computing the transform matrix in :meth:`Page.get_image__bbox`.
* **Fixed** issue `#1241 <https://github.com/pymupdf/PyMuPDF/issues/1241>`_. Prevent returning artifact characters in :meth:`Page.get_textbox`, which happened in certain constellations.
* **Fixed** issue `#1234 <https://github.com/pymupdf/PyMuPDF/issues/1234>`_. Avoid creating infinite rectangles in corner cases -- :meth:`Page.get_drawings`, :meth:`Page.get_cdrawings`.
* **Added** test data and test scripts to the source PyPI source distribution.
------
**Changes in Version 1.18.17**
Focus of this version are major performance improvements of selected functions.
* **Fixed** issue `#1199 <https://github.com/pymupdf/PyMuPDF/issues/1199>`_. Using a non-existing page number in :meth:`Document.get_page_images` and friends will no longer lead to segfaults.
* **Changed** :meth:`Page.get_drawings` to now differentiate between "stroke", "fill" and combined paths. Paths containing more than one rectangle (i.e. "re" items) are now supported. Extracting "clipped" paths is now available as an option.
* **Added** :meth:`Page.get_cdrawings`, performance-optimized version of :meth:`Page.get_drawings`.
* **Added** :attr:`Pixmap.samples_mv`, *memoryview* of a pixmap's pixel area. Does not copy and thus always accesses the current state of that area.
* **Added** :attr:`Pixmap.samples_ptr`, Python "pointer" to a pixmap's pixel area. Allows much faster creation (factor 800+) of Qt images.
------
**Changes in Version 1.18.16**
* **Fixed** issue `#1184 <https://github.com/pymupdf/PyMuPDF/issues/1184>`_. Existing PDF widget fonts in a PDF are now accepted (i.e. not forcedly changed to a Base-14 font).
* **Fixed** issue `#1154 <https://github.com/pymupdf/PyMuPDF/issues/1154>`_. Text search hits should now be correct when ``clip`` is specified.
* **Fixed** issue `#1152 <https://github.com/pymupdf/PyMuPDF/issues/1152>`_.
* **Fixed** issue `#1146 <https://github.com/pymupdf/PyMuPDF/issues/1146>`_.
* **Added** :attr:`Link.flags` and :meth:`Link.set_flags` to the :ref:`Link` class. Implements enhancement requests `#1187 <https://github.com/pymupdf/PyMuPDF/issues/1187>`_.
* **Added** option to *simulate* :meth:`TextWriter.fill_textbox` output for predicting the number of lines, that a given text would occupy in the textbox.
* **Added** text output support as subcommand `gettext` to the ``fitz`` CLI module. Most importantly, original **physical text layout** reproduction is now supported.
------
**Changes in Version 1.18.15**
* **Fixed** issue `#1088 <https://github.com/pymupdf/PyMuPDF/issues/1088>`_. Removing an annotation's fill color should now work again both ways, using the ``fill_color=[]`` argument in :meth:`Annot.update` as well as ``fill=[]`` in :meth:`Annot.set_colors`.
* **Fixed** issue `#1081 <https://github.com/pymupdf/PyMuPDF/issues/1081>`_. :meth:`Document.subset_fonts`: fixed an error which created wrong character widths for some fonts.
* **Fixed** issue `#1078 <https://github.com/pymupdf/PyMuPDF/issues/1078>`_. :meth:`Page.get_text` and other methods related to text extraction: changed the default value of the :ref:`TextPage` ``flags`` parameter. All whitespace and :data:`ligatures` are now preserved.
* **Fixed** issue `#1085 <https://github.com/pymupdf/PyMuPDF/issues/1085>`_. The old *snake_cased* alias of ``fitz.detTextlength`` is now defined correctly.
* **Changed** :meth:`Document.subset_fonts` will now correctly prefix font subsets with an appropriate six letter uppercase tag, complying with the PDF specification.
* **Added** new method :meth:`Widget.button_states` which returns the possible values that a button-type field can have when being set to "on" or "off".
* **Added** support of text with **Small Capital** letters to the :ref:`Font` and :ref:`TextWriter` classes. This is reflected by an additional bool parameter ``small_caps`` in various of their methods.
------
**Changes in Version 1.18.14**
* **Finished** implementing new, "snake_cased" names for methods and properties, that were "camelCased" and awkward in many aspects. At the end of this documentation, there is section :ref:`Deprecated` with more background and a mapping of old to new names.
* **Fixed** issue `#1053 <https://github.com/pymupdf/PyMuPDF/issues/1053>`_. :meth:`Page.insert_image`: when given, include image mask in the hash computation.
* **Fixed** issue `#1043 <https://github.com/pymupdf/PyMuPDF/issues/1043>`_. Added ``Pixmap.getPNGdata`` to the aliases of :meth:`Pixmap.tobytes`.
* **Fixed** an internal error when computing the enveloping rectangle of drawn paths as returned by :meth:`Page.get_drawings`.
* **Fixed** an internal error occasionally causing loops when outputting text via :meth:`TextWriter.fill_textbox`.
* **Added** :meth:`Font.char_lengths`, which returns a tuple of character widths of a string.
* **Added** more ways to specify pages in :meth:`Document.delete_pages`. Now a sequence (list, tuple or range) can be specified, and the Python ``del`` statement can be used. In the latter case, Python ``slices`` are also accepted.
* **Changed** :meth:`Document.del_toc_item`, which disables a single item of the TOC: previously, the title text was removed. Instead, now the complete item will be shown grayed-out by supporting viewers.
------
**Changes in Version 1.18.13**
* **Fixed** issue `#1014 <https://github.com/pymupdf/PyMuPDF/issues/1014>`_.
* **Fixed** an internal memory leak when computing image bboxes -- :meth:`Page.get_image_bbox`.
* **Added** support for low-level access and modification of the PDF trailer. Applies to :meth:`Document.xref_get_keys`, :meth:`Document.xref_get_key`, and :meth:`Document.xref_set_key`.
* **Added** documentation for maintaining private entries in PDF metadata.
* **Added** documentation for handling transparent image insertions, :meth:`Page.insert_image`.
* **Added** :meth:`Page.get_image_rects`, an improved version of :meth:`Page.get_image_bbox`.
* **Changed** :meth:`Document.delete_pages` to support various ways of specifying pages to delete. Implements `#1042 <https://github.com/pymupdf/PyMuPDF/issues/1042>`_.
* **Changed** :meth:`Page.insert_image` to also accept the xref of an existing image in the file. This allows "copying" images between pages, and extremely fast multiple insertions.
* **Changed** :meth:`Page.insert_image` to also accept the integer parameter ``alpha``. To be used for performance improvements.
* **Changed** :meth:`Pixmap.set_alpha` to support new parameters for pre-multiplying colors with their alpha values and setting a specific color to fully transparent (e.g. white).
* **Changed** :meth:`Document.embfile_add` to automatically set creation and modification date-time. Correspondingly, :meth:`Document.embfile_upd` automatically maintains modification date-time (``/ModDate`` PDF key), and :meth:`Document.embfile_info` correspondingly reports these data. In addition, the embedded file's associated "collection item" is included via its :data:`xref`. This supports the development of PDF portfolio applications.
------
**Changes in Version 1.18.11 / 1.18.12**
* **Fixed** issue `#972 <https://github.com/pymupdf/PyMuPDF/issues/972>`_. Improved layout of source distribution material.
* **Fixed** issue `#962 <https://github.com/pymupdf/PyMuPDF/issues/962>`_. Stabilized Linux distribution detection for generating PyMuPDF from sources.
* **Added:** :meth:`Page.get_xobjects` delivers the result of :meth:`Document.get_page_xobjects`.
* **Added:** :meth:`Page.get_image_info` delivers meta information for all images shown on the page.
* **Added:** :meth:`Tools.mupdf_display_warnings` allows setting on / off the display of MuPDF-generated warnings. The default is off.
* **Added:** :meth:`Document.ez_save` convenience alias of :meth:`Document.save` with some different defaults.
* **Changed:** Image extractions of document pages now also contain the image's **transformation matrix**. This concerns :meth:`Page.get_image_bbox` and the DICT, JSON, RAWDICT, and RAWJSON variants of :meth:`Page.get_text`.
------
**Changes in Version 1.18.10**
* **Fixed** issue `#941 <https://github.com/pymupdf/PyMuPDF/issues/941>`_. Added old aliases for :meth:`DisplayList.get_pixmap` and :meth:`DisplayList.get_textpage`.
* **Fixed** issue `#929 <https://github.com/pymupdf/PyMuPDF/issues/929>`_. Stabilized removal of JavaScript objects with :meth:`Document.scrub`.
* **Fixed** issue `#927 <https://github.com/pymupdf/PyMuPDF/issues/927>`_. Removed a loop in the reworked :meth:`TextWriter.fill_textbox`.
* **Changed** :meth:`Document.xref_get_keys` and :meth:`Document.xref_get_key` to also allow accessing the PDF trailer dictionary. This can be done by using `-1` as the xref number argument.
* **Added** a number of functions for reconstructing the quads for text lines, spans and characters extracted by :meth:`Page.get_text` options "dict" and "rawdict". See :meth:`recover_quad` and friends.
* **Added** :meth:`Tools.unset_quad_corrections` to suppress character quad corrections (occasionally required for erroneous fonts).
------
**Changes in Version 1.18.9**
* **Fixed** issue `#888 <https://github.com/pymupdf/PyMuPDF/issues/888>`_. Removed ambiguous statements concerning PyMuPDF's license, which is now clearly stated to be GNU AGPL V3.
* **Fixed** issue `#895 <https://github.com/pymupdf/PyMuPDF/issues/895>`_.
* **Fixed** issue `#896 <https://github.com/pymupdf/PyMuPDF/issues/896>`_. Since v1.17.6 PyMuPDF suppresses the font subset tags and only reports the base fontname in text extraction outputs "dict" / "json" / "rawdict" / "rawjson". Now a new global parameter can request the old behaviour, :meth:`Tools.set_subset_fontnames`.
* **Fixed** issue `#885 <https://github.com/pymupdf/PyMuPDF/issues/885>`_. Pixmap creation now also works with filenames given as ``pathlib.Paths``.
* **Changed** :meth:`Document.subset_fonts`: Text is **not rewritten** any more and should therefore **retain all its original properties** -- like being hidden or being controlled by Optional Content mechanisms.
* **Changed** :ref:`TextWriter` output to also accept text in right to left mode (Arabian, Hebrew): :meth:`TextWriter.fill_textbox`, :meth:`TextWriter.append`. These methods now accept a new boolean parameter `right_to_left`, which is *False* by default. Implements `#897 <https://github.com/pymupdf/PyMuPDF/issues/897>`_.
* **Changed** :meth:`TextWriter.fill_textbox` to return all lines of text, that did not fit in the given rectangle. Also changed the default of the ``warn`` parameter to no longer print a warning message in overflow situations.
* **Added** a utility function :meth:`recover_quad`, which computes the quadrilateral of a span. This function can be used for correctly marking text extracted with the "dict" or "rawdict" options of :meth:`Page.get_text`.
------
**Changes in Version 1.18.8**
This is a bug fix version only. We are publishing early because of the potentially widely used functions.
* **Fixed** issue `#881 <https://github.com/pymupdf/PyMuPDF/issues/881>`_. Fixed a memory leak in :meth:`Page.insert_image` when inserting images from files or memory.
* **Fixed** issue `#878 <https://github.com/pymupdf/PyMuPDF/issues/878>`_. ``pathlib.Path`` objects should now correctly handle file path hierarchies.
------
**Changes in Version 1.18.7**
* **Added** an experimental :meth:`Document.subset_fonts` which reduces the size of eligible fonts based on their use by text in the PDF. Implements `#855 <https://github.com/pymupdf/PyMuPDF/discussions/855>`_.
* **Implemented** request `#870 <https://github.com/pymupdf/PyMuPDF/pull/870>`_: :meth:`Document.convert_to_pdf` now also supports PDF documents.
* **Renamed** ``Document.write`` to :meth:`Document.tobytes` for greater clarity. But the deprecated name remains available for some time.
* **Implemented** request `#843 <https://github.com/pymupdf/PyMuPDF/Discussions/843>`_: :meth:`Document.tobytes` now supports linearized PDF output. :meth:`Document.save` now also supports writing to Python **file objects**. In addition, the open function now also supports Python file objects.
* **Fixed** issue `#844 <https://github.com/pymupdf/PyMuPDF/issues/844>`_.
* **Fixed** issue `#838 <https://github.com/pymupdf/PyMuPDF/issues/838>`_.
* **Fixed** issue `#823 <https://github.com/pymupdf/PyMuPDF/issues/823>`_. More logic for better support of OCRed text output (Tesseract, ABBYY).
* **Fixed** issue `#818 <https://github.com/pymupdf/PyMuPDF/issues/818>`_.
* **Fixed** issue `#814 <https://github.com/pymupdf/PyMuPDF/issues/814>`_.
* **Added** :meth:`Document.get_page_labels` which returns a list of page label definitions of a PDF.
* **Added** :meth:`Document.has_annots` and :meth:`Document.has_links` to check whether these object types are present anywhere in a PDF.
* **Added** expert low-level functions to simplify inquiry and modification of PDF object sources: :meth:`Document.xref_get_keys` lists the keys of object :data:`xref`, :meth:`Document.xref_get_key` returns type and content of a key, and :meth:`Document.xref_set_key` modifies the key's value.
* **Added** parameter ``thumbnails`` to :meth:`Document.scrub` to also allow removing page thumbnail images.
* **Improved** documentation for how to add valid text marker annotations for non-horizontal text.
We continued the process of renaming methods and properties from *"mixedCase"* to *"snake_case"*. Documentation usually mentions the new names only, but old, deprecated names remain available for some time.
------
**Changes in Version 1.18.6**
* **Fixed** issue `#812 <https://github.com/pymupdf/PyMuPDF/issues/812>`_.
* **Fixed** issue `#793 <https://github.com/pymupdf/PyMuPDF/issues/793>`_. Invalid document metadata previously prevented opening some documents at all. This error has been removed.
* **Fixed** issue `#792 <https://github.com/pymupdf/PyMuPDF/issues/792>`_. Text search and text extraction will make no rectangle containment checks at all if the default ``clip=None`` is used.
* **Fixed** issue `#785 <https://github.com/pymupdf/PyMuPDF/issues/785>`_.
* **Fixed** issue `#780 <https://github.com/pymupdf/PyMuPDF/issues/780>`_. Corrected a parameter check error.
* **Fixed** issue `#779 <https://github.com/pymupdf/PyMuPDF/issues/779>`_. Fixed typo
* **Added** an option to set the desired line height for text boxes. Implements `#804 <https://github.com/pymupdf/PyMuPDF/issues/804>`_.
* **Changed** text position retrieval to better cope with Tesseract's glyphless font. Implements `#803 <https://github.com/pymupdf/PyMuPDF/issues/803>`_.
* **Added** an option to choose the prefix of new annotations, fields and links for providing unique annotation ids. Implements request `#807 <https://github.com/pymupdf/PyMuPDF/issues/807>`_.
* **Added** getting and setting color and text properties for Table of Contents items for PDFs. Implements `#779 <https://github.com/pymupdf/PyMuPDF/issues/779>`_.
* **Added** PDF page label handling: :meth:`Page.get_label()` returns the page label, :meth:`Document.get_page_numbers` return all page numbers having a specified label, and :meth:`Document.set_page_labels` adds or updates a PDF's page label definition.
.. note::
This version introduces **Python type hinting**. The goal is to provide each parameter and the return value of all functions and methods with type information. This still is work in progress although the majority of functions has already been handled.
------
**Changes in Version 1.18.5**
Apart from several fixes, this version also focusses on several minor, but important feature improvements. Among the latter is a more precise computation of proper line heights and insertion points for writing / inserting text. As opposed to using font-agnostic constants, these values are now taken from the font's properties.
Also note that this is the first version which does no longer provide pregenerated wheels for Python versions older than 3.6. PIP also discontinues support for these by end of this year 2020.
* **Fixed** issue `#771 <https://github.com/pymupdf/PyMuPDF/issues/771>`_. By using "small glyph heights" option, the full page text can be extracted.
* **Fixed** issue `#768 <https://github.com/pymupdf/PyMuPDF/issues/768>`_.
* **Fixed** issue `#750 <https://github.com/pymupdf/PyMuPDF/issues/750>`_.
* **Fixed** issue `#739 <https://github.com/pymupdf/PyMuPDF/issues/739>`_. The "dict", "rawdict" and corresponding JSON output variants now have two new *span* keys: ``"ascender"`` and ``"descender"``. These floats represent special font properties which can be used to compute bboxes of spans or characters of **exactly fontsize height** (as opposed to the default line height). An example algorithm is shown in section "Span Dictionary" `here <https://pymupdf.readthedocs.io/en/latest/textpage.html#dictionary-structure-of-extractdict-and-extractrawdict>`_. Also improved the detection and correction of ill-specified ascender / descender values encountered in some fonts.
* **Added** a new, experimental :meth:`Tools.set_small_glyph_heights` -- also in response to issue `#739 <https://github.com/pymupdf/PyMuPDF/issues/739>`_. This method sets or unsets a global parameter to **always compute bboxes with fontsize height**. If "on", text searching and all text extractions will returned rectangles, bboxes and quads with a smaller height.
* **Fixed** issue `#728 <https://github.com/pymupdf/PyMuPDF/issues/728>`_.
* **Changed** fill color logic of 'Polyline' annotations: this parameter now only pertains to line end symbols -- the annotation itself can no longer have a fill color. Also addresses issue `#727 <https://github.com/pymupdf/PyMuPDF/issues/727>`_.
* **Changed** :meth:`Page.getImageBbox` to also compute the bbox if the image is contained in an XObject.
* **Changed** :meth:`Shape.insertTextbox`, resp. :meth:`Page.insertTextbox`, resp. :meth:`TextWriter.fillTextbox` to respect font's properties "ascender" / "descender" when computing line height and insertion point. This should no longer lead to line overlaps for multi-line output. These methods used to ignore font specifics and used constant values instead.
------
**Changes in Version 1.18.4**
This version adds several features to support PDF Optional Content. Among other things, this includes OCMDs (Optional Content Membership Dictionaries) with the full scope of *"visibility expressions"* (PDF key ``/VE``), text insertions (including the :ref:`TextWriter` class) and drawings.
* **Fixed** issue `#727 <https://github.com/pymupdf/PyMuPDF/issues/727>`_. Freetext annotations now support an uncolored rectangle when ``fill_color=None``.
* **Fixed** issue `#726 <https://github.com/pymupdf/PyMuPDF/issues/726>`_. UTF-8 encoding errors are now handled for HTML / XML :meth:`Page.getText` output.
* **Fixed** issue `#724 <https://github.com/pymupdf/PyMuPDF/issues/724>`_. Empty values are no longer stored in the PDF /Info metadata dictionary.
* **Added** new methods :meth:`Document.set_oc` and :meth:`Document.get_oc` to set or get optional content references for **existing** image and form XObjects. These methods are similar to the same-named methods of :ref:`Annot`.
* **Added** :meth:`Document.set_ocmd`, :meth:`Document.get_ocmd` for handling OCMDs.
* **Added** **Optional Content** support for text insertion and drawing.
* **Added** new method :meth:`Page.deleteWidget`, which deletes a form field from a page. This is analogous to deleting annotations.
* **Added** support for Popup annotations. This includes defining the Popup rectangle and setting the Popup to open or closed. Methods / attributes :meth:`Annot.set_popup`, :meth:`Annot.set_open`, :attr:`Annot.has_popup`, :attr:`Annot.is_open`, :attr:`Annot.popup_rect`, :attr:`Annot.popup_xref`.
Other changes:
* The **naming of methods and attributes** in PyMuPDF is far from being satisfactory: we have *CamelCases*, *mixedCases* and *lower_case_with_underscores* all over the place. With the :ref:`Annot` as the first candidate, we have started an activity to clean this up step by step, converting to lower case with underscores for methods and attributes while keeping UPPERCASE for the constants.
- Old names will remain available to prevent code breaks, but they will no longer be mentioned in the documentation.
- New methods and attributes of all classes will be named according to the new standard.
------
**Changes in Version 1.18.3**
As a major new feature, this version introduces support for PDF's **Optional Content** concept.
* **Fixed** issue `#714 <https://github.com/pymupdf/PyMuPDF/issues/714>`_.
* **Fixed** issue `#711 <https://github.com/pymupdf/PyMuPDF/issues/711>`_.
* **Fixed** issue `#707 <https://github.com/pymupdf/PyMuPDF/issues/707>`_: if a PDF user password, but no owner password is supplied nor present, then the user password is also used as the owner password.
* **Fixed** ``expand`` and ``deflate`` parameters of methods :meth:`Document.save` and :meth:`Document.write`. Individual image and font compression should now finally work. Addresses issue `#713 <https://github.com/pymupdf/PyMuPDF/issues/713>`_.
* **Added** a support of PDF optional content. This includes several new :ref:`Document` methods for inquiring and setting optional content status and adding optional content configurations and groups. In addition, images, form XObjects and annotations now can be bound to optional content specifications. **Resolved** issue `#709 <https://github.com/pymupdf/PyMuPDF/issues/709>`_.
------
**Changes in Version 1.18.2**
This version contains some interesting improvements for text searching: any number of search hits is now returned and the **hit_max** parameter was removed. The new **clip** parameter in addition allows to restrict the search area. Searching now detects hyphenations at line breaks and accordingly finds hyphenated words.
* **Fixed** issue `#575 <https://github.com/pymupdf/PyMuPDF/issues/575>`_: if using ``quads=False`` in text searching, then overlapping rectangles on the same line are joined. Previously, parts of the search string, which belonged to different "marked content" items, each generated their own rectangle -- just as if occurring on separate lines.
* **Added** :attr:`Document.isRepaired`, which is true if the PDF was repaired on open.
* **Added** :meth:`Document.setXmlMetadata` which either updates or creates PDF XML metadata. Implements issue `#691 <https://github.com/pymupdf/PyMuPDF/issues/691>`_.
* **Added** :meth:`Document.getXmlMetadata` returns PDF XML metadata.
* **Changed** creation of PDF documents: they will now always carry a PDF identification (``/ID`` field) in the document trailer. Implements issue `#691 <https://github.com/pymupdf/PyMuPDF/issues/691>`_.
* **Changed** :meth:`Page.searchFor`: a new parameter ``clip`` is accepted to restrict the search to this rectangle. Correspondingly, the attribute :attr:`TextPage.rect` is now respected by :meth:`TextPage.search`.
* **Changed** parameter ``hit_max`` in :meth:`Page.searchFor` and :meth:`TextPage.search` is now obsolete: methods will return all hits.
* **Changed** character **selection criteria** in :meth:`Page.getText`: a character is now considered to be part of a ``clip`` if its bbox is fully contained. Before this, a non-empty intersection was sufficient.
* **Changed** :meth:`Document.scrub` to support a new option `redact_images`. This addresses issue `#697 <https://github.com/pymupdf/PyMuPDF/issues/697>`_.
------
**Changes in Version 1.18.1**
* **Fixed** issue `#692 <https://github.com/pymupdf/PyMuPDF/issues/692>`_. PyMuPDF now detects and recovers from more cyclic resource dependencies in PDF pages and for the first time reports them in the MuPDF warnings store.
* **Fixed** issue `#686 <https://github.com/pymupdf/PyMuPDF/issues/686>`_.
* **Added** opacity options for the :ref:`Shape` class: Stroke and fill colors can now be set to some transparency value. This means that all :ref:`Page` draw methods, methods :meth:`Page.insertText`, :meth:`Page.insertTextbox`, :meth:`Shape.finish`, :meth:`Shape.insertText`, and :meth:`Shape.insertTextbox` support two new parameters: *stroke_opacity* and *fill_opacity*.
* **Added** new parameter ``mask`` to :meth:`Page.insertImage` for optionally providing an external image mask. Resolves issue `#685 <https://github.com/pymupdf/PyMuPDF/issues/685>`_.
* **Added** :meth:`Annot.soundGet` for extracting the sound of an audio annotation.
------
**Changes in Version 1.18.0**
This is the first PyMuPDF version supporting MuPDF v1.18. The focus here is on extending PyMuPDF's own functionality -- apart from bug fixing. Subsequent PyMuPDF patches may address features new in MuPDF.
* **Fixed** issue `#519 <https://github.com/pymupdf/PyMuPDF/issues/519>`_. This upstream bug occurred occasionally for some pages only and seems to be fixed now: page layout should no longer be ruined in these cases.
* **Fixed** issue `#675 <https://github.com/pymupdf/PyMuPDF/issues/675>`_.
- Unsuccessful storage allocations should now always lead to exceptions (circumvention of an upstream bug intermittently crashing the interpreter).
- :ref:`Pixmap` size is now based on ``size_t`` instead of ``int`` in C and should be correct even for extremely large pixmaps.
* **Fixed** issue `#668 <https://github.com/pymupdf/PyMuPDF/issues/668>`_. Specification of dashes for PDF drawing insertion should now correctly reflect the PDF spec.
* **Fixed** issue `#669 <https://github.com/pymupdf/PyMuPDF/issues/669>`_. A major source of memory leakage in :meth:`Page.insert_pdf` has been removed.
* **Added** keyword *"images"* to :meth:`Page.apply_redactions` for fine-controlling the handling of images.
* **Added** :meth:`Annot.getText` and :meth:`Annot.getTextbox`, which offer the same functionality as the :ref:`Page` versions.
* **Added** key *"number"* to the block dictionaries of :meth:`Page.getText` / :meth:`Annot.getText` for options "dict" and "rawdict".
* **Added** :meth:`glyph_name_to_unicode` and :meth:`unicode_to_glyph_name`. Both functions do not really connect to a specific font and are now independently available, too. The data are now based on the `Adobe Glyph List <https://github.com/adobe-type-tools/agl-aglfn/blob/master/glyphlist.txt>`_.
* **Added** convenience functions :meth:`adobe_glyph_names` and :meth:`adobe_glyph_unicodes` which return the respective available data.
* **Added** :meth:`Page.getDrawings` which returns details of drawing operations on a document page. Works for all document types.
* Improved performance of :meth:`Document.insert_pdf`. Multiple object copies are now also suppressed across multiple separate insertions from the same source. This saves time, memory and target file size. Previously this mechanism was only active within each single method execution. The feature can also be suppressed with the new method bool parameter *final=1*, which is the default.
* For PNG images created from pixmaps, the resolution (dpi) is now automatically set from the respective :attr:`Pixmap.xres` and :attr:`Pixmap.yres` values.
------
**Changes in Version 1.17.7**
* **Fixed** issue `#651 <https://github.com/pymupdf/PyMuPDF/issues/651>`_. An upstream bug causing interpreter crashes in corner case redaction processings was fixed by backporting MuPDF changes from their development repo.
* **Fixed** issue `#645 <https://github.com/pymupdf/PyMuPDF/issues/645>`_. Pixmap top-left coordinates can be set (again) by their own method, :meth:`Pixmap.set_origin`.
* **Fixed** issue `#622 <https://github.com/pymupdf/PyMuPDF/issues/622>`_. :meth:`Page.insertImage` again accepts a :data:`rect_like` parameter.
* **Added** several new methods to improve and speed-up table of contents (TOC) handling. Among other things, TOC items can now changed or deleted individually -- without always replacing the complete TOC. Furthermore, access to some PDF page attributes is now possible without first **loading** the page. This has a very significant impact on the performance of TOC manipulation.
* **Added** an option to :meth:`Document.insert_pdf` which allows displaying progress messages. Addresses `#640 <https://github.com/pymupdf/PyMuPDF/issues/640>`_.
* **Added** :meth:`Page.getTextbox` which extracts text contained in a rectangle. In many cases, this should obsolete writing your own script for this type of thing.
* **Added** new ``clip`` parameter to :meth:`Page.getText` to simplify and speed up text extraction of page sub areas.
* **Added** :meth:`TextWriter.appendv` to add text in **vertical write mode**. Addresses issue `#653 <https://github.com/pymupdf/PyMuPDF/issues/653>`_
------
**Changes in Version 1.17.6**
* **Fixed** issue `#605 <https://github.com/pymupdf/PyMuPDF/issues/605>`_
* **Fixed** issue `#600 <https://github.com/pymupdf/PyMuPDF/issues/600>`_ -- text should now be correctly positioned also for pages with a CropBox smaller than MediaBox.
* **Added** text span dictionary key ``origin`` which contains the lower left coordinate of the first character in that span.
* **Added** attribute :attr:`Font.buffer`, a *bytes* copy of the font file.
* **Added** parameter *sanitize* to :meth:`Page.cleanContents`. Allows switching of sanitization, so only syntax cleaning will be done.
------
**Changes in Version 1.17.5**
* **Fixed** issue `#561 <https://github.com/pymupdf/PyMuPDF/issues/561>`_ -- second go: certain :ref:`TextWriter` usages with many alternating fonts did not work correctly.
* **Fixed** issue `#566 <https://github.com/pymupdf/PyMuPDF/issues/566>`_.
* **Fixed** issue `#568 <https://github.com/pymupdf/PyMuPDF/issues/568>`_.
* **Fixed** -- opacity is now correctly taken from the :ref:`TextWriter` object, if not given in :meth:`TextWriter.writeText`.
* **Added** a new global attribute :attr:`fitz_fontdescriptors`. Contains information about usable fonts from repository `pymupdf-fonts <https://github.com/pymupdf/pymupdf-fonts>`_.
* **Added** :meth:`Font.valid_codepoints` which returns an array of unicode codepoints for which the font has a glyph.
* **Added** option ``text_as_path`` to :meth:`Page.getSVGimage`. this implements `#580 <https://github.com/pymupdf/PyMuPDF/issues/580>`_. Generates much smaller SVG files with parseable text if set to *False*.
------
**Changes in Version 1.17.4**
* **Fixed** issue `#561 <https://github.com/pymupdf/PyMuPDF/issues/561>`_. Handling of more than 10 :ref:`Font` objects on one page should now work correctly.
* **Fixed** issue `#562 <https://github.com/pymupdf/PyMuPDF/issues/562>`_. Annotation pixmaps are no longer derived from the page pixmap, thus avoiding unintended inclusion of page content.
* **Fixed** issue `#559 <https://github.com/pymupdf/PyMuPDF/issues/559>`_. This **MuPDF** bug is being temporarily fixed with a pre-version of MuPDF's next release.
* **Added** utility function :meth:`repair_mono_font` for correcting displayed character spacing for some mono-spaced fonts.
* **Added** utility method :meth:`Document.need_appearances` for fine-controlling Form PDF behavior. Addresses issue `#563 <https://github.com/pymupdf/PyMuPDF/issues/563>`_.
* **Added** utility function :meth:`sRGB_to_pdf` to recover the PDF color triple for a given color integer in sRGB format.
* **Added** utility function :meth:`sRGB_to_rgb` to recover the (R, G, B) color triple for a given color integer in sRGB format.
* **Added** utility function :meth:`make_table` which delivers table cells for a given rectangle and desired numbers of columns and rows.
* **Added** support for optional fonts in repository `pymupdf-fonts <https://github.com/pymupdf/pymupdf-fonts>`_.
------
**Changes in Version 1.17.3**
* **Fixed** an undocumented issue, which prevented fully cleaning a PDF page when using :meth:`Page.cleanContents`.
* **Fixed** issue `#540 <https://github.com/pymupdf/PyMuPDF/issues/540>`_. Text extraction for EPUB should again work correctly.
* **Fixed** issue `#548 <https://github.com/pymupdf/PyMuPDF/issues/548>`_. Documentation now includes ``LINK_NAMED``.
* **Added** new parameter to control start of text in :meth:`TextWriter.fillTextbox`. Implements `#549 <https://github.com/pymupdf/PyMuPDF/issues/549>`_.
* **Changed** documentation of :meth:`Page.add_redact_annot` to explain the usage of non-builtin fonts.
------
**Changes in Version 1.17.2**
* **Fixed** issue `#533 <https://github.com/pymupdf/PyMuPDF/issues/533>`_.
* **Added** options to modify 'Redact' annotation appearance. Implements `#535 <https://github.com/pymupdf/PyMuPDF/issues/535>`_.
------
**Changes in Version 1.17.1**
* **Fixed** issue `#520 <https://github.com/pymupdf/PyMuPDF/issues/520>`_.
* **Fixed** issue `#525 <https://github.com/pymupdf/PyMuPDF/issues/525>`_. Vertices for 'Ink' annots should now be correct.
* **Fixed** issue `#524 <https://github.com/pymupdf/PyMuPDF/issues/524>`_. It is now possible to query and set rotation for applicable annotation types.
Also significantly improved inline documentation for better support of interactive help.
------
**Changes in Version 1.17.0**
This version is based on MuPDF v1.17. Following are highlights of new and changed features:
* **Added** extended language support for annotations and widgets: a mixture of Latin, Greece, Russian, Chinese, Japanese and Korean characters can now be used in 'FreeText' annotations and text widgets. No special arrangement is required to use it.
* Faster page access is implemented for documents supporting a "chapter" structure. This applies to EPUB documents currently. This comes with several new :ref:`Document` methods and changes for :meth:`Document.loadPage` and the "indexed" page access *doc[n]*: In addition to specifying a page number as before, a tuple
gitextract_dv05yjlp/ ├── .gitattributes ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.yml │ │ └── feature_request.md │ └── workflows/ │ ├── build_wheels.yml │ ├── cla.yml │ ├── test-valgrind.yml │ ├── test.yml │ ├── test_multiple.yml │ ├── test_pyodide.yml │ ├── test_quick.yml │ └── test_sysinstall.yml ├── .gitignore ├── .python-version ├── .readthedocs.yaml ├── .vs/ │ ├── ProjectSettings.json │ ├── PyMuPDF/ │ │ └── v15/ │ │ └── .suo │ └── VSWorkspaceState.json ├── COPYING ├── README.md ├── READMEb.md ├── READMEd.md ├── changes.txt ├── docs/ │ ├── 404.rst │ ├── README.md │ ├── _static/ │ │ ├── custom.css │ │ └── prism/ │ │ ├── prism.css │ │ ├── prism.html │ │ └── prism.js │ ├── about-feature-matrix.rst │ ├── about-performance.rst │ ├── about.rst │ ├── algebra.rst │ ├── annot.rst │ ├── app1.rst │ ├── app2.rst │ ├── app3.rst │ ├── app4.rst │ ├── archive-class.rst │ ├── changes.rst │ ├── classes.rst │ ├── colors.rst │ ├── colorspace.rst │ ├── conf.py │ ├── converting-files.rst │ ├── coop_low.rst │ ├── device.rst │ ├── displaylist.rst │ ├── document-writer-class.rst │ ├── document.rst │ ├── extensions/ │ │ ├── __init__.py │ │ ├── fulltoc.py │ │ └── searchrepair.py │ ├── faq/ │ │ └── index.rst │ ├── faq.rst │ ├── font.rst │ ├── footer.rst │ ├── functions.rst │ ├── glossary.rst │ ├── header-404.rst │ ├── header.rst │ ├── how-to-open-a-file.rst │ ├── identity.rst │ ├── index.rst │ ├── installation.rst │ ├── irect.rst │ ├── link.rst │ ├── linkdest.rst │ ├── locales/ │ │ ├── ja/ │ │ │ ├── .readthedocs.yaml │ │ │ └── LC_MESSAGES/ │ │ │ ├── 404.mo │ │ │ ├── 404.po │ │ │ ├── about-feature-matrix.mo │ │ │ ├── about-feature-matrix.po │ │ │ ├── about-performance.mo │ │ │ ├── about-performance.po │ │ │ ├── about.mo │ │ │ ├── about.po │ │ │ ├── algebra.mo │ │ │ ├── algebra.po │ │ │ ├── annot.mo │ │ │ ├── annot.po │ │ │ ├── app1.mo │ │ │ ├── app1.po │ │ │ ├── app2.mo │ │ │ ├── app2.po │ │ │ ├── app3.mo │ │ │ ├── app3.po │ │ │ ├── app4.mo │ │ │ ├── app4.po │ │ │ ├── archive-class.mo │ │ │ ├── archive-class.po │ │ │ ├── changes.mo │ │ │ ├── changes.po │ │ │ ├── classes.mo │ │ │ ├── classes.po │ │ │ ├── colors.mo │ │ │ ├── colors.po │ │ │ ├── colorspace.mo │ │ │ ├── colorspace.po │ │ │ ├── converting-files.mo │ │ │ ├── converting-files.po │ │ │ ├── coop_low.mo │ │ │ ├── coop_low.po │ │ │ ├── deprecated.mo │ │ │ ├── deprecated.po │ │ │ ├── device.mo │ │ │ ├── device.po │ │ │ ├── displaylist.mo │ │ │ ├── displaylist.po │ │ │ ├── document-writer-class.mo │ │ │ ├── document-writer-class.po │ │ │ ├── document.mo │ │ │ ├── document.po │ │ │ ├── faq.mo │ │ │ ├── faq.po │ │ │ ├── font.mo │ │ │ ├── font.po │ │ │ ├── footer.mo │ │ │ ├── footer.po │ │ │ ├── functions.mo │ │ │ ├── functions.po │ │ │ ├── glossary.mo │ │ │ ├── glossary.po │ │ │ ├── header-404.mo │ │ │ ├── header-404.po │ │ │ ├── header.mo │ │ │ ├── header.po │ │ │ ├── how-to-open-a-file.mo │ │ │ ├── how-to-open-a-file.po │ │ │ ├── identity.mo │ │ │ ├── identity.po │ │ │ ├── index.mo │ │ │ ├── index.po │ │ │ ├── installation.mo │ │ │ ├── installation.po │ │ │ ├── intro.mo │ │ │ ├── intro.po │ │ │ ├── irect.mo │ │ │ ├── irect.po │ │ │ ├── link.mo │ │ │ ├── link.po │ │ │ ├── linkdest.mo │ │ │ ├── linkdest.po │ │ │ ├── lowlevel.mo │ │ │ ├── lowlevel.po │ │ │ ├── matrix.mo │ │ │ ├── matrix.po │ │ │ ├── module.mo │ │ │ ├── module.po │ │ │ ├── outline.mo │ │ │ ├── outline.po │ │ │ ├── packaging.mo │ │ │ ├── packaging.po │ │ │ ├── page.mo │ │ │ ├── page.po │ │ │ ├── pixmap.mo │ │ │ ├── pixmap.po │ │ │ ├── point.mo │ │ │ ├── point.po │ │ │ ├── pymupdf-layout/ │ │ │ │ ├── index.mo │ │ │ │ └── index.po │ │ │ ├── pymupdf-pro/ │ │ │ │ ├── index.mo │ │ │ │ └── index.po │ │ │ ├── pymupdf-pro.mo │ │ │ ├── pymupdf-pro.po │ │ │ ├── pymupdf4llm/ │ │ │ │ ├── api.mo │ │ │ │ ├── api.po │ │ │ │ ├── index.mo │ │ │ │ └── index.po │ │ │ ├── pyodide.mo │ │ │ ├── pyodide.po │ │ │ ├── quad.mo │ │ │ ├── quad.po │ │ │ ├── rag.mo │ │ │ ├── rag.po │ │ │ ├── recipes-annotations.mo │ │ │ ├── recipes-annotations.po │ │ │ ├── recipes-common-issues-and-their-solutions.mo │ │ │ ├── recipes-common-issues-and-their-solutions.po │ │ │ ├── recipes-drawing-and-graphics.mo │ │ │ ├── recipes-drawing-and-graphics.po │ │ │ ├── recipes-images.mo │ │ │ ├── recipes-images.po │ │ │ ├── recipes-journalling.mo │ │ │ ├── recipes-journalling.po │ │ │ ├── recipes-low-level-interfaces.mo │ │ │ ├── recipes-low-level-interfaces.po │ │ │ ├── recipes-multiprocessing.mo │ │ │ ├── recipes-multiprocessing.po │ │ │ ├── recipes-ocr.mo │ │ │ ├── recipes-ocr.po │ │ │ ├── recipes-optional-content.mo │ │ │ ├── recipes-optional-content.po │ │ │ ├── recipes-stories.mo │ │ │ ├── recipes-stories.po │ │ │ ├── recipes-text.mo │ │ │ ├── recipes-text.po │ │ │ ├── recipes.mo │ │ │ ├── recipes.po │ │ │ ├── rect.mo │ │ │ ├── rect.po │ │ │ ├── resources.mo │ │ │ ├── resources.po │ │ │ ├── shape.mo │ │ │ ├── shape.po │ │ │ ├── story-class.mo │ │ │ ├── story-class.po │ │ │ ├── supported-files-table.mo │ │ │ ├── supported-files-table.po │ │ │ ├── textpage.mo │ │ │ ├── textpage.po │ │ │ ├── textwriter.mo │ │ │ ├── textwriter.po │ │ │ ├── the-basics.mo │ │ │ ├── the-basics.po │ │ │ ├── tools.mo │ │ │ ├── tools.po │ │ │ ├── tutorial.mo │ │ │ ├── tutorial.po │ │ │ ├── vars.mo │ │ │ ├── vars.po │ │ │ ├── version.mo │ │ │ ├── version.po │ │ │ ├── widget.mo │ │ │ ├── widget.po │ │ │ ├── xml-class.mo │ │ │ ├── xml-class.po │ │ │ ├── znames.mo │ │ │ └── znames.po │ │ └── ko/ │ │ ├── .readthedocs.yaml │ │ └── LC_MESSAGES/ │ │ ├── 404.mo │ │ ├── 404.po │ │ ├── about-feature-matrix.mo │ │ ├── about-feature-matrix.po │ │ ├── about-performance.mo │ │ ├── about-performance.po │ │ ├── about.mo │ │ ├── about.po │ │ ├── algebra.mo │ │ ├── algebra.po │ │ ├── annot.mo │ │ ├── annot.po │ │ ├── app1.mo │ │ ├── app1.po │ │ ├── app2.mo │ │ ├── app2.po │ │ ├── app3.mo │ │ ├── app3.po │ │ ├── app4.mo │ │ ├── app4.po │ │ ├── archive-class.mo │ │ ├── archive-class.po │ │ ├── changes.mo │ │ ├── changes.po │ │ ├── classes.mo │ │ ├── classes.po │ │ ├── colors.mo │ │ ├── colors.po │ │ ├── colorspace.mo │ │ ├── colorspace.po │ │ ├── converting-files.mo │ │ ├── converting-files.po │ │ ├── coop_low.mo │ │ ├── coop_low.po │ │ ├── device.mo │ │ ├── device.po │ │ ├── displaylist.mo │ │ ├── displaylist.po │ │ ├── document-writer-class.mo │ │ ├── document-writer-class.po │ │ ├── document.mo │ │ ├── document.po │ │ ├── faq.mo │ │ ├── faq.po │ │ ├── font.mo │ │ ├── font.po │ │ ├── footer.mo │ │ ├── footer.po │ │ ├── functions.mo │ │ ├── functions.po │ │ ├── glossary.mo │ │ ├── glossary.po │ │ ├── header-404.mo │ │ ├── header-404.po │ │ ├── header.mo │ │ ├── header.po │ │ ├── how-to-open-a-file.mo │ │ ├── how-to-open-a-file.po │ │ ├── identity.mo │ │ ├── identity.po │ │ ├── index.mo │ │ ├── index.po │ │ ├── installation.mo │ │ ├── installation.po │ │ ├── irect.mo │ │ ├── irect.po │ │ ├── link.mo │ │ ├── link.po │ │ ├── linkdest.mo │ │ ├── linkdest.po │ │ ├── lowlevel.mo │ │ ├── lowlevel.po │ │ ├── matrix.mo │ │ ├── matrix.po │ │ ├── module.mo │ │ ├── module.po │ │ ├── outline.mo │ │ ├── outline.po │ │ ├── packaging.mo │ │ ├── packaging.po │ │ ├── page.mo │ │ ├── page.po │ │ ├── pixmap.mo │ │ ├── pixmap.po │ │ ├── point.mo │ │ ├── point.po │ │ ├── pymupdf-layout/ │ │ │ ├── index.mo │ │ │ └── index.po │ │ ├── pymupdf-pro/ │ │ │ ├── index.mo │ │ │ └── index.po │ │ ├── pymupdf4llm/ │ │ │ ├── api.mo │ │ │ ├── api.po │ │ │ ├── index.mo │ │ │ └── index.po │ │ ├── pyodide.mo │ │ ├── pyodide.po │ │ ├── quad.mo │ │ ├── quad.po │ │ ├── rag.mo │ │ ├── rag.po │ │ ├── recipes-annotations.mo │ │ ├── recipes-annotations.po │ │ ├── recipes-common-issues-and-their-solutions.mo │ │ ├── recipes-common-issues-and-their-solutions.po │ │ ├── recipes-drawing-and-graphics.mo │ │ ├── recipes-drawing-and-graphics.po │ │ ├── recipes-images.mo │ │ ├── recipes-images.po │ │ ├── recipes-journalling.mo │ │ ├── recipes-journalling.po │ │ ├── recipes-low-level-interfaces.mo │ │ ├── recipes-low-level-interfaces.po │ │ ├── recipes-multiprocessing.mo │ │ ├── recipes-multiprocessing.po │ │ ├── recipes-ocr.mo │ │ ├── recipes-ocr.po │ │ ├── recipes-optional-content.mo │ │ ├── recipes-optional-content.po │ │ ├── recipes-stories.mo │ │ ├── recipes-stories.po │ │ ├── recipes-text.mo │ │ ├── recipes-text.po │ │ ├── recipes.mo │ │ ├── recipes.po │ │ ├── rect.mo │ │ ├── rect.po │ │ ├── resources.mo │ │ ├── resources.po │ │ ├── shape.mo │ │ ├── shape.po │ │ ├── story-class.mo │ │ ├── story-class.po │ │ ├── supported-files-table.mo │ │ ├── supported-files-table.po │ │ ├── textpage.mo │ │ ├── textpage.po │ │ ├── textwriter.mo │ │ ├── textwriter.po │ │ ├── the-basics.mo │ │ ├── the-basics.po │ │ ├── tools.mo │ │ ├── tools.po │ │ ├── tutorial.mo │ │ ├── tutorial.po │ │ ├── vars.mo │ │ ├── vars.po │ │ ├── version.mo │ │ ├── version.po │ │ ├── widget.mo │ │ ├── widget.po │ │ ├── xml-class.mo │ │ ├── xml-class.po │ │ ├── znames.mo │ │ └── znames.po │ ├── lowlevel.rst │ ├── matrix.rst │ ├── module.rst │ ├── ocr/ │ │ └── tesseract-language-packs.rst │ ├── outline.rst │ ├── packaging.rst │ ├── page.rst │ ├── pixmap.rst │ ├── point.rst │ ├── pymupdf-pro/ │ │ └── index.rst │ ├── pymupdf4llm/ │ │ ├── api.rst │ │ ├── index.rst │ │ └── ocr-plugins.rst │ ├── pyodide.rst │ ├── quad.rst │ ├── rag.rst │ ├── recipes-annotations.rst │ ├── recipes-common-issues-and-their-solutions.rst │ ├── recipes-drawing-and-graphics.rst │ ├── recipes-images.rst │ ├── recipes-journalling.rst │ ├── recipes-low-level-interfaces.rst │ ├── recipes-multiprocessing.rst │ ├── recipes-ocr.rst │ ├── recipes-optional-content.rst │ ├── recipes-stories.rst │ ├── recipes-text.rst │ ├── recipes.rst │ ├── rect.rst │ ├── requirements.txt │ ├── resources.rst │ ├── samples/ │ │ ├── annotations-freetext1.py │ │ ├── annotations-freetext2.py │ │ ├── annotations-ink.py │ │ ├── code-printer.py │ │ ├── filmfestival-sql.py │ │ ├── json-example.py │ │ ├── multiprocess-gui.py │ │ ├── multiprocess-render.py │ │ ├── national-capitals.py │ │ ├── new-annots.py │ │ ├── quickfox-image-no-go.py │ │ ├── quickfox.py │ │ ├── showpdf-page.py │ │ ├── simple-grid.py │ │ ├── story-write-stabilized-links.py │ │ ├── story-write-stabilized.py │ │ ├── story-write.py │ │ ├── table01.py │ │ └── text-lister.py │ ├── shape.rst │ ├── story-class.rst │ ├── supported-files-table.rst │ ├── textpage.rst │ ├── textwriter.rst │ ├── the-basics.rst │ ├── tools.rst │ ├── tutorial.rst │ ├── vars.rst │ ├── version.rst │ ├── widget.rst │ ├── xml-class.rst │ └── znames.rst ├── pyproject.toml ├── pytest.ini ├── scripts/ │ ├── gh_release.py │ ├── sysinstall.py │ └── test.py ├── setup.py ├── src/ │ ├── __init__.py │ ├── __main__.py │ ├── _apply_pages.py │ ├── _wxcolors.py │ ├── extra.i │ ├── fitz___init__.py │ ├── fitz_table.py │ ├── fitz_utils.py │ ├── pipcl.py │ ├── pymupdf.py │ ├── table.py │ ├── utils.py │ └── wdev.py ├── src_classic/ │ ├── __init__.py │ ├── __main__.py │ ├── _config.h │ ├── fitz_old.i │ ├── helper-annot.i │ ├── helper-convert.i │ ├── helper-defines.i │ ├── helper-devices.i │ ├── helper-fields.i │ ├── helper-fileobj.i │ ├── helper-geo-c.i │ ├── helper-geo-py.i │ ├── helper-globals.i │ ├── helper-other.i │ ├── helper-pdfinfo.i │ ├── helper-pixmap.i │ ├── helper-portfolio.i │ ├── helper-python.i │ ├── helper-select.i │ ├── helper-stext.i │ ├── helper-xobject.i │ ├── utils.py │ └── version.i ├── tests/ │ ├── README.md │ ├── conftest.py │ ├── gentle_compare.py │ ├── resources/ │ │ ├── Bezier.epub │ │ ├── PragmaticaC.otf │ │ ├── chinese-tables.pickle │ │ ├── cython.pickle │ │ ├── full_toc.txt │ │ ├── metadata.txt │ │ ├── simple_toc.txt │ │ ├── symbols.txt │ │ ├── test_2608_expected │ │ ├── test_2608_expected_1.26 │ │ ├── test_2608_expected_1.28 │ │ ├── test_3493.epub │ │ ├── test_3615.epub │ │ ├── test_3654.docx │ │ ├── test_3687-3.epub │ │ ├── test_3687.epub │ │ ├── test_3842_expected_1.28.txt │ │ ├── test_3842_partial.txt │ │ ├── test_4496.hwpx │ │ ├── test_open2.cbz │ │ ├── test_open2.doc │ │ ├── test_open2.docx │ │ ├── test_open2.epub │ │ ├── test_open2.fb2 │ │ ├── test_open2.html │ │ ├── test_open2.mobi │ │ ├── test_open2.xhtml │ │ ├── test_open2.xml │ │ ├── test_open2.xps │ │ └── test_open2_expected.json │ ├── run_compound.py │ ├── test_2548.py │ ├── test_2634.py │ ├── test_2904.py │ ├── test_2907.py │ ├── test_4141.py │ ├── test_4503.py │ ├── test_4505.py │ ├── test_4520.py │ ├── test_4614.py │ ├── test_4716.py │ ├── test_4767.py │ ├── test_4942.py │ ├── test_annots.py │ ├── test_badfonts.py │ ├── test_balance_count.py │ ├── test_barcode.py │ ├── test_clip_page.py │ ├── test_cluster_drawings.py │ ├── test_codespell.py │ ├── test_crypting.py │ ├── test_docs_samples.py │ ├── test_drawings.py │ ├── test_embeddedfiles.py │ ├── test_extractimage.py │ ├── test_flake8.py │ ├── test_font.py │ ├── test_general.py │ ├── test_geometry.py │ ├── test_imagebbox.py │ ├── test_imagemasks.py │ ├── test_import.py │ ├── test_insertimage.py │ ├── test_insertpdf.py │ ├── test_linebreaks.py │ ├── test_linequad.py │ ├── test_memory.py │ ├── test_metadata.py │ ├── test_mupdf_regressions.py │ ├── test_named_links.py │ ├── test_nonpdf.py │ ├── test_object_manipulation.py │ ├── test_objectstreams.py │ ├── test_optional_content.py │ ├── test_page_links.py │ ├── test_pagedelete.py │ ├── test_pagelabels.py │ ├── test_pixmap.py │ ├── test_pylint.py │ ├── test_release.py │ ├── test_remove-rotation.py │ ├── test_rewrite_images.py │ ├── test_rtl.py │ ├── test_showpdfpage.py │ ├── test_spikes.py │ ├── test_story.py │ ├── test_tables.py │ ├── test_tesseract.py │ ├── test_textbox.py │ ├── test_textextract.py │ ├── test_textsearch.py │ ├── test_threads.py │ ├── test_toc.py │ ├── test_typing.py │ ├── test_widgets.py │ ├── test_word_delimiters.py │ └── util.py └── valgrind.supp
SYMBOL INDEX (2079 symbols across 97 files)
FILE: docs/_static/prism/prism.js
function u (line 3) | function u(e){s.highlightedCode=e,a.hooks.run("before-insert",s),s.eleme...
function i (line 3) | function i(e,n,t,r){this.type=e,this.content=n,this.alias=t,this.length=...
function l (line 3) | function l(e,n,t,r){e.lastIndex=n;var a=e.exec(t);if(a&&r&&a[1]){var i=a...
function o (line 3) | function o(e,n,t,r,s,g){for(var f in t)if(t.hasOwnProperty(f)&&t[f]){var...
function s (line 3) | function s(){var e={value:null,prev:null,next:null},n={value:null,prev:e...
function u (line 3) | function u(e,n,t){var r=n.next,a={value:t,prev:n,next:r};return n.next=a...
function c (line 3) | function c(e,n,t){for(var r=n.next,a=0;a<t&&r!==e.tail;a++)r=r.next;n.ne...
function f (line 3) | function f(){a.manual||a.highlightAll()}
function n (line 10) | function n(e,n){return e.replace(/<<(\d+)>>/g,(function(e,s){return"(?:"...
function s (line 10) | function s(e,s,a){return RegExp(n(e,s),a||"")}
function a (line 10) | function a(e,n){for(var s=0;s<n;s++)e=e.replace(/<<self>>/g,(function(){...
function l (line 10) | function l(e){return"\\b(?:"+e.trim().replace(/ /g,"|")+")\\b"}
function q (line 10) | function q(n,a){return{interpolation:{pattern:s("((?:^|[^{])(?:\\{\\{)*)...
function n (line 18) | function n(t){this.defaults=e({},t)}
function r (line 18) | function r(e){for(var t=0,n=0;n<e.length;++n)e.charCodeAt(n)=="\t".charC...
function t (line 20) | function t(t){var e=document.createElement("textarea");e.value=t.getText...
function i (line 20) | function i(){setTimeout((function(){u("copy")}),n["copy-timeout"])}
function u (line 20) | function u(t){r.textContent=n[t],c.setAttribute("data-copy-state",t)}
FILE: docs/extensions/fulltoc.py
function html_page_context (line 23) | def html_page_context(app, pagename, templatename, context, doctree):
function get_rendered_toctree (line 53) | def get_rendered_toctree(builder, docname, prune=False, collapse=True):
function build_full_toctree (line 68) | def build_full_toctree(builder, docname, prune, collapse):
function setup (line 97) | def setup(app):
FILE: docs/extensions/searchrepair.py
function modify_search_index (line 4) | def modify_search_index(app, exception):
function setup (line 22) | def setup(app):
FILE: docs/samples/code-printer.py
function recorder (line 34) | def recorder(elpos):
function header_story (line 60) | def header_story(text):
function footer_story (line 75) | def footer_story(text):
function code_printer (line 89) | def code_printer(outfile):
FILE: docs/samples/multiprocess-gui.py
function module_exists (line 29) | def module_exists(module_name):
class DocForm (line 48) | class DocForm(QtWidgets.QWidget):
method __init__ (line 49) | def __init__(self):
method initUI (line 65) | def initUI(self):
method openDoc (line 99) | def openDoc(self):
method playDoc (line 124) | def playDoc(self):
method stopPlay (line 127) | def stopPlay(self):
method onTimerSendPageNum (line 130) | def onTimerSendPageNum(self):
method onTimerGetPage (line 136) | def onTimerGetPage(self):
method onTimerWaiting (line 157) | def onTimerWaiting(self):
method closeEvent (line 164) | def closeEvent(self, event):
function openDocInProcess (line 169) | def openDocInProcess(path, queNum, quePageInfo):
FILE: docs/samples/multiprocess-render.py
function render_page (line 24) | def render_page(vector):
FILE: docs/samples/national-capitals.py
function recorder (line 306) | def recorder(elpos):
FILE: docs/samples/new-annots.py
function print_descr (line 45) | def print_descr(annot):
FILE: docs/samples/quickfox-image-no-go.py
function analyze_page (line 63) | def analyze_page(page):
FILE: docs/samples/showpdf-page.py
function make_pdf (line 15) | def make_pdf(fileptr, text, rect, font="sans-serif", archive=None):
FILE: docs/samples/story-write-stabilized-links.py
function rectfn (line 14) | def rectfn(rect_num, filled):
function contentfn (line 24) | def contentfn(positions):
FILE: docs/samples/story-write-stabilized.py
function rectfn (line 18) | def rectfn(rect_num, filled):
function contentfn (line 28) | def contentfn(positions):
FILE: docs/samples/story-write.py
function rectfn (line 50) | def rectfn(rect_num, filled):
FILE: docs/samples/text-lister.py
function flags_decomposer (line 6) | def flags_decomposer(flags):
FILE: scripts/gh_release.py
function main (line 100) | def main():
function build (line 180) | def build( platform_=None, valgrind=False):
function cpu_bits (line 501) | def cpu_bits():
function venv (line 509) | def venv( command=None, packages=None, quick=False, system_site_packages...
function test (line 562) | def test( project, package, valgrind):
function relpath (line 588) | def relpath(path, start=None):
function relpath (line 595) | def relpath(path, start=None):
function platform_tag (line 599) | def platform_tag():
FILE: scripts/sysinstall.py
function main (line 115) | def main():
function run_command (line 423) | def run_command(command, capture=False, check=True, doit=True, env_extra...
FILE: scripts/test.py
function cibw_cp (line 403) | def cibw_cp(*version_minors):
function main (line 413) | def main(argv):
function get_env_bool (line 779) | def get_env_bool(name, default=0):
function show_help (line 790) | def show_help():
function github_workflow_unimportant (line 795) | def github_workflow_unimportant():
function venv_info (line 810) | def venv_info(pytest_args=None):
function build (line 842) | def build(
function cibuildwheel (line 885) | def cibuildwheel(
function cibw_do_test_project (line 1004) | def cibw_do_test_project(
function build_pyodide_wheel (line 1166) | def build_pyodide_wheel(pyodide_build_version=None):
function pyodide_setup (line 1213) | def pyodide_setup(
function test (line 1301) | def test(
function get_pyproject_required (line 1510) | def get_pyproject_required(ppt=None):
function wrap_get_requires_for_build_wheel (line 1527) | def wrap_get_requires_for_build_wheel(dir_):
function venv_in (line 1550) | def venv_in(path=None):
function venv_run (line 1561) | def venv_run(args, path, recreate=True, clean=False):
FILE: setup.py
function _fs_remove (line 248) | def _fs_remove(path):
function _git_get_branch (line 275) | def _git_get_branch( directory):
function tar_check (line 292) | def tar_check(path, mode='r:gz', prefix=None, remove=False):
function tar_extract (line 324) | def tar_extract(path, mode='r:gz', prefix=None, exists='raise'):
function git_info (line 363) | def git_info( directory):
function git_patch (line 393) | def git_patch(directory, patch, hard=False):
function get_mupdf_internal (line 427) | def get_mupdf_internal(out, location=None, local_tgz=None):
function get_mupdf_tgz (line 528) | def get_mupdf_tgz():
function get_mupdf (line 542) | def get_mupdf(path=None, sha=None):
function build (line 575) | def build():
function env_add (line 766) | def env_add(env, name, value, sep=' ', prepend=False, verbose=False):
function build_mupdf_windows (line 788) | def build_mupdf_windows(
function _windows_lib_directory (line 886) | def _windows_lib_directory(mupdf_local, build_type):
function _cpu_bits (line 899) | def _cpu_bits():
function build_mupdf_unix (line 905) | def build_mupdf_unix(
function get_mupdf_version (line 1068) | def get_mupdf_version(mupdf_dir):
function _fs_update (line 1081) | def _fs_update(text, path):
function _build_extension (line 1093) | def _build_extension( mupdf_local, mupdf_build_dir, build_type, g_py_lim...
function _extension_flags (line 1151) | def _extension_flags( mupdf_local, mupdf_build_dir, build_type):
function clean (line 1229) | def clean(all_):
function sdist (line 1253) | def sdist():
function get_requires_for_build_wheel (line 1334) | def get_requires_for_build_wheel(config_settings=None):
function get_requires_for_build_wheel (line 1430) | def get_requires_for_build_wheel(config_settings=None):
function build_wheel (line 1469) | def build_wheel(
FILE: src/__init__.py
function _make_output (line 46) | def _make_output(
function _log_items (line 173) | def _log_items():
function _log_items_active (line 176) | def _log_items_active(active):
function _log_items_clear (line 180) | def _log_items_clear():
function set_messages (line 184) | def set_messages(
function set_log (line 213) | def set_log(
function log (line 243) | def log( text='', caller=1):
function message (line 268) | def message(text=''):
function exception_info (line 278) | def exception_info():
function get_env_bool (line 287) | def get_env_bool( name, default):
function get_env_int (line 305) | def get_env_int( name, default):
class _Globals (line 331) | class _Globals:
method __init__ (line 332) | def __init__(self):
function no_recommend_layout (line 346) | def no_recommend_layout():
function _warn_layout_once (line 352) | def _warn_layout_once():
function _int_rc (line 402) | def _int_rc(text):
function _format_g (line 447) | def _format_g(value, *, fmt='%g'):
function _as_fz_document (line 488) | def _as_fz_document(document):
function _as_pdf_document (line 506) | def _as_pdf_document(document, required=True):
function _as_fz_page (line 529) | def _as_fz_page(page):
function _as_pdf_page (line 544) | def _as_pdf_page(page, required=True):
function _pdf_annot_page (line 565) | def _pdf_annot_page(annot):
class Annot (line 586) | class Annot:
method __init__ (line 588) | def __init__(self, annot):
method __bool__ (line 592) | def __bool__(self):
method __repr__ (line 595) | def __repr__(self):
method __str__ (line 599) | def __str__(self):
method _erase (line 602) | def _erase(self):
method _get_redact_values (line 606) | def _get_redact_values(self):
method _getAP (line 645) | def _getAP(self):
method _setAP (line 664) | def _setAP(self, buffer_, rect=0):
method _update_appearance (line 684) | def _update_appearance(self, opacity=-1, blend_mode=None, fill_color=N...
method apn_bbox (line 784) | def apn_bbox(self):
method apn_matrix (line 801) | def apn_matrix(self):
method blendmode (line 825) | def blendmode(self):
method border (line 857) | def border(self):
method clean_contents (line 875) | def clean_contents(self, sanitize=1):
method colors (line 884) | def colors(self):
method delete_responses (line 895) | def delete_responses(self):
method file_info (line 923) | def file_info(self):
method flags (line 973) | def flags(self):
method get_file (line 979) | def get_file(self):
method get_oc (line 994) | def get_oc(self):
method get_parent (line 1008) | def get_parent(self):
method get_pixmap (line 1022) | def get_pixmap(self, matrix=None, dpi=None, colorspace=None, alpha=0):
method get_sound (line 1042) | def get_sound(self):
method get_text (line 1074) | def get_text(self, *args, **kwargs):
method get_textbox (line 1077) | def get_textbox(self, *args, **kwargs):
method get_textpage (line 1080) | def get_textpage(self, clip=None, flags=0):
method has_popup (line 1100) | def has_popup(self):
method info (line 1108) | def info(self):
method irt_xref (line 1142) | def irt_xref(self):
method is_open (line 1154) | def is_open(self):
method language (line 1160) | def language(self):
method line_ends (line 1170) | def line_ends(self):
method next (line 1182) | def next(self):
method opacity (line 1208) | def opacity(self):
method popup_rect (line 1219) | def popup_rect(self):
method popup_xref (line 1238) | def popup_xref(self):
method rect (line 1250) | def rect(self):
method rect_delta (line 1270) | def rect_delta(self):
method rotation (line 1285) | def rotation(self):
method set_apn_bbox (line 1294) | def set_apn_bbox(self, bbox):
method set_apn_matrix (line 1311) | def set_apn_matrix(self, matrix):
method set_blendmode (line 1322) | def set_blendmode(self, blend_mode):
method set_border (line 1329) | def set_border(self, border=None, width=-1, style=None, dashes=None, c...
method set_colors (line 1376) | def set_colors(self, colors=None, stroke=None, fill=None):
method set_flags (line 1417) | def set_flags(self, flags):
method set_info (line 1423) | def set_info(self, info=None, content=None, title=None, creationDate=N...
method set_irt_xref (line 1453) | def set_irt_xref(self, xref):
method set_language (line 1469) | def set_language(self, language=None):
method set_line_ends (line 1479) | def set_line_ends(self, start, end):
method set_name (line 1488) | def set_name(self, name):
method set_oc (line 1495) | def set_oc(self, oc=0):
method set_opacity (line 1505) | def set_opacity(self, opacity):
method set_open (line 1517) | def set_open(self, is_open):
method set_popup (line 1523) | def set_popup(self, rect):
method set_rect (line 1534) | def set_rect(self, rect):
method set_rotation (line 1550) | def set_rotation(self, rotate=0):
method type (line 1581) | def type(self):
method update (line 1594) | def update(self,
method update_file (line 1847) | def update_file(self, buffer_=None, filename=None, ufilename=None, des...
method update_timing_test (line 1891) | def update_timing_test():
method vertices (line 1898) | def vertices(self):
method xref (line 1952) | def xref(self):
class Archive (line 1959) | class Archive:
method __init__ (line 1960) | def __init__( self, *args):
method __repr__ (line 1973) | def __repr__( self):
method _add_arch (line 1976) | def _add_arch( self, subarch, path=None):
method _add_dir (line 1979) | def _add_dir( self, folder, path=None):
method _add_treeitem (line 1983) | def _add_treeitem( self, memory, name, path=None):
method _add_ziptarfile (line 1989) | def _add_ziptarfile( self, filepath, type_, path=None):
method _add_ziptarmemory (line 1996) | def _add_ziptarmemory( self, memory, type_, path=None):
method add (line 2005) | def add( self, content, path=None):
method entry_list (line 2111) | def entry_list( self):
method has_entry (line 2117) | def has_entry( self, name):
method read_entry (line 2120) | def read_entry( self, name):
class Xml (line 2125) | class Xml:
method __enter__ (line 2127) | def __enter__(self):
method __exit__ (line 2130) | def __exit__(self, *args):
method __init__ (line 2133) | def __init__(self, rhs):
method _get_node_tree (line 2142) | def _get_node_tree( self):
method add_bullet_list (line 2164) | def add_bullet_list(self):
method add_class (line 2170) | def add_class(self, text):
method add_code (line 2183) | def add_code(self, text=None):
method add_codeblock (line 2194) | def add_codeblock(self):
method add_description_list (line 2200) | def add_description_list(self):
method add_division (line 2206) | def add_division(self):
method add_header (line 2212) | def add_header(self, level=1):
method add_horizontal_line (line 2225) | def add_horizontal_line(self):
method add_image (line 2231) | def add_image(self, name, width=None, height=None, imgfloat=None, alig...
method add_link (line 2246) | def add_link(self, href, text=None):
method add_list_item (line 2259) | def add_list_item(self):
method add_number_list (line 2267) | def add_number_list(self, start=1, numtype=None):
method add_paragraph (line 2277) | def add_paragraph(self):
method add_span (line 2286) | def add_span(self):
method add_style (line 2291) | def add_style(self, text):
method add_subscript (line 2304) | def add_subscript(self, text=None):
method add_superscript (line 2315) | def add_superscript(self, text=None):
method add_text (line 2326) | def add_text(self, text):
method append_child (line 2340) | def append_child( self, child):
method append_styled_span (line 2343) | def append_styled_span(self, style):
method bodytag (line 2352) | def bodytag( self):
method clone (line 2355) | def clone( self):
method color_text (line 2360) | def color_text(color):
method create_element (line 2369) | def create_element( self, tag):
method create_text_node (line 2372) | def create_text_node( self, text):
method debug (line 2375) | def debug(self):
method find (line 2381) | def find( self, tag, att, match):
method find_next (line 2386) | def find_next( self, tag, att, match):
method first_child (line 2392) | def first_child( self):
method get_attribute_value (line 2400) | def get_attribute_value( self, key):
method get_attributes (line 2404) | def get_attributes( self):
method insert_after (line 2418) | def insert_after( self, node):
method insert_before (line 2421) | def insert_before( self, node):
method insert_text (line 2424) | def insert_text(self, text):
method is_text (line 2434) | def is_text(self):
method last_child (line 2439) | def last_child(self):
method next (line 2451) | def next( self):
method parent (line 2457) | def parent( self):
method previous (line 2463) | def previous( self):
method remove (line 2468) | def remove( self):
method remove_attribute (line 2471) | def remove_attribute( self, key):
method root (line 2476) | def root( self):
method set_align (line 2479) | def set_align(self, align):
method set_attribute (line 2496) | def set_attribute( self, key, value):
method set_bgcolor (line 2500) | def set_bgcolor(self, color):
method set_bold (line 2505) | def set_bold(self, val=True):
method set_color (line 2514) | def set_color(self, color):
method set_columns (line 2519) | def set_columns(self, cols):
method set_font (line 2524) | def set_font(self, font):
method set_fontsize (line 2529) | def set_fontsize(self, fontsize):
method set_id (line 2539) | def set_id(self, unique):
method set_italic (line 2548) | def set_italic(self, val=True):
method set_leading (line 2557) | def set_leading(self, leading):
method set_letter_spacing (line 2562) | def set_letter_spacing(self, spacing):
method set_lineheight (line 2567) | def set_lineheight(self, lineheight):
method set_margins (line 2572) | def set_margins(self, val):
method set_opacity (line 2577) | def set_opacity(self, opacity):
method set_pagebreak_after (line 2582) | def set_pagebreak_after(self):
method set_pagebreak_before (line 2587) | def set_pagebreak_before(self):
method set_properties (line 2592) | def set_properties(
method set_text_indent (line 2668) | def set_text_indent(self, indent):
method set_underline (line 2673) | def set_underline(self, val="underline"):
method set_word_spacing (line 2677) | def set_word_spacing(self, spacing):
method span_bottom (line 2682) | def span_bottom(self):
method tagname (line 2708) | def tagname( self):
method text (line 2712) | def text( self):
class Colorspace (line 2720) | class Colorspace:
method __init__ (line 2722) | def __init__(self, type_):
method __repr__ (line 2735) | def __repr__(self):
method _name (line 2739) | def _name(self):
method n (line 2743) | def n(self):
method name (line 2748) | def name(self):
class DeviceWrapper (line 2753) | class DeviceWrapper:
method __init__ (line 2754) | def __init__(self, *args):
class DisplayList (line 2776) | class DisplayList:
method __del__ (line 2777) | def __del__(self):
method __init__ (line 2781) | def __init__(self, *args):
method get_pixmap (line 2789) | def get_pixmap(self, matrix=None, colorspace=None, alpha=0, clip=None):
method get_textpage (line 2798) | def get_textpage(self, flags=3):
method rect (line 2807) | def rect(self):
method run (line 2812) | def run(self, dw, m, area):
class Document (line 2825) | class Document:
method __contains__ (line 2827) | def __contains__(self, loc) -> bool:
method __delitem__ (line 2849) | def __delitem__(self, i)->None:
method __enter__ (line 2872) | def __enter__(self):
method __exit__ (line 2875) | def __exit__(self, *args):
method __getitem__ (line 2879) | def __getitem__(self, i: int = 0) -> Page:
method __getitem__ (line 2884) | def __getitem__(self, i: slice) -> list[Page]:
method __getitem__ (line 2888) | def __getitem__(self, i: tuple[int, int]) -> Page:
method __getitem__ (line 2891) | def __getitem__(self, i=0):
method __init__ (line 2900) | def __init__(self, filename=None, stream=None, filetype=None, rect=Non...
method __len__ (line 3053) | def __len__(self) -> int:
method __repr__ (line 3056) | def __repr__(self) -> str:
method _addFormFont (line 3064) | def _addFormFont(self, name, font):
method del_toc_item (line 3084) | def del_toc_item(
method _delToC (line 3092) | def _delToC(self):
method _delete_page (line 3124) | def _delete_page(self, pno):
method _deleteObject (line 3130) | def _deleteObject(self, xref):
method _do_links (line 3137) | def _do_links(
method _do_widgets (line 3271) | def _do_widgets(
method _embeddedFileGet (line 3597) | def _embeddedFileGet(self, idx):
method _embeddedFileIndex (line 3612) | def _embeddedFileIndex(self, item: typing.Union[int, str]) -> int:
method _embfile_add (line 3622) | def _embfile_add(self, name, buffer_, filename=None, ufilename=None, d...
method _embfile_del (line 3653) | def _embfile_del(self, idx):
method _embfile_info (line 3665) | def _embfile_info(self, idx, infodict):
method _embfile_names (line 3712) | def _embfile_names(self, namelist):
method _embfile_upd (line 3732) | def _embfile_upd(self, idx, buffer_=None, filename=None, ufilename=Non...
method _extend_toc_items (line 3768) | def _extend_toc_items(self, items):
method _forget_page (line 3838) | def _forget_page(self, page: Page):
method _get_char_widths (line 3845) | def _get_char_widths(self, xref: int, bfname: str, ext: str, ordering:...
method _get_page_labels (line 3875) | def _get_page_labels(self):
method _getMetadata (line 3907) | def _getMetadata(self, key):
method _getOLRootNumber (line 3915) | def _getOLRootNumber(self):
method _getPDFfileid (line 3932) | def _getPDFfileid(self):
method _getPageInfo (line 3948) | def _getPageInfo(self, pno, what):
method _insert_font (line 3968) | def _insert_font(self, fontfile=None, fontbuffer=None):
method _loadOutline (line 3978) | def _loadOutline(self):
method _make_page_map (line 3989) | def _make_page_map(self):
method _move_copy_page (line 3995) | def _move_copy_page(self, pno, nb, before, copy):
method _newPage (line 4051) | def _newPage(self, pno=-1, width=595, height=842):
method _remove_links_to (line 4075) | def _remove_links_to(self, numbers):
method _remove_toc_item (line 4079) | def _remove_toc_item(self, xref):
method _reset_page_refs (line 4090) | def _reset_page_refs(self):
method _set_page_labels (line 4101) | def _set_page_labels(self, labels):
method _update_toc_item (line 4113) | def _update_toc_item(self, xref, action=None, title=None, flags=0, col...
method FormFonts (line 4142) | def FormFonts(self):
method add_layer (line 4162) | def add_layer(self, name, creator=None, on=None):
method add_ocg (line 4168) | def add_ocg(self, name, config=-1, on=1, intent=None, usage=None):
method authenticate (line 4238) | def authenticate(self, password):
method can_save_incrementally (line 4250) | def can_save_incrementally(self):
method bake (line 4257) | def bake(self, *, annots: bool = True, widgets: bool = True) -> None:
method chapter_count (line 4276) | def chapter_count(self):
method chapter_page_count (line 4282) | def chapter_page_count(self, chapter):
method close (line 4292) | def close(self):
method convert_to_pdf (line 4310) | def convert_to_pdf(self, from_page=0, to_page=-1, rotate=0):
method copy_page (line 4333) | def copy_page(self, pno: int, to: int =-1):
method del_xml_metadata (line 4358) | def del_xml_metadata(self):
method delete_page (line 4367) | def delete_page(self, pno: int =-1):
method delete_pages (line 4372) | def delete_pages(self, *args, **kw):
method embfile_add (line 4441) | def embfile_add(self,
method embfile_count (line 4479) | def embfile_count(self) -> int:
method embfile_del (line 4483) | def embfile_del(self, item: typing.Union[int, str]):
method embfile_get (line 4498) | def embfile_get(self, item: typing.Union[int, str]) -> bytes:
method embfile_info (line 4509) | def embfile_info(self, item: typing.Union[int, str]) -> dict:
method embfile_names (line 4531) | def embfile_names(self) -> list:
method embfile_upd (line 4537) | def embfile_upd(self,
method extract_font (line 4568) | def extract_font(self, xref=0, info_only=0, named=None):
method extract_image (line 4617) | def extract_image(self, xref):
method ez_save (line 4647) | def ez_save(
method find_bookmark (line 4696) | def find_bookmark(self, bm):
method fullcopy_page (line 4703) | def fullcopy_page(self, pno, to=-1):
method get_char_widths (line 4759) | def get_char_widths(
method get_layer (line 4860) | def get_layer(self, config=-1):
method get_layers (line 4882) | def get_layers(self):
method get_new_xref (line 4907) | def get_new_xref(self):
method get_oc (line 4917) | def get_oc(doc: 'Document', xref: int) -> int:
method get_ocgs (line 4934) | def get_ocgs(self):
method get_ocmd (line 4981) | def get_ocmd(doc: 'Document', xref: int) -> dict:
method get_outline_xrefs (line 5048) | def get_outline_xrefs(self):
method get_page_fonts (line 5066) | def get_page_fonts(self, pno: int, full: bool =False) -> list:
method get_page_images (line 5084) | def get_page_images(self, pno: int, full: bool =False) -> list:
method get_page_labels (line 5096) | def get_page_labels(self):
method get_page_numbers (line 5106) | def get_page_numbers(doc, label, only_one=False):
method get_page_pixmap (line 5132) | def get_page_pixmap(
method get_page_text (line 5167) | def get_page_text(
method get_page_xobjects (line 5188) | def get_page_xobjects(self, pno: int) -> list:
method get_sigflags (line 5198) | def get_sigflags(self):
method get_toc (line 5214) | def get_toc(
method get_xml_metadata (line 5268) | def get_xml_metadata(self):
method has_annots (line 5285) | def has_annots(doc: 'Document') -> bool:
method has_links (line 5298) | def has_links(doc: 'Document') -> bool:
method init_doc (line 5310) | def init_doc(self):
method insert_file (line 5332) | def insert_file(self,
method insert_page (line 5375) | def insert_page(
method insert_pdf (line 5405) | def insert_pdf(
method is_dirty (line 5525) | def is_dirty(self):
method is_fast_webaccess (line 5533) | def is_fast_webaccess(self):
method is_form_pdf (line 5543) | def is_form_pdf(self):
method is_pdf (line 5566) | def is_pdf(self):
method is_reflowable (line 5581) | def is_reflowable(self):
method is_repaired (line 5588) | def is_repaired(self):
method journal_can_do (line 5598) | def journal_can_do(self):
method journal_enable (line 5609) | def journal_enable(self):
method journal_is_enabled (line 5616) | def journal_is_enabled(self):
method journal_load (line 5624) | def journal_load(self, filename):
method journal_op_name (line 5638) | def journal_op_name(self, step):
method journal_position (line 5646) | def journal_position(self):
method journal_redo (line 5655) | def journal_redo(self):
method journal_save (line 5663) | def journal_save(self, filename):
method journal_start_op (line 5675) | def journal_start_op(self, name=None):
method journal_stop_op (line 5687) | def journal_stop_op(self):
method journal_undo (line 5694) | def journal_undo(self):
method language (line 5703) | def language(self):
method last_location (line 5714) | def last_location(self):
method layer_ui_configs (line 5721) | def layer_ui_configs(self):
method layout (line 5746) | def layout(self, rect=None, width=0, height=0, fontsize=11):
method load_page (line 5766) | def load_page(self, page_id):
method location_from_page_number (line 5796) | def location_from_page_number(self, pno):
method make_bookmark (line 5810) | def make_bookmark(self, loc):
method markinfo (line 5819) | def markinfo(self) -> dict:
method move_page (line 5848) | def move_page(self, pno: int, to: int =-1):
method name (line 5869) | def name(self):
method need_appearances (line 5872) | def need_appearances(self, value=None):
method needs_pass (line 5897) | def needs_pass(self):
method new_page (line 5905) | def new_page(
method next_location (line 5923) | def next_location(self, page_id):
method page_annot_xrefs (line 5944) | def page_annot_xrefs(self, n):
method page_count (line 5963) | def page_count(self):
method page_cropbox (line 5974) | def page_cropbox(self, pno):
method page_number_from_location (line 5994) | def page_number_from_location(self, page_id):
method page_xref (line 6008) | def page_xref(self, pno):
method pagelayout (line 6026) | def pagelayout(self) -> str:
method pagemode (line 6040) | def pagemode(self) -> str:
method pages (line 6053) | def pages(self, start: OptInt =None, stop: OptInt =None, step: OptInt ...
method pdf_catalog (line 6082) | def pdf_catalog(self):
method pdf_trailer (line 6092) | def pdf_trailer(self, compressed=0, ascii=0):
method permissions (line 6097) | def permissions(self):
method prev_location (line 6121) | def prev_location(self, page_id):
method reload_page (line 6137) | def reload_page(self, page: Page) -> Page:
method repair (line 6196) | def repair(self):
method resolve_link (line 6204) | def resolve_link(self, uri=None, chapters=0):
method rewrite_images (line 6230) | def rewrite_images(
method recolor (line 6317) | def recolor(self, components=1):
method resolve_names (line 6330) | def resolve_names(self):
method save (line 6461) | def save(
method save_snapshot (line 6555) | def save_snapshot(self, filename):
method saveIncr (line 6572) | def saveIncr(self):
method scrub (line 6580) | def scrub(
method search_page_for (line 6735) | def search_page_for(
method select (line 6771) | def select(self, pyliste):
method set_language (line 6798) | def set_language(self, language=None):
method set_layer (line 6807) | def set_layer(self, config, basestate=None, on=None, off=None, rbgroup...
method set_layer_ui_config (line 6872) | def set_layer_ui_config(self, number, action=0):
method set_markinfo (line 6889) | def set_markinfo(self, markinfo: dict) -> bool:
method set_metadata (line 6912) | def set_metadata(doc: 'Document', m: dict = None) -> None:
method set_oc (line 6973) | def set_oc(doc: 'Document', xref: int, oc: int) -> None:
method set_ocmd (line 6995) | def set_ocmd(
method set_pagelayout (line 7068) | def set_pagelayout(self, pagelayout: str):
method set_pagemode (line 7084) | def set_pagemode(self, pagemode: str):
method set_page_labels (line 7100) | def set_page_labels(doc, labels):
method set_toc (line 7144) | def set_toc(
method set_toc_item (line 7335) | def set_toc_item(
method set_xml_metadata (line 7443) | def set_xml_metadata(self, metadata):
method subset_fonts (line 7461) | def subset_fonts(doc: 'Document', verbose: bool = False, fallback: boo...
method switch_layer (line 7773) | def switch_layer(self, config, as_default=0):
method update_object (line 7793) | def update_object(self, xref, text, page=None):
method update_stream (line 7808) | def update_stream(self, xref=0, stream=None, new=1, compress=1):
method version_count (line 7827) | def version_count(self):
method write (line 7836) | def write(
method tobytes (line 7886) | def tobytes(self, *args, **kwargs):
method xref (line 7890) | def xref(self):
method xref_copy (line 7895) | def xref_copy(doc: 'Document', source: int, target: int, *, keep: list...
method xref_get_key (line 7930) | def xref_get_key(self, xref, key):
method xref_get_keys (line 7980) | def xref_get_keys(self, xref):
method xref_is_font (line 7999) | def xref_is_font(self, xref):
method xref_is_image (line 8007) | def xref_is_image(self, xref):
method xref_is_stream (line 8015) | def xref_is_stream(self, xref=0):
method xref_is_xobject (line 8022) | def xref_is_xobject(self, xref):
method xref_length (line 8030) | def xref_length(self):
method xref_object (line 8038) | def xref_object(self, xref, compressed=0, ascii=0):
method xref_set_key (line 8057) | def xref_set_key(self, xref, key, value):
method xref_stream (line 8095) | def xref_stream(self, xref):
method xref_stream_raw (line 8113) | def xref_stream_raw(self, xref):
method xref_xml_metadata (line 8131) | def xref_xml_metadata(self):
class DocumentWriter (line 8151) | class DocumentWriter:
method __enter__ (line 8153) | def __enter__(self):
method __exit__ (line 8156) | def __exit__(self, *args):
method __init__ (line 8159) | def __init__(self, path, options=''):
method begin_page (line 8182) | def begin_page( self, mediabox):
method close (line 8188) | def close( self):
method end_page (line 8191) | def end_page( self):
class Font (line 8195) | class Font:
method __del__ (line 8197) | def __del__(self):
method __init__ (line 8201) | def __init__(
method __repr__ (line 8252) | def __repr__(self):
method ascender (line 8256) | def ascender(self):
method bbox (line 8261) | def bbox(self):
method buffer (line 8265) | def buffer(self):
method char_lengths (line 8269) | def char_lengths(self, text, fontsize=11, language=None, script=0, wmo...
method descender (line 8285) | def descender(self):
method flags (line 8290) | def flags(self):
method glyph_advance (line 8333) | def glyph_advance(self, chr_, language=None, script=0, wmode=0, small_...
method glyph_bbox (line 8344) | def glyph_bbox(self, char, language=None, script=0, small_caps=0):
method glyph_count (line 8356) | def glyph_count(self):
method glyph_name_to_unicode (line 8359) | def glyph_name_to_unicode(self, name):
method has_glyph (line 8363) | def has_glyph(self, chr, language=None, script=0, fallback=0, small_ca...
method is_bold (line 8376) | def is_bold(self):
method is_italic (line 8380) | def is_italic(self):
method is_monospaced (line 8384) | def is_monospaced(self):
method is_serif (line 8388) | def is_serif(self):
method is_writable (line 8392) | def is_writable(self):
method name (line 8411) | def name(self):
method text_length (line 8416) | def text_length(self, text, fontsize=11, language=None, script=0, wmod...
method unicode_to_glyph_name (line 8435) | def unicode_to_glyph_name(self, ch):
method valid_codepoints (line 8439) | def valid_codepoints(self):
class Graftmap (line 8450) | class Graftmap:
method __del__ (line 8452) | def __del__(self):
method __init__ (line 8457) | def __init__(self, doc):
class Link (line 8464) | class Link:
method __del__ (line 8465) | def __del__(self):
method __init__ (line 8468) | def __init__( self, this):
method __repr__ (line 8472) | def __repr__(self):
method __str__ (line 8476) | def __str__(self):
method _border (line 8480) | def _border(self, doc, xref):
method _colors (line 8490) | def _colors(self, doc, xref):
method _erase (line 8500) | def _erase(self):
method _setBorder (line 8504) | def _setBorder(self, border, doc, xref):
method border (line 8515) | def border(self):
method colors (line 8519) | def colors(self):
method dest (line 8523) | def dest(self):
method flags (line 8539) | def flags(self)->int:
method is_external (line 8550) | def is_external(self):
method next (line 8561) | def next(self):
method rect (line 8589) | def rect(self):
method set_border (line 8600) | def set_border(self, border=None, width=0, dashes=None, style=None):
method set_colors (line 8605) | def set_colors(self, colors=None, stroke=None, fill=None):
method set_flags (line 8625) | def set_flags(self, flags):
method uri (line 8636) | def uri(self):
class Matrix (line 8647) | class Matrix:
method __abs__ (line 8649) | def __abs__(self):
method __add__ (line 8652) | def __add__(self, m):
method __bool__ (line 8661) | def __bool__(self):
method __eq__ (line 8664) | def __eq__(self, mat):
method __getitem__ (line 8669) | def __getitem__(self, i):
method __init__ (line 8672) | def __init__(self, *args, a=None, b=None, c=None, d=None, e=None, f=No...
method __invert__ (line 8727) | def __invert__(self):
method __len__ (line 8733) | def __len__(self):
method __mul__ (line 8736) | def __mul__(self, m):
method __neg__ (line 8743) | def __neg__(self):
method __nonzero__ (line 8746) | def __nonzero__(self):
method __pos__ (line 8749) | def __pos__(self):
method __repr__ (line 8752) | def __repr__(self):
method __setitem__ (line 8755) | def __setitem__(self, i, v):
method __sub__ (line 8767) | def __sub__(self, m):
method __truediv__ (line 8776) | def __truediv__(self, m):
method concat (line 8786) | def concat(self, one, two):
method invert (line 8793) | def invert(self, src=None):
method is_rectilinear (line 8807) | def is_rectilinear(self):
method prerotate (line 8812) | def prerotate(self, theta):
method prescale (line 8855) | def prescale(self, sx, sy):
method preshear (line 8865) | def preshear(self, h, v):
method pretranslate (line 8876) | def pretranslate(self, tx, ty):
class IdentityMatrix (line 8889) | class IdentityMatrix(Matrix):
method __hash__ (line 8892) | def __hash__(self):
method __init__ (line 8895) | def __init__(self):
method __repr__ (line 8898) | def __repr__(self):
method __setattr__ (line 8901) | def __setattr__(self, name, value):
method checkargs (line 8909) | def checkargs(*args):
class linkDest (line 8915) | class linkDest:
method __init__ (line 8918) | def __init__(self, obj, rlink, document=None):
class Widget (line 9018) | class Widget:
method __init__ (line 9023) | def __init__(self):
method __repr__ (line 9060) | def __repr__(self):
method _adjust_font (line 9063) | def _adjust_font(self):
method _checker (line 9077) | def _checker(self):
method _parse_da (line 9098) | def _parse_da(self):
method _validate (line 9129) | def _validate(self):
method _sync_flags (line 9200) | def _sync_flags(self):
method button_states (line 9245) | def button_states(self):
method next (line 9295) | def next(self):
method on_state (line 9298) | def on_state(self):
method reset (line 9319) | def reset(self):
method update (line 9324) | def update(self, sync_flags=False):
class Outline (line 9358) | class Outline:
method __init__ (line 9360) | def __init__(self, ol):
method dest (line 9364) | def dest(self):
method destination (line 9368) | def destination(self, document):
method down (line 9376) | def down(self):
method is_external (line 9384) | def is_external(self):
method is_open (line 9399) | def is_open(self):
method next (line 9405) | def next(self):
method page (line 9413) | def page(self):
method title (line 9419) | def title(self):
method uri (line 9423) | def uri(self):
method x (line 9430) | def x(self):
method y (line 9434) | def y(self):
function _make_PdfFilterOptions (line 9440) | def _make_PdfFilterOptions(
class Page (line 9502) | class Page:
method __init__ (line 9504) | def __init__(self, page, document):
method __repr__ (line 9520) | def __repr__(self):
method __str__ (line 9523) | def __str__(self):
method _add_caret_annot (line 9542) | def _add_caret_annot(self, point):
method _add_file_annot (line 9557) | def _add_file_annot(self, point, buffer_, filename, ufilename=None, de...
method _add_freetext_annot (line 9584) | def _add_freetext_annot(
method _add_ink_annot (line 9664) | def _add_ink_annot(self, list):
method _add_line_annot (line 9696) | def _add_line_annot(self, p1, p2):
method _add_multiline (line 9707) | def _add_multiline(self, points, annot_type):
method _add_redact_annot (line 9722) | def _add_redact_annot(self, quad, text=None, da_str=None, align=0, fil...
method _add_square_or_circle (line 9752) | def _add_square_or_circle(self, rect, annot_type):
method _add_stamp_annot (line 9764) | def _add_stamp_annot(self, rect, stamp=0):
method _add_text_annot (line 9832) | def _add_text_annot(self, point, text, icon=None):
method _add_text_marker (line 9846) | def _add_text_marker(self, quads, annot_type):
method _addAnnot_FromString (line 9860) | def _addAnnot_FromString(self, linklist):
method _addWidget (line 9894) | def _addWidget(self, field_type, field_name):
method _apply_redactions (line 9903) | def _apply_redactions(self, text, images, graphics):
method _erase (line 9913) | def _erase(self):
method _count_q_balance (line 9925) | def _count_q_balance(self):
method _get_optional_content (line 9949) | def _get_optional_content(self, oc: OptInt) -> OptStr:
method _get_resource_properties (line 9972) | def _get_resource_properties(self):
method _get_textpage (line 9980) | def _get_textpage(self, clip=None, flags=0, matrix=None):
method _insert_image (line 10005) | def _insert_image(self,
method _insertFont (line 10177) | def _insertFont(self, fontname, bfname, fontfile, fontbuffer, set_simp...
method _load_annot (line 10198) | def _load_annot(self, name, xref):
method _makePixmap (line 10207) | def _makePixmap(self, doc, ctm, cs, alpha=0, annots=1, clip=None):
method _other_box (line 10211) | def _other_box(self, boxtype):
method _pdf_page (line 10222) | def _pdf_page(self, required=True):
method _reset_annot_refs (line 10225) | def _reset_annot_refs(self):
method _set_opacity (line 10229) | def _set_opacity(self, gstate=None, CA=1, ca=1, blendmode=None):
method _set_pagebox (line 10262) | def _set_pagebox(self, boxtype, rect):
method _set_resource_property (line 10283) | def _set_resource_property(self, name, xref):
method _show_pdf_page (line 10287) | def _show_pdf_page(self, fz_srcpage, overlay=1, matrix=None, xref=0, o...
method add_caret_annot (line 10344) | def add_caret_annot(self, point: point_like) -> Annot:
method add_circle_annot (line 10357) | def add_circle_annot(self, rect: rect_like) -> Annot:
method add_file_annot (line 10368) | def add_file_annot(
method add_freetext_annot (line 10393) | def add_freetext_annot(
method add_highlight_annot (line 10441) | def add_highlight_annot(self, quads=None, start=None,
method add_ink_annot (line 10451) | def add_ink_annot(self, handwriting: list) -> Annot:
method add_line_annot (line 10465) | def add_line_annot(self, p1: point_like, p2: point_like) -> Annot:
method add_polygon_annot (line 10476) | def add_polygon_annot(self, points: list) -> Annot:
method add_polyline_annot (line 10487) | def add_polyline_annot(self, points: list) -> Annot:
method add_rect_annot (line 10498) | def add_rect_annot(self, rect: rect_like) -> Annot:
method add_redact_annot (line 10509) | def add_redact_annot(
method add_squiggly_annot (line 10571) | def add_squiggly_annot(
method add_stamp_annot (line 10585) | def add_stamp_annot(self, rect: rect_like, stamp=0) -> Annot:
method add_strikeout_annot (line 10596) | def add_strikeout_annot(self, quads=None, start=None, stop=None, clip=...
method add_text_annot (line 10604) | def add_text_annot(self, point: point_like, text: str, icon: str ="Not...
method add_underline_annot (line 10615) | def add_underline_annot(self, quads=None, start=None, stop=None, clip=...
method add_widget (line 10623) | def add_widget(self, widget: Widget) -> Annot:
method annot_names (line 10641) | def annot_names(self):
method annot_xrefs (line 10652) | def annot_xrefs(self):
method annots (line 10658) | def annots(self, types=None):
method apply_redactions (line 10678) | def apply_redactions(
method recolor (line 10789) | def recolor(self, components=1):
method clip_to_rect (line 10802) | def clip_to_rect(self, rect):
method get_layout (line 10813) | def get_layout(self):
method artbox (line 10828) | def artbox(self):
method bleedbox (line 10837) | def bleedbox(self):
method bound (line 10845) | def bound(self):
method clean_contents (line 10863) | def clean_contents(self, sanitize=1):
method cropbox (line 10873) | def cropbox(self):
method cropbox_position (line 10886) | def cropbox_position(self):
method delete_annot (line 10889) | def delete_annot(self, annot):
method delete_image (line 10912) | def delete_image(page: 'Page', xref: int):
method delete_link (line 10925) | def delete_link(self, linkdict):
method delete_widget (line 10969) | def delete_widget(page: 'Page', widget: Widget) -> Widget:
method derotation_matrix (line 10984) | def derotation_matrix(self) -> Matrix:
method draw_bezier (line 10993) | def draw_bezier(
method draw_circle (line 11032) | def draw_circle(
method draw_curve (line 11066) | def draw_curve(
method draw_line (line 11104) | def draw_line(
method draw_oval (line 11138) | def draw_oval(
method draw_polyline (line 11172) | def draw_polyline(
method draw_quad (line 11208) | def draw_quad(
method draw_rect (line 11242) | def draw_rect(
method draw_sector (line 11279) | def draw_sector(
method draw_squiggle (line 11325) | def draw_squiggle(
method draw_zigzag (line 11360) | def draw_zigzag(
method extend_textpage (line 11395) | def extend_textpage(self, tpage, flags=0, matrix=None):
method find_tables (line 11406) | def find_tables(self, **kwargs):
method first_annot (line 11410) | def first_annot(self):
method first_link (line 11426) | def first_link(self):
method first_widget (line 11433) | def first_widget(self):
method get_bboxlog (line 11452) | def get_bboxlog(self, layers=None):
method get_cdrawings (line 11468) | def get_cdrawings(self, extended=None, callback=None, method=None):
method get_contents (line 11499) | def get_contents(self):
method get_displaylist (line 11517) | def get_displaylist(self, annots=1):
method get_drawings (line 11530) | def get_drawings(self, extended: bool=False) -> list:
method get_image_info (line 11720) | def get_image_info(
method get_image_rects (line 11761) | def get_image_rects(page: 'Page', name, transform=False) -> list:
method get_label (line 11797) | def get_label(page):
method get_links (line 11813) | def get_links(page: 'Page') -> list:
method get_pixmap (line 11839) | def get_pixmap(
method remove_rotation (line 11882) | def remove_rotation(self):
method cluster_drawings (line 11936) | def cluster_drawings(
method get_fonts (line 12035) | def get_fonts(self, full=False):
method get_image_bbox (line 12040) | def get_image_bbox(self, name, transform=0):
method get_images (line 12104) | def get_images(self, full=False):
method get_oc_items (line 12109) | def get_oc_items(self) -> list:
method get_svg_image (line 12128) | def get_svg_image(self, matrix=None, text_as_path=1):
method get_textbox (line 12152) | def get_textbox(
method get_text (line 12167) | def get_text(self, *args, **kwargs):
method get_text_blocks (line 12170) | def get_text_blocks(self, *args, **kwargs):
method get_text_selection (line 12173) | def get_text_selection(self, *args, **kwargs):
method get_text_words (line 12176) | def get_text_words(self, *args, **kwargs):
method get_textpage_ocr (line 12179) | def get_textpage_ocr(self, *args, **kwargs):
method get_textpage (line 12182) | def get_textpage(self, clip: rect_like = None, flags: int = 0, matrix=...
method get_texttrace (line 12198) | def get_texttrace(self):
method get_xobjects (line 12219) | def get_xobjects(self):
method insert_font (line 12224) | def insert_font(self, fontname="helv", fontfile=None, fontbuffer=None,
method insert_htmlbox (line 12307) | def insert_htmlbox(
method insert_image (line 12454) | def insert_image(
method insert_link (line 12578) | def insert_link(page: 'Page', lnk: dict, mark: bool = True) -> None:
method insert_text (line 12586) | def insert_text(
method insert_textbox (line 12635) | def insert_textbox(
method is_wrapped (line 12708) | def is_wrapped(self):
method language (line 12713) | def language(self):
method links (line 12723) | def links(self, kinds=None):
method load_annot (line 12736) | def load_annot(self, ident: typing.Union[str, int]) -> Annot:
method load_links (line 12759) | def load_links(self):
method load_widget (line 12786) | def load_widget( self, xref):
method mediabox (line 12805) | def mediabox(self):
method mediabox_size (line 12816) | def mediabox_size(self):
method new_shape (line 12819) | def new_shape(self):
method read_contents (line 12829) | def read_contents(self):
method refresh (line 12833) | def refresh(self):
method replace_image (line 12841) | def replace_image(
method rotation (line 12880) | def rotation(self):
method rotation_matrix (line 12889) | def rotation_matrix(self) -> Matrix:
method run (line 12893) | def run(self, dw, m):
method search_for (line 12900) | def search_for(
method set_artbox (line 12941) | def set_artbox(self, rect):
method set_bleedbox (line 12945) | def set_bleedbox(self, rect):
method set_contents (line 12949) | def set_contents(self, xref):
method set_cropbox (line 12963) | def set_cropbox(self, rect):
method set_language (line 12967) | def set_language(self, language=None):
method set_mediabox (line 12982) | def set_mediabox(self, rect):
method set_rotation (line 12997) | def set_rotation(self, rotation):
method set_trimbox (line 13004) | def set_trimbox(self, rect):
method show_pdf_page (line 13008) | def show_pdf_page(
method transformation_matrix (line 13133) | def transformation_matrix(self):
method trimbox (line 13152) | def trimbox(self):
method update_link (line 13160) | def update_link(page: 'Page', lnk: dict) -> None:
method widgets (line 13169) | def widgets(self, types=None):
method wrap_contents (line 13186) | def wrap_contents(self):
method write_text (line 13196) | def write_text(
method xref (line 13248) | def xref(self):
class Pixmap (line 13259) | class Pixmap:
method __init__ (line 13261) | def __init__(self, *args):
method __len__ (line 13541) | def __len__(self):
method __repr__ (line 13544) | def __repr__(self):
method _tobytes (line 13553) | def _tobytes(self, format_, jpg_quality):
method _writeIMG (line 13574) | def _writeIMG(self, filename, format_, jpg_quality):
method alpha (line 13585) | def alpha(self):
method clear_with (line 13589) | def clear_with(self, value=None, bbox=None):
method color_count (line 13598) | def color_count(self, colors=0, clip=None):
method color_topusage (line 13608) | def color_topusage(self, clip=None):
method colorspace (line 13624) | def colorspace(self):
method copy (line 13631) | def copy(self, src, bbox):
method digest (line 13642) | def digest(self):
method gamma_with (line 13647) | def gamma_with(self, gamma):
method h (line 13656) | def h(self):
method invert_irect (line 13660) | def invert_irect(self, bbox=None):
method irect (line 13674) | def irect(self):
method is_monochrome (line 13680) | def is_monochrome(self):
method is_unicolor (line 13685) | def is_unicolor(self):
method n (line 13707) | def n(self):
method pdfocr_save (line 13719) | def pdfocr_save(self, filename, compress=1, language=None, tessdata=No...
method pdfocr_tobytes (line 13740) | def pdfocr_tobytes(self, compress=True, language="eng", tessdata=None):
method pil_image (line 13761) | def pil_image(self):
method pil_save (line 13782) | def pil_save(self, *args, **kwargs):
method pil_tobytes (line 13797) | def pil_tobytes(self, *args, **kwargs):
method pixel (line 13814) | def pixel(self, x, y):
method samples (line 13833) | def samples(self)->bytes:
method samples_mv (line 13838) | def samples_mv(self):
method _samples_mv_release (line 13850) | def _samples_mv_release(self):
method samples_ptr (line 13855) | def samples_ptr(self):
method save (line 13858) | def save(self, filename, output=None, jpg_quality=95):
method set_alpha (line 13899) | def set_alpha(self, alphavalues=None, premultiply=1, opaque=None, matt...
method tobytes (line 13994) | def tobytes(self, output="png", jpg_quality=95):
method set_dpi (line 14024) | def set_dpi(self, xres, yres):
method set_origin (line 14030) | def set_origin(self, x, y):
method set_pixel (line 14036) | def set_pixel(self, x, y, color):
method set_rect (line 14061) | def set_rect(self, bbox, color):
method shrink (line 14076) | def shrink(self, factor):
method size (line 14088) | def size(self):
method stride (line 14093) | def stride(self):
method tint_with (line 14097) | def tint_with(self, black, white):
method w (line 14105) | def w(self):
method warp (line 14109) | def warp(self, quad, width, height):
method x (line 14118) | def x(self):
method xres (line 14123) | def xres(self):
method y (line 14128) | def y(self):
method yres (line 14133) | def yres(self):
method __del__ (line 14140) | def __del__(self):
class Point (line 14145) | class Point:
method __abs__ (line 14147) | def __abs__(self):
method __add__ (line 14150) | def __add__(self, p):
method __bool__ (line 14157) | def __bool__(self):
method __eq__ (line 14160) | def __eq__(self, p):
method __getitem__ (line 14165) | def __getitem__(self, i):
method __hash__ (line 14168) | def __hash__(self):
method __init__ (line 14171) | def __init__(self, *args, x=None, y=None):
method __len__ (line 14205) | def __len__(self):
method __mul__ (line 14208) | def __mul__(self, m):
method __neg__ (line 14217) | def __neg__(self):
method __nonzero__ (line 14220) | def __nonzero__(self):
method __pos__ (line 14223) | def __pos__(self):
method __repr__ (line 14226) | def __repr__(self):
method __setitem__ (line 14229) | def __setitem__(self, i, v):
method __sub__ (line 14237) | def __sub__(self, p):
method __truediv__ (line 14244) | def __truediv__(self, m):
method abs_unit (line 14254) | def abs_unit(self):
method distance_to (line 14262) | def distance_to(self, *args):
method transform (line 14312) | def transform(self, m):
method unit (line 14320) | def unit(self):
class Quad (line 14332) | class Quad:
method __abs__ (line 14334) | def __abs__(self):
method __add__ (line 14339) | def __add__(self, q):
method __bool__ (line 14346) | def __bool__(self):
method __contains__ (line 14349) | def __contains__(self, x):
method __eq__ (line 14370) | def __eq__(self, quad):
method __getitem__ (line 14380) | def __getitem__(self, i):
method __hash__ (line 14383) | def __hash__(self):
method __init__ (line 14386) | def __init__(self, *args, ul=None, ur=None, ll=None, lr=None):
method __len__ (line 14421) | def __len__(self):
method __mul__ (line 14424) | def __mul__(self, m):
method __neg__ (line 14429) | def __neg__(self):
method __nonzero__ (line 14432) | def __nonzero__(self):
method __pos__ (line 14435) | def __pos__(self):
method __repr__ (line 14438) | def __repr__(self):
method __setitem__ (line 14441) | def __setitem__(self, i, v):
method __sub__ (line 14450) | def __sub__(self, q):
method __truediv__ (line 14457) | def __truediv__(self, m):
method is_convex (line 14469) | def is_convex(self):
method is_empty (line 14491) | def is_empty(self):
method is_infinite (line 14499) | def is_infinite(self):
method is_rectangular (line 14504) | def is_rectangular(self):
method morph (line 14528) | def morph(self, p, m):
method rect (line 14539) | def rect(self):
method transform (line 14547) | def transform(self, m):
class Rect (line 14564) | class Rect:
method __abs__ (line 14566) | def __abs__(self):
method __add__ (line 14571) | def __add__(self, p):
method __and__ (line 14578) | def __and__(self, x):
method __bool__ (line 14586) | def __bool__(self):
method __contains__ (line 14589) | def __contains__(self, x):
method __eq__ (line 14606) | def __eq__(self, rect):
method __getitem__ (line 14611) | def __getitem__(self, i):
method __hash__ (line 14614) | def __hash__(self):
method __init__ (line 14617) | def __init__(self, *args, p0=None, p1=None, x0=None, y0=None, x1=None,...
method __len__ (line 14636) | def __len__(self):
method __mul__ (line 14639) | def __mul__(self, m):
method __neg__ (line 14646) | def __neg__(self):
method __nonzero__ (line 14649) | def __nonzero__(self):
method __or__ (line 14652) | def __or__(self, x):
method __pos__ (line 14662) | def __pos__(self):
method __repr__ (line 14665) | def __repr__(self):
method __setitem__ (line 14668) | def __setitem__(self, i, v):
method __sub__ (line 14678) | def __sub__(self, p):
method __truediv__ (line 14685) | def __truediv__(self, m):
method bottom_left (line 14696) | def bottom_left(self):
method bottom_right (line 14701) | def bottom_right(self):
method contains (line 14705) | def contains(self, x):
method height (line 14710) | def height(self):
method get_area (line 14713) | def get_area(self, *args) -> float:
method include_point (line 14717) | def include_point(self, p):
method include_rect (line 14724) | def include_rect(self, r):
method intersect (line 14739) | def intersect(self, r):
method intersects (line 14756) | def intersects(self, x):
method is_empty (line 14771) | def is_empty(self):
method is_infinite (line 14776) | def is_infinite(self):
method is_valid (line 14781) | def is_valid(self):
method morph (line 14785) | def morph(self, p, m):
method norm (line 14793) | def norm(self):
method normalize (line 14796) | def normalize(self):
method quad (line 14805) | def quad(self):
method round (line 14809) | def round(self):
method top_left (line 14814) | def top_left(self):
method top_right (line 14819) | def top_right(self):
method torect (line 14823) | def torect(self, r):
method transform (line 14835) | def transform(self, m):
method width (line 14843) | def width(self):
class Shape (line 14855) | class Shape:
method horizontal_angle (line 14859) | def horizontal_angle(C, P):
method __init__ (line 14878) | def __init__(self, page: Page):
method updateRect (line 14898) | def updateRect(self, x):
method draw_line (line 14919) | def draw_line(self, p1: point_like, p2: point_like) -> Point:
method draw_polyline (line 14933) | def draw_polyline(self, points: list) -> Point:
method draw_bezier (line 14947) | def draw_bezier(
method draw_oval (line 14970) | def draw_oval(self, tetra: typing.Union[quad_like, rect_like]) -> Point:
method draw_circle (line 14994) | def draw_circle(self, center: point_like, radius: float) -> Point:
method draw_curve (line 15002) | def draw_curve(
method draw_sector (line 15017) | def draw_sector(
method draw_rect (line 15091) | def draw_rect(self, rect: rect_like, *, radius=None) -> Point:
method draw_quad (line 15142) | def draw_quad(self, quad: quad_like) -> Point:
method draw_zigzag (line 15147) | def draw_zigzag(
method draw_squiggle (line 15176) | def draw_squiggle(
method insert_text (line 15216) | def insert_text(
method insert_textbox (line 15405) | def insert_textbox(
method finish (line 15729) | def finish(
method commit (line 15820) | def commit(self, overlay: bool = True) -> None:
class Story (line 15845) | class Story:
method __init__ (line 15847) | def __init__( self, html='', user_css=None, em=12, archive=None):
method add_header_ids (line 15857) | def add_header_ids(self):
method add_pdf_links (line 15877) | def add_pdf_links(document_or_stream, positions):
method body (line 15962) | def body(self):
method document (line 15966) | def document( self):
method draw (line 15970) | def draw( self, device, matrix=None):
method element_positions (line 15975) | def element_positions( self, function, args=None):
method place (line 16006) | def place( self, where, flags=0):
method reset (line 16015) | def reset( self):
method write (line 16018) | def write(self, writer, rectfn, positionfn=None, pagefn=None):
method write_stabilized (line 16058) | def write_stabilized(writer, contentfn, rectfn, user_css=None, em=12, ...
method write_stabilized_with_links (line 16090) | def write_stabilized_with_links(contentfn, rectfn, user_css=None, em=1...
method write_with_links (line 16105) | def write_with_links(self, rectfn, positionfn=None, pagefn=None):
class FitResult (line 16120) | class FitResult:
method __init__ (line 16141) | def __init__(self, big_enough=None, filled=None, more=None, numcalls...
method __repr__ (line 16149) | def __repr__(self):
method fit (line 16159) | def fit(self, fn, pmin=None, pmax=None, delta=0.001, verbose=False, fl...
method fit_scale (line 16313) | def fit_scale(self, rect, scale_min=0, scale_max=None, delta=0.001, ve...
method fit_height (line 16343) | def fit_height(self, width, height_min=0, height_max=None, origin=(0, ...
method fit_width (line 16371) | def fit_width(self, height, width_min=0, width_max=None, origin=(0, 0)...
class TextPage (line 16400) | class TextPage:
method __init__ (line 16402) | def __init__(self, *args):
method _extractText (line 16413) | def _extractText(self, format_):
method _getNewBlockList (line 16434) | def _getNewBlockList(self, page_dict, raw):
method _textpage_dict (line 16437) | def _textpage_dict(self, raw=False):
method extractBLOCKS (line 16442) | def extractBLOCKS(self):
method extractDICT (line 16494) | def extractDICT(self, cb=None, sort=False) -> dict:
method extractHTML (line 16506) | def extractHTML(self) -> str:
method extractIMGINFO (line 16510) | def extractIMGINFO(self, hashes=0):
method extractJSON (line 16558) | def extractJSON(self, cb=None, sort=False) -> str:
method extractRAWDICT (line 16580) | def extractRAWDICT(self, cb=None, sort=False) -> dict:
method extractRAWJSON (line 16592) | def extractRAWJSON(self, cb=None, sort=False) -> str:
method extractSelection (line 16613) | def extractSelection(self, pointa, pointb):
method extractText (line 16619) | def extractText(self, sort=False) -> str:
method extractTextbox (line 16627) | def extractTextbox(self, rect):
method extractWORDS (line 16635) | def extractWORDS(self, delimiters=None):
method extractXHTML (line 16691) | def extractXHTML(self) -> str:
method extractXML (line 16695) | def extractXML(self) -> str:
method poolsize (line 16699) | def poolsize(self):
method rect (line 16708) | def rect(self):
method search (line 16717) | def search(self, needle, hit_max=0, quads=1):
class TextWriter (line 16746) | class TextWriter:
method __init__ (line 16748) | def __init__(self, page_rect, opacity=1, color=None):
method _bbox (line 16766) | def _bbox(self):
method append (line 16771) | def append(self, pos, text, font=None, fontsize=11, language=None, rig...
method appendv (line 16815) | def appendv(self, pos, text, font=None, fontsize=11, language=None, sm...
method clean_rtl (line 16823) | def clean_rtl(self, text):
method fill_textbox (line 16869) | def fill_textbox(
method write_text (line 17095) | def write_text(self, page, color=None, opacity=-1, overlay=1, morph=No...
class IRect (line 17230) | class IRect:
method __add__ (line 17240) | def __add__(self, p):
method __and__ (line 17243) | def __and__(self, x):
method __contains__ (line 17246) | def __contains__(self, x):
method __eq__ (line 17249) | def __eq__(self, r):
method __getitem__ (line 17254) | def __getitem__(self, i):
method __hash__ (line 17257) | def __hash__(self):
method __init__ (line 17260) | def __init__(self, *args, p0=None, p1=None, x0=None, y0=None, x1=None,...
method __len__ (line 17263) | def __len__(self):
method __mul__ (line 17266) | def __mul__(self, m):
method __neg__ (line 17269) | def __neg__(self):
method __or__ (line 17272) | def __or__(self, x):
method __pos__ (line 17275) | def __pos__(self):
method __repr__ (line 17278) | def __repr__(self):
method __setitem__ (line 17281) | def __setitem__(self, i, v):
method __sub__ (line 17291) | def __sub__(self, p):
method __truediv__ (line 17294) | def __truediv__(self, m):
method bottom_left (line 17298) | def bottom_left(self):
method bottom_right (line 17303) | def bottom_right(self):
method height (line 17308) | def height(self):
method contains (line 17311) | def contains(self, x):
method get_area (line 17315) | def get_area(self, *args) -> float:
method include_point (line 17319) | def include_point(self, p):
method include_rect (line 17324) | def include_rect(self, r):
method intersect (line 17329) | def intersect(self, r):
method intersects (line 17333) | def intersects(self, x):
method is_empty (line 17337) | def is_empty(self):
method is_infinite (line 17342) | def is_infinite(self):
method is_valid (line 17347) | def is_valid(self):
method morph (line 17351) | def morph(self, p, m):
method norm (line 17359) | def norm(self):
method normalize (line 17362) | def normalize(self):
method quad (line 17371) | def quad(self):
method rect (line 17376) | def rect(self):
method top_left (line 17380) | def top_left(self):
method top_right (line 17385) | def top_right(self):
method torect (line 17389) | def torect(self, r):
method transform (line 17400) | def transform(self, m):
method width (line 17404) | def width(self):
class FileDataError (line 17719) | class FileDataError(RuntimeError):
class FileNotFoundError (line 17723) | class FileNotFoundError(RuntimeError):
class EmptyFileError (line 17727) | class EmptyFileError(FileDataError):
function _rect_area (line 18329) | def _rect_area(width, height, args):
function _read_samples (line 18336) | def _read_samples( pixmap, offset, n):
function _INRANGE (line 18348) | def _INRANGE(v, low, high):
function _remove_dest_range (line 18352) | def _remove_dest_range(pdf, numbers):
function ASSERT_PDF (line 18388) | def ASSERT_PDF(cond):
function EMPTY_IRECT (line 18394) | def EMPTY_IRECT():
function EMPTY_QUAD (line 18398) | def EMPTY_QUAD():
function EMPTY_RECT (line 18402) | def EMPTY_RECT():
function ENSURE_OPERATION (line 18406) | def ENSURE_OPERATION(pdf):
function INFINITE_IRECT (line 18411) | def INFINITE_IRECT():
function INFINITE_QUAD (line 18415) | def INFINITE_QUAD():
function INFINITE_RECT (line 18419) | def INFINITE_RECT():
function JM_BinFromBuffer (line 18423) | def JM_BinFromBuffer(buffer_):
function JM_EscapeStrFromStr (line 18432) | def JM_EscapeStrFromStr(c):
function JM_BufferFromBytes (line 18461) | def JM_BufferFromBytes(stream):
function JM_FLOAT_ITEM (line 18479) | def JM_FLOAT_ITEM(obj, idx):
function JM_INT_ITEM (line 18484) | def JM_INT_ITEM(obj, idx):
function JM_pixmap_from_page (line 18492) | def JM_pixmap_from_page(doc, page, ctm, cs, alpha, annots, clip):
function JM_StrAsChar (line 18562) | def JM_StrAsChar(x):
function JM_TUPLE (line 18568) | def JM_TUPLE(o: typing.Sequence) -> tuple:
function JM_TUPLE3 (line 18572) | def JM_TUPLE3(o: typing.Sequence) -> tuple:
function JM_UnicodeFromStr (line 18576) | def JM_UnicodeFromStr(s):
function JM_add_annot_id (line 18585) | def JM_add_annot_id(annot, stem):
function JM_add_oc_object (line 18606) | def JM_add_oc_object(pdf, ref, xref):
function JM_annot_border (line 18622) | def JM_annot_border(annot_obj):
function JM_annot_colors (line 18662) | def JM_annot_colors(annot_obj):
function JM_annot_set_border (line 18685) | def JM_annot_set_border( border, doc, annot_obj):
function make_escape (line 18739) | def make_escape(ch):
function JM_append_rune (line 18752) | def JM_append_rune(buff, ch):
function JM_append_word (line 18759) | def JM_append_word(lines, buff, wbbox, block_n, line_n, word_n):
function JM_add_layer_config (line 18778) | def JM_add_layer_config( pdf, name, creator, ON):
function JM_char_bbox (line 18808) | def JM_char_bbox(line, ch):
function JM_char_font_flags (line 18821) | def JM_char_font_flags(font, line, ch):
function JM_char_quad (line 18832) | def JM_char_quad(line, ch):
function JM_choice_options (line 18921) | def JM_choice_options(annot):
function JM_clear_pixmap_rect_with_value (line 18949) | def JM_clear_pixmap_rect_with_value(dest, value, b):
function JM_color_FromSequence (line 19004) | def JM_color_FromSequence(color):
function JM_color_count (line 19022) | def JM_color_count( pm, clip):
function JM_compress_buffer (line 19062) | def JM_compress_buffer(inbuffer):
function JM_copy_rectangle (line 19078) | def JM_copy_rectangle(page, area):
function JM_convert_to_pdf (line 19101) | def JM_convert_to_pdf(doc, fp, tp, rotate):
function JM_create_widget (line 19154) | def JM_create_widget(doc, page, type, fieldname):
function JM_cropbox (line 19204) | def JM_cropbox(page_obj):
function JM_cropbox_size (line 19224) | def JM_cropbox_size(page_obj):
function JM_derotate_page_matrix (line 19232) | def JM_derotate_page_matrix(page):
function JM_embed_file (line 19240) | def JM_embed_file(
function JM_embedded_clean (line 19277) | def JM_embedded_clean(pdf):
function JM_EscapeStrFromBuffer (line 19301) | def JM_EscapeStrFromBuffer(buff):
function JM_ensure_identity (line 19309) | def JM_ensure_identity(pdf):
function JM_ensure_ocproperties (line 19325) | def JM_ensure_ocproperties(pdf):
function JM_expand_fname (line 19343) | def JM_expand_fname(name):
function JM_field_type_text (line 19359) | def JM_field_type_text(wtype):
function JM_fill_pixmap_rect_with_color (line 19380) | def JM_fill_pixmap_rect_with_color(dest, col, b):
function JM_find_annot_irt (line 19403) | def JM_find_annot_irt(annot):
function JM_font_ascender (line 19430) | def JM_font_ascender(font):
function JM_font_descender (line 19440) | def JM_font_descender(font):
function JM_is_word_delimiter (line 19451) | def JM_is_word_delimiter(ch, delimiters):
function JM_is_rtl_char (line 19471) | def JM_is_rtl_char(ch):
function JM_font_name (line 19477) | def JM_font_name(font):
function JM_gather_fonts (line 19486) | def JM_gather_fonts(pdf, dict_, fontlist, stream_xref):
function JM_gather_forms (line 19523) | def JM_gather_forms(doc, dict_: mupdf.PdfObj, imagelist, stream_xref: int):
function JM_gather_images (line 19563) | def JM_gather_images(doc: mupdf.PdfDocument, dict_: mupdf.PdfObj, imagel...
function JM_get_annot_by_xref (line 19621) | def JM_get_annot_by_xref(page, xref):
function JM_get_annot_by_name (line 19641) | def JM_get_annot_by_name(page, name):
function JM_get_annot_id_list (line 19665) | def JM_get_annot_id_list(page):
function JM_get_annot_xref_list (line 19679) | def JM_get_annot_xref_list( page_obj):
function JM_get_annot_xref_list2 (line 19704) | def JM_get_annot_xref_list2(page):
function JM_get_border_style (line 19711) | def JM_get_border_style(style):
function JM_get_font (line 19727) | def JM_get_font(
function JM_get_fontbuffer (line 19789) | def JM_get_fontbuffer(doc, xref):
function JM_get_resource_properties (line 19844) | def JM_get_resource_properties(ref):
function JM_get_widget_by_xref (line 19866) | def JM_get_widget_by_xref( page, xref):
function JM_get_widget_properties (line 19883) | def JM_get_widget_properties(annot, Widget):
function JM_get_fontextension (line 20044) | def JM_get_fontextension(doc, xref):
function JM_get_ocg_arrays_imp (line 20088) | def JM_get_ocg_arrays_imp(arr):
function JM_get_ocg_arrays (line 20104) | def JM_get_ocg_arrays(conf):
function JM_get_page_labels (line 20137) | def JM_get_page_labels(liste, nums):
function JM_get_script (line 20150) | def JM_get_script(key):
function JM_have_operation (line 20181) | def JM_have_operation(pdf):
function JM_image_extension (line 20190) | def JM_image_extension(type_):
function JM_image_filter (line 20216) | def JM_image_filter(opaque, ctm, name, image):
function JM_image_profile (line 20225) | def JM_image_profile( imagedata, keep_image):
function JM_image_reporter (line 20269) | def JM_image_reporter(page):
function JM_fitz_config (line 20303) | def JM_fitz_config():
function JM_insert_contents (line 20342) | def JM_insert_contents(pdf, pageref, newcont, overlay):
function JM_insert_font (line 20372) | def JM_insert_font(pdf, bfname, fontfile, fontbuffer, set_simple, idx, w...
function JM_irect_from_py (line 20449) | def JM_irect_from_py(r):
function JM_listbox_value (line 20478) | def JM_listbox_value( annot):
function JM_make_annot_DA (line 20502) | def JM_make_annot_DA(annot, ncol, col, fontname, fontsize):
function JM_make_spanlist (line 20522) | def JM_make_spanlist(line_dict, line, raw, buff, tp_rect):
function _make_image_dict (line 20672) | def _make_image_dict(img, img_dict):
function JM_make_image_block (line 20714) | def JM_make_image_block(block, block_dict):
function JM_make_text_block (line 20727) | def JM_make_text_block(block, block_dict, raw, buff, tp_rect):
function JM_make_textpage_dict (line 20750) | def JM_make_textpage_dict(tp, page_dict, raw):
function JM_matrix_from_py (line 20783) | def JM_matrix_from_py(m):
function JM_mediabox (line 20798) | def JM_mediabox(page_obj):
function JM_merge_range (line 20827) | def JM_merge_range(
function JM_merge_resources (line 20881) | def JM_merge_resources( page, temp_res):
function JM_mupdf_warning (line 20947) | def JM_mupdf_warning( text):
function JM_mupdf_error (line 20956) | def JM_mupdf_error( text):
function JM_new_bbox_device (line 20962) | def JM_new_bbox_device(rc, inc_layers):
function JM_new_buffer_from_stext_page (line 20967) | def JM_new_buffer_from_stext_page(page):
function JM_new_javascript (line 20988) | def JM_new_javascript(pdf, value):
function JM_new_output_fileptr (line 21010) | def JM_new_output_fileptr(bio):
function JM_norm_rotation (line 21014) | def JM_norm_rotation(rotate):
function JM_object_to_buffer (line 21027) | def JM_object_to_buffer(what, compress, ascii):
function JM_outline_xrefs (line 21036) | def JM_outline_xrefs(obj, xrefs):
function JM_page_rotation (line 21061) | def JM_page_rotation(page):
function JM_pdf_obj_from_str (line 21073) | def JM_pdf_obj_from_str(doc, src):
function JM_pixmap_from_display_list (line 21087) | def JM_pixmap_from_display_list(
function JM_point_from_py (line 21132) | def JM_point_from_py(p):
function JM_print_stext_page_as_text (line 21155) | def JM_print_stext_page_as_text(res, page):
function JM_put_script (line 21198) | def JM_put_script(annot_obj, key1, key2, value):
function JM_py_from_irect (line 21231) | def JM_py_from_irect(r):
function JM_py_from_matrix (line 21235) | def JM_py_from_matrix(m):
function JM_py_from_point (line 21239) | def JM_py_from_point(p):
function JM_py_from_quad (line 21243) | def JM_py_from_quad(q):
function JM_py_from_rect (line 21255) | def JM_py_from_rect(r):
function JM_quad_from_py (line 21259) | def JM_quad_from_py(r):
function JM_read_contents (line 21304) | def JM_read_contents(pageref):
function JM_rect_from_py (line 21326) | def JM_rect_from_py(r):
function JM_rects_overlap (line 21349) | def JM_rects_overlap(a, b):
function JM_refresh_links (line 21360) | def JM_refresh_links( page):
function JM_rotate_page_matrix (line 21377) | def JM_rotate_page_matrix(page):
function JM_search_stext_page (line 21401) | def JM_search_stext_page(page, needle):
function JM_scan_resources (line 21474) | def JM_scan_resources(pdf, rsrc, liste, what, stream_xref, tracer):
function JM_set_choice_options (line 21515) | def JM_set_choice_options(annot, liste):
function JM_set_field_type (line 21543) | def JM_set_field_type(doc, obj, type):
function JM_set_object_value (line 21581) | def JM_set_object_value(obj, key, value):
function JM_set_ocg_arrays (line 21629) | def JM_set_ocg_arrays(conf, basestate, on, off, rbgroups, locked):
function JM_set_ocg_arrays_imp (line 21659) | def JM_set_ocg_arrays_imp(arr, list_):
function JM_set_resource_property (line 21670) | def JM_set_resource_property(ref, name, xref):
function JM_set_widget_properties (line 21691) | def JM_set_widget_properties(annot, Widget):
function JM_show_string_cs (line 21885) | def JM_show_string_cs(
function JM_UnicodeFromBuffer (line 21913) | def JM_UnicodeFromBuffer(buff):
function message_warning (line 21922) | def message_warning(text):
function JM_update_stream (line 21929) | def JM_update_stream(doc, obj, buffer_, compress):
function JM_xobject_from_page (line 21953) | def JM_xobject_from_page(pdfout, fsrcpage, xref, gmap):
function PySequence_Check (line 21988) | def PySequence_Check(s):
function PySequence_Size (line 21992) | def PySequence_Size(s):
function RAISEPY (line 22030) | def RAISEPY( msg, exc):
function PyUnicode_DecodeRawUnicodeEscape (line 22036) | def PyUnicode_DecodeRawUnicodeEscape(s, errors='strict'):
function CheckColor (line 22048) | def CheckColor(c: OptSeq):
function CheckFont (line 22059) | def CheckFont(page: Page, fontname: str) -> tuple:
function CheckFontInfo (line 22067) | def CheckFontInfo(doc: Document, xref: int) -> list:
function CheckMarkerArg (line 22075) | def CheckMarkerArg(quads: typing.Any) -> tuple:
function CheckMorph (line 22087) | def CheckMorph(o: typing.Any) -> bool:
function CheckParent (line 22099) | def CheckParent(o: typing.Any):
function CheckQuad (line 22105) | def CheckQuad(q: typing.Any) -> bool:
function CheckRect (line 22118) | def CheckRect(r: typing.Any) -> bool:
function ColorCode (line 22131) | def ColorCode(c: typing.Union[list, tuple, float, None], f: str) -> str:
function Page__add_text_marker (line 22149) | def Page__add_text_marker(self, quads, annot_type):
function PDF_NAME (line 22172) | def PDF_NAME(x):
function UpdateFontInfo (line 22186) | def UpdateFontInfo(doc: Document, info: typing.Sequence):
function args_match (line 22199) | def args_match(args, *types):
function calc_image_matrix (line 22224) | def calc_image_matrix(width, height, tr, rotate, keep):
function detect_super_script (line 22273) | def detect_super_script(line, ch):
function dir_str (line 22279) | def dir_str(x):
function getTJstr (line 22286) | def getTJstr(text: str, glyphs: typing.Union[list, tuple, None], simple:...
function get_pdf_str (line 22323) | def get_pdf_str(s: str) -> str:
function get_tessdata (line 22376) | def get_tessdata(tessdata=None):
function css_for_pymupdf_font (line 22446) | def css_for_pymupdf_font(
function get_text_length (line 22515) | def get_text_length(text: str, fontname: str ="helv", fontsize: float =1...
function image_profile (line 22557) | def image_profile(img: ByteString) -> dict:
function jm_append_merge (line 22579) | def jm_append_merge(dev):
function jm_bbox_add_rect (line 22650) | def jm_bbox_add_rect( dev, ctx, rect, code):
function jm_bbox_fill_image (line 22657) | def jm_bbox_fill_image( dev, ctx, image, ctm, alpha, color_params):
function jm_bbox_fill_image_mask (line 22663) | def jm_bbox_fill_image_mask( dev, ctx, image, ctm, colorspace, color, al...
function jm_bbox_fill_path (line 22671) | def jm_bbox_fill_path( dev, ctx, path, even_odd, ctm, colorspace, color,...
function jm_bbox_fill_shade (line 22680) | def jm_bbox_fill_shade( dev, ctx, shade, ctm, alpha, color_params):
function jm_bbox_stroke_text (line 22688) | def jm_bbox_stroke_text( dev, ctx, text, stroke, ctm, *args):
function jm_bbox_fill_text (line 22696) | def jm_bbox_fill_text( dev, ctx, text, ctm, *args):
function jm_bbox_ignore_text (line 22704) | def jm_bbox_ignore_text( dev, ctx, text, ctm):
function jm_bbox_stroke_path (line 22708) | def jm_bbox_stroke_path( dev, ctx, path, stroke, ctm, colorspace, color,...
function jm_checkquad (line 22716) | def jm_checkquad(dev):
function jm_checkrect (line 22755) | def jm_checkrect(dev):
function jm_trace_text (line 22804) | def jm_trace_text( dev, text, type_, ctm, colorspace, color, alpha, seqno):
function jm_trace_text_span (line 22813) | def jm_trace_text_span(dev, span, type_, ctm, colorspace, color, alpha, ...
function jm_lineart_color (line 22965) | def jm_lineart_color(colorspace, color):
function jm_lineart_drop_device (line 22993) | def jm_lineart_drop_device(dev, ctx):
function jm_lineart_fill_path (line 22999) | def jm_lineart_fill_path( dev, ctx, path, even_odd, ctm, colorspace, col...
function jm_lineart_fill_text (line 23038) | def jm_lineart_fill_text( dev, ctx, text, ctm, colorspace, color, alpha,...
function jm_lineart_ignore_text (line 23052) | def jm_lineart_ignore_text(dev, text, ctm):
class Walker (line 23058) | class Walker(mupdf.FzPathWalker2):
method __init__ (line 23060) | def __init__(self, dev):
method closepath (line 23068) | def closepath(self, ctx): # trace_close().
method curveto (line 23096) | def curveto(self, ctx, x1, y1, x2, y2, x3, y3): # trace_curveto().
method lineto (line 23123) | def lineto(self, ctx, x, y): # trace_lineto().
method moveto (line 23144) | def moveto(self, ctx, x, y): # trace_moveto().
function jm_lineart_path (line 23173) | def jm_lineart_path(dev, ctx, path):
function jm_lineart_stroke_path (line 23209) | def jm_lineart_stroke_path( dev, ctx, path, stroke, ctm, colorspace, col...
function jm_lineart_clip_path (line 23260) | def jm_lineart_clip_path(dev, ctx, path, even_odd, ctm, scissor):
function jm_lineart_clip_stroke_path (line 23281) | def jm_lineart_clip_stroke_path(dev, ctx, path, stroke, ctm, scissor):
function jm_lineart_clip_stroke_text (line 23301) | def jm_lineart_clip_stroke_text(dev, ctx, text, stroke, ctm, scissor):
function jm_lineart_clip_text (line 23308) | def jm_lineart_clip_text(dev, ctx, text, ctm, scissor):
function jm_lineart_clip_image_mask (line 23315) | def jm_lineart_clip_image_mask( dev, ctx, image, ctm, scissor):
function jm_lineart_pop_clip (line 23322) | def jm_lineart_pop_clip(dev, ctx):
function jm_lineart_begin_layer (line 23332) | def jm_lineart_begin_layer(dev, ctx, name):
function jm_lineart_end_layer (line 23339) | def jm_lineart_end_layer(dev, ctx):
function jm_lineart_begin_group (line 23343) | def jm_lineart_begin_group(dev, ctx, bbox, cs, isolated, knockout, blend...
function jm_lineart_end_group (line 23361) | def jm_lineart_end_group(dev, ctx):
function jm_lineart_stroke_text (line 23368) | def jm_lineart_stroke_text(dev, ctx, text, stroke, ctm, colorspace, colo...
function jm_dev_linewidth (line 23373) | def jm_dev_linewidth( dev, ctx, path, stroke, matrix, colorspace, color,...
function jm_increase_seqno (line 23378) | def jm_increase_seqno( dev, ctx, *vargs):
function planish_line (line 23386) | def planish_line(p1: point_like, p2: point_like) -> Matrix:
class JM_image_reporter_Filter (line 23402) | class JM_image_reporter_Filter(mupdf.PdfFilterOptions2):
method __init__ (line 23403) | def __init__(self):
method image_filter (line 23407) | def image_filter( self, ctx, ctm, name, image):
class JM_new_bbox_device_Device (line 23416) | class JM_new_bbox_device_Device(mupdf.FzDevice2):
method __init__ (line 23417) | def __init__(self, result, layers):
class JM_new_output_fileptr_Output (line 23447) | class JM_new_output_fileptr_Output(mupdf.FzOutput2):
method __init__ (line 23448) | def __init__(self, bio):
method seek (line 23456) | def seek( self, ctx, offset, whence):
method tell (line 23459) | def tell( self, ctx):
method truncate (line 23463) | def truncate( self, ctx):
method write (line 23466) | def write(self, ctx, data_raw, data_length):
function compute_scissor (line 23471) | def compute_scissor(dev):
class JM_new_lineart_device_Device (line 23489) | class JM_new_lineart_device_Device(mupdf.FzDevice2):
method __init__ (line 23494) | def __init__(self, out, clips, method):
class JM_new_texttrace_device (line 23572) | class JM_new_texttrace_device(mupdf.FzDevice2):
method __init__ (line 23577) | def __init__(self, out):
function ConversionHeader (line 23626) | def ConversionHeader(i: str, filename: OptStr ="unknown"):
function ConversionTrailer (line 23678) | def ConversionTrailer(i: str):
function annot_preprocess (line 23699) | def annot_preprocess(page: "Page") -> int:
function annot_postprocess (line 23714) | def annot_postprocess(page: "Page", annot: "Annot") -> None:
function canon (line 23727) | def canon(c):
function chartocanon (line 23740) | def chartocanon(s):
function dest_is_valid (line 23747) | def dest_is_valid(o, page_count, page_object_nums, names_list):
function dest_is_valid_page (line 23775) | def dest_is_valid_page(obj, page_object_nums, pagecount):
function find_string (line 23786) | def find_string(s, needle):
function get_pdf_now (line 23796) | def get_pdf_now() -> str:
class ElementPosition (line 23814) | class ElementPosition(object):
method __init__ (line 23817) | def __init__(self):
function make_story_elpos (line 23821) | def make_story_elpos():
function get_highlight_selection (line 23825) | def get_highlight_selection(page, start: point_like =None, stop: point_l...
function glyph_name_to_unicode (line 23898) | def glyph_name_to_unicode(name: str) -> int:
function hdist (line 23908) | def hdist(dir, a, b):
function make_table (line 23914) | def make_table(rect: rect_like =(0, 0, 1, 1), cols: int =1, rows: int =1...
function util_ensure_widget_calc (line 23957) | def util_ensure_widget_calc(annot):
function util_make_rect (line 23985) | def util_make_rect( *args, p0=None, p1=None, x0=None, y0=None, x1=None, ...
function util_make_irect (line 24069) | def util_make_irect( *args, p0=None, p1=None, x0=None, y0=None, x1=None,...
function util_round_rect (line 24083) | def util_round_rect( rect):
function util_transform_rect (line 24087) | def util_transform_rect( rect, matrix):
function util_intersect_rect (line 24093) | def util_intersect_rect( r1, r2):
function util_is_point_in_rect (line 24102) | def util_is_point_in_rect( p, r):
function util_include_point_in_rect (line 24108) | def util_include_point_in_rect( r, p):
function util_point_in_quad (line 24117) | def util_point_in_quad( P, Q):
function util_transform_point (line 24123) | def util_transform_point( point, matrix):
function util_union_rect (line 24132) | def util_union_rect( r1, r2):
function util_concat_matrix (line 24141) | def util_concat_matrix( m1, m2):
function util_invert_matrix (line 24150) | def util_invert_matrix(matrix):
function util_measure_string (line 24189) | def util_measure_string( text, fontname, fontsize, encoding):
function util_sine_between (line 24211) | def util_sine_between(C, P, Q):
function util_hor_matrix (line 24225) | def util_hor_matrix(C, P):
function match_string (line 24241) | def match_string(h0, n0):
function on_highlight_char (line 24272) | def on_highlight_char(hits, line, ch):
function page_merge (line 24297) | def page_merge(doc_des, doc_src, page_from, page_to, rotate, links, copy...
function paper_rect (line 24368) | def paper_rect(s: str) -> Rect:
function paper_size (line 24375) | def paper_size(s: str) -> tuple:
function paper_sizes (line 24395) | def paper_sizes():
function pdf_lookup_page_loc (line 24451) | def pdf_lookup_page_loc(doc, needle):
function pdfobj_string (line 24455) | def pdfobj_string(o, prefix=''):
function repair_mono_font (line 24505) | def repair_mono_font(page: "Page", font: "Font") -> None:
function sRGB_to_pdf (line 24537) | def sRGB_to_pdf(srgb: int) -> tuple:
function sRGB_to_rgb (line 24551) | def sRGB_to_rgb(srgb: int) -> tuple:
function string_in_names_list (line 24569) | def string_in_names_list(p, names_list):
function strip_outline (line 24578) | def strip_outline(doc, outlines, page_count, page_object_nums, names_list):
function strip_outlines (line 24622) | def strip_outlines(doc, outlines, page_count, page_object_nums, names_li...
function unicode_to_glyph_name (line 24650) | def unicode_to_glyph_name(ch: int) -> str:
function vdist (line 24662) | def vdist(dir, a, b):
function apply_pages (line 24668) | def apply_pages(
function get_text (line 24798) | def get_text(
class TOOLS (line 24862) | class TOOLS:
method _derotate_matrix (line 24867) | def _derotate_matrix(page):
method _fill_widget (line 24874) | def _fill_widget(annot, widget):
method _get_all_contents (line 24898) | def _get_all_contents(page):
method _insert_contents (line 24905) | def _insert_contents(page, newcont, overlay=1):
method _le_annot_parms (line 24914) | def _le_annot_parms(annot, p1, p2, fill_color):
method _le_butt (line 24952) | def _le_butt(annot, p1, p2, lr, fill_color):
method _le_circle (line 24968) | def _le_circle(annot, p1, p2, lr, fill_color):
method _le_closedarrow (line 24982) | def _le_closedarrow(annot, p1, p2, lr, fill_color):
method _le_diamond (line 25002) | def _le_diamond(annot, p1, p2, lr, fill_color):
method _le_openarrow (line 25024) | def _le_openarrow(annot, p1, p2, lr, fill_color):
method _le_rclosedarrow (line 25044) | def _le_rclosedarrow(annot, p1, p2, lr, fill_color):
method _le_ropenarrow (line 25064) | def _le_ropenarrow(annot, p1, p2, lr, fill_color):
method _le_slash (line 25084) | def _le_slash(annot, p1, p2, lr, fill_color):
method _le_square (line 25100) | def _le_square(annot, p1, p2, lr, fill_color):
method _oval_string (line 25122) | def _oval_string(p1, p2, p3, p4):
method _parse_da (line 25150) | def _parse_da(annot):
method _reset_widget (line 25205) | def _reset_widget(annot):
method _rotate_matrix (line 25212) | def _rotate_matrix(page):
method _save_widget (line 25219) | def _save_widget(annot, widget):
method _update_da (line 25222) | def _update_da(annot, da_str):
method gen_id (line 25238) | def gen_id():
method glyph_cache_empty (line 25244) | def glyph_cache_empty():
method image_profile (line 25251) | def image_profile(stream, keep_image=0):
method mupdf_display_errors (line 25258) | def mupdf_display_errors(on=None):
method mupdf_display_warnings (line 25268) | def mupdf_display_warnings(on=None):
method mupdf_version (line 25278) | def mupdf_version():
method mupdf_warnings (line 25283) | def mupdf_warnings(reset=1):
method reset_mupdf_warnings (line 25295) | def reset_mupdf_warnings():
method set_aa_level (line 25300) | def set_aa_level(level):
method set_annot_stem (line 25307) | def set_annot_stem( stem=None):
method set_font_width (line 25318) | def set_font_width(doc, xref, width):
method set_graphics_min_line_width (line 25336) | def set_graphics_min_line_width(min_line_width):
method set_icc (line 25343) | def set_icc( on=0):
method set_low_memory (line 25354) | def set_low_memory( on=None):
method set_small_glyph_heights (line 25361) | def set_small_glyph_heights(on=None):
method set_subset_fontnames (line 25370) | def set_subset_fontnames(on=None):
method show_aa_level (line 25381) | def show_aa_level():
method store_maxsize (line 25392) | def store_maxsize():
method store_shrink (line 25400) | def store_shrink(percent):
method store_size (line 25412) | def store_size():
method unset_quad_corrections (line 25420) | def unset_quad_corrections(on=None):
function _atexit (line 25459) | def _atexit():
function colors_pdf_dict (line 25485) | def colors_pdf_dict():
function colors_wx_list (line 25494) | def colors_wx_list():
function _mupdf_devel (line 25503) | def _mupdf_devel(make_links=True):
class FitzDeprecation (line 25596) | class FitzDeprecation(DeprecationWarning):
function restore_aliases (line 25599) | def restore_aliases():
FILE: src/__main__.py
function mycenter (line 17) | def mycenter(x):
function recoverpix (line 21) | def recoverpix(doc, item):
function open_file (line 57) | def open_file(filename, password, show=False, pdf=True):
function print_dict (line 79) | def print_dict(item):
function print_xref (line 87) | def print_xref(doc, xref):
function get_list (line 110) | def get_list(rlist, limit, what="page"):
function show (line 157) | def show(args):
function clean (line 220) | def clean(args):
function doc_join (line 267) | def doc_join(args):
function embedded_copy (line 288) | def embedded_copy(args):
function embedded_del (line 328) | def embedded_del(args):
function embedded_get (line 347) | def embedded_get(args):
function embedded_add (line 368) | def embedded_add(args):
function embedded_upd (line 402) | def embedded_upd(args):
function embedded_list (line 452) | def embedded_list(args):
function extract_objects (line 489) | def extract_objects(args):
function page_simple (line 555) | def page_simple(page, textout, GRID, fontsize, noformfeed, skip_empty, f...
function page_blocksort (line 567) | def page_blocksort(page, textout, GRID, fontsize, noformfeed, skip_empty...
function page_layout (line 581) | def page_layout(page, textout, GRID, fontsize, noformfeed, skip_empty, f...
function gettext (line 806) | def gettext(args):
function _internal (line 839) | def _internal(args):
function main (line 843) | def main():
FILE: src/_apply_pages.py
class _worker_State (line 11) | class _worker_State:
function _worker_init (line 16) | def _worker_init(
function _stats_write (line 37) | def _stats_write(t, label):
function _worker_fn (line 43) | def _worker_fn(page_number):
function _multiprocessing (line 71) | def _multiprocessing(
function _fork (line 98) | def _fork(
FILE: src/pipcl.py
class Package (line 58) | class Package:
method __init__ (line 325) | def __init__(self,
method build_wheel (line 663) | def build_wheel(self,
method build_sdist (line 810) | def build_sdist(self,
method wheel_tag_string (line 896) | def wheel_tag_string(self):
method tag_python (line 902) | def tag_python(self):
method tag_abi (line 913) | def tag_abi(self):
method tag_platform (line 933) | def tag_platform(self):
method wheel_name (line 969) | def wheel_name(self):
method wheel_name_match (line 974) | def wheel_name_match(self, wheel):
method _entry_points_text (line 1019) | def _entry_points_text(self):
method _call_fn_build (line 1030) | def _call_fn_build( self, config_settings=None):
method _argv_clean (line 1067) | def _argv_clean(self, all_):
method install (line 1087) | def install(self, record_path=None, root=None):
method _argv_dist_info (line 1155) | def _argv_dist_info(self, root):
method _argv_egg_info (line 1169) | def _argv_egg_info(self, egg_base):
method _write_info (line 1178) | def _write_info(self, dirpath=None):
method handle_argv (line 1202) | def handle_argv(self, argv):
method __str__ (line 1415) | def __str__(self):
method _dist_info_dir (line 1449) | def _dist_info_dir( self):
method _metainfo (line 1452) | def _metainfo(self):
method _path_relative_to_root (line 1525) | def _path_relative_to_root(self, path, assert_within_root=True):
method _fromto (line 1548) | def _fromto(self, p):
function build_extension (line 1600) | def build_extension(
function base_compiler (line 1980) | def base_compiler(vs=None, pythonflags=None, cpp=False, use_env=True):
function base_linker (line 2030) | def base_linker(vs=None, pythonflags=None, cpp=False, use_env=True):
function git_info (line 2074) | def git_info( directory):
function git_items (line 2102) | def git_items( directory, submodules=False):
function git_get (line 2141) | def git_get(
function run (line 2290) | def run(
function darwin (line 2428) | def darwin():
function windows (line 2431) | def windows():
function wasm (line 2434) | def wasm():
function pyodide (line 2437) | def pyodide():
function linux (line 2440) | def linux():
function openbsd (line 2443) | def openbsd():
function show_system (line 2447) | def show_system():
class PythonFlags (line 2497) | class PythonFlags:
method __init__ (line 2511) | def __init__(self):
function macos_add_cross_flags (line 2604) | def macos_add_cross_flags(command):
function macos_patch (line 2620) | def macos_patch( library, *sublibraries):
function _macos_fixup_platform_tag (line 2664) | def _macos_fixup_platform_tag(tag):
function _command_lines (line 2701) | def _command_lines( command):
function cpu_bits (line 2723) | def cpu_bits():
function _cpu_name (line 2727) | def _cpu_name():
function run_if (line 2735) | def run_if( command, out, *prerequisites, caller=1):
function fs_find_in_paths (line 2968) | def fs_find_in_paths( name, paths=None, verbose=False):
function _get_prerequisites (line 2997) | def _get_prerequisites(path):
function _fs_mtime_newest (line 3013) | def _fs_mtime_newest( path):
function _flags (line 3030) | def _flags( items, prefix='', quote=''):
function _fs_mtime (line 3046) | def _fs_mtime( filename, default=0):
function _normalise (line 3056) | def _normalise(name):
function _normalise2 (line 3061) | def _normalise2(name):
function _assert_version_pep_440 (line 3066) | def _assert_version_pep_440(version):
function verbose (line 3076) | def verbose(level=None):
function log_line_numbers (line 3088) | def log_line_numbers(yes):
function log (line 3095) | def log(text='', caller=1):
function log0 (line 3098) | def log0(text='', caller=1):
function log1 (line 3101) | def log1(text='', caller=1):
function log2 (line 3104) | def log2(text='', caller=1):
function _log (line 3107) | def _log(text, level, caller):
function relpath (line 3121) | def relpath(path, start=None, allow_up=True):
function _so_suffix (line 3147) | def _so_suffix(use_so_versioning=True):
function get_soname (line 3175) | def get_soname(path):
function current_py_limited_api (line 3201) | def current_py_limited_api():
function install_dir (line 3209) | def install_dir(root=None):
class _Record (line 3235) | class _Record:
method __init__ (line 3240) | def __init__(self):
method add_content (line 3243) | def add_content(self, content, to_, verbose=True):
method add_file (line 3261) | def add_file(self, from_, to_):
method get (line 3267) | def get(self, record_path=None):
class NewFiles (line 3280) | class NewFiles:
method __init__ (line 3285) | def __init__(self, glob_pattern):
method get (line 3289) | def get(self):
method get_n (line 3302) | def get_n(self, n):
method get_one (line 3310) | def get_one(self):
method _file_id (line 3316) | def _file_id(self, path):
method _items (line 3324) | def _items(self):
function swig_get (line 3332) | def swig_get(swig, quick, swig_local='pipcl-swig-git'):
function macos_add_brew_path (line 3439) | def macos_add_brew_path(package, env=None, gnubin=True):
function _show_dict (line 3481) | def _show_dict(d):
function show_sysconfig (line 3488) | def show_sysconfig():
function sysconfig_python_flags (line 3499) | def sysconfig_python_flags():
function venv_in (line 3524) | def venv_in(path=None):
function venv_run (line 3535) | def venv_run(args, path, recreate=True, clean=False):
FILE: src/table.py
function rect_in_rect (line 115) | def rect_in_rect(inner, outer):
function chars_in_rect (line 126) | def chars_in_rect(CHARS, rect):
function _iou (line 138) | def _iou(r1, r2):
function intersects_words_h (line 150) | def intersects_words_h(bbox, y, word_rects) -> bool:
function get_table_dict_from_rect (line 157) | def get_table_dict_from_rect(textpage, rect):
function make_table_from_bbox (line 164) | def make_table_from_bbox(textpage, word_rects, rect):
function extract_cells (line 223) | def extract_cells(textpage, cell, markdown=False):
class UnsetFloat (line 332) | class UnsetFloat(float):
function to_list (line 376) | def to_list(collection) -> list:
class TextMap (line 388) | class TextMap:
method __init__ (line 394) | def __init__(self, tuples=None) -> None:
method match_to_dict (line 398) | def match_to_dict(
class WordMap (line 426) | class WordMap:
method __init__ (line 431) | def __init__(self, tuples) -> None:
method to_textmap (line 434) | def to_textmap(
class WordExtractor (line 587) | class WordExtractor:
method __init__ (line 588) | def __init__(
method merge_chars (line 617) | def merge_chars(self, ordered_chars: list):
method char_begins_new_word (line 654) | def char_begins_new_word(
method iter_chars_to_words (line 729) | def iter_chars_to_words(self, ordered_chars):
method iter_sort_chars (line 760) | def iter_sort_chars(self, chars):
method iter_extract_tuples (line 784) | def iter_extract_tuples(self, chars):
method extract_wordmap (line 794) | def extract_wordmap(self, chars) -> WordMap:
method extract_words (line 797) | def extract_words(self, chars: list) -> list:
function extract_words (line 802) | def extract_words(chars: list, **kwargs) -> list:
function chars_to_textmap (line 810) | def chars_to_textmap(chars: list, **kwargs) -> TextMap:
function extract_text (line 824) | def extract_text(chars: list, **kwargs) -> str:
function collate_line (line 857) | def collate_line(
function dedupe_chars (line 871) | def dedupe_chars(chars: list, tolerance=1) -> list:
function line_to_edge (line 894) | def line_to_edge(line):
function rect_to_edges (line 900) | def rect_to_edges(rect) -> list:
function curve_to_edges (line 940) | def curve_to_edges(curve) -> list:
function obj_to_edges (line 958) | def obj_to_edges(obj) -> list:
function filter_edges (line 968) | def filter_edges(
function cluster_list (line 986) | def cluster_list(xs, tolerance=0) -> list:
function make_cluster_dict (line 1006) | def make_cluster_dict(values, tolerance) -> dict:
function cluster_objects (line 1016) | def cluster_objects(xs, key_fn, tolerance) -> list:
function move_object (line 1032) | def move_object(obj, axis: str, value):
function snap_objects (line 1054) | def snap_objects(objs, attr: str, tolerance) -> list:
function snap_edges (line 1066) | def snap_edges(
function resize_object (line 1084) | def resize_object(obj, key: str, value):
function join_edge_group (line 1111) | def join_edge_group(edges, orientation: str, tolerance=DEFAULT_JOIN_TOLE...
function merge_edges (line 1138) | def merge_edges(
function bbox_to_rect (line 1171) | def bbox_to_rect(bbox) -> dict:
function objects_to_rect (line 1179) | def objects_to_rect(objects) -> dict:
function merge_bboxes (line 1188) | def merge_bboxes(bboxes):
function objects_to_bbox (line 1197) | def objects_to_bbox(objects):
function words_to_edges_h (line 1205) | def words_to_edges_h(words, word_threshold: int = DEFAULT_MIN_WORDS_HORI...
function get_bbox_overlap (line 1246) | def get_bbox_overlap(a, b):
function words_to_edges_v (line 1261) | def words_to_edges_v(words, word_threshold: int = DEFAULT_MIN_WORDS_VERT...
function edges_to_intersections (line 1322) | def edges_to_intersections(edges, x_tolerance=1, y_tolerance=1) -> dict:
function obj_to_bbox (line 1347) | def obj_to_bbox(obj):
function intersections_to_cells (line 1354) | def intersections_to_cells(intersections):
function cells_to_tables (line 1416) | def cells_to_tables(page, cells) -> list:
class CellGroup (line 1498) | class CellGroup:
method __init__ (line 1499) | def __init__(self, cells):
class TableRow (line 1509) | class TableRow(CellGroup):
class TableHeader (line 1513) | class TableHeader:
method __init__ (line 1516) | def __init__(self, bbox, cells, names, above):
class Table (line 1523) | class Table:
method __init__ (line 1524) | def __init__(self, page, cells):
method bbox (line 1531) | def bbox(self):
method rows (line 1541) | def rows(self) -> list:
method row_count (line 1552) | def row_count(self) -> int: # PyMuPDF extension
method col_count (line 1556) | def col_count(self) -> int: # PyMuPDF extension
method extract (line 1559) | def extract(self, **kwargs) -> list:
method to_markdown (line 1597) | def to_markdown(self, clean=False, fill_empty=True):
method to_pandas (line 1667) | def to_pandas(self, **kwargs):
method _get_header (line 1703) | def _get_header(self, y_tolerance=3):
class TableSettings (line 1933) | class TableSettings:
method __post_init__ (line 1952) | def __post_init__(self) -> "TableSettings":
method resolve (line 2006) | def resolve(cls, settings=None):
class TableFinder (line 2025) | class TableFinder:
method __init__ (line 2036) | def __init__(self, page, settings=None):
method get_edges (line 2052) | def get_edges(self) -> list:
method __getitem__ (line 2151) | def __getitem__(self, i):
function make_chars (line 2181) | def make_chars(page, clip=None):
function make_edges (line 2246) | def make_edges(page, clip=None, tset=None, paths=None, add_lines=None, a...
function page_rotation_set0 (line 2536) | def page_rotation_set0(page):
function page_rotation_reset (line 2580) | def page_rotation_reset(page, xref, rot, mediabox):
function find_tables (line 2593) | def find_tables(
FILE: src/utils.py
function get_text_blocks (line 48) | def get_text_blocks(
function get_text_words (line 82) | def get_text_words(
function get_sorted_text (line 161) | def get_sorted_text(
function get_textbox (line 278) | def get_textbox(
function get_text_selection (line 294) | def get_text_selection(
function get_textpage_ocr (line 313) | def get_textpage_ocr(
function get_text (line 459) | def get_text(
function getLinkDict (line 568) | def getLinkDict(ln, document=None) -> dict:
function getDestStr (line 627) | def getDestStr(xref: int, ddict: dict) -> str:
function getLinkText (line 685) | def getLinkText(page: pymupdf.Page, lnk: dict) -> str:
function getColorList (line 782) | def getColorList() -> list:
function getColorInfoList (line 790) | def getColorInfoList() -> list:
function getColor (line 800) | def getColor(name: str) -> tuple:
function getColorHSV (line 809) | def getColorHSV(name: str) -> tuple:
function _get_font_properties (line 848) | def _get_font_properties(doc: pymupdf.Document, xref: int) -> tuple:
function _show_fz_text (line 885) | def _show_fz_text( text):
function rule_dict (line 920) | def rule_dict(item):
function get_label_pno (line 954) | def get_label_pno(pgNo, labels):
function construct_label (line 975) | def construct_label(style, prefix, pno) -> str:
function integerToLetter (line 994) | def integerToLetter(i) -> str:
function integerToRoman (line 1012) | def integerToRoman(num: int) -> str:
function recover_bbox_quad (line 1046) | def recover_bbox_quad(line_dir: tuple, span: dict, bbox: tuple) -> pymup...
function recover_quad (line 1096) | def recover_quad(line_dir: tuple, span: dict) -> pymupdf.Quad:
function recover_line_quad (line 1112) | def recover_line_quad(line: dict, spans: list = None) -> pymupdf.Quad:
function recover_span_quad (line 1157) | def recover_span_quad(line_dir: tuple, span: dict, chars: list = None) -...
function recover_char_quad (line 1202) | def recover_char_quad(line_dir: tuple, span: dict, char: dict) -> pymupd...
FILE: src/wdev.py
class WindowsVS (line 17) | class WindowsVS:
method __init__ (line 37) | def __init__(
method description_ml (line 191) | def description_ml( self, indent=''):
method __repr__ (line 210) | def __repr__( self):
function _vs_pattern (line 229) | def _vs_pattern(year=None, grade=None):
function windows_vs_multiple (line 233) | def windows_vs_multiple(year=None, grade=None, verbose=0):
class WindowsCpu (line 247) | class WindowsCpu:
method __init__ (line 263) | def __init__(self, name=None):
method __repr__ (line 282) | def __repr__(self):
class WindowsPython (line 286) | class WindowsPython:
method __init__ (line 308) | def __init__( self, cpu=None, version=None, verbose=True):
method description_ml (line 394) | def description_ml(self, indent=''):
method __repr__ (line 404) | def __repr__(self):
function _cpu_name (line 411) | def _cpu_name():
function _log (line 420) | def _log(text='', caller=1):
FILE: src_classic/__init__.py
function message (line 22) | def message(text=''):
function cleanup_tools (line 57) | def cleanup_tools(TOOLS):
function v_str_to_tuple (line 70) | def v_str_to_tuple(s):
function v_tuple_to_string (line 73) | def v_tuple_to_string(t):
class FitzDeprecation (line 182) | class FitzDeprecation(DeprecationWarning):
function restore_aliases (line 186) | def restore_aliases():
FILE: src_classic/__main__.py
function recoverpix (line 25) | def recoverpix(doc, item):
function open_file (line 61) | def open_file(filename, password, show=False, pdf=True):
function print_dict (line 80) | def print_dict(item):
function print_xref (line 89) | def print_xref(doc, xref):
function get_list (line 112) | def get_list(rlist, limit, what="page"):
function show (line 159) | def show(args):
function clean (line 222) | def clean(args):
function doc_join (line 269) | def doc_join(args):
function embedded_copy (line 290) | def embedded_copy(args):
function embedded_del (line 330) | def embedded_del(args):
function embedded_get (line 349) | def embedded_get(args):
function embedded_add (line 365) | def embedded_add(args):
function embedded_upd (line 398) | def embedded_upd(args):
function embedded_list (line 447) | def embedded_list(args):
function extract_objects (line 483) | def extract_objects(args):
function page_simple (line 551) | def page_simple(page, textout, GRID, fontsize, noformfeed, skip_empty, f...
function page_blocksort (line 563) | def page_blocksort(page, textout, GRID, fontsize, noformfeed, skip_empty...
function page_layout (line 577) | def page_layout(page, textout, GRID, fontsize, noformfeed, skip_empty, f...
function gettext (line 802) | def gettext(args):
function main (line 837) | def main():
FILE: src_classic/utils.py
function write_text (line 47) | def write_text(page: Page, **kwargs) -> None:
function show_pdf_page (line 117) | def show_pdf_page(*args, **kwargs) -> int:
function replace_image (line 246) | def replace_image(page: Page, xref: int, *, filename=None, pixmap=None, ...
function delete_image (line 277) | def delete_image(page: Page, xref: int):
function insert_image (line 291) | def insert_image(page, rect, **kwargs):
function search_for (line 426) | def search_for(*args, **kwargs) -> list:
function search_page_for (line 466) | def search_page_for(
function get_text_blocks (line 500) | def get_text_blocks(
function get_text_words (line 539) | def get_text_words(
function get_textbox (line 575) | def get_textbox(
function get_text_selection (line 591) | def get_text_selection(
function get_textpage_ocr (line 610) | def get_textpage_ocr(
function get_image_info (line 686) | def get_image_info(page: Page, hashes: bool = False, xrefs: bool = False...
function get_image_rects (line 724) | def get_image_rects(page: Page, name, transform=False) -> list:
function get_text (line 761) | def get_text(
function get_page_text (line 857) | def get_page_text(
function get_pixmap (line 879) | def get_pixmap(
function get_page_pixmap (line 922) | def get_page_pixmap(
function getLinkDict (line 955) | def getLinkDict(ln) -> dict:
function get_links (line 1002) | def get_links(page: Page) -> list:
function get_toc (line 1025) | def get_toc(
function del_toc_item (line 1081) | def del_toc_item(
function set_toc_item (line 1090) | def set_toc_item(
function get_area (line 1187) | def get_area(*args) -> float:
function set_metadata (line 1199) | def set_metadata(doc: Document, m: dict) -> None:
function getDestStr (line 1258) | def getDestStr(xref: int, ddict: dict) -> str:
function set_toc (line 1316) | def set_toc(
function do_links (line 1493) | def do_links(
function getLinkText (line 1613) | def getLinkText(page: Page, lnk: dict) -> str:
function delete_widget (line 1690) | def delete_widget(page: Page, widget: Widget) -> Widget:
function update_link (line 1706) | def update_link(page: Page, lnk: dict) -> None:
function insert_link (line 1717) | def insert_link(page: Page, lnk: dict, mark: bool = True) -> None:
function insert_textbox (line 1727) | def insert_textbox(
function insert_text (line 1797) | def insert_text(
function new_page (line 1843) | def new_page(
function insert_page (line 1862) | def insert_page(
function draw_line (line 1893) | def draw_line(
function draw_squiggle (line 1928) | def draw_squiggle(
function draw_zigzag (line 1964) | def draw_zigzag(
function draw_rect (line 2000) | def draw_rect(
function draw_quad (line 2036) | def draw_quad(
function draw_polyline (line 2071) | def draw_polyline(
function draw_circle (line 2108) | def draw_circle(
function draw_oval (line 2143) | def draw_oval(
function draw_curve (line 2178) | def draw_curve(
function draw_bezier (line 2217) | def draw_bezier(
function draw_sector (line 2257) | def draw_sector(
function getColorList (line 2318) | def getColorList() -> list:
function getColorInfoList (line 2327) | def getColorInfoList() -> list:
function getColorInfoDict (line 2882) | def getColorInfoDict() -> dict:
function getColor (line 2889) | def getColor(name: str) -> tuple:
function getColorHSV (line 2902) | def getColorHSV(name: str) -> tuple:
function _get_font_properties (line 2940) | def _get_font_properties(doc: Document, xref: int) -> tuple:
function get_char_widths (line 2975) | def get_char_widths(
class Shape (line 3073) | class Shape(object):
method horizontal_angle (line 3077) | def horizontal_angle(C, P):
method __init__ (line 3096) | def __init__(self, page: Page):
method updateRect (line 3116) | def updateRect(self, x):
method draw_line (line 3137) | def draw_line(self, p1: point_like, p2: point_like) -> Point:
method draw_polyline (line 3151) | def draw_polyline(self, points: list) -> Point:
method draw_bezier (line 3165) | def draw_bezier(
method draw_oval (line 3189) | def draw_oval(self, tetra: typing.Union[quad_like, rect_like]) -> Point:
method draw_circle (line 3213) | def draw_circle(self, center: point_like, radius: float) -> Point:
method draw_curve (line 3221) | def draw_curve(
method draw_sector (line 3236) | def draw_sector(
method draw_rect (line 3310) | def draw_rect(self, rect: rect_like, *, radius=None) -> Point:
method draw_quad (line 3361) | def draw_quad(self, quad: quad_like) -> Point:
method draw_zigzag (line 3366) | def draw_zigzag(
method draw_squiggle (line 3395) | def draw_squiggle(
method insert_text (line 3435) | def insert_text(
method insert_textbox (line 3619) | def insert_textbox(
method finish (line 3938) | def finish(
method commit (line 4029) | def commit(self, overlay: bool = True) -> None:
function apply_redactions (line 4050) | def apply_redactions(page: Page, images: int = 2) -> bool:
function scrub (line 4146) | def scrub(
function fill_textbox (line 4299) | def fill_textbox(
function get_oc (line 4524) | def get_oc(doc: Document, xref: int) -> int:
function set_oc (line 4542) | def set_oc(doc: Document, xref: int, oc: int) -> None:
function set_ocmd (line 4565) | def set_ocmd(
function get_ocmd (line 4639) | def get_ocmd(doc: Document, xref: int) -> dict:
function rule_dict (line 4723) | def rule_dict(item):
function get_label_pno (line 4757) | def get_label_pno(pgNo, labels):
function get_label (line 4776) | def get_label(page):
function get_page_numbers (line 4793) | def get_page_numbers(doc, label, only_one=False):
function construct_label (line 4820) | def construct_label(style, prefix, pno) -> str:
function integerToLetter (line 4839) | def integerToLetter(i) -> str:
function integerToRoman (line 4857) | def integerToRoman(num: int) -> str:
function get_page_labels (line 4888) | def get_page_labels(doc):
function set_page_labels (line 4901) | def set_page_labels(doc, labels):
function has_links (line 4949) | def has_links(doc: Document) -> bool:
function has_annots (line 4962) | def has_annots(doc: Document) -> bool:
function recover_bbox_quad (line 4978) | def recover_bbox_quad(line_dir: tuple, span: dict, bbox: tuple) -> Quad:
function recover_quad (line 5028) | def recover_quad(line_dir: tuple, span: dict) -> Quad:
function recover_line_quad (line 5044) | def recover_line_quad(line: dict, spans: list = None) -> Quad:
function recover_span_quad (line 5089) | def recover_span_quad(line_dir: tuple, span: dict, chars: list = None) -...
function recover_char_quad (line 5134) | def recover_char_quad(line_dir: tuple, span: dict, char: dict) -> Quad:
function subset_fonts (line 5165) | def subset_fonts(doc: Document, verbose: bool = False) -> None:
function xref_copy (line 5473) | def xref_copy(doc: Document, source: int, target: int, *, keep: list = N...
FILE: tests/conftest.py
function install_required_packages (line 16) | def install_required_packages():
function log_global_env_facts (line 44) | def log_global_env_facts(record_testsuite_property):
function wrap (line 55) | def wrap(request):
FILE: tests/gentle_compare.py
function gentle_compare (line 6) | def gentle_compare(w0, w1):
function rms (line 31) | def rms(a, b, verbose=None, out_prefix=''):
function pixmaps_rms (line 45) | def pixmaps_rms(a, b, out_prefix=''):
function pixmaps_diff (line 68) | def pixmaps_diff(a, b, out_prefix=''):
FILE: tests/run_compound.py
function log (line 32) | def log(text):
function log_star (line 37) | def log_star(text):
function main (line 43) | def main():
FILE: tests/test_2548.py
function test_2548 (line 7) | def test_2548():
FILE: tests/test_2634.py
function test_2634 (line 9) | def test_2634():
FILE: tests/test_2904.py
function test_2904 (line 6) | def test_2904():
FILE: tests/test_2907.py
function test_2907 (line 6) | def test_2907():
FILE: tests/test_4141.py
function test_4141 (line 6) | def test_4141():
FILE: tests/test_4503.py
function test_4503 (line 14) | def test_4503():
FILE: tests/test_4505.py
function test_4505 (line 5) | def test_4505():
FILE: tests/test_4520.py
function test_4520 (line 4) | def test_4520():
FILE: tests/test_4614.py
function test_4614 (line 5) | def test_4614():
FILE: tests/test_4716.py
function test_4716 (line 4) | def test_4716():
FILE: tests/test_4767.py
function test_4767 (line 10) | def test_4767():
FILE: tests/test_4942.py
function test_4942 (line 4) | def test_4942():
FILE: tests/test_annots.py
function test_caret (line 26) | def test_caret():
function test_freetext (line 36) | def test_freetext():
function test_text (line 53) | def test_text():
function test_highlight (line 60) | def test_highlight():
function test_underline (line 67) | def test_underline():
function test_squiggly (line 74) | def test_squiggly():
function test_strikeout (line 81) | def test_strikeout():
function test_polyline (line 89) | def test_polyline():
function test_polygon (line 103) | def test_polygon():
function test_line (line 110) | def test_line():
function test_square (line 124) | def test_square():
function test_circle (line 131) | def test_circle():
function test_fileattachment (line 138) | def test_fileattachment():
function test_stamp (line 145) | def test_stamp():
function test_image_stamp (line 158) | def test_image_stamp():
function test_redact1 (line 166) | def test_redact1():
function test_redact2 (line 185) | def test_redact2():
function test_redact3 (line 201) | def test_redact3():
function test_redact4 (line 215) | def test_redact4():
function test_1645 (line 231) | def test_1645():
function test_1824 (line 273) | def test_1824():
function test_2270 (line 283) | def test_2270():
function test_2934_add_redact_annot (line 322) | def test_2934_add_redact_annot():
function test_2969 (line 341) | def test_2969():
function test_file_info (line 351) | def test_file_info():
function test_3131 (line 371) | def test_3131():
function test_3209 (line 381) | def test_3209():
function test_3863 (line 393) | def test_3863():
function test_3758 (line 440) | def test_3758():
function test_parent (line 461) | def test_parent():
function test_4047 (line 478) | def test_4047():
function test_4079 (line 492) | def test_4079():
function test_4254 (line 524) | def test_4254():
function test_richtext (line 566) | def test_richtext():
function test_4447 (line 618) | def test_4447():
function test_4755 (line 681) | def test_4755():
function test_4944 (line 724) | def test_4944():
FILE: tests/test_badfonts.py
function test_survive_names (line 9) | def test_survive_names():
FILE: tests/test_balance_count.py
function test_q_count (line 4) | def test_q_count():
FILE: tests/test_barcode.py
function test_barcode (line 6) | def test_barcode():
FILE: tests/test_clip_page.py
function test_clip (line 9) | def test_clip():
FILE: tests/test_cluster_drawings.py
function test_cluster1 (line 7) | def test_cluster1():
function test_cluster2 (line 22) | def test_cluster2():
function test_cluster3 (line 36) | def test_cluster3():
function test_4599 (line 50) | def test_4599():
FILE: tests/test_codespell.py
function test_codespell (line 11) | def test_codespell():
FILE: tests/test_crypting.py
function test_encryption (line 9) | def test_encryption():
FILE: tests/test_docs_samples.py
function _test_all (line 27) | def _test_all():
function test_docs_samples (line 57) | def test_docs_samples(sample):
FILE: tests/test_drawings.py
function test_drawings1 (line 17) | def test_drawings1():
function test_drawings2 (line 27) | def test_drawings2():
function _dict_difference (line 66) | def _dict_difference(a, b):
function test_drawings3 (line 86) | def test_drawings3():
function test_2365 (line 127) | def test_2365():
function test_2462 (line 150) | def test_2462():
function test_2556 (line 165) | def test_2556():
function test_3207 (line 179) | def test_3207():
function test_3591 (line 223) | def test_3591():
function test_4954_1 (line 233) | def test_4954_1():
function test_4954_2 (line 251) | def test_4954_2():
FILE: tests/test_embeddedfiles.py
function test_embedded1 (line 7) | def test_embedded1():
function test_4050 (line 26) | def test_4050():
FILE: tests/test_extractimage.py
function test_extract_image (line 12) | def test_extract_image():
function test_2348 (line 25) | def test_2348():
function test_delete_image (line 52) | def test_delete_image():
FILE: tests/test_flake8.py
function test_flake8 (line 8) | def test_flake8():
FILE: tests/test_font.py
function test_font1 (line 13) | def test_font1():
function test_font2 (line 41) | def test_font2():
function test_fontname (line 48) | def test_fontname():
function test_2608 (line 61) | def test_2608():
function test_fontarchive (line 87) | def test_fontarchive():
function test_load_system_font (line 109) | def test_load_system_font():
function test_mupdf_subset_fonts2 (line 131) | def test_mupdf_subset_fonts2():
function test_3677 (line 140) | def test_3677():
function test_3933 (line 166) | def test_3933():
function test_3780 (line 191) | def test_3780():
function test_3887 (line 215) | def test_3887():
function test_4457 (line 238) | def test_4457():
FILE: tests/test_general.py
function test_haslinks (line 40) | def test_haslinks():
function test_hasannots (line 45) | def test_hasannots():
function test_haswidgets (line 50) | def test_haswidgets():
function test_isrepaired (line 55) | def test_isrepaired():
function test_isdirty (line 61) | def test_isdirty():
function test_cansaveincrementally (line 66) | def test_cansaveincrementally():
function test_iswrapped (line 71) | def test_iswrapped():
function test_wrapcontents (line 79) | def test_wrapcontents():
function test_page_clean_contents (line 96) | def test_page_clean_contents():
function test_annot_clean_contents (line 113) | def test_annot_clean_contents():
function test_config (line 129) | def test_config():
function test_glyphnames (line 133) | def test_glyphnames():
function test_rgbcodes (line 139) | def test_rgbcodes():
function test_pdfstring (line 145) | def test_pdfstring():
function test_open_exceptions (line 152) | def test_open_exceptions():
function test_bug1945 (line 176) | def test_bug1945():
function test_bug1971 (line 182) | def test_bug1971():
function test_default_font (line 190) | def test_default_font():
function test_add_ink_annot (line 195) | def test_add_ink_annot():
function test_techwriter_append (line 215) | def test_techwriter_append():
function test_opacity (line 230) | def test_opacity():
function test_get_text_dict (line 247) | def test_get_text_dict():
function test_font (line 257) | def test_font():
function test_insert_font (line 263) | def test_insert_font():
function test_2173 (line 269) | def test_2173():
function test_texttrace (line 276) | def test_texttrace():
function test_2533 (line 295) | def test_2533():
function test_2645 (line 321) | def test_2645():
function test_2506 (line 336) | def test_2506():
function test_2108 (line 365) | def test_2108():
function test_2238 (line 406) | def test_2238():
function test_2093 (line 433) | def test_2093():
function test_2182 (line 501) | def test_2182():
function test_2246 (line 510) | def test_2246():
function test_2430 (line 570) | def test_2430():
function test_2692 (line 576) | def test_2692():
function test_2596 (line 595) | def test_2596():
function test_2730 (line 616) | def test_2730():
function test_2553 (line 627) | def test_2553():
function test_2553_2 (line 670) | def test_2553_2():
function test_2635 (line 678) | def test_2635():
function test_resolve_names (line 689) | def test_resolve_names():
function test_2777 (line 701) | def test_2777():
function test_2710 (line 706) | def test_2710():
function test_2736 (line 746) | def test_2736():
function test_subset_fonts (line 777) | def test_subset_fonts():
function test_2957_1 (line 801) | def test_2957_1():
function test_2957_2 (line 827) | def test_2957_2():
function test_707560 (line 845) | def test_707560():
function test_3070 (line 887) | def test_3070():
function test_bboxlog_2885 (line 894) | def test_bboxlog_2885():
function test_3081 (line 912) | def test_3081():
function test_xml (line 969) | def test_xml():
function test_3112_set_xml_metadata (line 974) | def test_3112_set_xml_metadata():
function test_archive_3126 (line 978) | def test_archive_3126():
function test_3140 (line 983) | def test_3140():
function test_cli (line 1015) | def test_cli():
function check_lines (line 1024) | def check_lines(expected_regexes, actual):
function test_cli_out (line 1073) | def test_cli_out():
function test_use_python_logging (line 1169) | def test_use_python_logging():
function relpath (line 1347) | def relpath(path, start=None):
function test_open (line 1360) | def test_open():
function test_open2 (line 1460) | def test_open2():
function test_533 (line 1607) | def test_533():
function test_3354 (line 1618) | def test_3354():
function test_scientific_numbers (line 1624) | def test_scientific_numbers():
function test_3615 (line 1636) | def test_3615():
function test_3654 (line 1647) | def test_3654():
function test_3727 (line 1655) | def test_3727():
function test_3569 (line 1661) | def test_3569():
function test_3450 (line 1723) | def test_3450():
function test_3859 (line 1741) | def test_3859():
function test_3905 (line 1751) | def test_3905():
function test_3624 (line 1762) | def test_3624():
function test_4043 (line 1782) | def test_4043():
function test_4018 (line 1788) | def test_4018():
function test_4034 (line 1793) | def test_4034():
function test_4309 (line 1808) | def test_4309():
function test_4263 (line 1813) | def test_4263():
function test_4224 (line 1826) | def test_4224():
function test_4319 (line 1835) | def test_4319():
function test_3886 (line 1850) | def test_3886():
function test_4415 (line 1872) | def test_4415():
function test_4466 (line 1888) | def test_4466():
function test_4479 (line 1898) | def test_4479():
function test_4533 (line 1937) | def test_4533():
function test_4564 (line 1960) | def test_4564():
function test_4496 (line 1973) | def test_4496():
function test_gitinfo (line 1979) | def test_gitinfo():
function test_4392 (line 1994) | def test_4392():
function test_4639 (line 2050) | def test_4639():
function test_4590 (line 2057) | def test_4590():
function test_4702 (line 2098) | def test_4702():
function test_4712 (line 2131) | def test_4712():
function test_4712m (line 2148) | def test_4712m():
function test_4746 (line 2194) | def test_4746():
function test_4907 (line 2199) | def test_4907():
function test_4928 (line 2209) | def test_4928():
function test_4902 (line 2215) | def test_4902():
FILE: tests/test_geometry.py
function test_rect (line 11) | def test_rect():
function test_irect (line 71) | def test_irect():
function test_inversion (line 124) | def test_inversion():
function test_matrix (line 135) | def test_matrix():
function test_point (line 210) | def test_point():
function test_algebra (line 247) | def test_algebra():
function test_quad (line 294) | def test_quad():
function test_pageboxes (line 322) | def test_pageboxes():
function test_3163 (line 341) | def test_3163():
function test_3182 (line 345) | def test_3182():
FILE: tests/test_imagebbox.py
function test_image_bbox (line 18) | def test_image_bbox():
function test_bboxlog (line 37) | def test_bboxlog():
FILE: tests/test_imagemasks.py
function test_imagemask1 (line 14) | def test_imagemask1():
function test_imagemask2 (line 24) | def test_imagemask2():
FILE: tests/test_import.py
function test_import (line 7) | def test_import():
FILE: tests/test_insertimage.py
function test_insert (line 15) | def test_insert():
function test_compress (line 29) | def test_compress():
function test_3087 (line 49) | def test_3087():
FILE: tests/test_insertpdf.py
function approx_parse (line 18) | def approx_parse( text):
function approx_compare (line 35) | def approx_compare( a, b, max_delta):
function test_insert (line 60) | def test_insert():
function test_issue1417_insertpdf_in_loop (line 104) | def test_issue1417_insertpdf_in_loop():
function _test_insert_adobe (line 121) | def _test_insert_adobe():
function _2861_2871_merge_pdf (line 131) | def _2861_2871_merge_pdf(content: bytes, coverpage: bytes):
function test_2861 (line 138) | def test_2861():
function test_2871 (line 146) | def test_2871():
function test_3789 (line 155) | def test_3789():
function test_widget_insert (line 192) | def test_widget_insert():
function names_and_kids (line 226) | def names_and_kids(doc):
function test_merge_checks1 (line 255) | def test_merge_checks1():
function test_merge_checks2 (line 268) | def test_merge_checks2():
function test_4412 (line 305) | def test_4412():
function test_4571 (line 319) | def test_4571():
function test_4958 (line 337) | def test_4958():
FILE: tests/test_linebreaks.py
function test_linebreaks (line 6) | def test_linebreaks():
FILE: tests/test_linequad.py
function test_quadcalc (line 13) | def test_quadcalc():
FILE: tests/test_memory.py
function merge_pdf (line 10) | def merge_pdf(content: bytes, coverpage: bytes):
function test_2791 (line 17) | def test_2791():
function test_4090 (line 103) | def test_4090():
function show_tracemalloc_diff (line 137) | def show_tracemalloc_diff(snapshot1, snapshot2):
function test_4125 (line 161) | def test_4125():
function _test_4751 (line 239) | def _test_4751():
function test_4751 (line 321) | def test_4751():
FILE: tests/test_metadata.py
function test_metadata (line 17) | def test_metadata():
function test_erase_meta (line 21) | def test_erase_meta():
function test_3237 (line 30) | def test_3237():
FILE: tests/test_mupdf_regressions.py
function test_707448 (line 8) | def test_707448():
function test_707673 (line 19) | def test_707673():
function test_707727 (line 37) | def test_707727():
function test_707721 (line 57) | def test_707721():
function test_3376 (line 69) | def test_3376():
FILE: tests/test_named_links.py
function test_2886 (line 6) | def test_2886():
function test_2922 (line 34) | def test_2922():
function test_3301 (line 62) | def test_3301():
FILE: tests/test_nonpdf.py
function test_isnopdf (line 15) | def test_isnopdf():
function test_pageids (line 19) | def test_pageids():
function test_layout (line 31) | def test_layout():
FILE: tests/test_object_manipulation.py
function test_rotation1 (line 16) | def test_rotation1():
function test_rotation2 (line 23) | def test_rotation2():
function test_trailer (line 30) | def test_trailer():
function test_valid_name (line 41) | def test_valid_name():
FILE: tests/test_objectstreams.py
function test_objectstream1 (line 4) | def test_objectstream1():
function test_objectstream2 (line 26) | def test_objectstream2():
function test_objectstream3 (line 49) | def test_objectstream3():
FILE: tests/test_optional_content.py
function test_oc1 (line 13) | def test_oc1():
function test_oc2 (line 29) | def test_oc2():
function test_3143 (line 67) | def test_3143():
function test_3180 (line 77) | def test_3180():
FILE: tests/test_page_links.py
function test_page_links_generator (line 6) | def test_page_links_generator():
FILE: tests/test_pagedelete.py
function test_deletion (line 33) | def test_deletion():
function test_3094 (line 76) | def test_3094():
function test_3150 (line 83) | def test_3150():
function test_4462 (line 96) | def test_4462():
function test_4790 (line 118) | def test_4790():
FILE: tests/test_pagelabels.py
function make_doc (line 9) | def make_doc():
function make_labels (line 17) | def make_labels():
function test_setlabels (line 28) | def test_setlabels():
function test_labels_styleA (line 44) | def test_labels_styleA():
FILE: tests/test_pixmap.py
function test_pagepixmap (line 30) | def test_pagepixmap():
function test_pdfpixmap (line 41) | def test_pdfpixmap():
function test_filepixmap (line 57) | def test_filepixmap():
function test_pilsave (line 67) | def test_pilsave():
function test_save (line 79) | def test_save(tmpdir):
function test_setalpha (line 90) | def test_setalpha():
function test_color_count (line 104) | def test_color_count():
function test_memoryview (line 112) | def test_memoryview():
function test_samples_ptr (line 127) | def test_samples_ptr():
function test_2369 (line 133) | def test_2369():
function test_page_idx_int (line 148) | def test_page_idx_int():
function test_fz_write_pixmap_as_jpeg (line 155) | def test_fz_write_pixmap_as_jpeg():
function test_3020 (line 162) | def test_3020():
function test_3050 (line 168) | def test_3050():
function test_3058 (line 207) | def test_3058():
function test_3072 (line 227) | def test_3072():
function test_3134 (line 256) | def test_3134():
function test_3177 (line 267) | def test_3177():
function test_3493 (line 273) | def test_3493():
function test_3848 (line 374) | def test_3848():
function test_3994 (line 396) | def test_3994():
function test_3448 (line 408) | def test_3448():
function test_3854 (line 426) | def test_3854():
function test_4155 (line 449) | def test_4155():
function test_4336 (line 467) | def test_4336():
function test_4435 (line 514) | def test_4435():
function test_4423 (line 552) | def test_4423():
function test_4445 (line 578) | def test_4445():
function test_3806 (line 607) | def test_3806():
function test_4388 (line 625) | def test_4388():
function test_4699 (line 653) | def test_4699():
FILE: tests/test_pylint.py
function test_pylint (line 8) | def test_pylint():
FILE: tests/test_release.py
function _file_line (line 21) | def _file_line(path, text, re_match, offset=+2):
function test_release_versions (line 41) | def test_release_versions():
function test_release_bug_template (line 51) | def test_release_bug_template():
function test_release_changelog_version (line 62) | def test_release_changelog_version():
function test_release_changelog_mupdf_version (line 76) | def test_release_changelog_mupdf_version():
FILE: tests/test_remove-rotation.py
function test_remove_rotation (line 8) | def test_remove_rotation():
FILE: tests/test_rewrite_images.py
function test_rewrite_images (line 7) | def test_rewrite_images():
FILE: tests/test_rtl.py
function test_rtl (line 6) | def test_rtl():
FILE: tests/test_showpdfpage.py
function test_insert (line 16) | def test_insert():
function test_2742 (line 33) | def test_2742():
FILE: tests/test_spikes.py
function test_spikes (line 6) | def test_spikes():
FILE: tests/test_story.py
function test_story (line 6) | def test_story():
function test_2753 (line 38) | def test_2753():
function test_fit_springer (line 106) | def test_fit_springer():
function test_write_stabilized_with_links (line 156) | def test_write_stabilized_with_links():
function test_archive_creation (line 232) | def test_archive_creation():
function test_3813 (line 237) | def test_3813():
FILE: tests/test_tables.py
function test_table1 (line 15) | def test_table1():
function test_table2 (line 40) | def test_table2():
function test_2812 (line 52) | def test_2812():
function test_2979 (line 164) | def test_2979():
function test_3062 (line 196) | def test_3062():
function test_strict_lines (line 217) | def test_strict_lines():
function test_add_lines (line 229) | def test_add_lines():
function test_3148 (line 252) | def test_3148():
function test_3179 (line 280) | def test_3179():
function test_battery_file (line 289) | def test_battery_file():
function test_markdown (line 302) | def test_markdown():
function test_paths_param (line 333) | def test_paths_param():
function test_boxes_param (line 342) | def test_boxes_param():
function test_dotted_grid (line 374) | def test_dotted_grid():
function test_4017 (line 388) | def test_4017():
function test_md_styles (line 453) | def test_md_styles():
FILE: tests/test_tesseract.py
function test_tesseract (line 7) | def test_tesseract():
function test_3842b (line 54) | def test_3842b():
function test_3842 (line 76) | def test_3842():
FILE: tests/test_textbox.py
function test_textbox1 (line 25) | def test_textbox1():
function test_textbox2 (line 44) | def test_textbox2():
function test_textbox3 (line 64) | def test_textbox3():
function test_textbox4 (line 87) | def test_textbox4():
function test_textbox5 (line 108) | def test_textbox5():
function test_2637 (line 137) | def test_2637():
function test_htmlbox1 (line 159) | def test_htmlbox1():
function test_htmlbox2 (line 234) | def test_htmlbox2():
function test_htmlbox3 (line 254) | def test_htmlbox3():
function test_3559 (line 273) | def test_3559():
function test_3916 (line 281) | def test_3916():
function test_4400 (line 289) | def test_4400():
function test_4613 (line 298) | def test_4613():
FILE: tests/test_textextract.py
function test_extract1 (line 20) | def test_extract1():
function _test_extract2 (line 37) | def _test_extract2():
function _test_extract3 (line 66) | def _test_extract3():
function test_extract4 (line 81) | def test_extract4():
function test_2954 (line 136) | def test_2954():
function test_3027 (line 211) | def test_3027():
function test_3186 (line 219) | def test_3186():
function test_3197 (line 244) | def test_3197():
function test_document_text (line 280) | def test_document_text():
function test_4524 (line 331) | def test_4524():
function test_3594 (line 345) | def test_3594():
function test_3687 (line 365) | def test_3687():
function test_3705 (line 378) | def test_3705():
function test_3650 (line 419) | def test_3650():
function test_4026 (line 430) | def test_4026():
function test_3725 (line 444) | def test_3725():
function test_4147 (line 453) | def test_4147():
function test_4139 (line 483) | def test_4139():
function test_4245 (line 505) | def test_4245():
function test_4180 (line 531) | def test_4180():
function test_4182 (line 552) | def test_4182():
function test_4179 (line 582) | def test_4179():
function test_extendable_textpage (line 671) | def test_extendable_textpage():
function test_4363 (line 856) | def test_4363():
function test_4546 (line 887) | def test_4546():
function test_4503 (line 927) | def test_4503():
FILE: tests/test_textsearch.py
function test_search1 (line 21) | def test_search1():
function test_search2 (line 31) | def test_search2():
function test_search3 (line 42) | def test_search3():
FILE: tests/test_threads.py
function log (line 9) | def log(text):
function threadfn (line 13) | def threadfn(queue_to_threads, queue_from_threads):
function test_threads_stress (line 49) | def test_threads_stress():
FILE: tests/test_toc.py
function test_simple_toc (line 23) | def test_simple_toc():
function test_full_toc (line 29) | def test_full_toc():
function test_erase_toc (line 45) | def test_erase_toc():
function test_replace_toc (line 50) | def test_replace_toc():
function test_setcolors (line 55) | def test_setcolors():
function test_circular (line 75) | def test_circular():
function test_2355 (line 85) | def test_2355():
function test_2788 (line 106) | def test_2788():
function test_toc_count (line 139) | def test_toc_count():
function test_3347 (line 161) | def test_3347():
function test_3400 (line 208) | def test_3400():
function test_3820 (line 279) | def test_3820():
FILE: tests/test_typing.py
function run (line 8) | def run(command, check=1):
function test_py_typed (line 12) | def test_py_typed():
function _test_4903 (line 44) | def _test_4903(page: pymupdf.Page) -> float: # In 1.27.1, error: Variab...
function _test_4932 (line 47) | def _test_4932(page: pymupdf.Page):
FILE: tests/test_widgets.py
function test_text (line 24) | def test_text():
function test_checkbox (line 47) | def test_checkbox():
function test_listbox (line 78) | def test_listbox():
function test_combobox (line 107) | def test_combobox():
function test_text2 (line 141) | def test_text2():
function test_2333 (line 162) | def test_2333():
function test_2411 (line 187) | def test_2411():
function test_2391 (line 212) | def test_2391():
function test_3216 (line 232) | def test_3216():
function test_add_widget (line 243) | def test_add_widget():
function test_interfield_calculation (line 256) | def test_interfield_calculation():
function test_3950 (line 323) | def test_3950():
function test_4004 (line 339) | def test_4004():
function test_4055 (line 381) | def test_4055():
function test_4965 (line 435) | def test_4965():
FILE: tests/test_word_delimiters.py
function test_delimiters (line 5) | def test_delimiters():
FILE: tests/util.py
function download (line 5) | def download(url, name, size=None):
function skip_slow_tests (line 30) | def skip_slow_tests(test_name):
Copy disabled (too large)
Download .json
Condensed preview — 589 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (10,889K chars).
[
{
"path": ".gitattributes",
"chars": 13,
"preview": "*.pdf binary\n"
},
{
"path": ".github/ISSUE_TEMPLATE/bug_report.yml",
"chars": 2350,
"preview": "name: Bug Report\ndescription: Create a bug report for PyMuPDF\n\n# We omit `title: \"...\"` so that the field defaults to bl"
},
{
"path": ".github/ISSUE_TEMPLATE/feature_request.md",
"chars": 569,
"preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: enhancement\nassignees:\n\n---\n\n**Is yo"
},
{
"path": ".github/workflows/build_wheels.yml",
"chars": 4949,
"preview": "name: Build wheels\n\non:\n workflow_dispatch:\n inputs:\n \n flavours:\n description: 'If set, we build s"
},
{
"path": ".github/workflows/cla.yml",
"chars": 2222,
"preview": "name: \"CLA Assistant\"\non:\n pull_request_target:\n types: [opened,closed,synchronize]\n\njobs:\n CLAAssistant:\n runs-"
},
{
"path": ".github/workflows/test-valgrind.yml",
"chars": 611,
"preview": "name: Test valgrind\n\non:\n workflow_dispatch:\n schedule:\n - cron: '13 6 * * *'\n\njobs:\n\n valgrind:\n name: valgrin"
},
{
"path": ".github/workflows/test.yml",
"chars": 1660,
"preview": "# Run scripts/test.py directly on multiple Github servers. Instead of\n# specifying individual inputs, we support a sing"
},
{
"path": ".github/workflows/test_multiple.yml",
"chars": 1058,
"preview": "# Run scripts/test.py on multiple OS's (Windows, Linux, MacOS x64, MacOS arm64)\n# and with multiple specifications of Mu"
},
{
"path": ".github/workflows/test_pyodide.yml",
"chars": 1058,
"preview": "name: Test pyodide\n\n# Build and test pyodide wheels using cibuildwheel.\n\non:\n workflow_dispatch:\n \n schedule:\n - c"
},
{
"path": ".github/workflows/test_quick.yml",
"chars": 1143,
"preview": "name: test_quick\n\non:\n pull_request:\n branches: [main]\n \n workflow_dispatch:\n inputs:\n args:\n typ"
},
{
"path": ".github/workflows/test_sysinstall.yml",
"chars": 1704,
"preview": "name: Test sysinstall\n\non:\n schedule:\n - cron: '13 4 * * *'\n workflow_dispatch:\n inputs:\n args:\n des"
},
{
"path": ".gitignore",
"chars": 67,
"preview": "*.pyc\n*.so\n*.o\n*.swp\nbuild/\ndemo/README.rst\ndocs/build\ndocs/_build\n"
},
{
"path": ".python-version",
"chars": 5,
"preview": "3.12\n"
},
{
"path": ".readthedocs.yaml",
"chars": 794,
"preview": "# .readthedocs.yaml\r\n# Read the Docs configuration file\r\n# See https://docs.readthedocs.io/en/stable/config-file/v2.html"
},
{
"path": ".vs/ProjectSettings.json",
"chars": 34,
"preview": "{\n \"CurrentProjectSetting\": \"\"\n}\n"
},
{
"path": ".vs/VSWorkspaceState.json",
"chars": 96,
"preview": "{\n \"ExpandedNodes\": [\n \"\"\n ],\n \"SelectedNode\": \"\",\n \"PreviewInSolutionExplorer\": false\n}\n"
},
{
"path": "COPYING",
"chars": 34520,
"preview": " GNU AFFERO GENERAL PUBLIC LICENSE\n Version 3, 19 November 2007\n\n Copyright (C)"
},
{
"path": "README.md",
"chars": 22697,
"preview": "<p align=\"center\">\n <a href=\"https://github.com/pymupdf/PyMuPDF/\">\n <img loading=\"lazy\" alt=\"PyMuPDF\" src=\"https://p"
},
{
"path": "READMEb.md",
"chars": 283,
"preview": "# PyMuPDFb\n\nThis wheel contains [MuPDF](https://mupdf.readthedocs.io/) shared libraries for\nuse by [PyMuPDF](https://pym"
},
{
"path": "READMEd.md",
"chars": 156,
"preview": "# PyMuPDFd\n\nThis wheel contains [MuPDF](https://mupdf.readthedocs.io/) build-time files\nthat were used to build [PyMuPDF"
},
{
"path": "changes.txt",
"chars": 182342,
"preview": "Change Log\n==========\n\n\n**Changes in version 1.27.2.3** (2026-04-24)\n\n* Fixed issues:\n\n * **Fixed** `4928 <https://gith"
},
{
"path": "docs/404.rst",
"chars": 166,
"preview": ".. include:: header-404.rst\n\n404!\n======\n\n\n**This page is not available.**\n\n\nPlease use the menu or search to find what "
},
{
"path": "docs/README.md",
"chars": 3911,
"preview": "# PyMuPDF documentation\n\nWelcome to the PyMuPDF documentation. This documentation relies on [Sphinx](https://www.sphinx-"
},
{
"path": "docs/_static/custom.css",
"chars": 3776,
"preview": "/* main document page: ensures pages fit to the available width and height */\n.wy-nav-content {\n min-width: 100%;\n "
},
{
"path": "docs/_static/prism/prism.css",
"chars": 3217,
"preview": "/* PrismJS 1.29.0\nhttps://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+bash+c+csharp+cpp"
},
{
"path": "docs/_static/prism/prism.html",
"chars": 2138,
"preview": "<html>\n\n <head>\n\n <link rel=\"stylesheet\" type=\"text/css\" href=\"prism.css\">\n\n <style>\n\n .copy"
},
{
"path": "docs/_static/prism/prism.js",
"chars": 51430,
"preview": "/* PrismJS 1.29.0\nhttps://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+bash+c+csharp+cpp"
},
{
"path": "docs/about-feature-matrix.rst",
"chars": 27701,
"preview": "\n\n.. required image embeds for HTML to reference\n\n\n.. image:: images/icons/icon-pdf.svg\n :width: 0\n :h"
},
{
"path": "docs/about-performance.rst",
"chars": 16172,
"preview": ".. raw:: html\n\n <style>\n\n * {\n -webkit-tap-highlight-color: rgba(0,0,0,0); /* make transparent link"
},
{
"path": "docs/about.rst",
"chars": 6295,
"preview": ".. include:: header.rst\n\n.. _About:\n\n\n\n.. _About_Features:\n\nFeatures Comparison\n----------------------------------------"
},
{
"path": "docs/algebra.rst",
"chars": 10078,
"preview": ".. include:: header.rst\n\n.. _Algebra:\n\nOperator Algebra for Geometry Objects\n======================================\n\n.. "
},
{
"path": "docs/annot.rst",
"chars": 31837,
"preview": ".. include:: header.rst\n\n.. _Annot:\n\n================\nAnnot\n================\n\n|pdf_only_class|\n\nQuote from the :ref:`Ado"
},
{
"path": "docs/app1.rst",
"chars": 17177,
"preview": ".. include:: header.rst\n\n.. _Appendix1:\n\n======================================\nAppendix 1: Details on Text Extraction\n="
},
{
"path": "docs/app2.rst",
"chars": 2206,
"preview": ".. include:: header.rst\n\n.. _Appendix2:\n\n================================================\nAppendix 2: Considerations on "
},
{
"path": "docs/app3.rst",
"chars": 24390,
"preview": ".. include:: header.rst\n\n.. _Appendix3:\n\n================================================\nAppendix 3: Assorted Technical"
},
{
"path": "docs/app4.rst",
"chars": 10992,
"preview": ".. include:: header.rst\n\n\n.. role:: red-color\n.. role:: orange-color\n.. role:: green-color\n\n\n\n.. _Appendix4:\n\n=========="
},
{
"path": "docs/archive-class.rst",
"chars": 5566,
"preview": ".. include:: header.rst\n\n.. _Archive:\n\n================\nArchive\n================\n\n* New in v1.21.0\n\nThis class represent"
},
{
"path": "docs/changes.rst",
"chars": 78,
"preview": ".. include:: header.rst\n\n.. include:: ../changes.txt\n\n.. include:: footer.rst\n"
},
{
"path": "docs/classes.rst",
"chars": 502,
"preview": ".. include:: header.rst\n\n============\nClasses\n============\n\n.. toctree::\n :maxdepth: 2\n\n annot.rst\n archive-class."
},
{
"path": "docs/colors.rst",
"chars": 2636,
"preview": ".. include:: header.rst\n\n.. _ColorDatabase:\n\n================\nColor Database\n================\nSince the introduction of "
},
{
"path": "docs/colorspace.rst",
"chars": 981,
"preview": ".. include:: header.rst\n\n.. _Colorspace:\n\n================\nColorspace\n================\n\nRepresents the color space of a "
},
{
"path": "docs/conf.py",
"chars": 10349,
"preview": "# -*- coding: utf-8 -*-\n#\nimport re\nimport sys\nimport os\nimport datetime\n\n# If extensions (or modules to document with a"
},
{
"path": "docs/converting-files.rst",
"chars": 1914,
"preview": ".. include:: header.rst\n\n.. _ConvertingFiles:\n\n==============================\nConverting Files\n========================="
},
{
"path": "docs/coop_low.rst",
"chars": 3709,
"preview": ".. include:: header.rst\n\n.. _cooperation:\n\n===============================================================\nWorking toget"
},
{
"path": "docs/device.rst",
"chars": 1293,
"preview": ".. include:: header.rst\n\n.. _Device:\n\n================\nDevice\n================\n\nThe different format handlers (pdf, xps,"
},
{
"path": "docs/displaylist.rst",
"chars": 3830,
"preview": ".. include:: header.rst\n\n.. _DisplayList:\n\n================\nDisplayList\n================\n\nDisplayList is a list containi"
},
{
"path": "docs/document-writer-class.rst",
"chars": 2373,
"preview": ".. include:: header.rst\n\n.. _DocumentWriter:\n\n================\nDocumentWriter\n================\n\n|pdf_only_class|\n\n\n* New"
},
{
"path": "docs/document.rst",
"chars": 131878,
"preview": ".. include:: header.rst\n\n.. _Document:\n\n================\nDocument\n================\n\n.. highlight:: python\n\nThis class re"
},
{
"path": "docs/extensions/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "docs/extensions/fulltoc.py",
"chars": 3163,
"preview": "# -*- encoding: utf-8 -*-\n#\n# Copyright © 2012 New Dream Network, LLC (DreamHost)\n#\n# Author: Doug Hellmann <doug.hellma"
},
{
"path": "docs/extensions/searchrepair.py",
"chars": 729,
"preview": "import os\r\n\r\n\r\ndef modify_search_index(app, exception):\r\n if exception is None: # build succeeded\r\n filename "
},
{
"path": "docs/faq/index.rst",
"chars": 53198,
"preview": "\n.. include:: ../header.rst\n\n\n\nFAQ\n=============\n\n\n.. raw:: html\n\n <script>\n document.getElementById(\"headerSe"
},
{
"path": "docs/faq.rst",
"chars": 251,
"preview": ".. include:: header.rst\n\n.. _FAQ:\n\n==============================\nFAQ\n==============================\n\nA collection of re"
},
{
"path": "docs/font.rst",
"chars": 17965,
"preview": ".. include:: header.rst\n\n.. _Font:\n\n================\nFont\n================\n\n* New in v1.16.18\n\nThis class represents a f"
},
{
"path": "docs/footer.rst",
"chars": 4847,
"preview": ".. _documentation_footer:\n\n----\n\n.. raw:: html\n\n <p style=\"color:#999\" id=\"footerDisclaimer\">This software is provided"
},
{
"path": "docs/functions.rst",
"chars": 47229,
"preview": ".. include:: header.rst\n\n============\nFunctions\n============\nThe following are miscellaneous functions and attributes on"
},
{
"path": "docs/glossary.rst",
"chars": 14331,
"preview": ".. include:: header.rst\n\n.. _Glossary:\n\n==============\nGlossary\n==============\n\n.. data:: coordinate\n\n This is an"
},
{
"path": "docs/header-404.rst",
"chars": 785,
"preview": ".. meta::\n :author: Artifex\n :description: PyMuPDF is a high-performance Python library for data extraction, analysi"
},
{
"path": "docs/header.rst",
"chars": 8559,
"preview": ".. meta::\n :author: Artifex\n :description: PyMuPDF is a high-performance Python library for data extraction, analysi"
},
{
"path": "docs/how-to-open-a-file.rst",
"chars": 6025,
"preview": ".. include:: header.rst\n\n.. _HowToOpenAFile:\n\n==============================\nOpening Files\n============================="
},
{
"path": "docs/identity.rst",
"chars": 825,
"preview": ".. include:: header.rst\n\n.. _Identity:\n\n============\nIdentity\n============\n\nIdentity is a :ref:`Matrix` that performs no"
},
{
"path": "docs/index.rst",
"chars": 1604,
"preview": ".. include:: header.rst\n\n.. This is the TOC in the sidebar!\n\n.. raw:: html\n\n <style>\n\n .toc-drawer {\n dis"
},
{
"path": "docs/installation.rst",
"chars": 11490,
"preview": ".. include:: header.rst\n\n\n\nInstallation\n=============\n\nRequirements\n----------------------------------------------------"
},
{
"path": "docs/irect.rst",
"chars": 7248,
"preview": ".. include:: header.rst\n\n.. _IRect:\n\n==========\nIRect\n==========\n\nIRect is a rectangular bounding box, very similar to :"
},
{
"path": "docs/link.rst",
"chars": 6648,
"preview": ".. include:: header.rst\n\n.. _Link:\n\n================\nLink\n================\nRepresents a pointer to somewhere (this docum"
},
{
"path": "docs/linkdest.rst",
"chars": 3642,
"preview": ".. include:: header.rst\n\n.. _linkDest:\n\n================\nlinkDest\n================\nClass representing the `dest` propert"
},
{
"path": "docs/locales/ja/.readthedocs.yaml",
"chars": 705,
"preview": "# .readthedocs.yaml\r\n# Note: We use this dedicated yaml inside the locales/ja folder as RTD was having problems building"
},
{
"path": "docs/locales/ja/LC_MESSAGES/404.po",
"chars": 1757,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2024, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/about-feature-matrix.po",
"chars": 680,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/about-performance.po",
"chars": 680,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/about.po",
"chars": 7711,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/algebra.po",
"chars": 18014,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/annot.po",
"chars": 64865,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/app1.po",
"chars": 27179,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/app2.po",
"chars": 5969,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/app3.po",
"chars": 37784,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/app4.po",
"chars": 30678,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/archive-class.po",
"chars": 11652,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/changes.po",
"chars": 316410,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ja/LC_MESSAGES/classes.po",
"chars": 1554,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ja/LC_MESSAGES/colors.po",
"chars": 4952,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/colorspace.po",
"chars": 4054,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/converting-files.po",
"chars": 3663,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ja/LC_MESSAGES/coop_low.po",
"chars": 7383,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/deprecated.po",
"chars": 28647,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2024, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/device.po",
"chars": 3623,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/displaylist.po",
"chars": 9231,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/document-writer-class.po",
"chars": 7289,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/document.po",
"chars": 275324,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/faq.po",
"chars": 1923,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2024, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/font.po",
"chars": 40870,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/footer.po",
"chars": 891,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/functions.po",
"chars": 96469,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/glossary.po",
"chars": 24986,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/header-404.po",
"chars": 1270,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2024, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ja/LC_MESSAGES/header.po",
"chars": 1295,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/how-to-open-a-file.po",
"chars": 11734,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/identity.po",
"chars": 2574,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/index.po",
"chars": 3818,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2024, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/installation.po",
"chars": 30158,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/intro.po",
"chars": 8079,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2024, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ja/LC_MESSAGES/irect.po",
"chars": 17626,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/link.po",
"chars": 15702,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/linkdest.po",
"chars": 10103,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/lowlevel.po",
"chars": 1899,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/matrix.po",
"chars": 19812,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/module.po",
"chars": 21910,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/outline.po",
"chars": 9583,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/packaging.po",
"chars": 8277,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2024, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/page.po",
"chars": 316317,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/pixmap.po",
"chars": 76143,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/point.po",
"chars": 9001,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/pymupdf-layout/index.po",
"chars": 12242,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ja/LC_MESSAGES/pymupdf-pro/index.po",
"chars": 9821,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ja/LC_MESSAGES/pymupdf-pro.po",
"chars": 8184,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2024, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ja/LC_MESSAGES/pymupdf4llm/api.po",
"chars": 38306,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2024, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ja/LC_MESSAGES/pymupdf4llm/index.po",
"chars": 11248,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2024, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/pyodide.po",
"chars": 7124,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2024, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/quad.po",
"chars": 13379,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/rag.po",
"chars": 8680,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2024, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/recipes-annotations.po",
"chars": 5983,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/recipes-common-issues-and-their-solutions.po",
"chars": 24158,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/recipes-drawing-and-graphics.po",
"chars": 12514,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/recipes-images.po",
"chars": 44382,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/recipes-journalling.po",
"chars": 8422,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/recipes-low-level-interfaces.po",
"chars": 25715,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/recipes-multiprocessing.po",
"chars": 4125,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/recipes-ocr.po",
"chars": 7713,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2024, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/recipes-optional-content.po",
"chars": 9618,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/recipes-stories.po",
"chars": 30197,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/recipes-text.po",
"chars": 36264,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/recipes.po",
"chars": 1513,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2024, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/rect.po",
"chars": 29936,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/resources.po",
"chars": 2924,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2024, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/shape.po",
"chars": 67206,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/story-class.po",
"chars": 37319,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/supported-files-table.po",
"chars": 676,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2024, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/textpage.po",
"chars": 49976,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/textwriter.po",
"chars": 28194,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/the-basics.po",
"chars": 37865,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/tools.po",
"chars": 27673,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ja/LC_MESSAGES/tutorial.po",
"chars": 48497,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/vars.po",
"chars": 30861,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/version.po",
"chars": 2423,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ja/LC_MESSAGES/widget.po",
"chars": 26004,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/xml-class.po",
"chars": 39041,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ja/LC_MESSAGES/znames.po",
"chars": 22346,
"preview": "# PyMuPDF Japanese documentation\n# Copyright (C) 2015-2023, Artifex\n# This file is distributed under the same license as"
},
{
"path": "docs/locales/ko/.readthedocs.yaml",
"chars": 680,
"preview": "# .readthedocs.yaml\n# Note: We use this dedicated yaml inside the locales/ko folder as RTD was having problems building "
},
{
"path": "docs/locales/ko/LC_MESSAGES/404.po",
"chars": 1822,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/about-feature-matrix.po",
"chars": 630,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/about-performance.po",
"chars": 630,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/about.po",
"chars": 7150,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/algebra.po",
"chars": 17066,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/annot.po",
"chars": 63620,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/app1.po",
"chars": 27390,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/app2.po",
"chars": 5742,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/app3.po",
"chars": 39448,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/app4.po",
"chars": 30126,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/archive-class.po",
"chars": 11391,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/changes.po",
"chars": 306215,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/classes.po",
"chars": 1522,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/colors.po",
"chars": 4723,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/colorspace.po",
"chars": 3932,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/converting-files.po",
"chars": 3816,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/coop_low.po",
"chars": 7097,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/device.po",
"chars": 3663,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/displaylist.po",
"chars": 9133,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/document-writer-class.po",
"chars": 7104,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/document.po",
"chars": 269005,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/faq.po",
"chars": 1927,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/font.po",
"chars": 40335,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/footer.po",
"chars": 795,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/functions.po",
"chars": 94748,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/glossary.po",
"chars": 25056,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/header-404.po",
"chars": 1283,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/header.po",
"chars": 1271,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/how-to-open-a-file.po",
"chars": 11464,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/identity.po",
"chars": 2448,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/index.po",
"chars": 2690,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/installation.po",
"chars": 25347,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/irect.po",
"chars": 18195,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/link.po",
"chars": 15176,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/linkdest.po",
"chars": 10296,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/lowlevel.po",
"chars": 1824,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/matrix.po",
"chars": 20012,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/module.po",
"chars": 21508,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/outline.po",
"chars": 8466,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/packaging.po",
"chars": 7724,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/page.po",
"chars": 271773,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/pixmap.po",
"chars": 75037,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/point.po",
"chars": 8976,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/pymupdf-layout/index.po",
"chars": 16351,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/pymupdf-pro/index.po",
"chars": 10014,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/pymupdf4llm/api.po",
"chars": 48297,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2024, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/pymupdf4llm/index.po",
"chars": 12336,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/pyodide.po",
"chars": 7106,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/quad.po",
"chars": 13650,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/rag.po",
"chars": 8424,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/recipes-annotations.po",
"chars": 5159,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
},
{
"path": "docs/locales/ko/LC_MESSAGES/recipes-common-issues-and-their-solutions.po",
"chars": 15536,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) 2015-2025, Artifex\n# This file is distributed under the same license as the Py"
}
]
// ... and 389 more files (download for full content)
About this extraction
This page contains the full source code of the rk700/PyMuPDF GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 589 files (9.1 MB), approximately 2.4M tokens, and a symbol index with 2079 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.