Skip to content
This repository
Browse code

Merge remote branch 'mikel/master'

  • Loading branch information...
commit 8399a315f5a2dc1dd3d9efd75d66151c793fa664 2 parents 7b8c647 + a06a5a6
Jeremy Kemper jeremy authored

Showing 157 changed files with 14 additions and 19,756 deletions. Show diff stats Hide diff stats

  1. +2 0  actionmailer/CHANGELOG
  2. +2 1  actionmailer/actionmailer.gemspec
  3. +1 1  actionmailer/lib/action_mailer.rb
  4. +0 1,467 actionmailer/lib/action_mailer/vendor/text-format-0.6.3/text/format.rb
  5. +0 10 actionmailer/lib/action_mailer/vendor/text_format.rb
  6. +6 0 activesupport/CHANGELOG
  7. +0 100 activesupport/Rakefile
  8. +3 0  activesupport/activesupport.gemspec
  9. +0 2  activesupport/lib/active_support.rb
  10. +0 19 activesupport/lib/active_support/vendor.rb
  11. +0 113 activesupport/lib/active_support/vendor/builder-2.1.2/lib/blankslate.rb
  12. +0 13 activesupport/lib/active_support/vendor/builder-2.1.2/lib/builder.rb
  13. +0 20 activesupport/lib/active_support/vendor/builder-2.1.2/lib/builder/blankslate.rb
  14. +0 250 activesupport/lib/active_support/vendor/builder-2.1.2/lib/builder/css.rb
  15. +0 115 activesupport/lib/active_support/vendor/builder-2.1.2/lib/builder/xchar.rb
  16. +0 139 activesupport/lib/active_support/vendor/builder-2.1.2/lib/builder/xmlbase.rb
  17. +0 63 activesupport/lib/active_support/vendor/builder-2.1.2/lib/builder/xmlevents.rb
  18. +0 328 activesupport/lib/active_support/vendor/builder-2.1.2/lib/builder/xmlmarkup.rb
  19. +0 1,133 activesupport/lib/active_support/vendor/memcache-client-1.7.5/lib/memcache.rb
  20. +0 33 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo.rb
  21. +0 47 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/data_timezone.rb
  22. +0 228 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/data_timezone_info.rb
  23. +0 55 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Africa/Algiers.rb
  24. +0 219 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Africa/Cairo.rb
  25. +0 42 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Africa/Casablanca.rb
  26. +0 18 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Africa/Harare.rb
  27. +0 25 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Africa/Johannesburg.rb
  28. +0 22 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Africa/Monrovia.rb
  29. +0 23 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Africa/Nairobi.rb
  30. +0 84 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/America/Argentina/Buenos_Aires.rb
  31. +0 23 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/America/Bogota.rb
  32. +0 23 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/America/Caracas.rb
  33. +0 283 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/America/Chicago.rb
  34. +0 136 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/America/Chihuahua.rb
  35. +0 204 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/America/Denver.rb
  36. +0 161 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/America/Godthab.rb
  37. +0 27 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/America/Guatemala.rb
  38. +0 24 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/America/Guyana.rb
  39. +0 274 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/America/Halifax.rb
  40. +0 149 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/America/Indiana/Indianapolis.rb
  41. +0 194 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/America/Juneau.rb
  42. +0 22 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/America/La_Paz.rb
  43. +0 35 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/America/Lima.rb
  44. +0 232 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/America/Los_Angeles.rb
  45. +0 139 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/America/Mazatlan.rb
  46. +0 144 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/America/Mexico_City.rb
  47. +0 131 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/America/Monterrey.rb
  48. +0 282 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/America/New_York.rb
  49. +0 30 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/America/Phoenix.rb
  50. +0 74 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/America/Regina.rb
  51. +0 205 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/America/Santiago.rb
  52. +0 171 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/America/Sao_Paulo.rb
  53. +0 288 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/America/St_Johns.rb
  54. +0 196 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/America/Tijuana.rb
  55. +0 67 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Asia/Almaty.rb
  56. +0 73 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Asia/Baghdad.rb
  57. +0 161 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Asia/Baku.rb
  58. +0 20 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Asia/Bangkok.rb
  59. +0 33 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Asia/Chongqing.rb
  60. +0 30 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Asia/Colombo.rb
  61. +0 112 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Asia/Dhaka.rb
  62. +0 90 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Asia/Hong_Kong.rb
  63. +0 165 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Asia/Irkutsk.rb
  64. +0 30 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Asia/Jakarta.rb
  65. +0 163 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Asia/Jerusalem.rb
  66. +0 20 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Asia/Kabul.rb
  67. +0 163 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Asia/Kamchatka.rb
  68. +0 114 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Asia/Karachi.rb
  69. +0 20 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Asia/Kathmandu.rb
  70. +0 25 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Asia/Kolkata.rb
  71. +0 163 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Asia/Krasnoyarsk.rb
  72. +0 31 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Asia/Kuala_Lumpur.rb
  73. +0 18 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Asia/Kuwait.rb
  74. +0 163 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Asia/Magadan.rb
  75. +0 18 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Asia/Muscat.rb
  76. +0 164 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Asia/Novosibirsk.rb
  77. +0 24 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Asia/Rangoon.rb
  78. +0 18 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Asia/Riyadh.rb
  79. +0 34 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Asia/Seoul.rb
  80. +0 35 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Asia/Shanghai.rb
  81. +0 33 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Asia/Singapore.rb
  82. +0 59 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Asia/Taipei.rb
  83. +0 47 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Asia/Tashkent.rb
  84. +0 78 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Asia/Tbilisi.rb
  85. +0 121 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Asia/Tehran.rb
  86. +0 30 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Asia/Tokyo.rb
  87. +0 65 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Asia/Ulaanbaatar.rb
  88. +0 33 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Asia/Urumqi.rb
  89. +0 164 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Asia/Vladivostok.rb
  90. +0 163 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Asia/Yakutsk.rb
  91. +0 165 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Asia/Yekaterinburg.rb
  92. +0 165 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Asia/Yerevan.rb
  93. +0 270 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Atlantic/Azores.rb
  94. +0 23 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Atlantic/Cape_Verde.rb
  95. +0 18 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Atlantic/South_Georgia.rb
  96. +0 187 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Australia/Adelaide.rb
  97. +0 35 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Australia/Brisbane.rb
  98. +0 29 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Australia/Darwin.rb
  99. +0 193 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Australia/Hobart.rb
  100. +0 185 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Australia/Melbourne.rb
  101. +0 37 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Australia/Perth.rb
  102. +0 185 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Australia/Sydney.rb
  103. +0 16 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Etc/UTC.rb
  104. +0 228 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Europe/Amsterdam.rb
  105. +0 185 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Europe/Athens.rb
  106. +0 163 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Europe/Belgrade.rb
  107. +0 188 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Europe/Berlin.rb
  108. +0 13 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Europe/Bratislava.rb
  109. +0 232 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Europe/Brussels.rb
  110. +0 181 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Europe/Bucharest.rb
  111. +0 197 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Europe/Budapest.rb
  112. +0 179 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Europe/Copenhagen.rb
  113. +0 276 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Europe/Dublin.rb
  114. +0 163 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Europe/Helsinki.rb
  115. +0 218 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Europe/Istanbul.rb
  116. +0 168 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Europe/Kiev.rb
  117. +0 268 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Europe/Lisbon.rb
  118. +0 13 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Europe/Ljubljana.rb
  119. +0 288 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Europe/London.rb
  120. +0 211 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Europe/Madrid.rb
  121. +0 170 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Europe/Minsk.rb
  122. +0 181 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Europe/Moscow.rb
  123. +0 232 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Europe/Paris.rb
  124. +0 187 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Europe/Prague.rb
  125. +0 176 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Europe/Riga.rb
  126. +0 215 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Europe/Rome.rb
  127. +0 13 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Europe/Sarajevo.rb
  128. +0 13 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Europe/Skopje.rb
  129. +0 173 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Europe/Sofia.rb
  130. +0 165 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Europe/Stockholm.rb
  131. +0 172 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Europe/Tallinn.rb
  132. +0 183 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Europe/Vienna.rb
  133. +0 170 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Europe/Vilnius.rb
  134. +0 212 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Europe/Warsaw.rb
  135. +0 13 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Europe/Zagreb.rb
  136. +0 202 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Pacific/Auckland.rb
  137. +0 25 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Pacific/Fiji.rb
  138. +0 22 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Pacific/Guam.rb
  139. +0 28 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Pacific/Honolulu.rb
  140. +0 20 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Pacific/Majuro.rb
  141. +0 25 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Pacific/Midway.rb
  142. +0 25 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Pacific/Noumea.rb
  143. +0 26 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Pacific/Pago_Pago.rb
  144. +0 20 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Pacific/Port_Moresby.rb
  145. +0 27 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/definitions/Pacific/Tongatapu.rb
  146. +0 52 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/info_timezone.rb
  147. +0 51 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/linked_timezone.rb
  148. +0 44 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/linked_timezone_info.rb
  149. +0 98 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/offset_rationals.rb
  150. +0 56 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/ruby_core_support.rb
  151. +0 292 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/time_or_datetime.rb
  152. +0 508 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/timezone.rb
  153. +0 56 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/timezone_definition.rb
  154. +0 40 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/timezone_info.rb
  155. +0 94 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/timezone_offset_info.rb
  156. +0 198 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/timezone_period.rb
  157. +0 129 activesupport/lib/active_support/vendor/tzinfo-0.3.16/lib/tzinfo/timezone_transition_info.rb
2  actionmailer/CHANGELOG
... ... @@ -1,5 +1,7 @@
1 1 *Rails 3.0 (pending)*
2 2
  3 +* Unvendor'd text-format, now requires text-format gem
  4 +
3 5 * Whole new API added with tests. See base.rb for full details. Old API is deprecated.
4 6
5 7 * The Mail::Message class has helped methods for all the field types that return 'common' defaults for the common use case, so to get the subject, mail.subject will give you a string, mail.date will give you a DateTime object, mail.from will give you an array of address specs (mikel@test.lindsaar.net) etc. If you want to access the field object itself, call mail[:field_name] which will return the field object you want, which you can then chain, like mail[:from].formatted
3  actionmailer/actionmailer.gemspec
@@ -11,7 +11,8 @@ Gem::Specification.new do |s|
11 11 s.homepage = "http://www.rubyonrails.org"
12 12
13 13 s.add_dependency('actionpack', '= 3.0.pre')
14   - s.add_dependency('mail', '~> 2.1.1')
  14 + s.add_dependency('mail', '~> 2.1.2')
  15 + s.add_dependency('text-format', '~> 1.0.0')
15 16
16 17 s.files = Dir['CHANGELOG', 'README', 'MIT-LICENSE', 'lib/**/*']
17 18 s.has_rdoc = true
2  actionmailer/lib/action_mailer.rb
@@ -45,5 +45,5 @@ module ActionMailer
45 45 module Text
46 46 extend ActiveSupport::Autoload
47 47
48   - autoload :Format, 'action_mailer/vendor/text_format'
  48 + autoload :Format, 'text/format'
49 49 end
1,467 actionmailer/lib/action_mailer/vendor/text-format-0.6.3/text/format.rb
... ... @@ -1,1467 +0,0 @@
1   -#--
2   -# Text::Format for Ruby
3   -# Version 0.63
4   -#
5   -# Copyright (c) 2002 - 2003 Austin Ziegler
6   -#
7   -# $Id: format.rb,v 1.1.1.1 2004/10/14 11:59:57 webster132 Exp $
8   -#
9   -# ==========================================================================
10   -# Revision History ::
11   -# YYYY.MM.DD Change ID Developer
12   -# Description
13   -# --------------------------------------------------------------------------
14   -# 2002.10.18 Austin Ziegler
15   -# Fixed a minor problem with tabs not being counted. Changed
16   -# abbreviations from Hash to Array to better suit Ruby's
17   -# capabilities. Fixed problems with the way that Array arguments
18   -# are handled in calls to the major object types, excepting in
19   -# Text::Format#expand and Text::Format#unexpand (these will
20   -# probably need to be fixed).
21   -# 2002.10.30 Austin Ziegler
22   -# Fixed the ordering of the <=> for binary tests. Fixed
23   -# Text::Format#expand and Text::Format#unexpand to handle array
24   -# arguments better.
25   -# 2003.01.24 Austin Ziegler
26   -# Fixed a problem with Text::Format::RIGHT_FILL handling where a
27   -# single word is larger than #columns. Removed Comparable
28   -# capabilities (<=> doesn't make sense; == does). Added Symbol
29   -# equivalents for the Hash initialization. Hash initialization has
30   -# been modified so that values are set as follows (Symbols are
31   -# highest priority; strings are middle; defaults are lowest):
32   -# @columns = arg[:columns] || arg['columns'] || @columns
33   -# Added #hard_margins, #split_rules, #hyphenator, and #split_words.
34   -# 2003.02.07 Austin Ziegler
35   -# Fixed the installer for proper case-sensitive handling.
36   -# 2003.03.28 Austin Ziegler
37   -# Added the ability for a hyphenator to receive the formatter
38   -# object. Fixed a bug for strings matching /\A\s*\Z/ failing
39   -# entirely. Fixed a test case failing under 1.6.8.
40   -# 2003.04.04 Austin Ziegler
41   -# Handle the case of hyphenators returning nil for first/rest.
42   -# 2003.09.17 Austin Ziegler
43   -# Fixed a problem where #paragraphs(" ") was raising
44   -# NoMethodError.
45   -#
46   -# ==========================================================================
47   -#++
48   -
49   -module Text #:nodoc:
50   - # Text::Format for Ruby is copyright 2002 - 2005 by Austin Ziegler. It
51   - # is available under Ruby's licence, the Perl Artistic licence, or the
52   - # GNU GPL version 2 (or at your option, any later version). As a
53   - # special exception, for use with official Rails (provided by the
54   - # rubyonrails.org development team) and any project created with
55   - # official Rails, the following alternative MIT-style licence may be
56   - # used:
57   - #
58   - # == Text::Format Licence for Rails and Rails Applications
59   - # Permission is hereby granted, free of charge, to any person
60   - # obtaining a copy of this software and associated documentation files
61   - # (the "Software"), to deal in the Software without restriction,
62   - # including without limitation the rights to use, copy, modify, merge,
63   - # publish, distribute, sublicense, and/or sell copies of the Software,
64   - # and to permit persons to whom the Software is furnished to do so,
65   - # subject to the following conditions:
66   - #
67   - # * The names of its contributors may not be used to endorse or
68   - # promote products derived from this software without specific prior
69   - # written permission.
70   - #
71   - # The above copyright notice and this permission notice shall be
72   - # included in all copies or substantial portions of the Software.
73   - #
74   - # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
75   - # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
76   - # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
77   - # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
78   - # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
79   - # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
80   - # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
81   - # SOFTWARE.
82   - class Format
83   - VERSION = '0.63'
84   -
85   - # Local abbreviations. More can be added with Text::Format.abbreviations
86   - ABBREV = [ 'Mr', 'Mrs', 'Ms', 'Jr', 'Sr' ]
87   -
88   - # Formatting values
89   - LEFT_ALIGN = 0
90   - RIGHT_ALIGN = 1
91   - RIGHT_FILL = 2
92   - JUSTIFY = 3
93   -
94   - # Word split modes (only applies when #hard_margins is true).
95   - SPLIT_FIXED = 1
96   - SPLIT_CONTINUATION = 2
97   - SPLIT_HYPHENATION = 4
98   - SPLIT_CONTINUATION_FIXED = SPLIT_CONTINUATION | SPLIT_FIXED
99   - SPLIT_HYPHENATION_FIXED = SPLIT_HYPHENATION | SPLIT_FIXED
100   - SPLIT_HYPHENATION_CONTINUATION = SPLIT_HYPHENATION | SPLIT_CONTINUATION
101   - SPLIT_ALL = SPLIT_HYPHENATION | SPLIT_CONTINUATION | SPLIT_FIXED
102   -
103   - # Words forcibly split by Text::Format will be stored as split words.
104   - # This class represents a word forcibly split.
105   - class SplitWord
106   - # The word that was split.
107   - attr_reader :word
108   - # The first part of the word that was split.
109   - attr_reader :first
110   - # The remainder of the word that was split.
111   - attr_reader :rest
112   -
113   - def initialize(word, first, rest) #:nodoc:
114   - @word = word
115   - @first = first
116   - @rest = rest
117   - end
118   - end
119   -
120   - private
121   - LEQ_RE = /[.?!]['"]?$/
122   -
123   - def brk_re(i) #:nodoc:
124   - %r/((?:\S+\s+){#{i}})(.+)/
125   - end
126   -
127   - def posint(p) #:nodoc:
128   - p.to_i.abs
129   - end
130   -
131   - public
132   - # Compares two Text::Format objects. All settings of the objects are
133   - # compared *except* #hyphenator. Generated results (e.g., #split_words)
134   - # are not compared, either.
135   - def ==(o)
136   - (@text == o.text) &&
137   - (@columns == o.columns) &&
138   - (@left_margin == o.left_margin) &&
139   - (@right_margin == o.right_margin) &&
140   - (@hard_margins == o.hard_margins) &&
141   - (@split_rules == o.split_rules) &&
142   - (@first_indent == o.first_indent) &&
143   - (@body_indent == o.body_indent) &&
144   - (@tag_text == o.tag_text) &&
145   - (@tabstop == o.tabstop) &&
146   - (@format_style == o.format_style) &&
147   - (@extra_space == o.extra_space) &&
148   - (@tag_paragraph == o.tag_paragraph) &&
149   - (@nobreak == o.nobreak) &&
150   - (@abbreviations == o.abbreviations) &&
151   - (@nobreak_regex == o.nobreak_regex)
152   - end
153   -
154   - # The text to be manipulated. Note that value is optional, but if the
155   - # formatting functions are called without values, this text is what will
156   - # be formatted.
157   - #
158   - # *Default*:: <tt>[]</tt>
159   - # <b>Used in</b>:: All methods
160   - attr_accessor :text
161   -
162   - # The total width of the format area. The margins, indentation, and text
163   - # are formatted into this space.
164   - #
165   - # COLUMNS
166   - # <-------------------------------------------------------------->
167   - # <-----------><------><---------------------------><------------>
168   - # left margin indent text is formatted into here right margin
169   - #
170   - # *Default*:: <tt>72</tt>
171   - # <b>Used in</b>:: <tt>#format</tt>, <tt>#paragraphs</tt>,
172   - # <tt>#center</tt>
173   - attr_reader :columns
174   -
175   - # The total width of the format area. The margins, indentation, and text
176   - # are formatted into this space. The value provided is silently
177   - # converted to a positive integer.
178   - #
179   - # COLUMNS
180   - # <-------------------------------------------------------------->
181   - # <-----------><------><---------------------------><------------>
182   - # left margin indent text is formatted into here right margin
183   - #
184   - # *Default*:: <tt>72</tt>
185   - # <b>Used in</b>:: <tt>#format</tt>, <tt>#paragraphs</tt>,
186   - # <tt>#center</tt>
187   - def columns=(c)
188   - @columns = posint(c)
189   - end
190   -
191   - # The number of spaces used for the left margin.
192   - #
193   - # columns
194   - # <-------------------------------------------------------------->
195   - # <-----------><------><---------------------------><------------>
196   - # LEFT MARGIN indent text is formatted into here right margin
197   - #
198   - # *Default*:: <tt>0</tt>
199   - # <b>Used in</b>:: <tt>#format</tt>, <tt>#paragraphs</tt>,
200   - # <tt>#center</tt>
201   - attr_reader :left_margin
202   -
203   - # The number of spaces used for the left margin. The value provided is
204   - # silently converted to a positive integer value.
205   - #
206   - # columns
207   - # <-------------------------------------------------------------->
208   - # <-----------><------><---------------------------><------------>
209   - # LEFT MARGIN indent text is formatted into here right margin
210   - #
211   - # *Default*:: <tt>0</tt>
212   - # <b>Used in</b>:: <tt>#format</tt>, <tt>#paragraphs</tt>,
213   - # <tt>#center</tt>
214   - def left_margin=(left)
215   - @left_margin = posint(left)
216   - end
217   -
218   - # The number of spaces used for the right margin.
219   - #
220   - # columns
221   - # <-------------------------------------------------------------->
222   - # <-----------><------><---------------------------><------------>
223   - # left margin indent text is formatted into here RIGHT MARGIN
224   - #
225   - # *Default*:: <tt>0</tt>
226   - # <b>Used in</b>:: <tt>#format</tt>, <tt>#paragraphs</tt>,
227   - # <tt>#center</tt>
228   - attr_reader :right_margin
229   -
230   - # The number of spaces used for the right margin. The value provided is
231   - # silently converted to a positive integer value.
232   - #
233   - # columns
234   - # <-------------------------------------------------------------->
235   - # <-----------><------><---------------------------><------------>
236   - # left margin indent text is formatted into here RIGHT MARGIN
237   - #
238   - # *Default*:: <tt>0</tt>
239   - # <b>Used in</b>:: <tt>#format</tt>, <tt>#paragraphs</tt>,
240   - # <tt>#center</tt>
241   - def right_margin=(r)
242   - @right_margin = posint(r)
243   - end
244   -
245   - # The number of spaces to indent the first line of a paragraph.
246   - #
247   - # columns
248   - # <-------------------------------------------------------------->
249   - # <-----------><------><---------------------------><------------>
250   - # left margin INDENT text is formatted into here right margin
251   - #
252   - # *Default*:: <tt>4</tt>
253   - # <b>Used in</b>:: <tt>#format</tt>, <tt>#paragraphs</tt>
254   - attr_reader :first_indent
255   -
256   - # The number of spaces to indent the first line of a paragraph. The
257   - # value provided is silently converted to a positive integer value.
258   - #
259   - # columns
260   - # <-------------------------------------------------------------->
261   - # <-----------><------><---------------------------><------------>
262   - # left margin INDENT text is formatted into here right margin
263   - #
264   - # *Default*:: <tt>4</tt>
265   - # <b>Used in</b>:: <tt>#format</tt>, <tt>#paragraphs</tt>
266   - def first_indent=(f)
267   - @first_indent = posint(f)
268   - end
269   -
270   - # The number of spaces to indent all lines after the first line of a
271   - # paragraph.
272   - #
273   - # columns
274   - # <-------------------------------------------------------------->
275   - # <-----------><------><---------------------------><------------>
276   - # left margin INDENT text is formatted into here right margin
277   - #
278   - # *Default*:: <tt>0</tt>
279   - # <b>Used in</b>:: <tt>#format</tt>, <tt>#paragraphs</tt>
280   - attr_reader :body_indent
281   -
282   - # The number of spaces to indent all lines after the first line of
283   - # a paragraph. The value provided is silently converted to a
284   - # positive integer value.
285   - #
286   - # columns
287   - # <-------------------------------------------------------------->
288   - # <-----------><------><---------------------------><------------>
289   - # left margin INDENT text is formatted into here right margin
290   - #
291   - # *Default*:: <tt>0</tt>
292   - # <b>Used in</b>:: <tt>#format</tt>, <tt>#paragraphs</tt>
293   - def body_indent=(b)
294   - @body_indent = posint(b)
295   - end
296   -
297   - # Normally, words larger than the format area will be placed on a line
298   - # by themselves. Setting this to +true+ will force words larger than the
299   - # format area to be split into one or more "words" each at most the size
300   - # of the format area. The first line and the original word will be
301   - # placed into <tt>#split_words</tt>. Note that this will cause the
302   - # output to look *similar* to a #format_style of JUSTIFY. (Lines will be
303   - # filled as much as possible.)
304   - #
305   - # *Default*:: +false+
306   - # <b>Used in</b>:: <tt>#format</tt>, <tt>#paragraphs</tt>
307   - attr_accessor :hard_margins
308   -
309   - # An array of words split during formatting if #hard_margins is set to
310   - # +true+.
311   - # #split_words << Text::Format::SplitWord.new(word, first, rest)
312   - attr_reader :split_words
313   -
314   - # The object responsible for hyphenating. It must respond to
315   - # #hyphenate_to(word, size) or #hyphenate_to(word, size, formatter) and
316   - # return an array of the word split into two parts; if there is a
317   - # hyphenation mark to be applied, responsibility belongs to the
318   - # hyphenator object. The size is the MAXIMUM size permitted, including
319   - # any hyphenation marks. If the #hyphenate_to method has an arity of 3,
320   - # the formatter will be provided to the method. This allows the
321   - # hyphenator to make decisions about the hyphenation based on the
322   - # formatting rules.
323   - #
324   - # *Default*:: +nil+
325   - # <b>Used in</b>:: <tt>#format</tt>, <tt>#paragraphs</tt>
326   - attr_reader :hyphenator
327   -
328   - # The object responsible for hyphenating. It must respond to
329   - # #hyphenate_to(word, size) and return an array of the word hyphenated
330   - # into two parts. The size is the MAXIMUM size permitted, including any
331   - # hyphenation marks.
332   - #
333   - # *Default*:: +nil+
334   - # <b>Used in</b>:: <tt>#format</tt>, <tt>#paragraphs</tt>
335   - def hyphenator=(h)
336   - raise ArgumentError, "#{h.inspect} is not a valid hyphenator." unless h.respond_to?(:hyphenate_to)
337   - arity = h.method(:hyphenate_to).arity
338   - raise ArgumentError, "#{h.inspect} must have exactly two or three arguments." unless [2, 3].include?(arity)
339   - @hyphenator = h
340   - @hyphenator_arity = arity
341   - end
342   -
343   - # Specifies the split mode; used only when #hard_margins is set to
344   - # +true+. Allowable values are:
345   - # [+SPLIT_FIXED+] The word will be split at the number of
346   - # characters needed, with no marking at all.
347   - # repre
348   - # senta
349   - # ion
350   - # [+SPLIT_CONTINUATION+] The word will be split at the number of
351   - # characters needed, with a C-style continuation
352   - # character. If a word is the only item on a
353   - # line and it cannot be split into an
354   - # appropriate size, SPLIT_FIXED will be used.
355   - # repr\
356   - # esen\
357   - # tati\
358   - # on
359   - # [+SPLIT_HYPHENATION+] The word will be split according to the
360   - # hyphenator specified in #hyphenator. If there
361   - # is no #hyphenator specified, works like
362   - # SPLIT_CONTINUATION. The example is using
363   - # TeX::Hyphen. If a word is the only item on a
364   - # line and it cannot be split into an
365   - # appropriate size, SPLIT_CONTINUATION mode will
366   - # be used.
367   - # rep-
368   - # re-
369   - # sen-
370   - # ta-
371   - # tion
372   - #
373   - # *Default*:: <tt>Text::Format::SPLIT_FIXED</tt>
374   - # <b>Used in</b>:: <tt>#format</tt>, <tt>#paragraphs</tt>
375   - attr_reader :split_rules
376   -
377   - # Specifies the split mode; used only when #hard_margins is set to
378   - # +true+. Allowable values are:
379   - # [+SPLIT_FIXED+] The word will be split at the number of
380   - # characters needed, with no marking at all.
381   - # repre
382   - # senta
383   - # ion
384   - # [+SPLIT_CONTINUATION+] The word will be split at the number of
385   - # characters needed, with a C-style continuation
386   - # character.
387   - # repr\
388   - # esen\
389   - # tati\
390   - # on
391   - # [+SPLIT_HYPHENATION+] The word will be split according to the
392   - # hyphenator specified in #hyphenator. If there
393   - # is no #hyphenator specified, works like
394   - # SPLIT_CONTINUATION. The example is using
395   - # TeX::Hyphen as the #hyphenator.
396   - # rep-
397   - # re-
398   - # sen-
399   - # ta-
400   - # tion
401   - #
402   - # These values can be bitwise ORed together (e.g., <tt>SPLIT_FIXED |
403   - # SPLIT_CONTINUATION</tt>) to provide fallback split methods. In the
404   - # example given, an attempt will be made to split the word using the
405   - # rules of SPLIT_CONTINUATION; if there is not enough room, the word
406   - # will be split with the rules of SPLIT_FIXED. These combinations are
407   - # also available as the following values:
408   - # * +SPLIT_CONTINUATION_FIXED+
409   - # * +SPLIT_HYPHENATION_FIXED+
410   - # * +SPLIT_HYPHENATION_CONTINUATION+
411   - # * +SPLIT_ALL+
412   - #
413   - # *Default*:: <tt>Text::Format::SPLIT_FIXED</tt>
414   - # <b>Used in</b>:: <tt>#format</tt>, <tt>#paragraphs</tt>
415   - def split_rules=(s)
416   - raise ArgumentError, "Invalid value provided for split_rules." if ((s < SPLIT_FIXED) || (s > SPLIT_ALL))
417   - @split_rules = s
418   - end
419   -
420   - # Indicates whether sentence terminators should be followed by a single
421   - # space (+false+), or two spaces (+true+).
422   - #
423   - # *Default*:: +false+
424   - # <b>Used in</b>:: <tt>#format</tt>, <tt>#paragraphs</tt>
425   - attr_accessor :extra_space
426   -
427   - # Defines the current abbreviations as an array. This is only used if
428   - # extra_space is turned on.
429   - #
430   - # If one is abbreviating "President" as "Pres." (abbreviations =
431   - # ["Pres"]), then the results of formatting will be as illustrated in
432   - # the table below:
433   - #
434   - # extra_space | include? | !include?
435   - # true | Pres. Lincoln | Pres. Lincoln
436   - # false | Pres. Lincoln | Pres. Lincoln
437   - #
438   - # *Default*:: <tt>{}</tt>
439   - # <b>Used in</b>:: <tt>#format</tt>, <tt>#paragraphs</tt>
440   - attr_accessor :abbreviations
441   -
442   - # Indicates whether the formatting of paragraphs should be done with
443   - # tagged paragraphs. Useful only with <tt>#tag_text</tt>.
444   - #
445   - # *Default*:: +false+
446   - # <b>Used in</b>:: <tt>#format</tt>, <tt>#paragraphs</tt>
447   - attr_accessor :tag_paragraph
448   -
449   - # The array of text to be placed before each paragraph when
450   - # <tt>#tag_paragraph</tt> is +true+. When <tt>#format()</tt> is called,
451   - # only the first element of the array is used. When <tt>#paragraphs</tt>
452   - # is called, then each entry in the array will be used once, with
453   - # corresponding paragraphs. If the tag elements are exhausted before the
454   - # text is exhausted, then the remaining paragraphs will not be tagged.
455   - # Regardless of indentation settings, a blank line will be inserted
456   - # between all paragraphs when <tt>#tag_paragraph</tt> is +true+.
457   - #
458   - # *Default*:: <tt>[]</tt>
459   - # <b>Used in</b>:: <tt>#format</tt>, <tt>#paragraphs</tt>
460   - attr_accessor :tag_text
461   -
462   - # Indicates whether or not the non-breaking space feature should be
463   - # used.
464   - #
465   - # *Default*:: +false+
466   - # <b>Used in</b>:: <tt>#format</tt>, <tt>#paragraphs</tt>
467   - attr_accessor :nobreak
468   -
469   - # A hash which holds the regular expressions on which spaces should not
470   - # be broken. The hash is set up such that the key is the first word and
471   - # the value is the second word.
472   - #
473   - # For example, if +nobreak_regex+ contains the following hash:
474   - #
475   - # { '^Mrs?\.$' => '\S+$', '^\S+$' => '^(?:S|J)r\.$'}
476   - #
477   - # Then "Mr. Jones", "Mrs. Jones", and "Jones Jr." would not be broken.
478   - # If this simple matching algorithm indicates that there should not be a
479   - # break at the current end of line, then a backtrack is done until there
480   - # are two words on which line breaking is permitted. If two such words
481   - # are not found, then the end of the line will be broken *regardless*.
482   - # If there is a single word on the current line, then no backtrack is
483   - # done and the word is stuck on the end.
484   - #
485   - # *Default*:: <tt>{}</tt>
486   - # <b>Used in</b>:: <tt>#format</tt>, <tt>#paragraphs</tt>
487   - attr_accessor :nobreak_regex
488   -
489   - # Indicates the number of spaces that a single tab represents.
490   - #
491   - # *Default*:: <tt>8</tt>
492   - # <b>Used in</b>:: <tt>#expand</tt>, <tt>#unexpand</tt>,
493   - # <tt>#paragraphs</tt>
494   - attr_reader :tabstop
495   -
496   - # Indicates the number of spaces that a single tab represents.
497   - #
498   - # *Default*:: <tt>8</tt>
499   - # <b>Used in</b>:: <tt>#expand</tt>, <tt>#unexpand</tt>,
500   - # <tt>#paragraphs</tt>
501   - def tabstop=(t)
502   - @tabstop = posint(t)
503   - end
504   -
505   - # Specifies the format style. Allowable values are:
506   - # [+LEFT_ALIGN+] Left justified, ragged right.
507   - # |A paragraph that is|
508   - # |left aligned.|
509   - # [+RIGHT_ALIGN+] Right justified, ragged left.
510   - # |A paragraph that is|
511   - # | right aligned.|
512   - # [+RIGHT_FILL+] Left justified, right ragged, filled to width by
513   - # spaces. (Essentially the same as +LEFT_ALIGN+ except
514   - # that lines are padded on the right.)
515   - # |A paragraph that is|
516   - # |left aligned. |
517   - # [+JUSTIFY+] Fully justified, words filled to width by spaces,
518   - # except the last line.
519   - # |A paragraph that|
520   - # |is justified.|
521   - #
522   - # *Default*:: <tt>Text::Format::LEFT_ALIGN</tt>
523   - # <b>Used in</b>:: <tt>#format</tt>, <tt>#paragraphs</tt>
524   - attr_reader :format_style
525   -
526   - # Specifies the format style. Allowable values are:
527   - # [+LEFT_ALIGN+] Left justified, ragged right.
528   - # |A paragraph that is|
529   - # |left aligned.|
530   - # [+RIGHT_ALIGN+] Right justified, ragged left.
531   - # |A paragraph that is|
532   - # | right aligned.|
533   - # [+RIGHT_FILL+] Left justified, right ragged, filled to width by
534   - # spaces. (Essentially the same as +LEFT_ALIGN+ except
535   - # that lines are padded on the right.)
536   - # |A paragraph that is|
537   - # |left aligned. |
538   - # [+JUSTIFY+] Fully justified, words filled to width by spaces.
539   - # |A paragraph that|
540   - # |is justified.|
541   - #
542   - # *Default*:: <tt>Text::Format::LEFT_ALIGN</tt>
543   - # <b>Used in</b>:: <tt>#format</tt>, <tt>#paragraphs</tt>
544   - def format_style=(fs)
545   - raise ArgumentError, "Invalid value provided for format_style." if ((fs < LEFT_ALIGN) || (fs > JUSTIFY))
546   - @format_style = fs
547   - end
548   -
549   - # Indicates that the format style is left alignment.
550   - #
551   - # *Default*:: +true+
552   - # <b>Used in</b>:: <tt>#format</tt>, <tt>#paragraphs</tt>
553   - def left_align?
554   - return @format_style == LEFT_ALIGN
555   - end
556   -
557   - # Indicates that the format style is right alignment.
558   - #
559   - # *Default*:: +false+
560   - # <b>Used in</b>:: <tt>#format</tt>, <tt>#paragraphs</tt>
561   - def right_align?
562   - return @format_style == RIGHT_ALIGN
563   - end
564   -
565   - # Indicates that the format style is right fill.
566   - #
567   - # *Default*:: +false+
568   - # <b>Used in</b>:: <tt>#format</tt>, <tt>#paragraphs</tt>
569   - def right_fill?
570   - return @format_style == RIGHT_FILL
571   - end
572   -
573   - # Indicates that the format style is full justification.
574   - #
575   - # *Default*:: +false+
576   - # <b>Used in</b>:: <tt>#format</tt>, <tt>#paragraphs</tt>
577   - def justify?
578   - return @format_style == JUSTIFY
579   - end
580   -
581   - # The default implementation of #hyphenate_to implements
582   - # SPLIT_CONTINUATION.
583   - def hyphenate_to(word, size)
584   - [word[0 .. (size - 2)] + "\\", word[(size - 1) .. -1]]
585   - end
586   -
587   - private
588   - def __do_split_word(word, size) #:nodoc:
589   - [word[0 .. (size - 1)], word[size .. -1]]
590   - end
591   -
592   - def __format(to_wrap) #:nodoc:
593   - words = to_wrap.split(/\s+/).compact
594   - words.shift if words[0].nil? or words[0].empty?
595   - to_wrap = []
596   -
597   - abbrev = false
598   - width = @columns - @first_indent - @left_margin - @right_margin
599   - indent_str = ' ' * @first_indent
600   - first_line = true
601   - line = words.shift
602   - abbrev = __is_abbrev(line) unless line.nil? || line.empty?
603   -
604   - while w = words.shift
605   - if (w.size + line.size < (width - 1)) ||
606   - ((line !~ LEQ_RE || abbrev) && (w.size + line.size < width))
607   - line << " " if (line =~ LEQ_RE) && (not abbrev)
608   - line << " #{w}"
609   - else
610   - line, w = __do_break(line, w) if @nobreak
611   - line, w = __do_hyphenate(line, w, width) if @hard_margins
612   - if w.index(/\s+/)
613   - w, *w2 = w.split(/\s+/)
614   - words.unshift(w2)
615   - words.flatten!
616   - end
617   - to_wrap << __make_line(line, indent_str, width, w.nil?) unless line.nil?
618   - if first_line
619   - first_line = false
620   - width = @columns - @body_indent - @left_margin - @right_margin
621   - indent_str = ' ' * @body_indent
622   - end
623   - line = w
624   - end
625   -
626   - abbrev = __is_abbrev(w) unless w.nil?
627   - end
628   -
629   - loop do
630   - break if line.nil? or line.empty?
631   - line, w = __do_hyphenate(line, w, width) if @hard_margins
632   - to_wrap << __make_line(line, indent_str, width, w.nil?)
633   - line = w
634   - end
635   -
636   - if (@tag_paragraph && (to_wrap.size > 0)) then
637   - clr = %r{`(\w+)'}.match([caller(1)].flatten[0])[1]
638   - clr = "" if clr.nil?
639   -
640   - if ((not @tag_text[0].nil?) && (@tag_cur.size < 1) &&
641   - (clr != "__paragraphs")) then
642   - @tag_cur = @tag_text[0]
643   - end
644   -
645   - fchar = /(\S)/.match(to_wrap[0])[1]
646   - white = to_wrap[0].index(fchar)
647   - if ((white - @left_margin - 1) > @tag_cur.size) then
648   - white = @tag_cur.size + @left_margin
649   - to_wrap[0].gsub!(/^ {#{white}}/, "#{' ' * @left_margin}#{@tag_cur}")
650   - else
651   - to_wrap.unshift("#{' ' * @left_margin}#{@tag_cur}\n")
652   - end
653   - end
654   - to_wrap.join('')
655   - end
656   -
657   - # format lines in text into paragraphs with each element of @wrap a
658   - # paragraph; uses Text::Format.format for the formatting
659   - def __paragraphs(to_wrap) #:nodoc:
660   - if ((@first_indent == @body_indent) || @tag_paragraph) then
661   - p_end = "\n"
662   - else
663   - p_end = ''
664   - end
665   -
666   - cnt = 0
667   - ret = []
668   - to_wrap.each do |tw|
669   - @tag_cur = @tag_text[cnt] if @tag_paragraph
670   - @tag_cur = '' if @tag_cur.nil?
671   - line = __format(tw)
672   - ret << "#{line}#{p_end}" if (not line.nil?) && (line.size > 0)
673   - cnt += 1
674   - end
675   -
676   - ret[-1].chomp! unless ret.empty?
677   - ret.join('')
678   - end
679   -
680   - # center text using spaces on left side to pad it out empty lines
681   - # are preserved
682   - def __center(to_center) #:nodoc:
683   - tabs = 0
684   - width = @columns - @left_margin - @right_margin
685   - centered = []
686   - to_center.each do |tc|
687   - s = tc.strip
688   - tabs = s.count("\t")
689   - tabs = 0 if tabs.nil?
690   - ct = ((width - s.size - (tabs * @tabstop) + tabs) / 2)
691   - ct = (width - @left_margin - @right_margin) - ct
692   - centered << "#{s.rjust(ct)}\n"
693   - end
694   - centered.join('')
695   - end
696   -
697   - # expand tabs to spaces should be similar to Text::Tabs::expand
698   - def __expand(to_expand) #:nodoc:
699   - expanded = []
700   - to_expand.split("\n").each { |te| expanded << te.gsub(/\t/, ' ' * @tabstop) }
701   - expanded.join('')
702   - end
703   -
704   - def __unexpand(to_unexpand) #:nodoc:
705   - unexpanded = []
706   - to_unexpand.split("\n").each { |tu| unexpanded << tu.gsub(/ {#{@tabstop}}/, "\t") }
707   - unexpanded.join('')
708   - end
709   -
710   - def __is_abbrev(word) #:nodoc:
711   - # remove period if there is one.
712   - w = word.gsub(/\.$/, '') unless word.nil?
713   - return true if (!@extra_space || ABBREV.include?(w) || @abbreviations.include?(w))
714   - false
715   - end
716   -
717   - def __make_line(line, indent, width, last = false) #:nodoc:
718   - lmargin = " " * @left_margin
719   - fill = " " * (width - line.size) if right_fill? && (line.size <= width)
720   -
721   - if (justify? && ((not line.nil?) && (not line.empty?)) && line =~ /\S+\s+\S+/ && !last)
722   - spaces = width - line.size
723   - words = line.split(/(\s+)/)
724   - ws = spaces / (words.size / 2)
725   - spaces = spaces % (words.size / 2) if ws > 0
726   - words.reverse.each do |rw|
727   - next if (rw =~ /^\S/)
728   - rw.sub!(/^/, " " * ws)
729   - next unless (spaces > 0)
730   - rw.sub!(/^/, " ")
731   - spaces -= 1
732   - end
733   - line = words.join('')
734   - end
735   - line = "#{lmargin}#{indent}#{line}#{fill}\n" unless line.nil?
736   - if right_align? && (not line.nil?)
737   - line.sub(/^/, " " * (@columns - @right_margin - (line.size - 1)))
738   - else
739   - line
740   - end
741   - end
742   -
743   - def __do_hyphenate(line, next_line, width) #:nodoc:
744   - rline = line.dup rescue line
745   - rnext = next_line.dup rescue next_line
746   - loop do
747   - if rline.size == width
748   - break
749   - elsif rline.size > width
750   - words = rline.strip.split(/\s+/)
751   - word = words[-1].dup
752   - size = width - rline.size + word.size
753   - if (size <= 0)
754   - words[-1] = nil
755   - rline = words.join(' ').strip
756   - rnext = "#{word} #{rnext}".strip
757   - next
758   - end
759   -
760   - first = rest = nil
761   -
762   - if ((@split_rules & SPLIT_HYPHENATION) != 0)
763   - if @hyphenator_arity == 2
764   - first, rest = @hyphenator.hyphenate_to(word, size)
765   - else
766   - first, rest = @hyphenator.hyphenate_to(word, size, self)
767   - end
768   - end
769   -
770   - if ((@split_rules & SPLIT_CONTINUATION) != 0) and first.nil?
771   - first, rest = self.hyphenate_to(word, size)
772   - end
773   -
774   - if ((@split_rules & SPLIT_FIXED) != 0) and first.nil?
775   - first.nil? or @split_rules == SPLIT_FIXED
776   - first, rest = __do_split_word(word, size)
777   - end
778   -
779   - if first.nil?
780   - words[-1] = nil
781   - rest = word
782   - else
783   - words[-1] = first
784   - @split_words << SplitWord.new(word, first, rest)
785   - end
786   - rline = words.join(' ').strip
787   - rnext = "#{rest} #{rnext}".strip
788   - break
789   - else
790   - break if rnext.nil? or rnext.empty? or rline.nil? or rline.empty?
791   - words = rnext.split(/\s+/)
792   - word = words.shift
793   - size = width - rline.size - 1
794   -
795   - if (size <= 0)
796   - rnext = "#{word} #{words.join(' ')}".strip
797   - break
798   - end
799   -
800   - first = rest = nil
801   -
802   - if ((@split_rules & SPLIT_HYPHENATION) != 0)
803   - if @hyphenator_arity == 2
804   - first, rest = @hyphenator.hyphenate_to(word, size)
805   - else
806   - first, rest = @hyphenator.hyphenate_to(word, size, self)
807   - end
808   - end
809   -
810   - first, rest = self.hyphenate_to(word, size) if ((@split_rules & SPLIT_CONTINUATION) != 0) and first.nil?
811   -
812   - first, rest = __do_split_word(word, size) if ((@split_rules & SPLIT_FIXED) != 0) and first.nil?
813   -
814   - if (rline.size + (first ? first.size : 0)) < width
815   - @split_words << SplitWord.new(word, first, rest)
816   - rline = "#{rline} #{first}".strip
817   - rnext = "#{rest} #{words.join(' ')}".strip
818   - end
819   - break
820   - end
821   - end
822   - [rline, rnext]
823   - end
824   -
825   - def __do_break(line, next_line) #:nodoc:
826   - no_brk = false
827   - words = []
828   - words = line.split(/\s+/) unless line.nil?
829   - last_word = words[-1]
830   -
831   - @nobreak_regex.each { |k, v| no_brk = ((last_word =~ /#{k}/) and (next_line =~ /#{v}/)) }
832   -
833   - if no_brk && words.size > 1
834   - i = words.size
835   - while i > 0
836   - no_brk = false
837   - @nobreak_regex.each { |k, v| no_brk = ((words[i + 1] =~ /#{k}/) && (words[i] =~ /#{v}/)) }
838   - i -= 1
839   - break if not no_brk
840   - end
841   - if i > 0
842   - l = brk_re(i).match(line)
843   - line.sub!(brk_re(i), l[1])
844   - next_line = "#{l[2]} #{next_line}"
845   - line.sub!(/\s+$/, '')
846   - end
847   - end
848   - [line, next_line]
849   - end
850   -
851   - def __create(arg = nil, &block) #:nodoc:
852   - # Format::Text.new(text-to-wrap)
853   - @text = arg unless arg.nil?
854   - # Defaults
855   - @columns = 72
856   - @tabstop = 8
857   - @first_indent = 4
858   - @body_indent = 0
859   - @format_style = LEFT_ALIGN
860   - @left_margin = 0
861   - @right_margin = 0
862   - @extra_space = false
863   - @text = Array.new if @text.nil?
864   - @tag_paragraph = false
865   - @tag_text = Array.new
866   - @tag_cur = ""
867   - @abbreviations = Array.new
868   - @nobreak = false
869   - @nobreak_regex = Hash.new
870   - @split_words = Array.new
871   - @hard_margins = false
872   - @split_rules = SPLIT_FIXED
873   - @hyphenator = self
874   - @hyphenator_arity = self.method(:hyphenate_to).arity
875   -
876   - instance_eval(&block) unless block.nil?
877   - end
878   -
879   - public
880   - # Formats text into a nice paragraph format. The text is separated
881   - # into words and then reassembled a word at a time using the settings
882   - # of this Format object. If a word is larger than the number of
883   - # columns available for formatting, then that word will appear on the
884   - # line by itself.
885   - #
886   - # If +to_wrap+ is +nil+, then the value of <tt>#text</tt> will be
887   - # worked on.
888   - def format(to_wrap = nil)
889   - to_wrap = @text if to_wrap.nil?
890   - if to_wrap.class == Array