Created
July 3, 2011 07:41
-
-
Save pgundlach/1062041 to your computer and use it in GitHub Desktop.
Sample Lua Document to create a two page PDF document with hyperlinks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
do | |
-- this will hold the items that go onto the page | |
local pagelist | |
-- Call tex.shipout() with the contents of the pagelist | |
function shipout() | |
local vbox,b = node.vpack(pagelist) -- we ignore the badness 'b' | |
tex.box[666] = vbox | |
tex.shipout(666) | |
pagelist = nil | |
-- Not strictly necessary. TeX holds the current page number in counter 0. | |
-- TeX displays the contents of this counter when it puts a page into | |
-- the pdf (tex.shipout()). If we don't change the counter, TeX will | |
-- display [1] [1], instead of [1] [2] for our two page document. | |
tex.count[0] = tex.count[0] + 1 | |
end | |
function add_to_page( list ) | |
-- We attach the nodelist 'list' to the end of the pagelist | |
-- if pagelist doesn't exist, 'list' is our new pagelist | |
-- if it exists, we go to the end with node.tail() and adjust | |
-- the prev and next pointers, so list becomes part | |
-- of pagelist. | |
if not pagelist then pagelist = list | |
else | |
local tail = node.tail(pagelist) | |
tail.next = list | |
list.prev = tail | |
end | |
end | |
end | |
-- This creates a new square rule and returns the pointer to it. | |
function mkrule( size ) | |
local r = node.new("rule") | |
r.width = size | |
r.height = size / 2 | |
r.depth = size / 2 | |
return r | |
end | |
do | |
local destcounter = 0 | |
-- Create a pdf anchor (dest object). It returns a whatsit node and the | |
-- number of the anchor, so it can be used in a pdf link or an outline. | |
function mkdest() | |
destcounter = destcounter + 1 | |
local d = node.new("whatsit","pdf_dest") | |
d.named_id = 0 | |
d.dest_id = destcounter | |
d.dest_type = 3 | |
return d, destcounter | |
end | |
end | |
-- Take a list of nodes and put them into an hbox. The prev and next fields | |
-- of the nodes will be set automatically. Return a pointer to the hbox. | |
function hpack( ... ) | |
local start, tmp, cur | |
start = select(1,...) | |
tmp = start | |
for i=2,select("#",...) do | |
cur = select(i,...) | |
tmp.next = cur | |
cur.prev = tmp | |
tmp = cur | |
end | |
local h,b = node.hpack(start) -- ignore badness | |
return h | |
end | |
local tenpt = 10 * 2^16 | |
--------------------------- | |
-- page 1 | |
--------------------------- | |
local n,dest = mkdest() -- dest is needed for the link to this anchor | |
add_to_page(n) | |
add_to_page(mkrule(2 * tenpt)) | |
-- The pagelist contains a pdf dest node (a link destination) and a rule of size 20pt x 20pt. | |
shipout() | |
--------------------------- | |
-- page 2 | |
--------------------------- | |
-- This is the page with the link to the anchor (dest) on page one. A | |
-- link consists of three nodes: a pdf_start_link, a pdf_end_link and and | |
-- action node that specifies the action to perform when the user clicks on | |
-- the link. | |
-- The pdf link must be inside a horizontal box, that's why we hpack() it. | |
-- The link_attr (link attributes) is optional, here it draws a yellowish border | |
-- around the link. | |
local start_link = node.new("whatsit","pdf_start_link") | |
local end_link = node.new("whatsit","pdf_end_link") | |
start_link.width = tenpt | |
start_link.height = tenpt / 2 | |
start_link.depth = tenpt / 2 | |
start_link.link_attr = "/C [0.9 1 0] /Border [0 0 2]" | |
start_link.action = node.new("action") | |
start_link.action.action_type = 1 | |
start_link.action.action_id = dest | |
local rule = mkrule(tenpt) | |
local hbox = hpack(start_link, rule, end_link) | |
add_to_page(hbox) | |
-- This pagelist consists of an hbox whose contents is "start_link", | |
-- the 10pt x 10pt rule and the "end_link" node. | |
shipout() | |
--------------------------- | |
-- Just to show you that you can get some memory usage statistics: | |
print(string.format("\nnode_mem_usage=%s",status.node_mem_usage)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment