forked from prawnpdf/prawn
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Prawn::View mixin for custom documents
Squashed commit of the following: commit 1a17128 Author: Gregory Brown <[email protected]> Date: Mon Aug 11 10:59:27 2014 -0400 Add a manual entry for Prawn::View commit a95fc34 Author: Gregory Brown <[email protected]> Date: Mon Aug 11 10:41:00 2014 -0400 Add test coverage for Prawn::View commit 443567c Merge: ce5eedd 3818c4f Author: Gregory Brown <[email protected]> Date: Mon Aug 11 10:08:49 2014 -0400 Merge branch 'master' of github.com:prawnpdf/prawn into view commit ce5eedd Author: Gregory Brown <[email protected]> Date: Mon Aug 11 10:06:48 2014 -0400 Add API documentation for Prawn::View commit 0e90868 Merge: f7bdf09 12ccc2c Author: Gregory Brown <[email protected]> Date: Mon Aug 11 09:32:25 2014 -0400 Merge branch 'master' of github.com:prawnpdf/prawn into view commit f7bdf09 Author: Gregory Brown <[email protected]> Date: Thu Aug 7 12:02:12 2014 -0400 Bump to latest Ruby 2.1 build commit db67e27 Author: Gregory Brown <[email protected]> Date: Thu Jul 31 07:01:22 2014 -0400 Somewhat softer method_missing hook for Prawn::View commit 06dec83 Author: Gregory Brown <[email protected]> Date: Wed Jul 30 19:37:44 2014 -0400 Allow NoMethodError to bubble up. commit afa0ef6 Author: Gregory Brown <[email protected]> Date: Wed Jul 30 08:41:48 2014 -0400 Add missing encoding comment commit 8ce3eaa Author: Gregory Brown <[email protected]> Date: Wed Jul 30 08:33:52 2014 -0400 Add Prawn::View
- Loading branch information
1 parent
3818c4f
commit c3e6d27
Showing
5 changed files
with
180 additions
and
4 deletions.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
# encoding: UTF-8 | ||
# | ||
# prawn/view.rb : Implements a mixin for Prawn's DSL | ||
# | ||
# This is free software. Please see the LICENSE and COPYING files for details. | ||
|
||
module Prawn | ||
# This mixin allows you to create modular Prawn code without the | ||
# need to create subclasses of Prawn::Document. | ||
# | ||
# class Greeter | ||
# include Prawn::View | ||
# | ||
# def initialize(name) | ||
# @name = name | ||
# end | ||
# | ||
# def say_hello | ||
# text "Hello, #{@name}!" | ||
# end | ||
# | ||
# def say_goodbye | ||
# font("Courier") do | ||
# text "Goodbye, #{@name}!" | ||
# end | ||
# end | ||
# end | ||
# | ||
# greeter = Greeter.new("Gregory") | ||
# | ||
# greeter.say_hello | ||
# greeter.say_goodbye | ||
# | ||
# greeter.save_as("greetings.pdf") | ||
# | ||
# The short story about why you should use this mixin rather than | ||
# creating subclasses of +Prawn::Document+ is that it helps | ||
# prevent accidental conflicts between your code and Prawn's | ||
# code. | ||
# | ||
# Here's the slightly longer story... | ||
# | ||
# By using composition rather than inheritance under the hood, this | ||
# mixin allows you to keep your state separate from +Prawn::Document+'s | ||
# state, and also will prevent unexpected method name collisions due | ||
# to late binding effects. | ||
# | ||
# This mixin is mostly meant for extending Prawn's functionality | ||
# with your own additions, but you can also use it to replace or | ||
# wrap existing Prawn methods. Calling +super+ will still work | ||
# as expected, and alternatively you can explictly call | ||
# +document.some_method+ to delegate to Prawn where needed. | ||
module View | ||
# @group Experimental API | ||
|
||
# Lazily instantiates a +Prawn::Document+ object. | ||
# | ||
# You can also redefine this method in your own classes to use | ||
# a custom document class. | ||
def document | ||
@document ||= Prawn::Document.new | ||
end | ||
|
||
# Delegates all unhandled calls to object returned by +document+ method. | ||
# (which is an instance of Prawn::Document by default) | ||
def method_missing(m, *a, &b) | ||
return super unless document.respond_to?(m) | ||
|
||
document.send(m, *a, &b) | ||
end | ||
|
||
# Syntactic sugar that uses +instance_eval+ under the hood to provide | ||
# a block-based DSL. | ||
# | ||
# greeter.update do | ||
# say_hello | ||
# say_goodbye | ||
# end | ||
# | ||
def update(&b) | ||
instance_eval(&b) | ||
end | ||
|
||
# Syntatic sugar that calls +document.render_file+ under the hood. | ||
# | ||
# greeter.save_as("greetings.pdf") | ||
def save_as(filename) | ||
document.render_file(filename) | ||
end | ||
end | ||
end |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# encoding: UTF-8 | ||
# | ||
# To create a custom class that extends Prawn's functionality, | ||
# use the <code>Prawn::View</code> mixin. This approach is safer than creating | ||
# subclasses of <code>Prawn::Document</code> while being just as convenient. | ||
# | ||
# By using this mixin, your state will be kept completely separate | ||
# from <code>Prawn::Document</code>'s state, and you will avoid accidental method | ||
# collisions within <code>Prawn::Document</code>. | ||
# | ||
# To build custom classes that make use of other custom classes, | ||
# you can define a method named <code>document()</code> that returns | ||
# any object that acts similar to a <code>Prawn::Document</code> | ||
# object. <code>Prawn::View</code> will then direct all delegated | ||
# calls to that object instead. | ||
|
||
require_relative "../example_helper" | ||
|
||
class Greeter | ||
include Prawn::View | ||
|
||
def initialize(name) | ||
@name = name | ||
end | ||
|
||
def say_hello | ||
text "Hello, #{@name}!" | ||
end | ||
|
||
def say_goodbye | ||
font("Courier") do | ||
text "Goodbye, #{@name}!" | ||
end | ||
end | ||
end | ||
|
||
greeter = Greeter.new("Gregory") | ||
|
||
greeter.say_hello | ||
greeter.say_goodbye | ||
|
||
greeter.save_as("greetings.pdf") |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
# encoding: utf-8 | ||
|
||
require_relative "spec_helper" | ||
|
||
describe "Prawn::View" do | ||
let(:view_object) { Object.new.tap { |o| o.extend(Prawn::View) } } | ||
|
||
it "provides a Prawn::Document object by default" do | ||
expect(view_object.document).to be_kind_of(Prawn::Document) | ||
end | ||
|
||
it "delegates unhandled methods to object returned by document method" do | ||
doc = mock("Document") | ||
view_object.stubs(:document => doc) | ||
|
||
doc.expects(:some_delegated_method) | ||
|
||
view_object.some_delegated_method | ||
end | ||
|
||
it "allows a block-like DSL via the update method" do | ||
doc = mock("Document") | ||
view_object.stubs(:document => doc) | ||
|
||
doc.expects(:foo) | ||
doc.expects(:bar) | ||
|
||
view_object.update do | ||
foo | ||
bar | ||
end | ||
end | ||
|
||
it "aliases save_as() to document.render_file()" do | ||
doc = mock("Document") | ||
doc.expects(:render_file) | ||
|
||
view_object.stubs(:document => doc) | ||
|
||
view_object.save_as("foo.pdf") | ||
end | ||
end | ||
|