Skip to content

Commit

Permalink
Features/outline (#831)
Browse files Browse the repository at this point in the history
Outline support by @alexvdev and @blforce
Close #216, close #13
  • Loading branch information
theBenForce authored and alafr committed Jun 22, 2018
1 parent 34cf8d5 commit f91bdd6
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ Installation uses the [npm](http://npmjs.org/) package manager. Just type the f
* Highlights
* Underlines
* etc.
* Outlines

## Coming soon!

* Patterns fills
* Outlines
* PDF Security
* Higher level APIs for creating tables and laying out content
* More performance optimizations
Expand Down
7 changes: 7 additions & 0 deletions docs/generate.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,11 @@ class Node
if @type in ['h1', 'h2'] and lastType? and lastType isnt 'h1'
doc.addPage()

if @type == 'h1'
doc.h1Outline = doc.outline.addItem(fragment.text)
else if @type == 'h2' && doc.h1Outline != null
doc.h1Outline.addItem(fragment.text)

# set styles and whether this fragment is continued (for rich text wrapping)
options = @setStyle doc
options.continued ?= continued or index < @content.length - 1
Expand Down Expand Up @@ -227,6 +232,7 @@ renderTitlePage = (doc) ->
doc.y = doc.page.height / 2 - doc.currentLineHeight()
doc.text title, align: 'center'
w = doc.widthOfString(title)
doc.h1Outline = doc.outline.addItem(title)

doc.fontSize 20
doc.y -= 10
Expand All @@ -250,5 +256,6 @@ do ->
render doc, 'vector.coffee.md'
render doc, 'text.coffee.md'
render doc, 'images.coffee.md'
render doc, 'outline.coffee.md'
render doc, 'annotations.coffee.md'
doc.end()
Binary file modified docs/guide.pdf
Binary file not shown.
28 changes: 28 additions & 0 deletions docs/outline.coffee.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Outlines in PDFKit

Outlines are the heirachical bookmarks that display in some PDF readers. Currently only page bookmarks are supported, but more may be added in the future. They are simple to add and only require a single method:

* `addItem(title, options)`
Here is an example of adding a bookmark with a single child bookmark.

# Get a reference to the Outline root
outline = doc.outline
# Add a top-level bookmark
top = outline.addItem('Top Level')
# Add a sub-section
top.addItem('Sub-section')
## Options

The `options` parameter currently only has one property: `expanded`. If this value is set to `true` then all of that section's children will be visible by default. This value defaults to `false`.

In this example the 'Top Level' section will be expanded to show 'Sub-section'.

# Add a top-level bookmark
top = outline.addItem('Top Level', { expanded: true })
# Add a sub-section
top.addItem('Sub-section')
4 changes: 4 additions & 0 deletions lib/document.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class PDFDocument extends stream.Readable
@initFonts()
@initText()
@initImages()
@initOutline()

# Initialize the metadata
@info =
Expand Down Expand Up @@ -77,6 +78,7 @@ class PDFDocument extends stream.Readable
mixin require './mixins/text'
mixin require './mixins/images'
mixin require './mixins/annotations'
mixin require './mixins/outline'

addPage: (options = @options) ->
# end the current page if needed
Expand Down Expand Up @@ -184,6 +186,8 @@ class PDFDocument extends stream.Readable
for name, font of @_fontFamilies
font.finalize()

@endOutline()

@_root.end()
@_root.data.Pages.end()

Expand Down
11 changes: 11 additions & 0 deletions lib/mixins/outline.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
PDFOutline = require '../outline'

module.exports =
initOutline: () ->
@outline = new PDFOutline(this, null, null, null)

endOutline: () ->
@outline.endOutline()
if @outline.children.length > 0
@_root.data.Outlines = @outline.dictionary
@_root.data.PageMode = 'UseOutlines'
47 changes: 47 additions & 0 deletions lib/outline.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
PDFObject = require './object'
PDFPage = require './page'

class PDFOutline
constructor: (@document, parent, title, dest, @options = { expanded: false }) ->

@outlineData = {}

if dest != null
@outlineData['Dest'] = [dest.dictionary, 'Fit']

if parent != null
@outlineData['Parent'] = parent

if title != null
@outlineData['Title'] = new String(title)

@dictionary = @document.ref @outlineData
@children = []

addItem: (title, options = { expanded: false }) ->
result = new PDFOutline(@document, @dictionary, title, @document.page, options)
@children.push(result)

return result

endOutline: () ->
if @children.length > 0
if @options.expanded
@outlineData.Count = @children.length

[first, ..., last] = @children
@outlineData.First = first.dictionary
@outlineData.Last = last.dictionary

for i in [0...@children.length]
child = @children[i]
if i > 0
child.outlineData.Prev = @children[i-1].dictionary
if i < @children.length - 1
child.outlineData.Next = @children[i+1].dictionary
child.endOutline()

@dictionary.end()


module.exports = PDFOutline

0 comments on commit f91bdd6

Please sign in to comment.