Class: RGhost::Document

Inherits:
PsFacade show all
Includes:
DocumentCallbackFacade, RubyToPs
Defined in:
lib/rghost/document.rb

Overview

The Document class child of PsFacade is used to join postscript objects to generate output file.

Constant Summary collapse

DISABLE_VIRTUAL_PAGE =
RGhost::Variable.new(:has_vp?, false)
ENABLE_VIRTUAL_PAGE =
RGhost::Variable.new(:has_vp?, true)
DEFAULT_OPTIONS =
{
  :rows_per_page => 80 , 
  :count_pages => 10,
  :row_height => 0.4,
  :row_padding => 0.1,
  :font_encoding=> RGhost::Config::GS[:font_encoding],
  :paper => RGhost::Paper::DEFAULT_OPTIONS
}

Instance Attribute Summary collapse

Attributes inherited from PsFacade

#rows

Instance Method Summary collapse

Methods included from RubyToPs

#array_to_stack, #hash_to_array, #pack_string, #ps_escape, #string_eval, #to_array, #to_bool, #to_string, #to_string_array

Methods included from DocumentCallbackFacade

#after_page_create, #after_virtual_page_create, #before_document_create, #before_page_create, #before_virtual_page_create, #even_pages, #first_page, #last_page, #odd_pages

Methods inherited from PsFacade

#background_row, #border, #circle, #closepath, #color, #dash, #dsc_entry, #frame, #goto_row, #graphic, #hl, #horizontal_line, #image, #jump_rows, #line_width, #lineto, #moveto, #newpath, #next_page, #next_row, #polygon, #rectangle_link, #rlineto, #rmoveto, #rotate, #scale, #shape_content, #show, #show_next_row, #showpage, #stroke, #text, #text_area, #text_in, #text_link, #translate, #use_function, #use_tag, #use_template, #vertical_line, #vertical_line_row, #write, #zoom

Methods inherited from PsObject

#<<, #call, #graphic_scope, #raw, #set, #to_s

Constructor Details

#initialize(options = {}, &block) ⇒ Document

===Examples Creating document with 80 rows per page and custom paper doc=Document.new :rows_per_page => 80, paper => [30,5] Document A4 with row height 0.5 and font encoding CodePage1252 doc=Document.new :row_height => 0.5, :font_encoding => 'CodePage1252' Defining all margins doc=Document.new :margin => 0.5

==Parameters

  • :paper - Facade to paper defined on the construction of Paper class
  • :margin, :duplex and :tuble - Facade to options defined on the construction of Paper class
  • :rows_per_page - Specifies count of rows per pages.
  • :landscape - Whether true invert de size(width per height)
  • :count_pages - Defines postscript internal variable to display with class TextIn. Example:

doc=Document.new :count_pages => 10 doc.before_page_create :except => 1 do |b| b.text_in :x => 15, :y => 5, :write => "Page %current_page% of %count_pages%" end

The value above %count_pages% will be evaluated inside of document for all pages except page one.

  • :fontsize - Defines the size of tag :default_font.
  • :row_height and row_padding - Its names say by itself :)
  • :font_encoding - Specifies encoding of data input. You can look for supported encoding using the method RGhost::Config.encode_test


77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/rghost/document.rb', line 77

def initialize(options={},&block)
  
  
  @head,@callbacks=RGhost::PsObject.new,RGhost::PsObject.new
  @head.set RGhost::Load.library(:type)
  @head.set RGhost::Load.library(:unit)
  #super()
  @variables=DEFAULT_OPTIONS.dup.merge(options)
  default_encoding
  @paper=RGhost::Paper.new(options[:paper] || :A4, options)
  @head.set @paper
  @done=false
  @docinfo={:Producer => "Ruby Ghostscript - RGhost v#{RGhost::VERSION::STRING}" }
  @defines=[]
  @additional_params=[]
  
  default_variables
  super()
  #block.call(self) if block
  #yield self if block
end

Instance Attribute Details

#additional_paramsObject (readonly)

Returns the value of attribute additional_params.



38
39
40
# File 'lib/rghost/document.rb', line 38

def additional_params
  @additional_params
end

Instance Method Details

#benchmark(state = :start) ⇒ Object

Starts and Ends internal benckmark will write in bottom of page. ===Example doc=Document.new doc.benchmark :start doc.... #do something doc.benchmarck :stop doc.render ...



377
378
379
380
381
382
383
384
385
386
387
388
# File 'lib/rghost/document.rb', line 377

def benchmark(state=:start)
  case state
  when :stop
    moveto(:x => "20", :y => "20")
    raw %Q{
    default_font (RGhost::Ghostscript benchmark: ) show
    realtime benchmark sub 1000 div 20 string cvs show ( seconds ) show
    }
  when :start
    set RGhost::Variable.new(:benchmark,"realtime")
  end
end

#csv_grid(default_columns_options = {}) {|grid| ... } ⇒ Object

Creates Grid::CSV inside of the document. Facade to RGhost::Grid::CSV

Yields:

  • (grid)


498
499
500
501
502
503
504
# File 'lib/rghost/document.rb', line 498

def csv_grid(default_columns_options={})
  grid=RGhost::Grid::CSV.new(default_columns_options) 
  yield grid
  grid.style(default_columns_options[:style]) if default_columns_options[:style]
  grid.data(default_columns_options[:data]) if default_columns_options[:data]
  set grid
end

#define(name, &block) ⇒ Object

Facade to Function.new Defines low level function to optimize repetitive piece of code. ===Example doc=Document.new doc.define :piece do set Show.new("Hello") set Cursor.next_row set HorizontalLine.new(:middle) set Cursor.next_row end #Repeting ten times the same code 10.times{ doc.call :piece }



274
275
276
# File 'lib/rghost/document.rb', line 274

def define(name,&block)
  @defines << RGhost::Function.new("_#{name}",&block)
end

#define_and_call(name, &block) ⇒ Object

Defines a function using the method define after that call de function one time.



281
282
283
284
# File 'lib/rghost/document.rb', line 281

def define_and_call(name,&block)
  define(name,&block)
  call(name)
end

#define_tags(&block) ⇒ Object

Creates map of tags if will be use in 'writable' classes(Show, Text, TextIn and TextArea). The font names file catalog can be generated by code below RGhost::Config.enviroment_fonts.render :pdf, :filename => "mycatalog.pdf" this can take while. If waiting for much time you has any font with problem, remove some fonts mostly international fonts not used often. Below little piece of catalog link:images/font_catalog.png

After genereted catalog you can map your tags.

Tags has name of tag(as Symbol) and its options. The options are

  • :name - Font name from catalog.
  • :size - Font size.
  • :color - Color.create facade
  • :encoding - If true the font will be encoding using de pattern :font_encoding of the document.
  • :from - Load True Type or Type1 font from file. ===Examples d=Document.new :encoding => 'IsoLatin' d.define_tags do tag :my_italic, :name => 'Hershey-Gothic-Italian-Oblique', :size => 10 tag :myfont, :name => 'Hershey-Plain' tag :font_encoded, :name => 'NimbusMonL-Regu', :size => 8, :color => 0.5, :encoding => true tag :other_font, :name => 'NimbusMonL-Regu', :size => 10 tag :arial, :name => 'Arial-ItalicMT', :color => '#ADAD66' tag :arial_bold, :name => 'NimbusSanL-BoldItal',:size => 12, :color => '#ADAD66' tag :monaco, :name => 'Monaco', :from => "/path/to/myfont.ttf", :size => 12 end You can use :default_font tag for custom the default font. ===Using tags ====With Show class doc.show 'My Text on this row', :with => :my_italic, :align => :page_center ====With Show class overrinding tag's color. doc.show 'My Text on this row', :with => :my_italic, :align => :page_center, :color => :red ====With TextIn class. doc.text_in :x=> 3, :y=> 10, :tag => :arial_bold , :write => "Here's point(3,10)" ====With Text doc.text 'My Texton this row.Other text<my_italic>Italic font</my_italic>' ====With TextArea txt='My Texton this row.Other text<my_italic>Italic font</my_italic>' doc.text_area txt, :text_align => :center, :width => 5, :x => 3, :y => 10 ====Using tag doc.use_tag :myfont doc.show "Simple Text", :tag => nil # it will use :myfont doc.show "Simple Text2", :tag => nil # it will use :myfont too


149
150
151
# File 'lib/rghost/document.rb', line 149

def define_tags(&block)
  RGhost::Config::FONTMAP.instance_eval(&block)
end

#define_template(name, file_path, options = {}) ⇒ Object

Rghost can make use of Encapsulated Postscript files to act as templates(EPS). This way you can create the visual layout of the page using a graphics tool and just paint the dynamic pieces over using Rghost.

link:images/templates_demo.jpg

Above we have mytemplate.eps that was generated by a graphic app, my_ruby_program.rb that takes care of the positioning and at last the generated output.

A Template use example Let's say that the files first.eps and content.eps already exist. Now we shall see how to create a document that uses the template first.eps for the cover and the rest of the document uses content.eps.

d = Document.new :margin_top => 5, :margin_bottom => 2

Just for the first page

d.first_page do image "/my/dir/first.eps" #loads the template text_in :x=> 5, :y=> 17, :text => "My Report", :with => :big next_page #go to the next page using cursors end Callback for all other pages.

d.before_page_create :except => 1 do image "/my/dir/content.eps" text_in :text => "Page %current_page% of %count_pages%", :x => 18, :y => 27, :with => :normal
end

1500 rows

1500.times do |n| d.show "Value #n" d.next_row end We have a cover page and 1500 rows, judging by the margins each page supports 46 rows, so we have 1500/46 = 32.60 pages plus the cover. Rounding it up totals 34 pages for the :count_pages

d.define_variable(:count_pages, 34) d.showpage d.render :pdf, :filename => "/tmp/test.pdf"

If we knew the amount of pages beforehand we could state it on the creation of the document, i.e.

:current_pages => 34

The example uses one template per page, but this is not a limit in RGhost. You can have multiple images and templates on per page. Just have to define the template:

d=Document.new :margin_top => 5, :margin_bottom => 2
d.define_template(:myform, '/local/template/form1.eps', :x=> 3, :y => 5)

and call it on the document. d.use_template :myform

===Arguments

  • :name - Template's name.
  • :file_path - Path to file.
  • :options - Options facade to Image.for(or image)


445
446
447
448
# File 'lib/rghost/document.rb', line 445

def define_template(name,file_path,options={})
  
  @defines <<  RGhost::Function.new("_#{name}",RGhost::Image.for(file_path,options))
end

#define_variable(name, value) ⇒ Object



277
278
279
# File 'lib/rghost/document.rb', line 277

def define_variable(name,value)
  set RGhost::Variable.new(name,value)
end

#disable_virtual_pagesObject



470
471
472
473
474
475
# File 'lib/rghost/document.rb', line 470

def disable_virtual_pages
  set RGhost::Variable.new(:has_vp?, false)
  set RGhost::Variable.new(:limit_left,  'source_limit_left')
  set RGhost::Variable.new(:limit_right, 'source_limit_right')
  
end

#doneObject

Informs is ready to converts/prints



452
453
454
455
456
457
458
459
460
461
462
463
464
465
# File 'lib/rghost/document.rb', line 452

def done
  
  unless @done
    @done=true
    raw "\n\n"
    call :after_page_create
    call :callback
    call :after_document_create
  
    showpage
    raw "\n%%EOF"
  end
  self
end

#enable_virtual_pagesObject



466
467
468
469
# File 'lib/rghost/document.rb', line 466

def enable_virtual_pages
  set RGhost::Variable.new(:has_vp?, true)
  
end

#gs_paperObject

:nodoc:



99
100
101
# File 'lib/rghost/document.rb', line 99

def gs_paper #:nodoc:
  @paper.gs_paper
end

#info(docinfo = {}) ⇒ Object

Configures properties about your document. The keys are supported :Creator, :Title, :Author, :Subject and :Keywords, or downcase as :title etc. Example: doc.properties :Autor => "Shairon Toledo", :Title => "Learning RGhost"



481
482
483
484
485
# File 'lib/rghost/document.rb', line 481

def info(docinfo={})
  #puts docinfo.inspect
  @docinfo.merge!(docinfo)
  #puts @docinfo.inspect
end

#matrix_grid(default_columns_options = {}) {|grid| ... } ⇒ Object

Creates Grid::Matrix inside of the document. Facade to RGhost::Grid::Matrix

Yields:

  • (grid)


506
507
508
509
510
511
# File 'lib/rghost/document.rb', line 506

def matrix_grid(default_columns_options={})
  grid=RGhost::Grid::Matrix.new(default_columns_options) 
  yield grid
  grid.style(default_columns_options[:style]) if default_columns_options[:style]
  set grid
end

Prints the text file using the predefined tag :pre ===Example doc=Document.new :paper => :A4, :landscape => true doc.print_file "/etc/passwd" doc.render :pdf, :filename => "/tmp/passwd.pdf



291
292
293
294
295
296
297
# File 'lib/rghost/document.rb', line 291

def print_file(file)
  s=File.open(file).readlines.join.gsub(/</,'&lt').gsub(/>/,'&gt').gsub(/\n/,'<br/>')
  
  use_tag :pre
  set RGhost::Text.new(s,true)
  
end

#psObject

:nodoc:



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/rghost/document.rb', line 153

def ps #:nodoc:
  done 
  
  
  
  out=RGhost::PsObject.new
  out.set @head
  out.raw formated_docinfo
  out.set @default_variables 
  out.set RGhost::Load.rg_enviroment
  out.raw @defines.join
  out.set RGhost::Cursor.moveto
  out.set RGhost::Config::FONTMAP
  out.set @callbacks
  out.set RGhost::Load.library(:begin_document)
  RGhost::Config::GS[:preload].uniq.each{|v| out.set RGhost::Load.library(v) }
  out.set RGhost::Cursor.moveto
  out.raw super
  out.raw "\n\n"
 
  "#{out} "
    
  #"#{@head} \n%%endhead\n#{@default_variables}\n\n #{Load.rg_enviroment} #{@defines.join} #{@callbacks} #{Load.library(:begin_document)}\n #{Cursor.moveto}#{super}"
  
  
end

#rails_grid(default_columns_options = {}) {|grid| ... } ⇒ Object

Creates Grid::Rails inside of the document. Facade to RGhost::Grid::Rails

Yields:

  • (grid)


488
489
490
491
492
493
494
495
496
# File 'lib/rghost/document.rb', line 488

def rails_grid(default_columns_options={})
  
  grid=RGhost::Grid::Rails.new(default_columns_options)
  yield grid
  grid.style(default_columns_options[:style]) if default_columns_options[:style]
  grid.data(default_columns_options[:data]) if default_columns_options[:data]
  set grid
  
end

#render(device, options = {}) ⇒ Object

def link(label,options==> 'http://rghost.rubyforge.net') raw "/:link_str #to_string(label) def /:link_uri #to_string(options[:to]) def :link_make"

end Facade to RubyGhostEngine.render Converts a document to an output format, such as :pdf, :png, :ps, :jpeg, :tiff etc The paramter device can be found at RGhost::Constants::Devices or at http://pages.cs.wisc.edu/~ghost/doc/cvs/Devices.htm ===Options Method render have the following options available.

  • :filename - File path.
  • :logfile - Writes the converter's process into a file.
  • :multipage - Whether true the output will be one page per file posfixed by _0001.ext, for example, for one file name 'test.png' with two pages will create test_001.png and test_002.png
  • :resolution - Integer value to output resolution.
  • :quality - Presets the "distiller parameters" to one of four predefined settings: :screen - selects low-resolution output similar to the Acrobat Distiller "Screen Optimized" setting. :ebook - selects medium-resolution output similar to the Acrobat Distiller "eBook" setting. :printer - selects output similar to the Acrobat Distiller "Print Optimized" setting. :prepress - selects output similar to Acrobat Distiller "Prepress Optimized" setting. :default - selects output intended to be useful across a wide variety of uses, possibly at the expense of a larger output file.
  • :size - Crops a single page using a string of dimension, example, '200x180', '140x90'.
  • :range - Specifies range of pages(PDF only) ====Ghostscript interpreter options

Array of Hashes for Ghostscript interpreter look at http://pages.cs.wisc.edu/~ghost/doc/cvs/Use.htm#Parameter_switches for more details. You can use two parameter :s and :d, examples :s => [=> /dir, :DEFAULTPAPERSIZE=> "a3"] :d => [ => 2 ] Or one string using the parameter :raw, as below :raw => "-sGenericResourceDir=/test -dTextAlphaBits=2"

===Examples doc=Document.new #do something

doc.render :pdf, :filename => 'foo.pdf # PDF output doc.render :pdf, :filename => 'foo.pdf, :quality => :ebook # PDF output doc.render :jpeg, :filename => 'foo.jpg' # JPEG output doc.render :png, :filename => 'foo.png', :multipage => true # PNG output one page per file doc.render :tiff, :filename => 'foo.tiff', :resolution => 300 # TIFF with 300dpi doc.render :ps, :raw => '-sFONTMAP=/var/myoptional/font/map', :filename => 'test.ps'

===Testing if has errors doc=Document.new doc.raw "hahahah!" #it produce error in ps stack doc.render :jpeg, :filename => 'with_error.jpg' puts r.errors if r.error? #=> GPL Ghostscript 8.61: Unrecoverable error, exit code 1.\ Error: /undefined in hahahah!

===Printing ====Using printing system doc=Document.new #do something f="myjob.prn"
doc.render :laserjet, :filename => f lpr #{f} ====Windows shared printer doc.render :eps9mid, :filename => "//machine/printer"



235
236
237
238
239
# File 'lib/rghost/document.rb', line 235

def render(device,options={})
  rg=RGhost::Engine.new(self,options)
  rg.render(device)
  rg
end

#render_stream(device, options = {}) ⇒ Object

Behavior as render but returns content file after convertion. ===Example with Rails def my_action doc=RGhost::Document.new #do something
send_data doc.render_stream(:pdf), :filename => "/tmp/myReport.pdf"
end

===TCP/IP direct printer require 'socket'

doc=Document.new #do something
printer = TCPSocket.open('192.168.1.70', 9100)
printer.write doc.render_stream(:ps) printer.close



256
257
258
259
260
261
# File 'lib/rghost/document.rb', line 256

def render_stream(device,options={})
  rg=render(device,options)
  out=rg.output.readlines.join
  rg.clear_output
  out
end

#security {|sec| ... } ⇒ Object

Security disable the permissions and define passwords to PDF documents. The password just support set of \w . Always that use the block security should set owner and user password. By default the encryption is 3. Document Security can be set with the permissions flags ===Disable options

  • :base or :print Print document (possibly not at the highest quality level).
  • :modifyModify contents of document, except as controlled by :annotate, :interective and :assemble.
  • :copyCopy text and graphics from document other than that controlled by :copy_access
  • :annotateAdd or modify text annotations, fill in interactive form fields, and if :interective is set, create or modify interactive form fields
  • :interactiveFill in existing interacive form fields, even if :annotate is clear
  • :copy_accessExtract text and graphics (in support of accessibility to disabled users or for other purposes).
  • :assembleAssemble the document (insert, rotate, or delete pages and create bookmarks or thumbnail images), even when :base is clear
  • :high_quality_printAdd or modify text annotations
  • :allDisable all permissions. ===Example 1

doc.security do |sec| sec.owner_password ="owner" #password without space! sec.user_password ="user" #password without space! sec.key_length = 128 sec.disable :print, :copy, :high_quality end ===Example 2 Disable all doc.security do |sec| sec.owner_password ="owner" #password without space! sec.user_password ="user" #password without space! sec.disable :all end

Yields:

  • (sec)


364
365
366
367
368
# File 'lib/rghost/document.rb', line 364

def security
   sec=RGhost::PdfSecurity.new
   yield sec
   @additional_params << sec.gs_params
end

#virtual_pages(&block) ⇒ Object

With method virtual_pages you can define any virtual pages per physical page. The cursor into virtual page jumps in column for each virtual page and run primitives next_page when ends columns. Look the example below. Example for a document without virtual pages we will has doc=Document.new doc.text File.readlines("/tmp/mytext.txt") will generate

link:images/virtual_page1.png

Now for a document with 3 virtual pages doc=Document.new doc.virtual_pages do new_page :width => 4 new_page :width => 7, :margin_left => 1 new_page :width => 4, :margin_left => 1 end doc.text File.readlines("/tmp/mytext.txt") will generate

link:images/virtual_page2.png

PS: The parameter margin left of first virtual page won't be used because it's will use page's margin left.



320
321
322
# File 'lib/rghost/document.rb', line 320

def virtual_pages(&block)
  set RGhost::VirtualPages.new(&block)
end