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

Attributes inherited from PsFacade

#rows

Instance Method Summary collapse

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, #rlineto, #rmoveto, #rotate, #scale, #shape_content, #show, #show_next_row, #showpage, #stroke, #text, #text_area, #text_in, #translate, #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 = {}) ⇒ 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

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



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/rghost/document.rb', line 57

def initialize(options={})
  super()
  @head,@callbacks=RGhost::PsObject.new,RGhost::PsObject.new
  @head.set RGhost::Load.library(:type)
  @head.set RGhost::Load.library(:unit)
  
  @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=[]
  
  default_variables
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 …



296
297
298
299
300
301
302
303
304
305
306
307
# File 'lib/rghost/document.rb', line 296

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

#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 }



238
239
240
# File 'lib/rghost/document.rb', line 238

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.



245
246
247
248
# File 'lib/rghost/document.rb', line 245

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

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.

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'

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 ‘<myfont>My Text</myfont>on this row.<arial>Other text</arial><my_italic>Italic font</my_italic>’

With TextArea

txt=‘<myfont>My Text</myfont>on this row.<arial>Other text</arial><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



122
123
124
# File 'lib/rghost/document.rb', line 122

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.

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)



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

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

#define_variable(name, value) ⇒ Object



241
242
243
# File 'lib/rghost/document.rb', line 241

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

#disable_virtual_pagesObject



385
386
387
388
389
390
# File 'lib/rghost/document.rb', line 385

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



371
372
373
374
375
376
377
378
379
380
# File 'lib/rghost/document.rb', line 371

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

#enable_virtual_pagesObject



381
382
383
384
# File 'lib/rghost/document.rb', line 381

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

#gs_paperObject

:nodoc:



74
75
76
# File 'lib/rghost/document.rb', line 74

def gs_paper #:nodoc:
  @paper.gs_paper
end

#informations(docinfo = {}) ⇒ Object



391
392
393
394
395
# File 'lib/rghost/document.rb', line 391

def informations(docinfo={})
  puts docinfo.inspect
  @docinfo.merge!(docinfo)
  puts @docinfo.inspect
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



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

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:



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/rghost/document.rb', line 127

def ps #:nodoc:
  done unless @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

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

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 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.

  • :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 pages.cs.wisc.edu/~ghost/doc/cvs/Use.htm#Parameter_switches for more details. You can use two parameter :s and :d, examples

:s => [{:GenericResourceDir => /dir, :DEFAULTPAPERSIZE=> "a3"}]
:d => [ {:TextAlphaBits => 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 :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”



199
200
201
202
203
# File 'lib/rghost/document.rb', line 199

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



220
221
222
223
224
225
# File 'lib/rghost/document.rb', line 220

def render_stream(device,options={})
  rg=render(device,options)
  out=rg.output.readlines.join
  rg.clear_output
  out
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

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

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



284
285
286
# File 'lib/rghost/document.rb', line 284

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