yard-appendix 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +3 -0
- data/LICENSE +7 -0
- data/README.md +115 -0
- data/lib/yard-appendix/code_objects/appendix_object.rb +38 -0
- data/lib/yard-appendix/handlers/appendix_handler.rb +49 -0
- data/lib/yard-appendix/namespace_resolver.rb +149 -0
- data/lib/yard-appendix/tags/appendix_directive.rb +92 -0
- data/lib/yard-appendix/templates/helpers/html_helper.rb +120 -0
- data/lib/yard-appendix/version.rb +27 -0
- data/lib/yard-appendix.rb +46 -0
- data/spec/code_objects/appendix_object_spec.rb +66 -0
- data/spec/handlers/appendix_handler_spec.rb +117 -0
- data/spec/spec_helper.rb +44 -0
- data/spec/tags/appendix_directive_spec.rb +137 -0
- data/spec/templates/helpers/html_helper_spec.rb +70 -0
- data/templates/default/appendix/html/setup.rb +26 -0
- data/templates/default/module/html/setup.rb +4 -0
- data/yard-appendix.gemspec +25 -0
- metadata +100 -0
data/.rspec
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
Copyright (c) 2013 Instructure, Inc.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
4
|
+
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
6
|
+
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
# yard-appendix
|
2
|
+
|
3
|
+
[![Build Status](https://travis-ci.org/amireh/yard-appendix.png)](https://travis-ci.org/amireh/yard-appendix)
|
4
|
+
|
5
|
+
A YARD plugin that adds support for Appendix sections like ones you find in books and papers. Appendix entries provide you with a very convenient place to write supplementary documentation, references, or advanced-usage content, that would otherwise clutter up (or even seem unrelated) a certain method or class inline-documentation.
|
6
|
+
|
7
|
+
## Usage
|
8
|
+
|
9
|
+
The plugin defines a `@!appendix` directive that lets you write the appendix entry with a title. You can link to in your docstrings using the explicit `@see` tag, or an inline reference as in: `(see {path to appendix})`.
|
10
|
+
|
11
|
+
**Defining appendices**
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
class SomeClass
|
15
|
+
# your methods here
|
16
|
+
def foo()
|
17
|
+
end
|
18
|
+
|
19
|
+
# @!appendix Title
|
20
|
+
#
|
21
|
+
# Appendix body goes here.
|
22
|
+
end
|
23
|
+
```
|
24
|
+
|
25
|
+
**Referencing appendix entries**
|
26
|
+
|
27
|
+
Referencing appendices is done by prefixing the appendix title with `Appendix: `. To reference the appendix defined above with the title `Title`:
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
class SomeClass
|
31
|
+
# foo() brief
|
32
|
+
#
|
33
|
+
# Inline reference: (see {Appendix: Title})
|
34
|
+
#
|
35
|
+
# Explicit reference:
|
36
|
+
#
|
37
|
+
# @see Appendix: Title
|
38
|
+
def foo()
|
39
|
+
end
|
40
|
+
|
41
|
+
# ...
|
42
|
+
end
|
43
|
+
```
|
44
|
+
|
45
|
+
**Note**: you can define the appendix entry wherever you want; they can be attached to a node or "free", at the bottom of the module or class definition.
|
46
|
+
|
47
|
+
## Example
|
48
|
+
|
49
|
+
Let's say you're writing an API controller that serves and manages Bananas in your warehouse. One of the methods is called `serve_fried_bananas()` and you want to provide some background about fried bananas that:
|
50
|
+
|
51
|
+
1. is too long and would clutter up the rest of the method's documentation
|
52
|
+
2. contains supplementary content that only users with specific uses of the method need to know about
|
53
|
+
|
54
|
+
We will instead define an appendix titled `Fried Bananas`, and in our method's docstring we will reference that appendix for the user to check out.
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
module FruitAPI
|
58
|
+
|
59
|
+
class BananaController
|
60
|
+
# Explain why one would want a fried banana, what it would do
|
61
|
+
# to their health and self-esteem, and any side-effects one
|
62
|
+
# would enjoy.
|
63
|
+
#
|
64
|
+
# @see Appendix: Fried Bananas
|
65
|
+
def serve_fried_bananas
|
66
|
+
end
|
67
|
+
|
68
|
+
# @!appendix Fried Bananas
|
69
|
+
#
|
70
|
+
# This entry will be displayed at the bottom of the class'
|
71
|
+
# documentation page, under a separate section aptly named
|
72
|
+
# 'Appendixes'.
|
73
|
+
#
|
74
|
+
# You can use tags and directives here just like you would in
|
75
|
+
# any other docstring.
|
76
|
+
#
|
77
|
+
# @example A fried banana in JSON
|
78
|
+
# {
|
79
|
+
# "id": 1,
|
80
|
+
# "type": "fried",
|
81
|
+
# "frying_level": "atomic"
|
82
|
+
# }
|
83
|
+
#
|
84
|
+
# You can also reference other appendices: {Appendix: Fruit}
|
85
|
+
|
86
|
+
# @!appendix Fruit
|
87
|
+
#
|
88
|
+
# ...
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
```
|
93
|
+
|
94
|
+
### Other stuff
|
95
|
+
|
96
|
+
You can run the specs using RSpec:
|
97
|
+
|
98
|
+
```bash
|
99
|
+
cd /path/to/yard-appendix; rspec spec/
|
100
|
+
```
|
101
|
+
|
102
|
+
And you can generate the docs using YARD:
|
103
|
+
|
104
|
+
```bash
|
105
|
+
cd /path/to/yard-appendix; yardoc
|
106
|
+
```
|
107
|
+
|
108
|
+
## License
|
109
|
+
Copyright (c) 2013 Instructure, Inc.
|
110
|
+
|
111
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
112
|
+
|
113
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
114
|
+
|
115
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@@ -0,0 +1,38 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2013 Instructure, Inc.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a
|
5
|
+
# copy of this software and associated documentation files (the "Software"),
|
6
|
+
# to deal in the Software without restriction, including without limitation
|
7
|
+
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
8
|
+
# and/or sell copies of the Software, and to permit persons to whom the
|
9
|
+
# Software is furnished to do so, subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
12
|
+
# all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
17
|
+
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
20
|
+
# SOFTWARE.
|
21
|
+
#
|
22
|
+
|
23
|
+
require 'yard/code_objects/base'
|
24
|
+
|
25
|
+
module YARD
|
26
|
+
module CodeObjects
|
27
|
+
|
28
|
+
# An object that is spawned by the @!appendix directive.
|
29
|
+
#
|
30
|
+
# @see YARD::Tags::AppendixDirective
|
31
|
+
class AppendixObject < Base
|
32
|
+
def type; :appendix end
|
33
|
+
def title; "Appendix: #{name}" end
|
34
|
+
def path; ".#{type}.#{namespace && namespace.path}.#{name}" end
|
35
|
+
def to_s; "#{name}-appendix" end
|
36
|
+
end # AppendixObject
|
37
|
+
end # CodeObjects
|
38
|
+
end # YARD
|
@@ -0,0 +1,49 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2013 Instructure, Inc.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a
|
5
|
+
# copy of this software and associated documentation files (the "Software"),
|
6
|
+
# to deal in the Software without restriction, including without limitation
|
7
|
+
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
8
|
+
# and/or sell copies of the Software, and to permit persons to whom the
|
9
|
+
# Software is furnished to do so, subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
12
|
+
# all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
17
|
+
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
20
|
+
# SOFTWARE.
|
21
|
+
#
|
22
|
+
|
23
|
+
require 'yard/handlers/ruby/comment_handler'
|
24
|
+
|
25
|
+
module YARD
|
26
|
+
module Handlers
|
27
|
+
module Ruby
|
28
|
+
# Tracks every namespace defining statement and registers
|
29
|
+
# it with the NamespaceResolver.
|
30
|
+
#
|
31
|
+
# @see YARD::AppendixPlugin::NamespaceResolver
|
32
|
+
class AppendixHandler < CommentHandler
|
33
|
+
handles :class, :module
|
34
|
+
|
35
|
+
def initialize(*args)
|
36
|
+
super(*args)
|
37
|
+
|
38
|
+
globals.resolver ||= YARD::AppendixPlugin::NamespaceResolver.new
|
39
|
+
end
|
40
|
+
|
41
|
+
def process
|
42
|
+
globals.resolver.register_namespace(statement, namespace)
|
43
|
+
end
|
44
|
+
end # AppendixHandler
|
45
|
+
|
46
|
+
CommentHandler.inherited(AppendixHandler)
|
47
|
+
end # Ruby
|
48
|
+
end # Handlers
|
49
|
+
end # YARD
|
@@ -0,0 +1,149 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2013 Instructure, Inc.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a
|
5
|
+
# copy of this software and associated documentation files (the "Software"),
|
6
|
+
# to deal in the Software without restriction, including without limitation
|
7
|
+
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
8
|
+
# and/or sell copies of the Software, and to permit persons to whom the
|
9
|
+
# Software is furnished to do so, subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
12
|
+
# all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
17
|
+
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
20
|
+
# SOFTWARE.
|
21
|
+
#
|
22
|
+
|
23
|
+
module YARD
|
24
|
+
module AppendixPlugin
|
25
|
+
|
26
|
+
# This class is a necessary hack for locating the namespaces in which
|
27
|
+
# comments that are not tied to any CodeObjects were defined.
|
28
|
+
#
|
29
|
+
# The issue has been reported as a bug in Ripper and until it is solved,
|
30
|
+
# this is required to work around it.
|
31
|
+
class NamespaceResolver
|
32
|
+
attr_reader :namespaces
|
33
|
+
|
34
|
+
def initialize()
|
35
|
+
@namespaces ||= {}
|
36
|
+
|
37
|
+
super()
|
38
|
+
end
|
39
|
+
|
40
|
+
# Tracks the namespace the namespace-defining statement (such as class or module)
|
41
|
+
# was registered in. This registry is used to map between free comment statements
|
42
|
+
# and the namespace they're actually defined in.
|
43
|
+
#
|
44
|
+
# @param [Parser::Ruby::ClassNode, Parser::Ruby::ModuleNode] statement
|
45
|
+
# the namespace defining statement
|
46
|
+
# @param [CodeObjects::NamespaceObject] ns the namespace object the YARD handler processor
|
47
|
+
# was tracking when the statement was parsed
|
48
|
+
#
|
49
|
+
# @return [void]
|
50
|
+
#
|
51
|
+
# @see namespace_for
|
52
|
+
#
|
53
|
+
# @note
|
54
|
+
# Internally called by the AppendixHandler whenever a new namespace object
|
55
|
+
# is encountered.
|
56
|
+
def register_namespace(statement, ns)
|
57
|
+
klass_name = path_from_ast(statement, ns)
|
58
|
+
|
59
|
+
# already registered?
|
60
|
+
return if @namespaces[klass_name]
|
61
|
+
|
62
|
+
klass_path = path_from_ast(statement, ns, true)
|
63
|
+
|
64
|
+
log.debug "yard-appendix: registering path for namespace '#{klass_name}' => #{klass_path}"
|
65
|
+
|
66
|
+
@namespaces[klass_name] = klass_path
|
67
|
+
end
|
68
|
+
|
69
|
+
# Attempts to locate the enclosing namespace for the given
|
70
|
+
# statement. This is useful only for comment statements which
|
71
|
+
# are parsed by Ripper in a strange non-linear fashion that does not
|
72
|
+
# correlate with the namespace they're defined in.
|
73
|
+
#
|
74
|
+
# @param [YARD::Parser::Ruby::AstNode] statement the enclosed CommentNode
|
75
|
+
# (or any other type, really)
|
76
|
+
# @param [YARD::CodeObjects::NamespaceObject] ns the handler's current namespace
|
77
|
+
# @return [CodeObjects::NamespaceObject] the enclosing namespace object
|
78
|
+
def namespace_for(statement, ns)
|
79
|
+
YARD::Registry.at(locate_enclosing_ns(statement, ns))
|
80
|
+
end
|
81
|
+
|
82
|
+
protected
|
83
|
+
|
84
|
+
# Attempts to locate the enclosing namespace for the given
|
85
|
+
# statement. This is useful only for comment statements which
|
86
|
+
# are parsed by Ripper in a strange non-linear fashion that does not
|
87
|
+
# correlate with the namespace they're defined in.
|
88
|
+
#
|
89
|
+
# @param [YARD::Parser::Ruby::AstNode] statement the enclosed CommentNode
|
90
|
+
# (or any other type, really)
|
91
|
+
# @param [YARD::CodeObjects::NamespaceObject] ns the handler's current namespace
|
92
|
+
# @return [String] a Registry path to the enclosing namespace object
|
93
|
+
#
|
94
|
+
# @note
|
95
|
+
# You shouldn't need to use this directly. Use #namespace_for instead.
|
96
|
+
#
|
97
|
+
# @see #namespace_for
|
98
|
+
def locate_enclosing_ns(statement, ns)
|
99
|
+
|
100
|
+
unless ns || CodeObjects::NamespaceObject === ns || String === ns
|
101
|
+
raise ArgumentError.new "A valid NamespaceObject must be passed."
|
102
|
+
end
|
103
|
+
|
104
|
+
if ns.is_a?(String)
|
105
|
+
ns = YARD::Registry.at(ns)
|
106
|
+
end
|
107
|
+
|
108
|
+
lines_to_namespaces = {}
|
109
|
+
statement.parent.traverse { |ast|
|
110
|
+
next unless [:module, :class].include?(ast.type)
|
111
|
+
|
112
|
+
if ast.line_range.include?(statement.line)
|
113
|
+
lines_to_namespaces[ast.line] = ast
|
114
|
+
end
|
115
|
+
}
|
116
|
+
|
117
|
+
closest = {}
|
118
|
+
lines_to_namespaces.each_pair { |line, ast|
|
119
|
+
distance = statement.line - line
|
120
|
+
if closest.empty? || distance < closest[:distance]
|
121
|
+
closest = { node: ast, distance: distance }
|
122
|
+
end
|
123
|
+
}
|
124
|
+
|
125
|
+
path_to(closest[:node], ns)
|
126
|
+
end
|
127
|
+
|
128
|
+
def path_from_ast(node, ns, fully_qualified = false)
|
129
|
+
path = ''
|
130
|
+
|
131
|
+
if fully_qualified
|
132
|
+
unless ns.to_s.empty? || ns.to_s == 'root'
|
133
|
+
path = ns.to_s + '::'
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
path += case node.type
|
138
|
+
when :class; node.class_name.path.first
|
139
|
+
when :module; node.module_name.path.first
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def path_to(ast, ns)
|
144
|
+
(ast && @namespaces[path_from_ast(ast, ns)]) || ns.to_s
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2013 Instructure, Inc.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a
|
5
|
+
# copy of this software and associated documentation files (the "Software"),
|
6
|
+
# to deal in the Software without restriction, including without limitation
|
7
|
+
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
8
|
+
# and/or sell copies of the Software, and to permit persons to whom the
|
9
|
+
# Software is furnished to do so, subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
12
|
+
# all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
17
|
+
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
20
|
+
# SOFTWARE.
|
21
|
+
#
|
22
|
+
|
23
|
+
require 'yard/tags/directives'
|
24
|
+
|
25
|
+
module YARD
|
26
|
+
module Tags
|
27
|
+
|
28
|
+
# Defines a @!appendix directive that allows writing Appendix
|
29
|
+
# entries which will be attached to the end of the namespace's
|
30
|
+
# output, similar to appendixes in books or documents.
|
31
|
+
#
|
32
|
+
# @example Appendix definition syntax
|
33
|
+
# module SomeModule
|
34
|
+
# # @!appendix Title
|
35
|
+
# #
|
36
|
+
# # Appendix body.
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
# @note When defining an appendix entry, there's no need to
|
40
|
+
# prefix its name with 'Appendix: ' as that is automatically
|
41
|
+
# done for you.
|
42
|
+
#
|
43
|
+
# @example Defining an appendix titled 'API Response Codes'
|
44
|
+
#
|
45
|
+
# class BananaAPIController
|
46
|
+
# # Explain why one would want a fried banana, what it would do
|
47
|
+
# # to their health and self-esteem, and any side-effects one
|
48
|
+
# # would enjoy.
|
49
|
+
# #
|
50
|
+
# # @see Appendix: API Response Codes
|
51
|
+
# def serve_fried_bananas
|
52
|
+
# end
|
53
|
+
#
|
54
|
+
# # @!appendix API Response Codes
|
55
|
+
# #
|
56
|
+
# # The following map explains the HTTP response codes returned
|
57
|
+
# # by our servers and how you should treat them:
|
58
|
+
# #
|
59
|
+
# # 1. 200 -> a banana is available
|
60
|
+
# # 1. 403 -> that banana is super exclusive
|
61
|
+
# # 1. 404 -> no such banana, verify the ID
|
62
|
+
# end
|
63
|
+
#
|
64
|
+
# You can also reference the appendix identified by `Title` in
|
65
|
+
# other parts of your namespace documentation strings by using
|
66
|
+
# the @see tag. See the "See Also" link for more info about
|
67
|
+
# referencing appendices.
|
68
|
+
#
|
69
|
+
# @see YARD::AppendixPlugin::AppendixLinker
|
70
|
+
class AppendixDirective < Directive
|
71
|
+
|
72
|
+
def statement; handler.statement; end
|
73
|
+
def namespace; handler.namespace; end
|
74
|
+
def resolver; handler.globals.resolver; end
|
75
|
+
|
76
|
+
def call
|
77
|
+
# no resolver? then use the handler's namespace
|
78
|
+
comment_ns = handler.namespace
|
79
|
+
|
80
|
+
if resolver
|
81
|
+
comment_ns = resolver.namespace_for(statement, namespace)
|
82
|
+
log.debug "yard-appendix: appendix #{tag.name} will be enclosed under #{comment_ns}"
|
83
|
+
end
|
84
|
+
|
85
|
+
log.info "yard-appendix: appendix #{tag.name} has been registered under #{comment_ns.name}"
|
86
|
+
appendix = CodeObjects::AppendixObject.new(comment_ns, tag.name)
|
87
|
+
handler.register_docstring appendix, tag.text
|
88
|
+
handler.register_file_info appendix
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2013 Instructure, Inc.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a
|
5
|
+
# copy of this software and associated documentation files (the "Software"),
|
6
|
+
# to deal in the Software without restriction, including without limitation
|
7
|
+
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
8
|
+
# and/or sell copies of the Software, and to permit persons to whom the
|
9
|
+
# Software is furnished to do so, subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
12
|
+
# all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
17
|
+
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
20
|
+
# SOFTWARE.
|
21
|
+
#
|
22
|
+
|
23
|
+
require 'yard/templates/helpers/html_helper'
|
24
|
+
|
25
|
+
module YARD
|
26
|
+
module AppendixPlugin
|
27
|
+
module AppendixLinker
|
28
|
+
|
29
|
+
# Handles reference links to Appendix objects in @see tags
|
30
|
+
# by printing out their readable titles in the anchor text and tooltip.
|
31
|
+
#
|
32
|
+
# Delegates to YARD::Templates::Helpers::HtmlHelper#linkify if
|
33
|
+
# the @see tag syntax does not qualify as an appendix one.
|
34
|
+
#
|
35
|
+
# @example Referencing appendix objects:
|
36
|
+
#
|
37
|
+
# # Some method description.
|
38
|
+
# # ...
|
39
|
+
# # @see Appendix: Bananas
|
40
|
+
# def some_method()
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# Note that the syntax expected is `@see Appendix: APPENDIX_NAME` where
|
44
|
+
# only the `APPENDIX_NAME` is variable.
|
45
|
+
#
|
46
|
+
# @note
|
47
|
+
# Appendix links will be resolved only within the namespace they're defined in (class or module).
|
48
|
+
#
|
49
|
+
def linkify(link, *args)
|
50
|
+
if link == 'Appendix:' && !args.empty?
|
51
|
+
if res = link_appendix(args.first)
|
52
|
+
return res
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
super(link, *args)
|
57
|
+
end
|
58
|
+
|
59
|
+
def link_appendix(in_title)
|
60
|
+
appendix, title = nil, in_title.to_s.strip.to_sym
|
61
|
+
ns = nil # used for reporting in case we couldn't locate it
|
62
|
+
|
63
|
+
if object
|
64
|
+
# try in the object scope
|
65
|
+
ns = object
|
66
|
+
appendix = YARD::Registry.at(".appendix.#{object.path}.#{title}")
|
67
|
+
|
68
|
+
# try in the object's namespace scope
|
69
|
+
if appendix.nil? && object.respond_to?(:namespace)
|
70
|
+
ns = object.namespace
|
71
|
+
appendix = YARD::Registry.at(".appendix.#{object.namespace.path}.#{title}")
|
72
|
+
end
|
73
|
+
# else
|
74
|
+
# this shouldn't happen (use stub!(:object) in specs)
|
75
|
+
# appendix = YARD::Registry.all(:appendix).select { |a| a.name == title }.first
|
76
|
+
end
|
77
|
+
|
78
|
+
unless appendix.nil?
|
79
|
+
link = url_for(appendix, nil, true)
|
80
|
+
link = link ? link_url(link, appendix.title, :title => h(appendix.title)) : appendix.title
|
81
|
+
|
82
|
+
return "<span class='object_link'>#{link}</span>"
|
83
|
+
end
|
84
|
+
|
85
|
+
log.warn %Q[unable to locate referenced appendix '#{title}'#{ns ? " in namespace " + ns.name.to_s : ''}]
|
86
|
+
nil
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
module YARD
|
93
|
+
module Templates
|
94
|
+
module Helpers
|
95
|
+
module HtmlHelper
|
96
|
+
include YARD::AppendixPlugin::AppendixLinker
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# module YARD::Templates::Helpers::HtmlHelper
|
103
|
+
# alias_method :old_link_object, :link_object # yeah...
|
104
|
+
#
|
105
|
+
# def link_object(obj, otitle = nil, anchor = nil, relative = true)
|
106
|
+
# if obj && obj.is_a?(String) && obj == 'Appendix:'
|
107
|
+
# appendix = object.namespace.children.select { |o| o.type == :appendix && o.title == "Appendix: #{otitle}" }.first
|
108
|
+
#
|
109
|
+
# unless appendix.nil?
|
110
|
+
# link = url_for(appendix, anchor, relative)
|
111
|
+
# link = link ? link_url(link, appendix.title, :title => h(appendix.title)) : appendix.title
|
112
|
+
#
|
113
|
+
# return "<span class='object_link'>#{link}</span>"
|
114
|
+
# end
|
115
|
+
# end
|
116
|
+
#
|
117
|
+
# return old_link_object(obj, otitle, anchor, relative)
|
118
|
+
# end
|
119
|
+
#
|
120
|
+
# end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2013 Instructure, Inc.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a
|
5
|
+
# copy of this software and associated documentation files (the "Software"),
|
6
|
+
# to deal in the Software without restriction, including without limitation
|
7
|
+
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
8
|
+
# and/or sell copies of the Software, and to permit persons to whom the
|
9
|
+
# Software is furnished to do so, subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
12
|
+
# all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
17
|
+
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
20
|
+
# SOFTWARE.
|
21
|
+
#
|
22
|
+
|
23
|
+
module YARD
|
24
|
+
module AppendixPlugin
|
25
|
+
VERSION = "0.1.5"
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2011 Ahmad Amireh <ahmad@amireh.net>
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a
|
5
|
+
# copy of this software and associated documentation files (the "Software"),
|
6
|
+
# to deal in the Software without restriction, including without limitation
|
7
|
+
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
8
|
+
# and/or sell copies of the Software, and to permit persons to whom the
|
9
|
+
# Software is furnished to do so, subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
12
|
+
# all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
17
|
+
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
20
|
+
# SOFTWARE.
|
21
|
+
#
|
22
|
+
|
23
|
+
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__)))
|
24
|
+
|
25
|
+
require 'yard'
|
26
|
+
require 'yard-appendix/version'
|
27
|
+
require 'yard-appendix/namespace_resolver'
|
28
|
+
require 'yard-appendix/code_objects/appendix_object'
|
29
|
+
require 'yard-appendix/tags/appendix_directive'
|
30
|
+
require 'yard-appendix/handlers/appendix_handler'
|
31
|
+
require 'yard-appendix/templates/helpers/html_helper'
|
32
|
+
|
33
|
+
module YARD
|
34
|
+
module AppendixPlugin
|
35
|
+
ROOT = File.dirname(__FILE__)
|
36
|
+
TEMPLATE_PATH = File.join(%W[#{ROOT} .. templates])
|
37
|
+
end
|
38
|
+
|
39
|
+
module Templates
|
40
|
+
Engine.register_template_path YARD::AppendixPlugin::TEMPLATE_PATH
|
41
|
+
end
|
42
|
+
|
43
|
+
module Tags
|
44
|
+
Library.define_directive(:appendix, :with_title_and_text, AppendixDirective)
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2013 Instructure, Inc.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a
|
5
|
+
# copy of this software and associated documentation files (the "Software"),
|
6
|
+
# to deal in the Software without restriction, including without limitation
|
7
|
+
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
8
|
+
# and/or sell copies of the Software, and to permit persons to whom the
|
9
|
+
# Software is furnished to do so, subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
12
|
+
# all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
17
|
+
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
20
|
+
# SOFTWARE.
|
21
|
+
#
|
22
|
+
|
23
|
+
include CodeObjects
|
24
|
+
|
25
|
+
describe YARD::CodeObjects::AppendixObject do
|
26
|
+
before { Registry.clear }
|
27
|
+
|
28
|
+
it "should create an appendix object" do
|
29
|
+
o1 = AppendixObject.new(:root, 'Zoo')
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should respect uniqueness of appendix titles in scope" do
|
33
|
+
# root scope, same titles:
|
34
|
+
o1 = AppendixObject.new(:root, 'Zoo')
|
35
|
+
o2 = AppendixObject.new(:root, 'Zoo')
|
36
|
+
o1.should == o2
|
37
|
+
|
38
|
+
# root scope, different titles:
|
39
|
+
o3 = AppendixObject.new(:root, 'Monkeys')
|
40
|
+
o4 = AppendixObject.new(:root, 'Parrots')
|
41
|
+
o3.should_not == o4
|
42
|
+
|
43
|
+
# custom scope:
|
44
|
+
YARD.parse_string <<-'eof'
|
45
|
+
module TheZoo
|
46
|
+
module ParrotZone
|
47
|
+
end
|
48
|
+
end
|
49
|
+
eof
|
50
|
+
|
51
|
+
# same scope, same title:
|
52
|
+
o1 = AppendixObject.new(Registry.at('TheZoo'), 'Animals')
|
53
|
+
o2 = AppendixObject.new(Registry.at('TheZoo'), 'Animals')
|
54
|
+
o1.should == o2
|
55
|
+
|
56
|
+
# same scope, different title:
|
57
|
+
o1 = AppendixObject.new(Registry.at('TheZoo'), 'Monkeys')
|
58
|
+
o2 = AppendixObject.new(Registry.at('TheZoo'), 'Parrots')
|
59
|
+
o1.should_not == o2
|
60
|
+
|
61
|
+
# same title, different scope:
|
62
|
+
o3 = AppendixObject.new(Registry.at('TheZoo.ParrotZone'), 'Monkeys')
|
63
|
+
o1.should_not == o3
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2013 Instructure, Inc.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a
|
5
|
+
# copy of this software and associated documentation files (the "Software"),
|
6
|
+
# to deal in the Software without restriction, including without limitation
|
7
|
+
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
8
|
+
# and/or sell copies of the Software, and to permit persons to whom the
|
9
|
+
# Software is furnished to do so, subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
12
|
+
# all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
17
|
+
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
20
|
+
# SOFTWARE.
|
21
|
+
#
|
22
|
+
|
23
|
+
include Handlers::Ruby
|
24
|
+
|
25
|
+
describe YARD::Handlers::Ruby::AppendixHandler do
|
26
|
+
|
27
|
+
before {
|
28
|
+
Registry.clear
|
29
|
+
|
30
|
+
class StubHandler < AppendixHandler
|
31
|
+
handles :class, :module
|
32
|
+
|
33
|
+
def self.resolver; @@resolver end
|
34
|
+
def process; @@resolver ||= globals.resolver end
|
35
|
+
|
36
|
+
# have to do this manually as to not clutter up the other specs
|
37
|
+
AppendixHandler.clear_subclasses
|
38
|
+
end
|
39
|
+
|
40
|
+
AppendixHandler.inherited(StubHandler)
|
41
|
+
}
|
42
|
+
|
43
|
+
after {
|
44
|
+
AppendixHandler.clear_subclasses
|
45
|
+
}
|
46
|
+
|
47
|
+
it "should track a namespace statement" do
|
48
|
+
YARD.parse_string <<-'eof'
|
49
|
+
module SomeModule
|
50
|
+
class SomeClass
|
51
|
+
# comment in SomeClass
|
52
|
+
end
|
53
|
+
|
54
|
+
# comment in SomeModule
|
55
|
+
end
|
56
|
+
eof
|
57
|
+
|
58
|
+
StubHandler.resolver.namespaces.size.should == 2
|
59
|
+
StubHandler.resolver.namespaces["SomeModule"].should == "SomeModule"
|
60
|
+
StubHandler.resolver.namespaces["SomeClass"].should == "SomeModule::SomeClass"
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should locate an enclosing ns for a comment" do
|
64
|
+
class StubCommentHandler < Handlers::Ruby::Base
|
65
|
+
handles :comment
|
66
|
+
|
67
|
+
class << self
|
68
|
+
def comments; @@comments end
|
69
|
+
end
|
70
|
+
|
71
|
+
def process
|
72
|
+
@@comments ||= []
|
73
|
+
@@comments << [ statement, namespace ] if statement.type == :comment
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
YARD.parse_string <<-'eof'
|
79
|
+
module SomeModule
|
80
|
+
class SomeClass
|
81
|
+
def f() end
|
82
|
+
# comment in SomeClass
|
83
|
+
end
|
84
|
+
|
85
|
+
# comment in SomeModule
|
86
|
+
end
|
87
|
+
|
88
|
+
# comment in :root
|
89
|
+
eof
|
90
|
+
|
91
|
+
comments = StubCommentHandler.comments
|
92
|
+
comments.size.should == 3
|
93
|
+
|
94
|
+
resolver = StubHandler.resolver
|
95
|
+
resolver.namespaces.size.should == 2
|
96
|
+
|
97
|
+
resolver.
|
98
|
+
namespace_for(
|
99
|
+
comments[0][0],
|
100
|
+
comments[0][1]).
|
101
|
+
should == Registry.at('SomeModule::SomeClass')
|
102
|
+
|
103
|
+
resolver.
|
104
|
+
namespace_for(
|
105
|
+
comments[1][0],
|
106
|
+
comments[1][1]).
|
107
|
+
should == Registry.at('SomeModule')
|
108
|
+
|
109
|
+
resolver.
|
110
|
+
namespace_for(
|
111
|
+
comments[2][0],
|
112
|
+
comments[2][1]).
|
113
|
+
should == Registry.at(:root)
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2013 Instructure, Inc.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a
|
5
|
+
# copy of this software and associated documentation files (the "Software"),
|
6
|
+
# to deal in the Software without restriction, including without limitation
|
7
|
+
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
8
|
+
# and/or sell copies of the Software, and to permit persons to whom the
|
9
|
+
# Software is furnished to do so, subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
12
|
+
# all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
17
|
+
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
20
|
+
# SOFTWARE.
|
21
|
+
#
|
22
|
+
|
23
|
+
require 'yard'
|
24
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'yard-appendix')
|
25
|
+
|
26
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
27
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
28
|
+
# Require this file using `require "spec_helper"` to ensure that it is only
|
29
|
+
# loaded once.
|
30
|
+
#
|
31
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
32
|
+
RSpec.configure do |config|
|
33
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
34
|
+
config.run_all_when_everything_filtered = true
|
35
|
+
config.filter_run :focus
|
36
|
+
|
37
|
+
# Run specs in random order to surface order dependencies. If you find an
|
38
|
+
# order dependency and want to debug it, you can fix the order by providing
|
39
|
+
# the seed, which is printed after each run.
|
40
|
+
# --seed 1234
|
41
|
+
config.order = 'random'
|
42
|
+
|
43
|
+
include YARD
|
44
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2013 Instructure, Inc.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a
|
5
|
+
# copy of this software and associated documentation files (the "Software"),
|
6
|
+
# to deal in the Software without restriction, including without limitation
|
7
|
+
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
8
|
+
# and/or sell copies of the Software, and to permit persons to whom the
|
9
|
+
# Software is furnished to do so, subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
12
|
+
# all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
17
|
+
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
20
|
+
# SOFTWARE.
|
21
|
+
#
|
22
|
+
|
23
|
+
include YARD::Tags
|
24
|
+
|
25
|
+
describe YARD::Tags::AppendixDirective do
|
26
|
+
before { Registry.clear }
|
27
|
+
|
28
|
+
it "should build an AppendixObject" do
|
29
|
+
YARD.parse_string <<-'eof'
|
30
|
+
module TheQuestion
|
31
|
+
module TheAnswer
|
32
|
+
# @!appendix 42
|
33
|
+
end
|
34
|
+
|
35
|
+
# @!appendix Life, the Universe, and Everything
|
36
|
+
end
|
37
|
+
eof
|
38
|
+
|
39
|
+
appendixes = Registry.all(:appendix)
|
40
|
+
appendixes.count.should == 2
|
41
|
+
appendixes[0].namespace.should == Registry.at("TheQuestion::TheAnswer")
|
42
|
+
appendixes[1].namespace.should == Registry.at("TheQuestion")
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should allow for more than one AppendixObject" do
|
47
|
+
YARD.parse_string <<-'eof'
|
48
|
+
module TheQuestion
|
49
|
+
module TheAnswer
|
50
|
+
# @!appendix 42
|
51
|
+
end
|
52
|
+
|
53
|
+
# @!appendix Life, the Universe, and Everything
|
54
|
+
#
|
55
|
+
# But what is it?
|
56
|
+
|
57
|
+
# @!appendix DeepThought
|
58
|
+
#
|
59
|
+
# YEEHAA
|
60
|
+
end
|
61
|
+
eof
|
62
|
+
|
63
|
+
appendixes = Registry.all(:appendix)
|
64
|
+
appendixes.count.should == 3
|
65
|
+
appendixes[0].namespace.should == Registry.at("TheQuestion::TheAnswer")
|
66
|
+
appendixes[1].namespace.should == Registry.at("TheQuestion")
|
67
|
+
appendixes[2].namespace.should == Registry.at("TheQuestion")
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should implicitly prefix an appendix's title with Appendix: " do
|
72
|
+
YARD.parse_string <<-'eof'
|
73
|
+
module TheQuestion
|
74
|
+
# @!appendix Life, the Universe, and Everything
|
75
|
+
#
|
76
|
+
# But what is it?
|
77
|
+
end
|
78
|
+
eof
|
79
|
+
|
80
|
+
appendixes = Registry.all(:appendix)
|
81
|
+
appendixes.count.should == 1
|
82
|
+
appendixes[0].title.should == 'Appendix: Life, the Universe, and Everything'
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should build an appendix in the root namespace" do
|
87
|
+
YARD.parse_string <<-'eof'
|
88
|
+
# @!appendix Life, the Universe, and Everything
|
89
|
+
#
|
90
|
+
# But what is it?
|
91
|
+
eof
|
92
|
+
|
93
|
+
appendixes = Registry.all(:appendix)
|
94
|
+
appendixes.count.should == 1
|
95
|
+
appendixes[0].namespace.should == Registry.root
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should manage oddly titled appendices" do
|
99
|
+
|
100
|
+
[ 'Appendix: Life, the Universe, and Everything',
|
101
|
+
'#__ Booyah',
|
102
|
+
'123456789',
|
103
|
+
'\n',
|
104
|
+
'<lol>'
|
105
|
+
].each do |some_title|
|
106
|
+
YARD.parse_string %Q[
|
107
|
+
module TheQuestion
|
108
|
+
# @!appendix #{some_title}
|
109
|
+
#
|
110
|
+
# Some body.
|
111
|
+
end
|
112
|
+
]
|
113
|
+
|
114
|
+
appendixes = Registry.all(:appendix)
|
115
|
+
appendixes.count.should == 1
|
116
|
+
appendixes[0].title.should == 'Appendix: %s' %[some_title]
|
117
|
+
|
118
|
+
Registry.clear
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should ignore an appendix with no title" do
|
123
|
+
log.should_receive(:warn).with(/Invalid directive format for @!appendix/)
|
124
|
+
|
125
|
+
YARD.parse_string <<-'eof'
|
126
|
+
module TheQuestion
|
127
|
+
# @!appendix
|
128
|
+
#
|
129
|
+
# But what is it?
|
130
|
+
end
|
131
|
+
eof
|
132
|
+
|
133
|
+
|
134
|
+
Registry.all(:appendix).count.should == 0
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2013 Instructure, Inc.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a
|
5
|
+
# copy of this software and associated documentation files (the "Software"),
|
6
|
+
# to deal in the Software without restriction, including without limitation
|
7
|
+
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
8
|
+
# and/or sell copies of the Software, and to permit persons to whom the
|
9
|
+
# Software is furnished to do so, subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
12
|
+
# all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
17
|
+
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
20
|
+
# SOFTWARE.
|
21
|
+
#
|
22
|
+
|
23
|
+
describe YARD::AppendixPlugin::AppendixLinker do
|
24
|
+
include YARD::Templates::Helpers::BaseHelper
|
25
|
+
include YARD::Templates::Helpers::HtmlHelper
|
26
|
+
include YARD::Templates::Helpers::MethodHelper
|
27
|
+
|
28
|
+
before {
|
29
|
+
Registry.clear
|
30
|
+
}
|
31
|
+
|
32
|
+
it "should linkify an appendix object" do
|
33
|
+
linkify('Appendix: Booyah').should == 'Appendix: Booyah'
|
34
|
+
|
35
|
+
|
36
|
+
YARD.parse_string <<-'eof'
|
37
|
+
module TheAnswer
|
38
|
+
# @!appendix 42
|
39
|
+
#
|
40
|
+
# Vroom vroom.
|
41
|
+
end
|
42
|
+
eof
|
43
|
+
|
44
|
+
Registry.all(:appendix).count.should == 1
|
45
|
+
|
46
|
+
stub!(:serializer).and_return(Serializers::FileSystemSerializer.new)
|
47
|
+
stub!(:object).and_return(Registry.all(:appendix).first)
|
48
|
+
|
49
|
+
linkify('Appendix:','42').should match(%r{<a href="#42-appendix".*>Appendix: 42</a>})
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should linkify an appendix with any title" do
|
53
|
+
YARD.parse_string <<-'eof'
|
54
|
+
module TheAnswer
|
55
|
+
# @!appendix Life, the Universe, and Everything
|
56
|
+
#
|
57
|
+
# Vroom vroom.
|
58
|
+
end
|
59
|
+
eof
|
60
|
+
|
61
|
+
Registry.all(:appendix).count.should == 1
|
62
|
+
|
63
|
+
stub!(:serializer).and_return(Serializers::FileSystemSerializer.new)
|
64
|
+
stub!(:object).and_return(Registry.all(:appendix).first)
|
65
|
+
|
66
|
+
linkify('Appendix:','Life, the Universe, and Everything').should match(
|
67
|
+
%r{<a href="#Life%2C\+the\+Universe%2C\+and\+Everything\-appendix".*>Appendix: Life, the Universe, and Everything</a>})
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
def init
|
2
|
+
super
|
3
|
+
sections :appendix, [ :appendix_entry, [ T('docstring')] ]
|
4
|
+
end
|
5
|
+
|
6
|
+
def appendix
|
7
|
+
unless @appendixes
|
8
|
+
return if !object.respond_to?(:type) || !object.is_a?(YARD::CodeObjects::Base) || object.type == :appendix
|
9
|
+
end
|
10
|
+
|
11
|
+
@appendixes ||= object.children.select { |o| o.type == :appendix }
|
12
|
+
|
13
|
+
return if @appendixes.empty?
|
14
|
+
|
15
|
+
log.info "yard-appendix: found #{@appendixes.count} appendix entries for #{object}"
|
16
|
+
|
17
|
+
erb :listing
|
18
|
+
end
|
19
|
+
|
20
|
+
def appendix_entry
|
21
|
+
return unless object.type == :appendix
|
22
|
+
|
23
|
+
log.info "yard-appendix: rendering appending entry #{object.title}"
|
24
|
+
|
25
|
+
erb :entry
|
26
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require File.join(%W[#{File.dirname(__FILE__)} lib yard-appendix version])
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = 'yard-appendix'
|
5
|
+
s.summary = "A YARD plugin that adds support for Appendix sections."
|
6
|
+
s.description = <<-eof
|
7
|
+
yard-appendix is a plugin for YARD, the Ruby documentation generation tool,
|
8
|
+
that defines a special directive @!appendix for writing appendixes for your
|
9
|
+
code documentation, similar to appendixes you find in books.
|
10
|
+
|
11
|
+
Appendix entries can be referenced to by methods and classes in your docs
|
12
|
+
using the @see tag and inline-references, just like any other object.
|
13
|
+
eof
|
14
|
+
s.version = YARD::AppendixPlugin::VERSION
|
15
|
+
s.date = Time.now.strftime('%Y-%m-%d')
|
16
|
+
s.authors = ["Ahmad Amireh"]
|
17
|
+
s.email = 'ahmad@instructure.com'
|
18
|
+
s.homepage = 'https://github.com/amireh/yard-appendix'
|
19
|
+
s.files = Dir.glob("{lib,spec,templates}/**/*.rb") +
|
20
|
+
['LICENSE', 'README.md', '.rspec', __FILE__]
|
21
|
+
s.has_rdoc = 'yard'
|
22
|
+
s.license = 'MIT'
|
23
|
+
s.add_dependency('yard', '>= 0.8.0')
|
24
|
+
s.add_development_dependency 'rspec'
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: yard-appendix
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.5
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Ahmad Amireh
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-02-05 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: yard
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.8.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.8.0
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
description: ! " yard-appendix is a plugin for YARD, the Ruby documentation generation
|
47
|
+
tool,\n that defines a special directive @!appendix for writing appendixes for
|
48
|
+
your\n code documentation, similar to appendixes you find in books.\n\n Appendix
|
49
|
+
entries can be referenced to by methods and classes in your docs\n using the
|
50
|
+
@see tag and inline-references, just like any other object.\n"
|
51
|
+
email: ahmad@instructure.com
|
52
|
+
executables: []
|
53
|
+
extensions: []
|
54
|
+
extra_rdoc_files: []
|
55
|
+
files:
|
56
|
+
- lib/yard-appendix/code_objects/appendix_object.rb
|
57
|
+
- lib/yard-appendix/version.rb
|
58
|
+
- lib/yard-appendix/handlers/appendix_handler.rb
|
59
|
+
- lib/yard-appendix/namespace_resolver.rb
|
60
|
+
- lib/yard-appendix/tags/appendix_directive.rb
|
61
|
+
- lib/yard-appendix/templates/helpers/html_helper.rb
|
62
|
+
- lib/yard-appendix.rb
|
63
|
+
- spec/code_objects/appendix_object_spec.rb
|
64
|
+
- spec/handlers/appendix_handler_spec.rb
|
65
|
+
- spec/spec_helper.rb
|
66
|
+
- spec/tags/appendix_directive_spec.rb
|
67
|
+
- spec/templates/helpers/html_helper_spec.rb
|
68
|
+
- templates/default/appendix/html/setup.rb
|
69
|
+
- templates/default/module/html/setup.rb
|
70
|
+
- LICENSE
|
71
|
+
- README.md
|
72
|
+
- .rspec
|
73
|
+
- yard-appendix.gemspec
|
74
|
+
homepage: https://github.com/amireh/yard-appendix
|
75
|
+
licenses:
|
76
|
+
- MIT
|
77
|
+
post_install_message:
|
78
|
+
rdoc_options: []
|
79
|
+
require_paths:
|
80
|
+
- lib
|
81
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
83
|
+
requirements:
|
84
|
+
- - ! '>='
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '0'
|
87
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
88
|
+
none: false
|
89
|
+
requirements:
|
90
|
+
- - ! '>='
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
requirements: []
|
94
|
+
rubyforge_project:
|
95
|
+
rubygems_version: 1.8.23
|
96
|
+
signing_key:
|
97
|
+
specification_version: 3
|
98
|
+
summary: A YARD plugin that adds support for Appendix sections.
|
99
|
+
test_files: []
|
100
|
+
has_rdoc: yard
|