Class: Prawn::ManualBuilder::Example

Inherits:
Object
  • Object
show all
Defined in:
lib/prawn/manual_builder/example.rb

Overview

The Prawn::ManualBuilder::Example class holds all the helper methods used to generate manuals.

The overall structure is to have single example files grouped by package folders. Each package has a package builder file (with the same name as the package folder) that defines the inner structure of subsections and examples. The manual is then built by loading all the packages and some standalone pages.

To see one of the examples check manual/basic_concepts/cursor.rb

To see one of the package builders check manual/basic_concepts/basic_concepts.rb

To see how the manual is built check manual/manual/manual.rb (Yes that’s a whole load of manuals)

Constant Summary collapse

BOX_MARGIN =

This is the default value for the margin box

36
INNER_MARGIN =

Additional indentation to keep the line measure with a reasonable size

30
RHYTHM =

Vertical Rhythm settings

10
LEADING =
2
BLACK =

Colors

"000000"
LIGHT_GRAY =
"F2F2F2"
GRAY =
"DDDDDD"
DARK_GRAY =
"333333"
BROWN =
"A4441C"
ORANGE =
"F28157"
LIGHT_GOLD =
"FBFBBE"
DARK_GOLD =
"EBE389"
BLUE =
"0000D0"
MANUAL_URL =

Used to generate the url for the example files

"http://github.com/prawnpdf/prawn/tree/master/manual"

Instance Method Summary collapse

Instance Method Details

#code(str) ⇒ Object

Render a code block. Used on the example pages of the manual



202
203
204
205
206
207
208
209
# File 'lib/prawn/manual_builder/example.rb', line 202

def code(str)
  pre_text = str.gsub(' ', Prawn::Text::NBSP)
  pre_text = ::CodeRay.scan(pre_text, :ruby).to_prawn

  font('Courier', :size => 9.5) do
    colored_box(pre_text, :fill_color => DARK_GRAY)
  end
end

#colored_box(box_text, options = {}) ⇒ Object

Renders a Bounding Box with some background color and the formatted text inside it



325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
# File 'lib/prawn/manual_builder/example.rb', line 325

def colored_box(box_text, options={})
  options = { :fill_color   => DARK_GRAY,
              :stroke_color => nil,
              :text_color   => LIGHT_GRAY,
              :leading      => LEADING
            }.merge(options)

  register_fonts
  text_options = { :leading        => options[:leading],
                   :fallback_fonts => ["DejaVu", "Kai"]
                 }

  box_height = height_of_formatted(box_text, text_options)

  bounding_box([INNER_MARGIN + RHYTHM, cursor],
               :width => bounds.width - (INNER_MARGIN+RHYTHM)*2) do

    fill_color   options[:fill_color]
    stroke_color options[:stroke_color] || options[:fill_color]
    fill_and_stroke_rounded_rectangle(
        [bounds.left - RHYTHM, cursor],
        bounds.left + bounds.right + RHYTHM*2,
        box_height + RHYTHM*2,
        5
    )
    fill_color   BLACK
    stroke_color BLACK

    pad(RHYTHM) do
      formatted_text(box_text, text_options)
    end
  end

  move_down(RHYTHM*2)
end

#eval_code(source) ⇒ Object

Renders a dashed line and evaluates the code inline



213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/prawn/manual_builder/example.rb', line 213

def eval_code(source)
  move_down(RHYTHM)

  dash(3)
  stroke_color(BROWN)
  stroke_horizontal_line(-BOX_MARGIN, bounds.width + BOX_MARGIN)
  stroke_color(BLACK)
  undash

  move_down(RHYTHM*3)
  begin
    eval(source)
  rescue => e
    puts "Error evaluating example: #{e.message}"
    puts
    puts "---- Source: ----"
    puts source
  end
end

#example_header(package, example) ⇒ Object

Render the example header. Used on the example pages of the manual



140
141
142
143
144
145
146
147
148
149
150
# File 'lib/prawn/manual_builder/example.rb', line 140

def example_header(package, example)
  header_box do
    register_fonts
    font('DejaVu', :size => 18) do
      formatted_text([ { :text => package, :color => BROWN  },
                       { :text => "/",     :color => BROWN  },
                       { :text => example, :color => ORANGE }
                     ], :valign => :center)
    end
  end
end

#header(str) ⇒ Object

Render a page header. Used on the manual lone pages and package introductory pages



259
260
261
262
263
264
265
266
# File 'lib/prawn/manual_builder/example.rb', line 259

def header(str)
  header_box do
    register_fonts
    font('DejaVu', :size => 24) do
      text(str, :color  => BROWN, :valign => :center)
    end
  end
end

#header_box(&block) ⇒ Object

Renders the page-wide headers



293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
# File 'lib/prawn/manual_builder/example.rb', line 293

def header_box(&block)
  bounding_box([-bounds.absolute_left, cursor + BOX_MARGIN],
               :width  => bounds.absolute_left + bounds.absolute_right,
               :height => BOX_MARGIN*2 + RHYTHM*2) do

    fill_color LIGHT_GRAY
    fill_rectangle([bounds.left, bounds.top],
                    bounds.right,
                    bounds.top - bounds.bottom)
    fill_color BLACK

    indent(BOX_MARGIN + INNER_MARGIN, &block)
  end

  stroke_color GRAY
  stroke_horizontal_line(-BOX_MARGIN, bounds.width + BOX_MARGIN, :at => cursor)
  stroke_color BLACK

  move_down(RHYTHM*3)
end

#inner_box(&block) ⇒ Object

Renders a Bounding Box for the inner margin



316
317
318
319
320
# File 'lib/prawn/manual_builder/example.rb', line 316

def inner_box(&block)
  bounding_box([INNER_MARGIN, cursor],
               :width => bounds.width - INNER_MARGIN*2,
               &block)
end

#list(*items) ⇒ Object

Render the arguments as a bulleted list. Used on the manual package introductory pages



271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
# File 'lib/prawn/manual_builder/example.rb', line 271

def list(*items)
  move_up(RHYTHM)

  inner_box do
    font("Helvetica", :size => 11) do
      items.each do |li|
        float { text("", :color => DARK_GRAY) }
        indent(RHYTHM) do
          text(li.gsub(/\s+/," "),
               :inline_format => true,
               :color         => DARK_GRAY,
               :leading       => LEADING)
        end

        move_down(RHYTHM)
      end
    end
  end
end

#load_file(package, file) ⇒ Object

Opens a file in a given package and evals the source



71
72
73
74
75
# File 'lib/prawn/manual_builder/example.rb', line 71

def load_file(package, file)
  start_new_page
  example = ExampleFile.new(package, "#{file}.rb")
  eval example.generate_block_source
end

#load_package(package) ⇒ Object

Loads a package. Used on the manual.



55
56
57
# File 'lib/prawn/manual_builder/example.rb', line 55

def load_package(package)
  load_file(package, package)
end

#load_page(page) ⇒ Object

Loads a page with outline support. Used on the manual.



61
62
63
64
65
66
67
# File 'lib/prawn/manual_builder/example.rb', line 61

def load_page(page)
  load_file("manual", page)

  outline.define do
    section(page.gsub("_", " ").capitalize, :destination => page_number)
  end
end

#package(package, &block) ⇒ Object

Creates a new ExamplePackage object and yields it to a block in order for it to be populated with examples, sections and some introduction text. Used on the package files.



82
83
84
85
86
# File 'lib/prawn/manual_builder/example.rb', line 82

def package(package, &block)
  ep = ExamplePackage.new(package)
  ep.instance_eval(&block)
  ep.render(self)
end

#prose(str) ⇒ Object

Render a block of text after processing code tags and URLs to be used with the inline_format option.

Used on the introducory text for example pages of the manual and on package pages intro



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/prawn/manual_builder/example.rb', line 172

def prose(str)

  # Process the <code> tags
  str.gsub!(/<code>([^<]+?)<\/code>/,
      "<font name='Courier'><b>\\1<\/b><\/font>")

  # Process the links
  str.gsub!(/(https?:\/\/\S+)/,
              "<color rgb='#{BLUE}'><link href=\"\\1\">\\1</link></color>")

  inner_box do
    font("Helvetica", :size => 11) do
      str.split(/\n\n+/).each do |paragraph|

        text(paragraph.gsub(/\s+/," "),
             :align         => :justify,
             :inline_format => true,
             :leading       => LEADING,
             :color         => DARK_GRAY)

        move_down(RHYTHM)
      end
    end
  end

  move_down(RHYTHM)
end

#register_fontsObject

Register fonts used on the manual



154
155
156
157
158
159
160
161
162
163
164
# File 'lib/prawn/manual_builder/example.rb', line 154

def register_fonts
  kai_file = "#{Prawn::ManualBuilder::DATADIR}/fonts/gkai00mp.ttf"
  font_families["Kai"] = {
    :normal => { :file => kai_file, :font => "Kai" }
  }

  dejavu_file = "#{Prawn::ManualBuilder::DATADIR}/fonts/DejaVuSans.ttf"
  font_families["DejaVu"] = {
    :normal => { :file => dejavu_file, :font => "DejaVu" }
  }
end

#render_example(example) ⇒ Object

Renders an ExampleFile.

Starts a new page and renders an introductory text, the example source and evaluates the example source inline whenever that is appropriate according to the ExampleFile directives.



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/prawn/manual_builder/example.rb', line 116

def render_example(example)
  start_new_page

  outline.add_subsection_to(example.parent_name) do
    outline.page(:destination => page_number, :title => example.name)
  end

  example_header(example.parent_folder_name, example.filename)

  prose(example.introduction_text)

  code(example.source)

  if example.eval?
    eval_code(example.source)
  else
    source_link(example)
  end

  reset_settings
end

#render_package_cover(package) ⇒ Object

Renders an ExamplePackage cover page.

Starts a new page and renders the package introduction text.



92
93
94
95
96
97
98
99
# File 'lib/prawn/manual_builder/example.rb', line 92

def render_package_cover(package)
  header(package.name)
  instance_eval &(package.intro_block)

  outline.define do
    section(package.name, :destination => page_number, :closed => true)
  end
end

#render_section(section) ⇒ Object

Add the ExampleSection to the document outline within the appropriate package.



104
105
106
107
108
# File 'lib/prawn/manual_builder/example.rb', line 104

def render_section(section)
  outline.add_subsection_to(section.package_name) do
    outline.section(section.name, :closed => true)
  end
end

#reset_settingsObject

Reset some of the Prawn settings including graphics and text to their defaults.

Used after rendering examples so that each new example starts with a clean slate.



374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
# File 'lib/prawn/manual_builder/example.rb', line 374

def reset_settings

  # Text settings
  font("Helvetica", :size => 12)
  default_leading 0
  self.text_direction = :ltr

  # Graphics settings
  self.line_width = 1
  self.cap_style  = :butt
  self.join_style = :miter
  undash
  fill_color   BLACK
  stroke_color BLACK
end

Renders a box with the link for the example file



235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
# File 'lib/prawn/manual_builder/example.rb', line 235

def source_link(example)
  url = "#{MANUAL_URL}/#{example.parent_folder_name}/#{example.filename}"

  reason = [{ :text  => "This code snippet was not evaluated inline. " +
                        "You may see its output by running the " +
                        "example file located here:\n",
              :color => DARK_GRAY },

            { :text   => url,
              :color  => BLUE,
              :link   => url}
           ]

  font('Helvetica', :size => 9) do
    colored_box(reason,
                :fill_color   => LIGHT_GOLD,
                :stroke_color => DARK_GOLD,
                :leading      => LEADING*3)
  end
end

#stroke_axis(options = {}) ⇒ Object

Draws X and Y axis rulers beginning at the margin box origin. Used on examples.



364
365
366
# File 'lib/prawn/manual_builder/example.rb', line 364

def stroke_axis(options={})
  super({:height => (cursor - 20).to_i}.merge(options))
end