docjs 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
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
data/README.md CHANGED
@@ -4,81 +4,51 @@ Bad news first: **You still have to write documentation**
4
4
 
5
5
  Good news: **It will look awesome!!**
6
6
 
7
+ Doc.js is a JavaScript-Documentation tool which detects `tokens` in your comments and
8
+ generates documentation out of it. Doc.js could be ported pretty easy to any other
9
+ language, because the most of it's parts are language agnostic.
10
+
11
+ Guides
12
+ ======
13
+ If you read this, you may belong to one of the following four groups:
14
+
15
+ 1. You want to {file:TRY.md try out Doc.js} for the first time
16
+ 2. You need some more {file:USE.md information, how to use Doc.js}
17
+ 3. You want to {file:CUSTOMIZE.md customize Doc.js}, to exactly fit your needs
18
+ 4. You are interested in the {file:ARCHITECTURE.md architectural insides} of Doc.js
7
19
 
8
20
  Supported Ruby-Version
9
21
  ======================
10
- Currently **only ruby > 1.9** is supported. I am working on supporting > 1.8.7, though this is not
11
- my target platform.
22
+ Currently **only ruby > 1.9.x is supported**. Support for 1.8.x is not planned,
23
+ because there are some problems:
24
+
25
+ - UTF-8 Support in parser
26
+ - Intensive use of require_relative
27
+ - Named captures in RegularExpressions
28
+
29
+ For the last two, a rewrite could solve the compatibility issues. Sadly enough
30
+ currently i don't find the time to fix thoses and the first problem in 1.8.x so
31
+ only 1.9 is supported. If you have the time to work on 1.8 compatibility you would
32
+ make me (and possibly some other 1.8 users) very happy.
12
33
 
13
34
 
14
35
  Installation
15
36
  ============
16
37
  gem install docjs
17
38
 
18
-
19
- Required Gems
20
- =============
39
+ Dependencies
40
+ ============
21
41
  The following Gems are required to make docjs work and should automatically be
22
42
  installed while installing docjs:
23
43
 
24
- - thor
25
- - rdiscount
26
-
27
-
28
- Basic Usage
29
- ===========
30
-
31
- Configuration
32
- -------------
33
- Before you can use Doc.js you may create your own **Configuration-File**. This
34
- can easily be done, using the built-in
35
- configuration-generator:
36
-
37
- docjs configure
38
-
39
- You optionally can specify the filename of your configuration file. If no file
40
- is specified the configs will be written to `build.yml`.
41
-
42
- docjs configure my_config_file.yml
44
+ - thor
45
+ - rdiscount
43
46
 
44
- The configuration is an interactive one - simply answer the questions you will
45
- be asked.
46
47
 
47
-
48
- Start documenting your code
49
- ---------------------------
50
- To make jsdoc recognize your documentation you have to use some special tokens.
51
- Let's write a documented function `hello_doc`:
52
-
53
- /**
54
- * @function hello_doc
55
- *
56
- * Innovative function to greet a Person.
57
- *
58
- * @param [String] name the person you want to greet
59
- * @return void
60
- */
61
- function hello_doc(name) {
62
- console.log("Hello " + name + "!");
63
- }
64
-
65
- The symbols `@function`, `@param` and `@return` are called **tokens** in Doc.js.
66
- There are many more by default. To see which one you can use simply type:
67
-
68
- docjs tokens
69
-
70
-
71
- Run the documentation and enjoy!
72
- --------------------------------
73
- Now it's time to kickoff the documentation-process by typing:
74
-
75
- docjs your_config.yml
76
-
77
- You will find the docs in the output-directory you have specified in your
78
- config-file.
79
-
80
-
81
- Legal Notice
82
- ============
48
+ Legal Notice & Contact
49
+ ======================
83
50
  docjs is released under MIT-License. See LICENSE.md for more information.
84
- The used icons, are part of the legendary famfamfam-silk-iconset. (http://www.famfamfam.com/lab/icons/silk/)
51
+ The used icons, are part of the legendary [famfamfam-silk-iconset](http://www.famfamfam.com/lab/icons/silk/).
52
+
53
+ For further information about contacting me, please visit my personal [blog](http://b-studios.de).
54
+ Of course you are also invited to [follow me on twitter](http://twitter.com/#!/__protected).
data/bin/docjs CHANGED
@@ -25,15 +25,37 @@ Configs.set :root => Pathname.new(__FILE__).realpath + '../..'
25
25
  #
26
26
  # @note options declared in a docjs.yml will override command-line ones
27
27
  class DocJs < Thor
28
-
28
+
29
29
  include Thor::Actions
30
+
31
+ def help(task = nil)
32
+
33
+ # Introduction
34
+ unless task
35
+ say "Welcome to Doc.js", :bold
36
+ say "If you are using Doc.js for the first time in your project, you may want to create a config file (like docjs.yml)
37
+ A guided wizard can help you achieving this goal - Simply run the following command:
38
+ docjs configure
39
+ \n
40
+ After creating a config-file (like docjs.yml) the documentation can be generated by running:
41
+ docjs docjs.yml
42
+
43
+ For further information, please visit http://b-studios.github.com/doc.js\n\n"
44
+
45
+ self.class.help(shell, false)
46
+
47
+ # Help for a specific task
48
+ else
49
+ self.class.task_help(shell, task)
50
+ end
51
+ end
30
52
 
31
53
  desc "CONFIG_FILE", "Starts documentation process"
32
54
  set_options :files =>
33
- { :type => :array, :aliases => '-f', :default => [], :required => true },
55
+ { :type => :array, :aliases => '-f', :default => [] },
34
56
 
35
57
  :docs =>
36
- { :type => :array, :aliases => '-d', :default => ['README.md'], :required => true },
58
+ { :type => :array, :aliases => '-d', :default => ['README.md'] },
37
59
 
38
60
  :output =>
39
61
  { :type => :string, :aliases => '-o', :default => 'out' },
@@ -209,16 +231,16 @@ class DocJs < Thor
209
231
 
210
232
 
211
233
 
212
- desc "tasks TEMPLATE_PATH?", "Lists all registered render-tasks\nNeeds your TEMPLATE_PATH to include your own custom tokens. If TEMPLATE_PATH is ommitted, only the default-tokens will be shown"
213
- def tasks(template_path = nil)
234
+ desc "generators TEMPLATE_PATH?", "Lists all registered generators\nNeeds your TEMPLATE_PATH to include your own generators."
235
+ def generators(template_path = nil)
214
236
 
215
237
  load_templates template_path
216
238
 
217
- say "Registered render-tasks:"
239
+ say "Registered Generators:"
218
240
 
219
- task_table = Tasks::RenderTask.all.map{|task| ["#{task.name}","# #{task.description}"] }.sort
241
+ gen_table = Generator::Generator.all.map{|gen| ["#{gen.name}","# #{gen.description}"] }.sort
220
242
 
221
- print_table task_table, :ident => 2, :colwidth => 20
243
+ print_table gen_table, :ident => 2, :colwidth => 40
222
244
  end
223
245
  end
224
246
 
@@ -25,15 +25,37 @@ Configs.set :root => Pathname.new(__FILE__).realpath + '../..'
25
25
  #
26
26
  # @note options declared in a docjs.yml will override command-line ones
27
27
  class DocJs < Thor
28
-
28
+
29
29
  include Thor::Actions
30
+
31
+ def help(task = nil)
32
+
33
+ # Introduction
34
+ unless task
35
+ say "Welcome to Doc.js", :bold
36
+ say "If you are using Doc.js for the first time in your project, you may want to create a config file (like docjs.yml)
37
+ A guided wizard can help you achieving this goal - Simply run the following command:
38
+ docjs configure
39
+ \n
40
+ After creating a config-file (like docjs.yml) the documentation can be generated by running:
41
+ docjs docjs.yml
42
+
43
+ For further information, please visit http://b-studios.github.com/doc.js\n\n"
44
+
45
+ self.class.help(shell, false)
46
+
47
+ # Help for a specific task
48
+ else
49
+ self.class.task_help(shell, task)
50
+ end
51
+ end
30
52
 
31
53
  desc "CONFIG_FILE", "Starts documentation process"
32
54
  set_options :files =>
33
- { :type => :array, :aliases => '-f', :default => [], :required => true },
55
+ { :type => :array, :aliases => '-f', :default => [] },
34
56
 
35
57
  :docs =>
36
- { :type => :array, :aliases => '-d', :default => ['README.md'], :required => true },
58
+ { :type => :array, :aliases => '-d', :default => ['README.md'] },
37
59
 
38
60
  :output =>
39
61
  { :type => :string, :aliases => '-o', :default => 'out' },
@@ -209,16 +231,16 @@ class DocJs < Thor
209
231
 
210
232
 
211
233
 
212
- desc "tasks TEMPLATE_PATH?", "Lists all registered render-tasks\nNeeds your TEMPLATE_PATH to include your own custom tokens. If TEMPLATE_PATH is ommitted, only the default-tokens will be shown"
213
- def tasks(template_path = nil)
234
+ desc "generators TEMPLATE_PATH?", "Lists all registered generators\nNeeds your TEMPLATE_PATH to include your own generators."
235
+ def generators(template_path = nil)
214
236
 
215
237
  load_templates template_path
216
238
 
217
- say "Registered render-tasks:"
239
+ say "Registered Generators:"
218
240
 
219
- task_table = Tasks::RenderTask.all.map{|task| ["#{task.name}","# #{task.description}"] }.sort
241
+ gen_table = Generator::Generator.all.map{|gen| ["#{gen.name}","# #{gen.description}"] }.sort
220
242
 
221
- print_table task_table, :ident => 2, :colwidth => 20
243
+ print_table gen_table, :ident => 2, :colwidth => 40
222
244
  end
223
245
  end
224
246
 
@@ -4,8 +4,8 @@ Gem::Specification.new do |s|
4
4
 
5
5
 
6
6
  s.name = 'docjs'
7
- s.version = '0.1.4'
8
- s.date = '2011-06-17'
7
+ s.version = '0.1.5'
8
+ s.date = '2011-06-25'
9
9
  s.summary = "Javascript Documentation Generator"
10
10
  s.description = "Create beautyful Javascript documentations with this ruby-gem. It's pretty easy to customize and add your own tokens/DSL."
11
11
  s.homepage = "https://github.com/b-studios/doc.js"
File without changes
File without changes
@@ -3,9 +3,8 @@ Fullqualifier
3
3
  Like an absolute path (/etc/init.d/apache2) we use `FOO.bar` as fullqualifier to
4
4
  an object or function.
5
5
 
6
- A leading dot suggests filling the empty leading space with the current parsing-context
7
- without modifying it. As such `.something_else` would be resolved to
8
- `FOO.bar.something_else` in the current context.
6
+ A leading dot suggests filling the empty leading space with the current parsing-context.
7
+ As such `.something_else` would be resolved to `FOO.bar.something_else` in the current context.
9
8
 
10
9
  Examplecode:
11
10
 
@@ -38,4 +37,3 @@ Examplecode:
38
37
  property_of_the: "returned object"
39
38
  };
40
39
  }
41
-
@@ -0,0 +1,101 @@
1
+ Documentation Patterns
2
+ ======================
3
+ There are some widely used patterns in JavaScript that need a proper way of documentation.
4
+
5
+ Prototypal Inheritance
6
+ ----------------------
7
+ Because most of the times (this is my personal impression) prototypal inheritence is used like in
8
+ the following example, Doc.js is specialized for that kind of prototyping.
9
+
10
+ /**
11
+ * @constructor Person
12
+ * This is the constructor for a Person. Just like you and me.
13
+ *
14
+ * @param [String] name The name of the person
15
+ * @param [Number] age
16
+ */
17
+ function Person(name, age) {
18
+ this.name = name;
19
+ this.age = age;
20
+ }
21
+
22
+ /**
23
+ * @prototype Person
24
+ */
25
+ Person.prototype = {
26
+
27
+ /**
28
+ * @object .configs
29
+ * @prop [Boolean] friendly
30
+ */
31
+ configs: {
32
+ friendly: true
33
+ },
34
+
35
+ /**
36
+ * @method .sayHello
37
+ */
38
+ sayHello: function() {
39
+ if(this.friendly)
40
+ console.log("Hello " + this.name);
41
+
42
+ else console.log("Grmppfbra!");
43
+ }
44
+
45
+ }
46
+
47
+ Of course the usage of prototypes can easiliy be modified. For example to use prototype as a
48
+ property like
49
+
50
+ /**
51
+ * @constructor Collection
52
+ * @prototype Array.prototype
53
+ */
54
+ function() {
55
+ ...
56
+ }
57
+
58
+ you have to delete the CodeObject::Prototype in `types/prototype.rb` and then register a token like
59
+
60
+ register :prototype, :area => :none
61
+
62
+
63
+
64
+ Revealing Module Pattern
65
+ ------------------------
66
+ The Revealing Module Pattern is a way of declaring some properties of an object as **private** and
67
+ reveal only the public ones. This can be documented like the following:
68
+
69
+ /**
70
+ * @constructor Person
71
+ * @param [String] name
72
+ */
73
+ function Person(name) {
74
+
75
+
76
+ var methods = {
77
+
78
+ /**
79
+ * @method .eatPizza
80
+ * @private
81
+ */
82
+ eatPizza: function() {
83
+ ...mhh...
84
+ }
85
+ }
86
+
87
+ return {
88
+
89
+ /**
90
+ * @method .sayHello
91
+ * Outputs a cheerfull greeting, containing the person's name
92
+ */
93
+ sayHello: function() {
94
+ console.log("Hello, from " + name)
95
+ }
96
+ };
97
+
98
+ }
99
+
100
+ Ommiting the comment of the private function `eatPizza` would exclude it from the documentation. This
101
+ may be the disired way of documenting for example a API-Documentation.
@@ -0,0 +1,158 @@
1
+ Areas
2
+ =====
3
+ To visually group the tokens you can specify an area. All tokens for one area (`:sidebar` in this
4
+ example) will be collected and can be rendered in the view-templates with the
5
+ {Helper::Helper#render_tokens render_tokens} helper-method.
6
+
7
+ render_tokens :of => @code_object, :in => :sidebar
8
+
9
+ While {Token::Handler.register registering a new token} you can use any symbol for `area`. But your tokens may not appear in
10
+ the rendered html-documentation, unless you explicitly call `render_tokens` for each area.
11
+
12
+ The default-templates make use of the following areas:
13
+
14
+ - :notification
15
+ - :body
16
+ - :sidebar
17
+ - :footnote
18
+
19
+ If you don't want your token to be rendered at all, you can use `:none` as value for `area`.
20
+
21
+ register :your_token, :area => :none
22
+
23
+
24
+
25
+ 1. Example - Adding a simple token
26
+ ==================================
27
+ You can extend Doc.js on different levels. The easiest way of customization is to add a simple token.
28
+ Let's say we want to add a new innovative token `@requires` to specify dependencies to other objects.
29
+
30
+ /**
31
+ * @function say_hello
32
+ * @requires console.log
33
+ */
34
+
35
+ If we start Doc.js without making any changes to the templates this documentation will result in an
36
+ error like **ERROR No Tokenhandler for: @requires**.
37
+ So let's register our tokenhandler to `tokens/tokens.rb`:
38
+
39
+ register :requires
40
+
41
+
42
+ Changing the area
43
+ -----------------
44
+ The token will now be processed using the {Token::Handler :text_only} tokenhandler and will appear
45
+ in the `:body` section of the template. Because `requires` may fit much better in the `:sidebar`
46
+ section (it contains meta-information about the object) we place it there with
47
+
48
+ register :requires, :area => :sidebar
49
+
50
+ Now our token should be displayed nicely in the sidebar-area on the right side (if you are using the
51
+ default template).
52
+
53
+
54
+ Using another tokenhandler
55
+ --------------------------
56
+ While using our new token, we may notice, that it would be nice if we can specify some detailed
57
+ information about the dependency like:
58
+
59
+ /**
60
+ * @function say_hello
61
+ * @requires console.log for printing the message to the console
62
+ */
63
+
64
+ So we have to change the tokenhandler to `:named` because our tokenline now consists of a `name`
65
+ and the description-`content`.
66
+
67
+ register :requires, :area => :sidebar, :handler => :named
68
+
69
+ The template, which renders the token now can access the `name` and the `content` of the token
70
+ seperatly and displays them somehow like:
71
+
72
+ <h4>console.log</h4>
73
+ <p>for printing the message to the console</p>
74
+
75
+
76
+ Creating a custom template
77
+ --------------------------
78
+ We've come pretty far with just adding one line to our own templates. But now we want to use our own
79
+ template for this token, because the title isn't automatically linked, if the required object exists
80
+ in our documentation. Because this would be a cool features, let's implement it.
81
+
82
+ First of all we have to create our partial. Like all other templates, the token-partials are located
83
+ under `views/tokens`. So we create a file called `views/tokens/_requires.html.erb` and fill in some
84
+ content:
85
+
86
+ <section>
87
+ <h3>Dependencies</h3>
88
+ <ul>
89
+ <% tokens.each do |token| %>
90
+ <li>
91
+ <h4><%=link_to token.name %></h4>
92
+ <%=to_html token.content %>
93
+ </li>
94
+ <% end %>
95
+ </ul>
96
+ </section>
97
+
98
+ Because all tokens of one type are rendered as a collection by default, we have to iterate over our
99
+ local-variable `tokens`. We use the {Helper::Linker#link_to link_to} helper to create a link to the
100
+ referenced dependency if it exists in our documentation. Additionally we use the
101
+ {Helper::Helper#to_html to_html} helper to convert the description (which could be written using
102
+ markdown and contain links we need to generate) to html.
103
+
104
+ Last thing we have to do, is to make the renderer use our new template for `@requires` tokens
105
+
106
+ register :requires, :area => :sidebar, :handler => :named, :template => :requires
107
+
108
+
109
+ 2. Example - Writing your own token-handler
110
+ ===========================================
111
+ There are a {Token::Handler few handlers}, which can be used to process the tokenlines. But sometimes
112
+ one of the existing handlers isn't enough to process your token.
113
+
114
+ Let's say we need a tokenhandler to parse something like
115
+
116
+ /**
117
+ * @special [String] my_name (default) description
118
+ */
119
+
120
+ We could get pretty close using the :typed_with_name handler. But this handler doesn't recognizes
121
+ defaults, so we need to write our own handler.
122
+
123
+ First of all we register our token in `tokens/tokens.rb`.
124
+
125
+ register :special do |tokenklass, content|
126
+ # currently the textual content is only stored as `content`
127
+ self.add_token token_klass.new(:content => stringcontent)
128
+ end
129
+
130
+ Next let's write a Regexp, that recognizes our parts. (Ok, that regular expression may not be the
131
+ most beautiful one, but it may work)
132
+
133
+ register :special do |token_klass, content|
134
+
135
+ TYPED_NAMED_WITH_DEFAULTS = /\[([^\]\n]+)\]\s*([\w_.:]+)\s(?:\(([^\)]+)\))?\s*(.*)/
136
+
137
+ types, name, default, content = TYPED_NAMED_WITH_DEFAULTS.match(content).captures
138
+ token = token_klass.new(:name => name, :types => types.split(','), :content => content)
139
+ token.define_singleton_method(:default) { default }
140
+
141
+ self.add_token token
142
+ end
143
+
144
+ Because :default isn't a default property of token, we have to add it manually by defining a
145
+ method which returns the value (`define_singleton_method`).
146
+
147
+ The last thing, we would have to do is to create a custom template and use it. See
148
+ {file:CUSTOMIZE.md#Creating_a_custom_template above} for tipps how to achieve this.
149
+ The template could make use of `token.default` to access the default value parsed by our cool
150
+ token-handler.
151
+
152
+ 3. Example - Creating the custom type `class`
153
+ =============================================
154
+ If you want to create your own Domain specific language (DSL) it's often not enough to add new tokens
155
+ and manipulate the templates. Sometimes you need to create your own custom types of objects. For
156
+ example maybe you could need classes, packages or mixins. So in this example we will create a type
157
+ called `class`.
158
+