table_setter 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. data/.document +5 -0
  2. data/.gitignore +20 -0
  3. data/LICENSE +20 -0
  4. data/README +10 -0
  5. data/Rakefile +66 -0
  6. data/TODO +3 -0
  7. data/VERSION.yml +5 -0
  8. data/bin/table-setter +5 -0
  9. data/doc/TableFu/Formatting.html +178 -0
  10. data/doc/TableSetter/App.html +176 -0
  11. data/doc/TableSetter/Command.html +376 -0
  12. data/doc/TableSetter/Table.html +1813 -0
  13. data/doc/TableSetter.html +292 -0
  14. data/doc/_index.html +146 -0
  15. data/doc/class_list.html +36 -0
  16. data/doc/css/common.css +1 -0
  17. data/doc/css/full_list.css +50 -0
  18. data/doc/css/style.css +268 -0
  19. data/doc/file.README.html +68 -0
  20. data/doc/file_list.html +38 -0
  21. data/doc/frames.html +13 -0
  22. data/doc/index.html +68 -0
  23. data/doc/js/app.js +99 -0
  24. data/doc/js/full_list.js +106 -0
  25. data/doc/js/jquery.js +19 -0
  26. data/doc/method_list.html +291 -0
  27. data/doc/top-level-namespace.html +85 -0
  28. data/documentation/css/dawn.css +121 -0
  29. data/documentation/css/styles.css +63 -0
  30. data/documentation/images/folder.png +0 -0
  31. data/documentation/images/key.png +0 -0
  32. data/documentation/images/proplogo.png +0 -0
  33. data/documentation/images/publish.png +0 -0
  34. data/documentation/images/text-x-generic.png +0 -0
  35. data/documentation/index.html.erb +221 -0
  36. data/documentation/tables/example/index.html +4074 -0
  37. data/documentation/tables/example_faceted/index.html +17239 -0
  38. data/documentation/tables/example_formatted/index.html +861 -0
  39. data/documentation/tables/example_local/1/index.html +6084 -0
  40. data/documentation/tables/example_local/10/index.html +6084 -0
  41. data/documentation/tables/example_local/11/index.html +6084 -0
  42. data/documentation/tables/example_local/12/index.html +6084 -0
  43. data/documentation/tables/example_local/13/index.html +6084 -0
  44. data/documentation/tables/example_local/14/index.html +6084 -0
  45. data/documentation/tables/example_local/15/index.html +6084 -0
  46. data/documentation/tables/example_local/16/index.html +6084 -0
  47. data/documentation/tables/example_local/17/index.html +6084 -0
  48. data/documentation/tables/example_local/18/index.html +6084 -0
  49. data/documentation/tables/example_local/19/index.html +6084 -0
  50. data/documentation/tables/example_local/2/index.html +6084 -0
  51. data/documentation/tables/example_local/20/index.html +6084 -0
  52. data/documentation/tables/example_local/21/index.html +6084 -0
  53. data/documentation/tables/example_local/22/index.html +6084 -0
  54. data/documentation/tables/example_local/23/index.html +6084 -0
  55. data/documentation/tables/example_local/24/index.html +1404 -0
  56. data/documentation/tables/example_local/3/index.html +6084 -0
  57. data/documentation/tables/example_local/4/index.html +6084 -0
  58. data/documentation/tables/example_local/5/index.html +6084 -0
  59. data/documentation/tables/example_local/6/index.html +6084 -0
  60. data/documentation/tables/example_local/7/index.html +6084 -0
  61. data/documentation/tables/example_local/8/index.html +6084 -0
  62. data/documentation/tables/example_local/9/index.html +6084 -0
  63. data/documentation/tables/example_local/index.html +6084 -0
  64. data/documentation/tables/favicon.ico +0 -0
  65. data/documentation/tables/images/th_arrow_asc.gif +0 -0
  66. data/documentation/tables/images/th_arrow_desc.gif +0 -0
  67. data/documentation/tables/index.html +48 -0
  68. data/documentation/tables/javascripts/application.js +32 -0
  69. data/documentation/tables/javascripts/jquery.tablesorter.js +852 -0
  70. data/documentation/tables/javascripts/jquery.tablesorter.multipagefilter.js +111 -0
  71. data/documentation/tables/javascripts/jquery.tablesorter.pager.js +183 -0
  72. data/documentation/tables/stylesheets/stylesheet.css +67 -0
  73. data/index.html +238 -0
  74. data/lib/table_setter/app.rb +54 -0
  75. data/lib/table_setter/command.rb +139 -0
  76. data/lib/table_setter/table.rb +226 -0
  77. data/lib/table_setter.rb +32 -0
  78. data/spec/spec.opts +1 -0
  79. data/spec/spec_helper.rb +11 -0
  80. data/spec/table-setter-app_spec.rb +24 -0
  81. data/spec/table-setter_spec.rb +179 -0
  82. data/table_setter.gemspec +171 -0
  83. data/template/config.ru +33 -0
  84. data/template/public/favicon.ico +0 -0
  85. data/template/public/images/th_arrow_asc.gif +0 -0
  86. data/template/public/images/th_arrow_desc.gif +0 -0
  87. data/template/public/javascripts/application.js +32 -0
  88. data/template/public/javascripts/jquery.tablesorter.js +852 -0
  89. data/template/public/javascripts/jquery.tablesorter.multipagefilter.js +111 -0
  90. data/template/public/javascripts/jquery.tablesorter.pager.js +183 -0
  91. data/template/public/stylesheets/stylesheet.css +74 -0
  92. data/template/tables/example.yml +21 -0
  93. data/template/tables/example_faceted.yml +27 -0
  94. data/template/tables/example_formatted.csv +1 -0
  95. data/template/tables/example_formatted.yml +27 -0
  96. data/template/tables/example_local.csv +5806 -0
  97. data/template/tables/example_local.yml +27 -0
  98. data/template/views/404.erb +4 -0
  99. data/template/views/500.erb +4 -0
  100. data/template/views/index.erb +7 -0
  101. data/template/views/layout.erb +34 -0
  102. data/template/views/table.erb +78 -0
  103. metadata +240 -0
@@ -0,0 +1,63 @@
1
+ body {
2
+ font-family: Garamond, Baskerville, "Baskerville Old Face", "Hoefler Text", "Times New Roman", serif;
3
+ font-size: 16px;
4
+ line-height:20px;
5
+ width: 600px;
6
+ margin-left:auto;
7
+ margin-right:auto;
8
+ background: #efefef;
9
+ }
10
+ a.propublica{
11
+ position:absolute;
12
+ background: transparent url(../images/proplogo.png) no-repeat -40px -20px;
13
+ top: 0;
14
+ left: 0;
15
+ width: 160px;
16
+ height: 141px;
17
+ }
18
+
19
+
20
+ .dir, .file{
21
+ padding-left: 25px;
22
+ background: transparent url(../images/folder.png) no-repeat 3px 0px;
23
+ margin-top: .25em;
24
+ margin-bottom: .25em;
25
+
26
+ }
27
+
28
+ .file{
29
+ background: transparent url(../images/text-x-generic.png) no-repeat 6px 3px;
30
+ }
31
+
32
+ pre {
33
+ font-family: Monaco, Courier, monospace;
34
+ font-size: 12px;
35
+ line-height: 16px;
36
+ padding:0.5em 1em;
37
+ overflow: auto;
38
+ border-left: 4px solid #143D8D;
39
+ margin-left: 1em;
40
+ }
41
+ a {
42
+ color: #143D8D;
43
+ text-decoration: none;
44
+ font-weight: bold;
45
+ }
46
+ ul {
47
+ margin:0 1em;
48
+ padding:0;
49
+ list-style: none;
50
+ }
51
+ li {
52
+ margin:0;
53
+ padding:0;
54
+ }
55
+ strong {
56
+ font-family: Monaco, Courier, monospace;
57
+ font-weight: normal;
58
+ background: #dadee5;
59
+ border: 1px solid #aaa;
60
+ padding: 1px 2px;
61
+ font-size: 12px;
62
+
63
+ }
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,221 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
5
+ <title>TableSetter</title>
6
+ <link rel="stylesheet" type="text/css" href="documentation/css/styles.css" />
7
+ <link rel="stylesheet" type="text/css" href="documentation/css/dawn.css" />
8
+ </head>
9
+ <body>
10
+ <a href="http://www.propublica.org" class="propublica">&nbsp;</a>
11
+ <h1>TableSetter <small>&ndash; Version: <%=
12
+ config = YAML.load(File.read('VERSION.yml'))
13
+ "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
14
+ %></small></h1>
15
+ <p><a href="https://github.com/propublica/table-setter">TableSetter</a> is a Ruby app that provides an easy way to present CSVs hosted locally or remotely (e.g. on google, etc) in custom HTML. TableSetter in the wild: <a href="http://projects.propublica.org/tables/failed-banks">a list of all stimulus projects from last year</a>, <a href="http://projects.propublica.org/tables/stimulus-spending-progress">the stimulus spending progress</a>, or <a href="http://projects.propublica.org/tables/failed-banks">a list of failed banks due to the last recession</a>.</p>
16
+ <p>Each table is filterable and sortable on multiple columns. Also each column can be formatted in one of many different styles. In production mode, <strong>TableSetter</strong> provides valid expires headers and can be coupled with an upstream cache like <a href="http://rtomayko.github.com/rack-cache/">Rack::Cache</a> or varnish for speedy presentation.</p>
17
+ <h2><a id="toc">Table of Contents</a></h2>
18
+ <ul>
19
+ <li><a href="#installation">Installation</a></li>
20
+ <li><a href="#tablesetter">The table-setter command</a></li>
21
+ <li><a href="#thedirectory">The Configuration Directory</a></li>
22
+ <li><a href="#thefile">A TableSetter File</a></li>
23
+ <li><a href="#deployment">Deployment</a></li>
24
+ <li><a href="#rails">Rails</a></li>
25
+ <li><a href="#links">Links</a></li>
26
+ <li><a href="#credits">Credits</a></li>
27
+ <li><a href="#license">License</a></li>
28
+ </ul>
29
+ <h2><a id="installation" href="#toc">Installation</a></h2>
30
+ <p>Install <strong>TableSetter</strong> through rubygems:</p>
31
+ <pre class="dawn">
32
+ gem install table_setter</pre>
33
+ <p>or from the source files:</p>
34
+ <pre class="dawn">
35
+ git clone git://github.com/propublica/table-setter.git
36
+ cd table-setter
37
+ rake install</pre>
38
+ <p>After you've installed the gem you'll have a new executable: <strong>table-setter</strong>. You can view the subcommands available by typing <strong>table-setter --help</strong>. To set things up you'll need to run it with the <strong>install</strong> command to install the configuration files and ERB templates into a directory. </p>
39
+ <pre>
40
+ table-setter install path/to/directory</pre>
41
+ <p>
42
+ To start the development server run:
43
+ </p>
44
+ <pre>
45
+ table-setter start path/to/directory</pre>
46
+ <p>Go to development url, <a href="http://localhost:3000/">http://localhost:3000/</a> and you'll see a list of the example tables. You can peruse the examples <a href="http://propublica.github.com/table-setter/documentation/tables/">here</a>.</p>
47
+ <h2><a id="tablesetter" href="#toc">The table-setter command</a></h2>
48
+ <p>
49
+ The <strong>table-setter</strong> command responds to three subcommands:
50
+ <ul>
51
+ <li><strong>install &lt;DIRECTORY&gt;</strong> installs the tablesetter files into the current directory or one you specify.</li>
52
+ <li><strong>start &lt;DIRECTORY&gt;</strong> starts the development server so you can preview your tables before deploying.</li>
53
+ <li><strong>build &lt;DIRECTORY&gt; -p &lt;PATH&gt;</strong> builds a static version of the tables, <strong>&lt;PATH&gt;</strong> is the relative path where you want to place the tables on your webserver.
54
+ See <a href="#deployment">Deployment</a></li>
55
+ </ul>
56
+ </p>
57
+ <h2><a id="thedirectory" href="#toc">The Configuration Directory</a></h2>
58
+ <p>
59
+ The configuration folder contains the javascripts, stylesheets, view templates (written in <a href="http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/">ERB</a>), rackup file, and most importantly the configuration files for each table.
60
+ </p>
61
+ <p>You'll put table definition files in the <strong>table</strong> directory, your javascript in <strong>public/javascripts</strong> and css in <strong>public/stylesheets</strong>. You can make most HTML customizations in <strong>views/layout.erb</strong>.
62
+ <p class="file">
63
+ The <strong>config.ru</strong> file is a rackup file that instructs the webserver to start the <strong>TableSetter</strong> application and serve the assets contained in the configuration folder. In most cases you'll want to use apache and passenger (see <a href="#deployment">Deployment</a> for details).
64
+ </p>
65
+ <p class="dir">
66
+ In <strong>public</strong> you'll find the static assets required for the look and feel and functionality of the table:
67
+ </p>
68
+ <ul>
69
+ <li class="dir"> The <strong>images</strong> directory contains the small images <img src="template/public/images/th_arrow_asc.gif" style="display:inline"> and <img src="template/public/images/th_arrow_desc.gif" style="display:inline"> which show the user the sorting direction of a given column.</li>
70
+ <li class="dir"> The <strong>javascripts</strong> directory contains scripts that power the dynamic functionality of a table. Each file depends on <a href="http://jquery.com/">jQuery</a>:
71
+ <ul>
72
+ <li class="file"><strong>application.js</strong> dispatches to the other javascript files to render the table at load time. It also defines the column highlighting function.</li>
73
+ <li class="file"><strong>jquery.tablesorter.js</strong> the jQuery <a href="http://tablesorter.com/docs/">tablesorter plugin</a> that handles the dynamic sorting by column.</li>
74
+ <li class="file"><strong>jquery.tablesorter.pager.js</strong> the <a href="http://tablesorter.com/docs/example-pager.html">tablesorter pager plugin</a> to tablesorter that provides the paging functionality.</li>
75
+ <li class="file"><strong>jquery.tablesorter.multipagefilter.js</strong> a custom plugin that allows for searching across multiple pages</li>
76
+ </ul>
77
+ </li>
78
+ <li class="dir">The <strong>stylesheets</strong> directory contains <strong>application.css</strong>, the <strong>TableSetter</strong> stylesheet. Each style is prefaced with <strong>#tablefu</strong> so you should be able to include your organization's css on the page without affecting the tables.</li>
79
+ </ul>
80
+ <p class="dir">The <strong>tables</strong> directory contains yml configuration files for each of the tables you want to deploy. By default it contains:</p>
81
+ <ul>
82
+ <li class="file"><strong>example.yml</strong> contains most of the simple options in a <strong>TableSetter</strong> file.</li>
83
+ <li class="file"><strong>example_local.yml</strong> and <strong>example_local.csv</strong> shows how to build a table from a local file. It also is hard_paginated (see <a href="#thefile">A Table Setter File</a>).</li>
84
+ <li class="file"><strong>example_faceted.yml</strong> is an example of faceting.</li>
85
+ <li class="file"><strong>example_formatted.yml</strong> and <strong>example_formatted.csv</strong> shows how to apply formatting to a column and a group of columns.</li>
86
+ </ul>
87
+ <p class="dir">The <strong>views</strong> directory contains the <a href="http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/">ERB</a> templates needed to render the table pages and index page.</p>
88
+ <ul>
89
+ <li class="file">
90
+ <strong>404.erb</strong> and <strong>500.erb</strong> render when a table is not found or a server error occurs, respectively.
91
+ </li>
92
+ <li class="file"><strong>layout.erb</strong> contains the basic frame of the page. You should place most of your customizations here. If you'd like to add custom html, place it above or below the <strong>&lt;%=&nbsp;yield&nbsp;%&gt;</strong> tag.</li>
93
+ <li class="file"><strong>index.erb</strong> renders the table list for the root path of the app.</li>
94
+ <li class="file"><strong>table.erb</strong> renders an individual table. You shouldn't have to tweak this much, if at all.</li>
95
+ </ul>
96
+ <h2><a id="thefile" href="#toc">A TableSetter File</a></h2>
97
+ <p>Each TableSetter file is written in <a href="http://www.yaml.org/">YAML</a> and outlines the the display options for a particular table. The filename dictates the path where it will appear (e.g. a config file named example.yml will appear at <strong>http://host/example</strong>). Initially TableSetter installs a few examples to get you started (see <a href="#thedirectory">above</a>).</p>
98
+ <p>Each table setter file must begin with a <strong>table:</strong> declaration, and it's important to note that whitespace matters. For example consider this csv:</p>
99
+ <pre>
100
+ Bank,Spent,Funds,Link
101
+ McDuck Bank,100000,10000000,http://diveintomoney.com
102
+ Potter Savings and Loans,1100,1000000,http://angelsandwingsmrstewart.com
103
+ </pre>
104
+ <p>these are the example options in a <strong>TableSetter</strong> config file:
105
+ <pre>
106
+ table:
107
+ title: The title of the table
108
+
109
+ # google_key:, file:, or url: define how a table is loaded.
110
+ # only one is necessary
111
+ file: loads a local CSV file from the /tables directory.
112
+ url: will load a CSV file from an external server, and
113
+ google_key: is a google key url from an external google doc (see note).
114
+
115
+ deck: A HTML string describing the table, appears above the table itself.
116
+
117
+ footer: A HTML string for notes/caveats etc. Appears below the table.
118
+
119
+ column_options: # Defines a hash of options that are passed onto TableFu
120
+
121
+ columns: # A list of columns to include, for example:
122
+ - Bank # would only include the bank column in the table
123
+
124
+ style: # A list of style declarations by column, for example:
125
+ Bank: 'text-align:left;' # would left-align the text in the "Bank" column.
126
+
127
+ sorted_by: # Defines the sort order and column to sort by of the table.
128
+ Bank: ascending # would sort by the Bank column in ascending order
129
+
130
+ total: # Declares which columns should have a totals row.
131
+ ['Funds', 'Spent']
132
+
133
+ formatting: # Defines which of the TableFu formatters to apply to a column.
134
+ (%) Spent: bar # applies the bar formatter to the '(%) Spent' column.
135
+ Link: # Creates a meta column form two other columns
136
+ method: link # describes the formatter to use
137
+ arguments: ['Bank', 'URL'] # Combines Bank and URL as arguments
138
+
139
+ faceting: # Describes the faceting, or grouping, to apply to a table
140
+ facet_by: Bank # groups the records by bank name
141
+
142
+ hard_paginate: true # Dictates that the table should be spread across multiple pages
143
+ # can't be used with faceting, and disables the user filtering
144
+
145
+ per_page: 250 # Instructs TableSetter to only page by 250 rows.
146
+
147
+ live: true # publishes the table in the index page. Note that even if live is
148
+ # set to false the table is still accessible directly.
149
+
150
+ </pre>
151
+
152
+ <h3>NB: A Note About google_key</h3>
153
+ <p>At ProPublica, we mainly use TableSetter to format public google spreadsheets. You can find the <strong>google_key</strong> by publishing a spreadsheet as a webpage:</p>
154
+ <img src="documentation/images/publish.png">
155
+ <p>and in the dialog box, the google key is here:</p>
156
+ <img src="documentation/images/key.png">
157
+ <h2><a id="deployment" href="#toc">Deployment</a></h2>
158
+
159
+ <h3>Passenger</h3>
160
+ <em>(Cribbed from the excellent <a href="http://www.modrails.com/documentation/Users%20guide.html#_deploying_a_rack_based_ruby_application">passenger documentation</a>.)</em>
161
+ <p>If you're familiar with deploying a Rails application under passenger, not much changes when deploying a rack basked application. <strong>TableSetter</strong> includes a <strong>config.ru</strong> file that should be sufficient under most situations. You'll need to create a <strong>tmp</strong> directory inside the <strong>TableSetter</strong> directory on the server. The following virtual host configuration will deploy <strong>TableSetter</strong> directory:
162
+ </p>
163
+ <pre>
164
+ &lt;VirtualHost *:80&gt;
165
+ ServerName www.yourdomain.com
166
+ DocumentRoot /path/to/table-setter/public
167
+ &lt;/VirtualHost&gt;</pre>
168
+ <p>If you want to deploy <strong>TableSetter</strong> under a sub URI you should symlink the public folder to a directory in the document root:</p>
169
+ <pre>
170
+ ln -s /path/to/table-setter/public /docroot/tables</pre>
171
+ <p>
172
+ and change you're apache config to reflect the sub URI:
173
+ </p>
174
+ <pre>
175
+ &lt;VirtualHost *:80&gt;
176
+ ServerName www.yourdomain.com
177
+ DocumentRoot /docroot/tables
178
+ RackBaseURI /tables
179
+ &lt;/VirtualHost&gt;</pre>
180
+ <h3>Caching</h3>
181
+ <p>You probably don't want to parse a remote CSV file on every request in production, so the <strong>config.ru</strong> file contains directives to enable <strong>Rack:Cache</strong> a simple reverse proxy cache. If your web server is not behind an upstream cache you'll want to enable it by uncommenting the required lines.<p>
182
+ <p>You'll also want to enable the <strong>TableSetter:App</strong> expire time by uncommenting this line:</p>
183
+ <pre>
184
+ TableSetter::App.cache_timeout = 60 * 15 # 15 minutes</pre>
185
+ <p>That line dictates the max age of a request and you'll want to tweak it depending on how frequently changed your tables will be and how many users you expect. If you want to define any <a href="https://github.com/propublica/table-fu">TableFu</a> formatters you should do so in <strong>config.ru</strong>.</p>
186
+
187
+ <h3>Static</h3>
188
+ <p>You can also use to pre-build <strong>table-setter</strong> your tables as html and upload the built files to your web server. You can build them using the <strong>table-setter</strong> command:</p>
189
+ <pre>
190
+ table-setter build path/to/table-setter/directory -p path</pre>
191
+ <p>The build tables will be placed in the <strong>out</strong> directory inside the configuration directory.</p>
192
+ <p>The <strong>-p</strong> flag dictates where on the server relative to root you'll install the files. If I want my tables to appear under the <strong>tables/</strong> directory on my site, I'd run:</p>
193
+ <pre>
194
+ table-setter build path/to/table-setter/directory -p tables</pre>
195
+ <p>And upload the files in the <strong>out/tables</strong> directory.</p>
196
+ <h2><a id="rails" href="#toc">Rails</a></h2>
197
+ <p>In order to use table-setter as a Rails, you'll need to install the <a href="http://github.com/propublica/table-setter-generator">table-setter-generator </a> gem. Once you've done that you'll be able to run:</p>
198
+ <pre>
199
+ script/generate table-setter</pre>
200
+ <p>In your existing Rails app path and it will install the <strong>TableSetter</strong> routes, controller, views, and <strong>Table</strong> model.</p>
201
+ <h2><a id="links" href="#toc">Links</a></h2>
202
+ <ul>
203
+ <li><a href="http://github.com/propublica/table-fu">TableFu</a><br>
204
+ A gem that provides the conceptual backend to <strong>TableSetter</strong>.</li>
205
+ <li><a href="http://www.modrails.com/documentation/Users%20guide.html#_deploying_a_rack_based_ruby_application">Passenger Documentation</a><br>
206
+ The Passenger Documention section on how to deploy a rack app under passenger.</li>
207
+ <li><a href="http://docs.heroku.com/rack">Heroku Documentation</a><br>
208
+ How to deploy a rack app in heroku.</li>
209
+ <li><a href="http://github.com/propublica/table-fu/issues">Issues</a><br>
210
+ The github issue tracker. Post bug reports and feature requests here.</li>
211
+ <li><a href="http://www.yaml.org/">YAML</a>
212
+ The YAML homepage. <strong>TableSetter</strong> config files are YAML files.
213
+ </li>
214
+ <li><a href="doc/index.html">API Docs</a></li>
215
+ </ul>
216
+ <h2><a id="credits" href="#toc">Credits</a></h2>
217
+ <p><a href="http://github.com/thejefflarson">Jeff Larson</a> (Maintainer), <a href="http://github.com/brianboyer/">Brian Boyer</a>, <a href="http://github.com/kleinmatic">Scott Klein</a>, <a href="http://github.com/markpercival">Mark Percival</a>, and <a href="http://github.com/seebq">Charles Brian Quinn</a>.</p>
218
+ <h2><a id="license" href="#toc">License</a></h2>
219
+ <pre><%= File.open("LICENSE").read %></pre>
220
+ </body>
221
+ </html>