docjs 0.1
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.
- data/CONCEPT.md +80 -0
- data/DOCUMENTATION.md +41 -0
- data/LICENSE.md +19 -0
- data/README.md +19 -0
- data/RENDERING.md +8 -0
- data/bin/docjs +190 -0
- data/docjs.gemspec +32 -0
- data/lib/boot.rb +34 -0
- data/lib/code_object/base.rb +48 -0
- data/lib/code_object/converter.rb +48 -0
- data/lib/code_object/exceptions.rb +5 -0
- data/lib/code_object/function.rb +84 -0
- data/lib/code_object/object.rb +18 -0
- data/lib/code_object/type.rb +43 -0
- data/lib/configs.rb +53 -0
- data/lib/document/document.rb +25 -0
- data/lib/dom/dom.rb +188 -0
- data/lib/dom/exceptions.rb +12 -0
- data/lib/dom/no_doc.rb +26 -0
- data/lib/dom/node.rb +415 -0
- data/lib/helper/helper.rb +120 -0
- data/lib/helper/linker.rb +130 -0
- data/lib/logger.rb +49 -0
- data/lib/parser/comment.rb +69 -0
- data/lib/parser/comment_parser.rb +90 -0
- data/lib/parser/exceptions.rb +6 -0
- data/lib/parser/meta_container.rb +20 -0
- data/lib/parser/parser.rb +269 -0
- data/lib/processor.rb +123 -0
- data/lib/renderer.rb +108 -0
- data/lib/tasks/render_task.rb +112 -0
- data/lib/thor.rb +27 -0
- data/lib/token/container.rb +84 -0
- data/lib/token/exceptions.rb +6 -0
- data/lib/token/handler.rb +242 -0
- data/lib/token/token.rb +46 -0
- data/templates/application.rb +14 -0
- data/templates/helpers/template.rb +66 -0
- data/templates/resources/css/.sass-cache/98c121fba905284c2c8ca6220fe3c590e5c9ec19/application.scssc +0 -0
- data/templates/resources/css/application.css +836 -0
- data/templates/resources/img/arrow_down.png +0 -0
- data/templates/resources/img/arrow_right.png +0 -0
- data/templates/resources/img/arrow_up.png +0 -0
- data/templates/resources/img/bullet_toggle_minus.png +0 -0
- data/templates/resources/img/bullet_toggle_plus.png +0 -0
- data/templates/resources/img/constructor.png +0 -0
- data/templates/resources/img/function.png +0 -0
- data/templates/resources/img/object.png +0 -0
- data/templates/resources/img/page.png +0 -0
- data/templates/resources/img/prototype.png +0 -0
- data/templates/resources/img/tag.png +0 -0
- data/templates/resources/js/application.js +318 -0
- data/templates/resources/js/jcore.js +129 -0
- data/templates/resources/js/jquery.cookie.js +92 -0
- data/templates/resources/js/jquery.js +16 -0
- data/templates/resources/js/jquery.tooltip.js +77 -0
- data/templates/resources/js/jquery.treeview.js +238 -0
- data/templates/resources/scss/_footer.scss +10 -0
- data/templates/resources/scss/_header.scss +184 -0
- data/templates/resources/scss/_helpers.scss +91 -0
- data/templates/resources/scss/_print.scss +20 -0
- data/templates/resources/scss/_resets.scss +132 -0
- data/templates/resources/scss/_tooltip.scss +26 -0
- data/templates/resources/scss/application.scss +442 -0
- data/templates/tasks/api_index_task.rb +26 -0
- data/templates/tasks/docs_task.rb +33 -0
- data/templates/tasks/json_data_task.rb +55 -0
- data/templates/tasks/typed_task.rb +54 -0
- data/templates/tokens/tokens.rb +22 -0
- data/templates/types/prototype.rb +20 -0
- data/templates/views/api_index.html.erb +21 -0
- data/templates/views/doc_page.html.erb +11 -0
- data/templates/views/function/_detail.html.erb +8 -0
- data/templates/views/function/index.html.erb +53 -0
- data/templates/views/index.html.erb +0 -0
- data/templates/views/layout/application.html.erb +73 -0
- data/templates/views/layout/json.html.erb +3 -0
- data/templates/views/object/index.html.erb +63 -0
- data/templates/views/tokens/_default.html.erb +11 -0
- data/templates/views/tokens/_default_token.html.erb +19 -0
- data/templates/views/tokens/_example.html.erb +2 -0
- data/templates/views/tokens/_examples.html.erb +1 -0
- data/test/code_object/converter.rb +78 -0
- data/test/code_object/prototype.rb +70 -0
- data/test/configs.rb +65 -0
- data/test/docs/README.CONCEPT.md +83 -0
- data/test/docs/README.md +14 -0
- data/test/dom/dom.absolute_nodes.rb +40 -0
- data/test/dom/dom.rb +72 -0
- data/test/dom/node.rb +53 -0
- data/test/integration/converter.rb +72 -0
- data/test/integration/parser_factory.rb +28 -0
- data/test/interactive.rb +7 -0
- data/test/js-files/absolute.js +11 -0
- data/test/js-files/comments_in_strings.js +31 -0
- data/test/js-files/core-doc-relative.js +77 -0
- data/test/js-files/core-doc.js +145 -0
- data/test/js-files/nested.js +34 -0
- data/test/js-files/nested_with_strings.js +35 -0
- data/test/js-files/prototype.js +33 -0
- data/test/js-files/simple.js +17 -0
- data/test/js-files/tokens.js +32 -0
- data/test/parser/comments_in_strings.rb +51 -0
- data/test/parser/intelligent_skip_until.rb +110 -0
- data/test/parser/parser.rb +273 -0
- data/test/rspec_helper.rb +23 -0
- data/test/token/handler.rb +136 -0
- data/test/token/tokens.rb +52 -0
- metadata +184 -0
data/lib/dom/no_doc.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# ../data.img#1811401:1
|
2
|
+
require_relative 'node'
|
3
|
+
module Dom
|
4
|
+
|
5
|
+
# NoDoc is used by {Dom} and {Dom::Node} to preserve the correct hierachy of
|
6
|
+
# the tree, while inserting nodes with non existing parents.
|
7
|
+
#
|
8
|
+
# For example let's add the node 'foo.bar.baz' in our empty Dom. This will
|
9
|
+
# result in the following tree:
|
10
|
+
#
|
11
|
+
# -foo (NoDoc)
|
12
|
+
# -bar (NoDoc)
|
13
|
+
# -baz
|
14
|
+
#
|
15
|
+
# If a documented
|
16
|
+
class NoDoc
|
17
|
+
include Node
|
18
|
+
|
19
|
+
attr_reader :name
|
20
|
+
|
21
|
+
def initialize(name)
|
22
|
+
@name = name
|
23
|
+
super()
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/dom/node.rb
ADDED
@@ -0,0 +1,415 @@
|
|
1
|
+
# ../data.img#1780307:3
|
2
|
+
require_relative 'dom'
|
3
|
+
require_relative 'exceptions'
|
4
|
+
|
5
|
+
module Dom
|
6
|
+
|
7
|
+
# Node can be seen as an **aspect** or feature of another Object. Therefore it can
|
8
|
+
# be mixed in to add node-functionality to a class.
|
9
|
+
# Such functionality is used by {CodeObject::Base code-objects} and {Document::Document documents}.
|
10
|
+
#
|
11
|
+
# Instance Variables
|
12
|
+
# ------------------
|
13
|
+
# The following instance-variables will be set while including Dom::Node into
|
14
|
+
# your class:
|
15
|
+
#
|
16
|
+
# - `@name` (should be already set in your including class)
|
17
|
+
# - `@parent`
|
18
|
+
# - `@children`
|
19
|
+
#
|
20
|
+
# @example
|
21
|
+
# class MyObject
|
22
|
+
# include Dom::Node
|
23
|
+
#
|
24
|
+
# # The contructor of MyObject should call init_node
|
25
|
+
# def initialize(name)
|
26
|
+
# super
|
27
|
+
# @name = name
|
28
|
+
# end
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# # MyObject can now be used as a node within our Domtree
|
32
|
+
# @baz = MyObject.new 'Baz'
|
33
|
+
# @baz.add_node(MyObject.new 'foo')
|
34
|
+
# @baz.add_node(MyObject.new 'bar')
|
35
|
+
#
|
36
|
+
# # These Nodes get inserted into Dom, so it looks like
|
37
|
+
# Dom.print_tree
|
38
|
+
# #=>
|
39
|
+
# #-Baz
|
40
|
+
# # -foo
|
41
|
+
# # -bar
|
42
|
+
#
|
43
|
+
# @note including Class should implement instance-variable @name
|
44
|
+
# @see CodeObject::Base
|
45
|
+
# @see Dom
|
46
|
+
module Node
|
47
|
+
|
48
|
+
NS_SEP_STRING = '.'
|
49
|
+
NS_SEP = /#{Regexp.escape(NS_SEP_STRING)}/
|
50
|
+
|
51
|
+
NODENAME = /[0-9a-zA-Z$_]+/
|
52
|
+
LEAF = /^#{NS_SEP}(?<name>#{NODENAME})$/
|
53
|
+
ABSOLUTE = /^(?<first>#{NODENAME})(?<rest>(#{NS_SEP}#{NODENAME})*)$/
|
54
|
+
RELATIVE = /^#{NS_SEP}(?<first>#{NODENAME})(?<rest>(#{NS_SEP}#{NODENAME})*)$/
|
55
|
+
|
56
|
+
|
57
|
+
# @group Initialization
|
58
|
+
|
59
|
+
# The 'constructor' of {Dom::Node}. It initializes all required
|
60
|
+
# instance-variables (see {Dom::Node above}).
|
61
|
+
def initialize
|
62
|
+
super
|
63
|
+
@children, @parent = {}, nil
|
64
|
+
@name ||= "" # should be written by including class
|
65
|
+
end
|
66
|
+
|
67
|
+
# @group Traversing
|
68
|
+
|
69
|
+
# `node.parent` returns the parent {Dom::Node node}, if there is one.
|
70
|
+
# If no parent exists `nil` is returned. In this case `node` can be
|
71
|
+
# considered either as loose leave or root of the {Dom}.
|
72
|
+
#
|
73
|
+
# @return [Dom::Node] the parent node, if one exists
|
74
|
+
def parent
|
75
|
+
@parent
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
# searches all parents recursivly and returns an array, starting with the
|
80
|
+
# highest order parent (excluding the {Dom.root}) and ending with the
|
81
|
+
# immediate parent.
|
82
|
+
#
|
83
|
+
# @example
|
84
|
+
# o1 = CodeObject::Base.new :foo
|
85
|
+
# o2 = CodeObject::Base.new :bar, o1
|
86
|
+
# o3 = CodeObject::Base.new :baz, o2
|
87
|
+
#
|
88
|
+
# # no parents
|
89
|
+
# o1.parents #=> []
|
90
|
+
#
|
91
|
+
# # all parents
|
92
|
+
# o3.parents #=> [#<CodeObject::Base:foo>, #<CodeObject::Base:bar>]
|
93
|
+
#
|
94
|
+
# @return [Array<Dom::Node>] the associated parents
|
95
|
+
def parents
|
96
|
+
return [] if @parent.nil? or @parent.parent.nil?
|
97
|
+
@parent.parents << @parent
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
# Returns all immediately associated children of this `node`
|
102
|
+
#
|
103
|
+
# @return [Hash<Symbol, Dom::Node>]
|
104
|
+
def children
|
105
|
+
@children
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
# Get's the child of this node, which is identified by `path`
|
110
|
+
#
|
111
|
+
# @example childname
|
112
|
+
# Dom[:Core] #=> #<CodeObject::Object:Core @parent=__ROOT__ …>
|
113
|
+
# Dom['Core'] #=> #<CodeObject::Object:Core @parent=__ROOT__ …>
|
114
|
+
#
|
115
|
+
# @example path
|
116
|
+
# Dom['Core.logger.log'] #=> #<CodeObject::Function:log @parent=logger …>
|
117
|
+
#
|
118
|
+
# @overload [](childname)
|
119
|
+
# @param [String, Symbol] childname
|
120
|
+
# @return <Dom::Node>
|
121
|
+
#
|
122
|
+
# @overload [](path)
|
123
|
+
# @param [String] path The path to the desired node
|
124
|
+
# @return <Dom::Node>
|
125
|
+
def [](path)
|
126
|
+
return @children[path] if path.is_a? Symbol
|
127
|
+
return @children[path.to_sym] if path.split(NS_SEP_STRING).size == 1
|
128
|
+
|
129
|
+
path = path.split(NS_SEP_STRING)
|
130
|
+
child = @children[path.shift.to_sym]
|
131
|
+
|
132
|
+
raise WrongPath.new(path) if child.nil?
|
133
|
+
|
134
|
+
# decend recursive
|
135
|
+
child[path.join(NS_SEP_STRING)]
|
136
|
+
end
|
137
|
+
|
138
|
+
# Alias for bracket-access
|
139
|
+
# @see #[]
|
140
|
+
def find(path)
|
141
|
+
self[path]
|
142
|
+
end
|
143
|
+
|
144
|
+
|
145
|
+
# Returns if the current node is a leaf or not.
|
146
|
+
#
|
147
|
+
# @return [Boolean]
|
148
|
+
def has_children?
|
149
|
+
not (@children.nil? or @children.size == 0)
|
150
|
+
end
|
151
|
+
|
152
|
+
# Finds all siblings of the current node. If there is no parent, it will
|
153
|
+
# return `nil`.
|
154
|
+
#
|
155
|
+
# @return [Array<Dom::Node>, nil]
|
156
|
+
def siblings
|
157
|
+
return nil if parent.nil?
|
158
|
+
@parent.children
|
159
|
+
end
|
160
|
+
|
161
|
+
|
162
|
+
# Resolves `nodename` in the current context and tries to find a matching
|
163
|
+
# {Dom::Node}. If `nodename` is not the current name and further cannot be found in the list of
|
164
|
+
# **children** the parent will be asked for resolution.
|
165
|
+
#
|
166
|
+
# Given the following example, each query (except `.log`) can be resolved without ambiguity.
|
167
|
+
#
|
168
|
+
# # -Core
|
169
|
+
# # -extend
|
170
|
+
# # -extensions
|
171
|
+
# # -logger
|
172
|
+
# # -log
|
173
|
+
# # -properties
|
174
|
+
# # -log
|
175
|
+
#
|
176
|
+
# Dom[:Core][:logger].resolve '.log'
|
177
|
+
# #=> #<CodeObject::Function:log @parent=logger @children=[]>
|
178
|
+
#
|
179
|
+
# Dom[:Core][:logger][:log].resolve '.log'
|
180
|
+
# #=> #<CodeObject::Function:log @parent=logger @children=[]>
|
181
|
+
#
|
182
|
+
# Dom[:Core][:logger][:log].resolve '.logger'
|
183
|
+
# #=> #<CodeObject::Object:logger @parent=Core @children=[]>
|
184
|
+
#
|
185
|
+
# Dom[:Core].resolve '.log'
|
186
|
+
# #=> #<CodeObject::Function:log @parent=Core @children=[]>
|
187
|
+
#
|
188
|
+
# Dom[:Core][:properties].resolve '.log'
|
189
|
+
# #=> #<CodeObject::Function:extend @parent=Core @children=[]>
|
190
|
+
#
|
191
|
+
# Dom[:Core][:logger].resolve 'foo'
|
192
|
+
# #=> nil
|
193
|
+
#
|
194
|
+
# @param [String] nodename
|
195
|
+
#
|
196
|
+
# @return [Dom::Node, nil]
|
197
|
+
def resolve(nodename)
|
198
|
+
|
199
|
+
return self if nodename == @name
|
200
|
+
return nil if @children.nil? and @parent.nil?
|
201
|
+
|
202
|
+
path = RELATIVE.match(nodename)
|
203
|
+
|
204
|
+
if path
|
205
|
+
first, rest = path.captures
|
206
|
+
|
207
|
+
# we did find the first part in our list of children
|
208
|
+
if not @children.nil? and @children.has_key? first.to_sym
|
209
|
+
|
210
|
+
# we have to continue our search
|
211
|
+
if rest != ""
|
212
|
+
@children[first.to_sym].resolve rest
|
213
|
+
|
214
|
+
# Finish
|
215
|
+
else
|
216
|
+
@children[first.to_sym]
|
217
|
+
end
|
218
|
+
|
219
|
+
else
|
220
|
+
@parent.resolve nodename unless @parent.nil?
|
221
|
+
end
|
222
|
+
|
223
|
+
# It's absolute?
|
224
|
+
elsif ABSOLUTE.match nodename
|
225
|
+
Dom.root.find nodename
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
# Iterates recursivly over all children of this node and applies `block` to them
|
230
|
+
#
|
231
|
+
# @param [Block] block
|
232
|
+
def each_child(&block)
|
233
|
+
@children.values.each do |child|
|
234
|
+
yield(child)
|
235
|
+
child.each_child(&block)
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
|
240
|
+
# @group Manipulation
|
241
|
+
|
242
|
+
# There are three different cases
|
243
|
+
# 1. Last Childnode i.e. ".foo"
|
244
|
+
# -> Append node as child
|
245
|
+
# 2. absolute path i.e. "Foo"
|
246
|
+
# -> delegate path resolution to Dom.root
|
247
|
+
# 3. relative path i.e. ".bar.foo"
|
248
|
+
# a. if there is a matching child for first element, delegate
|
249
|
+
# adding to this node
|
250
|
+
# b. create NoDoc node and delegate rest to this NoDoc
|
251
|
+
#
|
252
|
+
#
|
253
|
+
# @overload add_node(path, node)
|
254
|
+
# @param [String] path
|
255
|
+
# @param [Dom::Node] node
|
256
|
+
#
|
257
|
+
# @overload add_node(node)
|
258
|
+
# @param [Dom::Node] node
|
259
|
+
#
|
260
|
+
def add_node(*args)
|
261
|
+
|
262
|
+
# Grabbing right overload
|
263
|
+
if args.count == 2
|
264
|
+
node = args[1]
|
265
|
+
path = args[0]
|
266
|
+
elsif args.count == 1
|
267
|
+
node = args[0]
|
268
|
+
|
269
|
+
path = '.'+node.name
|
270
|
+
raise NoPathGiven.new("#{node} has no path.") if path.nil?
|
271
|
+
else
|
272
|
+
raise ArgumentError.new "Wrong number of arguments #{args.count} for 1 or 2"
|
273
|
+
end
|
274
|
+
|
275
|
+
leaf = LEAF.match path
|
276
|
+
|
277
|
+
if leaf
|
278
|
+
# node found, lets insert it
|
279
|
+
add_child(leaf[:name], node)
|
280
|
+
|
281
|
+
else
|
282
|
+
matches = RELATIVE.match path
|
283
|
+
|
284
|
+
if matches
|
285
|
+
name = matches[:first].to_s
|
286
|
+
|
287
|
+
# node not found, what to do?
|
288
|
+
add_child(name, NoDoc.new(name)) if self[name].nil?
|
289
|
+
|
290
|
+
# everything fixed, continue with rest
|
291
|
+
self[name].add_node(matches[:rest], node)
|
292
|
+
|
293
|
+
else
|
294
|
+
# has to be an absolute path or something totally strange
|
295
|
+
raise WrongPath.new(path) unless ABSOLUTE.match path
|
296
|
+
|
297
|
+
# begin at top, if absolute
|
298
|
+
Dom.add_node '.' + path, node
|
299
|
+
end
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
# @group Name- and Path-Handling
|
304
|
+
|
305
|
+
# Like {#qualified_name} it finds the absolute path.
|
306
|
+
# But in contrast to qualified_name it will not include the current node.
|
307
|
+
#
|
308
|
+
# @example
|
309
|
+
# my_node.qualified_name #=> "Core.logger.log"
|
310
|
+
# my_node.namespace #=> "Core.logger"
|
311
|
+
#
|
312
|
+
# @see #qualified_name
|
313
|
+
# @return [String]
|
314
|
+
def namespace
|
315
|
+
parents.map{|p| p.name}.join NS_SEP_STRING
|
316
|
+
end
|
317
|
+
|
318
|
+
|
319
|
+
# The **Qualified Name** equals the **Absolute Path** starting from the
|
320
|
+
# root-node of the Dom.
|
321
|
+
#
|
322
|
+
# @example
|
323
|
+
# my_node.qualified_name #=> "Core.logger.log"
|
324
|
+
#
|
325
|
+
# @return [String]
|
326
|
+
def qualified_name
|
327
|
+
parents.push(self).map{|p| p.name}.join NS_SEP_STRING
|
328
|
+
end
|
329
|
+
|
330
|
+
|
331
|
+
# Generates a text-output on console, representing the **subtree-structure**
|
332
|
+
# of the current node. The current node is **not** being printed.
|
333
|
+
#
|
334
|
+
# @example example output
|
335
|
+
# -Core
|
336
|
+
# -extend
|
337
|
+
# -extensions
|
338
|
+
# -logger
|
339
|
+
# -log
|
340
|
+
# -properties
|
341
|
+
#
|
342
|
+
# @return [nil]
|
343
|
+
def print_tree
|
344
|
+
|
345
|
+
# Because parent = nil and parent = Dom.root are handled the same at #parents
|
346
|
+
# we need to make a difference here
|
347
|
+
if @parent.nil?
|
348
|
+
level = 0
|
349
|
+
else
|
350
|
+
level = parents.count + 1
|
351
|
+
end
|
352
|
+
|
353
|
+
@children.each do |name, child|
|
354
|
+
puts "#{" " * level}-#{name.to_s}#{' (NoDoc)' if child.is_a? NoDoc}"
|
355
|
+
child.print_tree
|
356
|
+
end
|
357
|
+
nil
|
358
|
+
end
|
359
|
+
|
360
|
+
protected
|
361
|
+
|
362
|
+
def add_child(name, node)
|
363
|
+
|
364
|
+
name = name.to_sym
|
365
|
+
|
366
|
+
if self[name].nil?
|
367
|
+
self[name] = node
|
368
|
+
|
369
|
+
# If child is a NoDoc: replace NoDoc with node and move all children from
|
370
|
+
# NoDoc to node using node.add_child
|
371
|
+
elsif self[name].is_a? NoDoc
|
372
|
+
self[name].children.each do |name, childnode|
|
373
|
+
node.add_child(name, childnode)
|
374
|
+
end
|
375
|
+
self[name] = node
|
376
|
+
|
377
|
+
else
|
378
|
+
raise NodeAlreadyExists.new(name)
|
379
|
+
end
|
380
|
+
|
381
|
+
self[name].parent = self
|
382
|
+
end
|
383
|
+
|
384
|
+
# @note unimplemented
|
385
|
+
def remove_child(name) end
|
386
|
+
|
387
|
+
def parent=(node)
|
388
|
+
@parent = node
|
389
|
+
end
|
390
|
+
|
391
|
+
# setting a children of this node
|
392
|
+
def []=(name, value)
|
393
|
+
@children[name.to_sym] = value
|
394
|
+
end
|
395
|
+
|
396
|
+
# path can be absolute like `Foo.bar`, `Foo` or it can be relative like
|
397
|
+
# `.foo`, `.foo.bar`.
|
398
|
+
# in both cases we need to extract the name from the string and save it
|
399
|
+
# as name. After doing this we can use the path to save to dom.
|
400
|
+
#
|
401
|
+
# @example absolute path
|
402
|
+
# Node.extract_name_from("Foo.bar.baz") #=> 'baz'
|
403
|
+
# Node.extract_name_from("Foo.bar.baz") #=> 'baz'
|
404
|
+
#
|
405
|
+
# @param [String] path relative or absolute path of node
|
406
|
+
# @return [String] the extracted name
|
407
|
+
def extract_name_from(path)
|
408
|
+
name = path.split(NS_SEP_STRING).last
|
409
|
+
raise NoNameInPath.new(path) if name.nil?
|
410
|
+
|
411
|
+
return name
|
412
|
+
end
|
413
|
+
|
414
|
+
end
|
415
|
+
end
|