Skip to content

Commit 31162e2

Browse files
Add autoprint
1 parent 19390f4 commit 31162e2

8 files changed

Lines changed: 72 additions & 12 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## Latest
9+
10+
- Add `autoprint/1` to automatically open the print dialog in a browser
11+
812
## 0.6.1 (2023-01-19)
913

1014
- Fix bug with zero width strings and empty rows (also fixes [#24])

lib/pdf.ex

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,16 @@ defmodule Pdf do
214214
pid
215215
end
216216

217+
@doc """
218+
Adds an autoprint action to the Pdf.
219+
220+
This is can be useful for generating a PDF that will automatically open the print dialog in a browser
221+
"""
222+
def autoprint(pid) do
223+
:ok = GenServer.call(pid, :autoprint)
224+
pid
225+
end
226+
217227
@doc "Returns the current page number."
218228
def page_number(pid) do
219229
GenServer.call(pid, :page_number)
@@ -663,6 +673,11 @@ defmodule Pdf do
663673
end
664674

665675
@impl true
676+
def handle_call(:autoprint, _from, document) do
677+
document = Document.autoprint(document)
678+
{:reply, :ok, document}
679+
end
680+
666681
def handle_call({:write_to, path}, _from, document) do
667682
File.write!(path, Document.to_iolist(document))
668683
{:reply, :ok, document}

lib/pdf/dictionary.ex

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
defmodule Pdf.Dictionary do
22
@moduledoc false
3-
import Pdf.Size
43
import Pdf.Utils
4+
import Pdf.Size
55

66
@dict_start "<<\n"
77
@dict_start_length byte_size(@dict_start)
@@ -19,6 +19,7 @@ defmodule Pdf.Dictionary do
1919

2020
def new(map) do
2121
map
22+
|> Enum.filter(fn {_, value} -> value != nil end)
2223
|> Enum.reduce(new(), fn {key, value}, dictionary ->
2324
put(dictionary, key, value)
2425
end)

lib/pdf/document.ex

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ defmodule Pdf.Document do
88
current_font_size: 0,
99
pages: [],
1010
opts: [],
11+
action: nil,
1112
images: %{}
1213

1314
import Pdf.Utils
@@ -42,6 +43,24 @@ defmodule Pdf.Document do
4243
add_page(document, opts)
4344
end
4445

46+
def autoprint(document) do
47+
action =
48+
ObjectCollection.create_object(
49+
document.objects,
50+
Dictionary.new(%{
51+
"S" => n("Named"),
52+
"Type" => n("Action"),
53+
"N" => n("Print")
54+
})
55+
)
56+
57+
put_in(document.action, action)
58+
end
59+
60+
def get_object(document, ref) do
61+
ObjectCollection.get_object(document.objects, ref)
62+
end
63+
4564
@info_map %{
4665
title: "Title",
4766
producer: "Producer",
@@ -228,7 +247,11 @@ defmodule Pdf.Document do
228247
catalogue =
229248
ObjectCollection.create_object(
230249
document.objects,
231-
Dictionary.new(%{"Type" => n("Catalog"), "Pages" => master_page})
250+
Dictionary.new(%{
251+
"Type" => n("Catalog"),
252+
"Pages" => master_page,
253+
"OpenAction" => document.action
254+
})
232255
)
233256

234257
objects = Enum.sort_by(ObjectCollection.all(document.objects), &sort_objects/1)

lib/pdf/external_font.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ defmodule Pdf.ExternalFont do
2222
kern_pairs: []
2323

2424
import Pdf.Utils
25+
2526
alias Pdf.Font.Metrics
2627
alias Pdf.{Array, Dictionary}
2728

test/pdf/document_test.exs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
defmodule Pdf.DocumentTest do
22
use ExUnit.Case, async: true
3+
import Pdf.Utils
34

45
alias Pdf.{Document, ObjectCollection, Dictionary}
56

@@ -35,4 +36,17 @@ defmodule Pdf.DocumentTest do
3536
defp get_info(document) do
3637
document.objects |> ObjectCollection.get_object(document.info) |> Dictionary.to_map()
3738
end
39+
40+
test "autoprint/0" do
41+
document = Document.autoprint(Document.new())
42+
assert {:object, _, _} = ref = document.action
43+
44+
assert %Dictionary{
45+
entries: %{
46+
{:name, "S"} => {:name, "Named"},
47+
{:name, "Type"} => {:name, "Action"},
48+
{:name, "N"} => {:name, "Print"}
49+
}
50+
} = Document.get_object(document, ref)
51+
end
3852
end

test/pdf/object_test.exs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
defmodule Pdf.ObjectTest do
22
use ExUnit.Case, async: true
3+
import Pdf.Utils
34

45
alias Pdf.Object
56
alias Pdf.Dictionary
6-
alias Pdf.Utils
77

88
test "new/1" do
99
object = Object.new(1)
@@ -42,14 +42,14 @@ defmodule Pdf.ObjectTest do
4242
test "size" do
4343
dict =
4444
Dictionary.new()
45-
|> Dictionary.put("Author", Utils.n("Test Author"))
46-
|> Dictionary.put("Creator", Utils.n("Test Creator"))
47-
|> Dictionary.put("Keywords", Utils.n("word word word"))
48-
|> Dictionary.put("Producer", Utils.n("Test producer"))
49-
|> Dictionary.put("Subject", Utils.n("Test Subject"))
50-
|> Dictionary.put("Title", Utils.n("Test Document"))
51-
|> Dictionary.put("Title", Utils.n("Test Document"))
52-
|> Dictionary.put("Title", Utils.n("Test Document"))
45+
|> Dictionary.put("Author", n("Test Author"))
46+
|> Dictionary.put("Creator", n("Test Creator"))
47+
|> Dictionary.put("Keywords", n("word word word"))
48+
|> Dictionary.put("Producer", n("Test producer"))
49+
|> Dictionary.put("Subject", n("Test Subject"))
50+
|> Dictionary.put("Title", n("Test Document"))
51+
|> Dictionary.put("Title", n("Test Document"))
52+
|> Dictionary.put("Title", n("Test Document"))
5353

5454
object = Object.new(1, dict)
5555

test/pdf_test.exs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ defmodule PdfTest do
5151
|> Pdf.add_image({310, 365}, fixture("truecolour-alpha.png"))
5252
|> Pdf.add_font("test/fonts/Verdana-Bold.afm")
5353
|> Pdf.set_font("Verdana-Bold", 28)
54-
|> Pdf.text_at({120.070, 762.653}, "External fonts work", kerning: true)
54+
# |> Pdf.text_at({120.070, 762.653}, "External fonts work", kerning: true)
55+
|> Pdf.text_at({120.070, 762.653}, "External fonts work")
5556
|> Pdf.set_font("Helvetica", 28)
5657
|> Pdf.text_at({200, 230}, "Back to Helvetica")
5758
|> Pdf.set_font("Helvetica", size: 16, bold: true)
@@ -100,6 +101,7 @@ defmodule PdfTest do
100101
align: :right
101102
)
102103
|> elem(0)
104+
|> Pdf.autoprint()
103105
|> Pdf.write_to(file_path)
104106
end)
105107

0 commit comments

Comments
 (0)