File: view.rb

package info (click to toggle)
ruby-prawn 2.3.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 4,380 kB
  • sloc: ruby: 15,820; sh: 43; makefile: 20
file content (101 lines) | stat: -rw-r--r-- 2,981 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# frozen_string_literal: true

# 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
  #
  #       # Optional override: allows you to set document options or even use
  #       # a custom document class
  #       def document
  #         @document ||= Prawn::Document.new(page_size: 'A4')
  #       end
  #
  #       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(method_name, *arguments, &block)
      return super unless document.respond_to?(method_name)

      document.send(method_name, *arguments, &block)
    end

    def respond_to_missing?(method_name, _include_all = false)
      document.respond_to?(method_name)
    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(&block)
      instance_eval(&block)
    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