diff options
author | Karl Berry <karl@freefriends.org> | 2021-03-07 22:04:14 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2021-03-07 22:04:14 +0000 |
commit | 0ce7cbf84226220eaf916f5ed2657fe1981691d0 (patch) | |
tree | 6db6e10e277b8240d468db3d5cc45bc5a5f83c63 /Master/texmf-dist/tex/latex/newpax/newpax.lua | |
parent | 41af0d811446c2a97f6fe70d28570e3e4f8f9025 (diff) |
newpax (7mar21)
git-svn-id: svn://tug.org/texlive/trunk@58196 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex/newpax/newpax.lua')
-rw-r--r-- | Master/texmf-dist/tex/latex/newpax/newpax.lua | 521 |
1 files changed, 521 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/latex/newpax/newpax.lua b/Master/texmf-dist/tex/latex/newpax/newpax.lua new file mode 100644 index 00000000000..92b94c1f014 --- /dev/null +++ b/Master/texmf-dist/tex/latex/newpax/newpax.lua @@ -0,0 +1,521 @@ +-- +-- This is file `newpax.lua', +-- generated with the docstrip utility. +-- +-- The original source files were: +-- +-- newpax.dtx (with options: `lua') +-- +-- Copyright (C) 2021 Ulrike Fischer +-- +-- It may be distributed and/or modified under the conditions of +-- the LaTeX Project Public License (LPPL), either version 1.3c of +-- this license or (at your option) any later version. The latest +-- version of this license is in the file: +-- +-- https://www.latex-project.org/lppl.txt +-- +-- This file is part of the "newpax bundle" (The Work in LPPL) +-- and all files in that bundle must be distributed together. +-- +local ProvidesLuaModule = { + name = "newpax", + version = "0.51", --TAGVERSION + date = "2021-03-07", --TAGDATE + description = "newpax lua code", + license = "The LATEX Project Public License 1.3c" +} + +if luatexbase and luatexbase.provides_module then + luatexbase.provides_module (ProvidesLuaModule) +end + +local OPEN = pdfe.open +local GETSIZE = pdfe.getsize +local GETINFO = pdfe.getinfo +local GETPAGE = pdfe.getpage +local GETNAME = pdfe.getname +local GETARRAY = pdfe.getarray +local GETDICTIONARY = pdfe.getdictionary +local GETFROMDICTIONARY = pdfe.getfromdictionary +local GETFROMARRAY = pdfe.getfromarray +local PAGESTOTABLE = pdfe.pagestotable +local DICTIONARYTOTABLE = pdfe.dictionarytotable +local ARRAYTOTABLE = pdfe.arraytotable +local TYPE = pdfe.type +local GETFROMREFERENCE = pdfe.getfromreference +local FILENAMEONLY = file.nameonly + +local strENTRY_BEG = "\\[" +local strENTRY_END = "\\\\\n" +local strCMD_BEG = "{" +local strCMD_END = "}" +local strARG_BEG = "{" +local strARG_END = "}" +local strKVS_BEG = "{" +local strKVS_END = "\n}" +local strKVS_EMPTY = "{}" +local strKV_BEG = "\n " +local strKV_END = "," +local strKEY_BEG = "" +local strKEY_END = "" +local strVALUE_BEG = "={" +local strVALUE_END = "}" +local strHEX_STR_BEG = "\\<" +local strHEX_STR_END = "\\>" + +local strLIT_STR_BEG = "(" +local strLIT_STR_END = ")" +local strDICT_BEG= "<<" +local strDICT_END= ">>" +local strNAME= "/" +local strARRAY_BEG= "[" +local strARRAY_END= "]" +local strARRAY_SEP = " " +local strRECT_SEP = " " + +local constCMD_ANNOT = "annot" +local constCMD_BASEURL = "baseurl" -- unused +local constCMD_DEST = "dest" +local constCMD_FILE = "file" +local constCMD_INFO = "info" -- unused +local constCMD_PAGENUM = "pagenum" +local constCMD_PAGE = "page" +local constCMD_PAX = "pax" + +-- cmd file +local constKEY_SIZE = "Size" +local constKEY_DATE = "Date" + +-- cmd annot attributes +local constKEY_C = "C" +local constKEY_BORDER = "Border" +local constKEY_BS = "BS" +local constKEY_H = "H" + +-- cmd annot/link/URI +local constKEY_URI = "URI" +local constKEY_IS_MAP = "IsMap" -- not handled by pax, consider later + +-- cmd annot/link/GoToR +local constKEY_FILE = "File" +local constKEY_DEST_NAME = "DestName" -- handle?? +local constKEY_DEST_PAGE = "DestPage" --ok +local constKEY_DEST_VIEW = "DestView" --ok + +-- cmd annot/link/GoTo +local constKEY_DEST_RECT = "DestRect" +local constKEY_DEST_X = "DestX" +local constKEY_DEST_Y = "DestY" +local constKEY_DEST_ZOOM = "DestZoom" +local constKEY_DEST_LABEL = "DestLabel" --ok + +-- cmd annot/link/Named +local constKEY_NAME = "Name" + +-- destination views +local constDEST_XYZ = "XYZ" +local constDEST_FIT = "Fit" +local constDEST_FITH = "FitH" +local constDEST_FITV = "FitV" +local constDEST_FITR = "FitR" +local constDEST_FITB = "FitB" +local constDEST_FITBH = "FitBH" +local constDEST_FITBV = "FitBV" + +-- get/build data +-- returns table,pagecount where table objref ->page number +local function getpagesdata (pdfedoc) + local type,pagecount,detail = GETFROMDICTIONARY (pdfedoc.Catalog.Pages,"Count") + local pagestable = PAGESTOTABLE (pdfedoc) + local pagereftonum ={} + for i=1,#pagestable do + pagereftonum[pagestable[i][3]]=i + end + return pagereftonum, pagecount +end + +-- builds a table destination name -> obj reference (pdfedict) from the Names tree + +local function processnamesarray (pdfearray,targettable) + local tkey={} + for i=1,#pdfearray do + local type,value,detail= GETFROMARRAY(pdfearray,i) + if (i % 2 == 1) then + tkey = value + else + tvalue = value + targettable[tkey]=tvalue + end + end +end + +local function findallnamesarrays (pdfedict,deststable) + local namesarray = GETARRAY(pdfedict,"Names") + if namesarray then + processnamesarray (namesarray,deststable) + else + local kidsarray = GETARRAY(pdfedict,"Kids") + if kidsarray then + for i=1,#kidsarray do + findallnamesarrays (kidsarray[i],deststable) + end + end + end +end + +-- returns destnames -> objref table +local function getdestreferences (pdfedoc) + local deststable= {} + local catnames = GETDICTIONARY (pdfedoc.Catalog, "Names") + if catnames then + local destsdict = GETDICTIONARY (catnames, "Dests") + if destsdict then + findallnamesarrays (destsdict,deststable) + end + end + return deststable +end + +-- destinations can be an dict (/D [array]) or only an array! + +local function getdestdata (name,pagereftonum,destnamestoref) + local destref = destnamestoref[name] + local type,ref,pagenum,destx,desty = nil, nil, 1,0,0 + local data = {{0,0}, {5,constDEST_XYZ}} + if destref then + type,value,detail = GETFROMREFERENCE(destref) + if TYPE(value) == "pdfe.dictionary" then + local destarray = GETARRAY(value,"D") + if destarray then + data = ARRAYTOTABLE(destarray) + type, ref, pageref = GETFROMARRAY(destarray,1) + pagenum = pagereftonum[pageref] + end + elseif TYPE(value) == "pdfe.array" then + data = ARRAYTOTABLE(value) + type, ref, pageref = GETFROMARRAY(value,1) + pagenum = pagereftonum[pageref] + end + end + return pagenum, data +end + +-- output functions +-- write the info +-- XXXXXX encode/escape the file name? +local function outputENTRY_file (file, pdfedoc) + local bytes = GETSIZE(pdfedoc) + local date = GETINFO(pdfedoc).CreationDate + -- file + local a = strENTRY_BEG + a = a .. strCMD_BEG .. constCMD_FILE .. strCMD_END + a = a .. strARG_BEG .. strLIT_STR_BEG .. file .. strLIT_STR_END .. strARG_END + a = a .. strKVS_BEG + a = a .. strKV_BEG .. constKEY_SIZE .. strVALUE_BEG .. bytes .. strVALUE_END .. strKV_END + a = a .. strKV_BEG .. constKEY_DATE .. strVALUE_BEG .. date .. strVALUE_END.. strKV_END + a = a .. strKVS_END + a = a .. strENTRY_END + return a +end + +local function outputENTRY_pagenum (pages) + local a = strENTRY_BEG + a = a .. strCMD_BEG .. constCMD_PAGENUM .. strCMD_END + a = a .. strARG_BEG .. pages .. strARG_END + a = a .. strENTRY_END + return a +end + +local function outputENTRY_page (pdfedoc,page) -- page=integer + -- trimbox, bleedbox, cropbox,artbox,rotate etc could be put in + -- the second argument as keyval: + -- TrimBox={0 0 300 350}, + -- but pax skips the argument anyway, so not really useful + local mediabox = pdfe.getbox(GETPAGE(pdfedoc,page),"MediaBox") + local a="" + if mediabox then + a = strENTRY_BEG + a = a .. strCMD_BEG .. constCMD_PAGE .. strCMD_END + a = a .. strARG_BEG .. page .. strARG_END + a = a .. strARG_BEG + a = a .. mediabox[1] + for j = 2, 4 do + a = a .. strRECT_SEP.. mediabox[j] + end + a = a .. strARG_END + a = a .. strKVS_EMPTY + a = a .. strENTRY_END + end + return a +end + +local function outputCMD_annot (pdfedict,page,type) + local rectangle = ARRAYTOTABLE(GETARRAY(pdfedict,"Rect")) + local a = strCMD_BEG .. constCMD_ANNOT .. strCMD_END + a = a .. strARG_BEG .. page .. strARG_END + a = a .. strARG_BEG .. GETNAME(pdfedict,"Subtype") .. strARG_END + a = a .. strARG_BEG + a = a .. rectangle[1][2] + for k = 2, 4 do + a = a.. strRECT_SEP..rectangle[k][2] + end + a = a .. strARG_END + a = a .. strARG_BEG .. type .. strARG_END + return a +end + +local function outputKV_color (pdfedict) + local color = GETARRAY(pdfedict,constKEY_C) + local a ="" + if color then + local colortable = ARRAYTOTABLE(color) + a = strKV_BEG .. constKEY_C .. strVALUE_BEG .. strARRAY_BEG + for i=1,#colortable do + a = a.. colortable[i][2] .. strARRAY_SEP + end + a = a .. strARRAY_END .. strVALUE_END .. strKV_END + end + return a +end + +local function outputKV_key (pdfedict,key) + local name = GETNAME(pdfedict,key) + local a = "" + if name then + a = strKV_BEG .. key .. strVALUE_BEG .. strNAME .. name .. strVALUE_END .. strKV_END + end + return a +end + +-- XXX handle fourth argument +local function outputKV_Border (pdfedict) + local border = GETARRAY(pdfedict,constKEY_BORDER) + local a ="" + if border then + local bordertable = ARRAYTOTABLE(border) + a = strKV_BEG .. constKEY_BORDER .. strVALUE_BEG .. strARRAY_BEG + for i=1,3 do + a = a .. bordertable[i][2] .. strARRAY_SEP + end + -- fourth argument later, it is an array (type 7) + a = a ..strARRAY_END .. strVALUE_END .. strKV_END + end + return a +end + +local function outputKV_BS (pdfedict) + local bsstyle = GETDICTIONARY(pdfedict,constKEY_BS) + local a ="" + if bsstyle then + local bsstyledict = DICTIONARYTOTABLE(bsstyle) + a = strKV_BEG .. constKEY_BS .. strVALUE_BEG ..strDICT_BEG + for k,v in pairs (bsstyledict) do + a = a .. strNAME.. k + if v[1]== 5 then + a = a .. strNAME .. v[2] + else + a = a ..strRECT_SEP .. v[2] + end + end + a = a .. strDICT_END .. strVALUE_END .. strKV_END + end + return a +end + +local function outputKV_uri (pdfedict) + local type, value, hex = GETFROMDICTIONARY(pdfedict,constKEY_URI) + local a= strKV_BEG .. constKEY_URI .. strVALUE_BEG + if hex then + a = a .. strHEX_STR_BEG .. value .. strHEX_STR_END + else + a = a .. strLIT_STR_BEG ..value .. strLIT_STR_END + end + a = a .. strVALUE_END .. strKV_END + return a +end + +local function outputKV_N (pdfedict) + local name = GETNAME(pdfedict,"N") + local a= strKV_BEG .. constKEY_NAME .. strVALUE_BEG .. name .. strVALUE_END .. strKV_END + return a +end + +local function outputKV_gotor (pdfedict) -- action dictionary + local type, value, hex = GETFROMDICTIONARY(pdfedict,"F") + local desttype, destvalue, destdetail = GETFROMDICTIONARY(pdfedict,"D") + local a = strKV_BEG .. constKEY_FILE .. strVALUE_BEG + a = strKV_BEG .. constKEY_FILE .. strVALUE_BEG + if hex then + a = a .. strHEX_STR_BEG .. value .. strHEX_STR_end + else + a = a .. strLIT_STR_BEG .. value .. strLIT_STR_END + end + a = a .. strVALUE_END .. strKV_END + if desttype == 7 then + local type, pagenum = GETFROMARRAY(GETARRAY (pdfedict,"D"),1) + local type, fittype = GETFROMARRAY(GETARRAY (pdfedict,"D"),2) + a = a .. strKV_BEG .. constKEY_DEST_PAGE .. strVALUE_BEG .. pagenum .. strVALUE_END .. strKV_END + a = a .. strKV_BEG .. constKEY_DEST_VIEW .. strVALUE_BEG .. strNAME .. fittype .. strVALUE_END .. strKV_END + elseif desttype == 6 then + a = a .. strKV_BEG .. constKEY_DEST_NAME .. strVALUE_BEG .. + strLIT_STR_BEG .. destvalue .. strLIT_STR_END .. strVALUE_END .. strKV_END + end + return a +end + +local function outputKV_goto (count) + local a = strKV_BEG .. constKEY_DEST_LABEL .. strVALUE_BEG .. count .. strVALUE_END .. strKV_END + return a +end + +local function outputENTRY_dest (destcount,name,pagereftonum,destnamestoref,pdfedoc) + local pagenum, data = getdestdata(name,pagereftonum,destnamestoref) + local mediabox = pdfe.getbox(GETPAGE(pdfedoc,pagenum),"MediaBox") + local a = strENTRY_BEG + a = a .. strCMD_BEG .. constCMD_DEST .. strCMD_END + a = a .. strARG_BEG .. pagenum .. strARG_END + a = a .. strARG_BEG .. destcount .. strARG_END + -- name + a = a .. strARG_BEG .. data[2][2] .. strARG_END + a = a .. strKVS_BEG + if data[2][2] == constDEST_XYZ then + if data[3][2] then + a = a .. strKV_BEG .. constKEY_DEST_X .. strVALUE_BEG .. data[3][2] .. strVALUE_END .. strKV_END + else + a = a .. strKV_BEG .. constKEY_DEST_X .. strVALUE_BEG .. mediabox[1] .. strVALUE_END .. strKV_END + end + if data[4][2] then + a = a .. strKV_BEG .. constKEY_DEST_Y .. strVALUE_BEG .. data[4][2] .. strVALUE_END .. strKV_END + else + a = a .. strKV_BEG .. constKEY_DEST_X .. strVALUE_BEG .. mediabox[4] .. strVALUE_END .. strKV_END + end + if data[5][2] then + a = a .. strKV_BEG .. constKEY_DEST_ZOOM .. strVALUE_BEG .. data[5][2] .. strVALUE_END .. strKV_END + end + elseif data[2][2] == constDEST_FIT then -- nothing to do + elseif data[2][2] == constDEST_FITB then -- nothing to do + elseif data[2][2] == constDEST_FITH then + if data[3][2] then + a = a .. strKV_BEG .. constKEY_DEST_Y .. strVALUE_BEG .. data[3][2] .. strVALUE_END .. strKV_END + end + elseif data[2][2] == constDEST_FITBH then + if data[3][2] then + a = a .. strKV_BEG .. constKEY_DEST_Y .. strVALUE_BEG .. data[3][2] .. strVALUE_END .. strKV_END + end + elseif data[2][2] == constDEST_FITV then + if data[3][2] then + a = a .. strKV_BEG .. constKEY_DEST_X .. strVALUE_BEG .. data[3][2] .. strVALUE_END .. strKV_END + end + elseif data[2][2] == constDEST_FITBV then + if data[3][2] then + a = a .. strKV_BEG .. constKEY_DEST_X .. strVALUE_BEG .. data[3][2] .. strVALUE_END .. strKV_END + end + elseif data[2][2] == constDEST_FITR and data[6] then + a = a .. strKV_BEG .. constKEY_DEST_RECT .. strVALUE_BEG + a = a .. data[3][2] .. strRECT_SEP + a = a .. data[4][2] .. strRECT_SEP + a = a .. data[5][2] .. strRECT_SEP + a = a .. data[6][2] .. strVALUE_END .. strKV_END + end + a = a .. strKVS_END .. strENTRY_END + return a +end + +-- the main function + +local function __writepax (ext,file) + local fileVAR = assert(kpse.find_file(file ..".pdf"),"file `"..file..".pdf` not found") + local filebaseVAR = FILENAMEONLY(fileVAR) + -- getting the data for the concrete document: + local writeVAR = io.open (filebaseVAR .."."..ext,"w") -- always in current directory + local function WRITE(content) + writeVAR:write(content) + end + local docVAR = OPEN (fileVAR) + local pagereftonumVAR, pagecountVAR = getpagesdata (docVAR) + local destcountVAR = 0 + -- build from names table: + local destnamestorefVAR = getdestreferences (docVAR) + local collected_destinations = {} + -- output ... + WRITE(strENTRY_BEG .. "{pax}{0.1l}" .. strENTRY_END) + WRITE(outputENTRY_file(fileVAR,docVAR)) + WRITE(outputENTRY_pagenum(pagecountVAR)) + for i=1, pagecountVAR do + WRITE(outputENTRY_page(docVAR,i)) + local annots=GETPAGE(docVAR,i).Annots + if annots then + for j = 0,#annots-1 do + local annot = GETDICTIONARY (annots,j) + annottable = DICTIONARYTOTABLE (annot) + if annottable.Dest then + destcountVAR=destcountVAR + 1 + WRITE (strENTRY_BEG) + WRITE (outputCMD_annot(annot,i,"GoTo")) + WRITE (strKVS_BEG) -- begin KVS data + WRITE ( outputKV_color(annot) ) + WRITE ( outputKV_key(annot,constKEY_H) ) + WRITE ( outputKV_Border (annot) ) + WRITE ( outputKV_BS (annot) ) + WRITE ( outputKV_goto (destcountVAR) ) + WRITE(strKVS_END) -- end KVS + WRITE(strENTRY_END) -- end annot data + local type,annotgoto,hex = GETFROMDICTIONARY(annot,"Dest") + table.insert(collected_destinations, outputENTRY_dest(destcountVAR, + annotgoto,pagereftonumVAR,destnamestorefVAR,docVAR)) + else + local annotaction = GETDICTIONARY(annot,"A") + local annotactiontype ="" + if annotaction then + annotactiontype = GETNAME(annotaction,"S") + WRITE (strENTRY_BEG) + WRITE (outputCMD_annot(annot,i,annotactiontype)) + WRITE (strKVS_BEG) -- begin KVS data + WRITE ( outputKV_color(annot) ) + WRITE ( outputKV_key(annot,constKEY_H) ) + WRITE ( outputKV_Border (annot) ) + WRITE ( outputKV_BS (annot) ) + if annotactiontype == constKEY_URI then + WRITE ( outputKV_uri(annotaction) ) + elseif annotactiontype =="GoTo" then + destcountVAR=destcountVAR + 1 + WRITE ( outputKV_goto (destcountVAR) ) + elseif annotactiontype=="GoToR" then + WRITE ( outputKV_gotor(annotaction) ) + elseif annotactiontype=="Named" then + WRITE ( outputKV_N (annotaction) ) + end + WRITE(strKVS_END) -- end KVS + WRITE(strENTRY_END) -- end annot data + if annotactiontype =="GoTo" then + local type,annotactiongoto,hex = GETFROMDICTIONARY(annotaction,"D") + table.insert(collected_destinations, outputENTRY_dest(destcountVAR,annotactiongoto,pagereftonumVAR,destnamestorefVAR,docVAR)) + end + end + end + end + end + end + for i=1,#collected_destinations do + WRITE (collected_destinations[i]) + end + io.close(writeVAR) +end + +local function writepax (file) + __writepax ("pax",file) +end + +local function writenewpax (file) + __writepax ("newpax",file) +end + +newpax = {} +newpax.writepax = writepax +newpax.writenewpax = writenewpax + +return newpax + +-- +-- End of File `newpax.lua'. |