docjs 0.1.4 → 0.1.5

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 (41) hide show
  1. data/README.md +33 -63
  2. data/bin/docjs +30 -8
  3. data/bin/docjs.rb +30 -8
  4. data/docjs.gemspec +2 -2
  5. data/docs/ARCHITECTURE.md +0 -0
  6. data/{CONCEPT.md → docs/CONCEPT.md} +0 -0
  7. data/{DOCUMENTATION.md → docs/DOCUMENTATION.md} +2 -4
  8. data/docs/PATTERNS.md +101 -0
  9. data/docs/guides/CUSTOMIZE.md +158 -0
  10. data/docs/guides/TRY.md +63 -0
  11. data/docs/guides/USE.md +256 -0
  12. data/lib/boot.rb +2 -6
  13. data/lib/code_object/base.rb +5 -0
  14. data/lib/dom/node.rb +1 -1
  15. data/lib/{tasks/render_task.rb → generator/generator.rb} +15 -9
  16. data/lib/helper/helper.rb +2 -2
  17. data/lib/helper/linker.rb +7 -13
  18. data/lib/processor.rb +3 -12
  19. data/lib/renderer.rb +2 -0
  20. data/lib/token/container.rb +2 -1
  21. data/lib/token/handler.rb +187 -115
  22. data/lib/token/token.rb +35 -3
  23. data/templates/application.rb +7 -5
  24. data/templates/{tasks/api_index_task.rb → generators/api_index_generator.rb} +2 -2
  25. data/templates/{tasks/typed_task.rb → generators/api_pages_generator.rb} +2 -2
  26. data/templates/{tasks/docs_task.rb → generators/docs_generator.rb} +9 -2
  27. data/templates/{tasks/json_data_task.rb → generators/json_generator.rb} +2 -2
  28. data/templates/tokens/tokens.rb +2 -2
  29. data/{lib/code_object → templates/types}/function.rb +5 -3
  30. data/{lib/code_object → templates/types}/object.rb +0 -2
  31. data/templates/types/prototype.rb +2 -3
  32. data/templates/views/tokens/_default.html.erb +0 -2
  33. data/test/code_object/prototype.rb +1 -1
  34. data/test/dom/dom.absolute_nodes.rb +2 -3
  35. data/test/dom/dom.rb +3 -3
  36. data/test/dom/node.rb +9 -9
  37. data/test/integration/converter.rb +3 -3
  38. data/test/token/handler.rb +12 -9
  39. data/test/token/tokens.rb +1 -1
  40. metadata +16 -12
  41. data/RENDERING.md +0 -8
@@ -1,6 +1,6 @@
1
1
  require 'rdiscount'
2
2
  require_relative 'dom/dom'
3
- require_relative 'tasks/render_task'
3
+ require_relative 'generator/generator'
4
4
  require_relative 'document/document'
5
5
 
6
6
  module Processor
@@ -52,18 +52,9 @@ module Processor
52
52
 
53
53
 
54
54
  # @group Stage #3 - TemplateProcessor
55
-
56
- # just some notes
57
-
58
- # command line:
59
- # $~ jsdoc render_tasks
60
- # Registered Rendertasks:
61
- # - typed: renders objects type-dependant
62
- # - overview: renders an overview
63
- # - files: converts specified markdown files and renders them
64
- #
55
+
65
56
  def self.perform_all_tasks
66
- Tasks::RenderTask.all.each { |task| task.new.perform }
57
+ Generator::Generator.all.each { |task| task.new.perform }
67
58
  end
68
59
 
69
60
  # @group Stage #4 - Document Processor
@@ -58,6 +58,8 @@ class Renderer
58
58
  # create directories recursive
59
59
  FileUtils.mkpath File.dirname opt[:to_file]
60
60
 
61
+ # Working with Thor-Actions would be nice, but it seems to be too much overhead for this small
62
+ # renderer
61
63
  File.open(opt[:to_file], "w+") do |f|
62
64
  f.write view
63
65
  end
@@ -52,7 +52,8 @@ module Token
52
52
 
53
53
  # try to find matching tokenklass for token i.e. Token::Token::ParamToken for :param
54
54
  begin
55
- tokenklass = Token.const_get "#{tokenline.token.capitalize.to_s}Token"
55
+ camelcased = tokenline.token.to_s.capitalize.gsub(/_\w/){|w| w[1].capitalize}
56
+ tokenklass = Token.const_get "#{camelcased}Token"
56
57
  instance_exec(tokenklass, tokenline.content, &(tokenklass.handler))
57
58
  rescue Exception => error
58
59
  raise NoTokenHandler.new("No Tokenhandler for: @#{tokenline.token}
@@ -1,10 +1,10 @@
1
1
  require_relative 'token'
2
2
 
3
- # This module contains all required mixins and modules to register customized
4
- # tokens, that will be further processed and added to the {CodeObject::Base}.
3
+ # This module contains all required mixins and modules to register customized tokens, that will be
4
+ # further processed and added to the {CodeObject::Base}.
5
5
  #
6
- # The {CodeObject::Converter converter} starts the {Parser::Tokenline tokenline}-processing, by calling
7
- # the mixed-in function {Token::Container#process_token}.
6
+ # The {CodeObject::Converter converter} starts the {Parser::Tokenline tokenline}-processing, by
7
+ # calling the mixed-in function {Token::Container#process_token}.
8
8
  #
9
9
  # ![Token UML](../uml/Tokens.svg)
10
10
  #
@@ -15,38 +15,149 @@ require_relative 'token'
15
15
  # individual token-{Token::Container#add_token container} and
16
16
  # {Token::Container#process_token -processing} functionality to all CodeObjects.
17
17
  #
18
+ # Tokenprocessing means analysing the tokenline (plain textual content associated with a token) by
19
+ # applying a tokenhandler to it. The tokenhandler should parse the tokenline into it's contents and
20
+ # afterwards create an instance of the token-class.
18
21
  module Token
19
22
 
20
23
  # @note This module is **not** built to be used as a mixin! It should be seen as
21
24
  # a **global singleton** instead.
22
25
  #
23
26
  # The {Token::Handler} is meant to be the global store for all Token-handlers.
24
- # Token-handlers are needed to process incoming {Parser::Tokenline tokenlines}
25
- # of each comment. The following sample, shows a comment including a token line:
27
+ # Token-handlers are needed to process all {Parser::Tokenline tokenlines} associated with
28
+ # each comment. The following sample, shows a comment including a token line:
26
29
  #
27
30
  # /**
28
- # * @token this is a default tokenline
31
+ # * @foo this is a default tokenline
29
32
  # */
30
33
  #
31
- # This Comment will be transformed by the {Parser::CommentParser} into a
34
+ # This comment will be transformed by the {Parser::CommentParser} into a
32
35
  # {Parser::Tokenline tokenline} like the following:
33
36
  #
34
37
  # puts my_tokenline
35
- # #=> <struct Parser::Tokenline token="token", content="this is a default tokenline">
38
+ # #=> <struct Parser::Tokenline token="foo", content="this is a default tokenline">
36
39
  #
37
- # After creating the right type of {CodeObject::Base CodeObjects} (either a
38
- # {CodeObject::Object Object} or {CodeObject::Object Function}) the
39
- # {CodeObject::Converter converter} will trigger the conversion to a 'real'
40
- # {Token::Handler::Token token} by calling {Token::Container#process_token #process_token}
40
+ # After creating the right type of {CodeObject::Base CodeObjects} (either an
41
+ # {CodeObject::Object Object}, {CodeObject::Object Function} or a custom type) the
42
+ # {CodeObject::Converter converter} will trigger the conversion to an appropriate subclass of
43
+ # {Token::Token} by calling {Token::Container#process_token #process_token}
41
44
  # on the CodeObject.
42
45
  #
43
46
  # code_object.process_token(my_tokenline)
44
47
  # code_object.token(:token)
45
- # #=> [#<struct Token::Handler::Token content="this is a default tokenline">]
48
+ # #=> [#<Token::FooToken content="this is a default tokenline">]
46
49
  #
47
- # Tokens are always stored in an array to make multiple usage in one comment
48
- # possible.
50
+ # Tokens are always stored in an array to make multiple usage in one comment possible.
51
+ # For example one function-comment can contain many `@param`s:
52
+ #
53
+ # /**
54
+ # * @function foo
55
+ # * @param [Number] bar
56
+ # * @param [String] baz
57
+ # */
58
+ #
59
+ # Default Handlers
60
+ # ================
61
+ #
62
+ # :text_only
63
+ # ----------
64
+ # The default Header :text_only cannot parse typelists or tokennames, it
65
+ # only saves the content of the token to an instance of {Token::Token}
66
+ # Being the default handler we can use it without explicitly specifying it:
67
+ #
68
+ # Token::Handler.register :token
69
+ #
70
+ # This Default Handler is enough for tokens like `@todo` or `@note`. But for
71
+ # more complex Tokens we need some other handlers.
72
+ #
73
+ # :typed
74
+ # ------
75
+ # Typed tokens look like
76
+ #
77
+ # @return [Foo, Bar] This is the description
78
+ #
79
+ # Additional to their default **content** they specify the possible **types** as a commaseperated
80
+ # list.
81
+ #
82
+ # To register a typed-token, you only need to add the `:handler` option
83
+ #
84
+ # Token::Handler.register :return, :handler => :typed
85
+ #
86
+ # This line implicitly generates a class `Token::ReturnToken` which extends {Token::Token},
87
+ # content and types will be filled to access them later:
49
88
  #
89
+ # my_return_token.content #=> "This is the description"
90
+ # my_return_token.types #=> ["Foo", "Bar]
91
+ #
92
+ # :named
93
+ # ------
94
+ # Named tokenlines like
95
+ #
96
+ # @mixin Foo.bar The description of this mixin-usage
97
+ #
98
+ # interpret the first part (`Foo.bar`) as **name** and the rest as **content**
99
+ #
100
+ # Token::Handler.register :mixin, :handler => :named
101
+ #
102
+ # mixin_token.name #=> "Foo.bar"
103
+ # mixin_token.content #=> "The description of this mixin-usage"
104
+ #
105
+ # :named_multiline
106
+ # ----------------
107
+ # Named multiline are similiar to named tokenlines. But instead of taking the first word as
108
+ # name they are using the first line:
109
+ #
110
+ # @example this is the name
111
+ # function() {...}
112
+ #
113
+ # To register a named-multiline token just add the handler like:
114
+ #
115
+ # Token::Handler.register :example, :handler => :named_multiline
116
+ #
117
+ # my_example.name #=> "this is the name"
118
+ # my_example.content #=> "function() {...}"
119
+ #
120
+ # :typed_with_name
121
+ # ----------------
122
+ # The typed_with_name handler is much like the **Typed-Token-Handler**. It is neccessary for
123
+ # tokenlines, like
124
+ #
125
+ # @param [String] my_param This is a param
126
+ #
127
+ # Additional to **content** and **types** the generated class will contain a **name** property.
128
+ #
129
+ # Token::Handler.register :param, :handler => :typed_with_name
130
+ #
131
+ # param_token.name #=> "my_param"
132
+ # param_token.types #=> ["String"]
133
+ # param_token.content #=> "This is a param"
134
+ # param_token.class #=> Token::ParamToken
135
+ #
136
+ # :named_nested_shorthand
137
+ # -----------------------
138
+ # named_nested_shorthand can be used to parse nested `:typed_with_name` tokens.
139
+ #
140
+ # @param person
141
+ # [String] name the name
142
+ # [Number] age the age of the person
143
+ #
144
+ # It is called shorthand, because "`[String] name the name`" is not a full tokenline. (The
145
+ # `@param` is missing.)
146
+ #
147
+ # Token::Handler.register :param, :handler => :named_nested_shorthand
148
+ #
149
+ # The instance of `Token::ParamToken` can look like:
150
+ #
151
+ # param_token.name #=> "person"
152
+ # param_token.children # [<Token::ParamToken name="name"><Token::ParamToken name="age">]
153
+ #
154
+ # It also can parse typed_with_name tokenlines like `@param [String] name`. In this case it
155
+ # behaves exaclty like :typed_with_name
156
+ #
157
+ # :noop
158
+ # -----
159
+ # Can be used, if you don't want to do anything with that token
160
+ #
50
161
  # @see .register
51
162
  module Handler
52
163
 
@@ -55,6 +166,9 @@ module Token
55
166
  IDENTIFIER = /(?:[^\s])*/
56
167
  TYPELIST = /\[(?<types>#{IDENTIFIER}(?:,#{NO_BR}*#{IDENTIFIER})*)\]/
57
168
 
169
+ # Tokens with name and content
170
+ NAME = /#{NO_BR}*(?<name>#{IDENTIFIER})#{NO_BR}*(?<content>#{ALL}*)/
171
+
58
172
  # Token with type and content
59
173
  TOKEN_W_TYPE = /#{NO_BR}*#{TYPELIST}#{NO_BR}*(?<content>#{ALL}*)/
60
174
 
@@ -66,9 +180,8 @@ module Token
66
180
  (?<content>#{ALL}*)
67
181
  /x
68
182
 
69
-
70
- # @note It would be nice, if those defaults could be used without self.add_token
71
183
  @@defaults = {
184
+
72
185
  :text_only => ->(tokenklass, content) {
73
186
  tokenklass.new(:content => content)
74
187
  },
@@ -79,14 +192,12 @@ module Token
79
192
 
80
193
  tokenklass.new(:types => types, :content => content)
81
194
  },
82
-
83
- :typed_with_name => ->(tokenklass, content) {
84
- typestring, name, content = TOKEN_W_TYPE_NAME.match(content).captures
85
- types = typestring.split /,\s*/
86
-
87
- tokenklass.new(:name => name, :types => types, :content => content)
88
- },
89
195
 
196
+ :named => ->(tokenklass, content) {
197
+ name, content = NAME.match(content).captures
198
+ tokenklass.new(:name => name, :content => content)
199
+ },
200
+
90
201
  :named_multiline => ->(tokenklass, content) {
91
202
  rows = content.split(/\n/)
92
203
 
@@ -96,10 +207,17 @@ module Token
96
207
 
97
208
  tokenklass.new(:name => name, :content => content)
98
209
  },
210
+
211
+ :typed_with_name => ->(tokenklass, content) {
212
+ typestring, name, content = TOKEN_W_TYPE_NAME.match(content).captures
213
+ types = typestring.split /,\s*/
214
+
215
+ tokenklass.new(:name => name, :types => types, :content => content)
216
+ },
99
217
 
100
218
  :named_nested_shorthand => ->(tokenklass, content) {
101
219
 
102
- # First remove linebreaks with 2-times intendation
220
+ # First remove linebreaks with 2-times intendation (= continuation)
103
221
  lines = content.gsub(/\n((?!\n)\s){2}/, ' ').split(/\n/)
104
222
  name = lines.shift.strip
105
223
  documentation = []
@@ -107,7 +225,7 @@ module Token
107
225
 
108
226
  lines.each do |line|
109
227
  if TOKEN_W_TYPE_NAME.match(line)
110
- # apply default-handler :typed_with_name to each child-line
228
+ # apply handler :typed_with_name to each child-line
111
229
  # @todo maybe we need a special way to select Children's Class?
112
230
  children << Handler.apply(:typed_with_name, tokenklass, line)
113
231
  else
@@ -134,94 +252,49 @@ module Token
134
252
  @@defaults[default_handler].call(*args)
135
253
  end
136
254
 
137
- # Registering a new Tokenhandler
138
- # ==============================
139
- # It is possible to register your own Tokenhandlers and therefore extend the
140
- # capabilities of this documentation-program.
141
- #
142
- # There are different types of handlers which can be used:
143
- #
144
- # 1. Default-handler
145
- # 2. A handler for Typed-Token
146
- # 3. A handler for Named-Typed-Tokens
147
- # 4. Your custom handler (see second overload)
148
- #
149
- #
150
- # @overload self.register(tokenname, type=nil)
151
- #
152
- # The first three of the handlers above can be registered with this
153
- # overload.
154
- #
155
- # The Default Handler
156
- # -------------------
157
- # The Default Header can be used for tokens like the one in the example above.
158
- # Trying to add a token like `@token` without adding a handler, you may get
159
- # an `exception` like:
160
- #
161
- # #=> Token::NoTokenHandler: No Tokenhandler for: token
162
- # # from lib/token/container.rb:41:in process_token
163
- #
164
- # So we better register a handler for that token:
165
- #
166
- # Token::Handler.register :token
167
- #
168
- # As you can see **the second argument can be ommitted** to use a **default
169
- # handler**. This default handler cannot parse typelists or tokennames, it
170
- # only saves the content of the token to the struct {Token::Handler::Token Token}.
171
- #
172
- # This Default Handler is enough for tokens like `@todo` or `@note`. But for
173
- # more complex Tokens we need some other handlers.
174
- #
175
- # Handler for Typed-Tokens
176
- # ------------------------
177
- # Typed tokens look like `@return [Foo, Bar] This is the description` - Additional
178
- # to their **default content** they specify the possible Types.
179
- #
180
- # To register a typed-token, you only need to add a second argument:
181
- #
182
- # Token::Handler.register :return, :typed
183
- #
184
- # The {Token::Handler::TypedToken typed-token struct}, pretty much looks like
185
- # the default one.
186
- #
187
- # #=> #<struct Token::Handler::TypedToken types=["Foo", "Bar"], content="This is the description\n">
188
- #
189
- # Handler for Typed-Named-Tokens
190
- # ------------------------------
191
- # They are much like **Typed-Token-Handlers**. They are needed for Tokenlines
192
- # like `@param [String] my_param This is a param`. They are registered with
193
- # `:typed_with_name` as the second argument:
194
- #
195
- # Token::Handler.register :param, :typed_with_name
196
- #
197
- # @param [String, Symbol] tokenname
198
- # @param [:typed, :typed_with_name, nil] type
255
+ def self.add_default_handler(name, &block)
256
+ @@defaults[name] = block;
257
+ end
258
+
259
+ # It is possible to register your own Tokenhandlers and therefore extend the capabilities of
260
+ # this documentation-tool (See: {file:CUSTOMIZE.md CUSTOMIZE}).
199
261
  #
262
+ # There are different types of handlers which can be used out of the box. Further documentation
263
+ # about the default handlers can be found {Token::Handler in the introduction}.
200
264
  #
201
- # @overload self.register(tokenname, &handler)
202
- #
203
- # Writing your own custom Token-Handler
204
- # -------------------------------------
205
- # By adding a block in the Tokenregistration you easily can build your own
206
- # Tokenhandler:
265
+ # Writing your own custom Token-Handler
266
+ # -------------------------------------
267
+ # By adding the optional block you easily can build your own Tokenhandler:
207
268
  #
208
- # Token::Handler.register(:my_own) do |token_klass, stringcontent|
209
- # # Do something with token_id and stringcontent
210
- # # but don't forget to add the token like:
211
- # self.add_token(token_klass.new(:content => stringcontent)
212
- # end
269
+ # Token::Handler.register(:my_own) do |token_klass, stringcontent|
270
+ # # Do something with token_klass and stringcontent
271
+ # # but don't forget to add the token like, if you want to access it from the templates:
272
+ # # token_klass will be Token::MyOwnToken, which is dynamically created during registration
213
273
  #
214
- # Because the token processing is done in the **context of the CodeObject** you
215
- # can easily extend or manipulate the Objects.
216
- #
217
- # If you want to assure, that the object you are working on has a specific type
218
- # (for example a Function) add the following line to your handler:
274
+ # self.add_token(token_klass.new(:content => stringcontent)
275
+ # end
219
276
  #
220
- # has_to_be_a CodeObject::Function
277
+ # Because the token processing is done in the **context of the CodeObject** you
278
+ # can easily extend or manipulate the Object.
221
279
  #
222
- # @param [String, Symbol] tokenname
223
- # @yield [tokenklass, stringcontent] Your custom tokenhandler
280
+ # @param [String, Symbol] tokenname
281
+ # @param [Hash] options
282
+ # @option options [Symbol] :handler (:text_only)
283
+ # @option options [Symbol, String] :template (:default) The template for this token-collection
284
+ # @option options [Hash] :html ({}) Attributes which can be added to the html-representation of
285
+ # this token. For example use
286
+ # :html => { :class => 'big_button' }
287
+ # to add the class `.big_button` to the html-element. Please note, that your template has to
288
+ # render the html-attributes explicilty. For example by adding
289
+ # <div <%= attributize token.html %>>...</div>
290
+ # @option options [Symbol] :area (:body) The area the tokens will be rendered in. The default
291
+ # templates make use of (:notification|:body|:sidebar|:footnote), but you can use any symbol
292
+ # here.
293
+ # @option options [String] :description ("") The description specified here will appear in the
294
+ # command-line output of `docjs tokens`
224
295
  #
296
+ # @yield [tokenklass, stringcontent] Your custom tokenhandler
297
+ # @see Token::Token
225
298
  def self.register(tokenname, options = {}, &handler)
226
299
 
227
300
  tokenname = tokenname.to_sym
@@ -238,7 +311,8 @@ module Token
238
311
  end
239
312
 
240
313
  # Dynamically create Class named TokennameToken
241
- klass = Token.const_set "#{tokenname.to_s.capitalize}Token", Class.new(Token)
314
+ camelcased = tokenname.to_s.capitalize.gsub(/_\w/){|w| w[1].capitalize}
315
+ klass = Token.const_set "#{camelcased}Token", Class.new(Token)
242
316
 
243
317
  klass.process_options options.merge({
244
318
 
@@ -250,7 +324,9 @@ module Token
250
324
  @@handlers[tokenname] = klass
251
325
  end
252
326
 
253
- # Remove a registered handler from the list
327
+ # Remove a registered handler from the list.
328
+ #
329
+ # @todo remove symbol `Token::TokennameToken`
254
330
  #
255
331
  # @example
256
332
  # Token::Handler.register :foo
@@ -259,11 +335,7 @@ module Token
259
335
  # @param [String, Symbol] tokenname
260
336
  def self.unregister(tokenname)
261
337
  @@handlers.delete(tokenname.to_sym)
262
- end
263
-
264
- def self.add_default_handler(name, &block)
265
- @@defaults[name] = block;
266
- end
338
+ end
267
339
 
268
340
  protected
269
341