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.
Files changed (109) hide show
  1. data/CONCEPT.md +80 -0
  2. data/DOCUMENTATION.md +41 -0
  3. data/LICENSE.md +19 -0
  4. data/README.md +19 -0
  5. data/RENDERING.md +8 -0
  6. data/bin/docjs +190 -0
  7. data/docjs.gemspec +32 -0
  8. data/lib/boot.rb +34 -0
  9. data/lib/code_object/base.rb +48 -0
  10. data/lib/code_object/converter.rb +48 -0
  11. data/lib/code_object/exceptions.rb +5 -0
  12. data/lib/code_object/function.rb +84 -0
  13. data/lib/code_object/object.rb +18 -0
  14. data/lib/code_object/type.rb +43 -0
  15. data/lib/configs.rb +53 -0
  16. data/lib/document/document.rb +25 -0
  17. data/lib/dom/dom.rb +188 -0
  18. data/lib/dom/exceptions.rb +12 -0
  19. data/lib/dom/no_doc.rb +26 -0
  20. data/lib/dom/node.rb +415 -0
  21. data/lib/helper/helper.rb +120 -0
  22. data/lib/helper/linker.rb +130 -0
  23. data/lib/logger.rb +49 -0
  24. data/lib/parser/comment.rb +69 -0
  25. data/lib/parser/comment_parser.rb +90 -0
  26. data/lib/parser/exceptions.rb +6 -0
  27. data/lib/parser/meta_container.rb +20 -0
  28. data/lib/parser/parser.rb +269 -0
  29. data/lib/processor.rb +123 -0
  30. data/lib/renderer.rb +108 -0
  31. data/lib/tasks/render_task.rb +112 -0
  32. data/lib/thor.rb +27 -0
  33. data/lib/token/container.rb +84 -0
  34. data/lib/token/exceptions.rb +6 -0
  35. data/lib/token/handler.rb +242 -0
  36. data/lib/token/token.rb +46 -0
  37. data/templates/application.rb +14 -0
  38. data/templates/helpers/template.rb +66 -0
  39. data/templates/resources/css/.sass-cache/98c121fba905284c2c8ca6220fe3c590e5c9ec19/application.scssc +0 -0
  40. data/templates/resources/css/application.css +836 -0
  41. data/templates/resources/img/arrow_down.png +0 -0
  42. data/templates/resources/img/arrow_right.png +0 -0
  43. data/templates/resources/img/arrow_up.png +0 -0
  44. data/templates/resources/img/bullet_toggle_minus.png +0 -0
  45. data/templates/resources/img/bullet_toggle_plus.png +0 -0
  46. data/templates/resources/img/constructor.png +0 -0
  47. data/templates/resources/img/function.png +0 -0
  48. data/templates/resources/img/object.png +0 -0
  49. data/templates/resources/img/page.png +0 -0
  50. data/templates/resources/img/prototype.png +0 -0
  51. data/templates/resources/img/tag.png +0 -0
  52. data/templates/resources/js/application.js +318 -0
  53. data/templates/resources/js/jcore.js +129 -0
  54. data/templates/resources/js/jquery.cookie.js +92 -0
  55. data/templates/resources/js/jquery.js +16 -0
  56. data/templates/resources/js/jquery.tooltip.js +77 -0
  57. data/templates/resources/js/jquery.treeview.js +238 -0
  58. data/templates/resources/scss/_footer.scss +10 -0
  59. data/templates/resources/scss/_header.scss +184 -0
  60. data/templates/resources/scss/_helpers.scss +91 -0
  61. data/templates/resources/scss/_print.scss +20 -0
  62. data/templates/resources/scss/_resets.scss +132 -0
  63. data/templates/resources/scss/_tooltip.scss +26 -0
  64. data/templates/resources/scss/application.scss +442 -0
  65. data/templates/tasks/api_index_task.rb +26 -0
  66. data/templates/tasks/docs_task.rb +33 -0
  67. data/templates/tasks/json_data_task.rb +55 -0
  68. data/templates/tasks/typed_task.rb +54 -0
  69. data/templates/tokens/tokens.rb +22 -0
  70. data/templates/types/prototype.rb +20 -0
  71. data/templates/views/api_index.html.erb +21 -0
  72. data/templates/views/doc_page.html.erb +11 -0
  73. data/templates/views/function/_detail.html.erb +8 -0
  74. data/templates/views/function/index.html.erb +53 -0
  75. data/templates/views/index.html.erb +0 -0
  76. data/templates/views/layout/application.html.erb +73 -0
  77. data/templates/views/layout/json.html.erb +3 -0
  78. data/templates/views/object/index.html.erb +63 -0
  79. data/templates/views/tokens/_default.html.erb +11 -0
  80. data/templates/views/tokens/_default_token.html.erb +19 -0
  81. data/templates/views/tokens/_example.html.erb +2 -0
  82. data/templates/views/tokens/_examples.html.erb +1 -0
  83. data/test/code_object/converter.rb +78 -0
  84. data/test/code_object/prototype.rb +70 -0
  85. data/test/configs.rb +65 -0
  86. data/test/docs/README.CONCEPT.md +83 -0
  87. data/test/docs/README.md +14 -0
  88. data/test/dom/dom.absolute_nodes.rb +40 -0
  89. data/test/dom/dom.rb +72 -0
  90. data/test/dom/node.rb +53 -0
  91. data/test/integration/converter.rb +72 -0
  92. data/test/integration/parser_factory.rb +28 -0
  93. data/test/interactive.rb +7 -0
  94. data/test/js-files/absolute.js +11 -0
  95. data/test/js-files/comments_in_strings.js +31 -0
  96. data/test/js-files/core-doc-relative.js +77 -0
  97. data/test/js-files/core-doc.js +145 -0
  98. data/test/js-files/nested.js +34 -0
  99. data/test/js-files/nested_with_strings.js +35 -0
  100. data/test/js-files/prototype.js +33 -0
  101. data/test/js-files/simple.js +17 -0
  102. data/test/js-files/tokens.js +32 -0
  103. data/test/parser/comments_in_strings.rb +51 -0
  104. data/test/parser/intelligent_skip_until.rb +110 -0
  105. data/test/parser/parser.rb +273 -0
  106. data/test/rspec_helper.rb +23 -0
  107. data/test/token/handler.rb +136 -0
  108. data/test/token/tokens.rb +52 -0
  109. metadata +184 -0
@@ -0,0 +1,48 @@
1
+ # ../data.img#1769990:1
2
+ require_relative 'function'
3
+ require_relative 'exceptions'
4
+ require_relative 'type'
5
+
6
+ module CodeObject
7
+
8
+
9
+ # here the dependencies to {Dom::Node} and {Parser::Comment} should be described
10
+ module Converter
11
+
12
+ attr_reader :code_object, :path
13
+
14
+ def to_code_object
15
+
16
+ # 1. Create a new CodeObject from Type-Token
17
+ @code_object = Type.create_matching_object(@tokenlines) or return nil
18
+
19
+ # join all documentation-contents
20
+ @code_object.docs = @doclines.join ''
21
+
22
+ # move meta-information from comment to code_object
23
+ # (This includes filepath, source and line_start
24
+ @code_object.clone_meta(self)
25
+
26
+ # 2. Process Tokenlines with registered handlers
27
+ @code_object.process_tokens(@tokenlines)
28
+
29
+ # 3.Continue with all children of this comment and add them as
30
+ # child nodes
31
+ convert_children { |child| @code_object.add_node(child) }
32
+
33
+ return @code_object
34
+ end
35
+
36
+ protected
37
+
38
+
39
+ # recursivly process all child-tokens
40
+ def convert_children
41
+ @children.each do |child_comment|
42
+ code_object = child_comment.to_code_object
43
+ yield(code_object) unless code_object.nil?
44
+ end
45
+ end
46
+
47
+ end
48
+ end
@@ -0,0 +1,5 @@
1
+ module CodeObject
2
+
3
+ class MultipleTypeDeclarations < Exception; end
4
+
5
+ end
@@ -0,0 +1,84 @@
1
+ # ../data.img#1858563:1
2
+ require_relative 'object'
3
+
4
+ module CodeObject
5
+
6
+ class Function < CodeObject::Object
7
+
8
+ token_reader :params, :param
9
+ token_reader :returns, :return
10
+
11
+ def constructor?
12
+ @constructor || false
13
+ end
14
+
15
+ # @todo i need a @prototype token in object
16
+ def prototype
17
+ children[:prototype]
18
+ end
19
+
20
+ end
21
+
22
+ end
23
+
24
+ CodeObject::Type.register :function, CodeObject::Function
25
+ Token::Handler.register :function, :handler => :noop, :area => :none
26
+
27
+ # @todo rewrite as default-handler, because this looks a little distracting
28
+ module Token::Handler
29
+
30
+ # @todo maybe allow multipled nested layers of params by parsing them recursivly
31
+ register :param, :area => :body do |tokenklass, content|
32
+
33
+ # We want to support either named-typed-tokens like
34
+ # @param [Foo] barname some description
35
+ #
36
+ # or multiline tokens like:
37
+ # @param configs
38
+ # [String] foo some string
39
+ # [Bar] bar and another one
40
+ #
41
+ #
42
+ # if out content matches something with `[` at the beginning, it seems to be
43
+ # a normal named-typed-token
44
+ # it's a little tricky because we still want to allow multiline descriptions of each param
45
+ def parse_token(content)
46
+ typestring, name, content = TOKEN_W_TYPE_NAME.match(content).captures
47
+ types = typestring.split /,\s*/
48
+ Token::Token::ParamToken.new(:name => name, :types => types, :content => content)
49
+ end
50
+
51
+ # it's @param [String] name some content
52
+ if content.lines.first.match TOKEN_W_TYPE_NAME
53
+ self.add_token parse_token(content)
54
+
55
+ # it maybe a multiline
56
+ else
57
+ lines = content.split(/\n/)
58
+ name = lines.shift.strip
59
+ types = ['PropertyObject']
60
+
61
+ # now split line at opening bracket, not at line-break to enable multiline properties
62
+ children = lines.join("\n").strip.gsub(/\s+\[/, "<--SPLIT_HERE-->[").split("<--SPLIT_HERE-->")
63
+
64
+ children.map! do |child|
65
+ parse_token(child)
66
+ end
67
+
68
+ self.add_token tokenklass.new(:name => name, :types => types, :children => children)
69
+ end
70
+ end
71
+
72
+
73
+ end
74
+
75
+ Token::Handler.register :return, :handler => :typed
76
+ Token::Handler.register :throws, :handler => :typed
77
+
78
+ # MethodAlias
79
+ CodeObject::Type.register :method, CodeObject::Function
80
+ Token::Handler.register :method, :handler => :noop, :area => :none
81
+
82
+ # @constructor Foo.bar
83
+ CodeObject::Type.register :constructor, CodeObject::Function
84
+ Token::Handler.register(:constructor) { |token, content| @constructor = true }
@@ -0,0 +1,18 @@
1
+ # ../data.img#1858561:1
2
+ require_relative 'base'
3
+ require_relative 'type'
4
+
5
+ module CodeObject
6
+
7
+ class Object < CodeObject::Base
8
+
9
+ token_reader :props, :prop
10
+
11
+ end
12
+
13
+ end
14
+
15
+ CodeObject::Type.register :object, CodeObject::Object
16
+ Token::Handler.register :object, :handler => :noop, :area => :none
17
+
18
+ Token::Handler.register :prop, :handler => :typed_with_name
@@ -0,0 +1,43 @@
1
+ require_relative 'exceptions'
2
+
3
+ module CodeObject
4
+
5
+ module Type
6
+
7
+ @@types = {}
8
+
9
+ def self.register(tokenid, klass)
10
+ @@types[tokenid.to_sym] = klass
11
+ end
12
+
13
+ def self.create_matching_object(tokenlines)
14
+ klass = self.find_klass(tokenlines) or return nil
15
+ self[klass.token].new(klass.content)
16
+ end
17
+
18
+ protected
19
+
20
+ def self.[](tokenid)
21
+ @@types[tokenid.to_sym]
22
+ end
23
+
24
+ def self.include?(tokenid)
25
+ @@types.has_key? tokenid.to_sym
26
+ end
27
+
28
+ def self.find_klass(tokenlines)
29
+ klass = tokenlines.select {|t| self.include? t.token }
30
+
31
+ if klass.size > 1
32
+ raise CodeObject::MultipleTypeDeclarations.new, "Wrong number of TypeDeclarations: #{klass}"
33
+ elsif klass.size == 0
34
+ # it's not possible to create instance
35
+ return nil
36
+ end
37
+
38
+ klass.first
39
+ end
40
+
41
+ end
42
+
43
+ end
@@ -0,0 +1,53 @@
1
+ module Configs
2
+
3
+ def self.set(sym_or_hash, value = nil)
4
+
5
+ unless sym_or_hash.is_a? Hash
6
+ sym_or_hash = { sym_or_hash => value }
7
+ end
8
+
9
+ sym_or_hash.each_pair do |attr, value|
10
+ set_attribute(attr, value)
11
+ end
12
+ end
13
+
14
+ def self.attributes
15
+ class_variables.map do |var|
16
+ var.to_s.scan(/@@(.*)/).first.first.to_sym
17
+ end
18
+ end
19
+
20
+ def self.method_missing(method_name, *args)
21
+ nil
22
+ end
23
+
24
+ def self.clear
25
+ class_variables.each do |var|
26
+ class_variable_set(var, nil)
27
+ end
28
+ end
29
+
30
+ protected
31
+
32
+ def self.set_attribute(key, value)
33
+
34
+ key = key.to_s
35
+
36
+ class_variable_set("@@#{key}", value)
37
+
38
+ class_eval <<-EOS
39
+ def self.#{key}
40
+ return @@#{key}
41
+ end
42
+ EOS
43
+
44
+ if value.is_a? TrueClass or value.is_a? FalseClass
45
+ class_eval <<-EOS
46
+ def self.#{key}?
47
+ return @@#{key}
48
+ end
49
+ EOS
50
+ end
51
+ end
52
+
53
+ end
@@ -0,0 +1,25 @@
1
+ require_relative '../dom/dom'
2
+
3
+ module Document
4
+
5
+ class Document
6
+
7
+ include Dom::Node
8
+
9
+ FILE_ENDINGS = /\.(markdown|mdown|md|mkd|mkdn)$/i
10
+
11
+ attr_reader :name, :path, :content
12
+
13
+ def initialize(path, content)
14
+
15
+ path = File.basename(path).gsub(FILE_ENDINGS, '')
16
+
17
+ # please do not confuse Filepath of Document (like docs/README.md) with path in Dom
18
+ # an .md will be stripped from the name and README.SOMEMORE.md can be used as path information
19
+ @path, @name, @content = ".#{path}", extract_name_from(path), content
20
+ super()
21
+ end
22
+
23
+ end
24
+
25
+ end
@@ -0,0 +1,188 @@
1
+ # ../data.img#1811391:1 && #1811396:1
2
+ require_relative 'no_doc'
3
+ require_relative 'exceptions'
4
+
5
+ # Storing {CodeObject::Base Objects}
6
+ # ==================================
7
+ #
8
+ # The datastructure is based on a treelike concept. Every new inserted
9
+ # {CodeObject::Base object} is represented by a {Dom::Node node} of the tree.
10
+ # There are three types of nodes:
11
+ #
12
+ # 1. {Dom::NoDoc Not documented nodes} that contain other nodes
13
+ # 2. {Dom::Node Documented nodes}, that contain other nodes
14
+ # 3. Leafs of the tree, without children. (Those leafs have to be
15
+ # {Dom::Node documented nodes})
16
+ #
17
+ # The architecure of the Dom looks pretty much like this:
18
+ #
19
+ # ![Dom Architecture](../uml/Dom.svg)
20
+ #
21
+ # Take the following code-sample:
22
+ #
23
+ # /**
24
+ # * @function Foo.bar
25
+ # */
26
+ #
27
+ # The tree could look like:
28
+ #
29
+ # ROOT
30
+ # |
31
+ # Foo (not documented)
32
+ # |
33
+ # bar
34
+ #
35
+ # Extending this example with two other comments
36
+ #
37
+ # /**
38
+ # * @object Foo
39
+ # */
40
+ #
41
+ # /**
42
+ # * @object Foo.baz
43
+ # */
44
+ #
45
+ # leads to this tree:
46
+ #
47
+ # ROOT
48
+ # |
49
+ # Foo
50
+ # / \
51
+ # bar baz
52
+ #
53
+ # Now all nodes are documented (i.e. a CodeObject exists for every node) and `Foo`
54
+ # contains two other CodeObjects. `bar` and `baz` are leafs of the tree.
55
+ #
56
+ # Adding a new node to the tree is as simple as:
57
+ #
58
+ # Dom.add_node "Foo.bar", my_code_object
59
+ #
60
+ # Traversing the Tree
61
+ # -------------------
62
+ # There are several method, which you can use to navigate throught the dom. The
63
+ # most important is the {Dom::Node#[] children selector}.
64
+ #
65
+ # The tree above could be traversed using the following operations:
66
+ #
67
+ # Dom[:Foo]
68
+ # #=> #<CodeObject::Base:72903230 @parent=__ROOT__ @children=[:bar, :baz]>
69
+ #
70
+ # Dom[:Foo][:bar]
71
+ # #=> #<CodeObject::Base:72919910 @parent=Foo @children=[]>
72
+ #
73
+ #
74
+ # The Root Node
75
+ # -------------
76
+ # The Dom inherits functionality from it's **root-node**. So all method's
77
+ # invoked on the root node, can be expressed equivalent as member of the Dom.
78
+ #
79
+ # Dom.root[:some_child] <=> Dom[:some_child]
80
+ # Dom.root.children <=> Dom.children
81
+ # Dom.root.print_tree <=> Dom.print_tree
82
+ #
83
+ # Please note, that some methods of the root-node are hidden behind direct
84
+ # implementations.
85
+ #
86
+ # Dom.add_node != Dom.root.add_node
87
+ #
88
+ # For the example above the full UML-Graph, including the root-node, could look
89
+ # like:
90
+ #
91
+ # ![dom tree sample](../uml/dom_tree_sample.svg)
92
+ #
93
+ # @example Adding some Nodes
94
+ # o1 = CodeObject::Object.new "foo"
95
+ # o2 = CodeObject::Object.new "poo"
96
+ # o3 = CodeObject::Object.new "bar"
97
+ # o4 = CodeObject::Object.new "baz"
98
+ # Dom.add_node "foo", o1
99
+ # Dom.add_node "foo.poo", o2
100
+ # Dom.add_node "foo.poo.bar", o3
101
+ # Dom.add_node "foo.poo.baz", o4
102
+ #
103
+ # Dom.print_tree
104
+ # # -foo
105
+ # # -poo
106
+ # # -bar
107
+ # # -baz
108
+ #
109
+ # Using the Dom for Documents
110
+ # -------------------------------
111
+ # The Dom can be used in **two** ways. Because Document-structure can be very similiar to the one
112
+ # of our documentation-elements there are two kind of `root-nodes`:
113
+ #
114
+ # 1. {Dom.root}
115
+ # 2. {Dom.docs}
116
+ #
117
+ # @see Dom::Node
118
+ # @see Dom::NoDoc
119
+ # @see CodeObject::Base
120
+ # @see Document::Document
121
+ module Dom
122
+
123
+ @@cache_path = File.expand_path("../../../cache/dom.cache", __FILE__)
124
+
125
+ @@root = NoDoc.new('__ROOT__')
126
+ @@docs = NoDoc.new('__DOCUMENTS__')
127
+
128
+
129
+ # @group Dom Access-Methods
130
+
131
+ # @return [Dom::NoDoc] The Dom's root-node
132
+ def self.root
133
+ @@root
134
+ end
135
+
136
+ # @group Dom Management Methods
137
+
138
+ # Reset the Dom to it's initial state by creating an empty {.root root-node}
139
+ def self.clear
140
+ @@root = NoDoc.new('__ROOT__')
141
+ end
142
+
143
+ # @group Caching Methods
144
+
145
+ # Serializes and dumps the complete Domtree (but without last_position) to the
146
+ # specified `path`. If no `path` is given, the default `@@cache_path` will be
147
+ # used instead.
148
+ #
149
+ # This Method can be useful, to save a specific state of the Domtree to disk
150
+ # and reuse it later, without the need to reconstruct it from zero.
151
+ #
152
+ # @note To recreate the Dom from the dump-file, use {.load}.
153
+ #
154
+ # @param [String] file the filepath, where to write the serialized data
155
+ def self.dump(file = @@cache_path)
156
+ File.open(file, 'w') do |f|
157
+ f.write Marshal.dump @@root
158
+ end
159
+ end
160
+
161
+ # Loads the {.dump serialized Dom} and replaces the current root node with
162
+ # the one created from the file.
163
+ #
164
+ # @see .dump
165
+ # @param [String] file the filepath from which to load the Dom
166
+ def self.load(file = @@cache_path)
167
+ @@root = Marshal.load(File.read(file))
168
+ end
169
+
170
+ # @group Document Objects
171
+
172
+ # @return [Dom::NoDoc] the root of the Documenttree, consisting of {Document::Document}
173
+ def self.docs
174
+ @@docs
175
+ end
176
+
177
+ protected
178
+
179
+ # try to look up missing methods in @@root
180
+ def self.method_missing(method_name, *args)
181
+ if @@root.respond_to? method_name
182
+ @@root.send method_name, *args
183
+ else
184
+ raise NoMethodError.new(method_name.to_s)
185
+ end
186
+ end
187
+
188
+ end