Class: FormatR::Format

Inherits:
Object
  • Object
show all
Defined in:
lib/formatr.rb

Overview

The class that exports the functionality that a user is interested in.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(mid_or_top, mid_format = nil, bottom_format = nil) ⇒ Format

Create a new format with the given top, bottom, and middle formats. One argument will default to a top while two will give you a top and a middle. If you want a bottom and no top you’ll need to pass an empty format in as the first argument or a nil. The output defaults to standard out but can be changed with the Format.io= method.

The format is a string in the style of a perl format or an array of strings each of which is a line of a perl format. The passed in format contains multiple lines, picture lines and argument lines. A picture line can contain any text but if it contains an at field (@ followed by any number of <,>,| or a group of #‘s of the format #.# or #*) it must be followed by an argument line. The arguments in the argument line are inserted in place of the at fields in the picture line. Perl documentation for formats can be found here: www.cpan.org/doc/manual/html/pod/perlform.html An example of a format is

format = <<DOT
Name: @<<<       @<<<<<
      first_name last_name
DOT

This line specifies that when requested one line should be printed and that it will say “Name: #first_name #last_namen” but that if either of those variables is longer than the length its format the result will be truncated to the length of the format.

An at field specified as @<* specifies that the variable should be left justified within the space allocated. @>* is right justified, and @| is centered. #‘s are used to print numbers and can be used to set the number of digits after the decimal point. However the whole number portion of an argument will always be printed in its entirety even if it takes space set for the fractional portion or even more space. If the fractional portion is not long enough to fill the described space it will be padded with 0s.



828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
# File 'lib/formatr.rb', line 828

def initialize (mid_or_top, mid_format=nil, bottom_format=nil)
  if (mid_or_top.nil?)
    raise FormatException.new(),
      " You need to pass in at least one non-nil argument"
  end
  @use_hash = false
  @io = $stdout
  @picture_lines = []
  @vars = []
  @top = @bottom = nil
  @page_length = 60
  @lines_left = @page_length
  @format_length = 0

  @buffered_lines = []
  @print_top = true
  @printed_a_body = false
  @print_bottom = false

  @page_number = 1
  
  lines = ((mid_format.nil?) ? mid_or_top : mid_format)
  if (lines.class == String)
    lines = lines.split( /\n/ )
  end

  expected_vars = 0
  lines.each {|line|
    if (line =~ /^#.*/)
      #don't do anything, it's a comment
    elsif (0 != expected_vars)
      expected_vars = getVarLine(line, expected_vars)
    else
      expected_vars = getPictureLine(line, expected_vars)
      @format_length += 1
    end
  }

  setTop(mid_or_top) if mid_format
  setBottom(bottom_format) if bottom_format
end

Instance Attribute Details

#ioObject

Set the IO that the format will be printed to, from stdout to a file for example.



656
657
658
# File 'lib/formatr.rb', line 656

def io
  @io
end

Instance Method Details

#addToLineCount(line_change) ⇒ Object

If you’re writing to the file handle in another way than by calling printFormat you can keep the pagination working using this call to correctly keep track of lines.



781
782
783
# File 'lib/formatr.rb', line 781

def addToLineCount(line_change)
  @lines_left += line_change
end

#finishPageWithFF(aBinding, io = @io) ⇒ Object

When you don’t want anymore on this page just fill it with blank lines and print the bottom if it’s there, print a ^L also. This is good if you want to finish off the page but print more later to the same file.



697
698
699
# File 'lib/formatr.rb', line 697

def finishPageWithFF (aBinding, io = @io)
  finishPage(aBinding, false, io)
end

#finishPageWithoutFF(aBinding, io = @io) ⇒ Object

When you don’t want anymore on this page just fill it with blank lines and print the bottom if it’s there. Don’t print a ^L at the end. This is good if this will be the last page.



704
705
706
# File 'lib/formatr.rb', line 704

def finishPageWithoutFF (aBinding, io = @io)
  finishPage(aBinding, true, io)
end

#getBottomVarNames(vars) ⇒ Object



983
984
985
986
987
988
989
# File 'lib/formatr.rb', line 983

def getBottomVarNames (vars)
  vars += @vars.flatten
  if (@bottom)
    vars += @bottom.getBottomVarNames(vars)
  end
  vars
end

#getPictureLinesObject

return an Array of picture line FormatHolder s



882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
# File 'lib/formatr.rb', line 882

def getPictureLines ()
  output = Array.new
  @picture_lines.each_index do |i|
    line = @picture_lines[i]
    vars = @vars[i].dup
    output_line = FormatHolder.new
    output_line.repeat = line.repeat
    line.each do |element|
      val = element.val
      var_name = nil
      var_name = vars.shift() unless (element.unchanging)
      var_name.strip! unless (element.unchanging)
      output_line.push( [val,var_name] ) unless val == ""
    end
    output.push( output_line )
  end
  output
end

#getSizeObject

How big is the format? May be useful if you want to try a bottom with a variable length format



723
724
725
# File 'lib/formatr.rb', line 723

def getSize ()
  @format_length
end

#getTopVarNames(vars) ⇒ Object



974
975
976
977
978
979
980
# File 'lib/formatr.rb', line 974

def getTopVarNames (vars)
  vars += @vars.flatten
  if (@top)
    vars += @top.getTopVarNames(vars) 
  end
  vars
end

#pageNumberObject

Return how many times the top has been printed. You can use this to number pages. An empty top can be used if you need the page number but don’t want to print any other header. This is a somewhat interesting function as the bottom is only printed when a page is finished or a top is needed. If this is the case we’ll pretend the page number is one h



714
715
716
717
718
719
# File 'lib/formatr.rb', line 714

def pageNumber ()
  if (@print_bottom)
    return @page_number + 1
  end
  return @page_number
end

#printFormat(aBinding, io = @io) ⇒ Object

Print out the specified format. You need to pass in a Binding object for the variables that will be used in the format. This is usually just a call to Kernel.binding. The next argument gives a file handler to print to. This is useful so that a top or bottom’s output get written to the same place as the main format is going even if their formats have a different io when they’re not attached.



665
666
667
668
669
670
671
672
673
674
675
676
# File 'lib/formatr.rb', line 665

def printFormat (aBinding, io = @io)
  if (@use_hash)
    if (aBinding.is_a?( Binding ))
      printFormatFromBinding( aBinding, io )                  
    else
      printFormatWithHash( aBinding, io )
    end
  else
    printFormatWithBinding( aBinding, io )

  end
end

#printFormatWithBinding(aBinding, io = @io) ⇒ Object

print the format given that the binding is actually a binding.



687
688
689
690
691
# File 'lib/formatr.rb', line 687

def printFormatWithBinding (aBinding, io = @io)
  useHash( false )
  @binding = aBinding
  printBodyFormat(io)
end

#printFormatWithHash(aHash, io = @io) ⇒ Object

print the format given that the binding is a hash of values. This method will not call eval at all.



680
681
682
683
684
# File 'lib/formatr.rb', line 680

def printFormatWithHash (aHash, io = @io)
  useHash( true )
  @binding = aHash
  printBodyFormat(io)
end

#resetPageObject

Sets the variable that says how many lines may be printed to the maximum for the page which can be set using setPageLength (anInt). Defaults to 60.



772
773
774
775
776
# File 'lib/formatr.rb', line 772

def resetPage ()
  @lines_left = @page_length
  @top.resetPage unless @top.nil?
  @bottom.resetPage unless @bottom.nil?
end

#setBottom(format) ⇒ Object

Set a format to print at the end of a page. This is tricky and you should be careful using it. It currently has problems on short pages (at least). In order for a bottom to show up you need to finish off a page. This means that formats less than a page will need to be finished off with a call to one of the finishPageWithFF methods.

Raises:



749
750
751
752
753
754
755
756
757
758
759
# File 'lib/formatr.rb', line 749

def setBottom (format)
  bottom_format = format
  if (!format.is_a?(Format))
    bottom_format = Format.new(format);
  end
  raise FormatException, "recursive format not allowed" if (bottom_format == self)
  @bottom = bottom_format
  #in case we've already set use_hash
  useHash( @use_hash )

end

#setLinesLeft(lines_left) ⇒ Object

If you want to tell the system how many lines are left.



786
787
788
# File 'lib/formatr.rb', line 786

def setLinesLeft(lines_left)
  @lines_left = lines_left
end

#setPageLength(len) ⇒ Object

Sets the number of lines on a page. If you don’t want page breaks set this to some large number that you hope you won’t offset or liberally use resetPage. The default is 60.



764
765
766
767
# File 'lib/formatr.rb', line 764

def setPageLength (len)
  @page_length = len
  resetPage()
end

#setTop(format) ⇒ Object

If you want something to show up before the regular text of a format you can specify it here. It will be printed once above the format it is being set within. You can pass in either a format or the specification of a format and it will make one for you.

Raises:



731
732
733
734
735
736
737
738
739
740
741
# File 'lib/formatr.rb', line 731

def setTop (format)
  top_format = format
  if (!format.is_a?(Format))
    top_format = Format.new(format)
  end
  raise FormatException.new(), "recursive format not allowed" if (top_format == self)
  @top = top_format 
  #in case we've already set use_hash
  useHash( @use_hash )

end

#showPictureLineObject

print out all the values we’re holding for pictures useful for debugging



872
873
874
875
876
877
878
879
# File 'lib/formatr.rb', line 872

def showPictureLine ()
  @picture_lines.each do |line|
    puts "line:"
    line.each do |element|
      puts "  #{element.to_s} "
    end
  end
end

#useHash(value) ⇒ Object

if one format sets the @use_hash value everyone else will need to know too



903
904
905
906
907
# File 'lib/formatr.rb', line 903

def useHash (value)
  @use_hash = value
  @bottom.useHash( value ) unless (@bottom.nil?) 
  @top.useHash( value ) unless (@top.nil?) 
end