diff options
author | Luigi Scarso <luigi.scarso@gmail.com> | 2019-01-06 19:35:42 +0000 |
---|---|---|
committer | Luigi Scarso <luigi.scarso@gmail.com> | 2019-01-06 19:35:42 +0000 |
commit | 522dfa21dfa73176aedd7412314b510564144cfc (patch) | |
tree | a8a2796313a30d939d99f74f6e0df648f1259148 /Master/texmf-dist/doc/luatex/base/luatex-backend.tex | |
parent | 0c14fd18747b9f6fbbecb75ba8beef6d449c460a (diff) |
updated reference manual for luatex 1.09.2
git-svn-id: svn://tug.org/texlive/trunk@49615 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/doc/luatex/base/luatex-backend.tex')
-rw-r--r-- | Master/texmf-dist/doc/luatex/base/luatex-backend.tex | 2127 |
1 files changed, 1084 insertions, 1043 deletions
diff --git a/Master/texmf-dist/doc/luatex/base/luatex-backend.tex b/Master/texmf-dist/doc/luatex/base/luatex-backend.tex index 46e9222e289..0ec9be9b0f7 100644 --- a/Master/texmf-dist/doc/luatex/base/luatex-backend.tex +++ b/Master/texmf-dist/doc/luatex/base/luatex-backend.tex @@ -1,1043 +1,1084 @@ -% language=uk - -\environment luatex-style -\environment luatex-logos - -\startcomponent luatex-backend - -\startchapter[reference=backend,title={The backend libraries}] - -\section{The \type {pdf} library} - -This library contains variables and functions that are related to the \PDF\ -backend. You can find more details about the expected values to setters in \in -{section} [backendprimitives]. - -\subsection{\type {mapfile}, \type {mapline}} - -\startfunctioncall -pdf.mapfile(<string> map file) -pdf.mapline(<string> map line) -\stopfunctioncall - -These two functions can be used to replace primitives \type {\pdfmapfile} and -\type {\pdfmapline} inherited from \PDFTEX. They expect a string as only -parameter and have no return value. The first character in a map line can be -\type {-}, \type {+} or \type {=} which means as much as remove, add or replace -this line. - -\subsection {\type {[set|get][catalog|info|names|trailer]}} - -These functions complement the corresponding \PDF\ backend token lists dealing -with metadata. The value types are strings and they are written out to the \PDF\ -file directly after the token registers. - -\subsection {\type {[set|get][pageattributes|pageresources|pagesattributes]}} - -These functions complement the corresponding \PDF\ backend token lists dealing -with page resources. The variables have no interaction with the corresponding \PDF\ -backend token register. They are written out to the \PDF\ file directly after the -token registers. - -\subsection{\type {[set|get][xformattributes|xformresources]}} - -These functions complement the corresponding \PDF\ backend token lists dealing -with reuseable boxes and images. The variables have no interaction with the -corresponding \PDF\ backend token register. They are written out to the \PDF\ -file directly after the token registers. - -\subsection{\type {getversion} and \type {[set|get]minorversion}} - -The version is frozen in the binary but you can set the minor version. What minor -version you set depends on what \PDF\ features you use. This is out of control -of \LUATEX. - -\subsection{\type {getcreationdate}} - -This function returns a string with the date in the format that ends up in the -\PDF\ file, in this case it's: {\tttf \cldcontext{pdf.getcreationdate()}}. - -\subsection{\type {[set|get]inclusionerrorlevel}, \type {[set|get]ignoreunknownimages}} - -These variable control how error in included image are treated. They are modeled -after the \PDFTEX\ equivalents. - -\subsection{\type {[set|get]suppressoptionalinfo}} - -This bitset determnines what kind of info gets flushes. By default we flush all. - -\subsection{\type {[set|get]trailerid}} - -You can set your own trailer id. This has to be a valid array string -with checksums. - -\subsection{\type {[set|get]compresslevel}} - -These two functions set the level of compression. The minimum value is~0, -the maximum is~9. - -\subsection{\type {[set|get]objcompresslevel}} - -These two functions set the level of compression. The minimum value is~0, -the maximum is~9. - -\subsection{\type {[set|get]gentounicode}} - -This flag enables tounicode generation (like in \PDFTEX). - -\subsection{\type {[set|get]omitcidset}} - -This flag disables inclusion of a so called CIDSet which can be handy when aiming -at some of the many \PDF\ substandards. - -\subsection{\type {[set|get]decimaldigits}} - -These two functions set the accuracy of floats written to the \PDF file. You can -set any value but the backend will not go below~3 and above~6. - -\subsection{\type {[set|get]pkresolution}} - -These setter takes two arguments: the resolution and an optional zero or one that -indicates if this is a fixed one. The getter returns these two values. - -\subsection{\type {getlast[obj|link|annot]} and \type {getretval}} - -These status variables are similar to the ones traditionally used in the backend -interface at the \TEX\ end. - -\subsection{\type {maxobjnum} and \type {objtype}, \type {fontname}, \type {fontobjnum}, -\type {fontsize}, \type {xformname}}. - -These (and some other) introspective helpers were moved from the the \type {tex} -namespace to the \type {pdf} namespace but kept their original names. They are -mostly used when you construct \PDF\ objects yourself and need for instance -information about a (to be) embedded font. - -\subsection{\type {[set|get]origin}} - -This one is used to set the horizonal and|/|or vertical offset, a traditional -backend property. - -\starttyping -pdf.setorigin() -- sets both to 0pt -pdf.setorigin(tex.sp("1in")) -- sets both to 1in -pdf.setorigin(tex.sp("1in"),tex.sp("1in")) -\stoptyping - -The counterpart of this function returns two values. - -\subsection{\type {[set|get]imageresolution}} - -These two functions relate to the imageresolution that is used when the image -itself doesn't provide a non|-|zero x or y resolution. - -\subsection {\type {[set|get][link|dest|thread|xform]margin}} - -These functions can be used to set and retrieve the margins that are added to the -natural bounding boxes of the respective objects. - -\subsection {\type {get[pos|hpos|vpos]}} - -These function get current location on the output page, measured from its lower -left corner. The values return scaled points as units. - -\starttyping -local h, v = pdf.getpos() -\stoptyping - -\subsection {\type {[has|get]matrix}} - -The current matrix transformation is available via the \type {getmatrix} command, -which returns 6 values: \type {sx}, \type {rx}, \type {ry}, \type {sy}, \type -{tx}, and \type {ty}. The \type {hasmatrix} function returns \type {true} when a -matrix is applied. - -\starttyping -if pdf.hasmatrix() then - local sx, rx, ry, sy, tx, ty = pdf.getmatrix() - -- do something useful or not -end -\stoptyping - -\subsection {\type {print}} - -You can print string to the \PDF\ document from within a within a \type -{\latelua} call. This function is not to be used inside \type {\directlua} unless -you know {\it exactly} what you are doing. - -\startfunctioncall -pdf.print(<string> s) -pdf.print(<string> type, <string> s) -\stopfunctioncall - -The optional parameter can be used to mimic the behavior of \PDF\ literals: the -\type {type} is \type {direct} or \type {page}. - -\subsection {\type {immediateobj}} - -This function creates a \PDF\ object and immediately writes it to the \PDF\ file. -It is modelled after \PDFTEX's \type {\immediate} \type {\pdfobj} primitives. All -function variants return the object number of the newly generated object. - -\startfunctioncall -<number> n = - pdf.immediateobj(<string> objtext) -<number> n = - pdf.immediateobj("file", <string> filename) -<number> n = - pdf.immediateobj("stream", <string> streamtext, <string> attrtext) -<number> n = - pdf.immediateobj("streamfile", <string> filename, <string> attrtext) -\stopfunctioncall - -The first version puts the \type {objtext} raw into an object. Only the object -wrapper is automatically generated, but any internal structure (like \type {<< ->>} dictionary markers) needs to provided by the user. The second version with -keyword \type {file} as first argument puts the contents of the file with name -\type {filename} raw into the object. The third version with keyword \type -{stream} creates a stream object and puts the \type {streamtext} raw into the -stream. The stream length is automatically calculated. The optional \type -{attrtext} goes into the dictionary of that object. The fourth version with -keyword \type {streamfile} does the same as the third one, it just reads the -stream data raw from a file. - -An optional first argument can be given to make the function use a previously -reserved \PDF\ object. - -\startfunctioncall -<number> n = - pdf.immediateobj(<integer> n, <string> objtext) -<number> n = - pdf.immediateobj(<integer> n, "file", <string> filename) -<number> n = - pdf.immediateobj(<integer> n, "stream", <string> streamtext, <string> attrtext) -<number> n = - pdf.immediateobj(<integer> n, "streamfile", <string> filename, <string> attrtext) -\stopfunctioncall - -\subsection{\type{obj}} - -This function creates a \PDF\ object, which is written to the \PDF\ file only -when referenced, e.g., by \type {refobj()}. - -All function variants return the object number of the newly generated object, and -there are two separate calling modes. The first mode is modelled after \PDFTEX's -\type {\pdfobj} primitive. - -\startfunctioncall -<number> n = - pdf.obj(<string> objtext) -<number> n = - pdf.obj("file", <string> filename) -<number> n = - pdf.obj("stream", <string> streamtext, <string> attrtext) -<number> n = - pdf.obj("streamfile", <string> filename, <string> attrtext) -\stopfunctioncall - -An optional first argument can be given to make the function use a previously -reserved \PDF\ object. - -\startfunctioncall -<number> n = - pdf.obj(<integer> n, <string> objtext) -<number> n = - pdf.obj(<integer> n, "file", <string> filename) -<number> n = - pdf.obj(<integer> n, "stream", <string> streamtext, <string> attrtext) -<number> n = - pdf.obj(<integer> n, "streamfile", <string> filename, <string> attrtext) -\stopfunctioncall - -The second mode accepts a single argument table with key--value pairs. - -\startfunctioncall -<number> n = pdf.obj { - type = <string>, - immmediate = <boolean>, - objnum = <number>, - attr = <string>, - compresslevel = <number>, - objcompression = <boolean>, - file = <string>, - string = <string> -} -\stopfunctioncall - -The \type {type} field can have the values \type {raw} and \type {stream}, this -field is required, the others are optional (within constraints). - -Note: this mode makes \type{obj} look more flexible than it actually is: the -constraints from the separate parameter version still apply, so for example you -can't have both \type {string} and \type {file} at the same time. - -\subsection {\type {refobj}} - -This function, the \LUA\ version of the \type {\pdfrefobj} primitive, references an -object by its object number, so that the object will be written out. - -\startfunctioncall -pdf.refobj(<integer> n) -\stopfunctioncall - -This function works in both the \type {\directlua} and \type {\latelua} environment. -Inside \type {\directlua} a new whatsit node \quote {pdf_refobj} is created, which -will be marked for flushing during page output and the object is then written -directly after the page, when also the resources objects are written out. Inside -\type {\latelua} the object will be marked for flushing. - -This function has no return values. - -\subsection {\type {reserveobj}} - -This function creates an empty \PDF\ object and returns its number. - -\startfunctioncall -<number> n = pdf.reserveobj() -<number> n = pdf.reserveobj("annot") -\stopfunctioncall - -\subsection {\type {registerannot}} - -This function adds an object number to the \type {/Annots} array for the current -page without doing anything else. This function can only be used from within -\type {\latelua}. - -\startfunctioncall -pdf.registerannot (<number> objnum) -\stopfunctioncall - -\subsection {\type {newcolorstack}} - -This function allocates a new color stack and returns it's id. The arguments -are the same as for the similar backend extension primitive. - -\startfunctioncall -pdf.newcolorstack("0 g","page",true) -- page|direct|origin -\stopfunctioncall - -\subsection {\type {setfontattributes}} - -This function will force some additional code into the font resource. It can for -instance be used to add a custom \type {ToUnicode} vector to a bitmap file. - -\startfunctioncall -pdf.setfontattributes(<number> font id, <string> pdf code) -\stopfunctioncall - -\section {The \type {pdfscanner} library} - -The \type {pdfscanner} library allows interpretation of \PDF\ content streams and -\type {/ToUnicode} (cmap) streams. You can get those streams from the \type -{epdf} library, as explained in an earlier section. There is only a single -top|-|level function in this library: - -\startfunctioncall -pdfscanner.scan (<Object> stream, <table> operatortable, <table> info) -\stopfunctioncall - -The first argument, \type {stream}, should be either a \PDF\ stream object, or a -\PDF\ array of \PDF\ stream objects (those options comprise the possible return -values of \type {<Page>:getContents()} and \type {<Object>:getStream()} in the -\type {epdf} library). - -The second argument, \type {operatortable}, should be a \LUA\ table where the -keys are \PDF\ operator name strings and the values are \LUA\ functions (defined -by you) that are used to process those operators. The functions are called -whenever the scanner finds one of these \PDF\ operators in the content stream(s). -The functions are called with two arguments: the \type {scanner} object itself, -and the \type {info} table that was passed are the third argument to \type -{pdfscanner.scan}. - -Internally, \type {pdfscanner.scan} loops over the \PDF\ operators in the -stream(s), collecting operands on an internal stack until it finds a \PDF\ -operator. If that \PDF\ operator's name exists in \type {operatortable}, then the -associated function is executed. After the function has run (or when there is no -function to execute) the internal operand stack is cleared in preparation for the -next operator, and processing continues. - -The \type {scanner} argument to the processing functions is needed because it -offers various methods to get the actual operands from the internal operand -stack. - -A simple example of processing a \PDF's document stream could look like this: - -\starttyping -function Do (scanner, info) - local val = scanner:pop() - local name = val[2] -- val[1] == 'name' - local resources = info.resources - local xobject = resources:lookup("XObject"):getDict():lookup(name) - print (info.space ..'Use XObject '.. name) - if xobject and xobject:isStream() then - local dict = xobject:getStream():getDict() - if dict then - local name = dict:lookup("Subtype") - if name:getName() == "Form" then - local newinfo = { - space = info.space .. " " , - resources = dict:lookup("Resources"):getDict() - } - pdfscanner.scan(xobject, operatortable, newinfo) - end - end - end -end - -operatortable = { Do = Do } - -doc = epdf.open(arg[1]) -pagenum = 1 - -while pagenum <= doc:getNumPages() do - local page = doc:getCatalog():getPage(pagenum) - local info = { - space = " " , - resources = page:getResourceDict() - } - print('Page ' .. pagenum) - pdfscanner.scan(page:getContents(), operatortable, info) - pagenum = pagenum + 1 -end -\stoptyping - -This example iterates over all the actual content in the \PDF, and prints out the -found \type {XObject} names. While the code demonstrates quite some of the \type -{epdf} functions, let's focus on the type \type {pdfscanner} specific code -instead. - -From the bottom up, the following line runs the scanner with the \PDF\ page's -top-level content. - -\starttyping - pdfscanner.scan(page:getContents(), operatortable, info) -\stoptyping - -The third argument, \type {info}, contains two entries: \type {space} is used to -indent the printed output, and \type {resources} is needed so that embedded \type -{XForms} can find their own content. - -The second argument, \type {operatortable} defines a processing function for a -single \PDF\ operator, \type {Do}. - -The function \type {Do} prints the name of the current \type {XObject}, and then -starts a new scanner for that object's content stream, under the condition that -the \type {XObject} is in fact a \type {/Form}. That nested scanner is called -with new \type {info} argument with an updated \type {space} value so that the -indentation of the output nicely nests, and with an new \type {resources} field -to help the next iteration down to properly process any other, embedded \type -{XObject}s. - -Of course, this is not a very useful example in practise, but for the purpose of -demonstrating \type {pdfscanner}, it is just long enough. It makes use of only -one \type {scanner} method: \type {scanner:pop()}. That function pops the top -operand of the internal stack, and returns a \LUA\ table where the object at index -one is a string representing the type of the operand, and object two is its -value. - -The list of possible operand types and associated \LUA\ value types is: - -\starttabulate[|l|c|] -\NC \type{integer} \NC <number> \NC \NR -\NC \type{real} \NC <number> \NC \NR -\NC \type{boolean} \NC <boolean> \NC \NR -\NC \type{name} \NC <string> \NC \NR -\NC \type{operator} \NC <string> \NC \NR -\NC \type{string} \NC <string> \NC \NR -\NC \type{array} \NC <table> \NC \NR -\NC \type{dict} \NC <table> \NC \NR -\stoptabulate - -In case of \type {integer} or \type {real}, the value is always a \LUA\ (floating -point) number. - -In case of \type {name}, the leading slash is always stripped. - -In case of \type {string}, please bear in mind that \PDF\ actually supports -different types of strings (with different encodings) in different parts of the -\PDF\ document, so may need to reencode some of the results; \type {pdfscanner} -always outputs the byte stream without reencoding anything. \type {pdfscanner} -does not differentiate between literal strings and hexadecimal strings (the -hexadecimal values are decoded), and it treats the stream data for inline images -as a string that is the single operand for \type {EI}. - -In case of \type {array}, the table content is a list of \type {pop} return -values and in case of \type {dict}, the table keys are \PDF\ name strings and the -values are \type {pop} return values. - -\blank - -There are few more methods defined that you can ask \type {scanner}: - -\starttabulate[|l|p|] -\NC \type{pop} \NC as explained above \NC \NR -\NC \type{popNumber} \NC return only the value of a \type {real} or \type {integer} \NC \NR -\NC \type{popName} \NC return only the value of a \type {name} \NC \NR -\NC \type{popString} \NC return only the value of a \type {string} \NC \NR -\NC \type{popArray} \NC return only the value of a \type {array} \NC \NR -\NC \type{popDict} \NC return only the value of a \type {dict} \NC \NR -\NC \type{popBool} \NC return only the value of a \type {boolean} \NC \NR -\NC \type{done} \NC abort further processing of this \type {scan()} call \NC \NR -\stoptabulate - -The \type {popXXX} are convenience functions, and come in handy when you know the -type of the operands beforehand (which you usually do, in \PDF). For example, the -\type {Do} function could have used \type {local name = scanner:popName()} -instead, because the single operand to the \type {Do} operator is always a \PDF\ -name object. - -The \type {done} function allows you to abort processing of a stream once you -have learned everything you want to learn. This comes in handy while parsing -\type {/ToUnicode}, because there usually is trailing garbage that you are not -interested in. Without \type {done}, processing only end at the end of the -stream, possibly wasting \CPU\ cycles. - -\section{The \type {epdf} library} - -The \type {epdf} library provides \LUA\ bindings to many \PDF\ access functions -that are defined by the poppler \PDF\ viewer library (written in C$+{}+$ by -Kristian H\o gsberg, based on xpdf by Derek Noonburg). Within \LUATEX\ xpdf -functionality is being used since long time to embed \PDF\ files. The \type -{epdf} library allows to scrutinize an external \PDF\ file. It gives access to -its document structure: catalog, cross|-|reference table, individual pages, -objects, annotations, info, and metadata. The \type {epdf} library only provides -read|-|only access. At some point we might decide to limit the interface to a -reasonable subset. - -\start \em - -The following functions will be removed in a next version. This is partly due to -a change in the api of the used library and partly due to the fact that write -access is not needed at all. - -\starttabulate[|T|T||] -\NC Annot \NC getAppearance \NC gone \NC \NR -\NC \NC getBorder \NC gone \NC \NR -\NC AnnotBorderStyle \NC getWidth \NC gone \NC \NR -\NC Array \NC incRef \NC gone \NC \NR -\NC \NC decRef \NC gone \NC \NR -\NC \NC add \NC will go \NC \NR -\NC Attribute \NC setRevision \NC will go \NC \NR -\NC \NC setHidden \NC will go \NC \NR -\NC \NC setFormattedValue \NC will go \NC \NR -\NC EmbFile \NC save \NC will go \NC \NR -\NC Dict \NC incRef \NC gone \NC \NR -\NC \NC decRef \NC gone \NC \NR -\NC \NC add \NC will go \NC \NR -\NC \NC set \NC will go \NC \NR -\NC \NC remove \NC will go \NC \NR -\NC Object \NC initBool \NC will go \NC \NR -\NC \NC initInt \NC will go \NC \NR -\NC \NC initReal \NC will go \NC \NR -\NC \NC initString \NC will go \NC \NR -\NC \NC initName \NC will go \NC \NR -\NC \NC initNull \NC will go \NC \NR -\NC \NC initArray \NC will go \NC \NR -\NC \NC initDict \NC will go \NC \NR -\NC \NC initStream \NC will go \NC \NR -\NC \NC initRef \NC will go \NC \NR -\NC \NC initCmd \NC will go \NC \NR -\NC \NC initError \NC will go \NC \NR -\NC \NC initEOF \NC will go \NC \NR -\NC \NC dictAdd \NC will go \NC \NR -\NC \NC dictSet \NC will go \NC \NR -\NC \NC streamReset \NC will go \NC \NR -\NC StructElement \NC setRevision \NC will go \NC \NR -\NC \NC appendChild \NC will go \NC \NR -\NC \NC appendAttribute \NC will go \NC \NR -\NC StructTreeRoot \NC appendChild \NC will go \NC \NR -\stoptabulate - -\stop - -For a start, a \PDF\ file is opened by \type {epdf.open()} with file name, e.g.: - -\starttyping -doc = epdf.open("foo.pdf") -\stoptyping - -This normally returns a \type {PDFDoc} userdata variable; but if the file could -not be opened successfully, instead of a fatal error just the value \type {nil} is -returned. - -All \LUA\ functions in the \type {epdf} library are named after the poppler -functions listed in the poppler header files for the various classes, e.g., files -\type {PDFDoc.h}, \type {Dict.h}, and \type {Array.h}. These files can be found -in the poppler subdirectory within the \LUATEX\ sources. Which functions are -already implemented in the \type {epdf} library can be found in the \LUATEX\ -source file \type {lepdflib.cc}. For using the \type {epdf} library, knowledge of -the \PDF\ file architecture is indispensable. - -There are many different userdata types defined by the \type {epdf} library, -currently these are \type {AnnotBorderStyle}, \type {AnnotBorder}, \type -{Annots}, \type {Annot}, \type {Array}, \type {Attribute}, \type {Catalog}, \type -{Dict}, \type {EmbFile}, \type {GString}, \type {LinkDest}, \type {Links}, \type -{Link}, \type {ObjectStream}, \type {Object}, \type {PDFDoc}, \type -{PDFRectangle}, \type {Page}, \type {Ref}, \type {Stream}, \type {StructElement}, -\type {StructTreeRoot} \type {TextSpan}, \type {XRefEntry} and \type {XRef}. - -All these userdata names and the \LUA\ access functions closely resemble the -classes naming from the poppler header files, including the choice of mixed upper -and lower case letters. The \LUA\ function calls use object|-|oriented syntax, -e.g., the following calls return the \type {Page} object for page~1: - -\starttyping -pageref = doc:getCatalog():getPageRef(1) -pageobj = doc:getXRef():fetch(pageref.num, pageref.gen) -\stoptyping - -But writing such chained calls is risky, as an intermediate function may return -\type {nil} on error. Therefore between function calls there should be \LUA\ type -checks (e.g., against \type {nil}) done. If a non|-|object item is requested (for -instance a \type {Dict} item by calling \type {page:getPieceInfo()}, cf.~\type -{Page.h}) but not available, the \LUA\ functions return \type {nil} (without -error). If a function should return an \type {Object}, but it's not existing, a -\type {Null} object is returned instead, also without error. This is in|-|line -with poppler behavior. - -All library objects have a \type {__gc} metamethod for garbage collection. The -\type {__tostring} metamethod gives the type name for each object. - -These are the object constructors: - -\startfunctioncall -<PDFDoc> = epdf.open(<string> PDF filename) -<Annot> = epdf.Annot(<XRef>, <Dict>, <Catalog>, <Ref>) -<Annots> = epdf.Annots(<XRef>, <Catalog>, <Object>) -<Array> = epdf.Array(<XRef>) -<Attribute> = epdf.Attribute(<Type>,<Object>)| epdf.Attribute(<string>, <int>, <Object>) -<Dict> = epdf.Dict(<XRef>) -<Object> = epdf.Object()|epdf.Object(<Type>)|epdf.Object(<Object_Type>,<string>)| -<PDFRectangle> = epdf.PDFRectangle() -\stopfunctioncall - -There is a new API for the \type {Object} constructors: the old \type {init<ObjType>} constructors -are still present but they are deprecated. They will disappear after the next \TeX Live. -The functions \type {StructElement_Type}, \type {Object_Type}, \type {Attribute_Type} and \type -{AttributeOwner_Type} return a hash table \type {{<string>,<integer>}}. -The hash table \type {Object_Type} is useful for the -\type {epdf.Object(<Object_Type>,<string>)} \type {Object} constructor, where \type {<Object_Type>} is an -integer. - -\type {Annot} methods: - - -\startfunctioncall -<boolean> = <Annot>:isOK() -<boolean> = <Annot>:match(<Ref>) -<Object> = <Annot>:getAppearance() -- gone -<AnnotBorder> = <Annot>:getBorder() -- gone -\stopfunctioncall - -\type {AnnotBorderStyle} methods (gone): - -\startfunctioncall -<number> = <AnnotBorderStyle>:getWidth() -- gone -\stopfunctioncall - -\type {Annots} methods: - -\startfunctioncall -<integer> = <Annots>:getNumAnnots() -<Annot> = <Annots>:getAnnot(<integer>) -\stopfunctioncall - -\type {Array} methods: - -\startfunctioncall - <Array>:incRef() -- gone - <Array>:decRef() -- gone - <Array>:add(<Object>) -- will go -<integer> = <Array>:getLength() -<Object> = <Array>:get(<integer>) -<Object> = <Array>:getNF(<integer>) -<string> = <Array>:getString(<integer>) -\stopfunctioncall - -\type {Attribute} methods: - -\startfunctioncall -<boolean> = <Attribute>:isOk() -<integer> = <Attribute>:getType() -<integer> = <Attribute>:getOwner() -<string> = <Attribute>:getTypeName() -<string> = <Attribute>:getOwnerName() -<Object> = <Attribute>:getValue() -<Object> = <Attribute>:getDefaultValue -<string> = <Attribute>:getName() -<integer> = <Attribute>:getRevision() - <Attribute>:setRevision(<unsigned integer>) -- will go -<boolean> = <Attribute>:isHidden() - <Attribute>:setHidden(<boolean>) -- will go -<string> = <Attribute>:getFormattedValue() -<string> = <Attribute>:setFormattedValue(<string>) -- will go -\stopfunctioncall - -\type {Catalog} methods: - -\startfunctioncall -<boolean> = <Catalog>:isOK() -<integer> = <Catalog>:getNumPages() -<Page> = <Catalog>:getPage(<integer>) -<Ref> = <Catalog>:getPageRef(<integer>) -<string> = <Catalog>:getBaseURI() -<string> = <Catalog>:readMetadata() -<Object> = <Catalog>:getStructTreeRoot() -<integer> = <Catalog>:findPage(<integer> object number, <integer> object generation) -<LinkDest> = <Catalog>:findDest(<string> name) -<Object> = <Catalog>:getDests() -<integer> = <Catalog>:numEmbeddedFiles() -<EmbFile> = <Catalog>:embeddedFile(<integer>) -<integer> = <Catalog>:numJS() -<string> = <Catalog>:getJS(<integer>) -<Object> = <Catalog>:getOutline() -<Object> = <Catalog>:getAcroForm() -\stopfunctioncall - -\type {EmbFile} methods: - -\startfunctioncall -<integer> = <EmbFile>:size() -<string> = <EmbFile>:modDate() -<string> = <EmbFile>:createDate() -<string> = <EmbFile>:checksum() -<string> = <EmbFile>:mimeType() -<boolean> = <EmbFile>:isOk() -<string> = <EmbFile>:name() -- not (yet) implemented -<string> = <EmbFile>:description() -- not (yet) implemented -<Object> = <EmbFile>:streamObject() -- not (yet) implemented -<boolean> = <EmbFile>:save() -- will go -\stopfunctioncall - -\type {FileSpec} methods: - -\startfunctioncall -<boolean> = <FileSpec>:isOk() -<string> = <FileSpec>:getFileName() -<string> = <FileSpec>:getFileNameForPlatform() -<string> = <FileSpec>:getDescription() -<EmbFile> = <FileSpec>:getEmbeddedFile() -\stopfunctioncall - -\type {Dict} methods: - -\startfunctioncall - <Dict>:incRef() -- will go - <Dict>:decRef() -- will go - <Dict>:add(<string>, <Object>) -- will go - <Dict>:set(<string>, <Object>) -- will go - <Dict>:remove(<string>) -- will go -<integer> = <Dict>:getLength() -<boolean> = <Dict>:is(<string>) -<Object> = <Dict>:lookup(<string>) -<Object> = <Dict>:lookupNF(<string>) -<integer> = <Dict>:lookupInt(<string>, <string>) -<string> = <Dict>:getKey(<integer>) -<Object> = <Dict>:getVal(<integer>) -<Object> = <Dict>:getValNF(<integer>) -<boolean> = <Dict>:hasKey(<string>) -\stopfunctioncall - -% \type {Link} methods: - -% \startfunctioncall -% <boolean> = <Link>:isOK() -% <boolean> = <Link>:inRect(<number>, <number>) -% \stopfunctioncall - -\type {LinkDest} methods: - -\startfunctioncall -<boolean> = <LinkDest>:isOK() -<integer> = <LinkDest>:getKind() -<string> = <LinkDest>:getKindName() -<boolean> = <LinkDest>:isPageRef() -<integer> = <LinkDest>:getPageNum() -<Ref> = <LinkDest>:getPageRef() -<number> = <LinkDest>:getLeft() -<number> = <LinkDest>:getBottom() -<number> = <LinkDest>:getRight() -<number> = <LinkDest>:getTop() -<number> = <LinkDest>:getZoom() -<boolean> = <LinkDest>:getChangeLeft() -<boolean> = <LinkDest>:getChangeTop() -<boolean> = <LinkDest>:getChangeZoom() -\stopfunctioncall - -\type {Links} methods: - -% <Link> = <Links>:getLink(<integer>) - -\startfunctioncall -<integer> = <Links>:getNumLinks() -\stopfunctioncall - -\type {Object} methods: - -\startfunctioncall - <Object>:initBool(<boolean>) -- will go - <Object>:initInt(<integer>) -- will go - <Object>:initReal(<number>) -- will go - <Object>:initString(<string>) -- will go - <Object>:initName(<string>) -- will go - <Object>:initNull() -- will go - <Object>:initArray(<XRef>) -- will go - <Object>:initDict(<XRef>) -- will go - <Object>:initStream(<Stream>) -- will go - <Object>:initRef(<integer> object number, - <integer> object generation) -- will go - <Object>:initCmd(<string>) -- will go - <Object>:initError() -- will go - <Object>:initEOF() -- will go -<Object> = <Object>:fetch(<XRef>) -<integer> = <Object>:getType() -<string> = <Object>:getTypeName() -<boolean> = <Object>:isBool() -<boolean> = <Object>:isInt() -<boolean> = <Object>:isReal() -<boolean> = <Object>:isNum() -<boolean> = <Object>:isString() -<boolean> = <Object>:isName() -<boolean> = <Object>:isNull() -<boolean> = <Object>:isArray() -<boolean> = <Object>:isDict() -<boolean> = <Object>:isStream() -<boolean> = <Object>:isRef() -<boolean> = <Object>:isCmd() -<boolean> = <Object>:isError() -<boolean> = <Object>:isEOF() -<boolean> = <Object>:isNone() -<boolean> = <Object>:getBool() -<integer> = <Object>:getInt() -<number> = <Object>:getReal() -<number> = <Object>:getNum() -<string> = <Object>:getString() -<string> = <Object>:getName() -<Array> = <Object>:getArray() -<Dict> = <Object>:getDict() -<Stream> = <Object>:getStream() -<Ref> = <Object>:getRef() -<integer> = <Object>:getRefNum() -<integer> = <Object>:getRefGen() -<string> = <Object>:getCmd() -<integer> = <Object>:arrayGetLength() - = <Object>:arrayAdd(<Object>) -- will go -<Object> = <Object>:arrayGet(<integer>) -<Object> = <Object>:arrayGetNF(<integer>) -<integer> = <Object>:dictGetLength(<integer>) - = <Object>:dictAdd(<string>, <Object>) -- will go - = <Object>:dictSet(<string>, <Object>) -- will go -<Object> = <Object>:dictLookup(<string>) -<Object> = <Object>:dictLookupNF(<string>) -<string> = <Object>:dictgetKey(<integer>) -<Object> = <Object>:dictgetVal(<integer>) -<Object> = <Object>:dictgetValNF(<integer>) -<boolean> = <Object>:streamIs(<string>) - = <Object>:streamReset() -- will go -<integer> = <Object>:streamGetChar() -<integer> = <Object>:streamLookChar() -<integer> = <Object>:streamGetPos() - = <Object>:streamSetPos(<integer>) -<Dict> = <Object>:streamGetDict() -\stopfunctioncall - -\type {Page} methods: - -\startfunctioncall -<boolean> = <Page>:isOk() -<integer> = <Page>:getNum() -<PDFRectangle> = <Page>:getMediaBox() -<PDFRectangle> = <Page>:getCropBox() -<boolean> = <Page>:isCropped() -<number> = <Page>:getMediaWidth() -<number> = <Page>:getMediaHeight() -<number> = <Page>:getCropWidth() -<number> = <Page>:getCropHeight() -<PDFRectangle> = <Page>:getBleedBox() -<PDFRectangle> = <Page>:getTrimBox() -<PDFRectangle> = <Page>:getArtBox() -<integer> = <Page>:getRotate() -<string> = <Page>:getLastModified() -<Dict> = <Page>:getBoxColorInfo() -<Dict> = <Page>:getGroup() -<Stream> = <Page>:getMetadata() -<Dict> = <Page>:getPieceInfo() -<Dict> = <Page>:getSeparationInfo() -<Dict> = <Page>:getResourceDict() -<Object> = <Page>:getAnnots() -<Links> = <Page>:getLinks(<Catalog>) -<Object> = <Page>:getContents() -\stopfunctioncall - -\type {PDFDoc} methods: - -\startfunctioncall -<boolean> = <PDFDoc>:isOk() -<integer> = <PDFDoc>:getErrorCode() -<string> = <PDFDoc>:getErrorCodeName() -<string> = <PDFDoc>:getFileName() -<XRef> = <PDFDoc>:getXRef() -<Catalog> = <PDFDoc>:getCatalog() -<number> = <PDFDoc>:getPageMediaWidth() -<number> = <PDFDoc>:getPageMediaHeight() -<number> = <PDFDoc>:getPageCropWidth() -<number> = <PDFDoc>:getPageCropHeight() -<integer> = <PDFDoc>:getNumPages() -<string> = <PDFDoc>:readMetadata() -<Object> = <PDFDoc>:getStructTreeRoot() -<integer> = <PDFDoc>:findPage(<integer> object number, - <integer> object generation) -<Links> = <PDFDoc>:getLinks(<integer>) -<LinkDest> = <PDFDoc>:findDest(<string>) -<boolean> = <PDFDoc>:isEncrypted() -<boolean> = <PDFDoc>:okToPrint() -<boolean> = <PDFDoc>:okToChange() -<boolean> = <PDFDoc>:okToCopy() -<boolean> = <PDFDoc>:okToAddNotes() -<boolean> = <PDFDoc>:isLinearized() -<Object> = <PDFDoc>:getDocInfo() -<Object> = <PDFDoc>:getDocInfoNF() -<integer> = <PDFDoc>:getPDFMajorVersion() -<integer> = <PDFDoc>:getPDFMinorVersion() -\stopfunctioncall - -\type {PDFRectangle} methods: - -\startfunctioncall -<boolean> = <PDFRectangle>:isValid() -- setindex/newindex will go -\stopfunctioncall - -%\type {Ref} methods: -% -%\startfunctioncall -%\stopfunctioncall - -\type {Stream} methods: - -\startfunctioncall -<integer> = <Stream>:getKind() -<string> = <Stream>:getKindName() - = <Stream>:reset() - = <Stream>:close() -<integer> = <Stream>:getChar() -<integer> = <Stream>:lookChar() -<integer> = <Stream>:getRawChar() -<integer> = <Stream>:getUnfilteredChar() - = <Stream>:unfilteredReset() -<integer> = <Stream>:getPos() -<boolean> = <Stream>:isBinary() -<Stream> = <Stream>:getUndecodedStream() -<Dict> = <Stream>:getDict() -\stopfunctioncall - -\type {StructElement} methods: - -\startfunctioncall -<string> = <StructElement>:getTypeName() -<integer> = <StructElement>:getType() -<boolean> = <StructElement>:isOk() -<boolean> = <StructElement>:isBlock() -<boolean> = <StructElement>:isInline() -<boolean> = <StructElement>:isGrouping() -<boolean> = <StructElement>:isContent() -<boolean> = <StructElement>:isObjectRef() -<integer> = <StructElement>:getMCID() -<Ref> = <StructElement>:getObjectRef() -<Ref> = <StructElement>:getParentRef() -<boolean> = <StructElement>:hasPageRef() -<Ref> = <StructElement>:getPageRef() -<StructTreeRoot> = <StructElement>:getStructTreeRoot() -<string> = <StructElement>:getID() -<string> = <StructElement>:getLanguage() -<integer> = <StructElement>:getRevision() - <StructElement>:setRevision(<unsigned integer>) -- will go -<string> = <StructElement>:getTitle() -<string> = <StructElement>:getExpandedAbbr() -<integer> = <StructElement>:getNumChildren() -<StructElement> = <StructElement>:getChild() - = <StructElement>:appendChild<StructElement>) -- will go -<integer> = <StructElement>:getNumAttributes() -<Attribute> = <StructElement>:getAttribute(<integer>) -<string> = <StructElement>:appendAttribute(<Attribute>) -- will go -<Attribute> = <StructElement>:findAttribute(<Attribute::Type>, - boolean,Attribute::Owner) -<string> = <StructElement>:getAltText() -<string> = <StructElement>:getActualText() -<string> = <StructElement>:getText(<boolean>) -<table> = <StructElement>:getTextSpans() -\stopfunctioncall - -\type {StructTreeRoot} methods: - -\startfunctioncall -<StructElement> = <StructTreeRoot>:findParentElement -<PDFDoc> = <StructTreeRoot>:getDoc -<Dict> = <StructTreeRoot>:getRoleMap -<Dict> = <StructTreeRoot>:getClassMap -<integer> = <StructTreeRoot>:getNumChildren -<StructElement> = <StructTreeRoot>:getChild - <StructTreeRoot>:appendChild -- will go -<StructElement> = <StructTreeRoot>:findParentElement -\stopfunctioncall - -\type {TextSpan} han only one method: - -\startfunctioncall -<string> = <TestSpan>:getText() -\stopfunctioncall - -\type {XRef} methods: - -\startfunctioncall -<boolean> = <XRef>:isOk() -<integer> = <XRef>:getErrorCode() -<boolean> = <XRef>:isEncrypted() -<boolean> = <XRef>:okToPrint() -<boolean> = <XRef>:okToPrintHighRes() -<boolean> = <XRef>:okToChange() -<boolean> = <XRef>:okToCopy() -<boolean> = <XRef>:okToAddNotes() -<boolean> = <XRef>:okToFillForm() -<boolean> = <XRef>:okToAccessibility() -<boolean> = <XRef>:okToAssemble() -<Object> = <XRef>:getCatalog() -<Object> = <XRef>:fetch(<integer> object number, - <integer> object generation) -<Object> = <XRef>:getDocInfo() -<Object> = <XRef>:getDocInfoNF() -<integer> = <XRef>:getNumObjects() -<integer> = <XRef>:getRootNum() -<integer> = <XRef>:getRootGen() -<integer> = <XRef>:getSize() -<Object> = <XRef>:getTrailerDict() -\stopfunctioncall - -There is an experimental function \type {epdf.openMemStream} that takes three -arguments: - -\starttabulate -\NC \type {stream} \NC this is a (in low level \LUA\ speak) light userdata - object, i.e.\ a pointer to a sequence of bytes \NC \NR -\NC \type {length} \NC this is the length of the stream in bytes \NC \NR -\NC \type {name} \NC this is a unique identifier that is used for hashing the - stream, so that multiple doesn't use more memory \NC \NR -\stoptabulate - -Instead of a light userdata stream you can also pass a \LUA\ string, in which -case the given length is (at most) the string length. - -The function returns a \type{epdf} object and a string. The string can be used in -the \type {img} library instead of a filename. You need to prevent garbage -collection of the object when you use it as image (for instance by storing it -somewhere). - -Both the memory stream and it's use in the image library is experimental and can -change. In case you wonder where this can be used: when you use the swiglib -library for \type {graphicmagick}, it can return such a userdata object. This -permits conversion in memory and passing the result directly to the backend. This -might save some runtime in one|-|pass workflows. This feature is currently not -meant for production and we might come up with a better implementation. - -\stopchapter - -\stopcomponent +% language=uk
+
+\environment luatex-style
+
+\startcomponent luatex-backend
+
+\startchapter[reference=backend,title={The backend libraries}]
+
+\startsection[title={The \type {pdf} library}][library=pdf]
+
+\topicindex{backend}
+\topicindex{\PDF}
+
+This library contains variables and functions that are related to the \PDF\
+backend. You can find more details about the expected values to setters in \in
+{section} [backendprimitives].
+
+\startsubsection[title={\type {mapfile}, \type {mapline}}]
+
+\topicindex{map files}
+\topicindex{files+map}
+
+\startfunctioncall
+pdf.mapfile(<string> map file)
+pdf.mapline(<string> map line)
+\stopfunctioncall
+
+These two functions can be used to replace primitives \orm {pdfmapfile} and
+\orm {pdfmapline} inherited from \PDFTEX. They expect a string as only
+parameter and have no return value. The first character in a map line can be
+\type {-}, \type {+} or \type {=} which means as much as remove, add or replace
+this line. They are not state setters but act immediately.
+
+\stopsubsection
+
+\startsubsection[title={\type {[set|get][catalog|info|names|trailer]}}]
+
+\topicindex{\PDF+trailer}
+\topicindex{\PDF+catalog}
+\topicindex{\PDF+info}
+
+\libindex{setcatalog} \libindex{getcatalog}
+\libindex{setinfo} \libindex{getinfo}
+\libindex{setnames} \libindex{getnames}
+\libindex{settrailer} \libindex{gettrailer}
+
+These functions complement the corresponding \PDF\ backend token lists dealing
+with metadata. The value types are strings and they are written to the \PDF\
+file directly after the token registers set at the \TEX\ end are written.
+
+\stopsubsection
+
+\startsubsection[title={\type {[set|get][pageattributes|pageresources|pagesattributes]}}]
+
+\libindex{setpageattributes} \libindex{getpageattributes}
+\libindex{setpageresources} \libindex{getpageresources}
+\libindex{setpagesattributes} \libindex{getpagesattributes}
+
+\topicindex{\PDF+page attributes}
+\topicindex{\PDF+page resources}
+
+These functions complement the corresponding \PDF\ backend token lists dealing
+with page resources. The variables have no interaction with the corresponding \PDF\
+backend token register. They are written to the \PDF\ file directly after the
+token registers set at the \TEX\ end are written.
+
+\stopsubsection
+
+\startsubsection[title={\type {[set|get][xformattributes|xformresources]}}]
+
+\libindex{setxformattributes} \libindex{getxformattributes}
+\libindex{setxformresources} \libindex{getxformresources}
+
+\topicindex{\PDF+xform attributes}
+\topicindex{\PDF+xform resources}
+
+These functions complement the corresponding \PDF\ backend token lists dealing
+with reuseable boxes and images. The variables have no interaction with the
+corresponding \PDF\ backend token register. They are written to the \PDF\
+file directly after the token registers set at the \TEX\ end are written.
+
+\stopsubsection
+
+\startsubsection[title={\type {[set|get][major|minor]version}}]
+
+\topicindex{\PDF+version}
+
+\libindex{getmajorversion} \libindex{setmajorversion}
+\libindex{getminorversion} \libindex{setminorversion}
+
+You can set both the major and minor version of the output. The major version is
+normally~1 but when set to~2 some data will not be written to the file in order
+to comply with the standard. What minor version you set depends on what \PDF\
+features you use. This is out of control of \LUATEX.
+
+\stopsubsection
+
+\startsubsection[title={\type {getcreationdate}}]
+
+\topicindex{\PDF+date}
+
+\libindex{getcreationdate}
+
+This function returns a string with the date in the format that ends up in the
+\PDF\ file, in this case it's: {\tttf \cldcontext{pdf.getcreationdate()}}.
+
+\stopsubsection
+
+\startsubsection[title={\type {[set|get]inclusionerrorlevel} and \type {[set|get]ignoreunknownimages}}]
+
+\topicindex{\PDF+options}
+
+\libindex{getinclusionerrorlevel} \libindex{setinclusionerrorlevel}
+\libindex{getignoreunknownimages} \libindex{setignoreunknownimages}
+
+These variable control how error in included image are treated. They are modeled
+after the \PDFTEX\ equivalents.
+
+\stopsubsection
+
+\startsubsection[title={\type {[set|get]suppressoptionalinfo}, \type {[set|get]trailerid}
+and \type {[set|get]omitcidset}}]
+
+\topicindex{\PDF+options}
+\topicindex{\PDF+trailer}
+
+\libindex{getsuppressoptionalinfo} \libindex{setsuppressoptionalinfo}
+\libindex{gettrailerid} \libindex{settrailerid}
+\libindex{getomitcidset} \libindex{setomitcidset}
+\libindex{getomitcharset} \libindex{setomitcharset}
+
+The optional info bitset (a number) determines what kind of info gets flushed.
+By default we flush all. See \in {section} [sec:pdfextensions] for more details.
+
+You can set your own trailer id. This has to be string containing valid \PDF\
+array content with checksums.
+
+The cidset and charset flags (numbers) disables inclusion of a so called \type
+{CIDSet} and \type {CharSet} entries, which can be handy when aiming at some of
+the many \PDF\ substandards.
+
+\stopsubsection
+
+\startsubsection[title={\type {[set|get][obj|]compresslevel} and \type {[set|get]recompress}}]
+
+\topicindex{\PDF+compression}
+
+\libindex{getcompresslevel} \libindex{setcompresslevel}
+\libindex{getobjcompresslevel} \libindex{setobjcompresslevel}
+\libindex{getrecompress} \libindex{setrecompress}
+
+These functions set the level stream compression. When object compression is
+enabled multiple objects will be packed in a compressed stream which saves space.
+The minimum values are~0, the maxima are~9.
+
+When recompression is to~1 compressed objects will be decompressed and when
+compresslevel is larger than zero they will then be recompressed. This is mostly
+a debugging feature and should not be relied upon.
+
+\stopsubsection
+
+\startsubsection[title={\type {[set|get]gentounicode}}]
+
+\topicindex{\PDF+unicode}
+
+\libindex{getgentounicode} \libindex{setgentounicode}
+
+This flag enables tounicode generation (like in \PDFTEX). Normally the values are
+provided by the font loader.
+
+\stopsubsection
+
+\startsubsection[title={\type {[set|get]decimaldigits}}]
+
+\topicindex{\PDF+precision}
+
+\libindex{getdecimaldigits} \libindex{setdecimaldigits}
+
+These two functions set the accuracy of floats written to the \PDF file. You can
+set any value but the backend will not go below~3 and above~6.
+
+\stopsubsection
+
+\startsubsection[title={\type {[set|get]pkresolution}}]
+
+\topicindex{\PDF+resolution}
+
+\libindex{getpkresolution} \libindex{setpkresolution}
+
+These setter takes two arguments: the resolution and an optional zero or one that
+indicates if this is a fixed one. The getter returns these two values.
+
+\stopsubsection
+
+\startsubsection[title={\type {getlast[obj|link|annot]} and \type {getretval}}]
+
+\topicindex{\PDF+objects}
+\topicindex{\PDF+annotations}
+
+\libindex{getlastobj} \libindex{setlastobj}
+\libindex{getlastlink} \libindex{setlastlink}
+\libindex{getlastannot} \libindex{setlastannot}
+\libindex{getretval}
+
+These status variables are similar to the ones traditionally used in the backend
+interface at the \TEX\ end.
+
+\stopsubsection
+
+\startsubsection[title={\type {getmaxobjnum} and \type {getobjtype}, \type {getfontname},
+\type {getfontobjnum}, \type {getfontsize}, \type {getxformname}}]
+
+\libindex{getmaxobjnum}
+\libindex{getobjtype}
+\libindex{getfontname}
+\libindex{getfontobjnum}
+\libindex{getfontsize}
+\libindex{getxformname}
+
+These introspective helpers are mostly used when you construct \PDF\ objects
+yourself and need for instance information about a (to be) embedded font.
+
+\stopsubsection
+
+\startsubsection[title={\type {[set|get]origin}}]
+
+\topicindex{\PDF+positioning}
+
+\libindex{setorigin} \libindex{getorigin}
+
+This one is used to set the horizonal and|/|or vertical offset, a traditional
+backend property.
+
+\starttyping
+pdf.setorigin() -- sets both to 0pt
+pdf.setorigin(tex.sp("1in")) -- sets both to 1in
+pdf.setorigin(tex.sp("1in"),tex.sp("1in"))
+\stoptyping
+
+The counterpart of this function returns two values.
+
+\stopsubsection
+
+\startsubsection[title={\type {[set|get]imageresolution}}]
+
+\topicindex{\PDF+resolution}
+
+\libindex{setimageresolution} \libindex{getimageresolution}
+
+These two functions relate to the imageresolution that is used when the image
+itself doesn't provide a non|-|zero x or y resolution.
+
+\stopsubsection
+
+\startsubsection[title={\type {[set|get][link|dest|thread|xform]margin}}]
+
+\topicindex{\PDF+margins}
+
+\libindex{getlinkmargin} \libindex{setlinkmargin}
+\libindex{getdestmargin} \libindex{setdestmargin}
+\libindex{getthreadmargin} \libindex{setthreadmargin}
+\libindex{getxformmargin} \libindex{setxformmargin}
+\libindex{getmarginmargin} \libindex{setmarginmargin}
+
+These functions can be used to set and retrieve the margins that are added to the
+natural bounding boxes of the respective objects.
+
+\stopsubsection
+
+\startsubsection[title={\type {get[pos|hpos|vpos]}}]
+
+\topicindex{\PDF+positions}
+
+\libindex{getpos}
+\libindex{gethpos}
+\libindex{getvpos}
+
+These functions get current location on the output page, measured from its lower
+left corner. The values return scaled points as units.
+
+\starttyping
+local h, v = pdf.getpos()
+\stoptyping
+
+\stopsubsection
+
+\startsubsection[title={\type {[has|get]matrix}}]
+
+\topicindex{\PDF+matrix}
+
+\libindex{getmatrix} \libindex{hasmatrix}
+
+The current matrix transformation is available via the \type {getmatrix} command,
+which returns 6 values: \type {sx}, \type {rx}, \type {ry}, \type {sy}, \type
+{tx}, and \type {ty}. The \type {hasmatrix} function returns \type {true} when a
+matrix is applied.
+
+\starttyping
+if pdf.hasmatrix() then
+ local sx, rx, ry, sy, tx, ty = pdf.getmatrix()
+ -- do something useful or not
+end
+\stoptyping
+
+\stopsubsection
+
+\startsubsection[title={\type {print}}]
+
+\topicindex{\PDF+print to}
+
+\libindex{print}
+
+You can print a string to the \PDF\ document from within a \lpr {latelua} call.
+This function is not to be used inside \prm {directlua} unless you know {\it
+exactly} what you are doing.
+
+\startfunctioncall
+pdf.print(<string> s)
+pdf.print(<string> type, <string> s)
+\stopfunctioncall
+
+The optional parameter can be used to mimic the behavior of \PDF\ literals: the
+\type {type} is \type {direct} or \type {page}.
+
+\stopsubsection
+
+\startsubsection[title={\type {immediateobj}}]
+
+\topicindex{\PDF+objects}
+
+\libindex{immediateobj}
+
+This function creates a \PDF\ object and immediately writes it to the \PDF\ file.
+It is modelled after \PDFTEX's \prm {immediate} \orm {pdfobj} primitives. All
+function variants return the object number of the newly generated object.
+
+\startfunctioncall
+<number> n =
+ pdf.immediateobj(<string> objtext)
+<number> n =
+ pdf.immediateobj("file", <string> filename)
+<number> n =
+ pdf.immediateobj("stream", <string> streamtext, <string> attrtext)
+<number> n =
+ pdf.immediateobj("streamfile", <string> filename, <string> attrtext)
+\stopfunctioncall
+
+The first version puts the \type {objtext} raw into an object. Only the object
+wrapper is automatically generated, but any internal structure (like \type {<<
+>>} dictionary markers) needs to be provided by the user. The second version with
+keyword \type {file} as first argument puts the contents of the file with name
+\type {filename} raw into the object. The third version with keyword \type
+{stream} creates a stream object and puts the \type {streamtext} raw into the
+stream. The stream length is automatically calculated. The optional \type
+{attrtext} goes into the dictionary of that object. The fourth version with
+keyword \type {streamfile} does the same as the third one, it just reads the
+stream data raw from a file.
+
+An optional first argument can be given to make the function use a previously
+reserved \PDF\ object.
+
+\startfunctioncall
+<number> n =
+ pdf.immediateobj(<integer> n, <string> objtext)
+<number> n =
+ pdf.immediateobj(<integer> n, "file", <string> filename)
+<number> n =
+ pdf.immediateobj(<integer> n, "stream", <string> streamtext, <string> attrtext)
+<number> n =
+ pdf.immediateobj(<integer> n, "streamfile", <string> filename, <string> attrtext)
+\stopfunctioncall
+
+\stopsubsection
+
+\startsubsection[title={\type{obj}}]
+
+\topicindex{\PDF+objects}
+
+\libindex{obj}
+
+This function creates a \PDF\ object, which is written to the \PDF\ file only
+when referenced, e.g., by \type {refobj()}.
+
+All function variants return the object number of the newly generated object, and
+there are two separate calling modes. The first mode is modelled after \PDFTEX's
+\orm {pdfobj} primitive.
+
+\startfunctioncall
+<number> n =
+ pdf.obj(<string> objtext)
+<number> n =
+ pdf.obj("file", <string> filename)
+<number> n =
+ pdf.obj("stream", <string> streamtext, <string> attrtext)
+<number> n =
+ pdf.obj("streamfile", <string> filename, <string> attrtext)
+\stopfunctioncall
+
+An optional first argument can be given to make the function use a previously
+reserved \PDF\ object.
+
+\startfunctioncall
+<number> n =
+ pdf.obj(<integer> n, <string> objtext)
+<number> n =
+ pdf.obj(<integer> n, "file", <string> filename)
+<number> n =
+ pdf.obj(<integer> n, "stream", <string> streamtext, <string> attrtext)
+<number> n =
+ pdf.obj(<integer> n, "streamfile", <string> filename, <string> attrtext)
+\stopfunctioncall
+
+The second mode accepts a single argument table with key--value pairs.
+
+\startfunctioncall
+<number> n = pdf.obj {
+ type = <string>,
+ immediate = <boolean>,
+ objnum = <number>,
+ attr = <string>,
+ compresslevel = <number>,
+ objcompression = <boolean>,
+ file = <string>,
+ string = <string>,
+ nolength = <boolean>,
+}
+\stopfunctioncall
+
+The \type {type} field can have the values \type {raw} and \type {stream}, this
+field is required, the others are optional (within constraints). When \type
+{nolength} is set, there will be no \type {/Length} entry added to the
+dictionary.
+
+Note: this mode makes \type{obj} look more flexible than it actually is: the
+constraints from the separate parameter version still apply, so for example you
+can't have both \type {string} and \type {file} at the same time.
+
+\stopsubsection
+
+\startsubsection[title={\type {refobj}}]
+
+\topicindex{\PDF+objects}
+
+\libindex{refobj}
+
+This function, the \LUA\ version of the \orm {pdfrefobj} primitive, references an
+object by its object number, so that the object will be written to the \PDF\ file.
+
+\startfunctioncall
+pdf.refobj(<integer> n)
+\stopfunctioncall
+
+This function works in both the \prm {directlua} and \lpr {latelua} environment.
+Inside \prm {directlua} a new whatsit node \quote {pdf_refobj} is created, which
+will be marked for flushing during page output and the object is then written
+directly after the page, when also the resources objects are written to the \PDF\
+file. Inside \lpr {latelua} the object will be marked for flushing.
+
+This function has no return values.
+
+\stopsubsection
+
+\startsubsection[title={\type {reserveobj}}]
+
+\topicindex{\PDF+objects}
+
+\libindex{reserveobj}
+
+This function creates an empty \PDF\ object and returns its number.
+
+\startfunctioncall
+<number> n = pdf.reserveobj()
+<number> n = pdf.reserveobj("annot")
+\stopfunctioncall
+
+\stopsubsection
+
+\startsubsection[title={\type {getpageref}}]
+
+\topicindex{\PDF+pages}
+
+\libindex{getpageref}
+
+The object number of a page can be fetched with this function. This can be a
+forward reference so when you ask for a future page, you do get a number back.
+
+\startfunctioncall
+<number> n = pdf.getpageref(123)
+\stopfunctioncall
+
+\stopsubsection
+
+\startsubsection[title={\type {registerannot}}]
+
+\topicindex{\PDF+annotations}
+
+\libindex{registerannot}
+
+This function adds an object number to the \type {/Annots} array for the current
+page without doing anything else. This function can only be used from within
+\lpr {latelua}.
+
+\startfunctioncall
+pdf.registerannot (<number> objnum)
+\stopfunctioncall
+
+\stopsubsection
+
+\startsubsection[title={\type {newcolorstack}}]
+
+\topicindex{\PDF+color stack}
+
+\libindex{newcolorstack}
+
+This function allocates a new color stack and returns it's id. The arguments
+are the same as for the similar backend extension primitive.
+
+\startfunctioncall
+pdf.newcolorstack("0 g","page",true) -- page|direct|origin
+\stopfunctioncall
+
+\stopsubsection
+
+\startsubsection[title={\type {setfontattributes}}]
+
+\topicindex{\PDF+fonts}
+
+\libindex{setfontattributes}
+
+This function will force some additional code into the font resource. It can for
+instance be used to add a custom \type {ToUnicode} vector to a bitmap file.
+
+\startfunctioncall
+pdf.setfontattributes(<number> font id, <string> pdf code)
+\stopfunctioncall
+
+\stopsubsection
+
+\stopsection
+
+\startsection[title={The \type {pdfe} library}][library=pdfe]
+
+\startsubsection[title={Introduction}]
+
+\topicindex{\PDF+objects}
+
+\topicindex{\PDF+analyze}
+\topicindex{\PDF+\type{pdfe}}
+
+The \type {pdfe} library replaces the \type {epdf} library and provides an
+interface to \PDF\ files. It uses the same code as is used for \PDF\ image
+inclusion. The \type {pplib} library by Paweł Jackowski replaces the \type
+{poppler} (derived from \type {xpdf}) library.
+
+A \PDF\ file is basically a tree of objects and one descends into the tree via
+dictionaries (key/value) and arrays (index/value). There are a few topmost
+dictionaries that start at root that are accessed more directly.
+
+Although everything in \PDF\ is basically an object we only wrap a few in so
+called userdata \LUA\ objects.
+
+\starttabulate
+\BC \PDF \BC \LUA \NC \NR
+\NC null \NC nil \NC \NR
+\NC boolean \NC boolean \NC \NR
+\NC integer \NC integer \NC \NR
+\NC float \NC number \NC \NR
+\NC name \NC string \NC \NR
+\NC string \NC string \NC \NR
+\NC array \NC array userdatum \NC \NR
+\NC dictionary \NC dictionary userdatum \NC \NR
+\NC stream \NC stream userdatum (with related dictionary) \NC \NR
+\NC reference \NC reference userdatum \NC \NR
+\stoptabulate
+
+The regular getters return these \LUA\ data types but one can also get more
+detailed information.
+
+\stopsubsection
+
+\startsubsection[title={\type {open}, \type {new}, \type {status}, \type {close}, \type {unencrypt}}]
+
+\libindex {open}
+\libindex {new}
+\libindex {new}
+\libindex {status}
+\libindex {close}
+\libindex {unencrypt}
+
+A document is loaded from a file or string
+
+\starttyping
+<pdfe document> = pdfe.open(filename)
+<pdfe document> = pdfe.new(somestring,somelength)
+\stoptyping
+
+Such a document is closed with:
+
+\starttyping
+pdfe.close(<pdfe document>)
+\stoptyping
+
+You can check if a document opened well by:
+
+\starttyping
+pdfe.status(<pdfe document>)
+\stoptyping
+
+The returned codes are:
+
+\starttabulate[|c|l|]
+\DB value \BC explanation \NC \NR
+\TB
+\NC \type {-2} \NC the document failed to open \NC \NR
+\NC \type {-1} \NC the document is (still) protected \NC \NR
+\NC \type {0} \NC the document is not encrypted \NC \NR
+\NC \type {2} \NC the document has been unencrypted \NC \NR
+\LL
+\stoptabulate
+
+An encrypted document can be unencrypted by the next command where instead of
+either password you can give \type {nil}:
+
+\starttyping
+pdfe.unencrypt(<pdfe document>,userpassword,ownerpassword)
+\stoptyping
+
+\stopsubsection
+
+\startsubsection[title={\type {size}, \type {version}, \type {getnofobjects}, \type {getnofpages}}]
+
+\libindex {size}
+\libindex {version}
+\libindex {getnofobjects}
+\libindex {getnofpages}
+
+A successfully opened document can provide some information:
+
+\starttyping
+bytes = size(<pdfe document>)
+major, minor = version(<pdfe document>)
+n = getnofobjects(<pdfe document>)
+n = getnofpages(<pdfe document>)
+bytes, waste = getnofpages(<pdfe document>)
+\stoptyping
+
+\stopsubsection
+
+\startsubsection[title={\type {get[catalog|trailer|info]}}]
+
+\libindex {getcatalog}
+\libindex {gettrailer}
+\libindex {getinfo}
+
+For accessing the document structure you start with the so called catalog, a
+dictionary:
+
+\starttyping
+<pdfe dictionary> = pdfe.getcatalog(<pdfe document>)
+\stoptyping
+
+The other two root dictionaries are accessed with:
+
+\starttyping
+<pdfe dictionary> = pdfe.gettrailer(<pdfe document>)
+<pdfe dictionary> = pdfe.getinfo(<pdfe document>)
+\stoptyping
+
+\stopsubsection
+
+\startsubsection[title={\type {getpage}, \type {getbox}}]
+
+\libindex {getpage}
+\libindex {getbox}
+
+A specific page can conveniently be reached with the next command, which
+returns a dictionary. The first argument is to be a page dictionary.
+
+\starttyping
+<pdfe dictionary> = pdfe.getpage(<pdfe dictionary>,pagenumber)
+\stoptyping
+
+Another convenience command gives you the (bounding) box of a (normally page)
+which can be inheritted from the document itself. An example of a valid box name
+is \type {MediaBox}.
+
+\starttyping
+pages = pdfe.getbox(<pdfe document>,boxname)
+\stoptyping
+
+\stopsubsection
+
+\startsubsection[title={\type {get[string|integer|number|boolean|name]}}]
+
+\libindex {getstring}
+\libindex {getinteger}
+\libindex {getnumber}
+\libindex {getboolean}
+\libindex {getname}
+
+Common values in dictionaries and arrays are strings, integers, floats, booleans
+and names (which are also strings) and these are also normal \LUA\ objects:
+
+\starttyping
+s = getstring (<pdfe array|dictionary>,index|key)
+i = getinteger(<pdfe array|dictionary>,index|key)
+n = getnumber (<pdfe array|dictionary>,index|key)
+b = getboolean(<pdfe array|dictionary>,index|key)
+n = getname (<pdfe array|dictionary>,index|key)
+\stoptyping
+
+\stopsubsection
+
+\startsubsection[title={\type {get[from][dictionary|array|stream]}}]
+
+\libindex {getdictionary} \libindex {getfromdictionary}
+\libindex {getarray} \libindex {getfromarray}
+\libindex {getstream} \libindex {getfromstream}
+
+Normally you will use an index in an array and key in a dictionary but dictionaries
+also accept an index. The size of an array or dictionary is available with the
+usual \type {#} operator.
+
+\starttyping
+<pdfe dictionary> = getdictionary(<pdfe array|dictionary>,index|key)
+<pdfe array> = getarray (<pdfe array|dictionary>,index|key)
+<pdfe stream>,
+<pdfe dictionary> = getstream (<pdfe array|dictionary>,index|key)
+\stoptyping
+
+These commands return dictionaries, arrays and streams, which are dictionaries
+with a blob of data attached.
+
+Before we come to an alternative access mode, we mention that the objects provide
+access in a different way too, for instance this is valid:
+
+\starttyping
+print(pdfe.open("foo.pdf").Catalog.Type)
+\stoptyping
+
+At the topmost level there are \type {Catalog}, \type {Info}, \type {Trailer}
+and \type {Pages}, so this is also okay:
+
+\starttyping
+print(pdfe.open("foo.pdf").Pages[1])
+\stoptyping
+
+\stopsubsection
+
+\startsubsection[title={\type {[open|close|readfrom][whole|]stream}}]
+
+\libindex {openstream}
+\libindex {closestream}
+\libindex {readfromstream}
+\libindex {readfromwholestream}
+
+Streams are sort of special. When your index or key hits a stream you get back a
+stream object and dictionary object. The dictionary you can access in the usual
+way and for the stream there are the following methods:
+
+\starttyping
+okay = openstream(<pdfe stream>,[decode])
+ closestream(<pdfe stream>)
+str, n = readfromstream(<pdfe stream>)
+str, n = readwholestream(<pdfe stream>,[decode])
+\stoptyping
+
+You either read in chunks, or you ask for the whole. When reading in chunks, you
+need to open and close the stream yourself. The \type {n} value indicates the
+length read. The \type {decode} parameter controls if the stream data gets
+uncompressed.
+
+As with dictionaries, you can access fields in a stream dictionary in the usual
+\LUA\ way too. You get the content when you \quote {call} the stream. You can
+pass a boolean that indicates if the stream has to be decompressed.
+
+% pdfe.objectcodes = objectcodes
+% pdfe.stringcodes = stringcodes
+% pdfe.encryptioncodes = encryptioncodes
+
+\stopsubsection
+
+\startsubsection[title={\type {getfrom[dictionary|array]}}]
+
+\libindex {getfromdictionary}
+\libindex {getfromarray}
+
+In addition to the interface described before, there is also a bit lower level
+interface available.
+
+\starttyping
+key, type, value, detail = getfromdictionary(<pdfe dictionary>,index)
+type, value, detail = getfromarray(<pdfe array>,index)
+\stoptyping
+
+\starttabulate[|c|l|l|l|]
+\DB type \BC meaning \BC value \BC detail \NC \NR
+\NC \type {0} \NC none \NC nil \NC \NC \NR
+\NC \type {1} \NC null \NC nil \NC \NC \NR
+\NC \type {2} \NC boolean \NC boolean \NC \NC \NR
+\NC \type {3} \NC boolean \NC integer \NC \NC \NR
+\NC \type {4} \NC number \NC float \NC \NC \NR
+\NC \type {5} \NC name \NC string \NC \NC \NR
+\NC \type {6} \NC string \NC string \NC hex \NC \NR
+\NC \type {7} \NC array \NC arrayobject \NC size \NC \NR
+\NC \type {8} \NC dictionary \NC dictionaryobject \NC size \NC \NR
+\NC \type {9} \NC stream \NC streamobject \NC dictionary size \NC \NR
+\NC \type {10} \NC reference \NC integer \NC \NC \NR
+\LL
+\stoptabulate
+
+A \type {hex} string is (in the \PDF\ file) surrounded by \type {<>} while plain
+strings are bounded by \type {<>}.
+
+\stopsubsection
+
+\startsubsection[title={\type {[dictionary|array]totable}}]
+
+\libindex {dictionarytotable}
+\libindex {arraytotable}
+
+All entries in a dictionary or table can be fetched with the following commands
+where the return values are a hashed or indexed table.
+
+\starttyping
+hash = dictionarytotable(<pdfe dictionary>)
+list = arraytotable(<pdfe array>)
+\stoptyping
+
+You can get a list of pages with:
+
+\starttyping
+{ { <pdfe dictionary>, size, objnum }, ... } = pagestotable(<pdfe document>)
+\stoptyping
+
+\stopsubsection
+
+\startsubsection[title={\type {getfromreference}}]
+
+\libindex {getfromreference}
+
+Because you can have unresolved references, a reference object can be resolved
+with:
+
+\starttyping
+<pdfe dictionary|array|stream> = getfromreference(<pdfe reference>)
+\stoptyping
+
+So, you get back a new \type {pdfe} userdata object that you can query.
+
+\stopsubsection
+
+\stopsection
+
+\startsection[title={Memory streams}][library=pdfe]
+
+\topicindex{\PDF+memory streams}
+
+\libindex {new}
+
+The \type {pdfe.new} that takes three arguments:
+
+\starttabulate
+\DB value \BC explanation \NC \NR
+\TB
+\NC \type {stream} \NC this is a (in low level \LUA\ speak) light userdata
+ object, i.e.\ a pointer to a sequence of bytes \NC \NR
+\NC \type {length} \NC this is the length of the stream in bytes (the stream can
+ have embedded zeros) \NC \NR
+\NC \type {name} \NC optional, this is a unique identifier that is used for
+ hashing the stream, so that multiple doesn't use more
+ memory \NC \NR
+\LL
+\stoptabulate
+
+The third argument is optional. When it is not given the function will return an
+\type {pdfe} document object as with a regular file, otherwise it will return a
+filename that can be used elsewhere (e.g.\ in the image library) to reference the
+stream as pseudo file.
+
+Instead of a light userdata stream (which is actually fragile but handy when you
+come from a library) you can also pass a \LUA\ string, in which case the given
+length is (at most) the string length.
+
+The function returns an \type {pdfe} object and a string. The string can be used in
+the \type {img} library instead of a filename. You need to prevent garbage
+collection of the object when you use it as image (for instance by storing it
+somewhere).
+
+Both the memory stream and it's use in the image library is experimental and can
+change. In case you wonder where this can be used: when you use the swiglib
+library for \type {graphicmagick}, it can return such a userdata object. This
+permits conversion in memory and passing the result directly to the backend. This
+might save some runtime in one|-|pass workflows. This feature is currently not
+meant for production and we might come up with a better implementation.
+
+\stopsection
+
+\startsection[title={The \type {pdfscanner} library}][library=pdfscanner]
+
+\topicindex{\PDF+scanner}
+
+\libindex {scan}
+
+The \type {pdfscanner} library allows interpretation of \PDF\ content streams and
+\type {/ToUnicode} (cmap) streams. You can get those streams from the \type
+{pdfe} library, as explained in an earlier section. There is only a single
+top|-|level function in this library:
+
+\startfunctioncall
+pdfscanner.scan (<pdfe stream>, <table> operatortable, <table> info)
+pdfscanner.scan (<pdfe array>, <table> operatortable, <table> info)
+pdfscanner.scan (<string>, <table> operatortable, <table> info)
+\stopfunctioncall
+
+The first argument should be a \LUA\ string or a stream or array onject coming
+from the \type {pdfe} library. The second argument, \type {operatortable}, should
+be a \LUA\ table where the keys are \PDF\ operator name strings and the values
+are \LUA\ functions (defined by you) that are used to process those operators.
+The functions are called whenever the scanner finds one of these \PDF\ operators
+in the content stream(s). The functions are called with two arguments: the \type
+{scanner} object itself, and the \type {info} table that was passed are the third
+argument to \type {pdfscanner.scan}.
+
+Internally, \type {pdfscanner.scan} loops over the \PDF\ operators in the
+stream(s), collecting operands on an internal stack until it finds a \PDF\
+operator. If that \PDF\ operator's name exists in \type {operatortable}, then the
+associated function is executed. After the function has run (or when there is no
+function to execute) the internal operand stack is cleared in preparation for the
+next operator, and processing continues.
+
+The \type {scanner} argument to the processing functions is needed because it
+offers various methods to get the actual operands from the internal operand
+stack.
+
+A simple example of processing a \PDF's document stream could look like this:
+
+\starttyping
+local operatortable = { }
+
+operatortable.Do = function(scanner,info)
+ local resources = info.resources
+ if resources then
+ local val = scanner:pop()
+ local name = val[2]
+ local xobject = resources.XObject
+ print(info.space .. "Uses XObject " .. name)
+ local resources = xobject.Resources
+ if resources then
+ local newinfo = {
+ space = info.space .. " ",
+ resources = resources,
+ }
+ pdfscanner.scan(entry, operatortable, newinfo)
+ end
+ end
+end
+
+local function Analyze(filename)
+ local doc = pdfe.open(filename)
+ if doc then
+ local pages = doc.Pages
+ for i=1,#pages do
+ local page = pages[i]
+ local info = {
+ space = " " ,
+ resources = page.Resources,
+ }
+ print("Page " .. i)
+ -- pdfscanner.scan(page.Contents,operatortable,info)
+ pdfscanner.scan(page.Contents(),operatortable,info)
+ end
+ end
+end
+
+Analyze("foo.pdf")
+\stoptyping
+
+This example iterates over all the actual content in the \PDF, and prints out the
+found \type {XObject} names. While the code demonstrates quite some of the \type
+{pdfe} functions, let's focus on the type \type {pdfscanner} specific code
+instead.
+
+From the bottom up, the following line runs the scanner with the \PDF\ page's
+top|-|level content given in the first argument.
+
+The third argument, \type {info}, contains two entries: \type {space} is used to
+indent the printed output, and \type {resources} is needed so that embedded \type
+{XForms} can find their own content.
+
+The second argument, \type {operatortable} defines a processing function for a
+single \PDF\ operator, \type {Do}.
+
+The function \type {Do} prints the name of the current \type {XObject}, and then
+starts a new scanner for that object's content stream, under the condition that
+the \type {XObject} is in fact a \type {/Form}. That nested scanner is called
+with new \type {info} argument with an updated \type {space} value so that the
+indentation of the output nicely nests, and with a new \type {resources} field
+to help the next iteration down to properly process any other, embedded \type
+{XObject}s.
+
+Of course, this is not a very useful example in practice, but for the purpose of
+demonstrating \type {pdfscanner}, it is just long enough. It makes use of only
+one \type {scanner} method: \type {scanner:pop()}. That function pops the top
+operand of the internal stack, and returns a \LUA\ table where the object at index
+one is a string representing the type of the operand, and object two is its
+value.
+
+The list of possible operand types and associated \LUA\ value types is:
+
+\starttabulate[|l|l|]
+\DB types \BC type \NC \NR
+\TB
+\NC \type{integer} \NC <number> \NC \NR
+\NC \type{real} \NC <number> \NC \NR
+\NC \type{boolean} \NC <boolean> \NC \NR
+\NC \type{name} \NC <string> \NC \NR
+\NC \type{operator} \NC <string> \NC \NR
+\NC \type{string} \NC <string> \NC \NR
+\NC \type{array} \NC <table> \NC \NR
+\NC \type{dict} \NC <table> \NC \NR
+\LL
+\stoptabulate
+
+In case of \type {integer} or \type {real}, the value is always a \LUA\ (floating
+point) number. In case of \type {name}, the leading slash is always stripped.
+
+In case of \type {string}, please bear in mind that \PDF\ actually supports
+different types of strings (with different encodings) in different parts of the
+\PDF\ document, so you may need to reencode some of the results; \type {pdfscanner}
+always outputs the byte stream without reencoding anything. \type {pdfscanner}
+does not differentiate between literal strings and hexadecimal strings (the
+hexadecimal values are decoded), and it treats the stream data for inline images
+as a string that is the single operand for \type {EI}.
+
+In case of \type {array}, the table content is a list of \type {pop} return
+values and in case of \type {dict}, the table keys are \PDF\ name strings and the
+values are \type {pop} return values.
+
+\libindex{pop}
+\libindex{popnumber}
+\libindex{popname}
+\libindex{popstring}
+\libindex{poparray}
+\libindex{popdictionary}
+\libindex{popboolean}
+\libindex{done}
+
+There are a few more methods defined that you can ask \type {scanner}:
+
+\starttabulate[|l|p|]
+\DB method \BC explanation \NC \NR
+\TB
+\NC \type{pop} \NC see above \NC \NR
+\NC \type{popnumber} \NC return only the value of a \type {real} or \type {integer} \NC \NR
+\NC \type{popname} \NC return only the value of a \type {name} \NC \NR
+\NC \type{popstring} \NC return only the value of a \type {string} \NC \NR
+\NC \type{poparray} \NC return only the value of a \type {array} \NC \NR
+\NC \type{popdictionary} \NC return only the value of a \type {dict} \NC \NR
+\NC \type{popboolean} \NC return only the value of a \type {boolean} \NC \NR
+\NC \type{done} \NC abort further processing of this \type {scan()} call \NC \NR
+\LL
+\stoptabulate
+
+The \type {pop*} are convenience functions, and come in handy when you know the
+type of the operands beforehand (which you usually do, in \PDF). For example, the
+\type {Do} function could have used \type {local name = scanner:popname()}
+instead, because the single operand to the \type {Do} operator is always a \PDF\
+name object.
+
+The \type {done} function allows you to abort processing of a stream once you
+have learned everything you want to learn. This comes in handy while parsing
+\type {/ToUnicode}, because there usually is trailing garbage that you are not
+interested in. Without \type {done}, processing only ends at the end of the
+stream, possibly wasting \CPU\ cycles.
+
+{\em We keep the older names \type {popNumber}, \type {popName}, \type
+{popString}, \type {popArray}, \type {popDict} and \type {popBool} around.}
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
|