Class: RRTF::Document

Inherits:
CommandNode show all
Defined in:
lib/rrtf/node.rb

Overview

This class represents an RTF document. In actuality it is just a specialised Node type that cannot be assigned a parent and that holds document font, colour and information tables.

Author:

  • Peter Wood

Constant Summary collapse

CS_DICTIONARY =

A hash mapping character set string constants to their RTF counterparts.

Returns:

  • (Hash<String, Symbol>)

    the RTF character set dictionary.

{
  "ANSI"    => :ansi,
  "MAC"     => :mac,
  "PC"      => :pc,
  "PCA"     => :pca
}.freeze
LS_DICTIONARY =

A hash mapping langauge set string constants to their RTF counterparts.

Returns:

  • (Hash<String, Integer>)

    the RTF langauge setting dictionary.

{
  "AFRIKAANS"                   => 1078,
  "ARABIC"                      => 1025,
  "CATALAN"                     => 1027,
  "CHINESE_TRADITIONAL"         => 1028,
  "CHINESE_SIMPLIFIED"          => 2052,
  "CZECH"                       => 1029,
  "DANISH"                      => 1030,
  "DUTCH"                       => 1043,
  "DUTCH_BELGIAN"               => 2067,
  "ENGLISH_UK"                  => 2057,
  "ENGLISH_US"                  => 1033,
  "FINNISH"                     => 1035,
  "FRENCH"                      => 1036,
  "FRENCH_BELGIAN"              => 2060,
  "FRENCH_CANADIAN"             => 3084,
  "FRENCH_SWISS"                => 4108,
  "GERMAN"                      => 1031,
  "GERMAN_SWISS"                => 2055,
  "GREEK"                       => 1032,
  "HEBREW"                      => 1037,
  "HUNGARIAN"                   => 1038,
  "ICELANDIC"                   => 1039,
  "INDONESIAN"                  => 1057,
  "ITALIAN"                     => 1040,
  "JAPANESE"                    => 1041,
  "KOREAN"                      => 1042,
  "NORWEGIAN_BOKMAL"            => 1044,
  "NORWEGIAN_NYNORSK"           => 2068,
  "POLISH"                      => 1045,
  "PORTUGUESE"                  => 2070,
  "POTUGUESE_BRAZILIAN"         => 1046,
  "ROMANIAN"                    => 1048,
  "RUSSIAN"                     => 1049,
  "SERBO_CROATIAN_CYRILLIC"     => 2074,
  "SERBO_CROATIAN_LATIN"        => 1050,
  "SLOVAK"                      => 1051,
  "SPANISH_CASTILLIAN"          => 1034,
  "SPANISH_MEXICAN"             => 2058,
  "SWAHILI"                     => 1089,
  "SWEDISH"                     => 1053,
  "THAI"                        => 1054,
  "TURKISH"                     => 1055,
  "UNKNOWN"                     => 1024,
  "VIETNAMESE"                  => 1066
}.freeze

Instance Attribute Summary collapse

Attributes inherited from CommandNode

#prefix, #split, #suffix, #wrap

Attributes inherited from ContainerNode

#children

Attributes inherited from Node

#parent

Instance Method Summary collapse

Methods inherited from CommandNode

#<<, #apply, #background, #bold, #colour, #font, #footnote, #foreground, #image, #italic, #line_break, #link, #list, #paragraph, #strike, #subscript, #superscript, #table, #underline

Methods inherited from ContainerNode

#[], #each, #first, #last, #size, #store

Methods inherited from Node

#is_root?, #next_node, #previous_node, #root

Constructor Details

#initialize(options = {}) ⇒ Document

Note:

The “suppress_system_styles” option is ignored by most RTF platforms including Word and LibreOffice.

Represents an entire RTF document.

Parameters:

  • options (Hash<String, Object>) (defaults to: {})

    the options to use in creating the document.

Options Hash (options):

  • "default_font" (String, Font) — default: "SWISS:Helvetica"

    a font object OR string encapsulating the default font to be used by the document (see Font.from_string for string format).

  • "character_set" (String) — default: "ANSI"

    the character set to be applied to the document (see CS_DICTIONARY for valid values).

  • "language" (String) — default: "ENGLISH_US"

    the language setting to be applied to the document (see LS_DICTIONARY for valid values).

  • "suppress_system_styles" (Boolean) — default: false

    whether or not to suppress styles provided in the host platform (adds the noqfpromote control word before stylesheet definition).

  • "document_style" (DocumentStyle) — default: DocumentStyle.new

    a DocumentStyle object OR options hash encapsulating the style settings to be applied to the document.

  • "stylesheet" (Array, Hash, Stylesheet) — default: nil

    a Stylesheet object OR array of style hashes OR hash of stylesheet options with which to use as or construct the stylesheet for the document.

See Also:



1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
# File 'lib/rrtf/node.rb', line 1598

def initialize(options = {})
  # load default options
  options = {
     "default_font" => "SWISS:Helvetica",
     "document_style" => DocumentStyle.new,
     "character_set" => "ANSI",
     "language" => "ENGLISH_US",
     "suppress_system_styles" => false,
     "stylesheet" => nil
  }.merge(options)

   super(nil, '\rtf1')

   # parse font
   font = options.delete("default_font")
   case font
   when Font
   when String
     font = Font.from_string(font)
   else
     RTFError.fire("Unreconized font format #{font.class.to_s}")
   end # case

   # parse document style
   style = options.delete("document_style")
   case style
   when DocumentStyle
   when Hash
     style = DocumentStyle.new(style)
   else
     RTFError.fire("Unreconized document style format #{font.class.to_s}")
   end # case

   # parse character set
   cs_string = options.delete("character_set")
   cs_val = CS_DICTIONARY[cs_string]
   if cs_val.nil?
     RTFError.fire("Unreconized character set '#{cs_string}'.")
   end # if

   # parse language setting
   ls_string = options.delete("language")
   ls_val = LS_DICTIONARY[ls_string]
   if ls_val.nil?
     RTFError.fire("Unreconized language '#{ls_string}'.")
   end # if

   @fonts         = FontTable.new(font)
   @lists         = ListTable.new
   @default_font  = 0
   @colours       = ColourTable.new
   @information   = Information.new
   @character_set = cs_val
   @language      = ls_val
   @style         = style
   @headers       = [nil, nil, nil, nil]
   @footers       = [nil, nil, nil, nil]
   @id            = 0

   # parse stylesheet (must be done after font and colour tables are
   # initialized since declared styles may push fonts/colours onto the
   # tables)
   stylesheet = options.delete("stylesheet")
   case stylesheet
   when Stylesheet
     stylesheet.document = self
   when Array
     stylesheet = Stylesheet.new(self, "styles" => stylesheet)
   when Hash
     stylesheet = Stylesheet.new(self, stylesheet)
   else
     RTFError.fire("Unreconized stylesheet format #{font.class.to_s}")
   end unless stylesheet.nil? # case

   @stylesheet    = stylesheet
   # additional options
   @options       = options
end

Instance Attribute Details

#character_setObject

Attribute accessor.



1579
1580
1581
# File 'lib/rrtf/node.rb', line 1579

def character_set
  @character_set
end

#coloursObject (readonly)

Attribute accessor.



1579
1580
1581
# File 'lib/rrtf/node.rb', line 1579

def colours
  @colours
end

#fontsObject (readonly)

Attribute accessor.



1579
1580
1581
# File 'lib/rrtf/node.rb', line 1579

def fonts
  @fonts
end

#informationObject (readonly)

Attribute accessor.



1579
1580
1581
# File 'lib/rrtf/node.rb', line 1579

def information
  @information
end

#languageObject

Attribute accessor.



1579
1580
1581
# File 'lib/rrtf/node.rb', line 1579

def language
  @language
end

#listsObject (readonly)

Attribute accessor.



1579
1580
1581
# File 'lib/rrtf/node.rb', line 1579

def lists
  @lists
end

#styleObject (readonly)

Attribute accessor.



1579
1580
1581
# File 'lib/rrtf/node.rb', line 1579

def style
  @style
end

#stylesheetObject

Attribute accessor.



1579
1580
1581
# File 'lib/rrtf/node.rb', line 1579

def stylesheet
  @stylesheet
end

Instance Method Details

#body_heightObject

This method fetches the height of the available work area space for a a typical Document object page.



1810
1811
1812
# File 'lib/rrtf/node.rb', line 1810

def body_height
   @style.body_height
end

#body_widthObject

This method fetches the width of the available work area space for a typical Document object page.



1804
1805
1806
# File 'lib/rrtf/node.rb', line 1804

def body_width
   @style.body_width
end

#default_fontObject

Attribute accessor.



1685
1686
1687
# File 'lib/rrtf/node.rb', line 1685

def default_font
   @fonts[@default_font]
end

#default_font=(font) ⇒ Object

Attribute mutator.

Parameters

font

The new default font for the Document object.



1773
1774
1775
1776
# File 'lib/rrtf/node.rb', line 1773

def default_font=(font)
   @fonts << font
   @default_font = @fonts.index(font)
end

This method fetches a footer from a Document object.

Parameters

type

One of the footer types defined in the footer class. Defaults to FooterNode::UNIVERSAL.



1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
# File 'lib/rrtf/node.rb', line 1751

def footer(type=FooterNode::UNIVERSAL)
   index = 0
   if type == FooterNode::LEFT_PAGE
      index = 1
   elsif type == FooterNode::RIGHT_PAGE
      index = 2
   elsif type == FooterNode::FIRST_PAGE
      index = 3
   end
   @footers[index]
end

#footer=(footer) ⇒ Object

This method assigns a new footer to a document. A Document object can have up to four footers - a default footer, a footer for left pages, a footer for right pages and a footer for the first page. The method checks the footer type and stores it appropriately.

Parameters

footer

A reference to the footer object to be stored. Existing footer objects are overwritten.



1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
# File 'lib/rrtf/node.rb', line 1717

def footer=(footer)
   if footer.type == FooterNode::UNIVERSAL
      @footers[0] = footer
   elsif footer.type == FooterNode::LEFT_PAGE
      @footers[1] = footer
   elsif footer.type == FooterNode::RIGHT_PAGE
      @footers[2] = footer
   elsif footer.type == FooterNode::FIRST_PAGE
      @footers[3] = footer
   end
end

#get_idObject

This method provides a method that can be called to generate an identifier that is unique within the document.



1679
1680
1681
1682
# File 'lib/rrtf/node.rb', line 1679

def get_id
   @id += 1
   Time.now().strftime('%d%m%y') + @id.to_s
end

#header(type = HeaderNode::UNIVERSAL) ⇒ Object

This method fetches a header from a Document object.

Parameters

type

One of the header types defined in the header class. Defaults to HeaderNode::UNIVERSAL.



1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
# File 'lib/rrtf/node.rb', line 1734

def header(type=HeaderNode::UNIVERSAL)
   index = 0
   if type == HeaderNode::LEFT_PAGE
      index = 1
   elsif type == HeaderNode::RIGHT_PAGE
      index = 2
   elsif type == HeaderNode::FIRST_PAGE
      index = 3
   end
   @headers[index]
end

#header=(header) ⇒ Object

This method assigns a new header to a document. A Document object can have up to four header - a default header, a header for left pages, a header for right pages and a header for the first page. The method checks the header type and stores it appropriately.

Parameters

header

A reference to the header object to be stored. Existing header objects are overwritten.



1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
# File 'lib/rrtf/node.rb', line 1697

def header=(header)
   if header.type == HeaderNode::UNIVERSAL
      @headers[0] = header
   elsif header.type == HeaderNode::LEFT_PAGE
      @headers[1] = header
   elsif header.type == HeaderNode::RIGHT_PAGE
      @headers[2] = header
   elsif header.type == HeaderNode::FIRST_PAGE
      @headers[3] = header
   end
end

#load_stylesheet(hashmap_array) ⇒ Object

Loads a stylesheet for the document from an array of hashmaps representing styles



1765
1766
1767
# File 'lib/rrtf/node.rb', line 1765

def load_stylesheet(hashmap_array)
  @stylesheet = Stylesheet.new(self, hashmap_array)
end

#page_breakObject

This method inserts a page break into a document.



1797
1798
1799
1800
# File 'lib/rrtf/node.rb', line 1797

def page_break
   self.store(CommandNode.new(self, '\page', nil, false))
   nil
end

#paperObject

This method provides a short cut for obtaining the Paper object associated with a Document object.



1780
1781
1782
# File 'lib/rrtf/node.rb', line 1780

def paper
   @style.paper
end

#parent=(parent) ⇒ Object

This method overrides the parent=() method inherited from the CommandNode class to disallow setting a parent on a Document object.

Parameters

parent

A reference to the new parent node for the Document object.

Exceptions

RTFError

Generated whenever this method is called.



1792
1793
1794
# File 'lib/rrtf/node.rb', line 1792

def parent=(parent)
   RTFError.fire("Document objects may not have a parent.")
end

#to_rtfObject

This method generates the RTF text for a Document object.



1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
# File 'lib/rrtf/node.rb', line 1815

def to_rtf
   text = StringIO.new

   text << "{#{prefix}\\#{@character_set.id2name}"
   text << "\\deff#{@default_font}"
   text << "\\deflang#{@language}" if !@language.nil?
   text << "\\plain\\fs24\\fet1"
   text << "\n#{@fonts.to_rtf}"
   text << "\n#{@colours.to_rtf}" if @colours.size > 0
   text << "\n\\noqfpromote" if @options["suppress_system_styles"]
   text << "\n#{@stylesheet.to_rtf}" if !@stylesheet.nil?
   text << "\n#{@information.to_rtf}"
   text << "\n#{@lists.to_rtf}"
   if @headers.compact != []
      text << "\n#{@headers[3].to_rtf}" if !@headers[3].nil?
      text << "\n#{@headers[2].to_rtf}" if !@headers[2].nil?
      text << "\n#{@headers[1].to_rtf}" if !@headers[1].nil?
      if @headers[1].nil? or @headers[2].nil?
         text << "\n#{@headers[0].to_rtf}"
      end
   end
   if @footers.compact != []
      text << "\n#{@footers[3].to_rtf}" if !@footers[3].nil?
      text << "\n#{@footers[2].to_rtf}" if !@footers[2].nil?
      text << "\n#{@footers[1].to_rtf}" if !@footers[1].nil?
      if @footers[1].nil? or @footers[2].nil?
         text << "\n#{@footers[0].to_rtf}"
      end
   end
   text << "\n#{@style.prefix(self)}" if !@style.nil?
   self.each {|entry| text << "\n#{entry.to_rtf}"}
   text << "\n}"

   text.string
end