Skip to content
This repository
Browse code

Initial

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information...
commit db045dbbf60b53dbe013ef25554fd013baf88134 0 parents
David Heinemeier Hansson authored November 24, 2004

Showing 296 changed files with 29,880 additions and 0 deletions. Show diff stats Hide diff stats

  1. 19  actionmailer/CHANGELOG
  2. 21  actionmailer/MIT-LICENSE
  3. 102  actionmailer/README
  4. 107  actionmailer/Rakefile
  5. 61  actionmailer/install.rb
  6. 43  actionmailer/lib/action_mailer.rb
  7. 152  actionmailer/lib/action_mailer/base.rb
  8. 17  actionmailer/lib/action_mailer/mail_helper.rb
  9. 1,447  actionmailer/lib/action_mailer/vendor/text/format.rb
  10. 4  actionmailer/lib/action_mailer/vendor/tmail.rb
  11. 223  actionmailer/lib/action_mailer/vendor/tmail/address.rb
  12. 52  actionmailer/lib/action_mailer/vendor/tmail/base64.rb
  13. 50  actionmailer/lib/action_mailer/vendor/tmail/config.rb
  14. 447  actionmailer/lib/action_mailer/vendor/tmail/encode.rb
  15. 531  actionmailer/lib/action_mailer/vendor/tmail/facade.rb
  16. 893  actionmailer/lib/action_mailer/vendor/tmail/header.rb
  17. 16  actionmailer/lib/action_mailer/vendor/tmail/info.rb
  18. 1  actionmailer/lib/action_mailer/vendor/tmail/loader.rb
  19. 420  actionmailer/lib/action_mailer/vendor/tmail/mail.rb
  20. 414  actionmailer/lib/action_mailer/vendor/tmail/mailbox.rb
  21. 1  actionmailer/lib/action_mailer/vendor/tmail/mbox.rb
  22. 261  actionmailer/lib/action_mailer/vendor/tmail/net.rb
  23. 116  actionmailer/lib/action_mailer/vendor/tmail/obsolete.rb
  24. 1,503  actionmailer/lib/action_mailer/vendor/tmail/parser.rb
  25. 358  actionmailer/lib/action_mailer/vendor/tmail/port.rb
  26. 22  actionmailer/lib/action_mailer/vendor/tmail/scanner.rb
  27. 244  actionmailer/lib/action_mailer/vendor/tmail/scanner_r.rb
  28. 260  actionmailer/lib/action_mailer/vendor/tmail/stringio.rb
  29. 1  actionmailer/lib/action_mailer/vendor/tmail/tmail.rb
  30. 215  actionmailer/lib/action_mailer/vendor/tmail/utils.rb
  31. 3  actionmailer/test/fixtures/templates/signed_up.rhtml
  32. 3  actionmailer/test/fixtures/test_mailer/signed_up.rhtml
  33. 92  actionmailer/test/mail_service_test.rb
  34. 738  actionpack/CHANGELOG
  35. 21  actionpack/MIT-LICENSE
  36. 418  actionpack/README
  37. 25  actionpack/RUNNING_UNIT_TESTS
  38. 105  actionpack/Rakefile
  39. 24  actionpack/examples/.htaccess
  40. 33  actionpack/examples/address_book/index.rhtml
  41. 8  actionpack/examples/address_book/layout.rhtml
  42. 9  actionpack/examples/address_book_controller.cgi
  43. 6  actionpack/examples/address_book_controller.fcgi
  44. 52  actionpack/examples/address_book_controller.rb
  45. 4  actionpack/examples/address_book_controller.rbx
  46. 52  actionpack/examples/benchmark.rb
  47. 89  actionpack/examples/benchmark_with_ar.fcgi
  48. 53  actionpack/examples/blog_controller.cgi
  49. 14  actionpack/examples/debate/index.rhtml
  50. 22  actionpack/examples/debate/new_topic.rhtml
  51. 32  actionpack/examples/debate/topic.rhtml
  52. 57  actionpack/examples/debate_controller.cgi
  53. 97  actionpack/install.rb
  54. 51  actionpack/lib/action_controller.rb
  55. 199  actionpack/lib/action_controller/assertions/action_pack_assertions.rb
  56. 65  actionpack/lib/action_controller/assertions/active_record_assertions.rb
  57. 689  actionpack/lib/action_controller/base.rb
  58. 49  actionpack/lib/action_controller/benchmarking.rb
  59. 43  actionpack/lib/action_controller/cgi_ext/cgi_ext.rb
  60. 91  actionpack/lib/action_controller/cgi_ext/cgi_methods.rb
  61. 124  actionpack/lib/action_controller/cgi_process.rb
  62. 49  actionpack/lib/action_controller/dependencies.rb
  63. 279  actionpack/lib/action_controller/filters.rb
  64. 65  actionpack/lib/action_controller/flash.rb
  65. 100  actionpack/lib/action_controller/helpers.rb
  66. 149  actionpack/lib/action_controller/layout.rb
  67. 99  actionpack/lib/action_controller/request.rb
  68. 94  actionpack/lib/action_controller/rescue.rb
  69. 15  actionpack/lib/action_controller/response.rb
  70. 183  actionpack/lib/action_controller/scaffolding.rb
  71. 72  actionpack/lib/action_controller/session/active_record_store.rb
  72. 9  actionpack/lib/action_controller/session/drb_server.rb
  73. 31  actionpack/lib/action_controller/session/drb_store.rb
  74. 57  actionpack/lib/action_controller/support/class_attribute_accessors.rb
  75. 37  actionpack/lib/action_controller/support/class_inheritable_attributes.rb
  76. 10  actionpack/lib/action_controller/support/clean_logger.rb
  77. 121  actionpack/lib/action_controller/support/cookie_performance_fix.rb
  78. 78  actionpack/lib/action_controller/support/inflector.rb
  79. 28  actionpack/lib/action_controller/templates/rescues/_request_and_response.rhtml
  80. 22  actionpack/lib/action_controller/templates/rescues/diagnostics.rhtml
  81. 29  actionpack/lib/action_controller/templates/rescues/layout.rhtml
  82. 2  actionpack/lib/action_controller/templates/rescues/missing_template.rhtml
  83. 26  actionpack/lib/action_controller/templates/rescues/template_error.rhtml
  84. 2  actionpack/lib/action_controller/templates/rescues/unknown_action.rhtml
  85. 6  actionpack/lib/action_controller/templates/scaffolds/edit.rhtml
  86. 29  actionpack/lib/action_controller/templates/scaffolds/layout.rhtml
  87. 24  actionpack/lib/action_controller/templates/scaffolds/list.rhtml
  88. 5  actionpack/lib/action_controller/templates/scaffolds/new.rhtml
  89. 9  actionpack/lib/action_controller/templates/scaffolds/show.rhtml
  90. 195  actionpack/lib/action_controller/test_process.rb
  91. 170  actionpack/lib/action_controller/url_rewriter.rb
  92. 49  actionpack/lib/action_view.rb
  93. 264  actionpack/lib/action_view/base.rb
  94. 171  actionpack/lib/action_view/helpers/active_record_helper.rb
  95. 230  actionpack/lib/action_view/helpers/date_helper.rb
  96. 17  actionpack/lib/action_view/helpers/debug_helper.rb
  97. 182  actionpack/lib/action_view/helpers/form_helper.rb
  98. 212  actionpack/lib/action_view/helpers/form_options_helper.rb
  99. 59  actionpack/lib/action_view/helpers/tag_helper.rb
  100. 111  actionpack/lib/action_view/helpers/text_helper.rb
  101. 78  actionpack/lib/action_view/helpers/url_helper.rb
  102. 64  actionpack/lib/action_view/partials.rb
  103. 84  actionpack/lib/action_view/template_error.rb
  104. 13  actionpack/lib/action_view/vendor/builder.rb
  105. 51  actionpack/lib/action_view/vendor/builder/blankslate.rb
  106. 143  actionpack/lib/action_view/vendor/builder/xmlbase.rb
  107. 63  actionpack/lib/action_view/vendor/builder/xmlevents.rb
  108. 288  actionpack/lib/action_view/vendor/builder/xmlmarkup.rb
  109. 9  actionpack/test/abstract_unit.rb
  110. 323  actionpack/test/controller/action_pack_assertions_test.rb
  111. 119  actionpack/test/controller/active_record_assertions_test.rb
  112. 142  actionpack/test/controller/cgi_test.rb
  113. 38  actionpack/test/controller/cookie_test.rb
  114. 159  actionpack/test/controller/filters_test.rb
  115. 69  actionpack/test/controller/flash_test.rb
  116. 110  actionpack/test/controller/helper_test.rb
  117. 49  actionpack/test/controller/layout_test.rb
  118. 44  actionpack/test/controller/redirect_test.rb
  119. 178  actionpack/test/controller/render_test.rb
  120. 68  actionpack/test/controller/send_file_test.rb
  121. 368  actionpack/test/controller/url_test.rb
  122. 5  actionpack/test/fixtures/helpers/abc_helper.rb
  123. 3  actionpack/test/fixtures/layouts/builder.rxml
  124. 1  actionpack/test/fixtures/layouts/standard.rhtml
  125. 1  actionpack/test/fixtures/scope/test/modgreet.rhtml
  126. 1  actionpack/test/fixtures/test/_customer.rhtml
  127. 1  actionpack/test/fixtures/test/greeting.rhtml
  128. 4  actionpack/test/fixtures/test/hello.rxml
  129. 1  actionpack/test/fixtures/test/hello_world.rhtml
  130. 11  actionpack/test/fixtures/test/hello_xml_world.rxml
  131. 1  actionpack/test/fixtures/test/list.rhtml
  132. 76  actionpack/test/template/active_record_helper_test.rb
  133. 104  actionpack/test/template/date_helper_test.rb
  134. 124  actionpack/test/template/form_helper_test.rb
  135. 165  actionpack/test/template/form_options_helper_test.rb
  136. 18  actionpack/test/template/tag_helper_test.rb
  137. 62  actionpack/test/template/text_helper_test.rb
  138. 49  actionpack/test/template/url_helper_test.rb
  139. 757  activerecord/CHANGELOG
  140. 20  activerecord/MIT-LICENSE
  141. 361  activerecord/README
  142. 36  activerecord/RUNNING_UNIT_TESTS
  143. 126  activerecord/Rakefile
  144. 26  activerecord/benchmarks/benchmark.rb
  145. 19  activerecord/benchmarks/mysql_benchmark.rb
  146. 14  activerecord/dev-utils/eval_debugger.rb
  147. BIN  activerecord/examples/associations.png
  148. 87  activerecord/examples/associations.rb
  149. 15  activerecord/examples/shared_setup.rb
  150. 88  activerecord/examples/validation.rb
  151. 60  activerecord/install.rb
  152. 50  activerecord/lib/active_record.rb
  153. 165  activerecord/lib/active_record/aggregations.rb
  154. 576  activerecord/lib/active_record/associations.rb
  155. 129  activerecord/lib/active_record/associations/association_collection.rb
  156. 107  activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb
  157. 102  activerecord/lib/active_record/associations/has_many_association.rb
  158. 1,051  activerecord/lib/active_record/base.rb
  159. 337  activerecord/lib/active_record/callbacks.rb
  160. 371  activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
  161. 131  activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
  162. 170  activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
  163. 105  activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
  164. 298  activerecord/lib/active_record/connection_adapters/sqlserver_adapter.rb
  165. 70  activerecord/lib/active_record/deprecated_associations.rb
  166. 208  activerecord/lib/active_record/fixtures.rb
  167. 71  activerecord/lib/active_record/observer.rb
  168. 126  activerecord/lib/active_record/reflection.rb
  169. 43  activerecord/lib/active_record/support/class_attribute_accessors.rb
  170. 37  activerecord/lib/active_record/support/class_inheritable_attributes.rb
  171. 10  activerecord/lib/active_record/support/clean_logger.rb
  172. 78  activerecord/lib/active_record/support/inflector.rb
  173. 119  activerecord/lib/active_record/transactions.rb
  174. 205  activerecord/lib/active_record/validations.rb
  175. 1,117  activerecord/lib/active_record/vendor/mysql.rb
  176. 702  activerecord/lib/active_record/vendor/simple.rb
  177. 15  activerecord/lib/active_record/wrappers/yaml_wrapper.rb
  178. 59  activerecord/lib/active_record/wrappings.rb
  179. 22  activerecord/test/abstract_unit.rb
  180. 34  activerecord/test/aggregations_test.rb
  181. 8  activerecord/test/all.sh
  182. 549  activerecord/test/associations_test.rb
  183. 544  activerecord/test/base_test.rb
  184. 33  activerecord/test/class_inheritable_attributes_test.rb
  185. 24  activerecord/test/connections/native_mysql/connection.rb
  186. 24  activerecord/test/connections/native_postgresql/connection.rb
  187. 34  activerecord/test/connections/native_sqlite/connection.rb
  188. 15  activerecord/test/connections/native_sqlserver/connection.rb
  189. 335  activerecord/test/deprecated_associations_test.rb
  190. 67  activerecord/test/finder_test.rb
  191. 8  activerecord/test/fixtures/accounts.yml
  192. 4  activerecord/test/fixtures/auto_id.rb
  193. 1  activerecord/test/fixtures/bad_fixtures/attr_with_numeric_first_char
  194. 1  activerecord/test/fixtures/bad_fixtures/attr_with_spaces
  195. 3  activerecord/test/fixtures/bad_fixtures/blank_line
  196. 3  activerecord/test/fixtures/bad_fixtures/duplicate_attributes
  197. 1  activerecord/test/fixtures/bad_fixtures/missing_value
  198. 3  activerecord/test/fixtures/column_name.rb
  199. 6  activerecord/test/fixtures/companies/first_client
  200. 4  activerecord/test/fixtures/companies/first_firm
  201. 6  activerecord/test/fixtures/companies/second_client
  202. 37  activerecord/test/fixtures/company.rb
  203. 47  activerecord/test/fixtures/company_in_module.rb
  204. 3  activerecord/test/fixtures/course.rb
  205. 2  activerecord/test/fixtures/courses/java
  206. 2  activerecord/test/fixtures/courses/ruby
  207. 30  activerecord/test/fixtures/customer.rb
  208. 6  activerecord/test/fixtures/customers/david
  209. 97  activerecord/test/fixtures/db_definitions/mysql.sql
  210. 4  activerecord/test/fixtures/db_definitions/mysql2.sql
  211. 114  activerecord/test/fixtures/db_definitions/postgresql.sql
  212. 4  activerecord/test/fixtures/db_definitions/postgresql2.sql
  213. 86  activerecord/test/fixtures/db_definitions/sqlite.sql
  214. 4  activerecord/test/fixtures/db_definitions/sqlite2.sql
  215. 96  activerecord/test/fixtures/db_definitions/sqlserver.sql
  216. 4  activerecord/test/fixtures/db_definitions/sqlserver2.sql
  217. 2  activerecord/test/fixtures/default.rb
  218. 8  activerecord/test/fixtures/developer.rb
  219. 13  activerecord/test/fixtures/developers.yml
  220. 3  activerecord/test/fixtures/developers_projects/david_action_controller
  221. 3  activerecord/test/fixtures/developers_projects/david_active_record
  222. 2  activerecord/test/fixtures/developers_projects/jamis_active_record
  223. 3  activerecord/test/fixtures/entrant.rb
  224. 3  activerecord/test/fixtures/entrants/first
  225. 3  activerecord/test/fixtures/entrants/second
  226. 3  activerecord/test/fixtures/entrants/third
  227. 5  activerecord/test/fixtures/movie.rb
  228. 2  activerecord/test/fixtures/movies/first
  229. 2  activerecord/test/fixtures/movies/second
  230. 4  activerecord/test/fixtures/project.rb
  231. 2  activerecord/test/fixtures/projects/action_controller
  232. 2  activerecord/test/fixtures/projects/active_record
  233. 21  activerecord/test/fixtures/reply.rb
  234. 5  activerecord/test/fixtures/subscriber.rb
  235. 2  activerecord/test/fixtures/subscribers/first
  236. 2  activerecord/test/fixtures/subscribers/second
  237. 20  activerecord/test/fixtures/topic.rb
  238. 9  activerecord/test/fixtures/topics/first
  239. 8  activerecord/test/fixtures/topics/second
  240. 84  activerecord/test/fixtures_test.rb
  241. 121  activerecord/test/inflector_test.rb
  242. 125  activerecord/test/inheritance_test.rb
  243. 110  activerecord/test/lifecycle_test.rb
  244. 29  activerecord/test/modules_test.rb
  245. 46  activerecord/test/multiple_db_test.rb
  246. 59  activerecord/test/pk_test.rb
  247. 78  activerecord/test/reflection_test.rb
  248. 33  activerecord/test/thread_safety_test.rb
  249. 110  activerecord/test/transactions_test.rb
  250. 24  activerecord/test/unconnected_test.rb
  251. 126  activerecord/test/validations_test.rb
  252. 265  railties/CHANGELOG
  253. 20  railties/MIT-LICENSE
  254. 121  railties/README
  255. 279  railties/Rakefile
  256. 28  railties/bin/rails
  257. 31  railties/configs/apache.conf
  258. 20  railties/configs/database.yml
  259. 7  railties/dispatches/dispatch.fcgi
  260. 10  railties/dispatches/dispatch.rb
  261. 49  railties/dispatches/dispatch.servlet
  262. 1  railties/dispatches/start_server
  263. 2  railties/doc/README_FOR_APP
  264. 3  railties/doc/apache_protection
19  actionmailer/CHANGELOG
... ...
@@ -0,0 +1,19 @@
  1
+*0.4* (5)
  2
+
  3
+* Consolidated the server configuration options into Base#server_settings= and expanded that with controls for authentication and more [Marten]
  4
+  NOTE: This is an API change that could potentially break your application if you used the old application form. Please do change!
  5
+
  6
+* Added Base#deliveries as an accessor for an array of emails sent out through that ActionMailer class when using the :test delivery option. [bitsweat]
  7
+
  8
+* Added Base#perform_deliveries= which can be set to false to turn off the actual delivery of the email through smtp or sendmail.
  9
+  This is especially useful for functional testing that shouldn't send off real emails, but still trigger delivery_* methods.
  10
+
  11
+* Added option to specify delivery method with Base#delivery_method=. Default is :smtp and :sendmail is currently the only other option.
  12
+  Sendmail is assumed to be present at "/usr/sbin/sendmail" if that option is used. [Kent Sibilev]
  13
+
  14
+* Dropped "include TMail" as it added to much baggage into the default namespace (like Version) [Chad Fowler]
  15
+
  16
+
  17
+*0.3*
  18
+
  19
+* First release
21  actionmailer/MIT-LICENSE
... ...
@@ -0,0 +1,21 @@
  1
+Copyright (c) 2004 David Heinemeier Hansson
  2
+
  3
+Permission is hereby granted, free of charge, to any person obtaining
  4
+a copy of this software and associated documentation files (the
  5
+"Software"), to deal in the Software without restriction, including
  6
+without limitation the rights to use, copy, modify, merge, publish,
  7
+distribute, sublicense, and/or sell copies of the Software, and to
  8
+permit persons to whom the Software is furnished to do so, subject to
  9
+the following conditions:
  10
+
  11
+The above copyright notice and this permission notice shall be
  12
+included in all copies or substantial portions of the Software.
  13
+
  14
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  15
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  16
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  17
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  18
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  19
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  20
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  21
+
102  actionmailer/README
... ...
@@ -0,0 +1,102 @@
  1
+= Action Mailer -- Easy email delivery and testing
  2
+
  3
+Action Mailer is framework for designing email-service layers. These layers
  4
+are used to consolidate code for sending out forgotten passwords, welcoming
  5
+wishes on signup, invoices for billing, and any other use case that requires
  6
+a written notification to either a person or another system.
  7
+
  8
+The framework works by setting up all the email details, except the body,
  9
+in methods on the service layer. Subject, recipients, sender, and timestamp
  10
+are all set up this way. An example of such a method:
  11
+
  12
+  def signed_up(recipient)
  13
+    @recipients   = recipient
  14
+    @subject      = "[Signed up] Welcome #{recipient}"
  15
+    @from         = "system@loudthinking.com"
  16
+    @sent_on      = Time.local(2004, 12, 12)
  17
+
  18
+    @body["recipient"] = recipient
  19
+  end
  20
+
  21
+The body of the email is created by using an Action View template (regular
  22
+ERb) that has the content of the @body hash available as instance variables. 
  23
+So the corresponding body template for the method above could look like this:
  24
+
  25
+  Hello there, 
  26
+
  27
+  Mr. <%= @recipient %>
  28
+  
  29
+And if the recipient was given as "david@loudthinking.com", the email 
  30
+generated would look like this:
  31
+
  32
+  Date: Sun, 12 Dec 2004 00:00:00 +0100
  33
+  From: system@loudthinking.com
  34
+  To: david@loudthinking.com
  35
+  Subject: [Signed up] Welcome david@loudthinking.com
  36
+
  37
+  Hello there, 
  38
+
  39
+  Mr. david@loudthinking.com
  40
+
  41
+You never actually call the instance methods like signed_up directly. Instead,
  42
+you call class methods like deliver_* and create_* that are automatically
  43
+created for each instance method. So if the signed_up method sat on
  44
+ApplicationMailer, it would look like this:
  45
+
  46
+  ApplicationMailer.create_signed_up("david@loudthinking.com")  # => tmail object for testing
  47
+  ApplicationMailer.deliver_signed_up("david@loudthinking.com") # sends the email
  48
+  ApplicationMailer.new.signed_up("david@loudthinking.com")     # won't work!
  49
+
  50
+
  51
+== Dependencies
  52
+
  53
+Action Mailer requires that the Action Pack is either available to be required immediately
  54
+or is accessible as a GEM.
  55
+
  56
+
  57
+== Bundled software
  58
+
  59
+* tmail 0.10.8 by Minero Aoki released under LGPL
  60
+  Read more on http://i.loveruby.net/en/prog/tmail.html
  61
+
  62
+* Text::Format 0.63 by Austin Ziegler released under OpenSource
  63
+  Read more on http://www.halostatue.ca/ruby/Text__Format.html
  64
+
  65
+
  66
+== Download
  67
+
  68
+The latest version of Action Mailer can be found at
  69
+
  70
+* http://rubyforge.org/project/showfiles.php?group_id=361
  71
+
  72
+Documentation can be found at 
  73
+
  74
+* http://actionmailer.rubyonrails.org
  75
+
  76
+
  77
+== Installation
  78
+
  79
+You can install Action Mailer with the following command.
  80
+
  81
+  % [sudo] ruby install.rb
  82
+
  83
+from its distribution directory.
  84
+
  85
+
  86
+== License
  87
+
  88
+Action Mailer is released under the MIT license.
  89
+
  90
+
  91
+== Support
  92
+
  93
+The Action Mailer homepage is http://actionmailer.rubyonrails.org. You can find
  94
+the Action Mailer RubyForge page at http://rubyforge.org/projects/actionmailer.
  95
+And as Jim from Rake says:
  96
+
  97
+   Feel free to submit commits or feature requests.  If you send a patch,
  98
+   remember to update the corresponding unit tests.  If fact, I prefer
  99
+   new feature to be submitted in the form of new unit tests.
  100
+
  101
+For other information, feel free to ask on the ruby-talk mailing list (which
  102
+is mirrored to comp.lang.ruby) or contact mailto:david@loudthinking.com.
107  actionmailer/Rakefile
... ...
@@ -0,0 +1,107 @@
  1
+require 'rubygems'
  2
+require 'rake'
  3
+require 'rake/testtask'
  4
+require 'rake/rdoctask'
  5
+require 'rake/packagetask'
  6
+require 'rake/gempackagetask'
  7
+require 'rake/contrib/rubyforgepublisher'
  8
+
  9
+PKG_BUILD     = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
  10
+PKG_NAME      = 'actionmailer'
  11
+PKG_VERSION   = '0.4.0' + PKG_BUILD
  12
+PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
  13
+
  14
+desc "Default Task"
  15
+task :default => [ :test ]
  16
+
  17
+# Run the unit tests
  18
+
  19
+Rake::TestTask.new { |t|
  20
+  t.libs << "test"
  21
+  t.pattern = 'test/*_test.rb'
  22
+  t.verbose = true
  23
+}
  24
+
  25
+
  26
+# Genereate the RDoc documentation
  27
+
  28
+Rake::RDocTask.new { |rdoc|
  29
+  rdoc.rdoc_dir = 'doc'
  30
+  rdoc.title    = "Action Mailer -- Easy email delivery and testing"
  31
+  rdoc.options << '--line-numbers --inline-source --main README'
  32
+  rdoc.rdoc_files.include('README', 'CHANGELOG')
  33
+  rdoc.rdoc_files.include('lib/action_mailer.rb')
  34
+  rdoc.rdoc_files.include('lib/action_mailer/*.rb')
  35
+}
  36
+
  37
+
  38
+# Create compressed packages
  39
+
  40
+
  41
+spec = Gem::Specification.new do |s|
  42
+  s.platform = Gem::Platform::RUBY
  43
+  s.name = PKG_NAME
  44
+  s.summary = "Service layer for easy email delivery and testing."
  45
+  s.description = %q{Makes it trivial to test and deliver emails sent from a single service layer.}
  46
+  s.version = PKG_VERSION
  47
+
  48
+  s.author = "David Heinemeier Hansson"
  49
+  s.email = "david@loudthinking.com"
  50
+  s.rubyforge_project = "actionmailer"
  51
+  s.homepage = "http://actionmailer.rubyonrails.org"
  52
+
  53
+  s.add_dependency('actionpack', '>= 0.9.5')
  54
+
  55
+  s.has_rdoc = true
  56
+  s.requirements << 'none'
  57
+  s.require_path = 'lib'
  58
+  s.autorequire = 'action_mailer'
  59
+
  60
+  s.files = [ "rakefile", "install.rb", "README", "CHANGELOG", "MIT-LICENSE" ]
  61
+  s.files = s.files + Dir.glob( "lib/**/*" ).delete_if { |item| item.include?( "CVS" ) }
  62
+  s.files = s.files + Dir.glob( "test/**/*" ).delete_if { |item| item.include?( "CVS" ) }
  63
+end
  64
+  
  65
+Rake::GemPackageTask.new(spec) do |p|
  66
+  p.gem_spec = spec
  67
+  p.need_tar = true
  68
+  p.need_zip = true
  69
+end
  70
+
  71
+
  72
+# Publish beta gem
  73
+desc "Publish the API documentation"
  74
+task :pgem => [:package] do 
  75
+  Rake::SshFilePublisher.new("davidhh@one.textdrive.com", "domains/rubyonrails.org/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
  76
+end
  77
+
  78
+# Publish documentation
  79
+desc "Publish the API documentation"
  80
+task :pdoc => [:rdoc] do 
  81
+  Rake::SshDirPublisher.new("davidhh@one.textdrive.com", "domains/rubyonrails.org/am", "doc").upload
  82
+end
  83
+
  84
+desc "Publish to RubyForge"
  85
+task :rubyforge do
  86
+    Rake::RubyForgePublisher.new('actionmailer', 'webster132').upload
  87
+end
  88
+
  89
+
  90
+desc "Count lines in the main rake file"
  91
+task :lines do
  92
+  lines = 0
  93
+  codelines = 0
  94
+  Dir.foreach("lib/action_mailer") { |file_name| 
  95
+    next unless file_name =~ /.*rb/
  96
+    
  97
+    f = File.open("lib/action_mailer/" + file_name)
  98
+
  99
+    while line = f.gets
  100
+      lines += 1
  101
+      next if line =~ /^\s*$/
  102
+      next if line =~ /^\s*#/
  103
+      codelines += 1
  104
+    end
  105
+  }
  106
+  puts "Lines #{lines}, LOC #{codelines}"
  107
+end
61  actionmailer/install.rb
... ...
@@ -0,0 +1,61 @@
  1
+require 'rbconfig'
  2
+require 'find'
  3
+require 'ftools'
  4
+
  5
+include Config
  6
+
  7
+# this was adapted from rdoc's install.rb by ways of Log4r
  8
+
  9
+$sitedir = CONFIG["sitelibdir"]
  10
+unless $sitedir
  11
+  version = CONFIG["MAJOR"] + "." + CONFIG["MINOR"]
  12
+  $libdir = File.join(CONFIG["libdir"], "ruby", version)
  13
+  $sitedir = $:.find {|x| x =~ /site_ruby/ }
  14
+  if !$sitedir
  15
+    $sitedir = File.join($libdir, "site_ruby")
  16
+  elsif $sitedir !~ Regexp.quote(version)
  17
+    $sitedir = File.join($sitedir, version)
  18
+  end
  19
+end
  20
+
  21
+makedirs = %w{ action_mailer/vendor action_mailer/vendor/text action_mailer/vendor/tmail }
  22
+makedirs.each {|f| File::makedirs(File.join($sitedir, *f.split(/\//)))}
  23
+
  24
+# deprecated files that should be removed
  25
+# deprecated = %w{ }
  26
+
  27
+# files to install in library path
  28
+files = %w-
  29
+ action_mailer.rb
  30
+ action_mailer/base.rb
  31
+ action_mailer/mail_helper.rb
  32
+ action_mailer/vendor/text/format.rb
  33
+ action_mailer/vendor/tmail.rb
  34
+ action_mailer/vendor/tmail/address.rb
  35
+ action_mailer/vendor/tmail/base64.rb
  36
+ action_mailer/vendor/tmail/config.rb
  37
+ action_mailer/vendor/tmail/encode.rb
  38
+ action_mailer/vendor/tmail/facade.rb
  39
+ action_mailer/vendor/tmail/header.rb
  40
+ action_mailer/vendor/tmail/info.rb
  41
+ action_mailer/vendor/tmail/loader.rb
  42
+ action_mailer/vendor/tmail/mail.rb
  43
+ action_mailer/vendor/tmail/mailbox.rb
  44
+ action_mailer/vendor/tmail/mbox.rb
  45
+ action_mailer/vendor/tmail/net.rb
  46
+ action_mailer/vendor/tmail/obsolete.rb
  47
+ action_mailer/vendor/tmail/parser.rb
  48
+ action_mailer/vendor/tmail/port.rb
  49
+ action_mailer/vendor/tmail/scanner.rb
  50
+ action_mailer/vendor/tmail/scanner_r.rb
  51
+ action_mailer/vendor/tmail/stringio.rb
  52
+ action_mailer/vendor/tmail/tmail.rb
  53
+ action_mailer/vendor/tmail/utils.rb
  54
+-
  55
+
  56
+# the acual gruntwork
  57
+Dir.chdir("lib")
  58
+# File::safe_unlink *deprecated.collect{|f| File.join($sitedir, f.split(/\//))}
  59
+files.each {|f| 
  60
+  File::install(f, File.join($sitedir, *f.split(/\//)), 0644, true)
  61
+}
43  actionmailer/lib/action_mailer.rb
... ...
@@ -0,0 +1,43 @@
  1
+#--
  2
+# Copyright (c) 2004 David Heinemeier Hansson
  3
+#
  4
+# Permission is hereby granted, free of charge, to any person obtaining
  5
+# a copy of this software and associated documentation files (the
  6
+# "Software"), to deal in the Software without restriction, including
  7
+# without limitation the rights to use, copy, modify, merge, publish,
  8
+# distribute, sublicense, and/or sell copies of the Software, and to
  9
+# permit persons to whom the Software is furnished to do so, subject to
  10
+# the following conditions:
  11
+#
  12
+# The above copyright notice and this permission notice shall be
  13
+# included in all copies or substantial portions of the Software.
  14
+#
  15
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  16
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  18
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  19
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  20
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  21
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22
+#++
  23
+
  24
+begin
  25
+  require 'action_controller'
  26
+rescue LoadError
  27
+  # Action Pack is not already available, try RubyGems
  28
+  require 'rubygems'	
  29
+  require_gem 'actionpack', '>= 0.9.0'
  30
+end
  31
+
  32
+$:.unshift(File.dirname(__FILE__) + "/action_mailer/vendor/")
  33
+
  34
+require 'action_mailer/base'
  35
+require 'action_mailer/mail_helper'
  36
+require 'action_mailer/vendor/tmail'
  37
+require 'net/smtp'
  38
+
  39
+ActionView::Base.class_eval { include MailHelper }
  40
+
  41
+old_verbose, $VERBOSE = $VERBOSE, nil
  42
+TMail::Encoder.const_set("MAX_LINE_LEN", 200)
  43
+$VERBOSE = old_verbose
152  actionmailer/lib/action_mailer/base.rb
... ...
@@ -0,0 +1,152 @@
  1
+module ActionMailer #:nodoc:
  2
+  # Usage:
  3
+  #
  4
+  #   class ApplicationMailer < ActionMailer::Base
  5
+  #     def post_notification(recipients, post)
  6
+  #       @recipients   = recipients
  7
+  #       @subject      = "[#{post.account.name} #{post.title}]"
  8
+  #       @body["post"] = post
  9
+  #       @from         = post.author.email_address_with_name
  10
+  #     end
  11
+  #     
  12
+  #     def comment_notification(recipient, comment)
  13
+  #       @recipients      = recipient.email_address_with_name
  14
+  #       @subject         = "[#{comment.post.project.client.firm.account.name}]" +
  15
+  #                          " Re: #{comment.post.title}"
  16
+  #       @body["comment"] = comment
  17
+  #       @from            = comment.author.email_address_with_name
  18
+  #       @sent_on         = comment.posted_on
  19
+  #     end
  20
+  #   end
  21
+  #
  22
+  #   # After this post_notification will look for "templates/application_mailer/post_notification.rhtml"
  23
+  #   ApplicationMailer.template_root = "templates"
  24
+  #  
  25
+  #   ApplicationMailer.create_comment_notification(david, hello_world)  # => a tmail object
  26
+  #   ApplicationMailer.deliver_comment_notification(david, hello_world) # sends the email
  27
+  class Base
  28
+    private_class_method :new
  29
+
  30
+    # Template root determines the base from which template references will be made.
  31
+    cattr_accessor :template_root
  32
+
  33
+    # The logger is used for generating information on the mailing run if available.
  34
+    # Can be set to nil for no logging. Compatible with both Ruby's own Logger and Log4r loggers.
  35
+    cattr_accessor :logger
  36
+
  37
+    # Allows detailed configuration of the server:
  38
+    # * <tt>:address</tt> Allows you to use a remote mail server. Just change it away from it's default "localhost" setting.
  39
+    # * <tt>:port</tt> On the off change that your mail server doesn't run on port 25, you can change it.
  40
+    # * <tt>:domain</tt> If you need to specify a HELO domain, you can do it here.
  41
+    # * <tt>:user_name</tt> If your mail server requires authentication, set the username and password in these two settings.
  42
+    # * <tt>:password</tt> If your mail server requires authentication, set the username and password in these two settings.
  43
+    # * <tt>:authentication</tt> If your mail server requires authentication, you need to specify the authentication type here. 
  44
+    #   This is a symbol and one of :plain, :login, :cram_md5
  45
+    @@server_settings = { 
  46
+      :address        => "localhost", 
  47
+      :port           => 25, 
  48
+      :domain         => 'localhost.localdomain', 
  49
+      :user_name      => nil, 
  50
+      :password       => nil, 
  51
+      :authentication => nil
  52
+    }
  53
+    cattr_accessor :server_settings
  54
+
  55
+
  56
+    # Whether or not errors should be raised if the email fails to be delivered
  57
+    @@raise_delivery_errors = true
  58
+    cattr_accessor :raise_delivery_errors
  59
+
  60
+    # Defines a delivery method. Possible values are :smtp (default), :sendmail, and :test.
  61
+    # Sendmail is assumed to be present at "/usr/sbin/sendmail".
  62
+    @@delivery_method = :smtp
  63
+    cattr_accessor :delivery_method
  64
+    
  65
+    # Determines whether deliver_* methods are actually carried out. By default they are,
  66
+    # but this can be turned off to help functional testing.
  67
+    @@perform_deliveries = true
  68
+    cattr_accessor :perform_deliveries
  69
+    
  70
+    # Keeps an array of all the emails sent out through the Action Mailer with delivery_method :test. Most useful
  71
+    # for unit and functional testing.
  72
+    @@deliveries = []
  73
+    cattr_accessor :deliveries
  74
+
  75
+    attr_accessor :recipients, :subject, :body, :from, :sent_on, :bcc, :cc
  76
+
  77
+    class << self
  78
+      def method_missing(method_symbol, *parameters)#:nodoc:
  79
+        case method_symbol.id2name
  80
+          when /^create_([_a-z]*)/
  81
+            create_from_action($1, *parameters)
  82
+          when /^deliver_([_a-z]*)/
  83
+            begin
  84
+              deliver(send("create_" + $1, *parameters))
  85
+            rescue Object => e
  86
+              raise e if raise_delivery_errors
  87
+            end
  88
+        end        
  89
+      end
  90
+
  91
+      def mail(to, subject, body, from, timestamp = nil) #:nodoc:
  92
+        deliver(create(to, subject, body, from, timestamp))
  93
+      end
  94
+
  95
+      def create(to, subject, body, from, timestamp = nil) #:nodoc:
  96
+        m = TMail::Mail.new
  97
+        m.to, m.subject, m.body, m.from = to, subject, body, from
  98
+        m.date = timestamp.respond_to?("to_time") ? timestamp.to_time : (timestamp || Time.now)    
  99
+        return m
  100
+      end
  101
+
  102
+      def deliver(mail) #:nodoc:
  103
+        logger.info "Sent mail:\n #{mail.encoded}" unless logger.nil?
  104
+        send("perform_delivery_#{delivery_method}", mail) if perform_deliveries
  105
+      end
  106
+
  107
+      private      
  108
+        def perform_delivery_smtp(mail)
  109
+          Net::SMTP.start(server_settings[:address], server_settings[:port], server_settings[:domain], 
  110
+              server_settings[:user_name], server_settings[:password], server_settings[:authentication]) do |smtp|
  111
+            smtp.sendmail(mail.encoded, mail.from_address, mail.destinations)
  112
+          end
  113
+        end
  114
+
  115
+        def perform_delivery_sendmail(mail)
  116
+          IO.popen("/usr/sbin/sendmail -i -t","w+") do |sm|
  117
+            sm.print(mail.encoded)
  118
+            sm.flush
  119
+          end
  120
+        end
  121
+
  122
+        def perform_delivery_test(mail)
  123
+          deliveries << mail
  124
+        end
  125
+
  126
+        def create_from_action(method_name, *parameters)
  127
+          mailer = new
  128
+          mailer.body = {}
  129
+          mailer.send(method_name, *parameters)
  130
+
  131
+          if String === mailer.body
  132
+            mail = create(mailer.recipients, mailer.subject, mailer.body, mailer.from, mailer.sent_on)
  133
+          else
  134
+            mail = create(mailer.recipients, mailer.subject, render_body(mailer, method_name), mailer.from, mailer.sent_on)
  135
+          end
  136
+
  137
+          mail.bcc = @bcc if @bcc
  138
+          mail.cc  = @cc  if @cc
  139
+      
  140
+          return mail
  141
+        end
  142
+  
  143
+        def render_body(mailer, method_name)
  144
+          ActionView::Base.new(template_path, mailer.body).render_file(method_name)
  145
+        end
  146
+        
  147
+        def template_path
  148
+          template_root + "/" + Inflector.underscore(self.to_s)
  149
+        end
  150
+    end
  151
+  end
  152
+end
17  actionmailer/lib/action_mailer/mail_helper.rb
... ...
@@ -0,0 +1,17 @@
  1
+require 'action_mailer/vendor/text/format'
  2
+
  3
+module MailHelper#:nodoc:
  4
+  def block_format(text)
  5
+    formatted = text.split(/\n\r\n/).collect { |paragraph| 
  6
+      Text::Format.new(
  7
+        :columns => 72, :first_indent => 2, :body_indent => 2, :text => paragraph
  8
+      ).format
  9
+    }.join("\n")
  10
+    
  11
+    # Make list points stand on their own line
  12
+    formatted.gsub!(/[ ]*([*]+) ([^*]*)/) { |s| "  #{$1} #{$2.strip}\n" }
  13
+    formatted.gsub!(/[ ]*([#]+) ([^#]*)/) { |s| "  #{$1} #{$2.strip}\n" }
  14
+
  15
+    formatted
  16
+  end
  17
+end
1,447  actionmailer/lib/action_mailer/vendor/text/format.rb
... ...
@@ -0,0 +1,1447 @@
  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
+    # = Introduction
  51
+    #
  52
+    # Text::Format provides the ability to nicely format fixed-width text with
  53
+    # knowledge of the writeable space (number of columns), margins, and
  54
+    # indentation settings.
  55
+    #
  56
+    # Copyright::   Copyright (c) 2002 - 2003 by Austin Ziegler
  57
+    # Version::     0.63
  58
+    # Based On::    Perl
  59
+    #               Text::Format[http://search.cpan.org/author/GABOR/Text-Format0.52/lib/Text/Format.pm],
  60
+    #               Copyright (c) 1998 Gábor Egressy
  61
+    # Licence::     Ruby's, Perl Artistic, or GPL version 2 (or later)
  62
+    #
  63
+  class Format
  64
+    VERSION = '0.63'
  65
+
  66
+      # Local abbreviations. More can be added with Text::Format.abbreviations
  67
+    ABBREV = [ 'Mr', 'Mrs', 'Ms', 'Jr', 'Sr' ]
  68
+
  69
+      # Formatting values
  70
+    LEFT_ALIGN  = 0
  71
+    RIGHT_ALIGN = 1
  72
+    RIGHT_FILL  = 2
  73
+    JUSTIFY     = 3
  74
+
  75
+      # Word split modes (only applies when #hard_margins is true).
  76
+    SPLIT_FIXED                     = 1
  77
+    SPLIT_CONTINUATION              = 2
  78
+    SPLIT_HYPHENATION               = 4
  79
+    SPLIT_CONTINUATION_FIXED        = SPLIT_CONTINUATION | SPLIT_FIXED
  80
+    SPLIT_HYPHENATION_FIXED         = SPLIT_HYPHENATION | SPLIT_FIXED
  81
+    SPLIT_HYPHENATION_CONTINUATION  = SPLIT_HYPHENATION | SPLIT_CONTINUATION
  82
+    SPLIT_ALL                       = SPLIT_HYPHENATION | SPLIT_CONTINUATION | SPLIT_FIXED
  83
+
  84
+      # Words forcibly split by Text::Format will be stored as split words.
  85
+      # This class represents a word forcibly split.
  86
+    class SplitWord
  87
+        # The word that was split.
  88
+      attr_reader :word
  89
+        # The first part of the word that was split.
  90
+      attr_reader :first
  91
+        # The remainder of the word that was split.
  92
+      attr_reader :rest
  93
+
  94
+      def initialize(word, first, rest) #:nodoc:
  95
+        @word = word
  96
+        @first = first
  97
+        @rest = rest
  98
+      end
  99
+    end
  100
+
  101
+  private
  102
+    LEQ_RE = /[.?!]['"]?$/
  103
+
  104
+    def brk_re(i) #:nodoc:
  105
+      %r/((?:\S+\s+){#{i}})(.+)/
  106
+    end
  107
+
  108
+    def posint(p) #:nodoc:
  109
+      p.to_i.abs
  110
+    end
  111
+
  112
+  public
  113
+      # Compares two Text::Format objects. All settings of the objects are
  114
+      # compared *except* #hyphenator. Generated results (e.g., #split_words)
  115
+      # are not compared, either.
  116
+    def ==(o)
  117
+      (@text          ==  o.text)           &&
  118
+      (@columns       ==  o.columns)        &&
  119
+      (@left_margin   ==  o.left_margin)    &&
  120
+      (@right_margin  ==  o.right_margin)   &&
  121
+      (@hard_margins  ==  o.hard_margins)   &&
  122
+      (@split_rules   ==  o.split_rules)    &&
  123
+      (@first_indent  ==  o.first_indent)   &&
  124
+      (@body_indent   ==  o.body_indent)    &&
  125
+      (@tag_text      ==  o.tag_text)       &&
  126
+      (@tabstop       ==  o.tabstop)        &&
  127
+      (@format_style  ==  o.format_style)   &&
  128
+      (@extra_space   ==  o.extra_space)    &&
  129
+      (@tag_paragraph ==  o.tag_paragraph)  &&
  130
+      (@nobreak       ==  o.nobreak)        &&
  131
+      (@abbreviations ==  o.abbreviations)  &&
  132
+      (@nobreak_regex ==  o.nobreak_regex)
  133
+    end
  134
+
  135
+      # The text to be manipulated. Note that value is optional, but if the
  136
+      # formatting functions are called without values, this text is what will
  137
+      # be formatted.
  138
+      #
  139
+      # *Default*::       <tt>[]</tt>
  140
+      # <b>Used in</b>::  All methods
  141
+    attr_accessor :text
  142
+
  143
+      # The total width of the format area. The margins, indentation, and text
  144
+      # are formatted into this space.
  145
+      #
  146
+      #                             COLUMNS
  147
+      #  <-------------------------------------------------------------->
  148
+      #  <-----------><------><---------------------------><------------>
  149
+      #   left margin  indent  text is formatted into here  right margin
  150
+      #
  151
+      # *Default*::       <tt>72</tt>
  152
+      # <b>Used in</b>::  <tt>#format</tt>, <tt>#paragraphs</tt>,
  153
+      #                   <tt>#center</tt>
  154
+    attr_reader :columns
  155
+
  156
+      # The total width of the format area. The margins, indentation, and text
  157
+      # are formatted into this space. The value provided is silently
  158
+      # converted to a positive integer.
  159
+      #
  160
+      #                             COLUMNS
  161
+      #  <-------------------------------------------------------------->
  162
+      #  <-----------><------><---------------------------><------------>
  163
+      #   left margin  indent  text is formatted into here  right margin
  164
+      #
  165
+      # *Default*::       <tt>72</tt>
  166
+      # <b>Used in</b>::  <tt>#format</tt>, <tt>#paragraphs</tt>,
  167
+      #                   <tt>#center</tt>
  168
+    def columns=(c)
  169
+      @columns = posint(c)
  170
+    end
  171
+
  172
+      # The number of spaces used for the left margin.
  173
+      #
  174
+      #                             columns
  175
+      #  <-------------------------------------------------------------->
  176
+      #  <-----------><------><---------------------------><------------>
  177
+      #   LEFT MARGIN  indent  text is formatted into here  right margin
  178
+      #
  179
+      # *Default*::       <tt>0</tt>
  180
+      # <b>Used in</b>::  <tt>#format</tt>, <tt>#paragraphs</tt>,
  181
+      #                   <tt>#center</tt>
  182
+    attr_reader :left_margin
  183
+
  184
+      # The number of spaces used for the left margin. The value provided is
  185
+      # silently converted to a positive integer value.
  186
+      #
  187
+      #                             columns
  188
+      #  <-------------------------------------------------------------->
  189
+      #  <-----------><------><---------------------------><------------>
  190
+      #   LEFT MARGIN  indent  text is formatted into here  right margin
  191
+      #
  192
+      # *Default*::       <tt>0</tt>
  193
+      # <b>Used in</b>::  <tt>#format</tt>, <tt>#paragraphs</tt>,
  194
+      #                   <tt>#center</tt>
  195
+    def left_margin=(left)
  196
+      @left_margin = posint(left)
  197
+    end
  198
+
  199
+      # The number of spaces used for the right margin.
  200
+      #
  201
+      #                             columns
  202
+      #  <-------------------------------------------------------------->
  203
+      #  <-----------><------><---------------------------><------------>
  204
+      #   left margin  indent  text is formatted into here  RIGHT MARGIN
  205
+      #
  206
+      # *Default*::       <tt>0</tt>
  207
+      # <b>Used in</b>::  <tt>#format</tt>, <tt>#paragraphs</tt>,
  208
+      #                   <tt>#center</tt>
  209
+    attr_reader :right_margin
  210
+
  211
+      # The number of spaces used for the right margin. The value provided is
  212
+      # silently converted to a positive integer value.
  213
+      #
  214
+      #                             columns
  215
+      #  <-------------------------------------------------------------->
  216
+      #  <-----------><------><---------------------------><------------>
  217
+      #   left margin  indent  text is formatted into here  RIGHT MARGIN
  218
+      #
  219
+      # *Default*::       <tt>0</tt>
  220
+      # <b>Used in</b>::  <tt>#format</tt>, <tt>#paragraphs</tt>,
  221
+      #                   <tt>#center</tt>
  222
+    def right_margin=(r)
  223
+      @right_margin = posint(r)
  224
+    end
  225
+
  226
+      # The number of spaces to indent the first line of a paragraph.
  227
+      #
  228
+      #                             columns
  229
+      #  <-------------------------------------------------------------->
  230
+      #  <-----------><------><---------------------------><------------>
  231
+      #   left margin  INDENT  text is formatted into here  right margin
  232
+      #
  233
+      # *Default*::       <tt>4</tt>
  234
+      # <b>Used in</b>::  <tt>#format</tt>, <tt>#paragraphs</tt>
  235
+    attr_reader :first_indent
  236
+
  237
+      # The number of spaces to indent the first line of a paragraph. The
  238
+      # value provided is silently converted to a positive integer value.
  239
+      #
  240
+      #                             columns
  241
+      #  <-------------------------------------------------------------->
  242
+      #  <-----------><------><---------------------------><------------>
  243
+      #   left margin  INDENT  text is formatted into here  right margin
  244
+      #
  245
+      # *Default*::       <tt>4</tt>
  246
+      # <b>Used in</b>::  <tt>#format</tt>, <tt>#paragraphs</tt>
  247
+    def first_indent=(f)
  248
+      @first_indent = posint(f)
  249
+    end
  250
+
  251
+      # The number of spaces to indent all lines after the first line of a
  252
+      # paragraph.
  253
+      #
  254
+      #                             columns
  255
+      #  <-------------------------------------------------------------->
  256
+      #  <-----------><------><---------------------------><------------>
  257
+      #   left margin  INDENT  text is formatted into here  right margin
  258
+      #
  259
+      # *Default*::       <tt>0</tt>
  260
+      # <b>Used in</b>::  <tt>#format</tt>, <tt>#paragraphs</tt>
  261
+  attr_reader :body_indent
  262
+
  263
+      # The number of spaces to indent all lines after the first line of
  264
+      # a paragraph. The value provided is silently converted to a
  265
+      # positive integer value.
  266
+      #
  267
+      #                             columns
  268
+      #  <-------------------------------------------------------------->
  269
+      #  <-----------><------><---------------------------><------------>
  270
+      #   left margin  INDENT  text is formatted into here  right margin
  271
+      #
  272
+      # *Default*::       <tt>0</tt>
  273
+      # <b>Used in</b>::  <tt>#format</tt>, <tt>#paragraphs</tt>
  274
+    def body_indent=(b)
  275
+      @body_indent = posint(b)
  276
+    end
  277
+
  278
+      # Normally, words larger than the format area will be placed on a line
  279
+      # by themselves. Setting this to +true+ will force words larger than the
  280
+      # format area to be split into one or more "words" each at most the size
  281
+      # of the format area. The first line and the original word will be
  282
+      # placed into <tt>#split_words</tt>. Note that this will cause the
  283
+      # output to look *similar* to a #format_style of JUSTIFY. (Lines will be
  284
+      # filled as much as possible.)
  285
+      #
  286
+      # *Default*::       +false+
  287
+      # <b>Used in</b>::  <tt>#format</tt>, <tt>#paragraphs</tt>
  288
+    attr_accessor :hard_margins
  289
+
  290
+      # An array of words split during formatting if #hard_margins is set to
  291
+      # +true+.
  292
+      #   #split_words << Text::Format::SplitWord.new(word, first, rest)
  293
+    attr_reader :split_words
  294
+
  295
+      # The object responsible for hyphenating. It must respond to
  296
+      # #hyphenate_to(word, size) or #hyphenate_to(word, size, formatter) and
  297
+      # return an array of the word split into two parts; if there is a
  298
+      # hyphenation mark to be applied, responsibility belongs to the
  299
+      # hyphenator object. The size is the MAXIMUM size permitted, including
  300
+      # any hyphenation marks. If the #hyphenate_to method has an arity of 3,
  301
+      # the formatter will be provided to the method. This allows the
  302
+      # hyphenator to make decisions about the hyphenation based on the
  303
+      # formatting rules.
  304
+      #
  305
+      # *Default*::       +nil+
  306
+      # <b>Used in</b>::  <tt>#format</tt>, <tt>#paragraphs</tt>
  307
+    attr_reader :hyphenator
  308
+
  309
+      # The object responsible for hyphenating. It must respond to
  310
+      # #hyphenate_to(word, size) and return an array of the word hyphenated
  311
+      # into two parts. The size is the MAXIMUM size permitted, including any
  312
+      # hyphenation marks.
  313
+      #
  314
+      # *Default*::       +nil+
  315
+      # <b>Used in</b>::  <tt>#format</tt>, <tt>#paragraphs</tt>
  316
+    def hyphenator=(h)
  317
+      raise ArgumentError, "#{h.inspect} is not a valid hyphenator." unless h.respond_to?(:hyphenate_to)
  318
+      arity = h.method(:hyphenate_to).arity
  319
+      raise ArgumentError, "#{h.inspect} must have exactly two or three arguments." unless [2, 3].include?(arity)
  320
+      @hyphenator = h
  321
+      @hyphenator_arity = arity
  322
+    end
  323
+
  324
+      # Specifies the split mode; used only when #hard_margins is set to
  325
+      # +true+. Allowable values are:
  326
+      # [+SPLIT_FIXED+]         The word will be split at the number of
  327
+      #                         characters needed, with no marking at all.
  328
+      #      repre
  329
+      #      senta
  330
+      #      ion
  331
+      # [+SPLIT_CONTINUATION+]  The word will be split at the number of
  332
+      #                         characters needed, with a C-style continuation
  333
+      #                         character. If a word is the only item on a
  334
+      #                         line and it cannot be split into an
  335
+      #                         appropriate size, SPLIT_FIXED will be used.
  336
+      #       repr\
  337
+      #       esen\
  338
+      #       tati\
  339
+      #       on
  340
+      # [+SPLIT_HYPHENATION+]   The word will be split according to the
  341
+      #                         hyphenator specified in #hyphenator. If there
  342
+      #                         is no #hyphenator specified, works like
  343
+      #                         SPLIT_CONTINUATION. The example is using
  344
+      #                         TeX::Hyphen. If a word is the only item on a
  345
+      #                         line and it cannot be split into an
  346
+      #                         appropriate size, SPLIT_CONTINUATION mode will
  347
+      #                         be used.
  348
+      #       rep-
  349
+      #       re-
  350
+      #       sen-
  351
+      #       ta-
  352
+      #       tion
  353
+      #
  354
+      # *Default*::       <tt>Text::Format::SPLIT_FIXED</tt>
  355
+      # <b>Used in</b>::  <tt>#format</tt>, <tt>#paragraphs</tt>
  356
+    attr_reader :split_rules
  357
+
  358
+      # Specifies the split mode; used only when #hard_margins is set to
  359
+      # +true+. Allowable values are:
  360
+      # [+SPLIT_FIXED+]         The word will be split at the number of
  361
+      #                         characters needed, with no marking at all.
  362
+      #      repre
  363
+      #      senta
  364
+      #      ion
  365
+      # [+SPLIT_CONTINUATION+]  The word will be split at the number of
  366
+      #                         characters needed, with a C-style continuation
  367
+      #                         character.
  368
+      #       repr\
  369
+      #       esen\
  370
+      #       tati\
  371
+      #       on
  372
+      # [+SPLIT_HYPHENATION+]   The word will be split according to the
  373
+      #                         hyphenator specified in #hyphenator. If there
  374
+      #                         is no #hyphenator specified, works like
  375
+      #                         SPLIT_CONTINUATION. The example is using
  376
+      #                         TeX::Hyphen as the #hyphenator.
  377
+      #       rep-
  378
+      #       re-
  379
+      #       sen-
  380
+      #       ta-
  381
+      #       tion
  382
+      #
  383
+      # These values can be bitwise ORed together (e.g., <tt>SPLIT_FIXED |
  384
+      # SPLIT_CONTINUATION</tt>) to provide fallback split methods. In the
  385
+      # example given, an attempt will be made to split the word using the
  386
+      # rules of SPLIT_CONTINUATION; if there is not enough room, the word
  387
+      # will be split with the rules of SPLIT_FIXED. These combinations are
  388
+      # also available as the following values:
  389
+      # * +SPLIT_CONTINUATION_FIXED+
  390
+      # * +SPLIT_HYPHENATION_FIXED+
  391
+      # * +SPLIT_HYPHENATION_CONTINUATION+
  392
+      # * +SPLIT_ALL+
  393
+      #
  394
+      # *Default*::       <tt>Text::Format::SPLIT_FIXED</tt>
  395
+      # <b>Used in</b>::  <tt>#format</tt>, <tt>#paragraphs</tt>
  396
+    def split_rules=(s)
  397
+      raise ArgumentError, "Invalid value provided for split_rules." if ((s < SPLIT_FIXED) || (s > SPLIT_ALL))
  398
+      @split_rules = s
  399
+    end
  400
+
  401
+      # Indicates whether sentence terminators should be followed by a single
  402
+      # space (+false+), or two spaces (+true+).
  403
+      #
  404
+      # *Default*::       +false+
  405
+      # <b>Used in</b>::  <tt>#format</tt>, <tt>#paragraphs</tt>
  406
+    attr_accessor :extra_space
  407
+
  408
+      # Defines the current abbreviations as an array. This is only used if
  409
+      # extra_space is turned on.
  410
+      #
  411
+      # If one is abbreviating "President" as "Pres." (abbreviations =
  412
+      # ["Pres"]), then the results of formatting will be as illustrated in
  413
+      # the table below:
  414
+      #
  415
+      #       extra_space  |  include?        |  !include?
  416
+      #         true       |  Pres. Lincoln   |  Pres.  Lincoln
  417
+      #         false      |  Pres. Lincoln   |  Pres. Lincoln
  418
+      #
  419
+      # *Default*::       <tt>{}</tt>
  420
+      # <b>Used in</b>::  <tt>#format</tt>, <tt>#paragraphs</tt>
  421
+    attr_accessor :abbreviations
  422
+
  423
+      # Indicates whether the formatting of paragraphs should be done with
  424
+      # tagged paragraphs. Useful only with <tt>#tag_text</tt>.
  425
+      #
  426
+      # *Default*::       +false+
  427
+      # <b>Used in</b>::  <tt>#format</tt>, <tt>#paragraphs</tt>
  428
+    attr_accessor :tag_paragraph
  429
+
  430
+      # The array of text to be placed before each paragraph when
  431
+      # <tt>#tag_paragraph</tt> is +true+. When <tt>#format()</tt> is called,
  432
+      # only the first element of the array is used. When <tt>#paragraphs</tt>
  433
+      # is called, then each entry in the array will be used once, with
  434
+      # corresponding paragraphs. If the tag elements are exhausted before the
  435
+      # text is exhausted, then the remaining paragraphs will not be tagged.
  436
+      # Regardless of indentation settings, a blank line will be inserted
  437
+      # between all paragraphs when <tt>#tag_paragraph</tt> is +true+.
  438
+      #
  439
+      # *Default*::       <tt>[]</tt>
  440
+      # <b>Used in</b>::  <tt>#format</tt>, <tt>#paragraphs</tt>
  441
+    attr_accessor :tag_text
  442
+
  443
+      # Indicates whether or not the non-breaking space feature should be
  444
+      # used.
  445
+      #
  446
+      # *Default*::       +false+
  447
+      # <b>Used in</b>::  <tt>#format</tt>, <tt>#paragraphs</tt>
  448
+    attr_accessor :nobreak
  449
+
  450
+      # A hash which holds the regular expressions on which spaces should not
  451
+      # be broken. The hash is set up such that the key is the first word and
  452
+      # the value is the second word.
  453
+      #
  454
+      # For example, if +nobreak_regex+ contains the following hash:
  455
+      #
  456
+      #   { '^Mrs?\.$' => '\S+$', '^\S+$' => '^(?:S|J)r\.$'}
  457
+      #