emerald 0.0.1.alpha3 → 0.0.1.alpha4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,140 @@
1
+ = Legal stuff
2
+
3
+ Emerald uses some code from RDoc (currently maintained by Eric Hodel)
4
+ and it’s Darkfish generator (written by Michael Granger) as well as
5
+ some of Darkfish’s iconset, which in turn was taken from the Silk
6
+ iconset by Mark James. See below for all those copying conditions.
7
+
8
+ For Emerald’s own licensing conditions, see the file COPYING.rdoc.
9
+
10
+ == RDoc license
11
+
12
+ RDoc is copyrighted free software.
13
+
14
+ You can redistribute it and/or modify it under either the terms of the GPL
15
+ version 2 (see the file GPL), or the conditions below:
16
+
17
+ 1. You may make and give away verbatim copies of the source form of the
18
+ software without restriction, provided that you duplicate all of the
19
+ original copyright notices and associated disclaimers.
20
+
21
+ 2. You may modify your copy of the software in any way, provided that
22
+ you do at least ONE of the following:
23
+
24
+ a. place your modifications in the Public Domain or otherwise
25
+ make them Freely Available, such as by posting said
26
+ modifications to Usenet or an equivalent medium, or by allowing
27
+ the author to include your modifications in the software.
28
+
29
+ b. use the modified software only within your corporation or
30
+ organization.
31
+
32
+ c. give non-standard binaries non-standard names, with
33
+ instructions on where to get the original software distribution.
34
+
35
+ d. make other distribution arrangements with the author.
36
+
37
+ 3. You may distribute the software in object code or binary form,
38
+ provided that you do at least ONE of the following:
39
+
40
+ a. distribute the binaries and library files of the software,
41
+ together with instructions (in the manual page or equivalent)
42
+ on where to get the original distribution.
43
+
44
+ b. accompany the distribution with the machine-readable source of
45
+ the software.
46
+
47
+ c. give non-standard binaries non-standard names, with
48
+ instructions on where to get the original software distribution.
49
+
50
+ d. make other distribution arrangements with the author.
51
+
52
+ 4. You may modify and include the part of the software into any other
53
+ software (possibly commercial). But some files in the distribution
54
+ are not written by the author, so that they are not under these terms.
55
+
56
+ For the list of those files and their copying conditions, see the
57
+ file LEGAL[http://rdoc.rubyforge.org/LEGAL_rdoc.html].
58
+
59
+ 5. The scripts and library files supplied as input to or produced as
60
+ output from the software do not automatically fall under the
61
+ copyright of the software, but belong to whomever generated them,
62
+ and may be sold commercially, and may be aggregated with this
63
+ software.
64
+
65
+ 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
66
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
67
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
68
+ PURPOSE.
69
+
70
+ == Darkfish license
71
+
72
+ Darkfish was written by Michael Granger and is included under the MIT
73
+ license. Darkfish contains images from the Silk Icons set by Mark
74
+ James.
75
+
76
+ === Author/s
77
+ * Michael Granger (ged@FaerieMUD.org)
78
+
79
+ === Contributors
80
+ * Mahlon E. Smith (mahlon@martini.nu)
81
+ * Eric Hodel (drbrain@segment7.net)
82
+
83
+ === License
84
+
85
+ Copyright (c) 2007, 2008, Michael Granger. All rights reserved.
86
+
87
+ Redistribution and use in source and binary forms, with or without
88
+ modification, are permitted provided that the following conditions are met:
89
+
90
+ * Redistributions of source code must retain the above copyright notice,
91
+ this list of conditions and the following disclaimer.
92
+
93
+ * Redistributions in binary form must reproduce the above copyright notice,
94
+ this list of conditions and the following disclaimer in the documentation
95
+ and/or other materials provided with the distribution.
96
+
97
+ * Neither the name of the author/s, nor the names of the project's
98
+ contributors may be used to endorse or promote products derived from this
99
+ software without specific prior written permission.
100
+
101
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
102
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
103
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
104
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
105
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
106
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
107
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
108
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
109
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
110
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
111
+
112
+ === Attributions
113
+
114
+ Darkfish uses the {Silk Icons}[http://www.famfamfam.com/lab/icons/silk/] set
115
+ by Mark James.
116
+
117
+ == jQuery license
118
+
119
+ Copyright 2012 jQuery Foundation and other contributors
120
+
121
+ http://jquery.com/
122
+
123
+ Permission is hereby granted, free of charge, to any person obtaining
124
+ a copy of this software and associated documentation files (the
125
+ "Software"), to deal in the Software without restriction, including
126
+ without limitation the rights to use, copy, modify, merge, publish,
127
+ distribute, sublicense, and/or sell copies of the Software, and to
128
+ permit persons to whom the Software is furnished to do so, subject to
129
+ the following conditions:
130
+
131
+ The above copyright notice and this permission notice shall be
132
+ included in all copies or substantial portions of the Software.
133
+
134
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
135
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
136
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
137
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
138
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
139
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
140
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,119 @@
1
+ = Emerald -- Make your Ruby documentation a jewel, too
2
+
3
+ You think Darkfish is the worst RDoc generator ever? Got lost in SDoc
4
+ and Horo documentations? Found Hanna buggy and dislike frames? Then
5
+ this is for you: Emerald, the only RDoc template which makes your Ruby
6
+ docs a jewel, too.
7
+
8
+ Emerald is a generator for RDoc[http://rdoc.rubyforge.org], i.e. a
9
+ plugin that replaces RDoc’s standard _Darkfish_ generator from which
10
+ many people (myself included) think it’s the ugliest RDoc layouting
11
+ engine that ever was around. If you want nice and modern documentation
12
+ that allows you to retain overview over a library, Emerald is the
13
+ generator you want to use.
14
+
15
+ == Installation
16
+
17
+ Emerald is currently Alpha software. Use it at your own risk.
18
+
19
+ Get the current development release via RubyGems:
20
+
21
+ # gem install emerald --pre
22
+
23
+ If you want the latest version, check out the Git repisitory and build
24
+ the gem yourself:
25
+
26
+ $ git clone git://github.com/Quintus/emerald
27
+ $ cd emarald
28
+ $ rake gem
29
+ $ gem install pkg/emerald-x.x.x.gem
30
+
31
+ == Usage
32
+
33
+ From the commandline:
34
+
35
+ $ rdoc -f emerald YOURFILESHERE
36
+
37
+ From a rake RDoc::Task:
38
+
39
+ require "rdoc/task"
40
+ require "rdoc/generator/emerald"
41
+
42
+ RDoc::Task.new do |rt|
43
+ # Your option stuff...
44
+ rt.generator = "emerald"
45
+ end
46
+
47
+ == Features
48
+
49
+ * Default theme has is centered around light blue/grey, just as Hanna was.
50
+ * No frames.
51
+ * Uses jQuery[http://jquery.com].
52
+ * Generates a Table of Contents (ToC) for toplevel file docs (so yes,
53
+ your README will have a ToC).
54
+ * Classical file/class/method indices for best overview.
55
+ * Regular-Expression-powered JavaScript search.
56
+ * Darkfish-link compatible, i.e. if you switch to Emerald from Darkfish,
57
+ the old links to your documentation will still work.
58
+ * But note this is not the case for the other way round, as Emerald
59
+ allows you linking to more stuff.
60
+ * GPL’ed. Free software.
61
+ * And more...
62
+
63
+ == Weblinks
64
+
65
+ * Sourcecode: https://github.com/Quintus/emerald
66
+ * Bugtracker: https://github.com/Quintus/emerald/issues
67
+
68
+ == Caveats
69
+
70
+ * ToC generation only works for proper heading nestings, especially it
71
+ assumes your page to have <b>exactly one</b> level-1 heading. Having more
72
+ of these is bad style, and Emerald wants to encourage good
73
+ documentation/markup style.
74
+ * The search uses JavaScript’s regular expressions, so the quite
75
+ advanced constructs you can create with Ruby’s Regular Expressions
76
+ won’t work with all cases. But don’t tell me you search your API
77
+ documentation with constructs like <tt>\A(?>[^ab]q)\s*%.*stuff(?<!badstuff)\w{2,4}(?:$|\\\\)</tt>.
78
+ * Emerald is a bit slow at the moment. However, I did not optimise it
79
+ for speed. This may or may not change in the future.
80
+
81
+ == Thanks
82
+
83
+ Thanks to Eric Hodel keeping RDoc in an active and alive
84
+ state. Without this, there would be no point in developing
85
+ Emerald. Next my gratitude is dedicated at {Mislav
86
+ Marohnić}[https://github.com/mislav] for creating the {Hanna RDoc
87
+ template}[https://github.com/mislav/hanna], which sadly is not
88
+ maintained anymore, but was a big inspiration for Emerald and its
89
+ default theme, and to everyone on the web who posted something on
90
+ RDoc’s internals. Without you, it wouldn’t have been possible to get
91
+ Emerald to where it currently is.
92
+
93
+ == License
94
+
95
+ Emerald is an RDoc HTML generator.
96
+
97
+ Copyright © 2012 Marvin Gülker
98
+
99
+ This program is free software: you can redistribute it and/or modify
100
+ it under the terms of the GNU General Public License as published by
101
+ the Free Software Foundation, either version 3 of the License, or
102
+ (at your option) any later version.
103
+
104
+ This program is distributed in the hope that it will be useful,
105
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
106
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
107
+ GNU General Public License for more details.
108
+
109
+ You should have received a copy of the GNU General Public License
110
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
111
+
112
+ === Additional notes
113
+
114
+ * You can find the GNU GPL in the file COPYING.rdoc.
115
+ * This project incorporates some code and data (mainly images) from
116
+ RDoc and the projects RDoc in turn uses stuff from. See the file
117
+ LEGAL.rdoc for more information. Same goes for the jQuery licensing
118
+ conditions.
119
+ * You can contact me at quintus ÄT quintilianus DÖT eu.
@@ -0,0 +1,4 @@
1
+ # Discovery file for RDoc to recognise this
2
+ # generator.
3
+
4
+ require_relative "generator/emerald"
@@ -0,0 +1,304 @@
1
+ # -*- coding: utf-8 -*-
2
+ gem "rdoc"
3
+
4
+ require "pathname"
5
+ require "fileutils"
6
+ require "erb"
7
+ require "rdoc/rdoc"
8
+ require "rdoc/generator"
9
+
10
+ # This is the main generator class that is instanciated by RDoc when
11
+ # you order it to use the _emerald_ generator. It mainly works on
12
+ # ERB template files you can find in the <b>data/templates</b> directory,
13
+ # where each major component (read: classes and toplevel files) has a
14
+ # template file that is evaluated for it. The result is then injected
15
+ # into the layout template, <b>data/templates/layout.html.erb</b>, which
16
+ # is then evaluated as well.
17
+ #
18
+ # == About relative paths
19
+ # As the output generated by RDoc is supposed to be viewable by both
20
+ # visiting the doc/ directory with a browser and providing the doc/
21
+ # directory to an HTTP server, effectively making it the root directory,
22
+ # care has been taken to only use relative links in all the static HTML
23
+ # files. The key component for this to work is the #root_path method,
24
+ # which is called to set the relative path to the root directory (i.e.
25
+ # the output directory). When called without an argument, #root_path
26
+ # returns the value previously remembered (usually it contains a good
27
+ # number of <b>../</b> entries). This way, the root directory can be
28
+ # set whenever a new HTML file is going to be outputted and can then
29
+ # be referenced from the ERB template.
30
+ #
31
+ # == Darkfish compatibility
32
+ # RDoc’s HTML formatter has a good number of helper methods that
33
+ # have a strong hint regarding "where what belongs". By using these
34
+ # helper methods itself when creating cross-references, the HTML
35
+ # formatter enforces both the directory structure of the output
36
+ # directory and the anchor names used for references inside a single
37
+ # HTML file. The only way to circumvent this is to write another
38
+ # formatter, which I don’t intend to as the standard HTML formatter
39
+ # does a good job for HTML stuff. A nice side effect is that Emerald’s
40
+ # documentation is compatible with Darkfish’s one when it comes to links
41
+ # to specific elements. For example, you can create a link to a method
42
+ # called Foo::Bar#baz somewhere on the web, and if the destinatinon
43
+ # website chooses to switch from Darkfish output to Emerald (which I
44
+ # hope!), the link will continue to work.
45
+ class RDoc::Generator::Emerald
46
+ include FileUtils
47
+
48
+ # Generic exception class for this generator.
49
+ class EmeraldError < StandardError
50
+ end
51
+
52
+ # Minimal RDoc::Toplevel-alike object (i.e. it responds to the
53
+ # two methods required for rendering it, +full_name+ and
54
+ # +description+) that is used to create the index page if
55
+ # none was set. I really recommend to manually set a
56
+ # useful index page!
57
+ DummyStartPage = Struct.new(:full_name, :description) do
58
+ def initialize
59
+ super()
60
+ self.full_name = "Start page"
61
+ self.description =<<-DESC
62
+ <h1>RDoc documentation</h1>
63
+ <p>This is a dummy start page for the RDoc documentation of this project.</p>
64
+ <p>You’re seeing it, because the original author didn’t specify a real start
65
+ page for this project’s documentation, so you may want to contact him and
66
+ make him aware of this.</p>
67
+ <p>If you <em>are</em> the original author, try one or both of the following
68
+ code snippets to make your <strong>README.rdoc</strong> file the start
69
+ page of your documentation:</p>
70
+ <pre>
71
+ # In your gemspec:
72
+ Gem::Specification.new do |spec|
73
+ # ...
74
+ # "-m" sets the start ("main") page. "-t" specifies
75
+ # the title to display in the window title bar.
76
+ spec.rdoc_options << "-m" << "README.rdoc" << "-t" "Docs for YourProject"
77
+ end
78
+
79
+ # In your Rakefile:
80
+ RDoc::Task.new do |rt|
81
+ # ...
82
+ # Sets the start ("main") page and specifies the
83
+ # title to display in the window title bar:
84
+ rt.main = "README.rdoc"
85
+ rt.title = "Docs for YourProject"
86
+ end
87
+ </pre>
88
+ <p>For the time being, use the navigation sidebar to the left
89
+ in order to read this documentation.</p>
90
+ DESC
91
+ end
92
+ end
93
+
94
+ # Tell RDoc about the new generator
95
+ RDoc::RDoc.add_generator(self)
96
+
97
+ # Description displayed in RDoc’s help.
98
+ DESCRIPTION = "The only RDoc generator that makes your Ruby documentation a jewel, too"
99
+
100
+ # Root directory of this project.
101
+ ROOT_DIR = Pathname.new(__FILE__).dirname.parent.parent.parent
102
+
103
+ # Where to find the non-code stuff.
104
+ DATA_DIR = ROOT_DIR + "data"
105
+
106
+ # Main template used as the general layout.
107
+ LAYOUT_TEMPLATE = ERB.new(File.read(DATA_DIR + "templates" + "layout.html.erb"))
108
+
109
+ # Subtemplates injected into the main template.
110
+ TEMPLATES = {
111
+ :toplevel => ERB.new(File.read(DATA_DIR + "templates" + "toplevel.html.erb")),
112
+ :classmodule => ERB.new(File.read(DATA_DIR + "templates" + "classmodule.html.erb"))
113
+ }
114
+
115
+ # The version number.
116
+ VERSION = File.read(ROOT_DIR + "VERSION").chomp.freeze
117
+
118
+ # Add additional options to RDoc (see the
119
+ # RDoc::Generator::Emerald::Options module).
120
+ def self.setup_options(options)
121
+ options.extend(RDoc::Generator::Emerald::Options)
122
+ end
123
+
124
+ # Instanciates this generator. Automatically called
125
+ # by RDoc.
126
+ # ==Parameter
127
+ # [options]
128
+ # RDoc passed the current RDoc::Options instance.
129
+ def initialize(options)
130
+ @options = options
131
+ @op_dir = Pathname.pwd.expand_path + @options.op_dir
132
+ end
133
+
134
+ # Outputs a string on standard output, but only if RDoc
135
+ # was invoked with the <tt>--debug</tt> switch.
136
+ def debug(str)
137
+ puts(str) if $DEBUG_RDOC
138
+ end
139
+
140
+ # Main hook method called by RDoc, triggers the generation process.
141
+ def generate(top_levels)
142
+ debug "Sorting classes, modules, and methods..."
143
+ @toplevels = top_levels
144
+ @classes_and_modules = RDoc::TopLevel.all_classes_and_modules.sort_by{|klass| klass.full_name}
145
+ @methods = @classes_and_modules.map{|mod| mod.method_list}.flatten.sort
146
+
147
+ # Create the output directory
148
+ mkdir @op_dir unless @op_dir.exist?
149
+
150
+ copy_base_files
151
+ evaluate_toplevels
152
+ evaluate_classes_and_modules
153
+
154
+ unless @options.main_page # If set, #evaluate_toplevels creates the index.html for us
155
+ toplevel = DummyStartPage.new
156
+ root_path "./" # This *is* in the toplevel
157
+ File.open(@op_dir + "index.html", "w") do |file|
158
+ file.write(render(:toplevel, binding))
159
+ end
160
+ end
161
+ end
162
+
163
+ # Darkfish returns +nil+, hence we do this as well.
164
+ def file_dir
165
+ nil
166
+ end
167
+
168
+ # Darkfish returns +nil+, hence we do this as well.
169
+ def class_dir
170
+ nil
171
+ end
172
+
173
+ protected
174
+
175
+ # Set/get the root directory.
176
+ # == Parameter
177
+ # [set_to (nil)]
178
+ # If passed, this method _sets_ the root directory rather
179
+ # than returning it.
180
+ # == Return value
181
+ # The current relative path to the root directory.
182
+ # == Remarks
183
+ # See the class’ introductory text for more information
184
+ # on this.
185
+ def root_path(set_to = nil)
186
+ if set_to
187
+ @root_path = Pathname.new(set_to)
188
+ else
189
+ @root_path ||= Pathname.new("./")
190
+ end
191
+ end
192
+
193
+ # Set/get the page title.
194
+ # == Parameter
195
+ # [set_to (nil)]
196
+ # If passed, this method _sets_ the title rather
197
+ # than returning it.
198
+ # == Return value
199
+ # The current page title.
200
+ # == Remarks
201
+ # Works the same way as #root_path.
202
+ def title(set_to = nil)
203
+ if set_to
204
+ @title = set_to
205
+ else
206
+ @title ||= ""
207
+ end
208
+ end
209
+
210
+ # Takes a RDoc::TopLevel and transforms it into a complete pathname
211
+ # relative to the output directory. Filename alterations
212
+ # done by RDoc’s crossref-HTML formatter are honoured. Note you
213
+ # have to prepend #root_path to get a complete href.
214
+ def rdocize_toplevel(toplevel)
215
+ Pathname.new("#{toplevel.relative_name.gsub(".", "_")}.html")
216
+ end
217
+
218
+ # Takes a RDoc::ClassModule and transforms it into a complete pathname
219
+ # relative to the output directory. Filename alterations
220
+ # done by RDoc’s crossref-HTML formatter are honoured. Note you
221
+ # have to prepend #root_path to get a complete href.
222
+ def rdocize_classmod(classmod)
223
+ Pathname.new("#{classmod.full_name.split("::").join("/")}.html")
224
+ end
225
+
226
+ private
227
+
228
+ def copy_base_files
229
+ debug "Copying base base files..."
230
+ mkdir @op_dir + "stylesheets" unless File.directory?(@op_dir + "stylesheets")
231
+
232
+ cp Dir[DATA_DIR + "stylesheets" + "*.css"], @op_dir + "stylesheets"
233
+ cp_r DATA_DIR + "javascripts", @op_dir
234
+ cp_r DATA_DIR + "images", @op_dir
235
+ end
236
+
237
+ def evaluate_toplevels
238
+ @toplevels.each do |toplevel|
239
+ debug "Processing toplevel #{toplevel.name}..."
240
+
241
+ root_path("../" * (toplevel.relative_name.split("/").count - 1)) # Last component is a filename
242
+ title toplevel.relative_name
243
+
244
+ # Create the path to the file if necessary
245
+ path = @op_dir + rdocize_toplevel(toplevel)
246
+ mkdir_p path.parent unless path.parent.exist?
247
+
248
+ # Evaluate the actual file documentation
249
+ File.open(path, "w") do |file|
250
+ debug " => #{path}"
251
+ file.write(render(:toplevel, binding))
252
+ end
253
+
254
+ # If this toplevel is supposed to be the main file,
255
+ # copy it’s content to the index.html file.
256
+ if toplevel.relative_name == @options.main_page
257
+ debug " => This is the main page. Writing index.html."
258
+
259
+ root_path "./" # We *are* at the top here
260
+
261
+ File.open(@op_dir + "index.html", "w") do |file|
262
+ file.write(render(:toplevel, binding))
263
+ end
264
+ end
265
+ end
266
+ end
267
+
268
+ def evaluate_classes_and_modules
269
+ @classes_and_modules.each do |classmod|
270
+ debug "Processing class/module #{classmod.full_name} (#{classmod.method_list.count} methods)..."
271
+
272
+ path = @op_dir + rdocize_classmod(classmod)
273
+
274
+ mkdir_p path.parent unless path.parent.directory?
275
+ title classmod.full_name
276
+ root_path "../" * (classmod.full_name.split("::").count - 1) # Last element is a file
277
+
278
+
279
+ File.open(path, "w") do |file|
280
+ debug " => #{path}"
281
+ file.write(render(:classmodule, binding))
282
+ end
283
+ end
284
+ end
285
+
286
+ # Renders the subtemplate +template_name+ in the +context+ of the
287
+ # given binding, then injects it into the main template (which is
288
+ # evaluated in the same +context+).
289
+ #
290
+ # Returns the resulting string.
291
+ def render(template_name, context)
292
+ render_into_layout{TEMPLATES[template_name].result(context)}
293
+ end
294
+
295
+ # Renders into the main layout. The return value of the block
296
+ # passed to this method will be placed in the layout in place
297
+ # of the +yield+ expression.
298
+ def render_into_layout
299
+ LAYOUT_TEMPLATE.result(binding)
300
+ end
301
+
302
+ end
303
+
304
+ require_relative "emerald/options"