[comment {-*- tcl -*- doctools manpage}]

[comment {

 Source file for doctools

 Usage:
 tclsh c:\tcl\apps\dtplite.tcl  -o . html tclMuPDF.man
 tclsh c:\tcl\apps\dtplite.tcl  -o . wiki tclMuPDF.man
}]


[manpage_begin tclMuPDF n 2.3]
[copyright {2023, by A.Buratti}]
[moddesc {Tcl meets MuPDF}]
[titledesc  {Tcl meets MuPDF}]
[category  {pdf parsing and rendering}]
[require Tcl 8.6]
[require MuPDF [opt 2.3]]

[description]
Package [package MuPDF] integrates the [uri http://mupdf.com {MuPDF}] framework in Tcl.
[para]
The focus of  [uri http://mupdf.com {MuPDF}]  is on speed, small code size, and high-quality anti-aliased rendering. 
The main goal of this integration is to generate images of the pdf pages, in a .png format, or directly in a Tk's photo image type.
[para]
MuPDF also provides a partial support for editing PDFs, allowing to fill form-fields and working with annotations.
[para]
Thanks to its speed [package MuPDF] can be used for building interactive pdf-viewers with high-quality and real-time zooming.
[para]
[package MuPDF] is a binary package, distributed in a multi-platform bundle, i.e. it can be used on
[list_begin itemized]
[item] Windows 64 bit
[item] Linux 64 bit
[item] MacOS 64 bit
[list_end]

[para]
Just an example to get the flavor of how to use [package MuPDF]:
[para]
[example {
    # open a file and save 1st page as a .png file

    package require tclMuPDF
    set pdf [mupdf::open /mydir/sample.pdf]
    set page [$pdf getpage 0]   ;# 0 is the 1st page
    $page savePNG /mydir/page0.png
    $pdf quit
}]

[subsection {MuPDF 2.x and mupdf 1.x}]
Please note that MuPDF-2.x is a new major release breaking the backward compatibility with 1.x.
In order to support these new features, and for the next planned features, MuPDF-2.x has been totally redesigned.  
In Appendix you can find a quick summary of the changes and how to adapt your old code.
See [sectref "From mupdf 1.x to MuPDF 2.x"]

[subsection {MuPDF with and without Tk}]

[package MuPDF] is provided in two variants:
[list_begin itemized]
[item] [package tkMuPDF] (or simply [package MuPDF]) is the full package, it requires [cmd Tk]
[item] [package tclMuPDF] does not require [cmd Tk].
You will be still able to save images as PNG files, 
but of course some subcommands related to Tk won't be available (e.g [cmd saveImage] )
[list_end]


[comment =====================================================================]
[section {MuPDF Commands}]

The MuPDF package is based on 2 main classes [class mupdf::Doc], [class Mupdf::Page] whose instances correspond to
a PDF-document and its pages, plus an auxiliary class [class mupdf::TextSearch] whose purpose
is to manage progressive searches across all the pages of a document

[subsection "mupdf::Doc methods"]

[list_begin definitions]

[call [cmd mupdf::open] [arg filename] [opt "[option -password] [arg password]"]] 
This is the main command: it opens the PDF-file [arg filename] and returns a [arg pdfObj] to be used in subsequent operations.
[para]
If [arg filename] is password-protected, you may specify a [arg password] adding the option [option -password]; 
if option [option -password] is not specified, [package MuPDF] will ask for a password.
[para]
Read more about it in the section [sectref "Working with Password Protected Files"].

[call [arg pdfObj] [cmd authentication]]
return the current authentication mode for [arg pdfObj]. It may be [const none] (no auth required),
[const user] (opened with user's password), [const owner] (opened with owner's password).

[call [arg pdfObj] [cmd upwd] [arg user-password]] 
[call [arg pdfObj] [cmd opwd] [arg owner-password]] 
add or change respectively the user-password or the owner-password. In order to reset the passwords,set them to "".
[para]
Read more about it in the section [sectref "Working with Password Protected Files"].

[call [arg pdfObj] [cmd removepassword]]
reset both the user-password and the owner-passwords.  

[call [arg pdfObj] [cmd quit]] 
close and destroy the [arg pdfObj] without saving the changes. All the related resources (e.g. opened pages ..) will be destroyed.

[call [arg pdfObj] [cmd close]]
save the changes (if any) and then close and destroy the [arg pdfObj]. All the related resources (e.g. opened pages ..) will be destroyed.

[call [arg pdfObj] [cmd fullname]]
return the fully normalized pathname of the pdf-file.

[call [arg pdfObj] [cmd version]]
return the document's internal PDF-version.

[call [arg pdfObj] [cmd anchor] [arg anchorName]]
return the location of [arg anchorName] as list of 3 numbers:
[list_begin itemized]
  [item] a page number ( -1 if [arg anchorName] is not found )
  [item] x displacement
  [item] y displacement
[list_end]
x and y are hints for locating the anchor: they represent the displacement from the upper-left corner of the page (0,0).

[call [arg pdfObj] [cmd npages]]
return the number of pages.

[call [arg pdfObj] [cmd getpage] [arg n]]
return a [arg pageObj] to be used in subsequent operations. See [sectref "mupdf::Page methods"]. Note that first page is page 0.
Note that if the requested page is currently opened, [cmd getpage] reuses the handle of the opened page.

[call [arg pdfObj] [cmd openedpages]]
return the list of all currently opened pages (as page-numbers) related to [arg pdfObj]

[call [arg pdfObj] [cmd ispageopened] [arg pageNum]]
return 1 if page [arg pageNum] is currently opened, else 0.

[call [arg pdfObj] [cmd closepage] [arg pageNum]]
close the page referred bu [arg pageNum]. No error is returned if [arg pageNum] does not
refer to an opened page.

[call [arg pdfObj] [cmd closeallpages]]
close all currently opened pages related to [arg pdfObj]

[call [arg pdfObj] [cmd fields]]
return a list of field-records. Each field-record is a list of three elements:
[list_begin itemized]
  [item] the field-name
  [item] the field-type ([const button], [const radiobutton],
   [const checkbox], [const text], [const combobox], [const listbox],
   [const signature] or [const unknown])
  [item] the field-value
[list_end]

Note that for a [const signature] field, if a signature is present
the returned field-value is simply the fixed string [const <<signature>>].

[call [arg pdfObj] [cmd field] [arg fieldname]]
return the field's value, or raise an error if [arg fieldname] is not a valid field.
[para]
Warning: field-names with accented characters or in general characters from latin alphabets are accepted (even not encorauged).
Fields-names with characters from non-latin alphabets (greek, russian, chinese, ...) are not supported.

[call [arg pdfObj] [cmd field] [arg fieldname] [arg value]]
set the field's value, or raise an error if [arg fieldname] is not a valid field.
[para]
Warning: see limitations in [sectref {Notes and limitations about field names and values}]
for details.

[call [arg pdfObj] [cmd fieldattrib] [arg fieldname]]
get all the field's attributes, as a list of [arg options]/[arg values], or raise an error if [arg fieldname] is not a valid field.
[para]
Currently supported [arg options] are:
[list_begin itemized]
    [item] [option -readonly]
[list_end]  

[call [arg pdfObj] [cmd fieldattrib] [arg fieldname] [opt "[arg options]"]]
set the field's attributes, or raise an error if [arg fieldname] is not a valid field.
[para]
Currently supported [arg options] are:
[list_begin itemized]
    [item] [option -readonly] [arg bool]
[list_end]  

[call [arg pdfObj] [cmd flattenfield] [arg fieldname] [opt "..."]]
flatten all the listed fields appearances (and removes all the listed fields from the field-table).
[para]
Note that flattening N fields with a single command is far more efficient than running N flattening commands; this is especially true for documents with many pages.

[call [arg pdfObj] [cmd signatures]]
return a list of signature field-records . Each field-record is a list of two elements:
[list_begin itemized]
  [item] the field-name
  [item] the field-value
[list_end]
Empty signature fields (blanc signatures) have a field-value equal to "" (empty string).
Currently, filled signature fields are simply denoted with the fixed string [const <<signature>>].

[call [arg pdfObj] [cmd addsigfield] [arg fieldname] [arg pageNumber] [arg x0] [arg y0] [arg x1] [arg y1]]
add a blank signature field on the page number [arg pageNumber] in a rectangular box at coords [arg x0] [arg y0] [arg x1] [arg y1].
[para]
[arg fieldname] must be unique among the existing field names.

[call [arg pdfObj] [cmd haschanges]]
return [const 1] if [arg pdfObj] has been changed, otherwise [const 0].

[call [arg pdfObj] [cmd export] [arg filename]]
save the current document and its changes in an alternative [arg filename].

Note that in general, [arg filename] should be different from the name of any pdf-file
currently opened in this process.
The only exception is when [arg filename] is the same name of [arg pdfObj], but in this
case you MUST quit [arg pdfObj] just after export. 

[call [arg pdfObj] [cmd portfolio] [cmd list]]
return the list of the embedded files

[call [arg pdfObj] [cmd portfolio] [cmd extract] [arg i]  [opt "[option -dir] [arg pathname]"]  [opt "[option -as] [arg filename]"]]
extract the [arg i-th] embedded file. ( i >= 0 ) 
If option [option -dir] is not specified, the embedded file is saved in the current directory.
[para]
If option [option -as] is not specified, embedded file is saved with its original name

[call [arg pdfObj] [cmd newsearch] [opt "[option -mode] [arg listOfFlags]"]]
return a new [arg searchObj] object for performing text-search on the [arg pdfObj] document. See [sectref "mupdf::TextSearch methods"]

[call [arg pdfObj] [cmd graft] [arg pageObj]]
import in the currently open document referred by [arg pdfObj] 
the full content of the page referred by [arg pageObj]. The page contents are just imported, not displayed,
and should be inserted in [arg pdfObj] via the next [cmd embed] command.
The result of [cmd graft] is a [arg graftID] that should be used by the next
[cmd {embed ...}] command for inserting the source page within one or more pages of the document.
[para]
Note: this page-image is not a raster-image; it's vector based and hence remains accurate across zooming levels.
[para]
Note: [arg graftID] is unique for each [emph {opened}] document [arg pdfObj] and it's valid until [arg pdfObj] is closed.

[call [arg pdfObj] [cmd grafts]]
return the list of the currently grafted pages

[call [arg pdfObj] [cmd embed] [arg graftID] [arg pageNumber] [opt "...options..."]]
embed a copy of a grafted page in the page referred by [arg pageNumber].
[para]
Valid options are:
[list_begin itemized]
  [item] [option -over] [arg bool] - displays the contents of the grafted page over (or below) the contents of the current page (default is [const true]).
  [item] [option -angle] [arg theta] - rotate the grafted imaged by [arg theta] degrees (-360.0 ..+360.0), Default is [const 0.0].
  [item] [option -zoom] [arg factor] - enlarge/shrink the grafted imaged by a factor of [arg factor]  (default is [const 1.0]).
  [item] [option -crop] [arg x0] [arg y0] [opt "[arg x1] [arg y1]"] - just copy a rectangular sub-region of the grafted image. 
(x0,y0) and (x1,y1) specify diagonally opposite corners of the rectangle; (0,0) is the upper-left corner of the (visible portion of the) grafted page.
If [arg x1] and [arg y1] are not specified, the default value is the bottom-right corner of the grafted page.
  [item] [option -to] [arg x0] [arg y0] - place the center of the grafted page at ([arg x0], [arg y0]). 
  If  this option is not specified then the grafted page is placed in the center of the destination page.
[list_end]

[list_end]

[subsection "Control on warning-messages"]

See the rationale for these commands in the section [sectref "Better control for MuPDF internal errors/warnings and repaired PDFs"]

[list_begin definitions]

[call [cmd mupdf::printwarnings] [opt "[arg boolValue]"]]
If [arg boolVal] is true, then all the next MUPDF warning-messages will be printed on stderr.
If [arg boolVal] is false, printing on stderr is suppressed (but you can still inspect them with the "[arg pdfObj] [method warnings]"" command)
If [arg boolValue] is missing, the current setting is returned (true/false)
The default setting is [const false].

[call [arg pdfObj] [cmd warnings]]
return a list with all the recorded MUPDF warning-messages.

[call [arg pdfObj] [cmd resetwarnings]]
reset the list of the warning-messages 

[call [arg pdfObj] [cmd wasrepaired]]
returns [const true] if the PDF was automatically repaired (and in this case you should find some details with the warnings method.)

[list_end] 



[subsection "mupdf::TextSearch methods"]
Instances of TextSearch objects allows to perform text-search on a given [arg pdfObj] document.
[para]
TextSearch object can be created in two ways:
[example_begin]
  set searchObj [lb]mupdf::TextSearch new [arg pdfObj] [opt "[option -mode] [arg listOfFlags]"][rb]
or
  set searchObj [lb][arg pdfObj] newsearch [opt "[option -mode] [arg listOfFlags]"][rb]
[example_end]

The [option -mode] option can be used to control the quality of extracted text.
Read more about it in the section [sectref "Text-Extraction & Text-Search Flags"].
[para]
Note that when [arg pdfObj] is closed, all its TextSearch instances are automatically destroyed.
[para]
TextSearch methods:

[list_begin definitions]

[call [arg searchObj] [cmd destroy]]
destroy the [arg searchObj] object.

[call [arg searchObj] [cmd find] [arg searchStr] [opt "[option -max] [arg hits]"] [opt "[option -currpageonly] [arg boolean]"] ]
search for the string [arg searchStr] starting from the current search-position.
Return a list of up to [arg hits] matches (default is 10); the current position is then accordling advanced.
The result of the [cmd find] subcommand is a list of [arg page-positions]. Each [arg page-positions] is a list of two elements:
[list_begin itemized]
  [item] the page-number
  [item] a list with the 4 coords of the box enclosing the searched [arg searchStr]
[list_end]
If option [option -currpageonly] is true, the search is limited to the page holding the current search-position.

[call [arg searchObj] [cmd currpage]]
return the current search-position as a page-number
[call [arg searchObj] [cmd currpage] [arg n]]
set the current search-position at the beginning of page [arg n].

[call [arg searchObj] [cmd docref]]
return a reference to the related pdf-document as a [arg pdfObj]

[list_end]


[subsection "mupdf::Page methods"]
A Page object can be created starting from a [arg pdfObj] document with the following command:
[example {
  set pageObj [$pdfObj getpage _n_]
}]
If the requested page is currently opened, [cmd getpage] reuses the handle of the opened page.
Note that when [arg pdfObj] is closed, all its opened pages are automatically closed/destroyed.


[list_begin definitions]

[call [arg pageObj] [cmd annots]]
return the list of annotations-ID on [arg pageObj]. Annotations ID are unique within the whole PDF. 

[call [arg pageObj] [cmd annot] [cmd get] [arg annotID]]
[call [arg pageObj] [cmd annot] [arg annotID]]
return the list of the [arg annotID]'s attributes. 
The special read-only attributes [const -type] is provided for each annotation.
 
[call [arg pageObj] [cmd annot] [cmd get] [arg annotID] [arg attribute]]
[call [arg pageObj] [cmd annot] [arg annotID] [arg attribute]]
get the value of [arg attribute] for the annotation [arg annotID].
 
[call [arg pageObj] [cmd annot] [cmd set] [arg annotID] [arg attribute] [arg value] [opt "[arg attribute] [arg value] ..."]]
[call [arg pageObj] [cmd annot] [arg annotID] [arg attribute] [arg value] [opt "[arg attribute] [arg value] ..."]]
set the the value of one or more attributes of the annotation [arg annotID].

[call [arg pageObj] [cmd annot] [cmd delete] [arg annotID] [opt "[arg annotID] ..."]]
delete one or more annotations

[call [arg pageObj] [cmd annot] [cmd flatten] [arg annotID] [opt "[arg annotID] ..."]]
flatten one or more annotations

[call [arg pageObj] [cmd annot] [cmd create] [arg type] [opt "[arg attribute] [arg value] ..."]]
create a new annotation and return a new [arg annotationID].
[para]
Currently supported types are: [const highlight], [const underline], [const strikeout], [const squiggly] and [const stamp].
[para]
Common attributes for each supported type are:
[list_begin itemized]
 [item] [option -color] tkcolor  - color must be a simbolic name (lightblue) or #RRGGBB
[list_end]
Specific options for [const highlight], [const underline], [const strikeout], [const squiggly] are:
[list_begin itemized]
 [item] [option -vertices] {[arg x0] [arg y0] [arg x1] [arg y1] ... }  - a list of 4x numbers denoting the bounding boxes of the text to be marked. Note: these coordinates are not necessarily related to the text on a page.
[list_end]
Specific options for [const stamp] are:
[list_begin itemized]
 [item] [option -xobject] [arg xObjectID] - the ID of a grafted page (see  [cmd graft] method )
 [item] [option -rotate]  [arg angle] - the rotation anngle (in degree)
 [item] [option -scale]   [arg s] - the zoom factor
 [item] [option -to] {[arg x0] [arg y0]}  - a list of 2 numbers.
 [list_end]
Note that the center of the [const stamp] will placed at the coords specified with the [option -to] option. If this option is missing, 
the center of the stamp will be placed in the centre of the page.   


[call [arg pageObj] [cmd blocks]]
return the list of image/text blocks in [arg pageObj]. A block is a list of 5 elements with the following format:
[para]
  [const textblock]|[const imageblock] [arg x0] [arg y0] [arg x1] [arg y1]

[call [arg pageObj] [cmd close]]
[call [arg pageObj] [cmd destroy]]
close and free all the resources of the page referred by [arg pageObj]. the object [arg pdfObj] is destroyed.

[call [arg pageObj] [cmd size]]
return the physical size of the page as a list of two decimal numbers. Note that page size is expressed in [emph points], i.e. 1/72 inch.

[call [arg pageObj] [cmd docref]]
return a reference to the related pdf-document as a [arg pdfObj]

[call [arg pageObj] [cmd pagenumber]]
return the pagenumber of [arg pageObj]

[call [arg pageObj] [cmd lines]]
return the list of the bbox of the text lines in [arg pageObj]. A bbox is a list of 4 elements with the following format:
[para]
  [arg x0] [arg y0] [arg x1] [arg y1]

[call [arg pageObj] [cmd text] [opt "[option -bbox] [const none]|[const blocks]|[const lines]"] [opt "[option -mode] [arg listOfFlags]"]]
extract the plain text from the page [arg pageObj] with the (optional) bounding-box of each block or line.
The [option -mode] option can be used to control the amount and the quality of extracted text.
Read more about it in the section [sectref "Text-Extraction & Text-Search Flags"].
[list_begin itemized]
[item] If [option -bbox] is missing or equal to [const none], this method returns just the plain text.
[item] If [option -bbox] is equal to [const blocks], this method returns a list like the following
[example {
  {bbox of 1st block} {plain text of the 1st block}
   ... 
  {bbox of the Nth block} {plain text of the Nth block}
}]
[item] If [option -bbox] is equal to [const lines], this method returns a list like the following
[example {
{bbox of the 1st block} {
  {bbox of the 1st line} {plain text of the 1st line} 
  ... 
  {bbox of the Nth line} {plain text of the Nth line}
} 
...
{bbox of the Nth block} {
  {bbox of the 1st line} {plain text of the 1st line} 
  ... 
  {bbox of the Nth line} {plain text of the Nth line}
} 
}]
[list_end]

[call [arg pageObj] [cmd savePNG] [arg filename] [opt "[option -zoom] [arg zoom]"] [opt "[option -from] [arg x0] [arg y0] [arg x1] [arg y1]"] [opt "[option -overlay] [arg true/false]"]]
render the page in a .png file named [arg filename].
[para]
With a default [option -zoom] factor equal to [const 1.0], a page whose size is W x H [emph points]
is rendered as a raster image of W x H [emph pixels].
If [option -zoom] is specified, the resulting image size is scaled by a factor of [arg zoom].
[para]
By default the whole page is rendered; the [option -from] option, allows you to
render only a given rectangular area of the page. [arg x0] [arg y0] are the coords
of the  top-left corner and [arg x1] [arg y1] are for the bottom-right corner.
These coords must be expressed in terms of the physical size of the page, i.e in [emph points]
Note that if these coords lies outside of the page, only the [emph intersection] of this area with the page area is rendered.
If the [option -overlay] option is set to [const true] then the page is rendered with a transparent background, else if it set to [const false] (default)
the page is rendered with a white background.
[example {
  ...
  set page [$pdf getpage 0]   ;# 0 is the 1st page
  lassign [$page size] dx dy
   # save just the upper half of the page
  $page savePNG /mydir/page0.png -zoom 2.25 -from 0 0 $dx [expr $dy/2]
  ...
}]

[call [arg pageObj] [cmd saveImage] [arg image] [opt "[option -zoom] [arg zoom]"] [opt "[option -from] [arg x0] [arg y0] [arg x1] [arg y1]"] [opt "[option -to] [arg x0] [arg y0]"] [opt "[option -overlay] [arg true/false]"]]
render the page in an existing Tk's photo [arg image].
[para]
The width and/or height of [arg image] are unchanged if the user has set on it
an explicit image width or height (with the -width and/or -height configuration options, respectively).
[para]
About the [option -zoom], [option -from] and [option -overlay] options, the same rules for the [cmd savePNG] apply.
Option [option -to] allows you to place the resulting raster image at the [arg x0] [arg y0] coords of the destination [arg image].
By default, is [option -to] [const 0.0] [const 0.0]
[para]
NOTE: this command is not available with the package [package tclMuPDF].


[call [arg pageObj] [cmd images] [cmd list] [opt "[option -id] [arg imageID]"]] 
return a list of all the images contained in the page referred by [arg pageObj].
[para]
The result of [cmd images] [cmd list] subcommand is a list of [arg image-records]. Each [arg image-record] is a list of six elements:
[list_begin itemized]
  [item] image-ID   (unique for each page)
  [item] image's width  (in pixel)
  [item] image's height  (in pixel)
  [item] image's colorspace (e.g. DeviceRGB, ICCBased, ...)
  [item] image's bit per component  (number of color components may be inferred from colorspace)
  [item] mask-flag :  [const 1] means that the image has a pixel-mask (i.e. some transparent pixels)
[list_end]
If option [option -id] is present, the resulting list is limited to the [arg image-record] for [arg imageID].

[call [arg pageObj] [cmd images] [cmd extract] [opt "[option -id] [arg imageID]"] [opt "[option -dir] [arg pathname]"]  [opt "[option -as] [arg pattern]"] [opt "[option -transparency] [arg boolean]"]] 
if option [option -id] is specified, extract and save the image referred by [arg imageID] (see [cmd images] [cmd list]).
If option [option -id] is missing, all the images contained in a page are extracted and saved.
[para]
If option [option -dir] is not specified, images are saved in the current directory.
[para]
If option [option -as] is not specified, images are saved with a name derived from the default [cmd mupdf::imagenamesformat] (see below), otherwise images
are saved as [arg pattern] (for [arg pattern] rules see below for [cmd mupdf::imagenamesformat]).
[para]
if option [option -transparency] is [const true], save the (semi)transparent pixels (if any), otherwise transparent pixels (if any) are rendered as white pixels.
[para]
[cmd extract] returns a list of [arg extracted-records]. Each [arg extracted-record] is a list of three elements:
[list_begin itemized]
  [item] image-ID   (unique for each page)
  [item] image-name (pdf page's internal name)
  [item] saved filename   (empty string if the image was skipped (unknow format...))
[list_end]

[call [cmd mupdf::imagenamesformat] [opt [arg pattern]]] 
a [arg pattern] is a parametric filename specification similar to the format specification
used by the C printf function.
[para]
If [arg pattern] is not specified, return the currently defined default pattern.
If [arg pattern] is specified, set the default pattern.
[para]
When the "[arg pageObj] [cmd images] [cmd extract] ..." command is called, all the images are saved
with a filename based on a [arg pattern] (This pattern can be explicit,  if option [option -as] is present,
 or it can be implicit, based on the default [cmd mupdf::imagenamesformat]).
[para]
a [arg pattern] is a a simple filename specification 
(just the base-name, since the extension of the extracted images (png, jpg, ...) is automatically determined.)
 with zero or more special symbols like the following ones:
[list_begin itemized]
  [item] %p  : page number (first page is 1)
  [item] %P  : total number of pages
  [item] %i  : image number - images in a page are numbered starting from 1
  [item] %I  : total number of images (in the current page)
[list_end]
Special symbols may also be written with a padding-specification like [const %5P]; this notation means the the symbol %P
should be padded as a 5-character string with leading '0's.
[para]
If more than one image is extracted in a single operation, and [arg pattern] does
not contain the [const %i] symbol (the image number), then [const -%i] is 
implicitely appended in order to avoid a filename collision.
[para]
Assuming that the current page is the page 123 (i.e the 124th page), the following command
[example {
  $pageObj images extract -as "IMG_%5p"
}]
will generate IMG_00124-1.jpg, IMG_00124-2.jpg .....   (note: the file extension may be different)
[example {
  $pageObj images extract -as "Z%5p(%2i)"
}]  
will generate Z00124(01).jpg, Z00124(02).jpg .....   (note: the file extension may be different)

[list_end]


[subsection "MuPDF introspection commands"]
[list_begin definitions]

[call [cmd mupdf::isobject] [arg obj]] 
return 1 if [arg obj] is an oo-object (not limited to MuPDF objects).

[call [cmd mupdf::classes]] 
returns the list of the oo-classes of [package MuPDF]

[call [cmd mupdf::classinfo] [arg obj]] 
return the oo::class of [arg obj] (not limited to MuPDF objects)

[call [cmd mupdf::documents]] 
return a list of the currently opened [arg pdfObjs]

[call [cmd mupdf::documentnames]]
return a list of pdf-filenames currently opened (fully normalized filenames).

[call [cmd mupdf::isopen] [arg filename]] 
check if [arg filename] is among the currently opened pdf-files.

[call [cmd mupdf::Doc] [cmd names]]
[call [cmd mupdf::Page] [cmd names]]
[call [cmd mupdf::TextSearch] [cmd names]]
return a list of all the instances of Doc, Page, TextSearch.
Note that when a Doc is destroyed, all its related Pages and TextSearch are destroyed, too.



[call [cmd mupdf::cli_passwordhelper] [opt "[option helperProc]"]]
get/set the helper procedure for shell-like applications. 
If [option helperProc] is [const ""], then the default helper is re-set.
See section [sectref "Working with Password Protected Files"]. 

[call [cmd mupdf::tk_passwordhelper] [opt "[option helperProc]"]]
get/set the helper procedure for applications with a Tk graphical interface.
If [option helperProc] is [const ""], then the default helper is re-set.
See section [sectref "Working with Password Protected Files"]. 

[call [cmd mupdf::libinfo]]
return specific attributes of the underlying MuPdf libray as a list of keywords and their values.
The provided keywords are: 
 [list_begin definitions]
 [def [const version]]
  The version of the underlying MuPDf library

 [def "..more to come .."]
  
 [list_end]  

[list_end]

  
[comment =====================================================================]
[section {Working with Password Protected Files}]

You can open a password-protected PDF in a non-interactive or in an interactive way.
[para]
In non-interactive mode, you must provide in advance a password 
[example {
  set pdf [mupdf::open book.pdf -password "123open"]
}]
If password is wrong then an error is raised; look at the error message
and check for the errorcode: it should be [const "MUPDF WRONGPASSWORD"].
Note that there's no distinction between owner's password and user's password; if 
you provide the right owner's password, the PDF is opened in owner-mode, if you provide
the right user's password, the PDF is opened in user-mode.
[para]
You can check if PDF has been opened in user-mode or owner-mode by calling the [cmd authentication] command.
[example {
  set pdf [mupdf::open book.pdf -password "123open"]
   # if we are here, it means that password was OK
  set mode [$pdf authentication]
   # "none" means that book.pdf was not password-protected
   # "user" means that the supplyed password was the user's password
   # "owner" means ...
}]

In interactive mode, you should not provide an explicit password;
if the PDF is password-protected, [package MuPDF] will ask for a password. 
[para]
Depending on the nature of your application (with or without Tk), [package mupdf]
will select and call a predefined (yet customizable) helper procedure.
These predefined, built-in procedures can be changed with the [cmd mupdf::cli_passwordhelper]
or [cmd mupdf::tk_passwordhelper] command.
[example {
   # template for a (shell-like) password-helper procedure
   proc mypswdhelper {filename} {
       ...  ask for a password ....
       .... get the password ....
       ....
       return $password    
   }
  mupdf::cli_passwordhelper mypswdhelper

   # template for a (GUI) password-helper procedure
   proc myGUIpswdhelper {filename} {
       ...  raise some popup ...
       ...  ask for a password ....
       .... get the password ...
       .... close the popup
       return $password    
   }
  mupdf::tk_passwordhelper myGUIpswdhelper
}]

[section {Removing protection from a password protected files}]
If you open a password-protected file and export it, by default the resulting PDF
is saved without password.
You can explicitely control this behaviour by appending the [option -decrypt] option
to the [cmd export] or [cmd close] commands (default is [option -decrypt] [const true]).

[section {Adding or changing a password}]
After opening a PDF, you can add or change the user/owner password with the [cmd opwd]
or the [cmd upwd]commands,like in the following example
[example {
  set pdf [mupdf::open mybook.pdf]
   # if mybook.pdf is proteccted, insert the password

  $pdf upwd "my user-password"
  $pdf opwd "my owner-password"
  $pdf close  ;# ..or $pdf export ...
}]

[comment =====================================================================]
[section "Better control for MuPDF internal errors/warnings and repaired PDFs"]

In many cases MuPDF (the core library) is able to work with bad/corrrupted PDFs,
and if the errors are not critical, the 'repaired' PDF is opened as a good PDF.
[para]
By default MuPDF prints on stderr all these errors/warning; if the error is critical MuPDF raises an error (and so tclMuPDF), but if the malformed PDF can be automatically repaired,
no error is raised, just some messages are printed on stderr.
[para]
With the previous tclMuPDF release (2.1) we completely suppressed all these (non-critical) warning-messages generated by the core-MuPDF.
This was an useful feature because many of those messages were annoying and rarely useful, but there are still some cases that shouldn't be ignored
because in some cases the automatically repaired PDFs may be still inconsistent or damaged in some other parts.
[para]
Starting with tclMuPDf 2.1.1 we added some new commands and methods, for a better control on these warning-messages: 

[list_begin itemized]
[item] [cmd mupdf::printwarnings]
[item] [arg pdfObj] [method warnings]
[item] [arg pdfObj] [method resetwarnings]
[item] [arg pdfObj] [method wasrepaired]
[list_end]

By using "[cmd mupdf::printwarnings]" tou can enable/disable the warning-messages.
By default printing on stderr is disabled, but if you set "[cmd mupdf::printwarnings] [const true]"
then all the next errors/warnings will be printed on stderr.
[para]
Even if printing is globally disabled, all the MUPDF warning-messages are still recorded
and they can be inspected with the command "[arg pdfObj] [method warnings]".  
Note that each opened document [arg pdfObj] has its own list of warnings.
[para]
The command "[arg pdfObj] [method resetwarnings]" resets all the warnings bound to the [arg pdfObj] document; of course when the document is closed/deleted,
all its related warnings are deleted.
[para]
Finally, the "[arg pdfObj] [method wasrepaired]" command can be used for checking 
if [arg pdfObj] was automatically repaired, so you can decide to quit or keep on working with the repaired [arg pdfObj].


[comment =====================================================================]
[section {Notes and limitations about field names and values}]
Due to current limitations of the underlying MuPdf library, field names and values
should be limited to latin alphabets only.
See the note enclosed with MuPdf's BUG 696478 (Nov 2018):
[para]
[emph {
... "There is, however, a limitation with our form filling support that still
     needs to be addressed: it only supports PDFDocEncoding, not Unicode.
}]
[para]
[emph {
...   "We can currently fill out the form fields in any language, 
    but the display code still only handles the Latin alphabet."
}]
[para]
This means that you can enter text in a form field in any alphabet
(tested with Russian, Chinese, Greek, ...) but the rendered text for the non-latin alphabets
will appear wrong.
[para]
Another major limitation is the rendering of fields other that 'text' widgets, i.e. checkbox, radiobuttons...
For these kind of widgets the support of the underlying library is still incomplete,
in particular for values expressed in non-ASCII characters (e.g. accented letters ... )

[comment =====================================================================]
[section {Text-Extraction & Text-Search Flags}]
Extracting text from a PDF is still a matter of magic art. Different PDF-tools provide different results,
based on their own internal rules and assumptions. MuPDF text-extraction is far to be perfect, (MuPDF claims it's an experimental features), but starting with
release 2.3, [package tclMuPDF] provides some explicit flags that can be used for tuning the text-extraction logic.
They control how text should be handled with respect to white spaces, hyphenation and ligatures.
[para]
The following basic text-extraction command
[example {
	$pageObj text ..other options.. 
}]
is equivalent to
[example {
	$pageObj text -mode {preserve-ligatures preserve-whitespace} ..other options..
}]
Similarly, the following command for creating a text-search object
[example {
	set searchObj [$pdfObj newsearch]
}]
is equivalent to
[example {
	set searchObj [$pdfObj newsearch -mode {preserve-whitespace dehyphenate}]
}]


In general, text-extraction/search flags can be combined in a list for the [option -mode] option.
Be aware that if you specify the [option -mode] option, you must set all desired options.
[para]
These are the currently available flag, both for text-extraction and text-search:

[list_begin itemized]
[item][const preserve-ligatures]

    If set, ligatures are passed through to the application in their original form.
	Otherwise ligatures are expanded into their constituent parts, e.g. the ligature “ffi” 
	is expanded into three separate characters f, f and i. 
	MuPDF supports the following 7 ligatures: “ff”, “fi”, “fl”, “ffi”, “ffl”, , “ft”, “st”.

[item][const preserve-whitespace]

    If set, whitespace is passed through in its original form.
	Otherwise any type of horizontal whitespace (including horizontal tabs) 
	will be replaced with space characters of variable width

[item][const inhibit-spaces]

    If set, Mupdf will not try to add missing space characters where there are large
	gaps between characters.
	In PDF, the creator often does not insert spaces to point to the next character’s position,
	but will provide the direct location address. 

[item][const dehyphenate]
    Ignore hyphens at line ends and join with next line.
	if set, text extractions will return joined text lines (or spans)
	with the ending hyphen of the first line removed.
	So two separate spans “first meth-” and “od leads to wrong results” on different 
	lines will be joined to one span “first method leads to wrong results” 
	and correspondingly updated bboxes: the characters of the resulting span will
	no longer have identical y-coordinates.

[item][const preserve-spans]
	If this option is set, spans on the same line
	will not be merged. Each line will thus be a span of text with the same
	font, colour, and size.

[list_end]


[comment =====================================================================]
[section {Limitations}]
Full support for [cmd portfolio] management is still incomplete; commands for 
adding/removing/reordering embedded files will require a more robust mupdf-core implementation.

[comment =====================================================================]
[section "From mupdf 1.x to MuPDF 2.x"]
[subsection "New commands and methods"]
[list_begin definitions]

[def "[arg pdfObj] [cmd removepassword]"]
[def "[arg pdfObj] [cmd ispageopened]"]
[def "[arg pdfObj] [cmd closepage]"]
[def "[arg pdfObj] [cmd flatten]"]
[def "[arg pdfObj] [cmd grafts]"]
[def "[cmd "mupdf::classes"]"]
[def "[cmd "mupdf::classinfo"] [arg obj]"]
[list_end]

[subsection "Changed commands and methods"]
[list_begin definitions]

[def [cmd "package require mupdf"]]
[def [cmd "package require mupdf-notk"]]
	With the release 2.x these package names are no more valid.
	Use:
	[list_begin itemized]
		[item] package require tclMuPDF ;# replacement for "mupdf-notk"
		[item] package require tkMuPDF  ;# replacement for "mupdf"
		[item]package require MuPDF    ;# replacemente for "mupdf"
	[list_end]

[def "[arg pdfObj] [cmd openedpages]"]
	now returns a list of page-numbers.
	Formerly it returned a list of [arg pageObj]

[def "[arg pdfObj] [cmd close]  options"]
options [option -flatten] and [option -decrypt] are no more supported.
In case you need to flatten the fields or remove the password, you should call
  the new "[arg pdfObj] [cmd flatten]" or "[arg pdfObj] [cmd removepassword]" methods before
[arg pdfObj] [cmd close] 

[def "[arg pdfObj] [cmd flattenfield] ..."]
has been replaced by "[arg pdfObj] [cmd flatten] ..."

[def "[arg pdfObj] [cmd addsigfield] [arg fieldname]  [arg pageNum] [arg "x0 y0 x1 y1"]"]
	changed parameters order and signature

[def "[arg pdfObj] [cmd embed] ..."]
	changed parameters order and signature


[def "[arg pdf] [cmd export] ..."]
options [option -flatten] and [option -decrypt] have been removed.
In case you need to flatten the fields or remove the password, you should call
the new "[arg pdfObj] [cmd flatten]"" or "[arg pdfObj] [cmd removepassword]" methods before
[arg pdfObj] [cmd export] 

[def "[arg pageObj] [cmd annot] [cmd delete] [arg annotID] ..."]
	replaces "[arg pageObj] [cmd annot] [arg annotID] [cmd delete]"
	
[def "[arg pageObj] [cmd annot] ..."]
	Formerly colors were expressed as a triple {R G B}. (0<=R,G,B<=1.0)
	Now colors should be expressed as tk-color (e.g "lightblue" or #223312).
[list_end]


  
[subsection "Removed commands and methods"]
[list_begin definitions]

[def "32 bit"]
Removed support for Linux-32bit and Windows-32 bit 

[def [cmd "package require mupdf"]]
[def [cmd "package require mupdf-notk"]]

[def "[arg pdfObj] [cmd flattenfield] ..."]
	Renamed as "[arg pdfObj] [cmd flatten] ..."

[def "[arg pdfObj] [cmd canbesavedincrementally]"]
	Still present but deprecated.

[def "[arg pdfObj] [cmd search] ..."]
	Use the "[arg pdfObj] [cmd newsearch]" command and the [class mupdf::TextSearch] methods.
	
[def "[arg pageObj] [cmd embed] ..."]
	Replaced by "[arg pdfObj] [cmd embed] ..."

[def "[cmd mupdf::quit] [arg pdfObj]"]
[def "[cmd mupdf::close] [arg pdfObj]"]
[def "[cmd mupdf::close] [arg pageObj]"]

[def "[cmd mupdf::type] [arg obj]"]
	Use "[cmd mupdf::classinfo] [arg obj]"
[list_end]


[keywords PDF]
[manpage_end]