rdoc-generator-mdoc 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: dc966f0f203abe863af4e82f195c61412bd84417
4
+ data.tar.gz: 294a5f8c1f826fc2d8cc899ff6db5d99ae764319
5
+ SHA512:
6
+ metadata.gz: 60ce89d4a4490ac922b11da2cf4575dd20a576e2f6c87a5c641247ed6bab0db41e1eae45c36797ab4ddc347994fcf4f4b9bfe4c35a45782cf4fb92cd5b38cb20
7
+ data.tar.gz: 488e50382e04531abc0f4823d37a12b992de29d53015d90ad730279e1b9577ebfe30a09ea3a980e87756a6b7df5275c2df59d147cfce8f9828160f61b45c69b4
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Calle Erlandsson & thoughtbot, Inc.
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,48 @@
1
+ rdoc-generator-mdoc
2
+ ===================
3
+
4
+ An mdoc(7) generator for [RDoc](https://github.com/rdoc/rdoc).
5
+
6
+ Usage
7
+ -----
8
+
9
+ ### In Your Ruby Source Code
10
+
11
+ Add `rdoc-generator-mdoc` to your `Gemfile`:
12
+
13
+ gem "rdoc-generator-mdoc"
14
+
15
+ Specify `mdoc` as the formatter using the `-f` option when calling
16
+ `RDoc::RDoc#new`:
17
+
18
+ require "rdoc/generator/mdoc"
19
+
20
+ RDoc::RDoc.new.document "-f mdoc"
21
+
22
+ By default, the mdoc generator will put the generated man pages in section
23
+ `3-rdoc`. If you want the man pages to be put in a different section, specify
24
+ the section using the `--section` option:
25
+
26
+ RDoc::RDoc.new.document "-f mdoc --section 3-my-section"
27
+
28
+ For more information on using the `RDoc::RDoc` class see [the official RDoc
29
+ documentation](http://docs.seattlerb.org/rdoc/).
30
+
31
+ ### Using the `rdoc` executable
32
+
33
+ Specify `mdoc` as the formatter using the `-f` option:
34
+
35
+ $ rdoc -f mdoc
36
+
37
+ By default, the mdoc generator will put the generated man pages in section
38
+ `3-rdoc`. If you want the man pages to be put in a different section, specify
39
+ the section using the `--section` option:
40
+
41
+ $ rdoc -f mdoc --section 3-my-section
42
+
43
+ Copyright
44
+ ---------
45
+
46
+ Copyright (c) 2014 Calle Erlandsson & thoughtbot, Inc.
47
+
48
+ Lead by Calle Erlandsson & thoughtbot, Inc.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,5 @@
1
+ begin
2
+ gem "rdoc", "~> 4"
3
+ require "rdoc/generator/mdoc"
4
+ rescue Gem::LoadError
5
+ end
@@ -0,0 +1,106 @@
1
+ require "erb"
2
+ require "rdoc"
3
+ require "rdoc/generator/mdoc/version"
4
+ require "rdoc/generator/mdoc/class"
5
+ require "rdoc/generator/mdoc/module"
6
+ require "rdoc/generator/mdoc/render_context"
7
+
8
+ class RDoc::Options
9
+ attr_accessor :mandb_section
10
+ end
11
+
12
+ ##
13
+ # An mdoc(7) generator for RDoc.
14
+ #
15
+ # This generator will create man pages in mdoc(7) format for classes, modules
16
+ # and methods parsed by RDoc.
17
+ class RDoc::Generator::Mdoc
18
+ RDoc::RDoc.add_generator self
19
+
20
+ def self.setup_options(options)
21
+ options.option_parser.on("--section SECTION", String) do |mandb_section|
22
+ options.mandb_section = mandb_section
23
+ end
24
+ end
25
+
26
+ ##
27
+ # Create an instance usign the provided RDoc::Store and RDoc::Options.
28
+ def initialize(store, options)
29
+ @store = store
30
+ @mandb_section = options.mandb_section || "3-rdoc"
31
+ @output_directory = File.expand_path(File.join(options.op_dir, "man", "man#{mandb_section.split('-').first}"))
32
+ FileUtils.mkdir_p output_directory
33
+ end
34
+
35
+ ##
36
+ # Generate man pages.
37
+ #
38
+ # Every class, module and method gets their own man page in the
39
+ # "man/manSECTION_PREFIX" subdirectory of the output directory.
40
+ def generate
41
+ generate_class_and_module_pages
42
+ generate_method_pages
43
+ end
44
+
45
+ private
46
+
47
+ attr_reader :store, :output_directory, :mandb_section
48
+
49
+ def generate_class_and_module_pages
50
+ (classes + modules).each do |object|
51
+ generate_page(file_name(object), "module", module: object)
52
+ end
53
+ end
54
+
55
+ def generate_method_pages
56
+ methods.each do |method|
57
+ generate_page(file_name(method), "method", method: method)
58
+ end
59
+ end
60
+
61
+ def classes
62
+ @classes ||= decorate_displayed(store.all_classes, Class)
63
+ end
64
+
65
+ def modules
66
+ @modules ||= decorate_displayed(store.all_modules, Module)
67
+ end
68
+
69
+ def methods
70
+ @methods ||= (classes + modules).flat_map(&:methods)
71
+ end
72
+
73
+ def decorate_displayed(objects, decoration_class)
74
+ objects.select(&:display?).map do |object|
75
+ decoration_class.new(object, mandb_section)
76
+ end
77
+ end
78
+
79
+ def generate_page(file_name, template_name, assigns)
80
+ File.write(file_name, render_template(template(template_name), assigns))
81
+ end
82
+
83
+ def file_name(object)
84
+ File.join(output_directory, "#{object.full_name}.#{mandb_section}")
85
+ end
86
+
87
+ def render_template(template, assigns)
88
+ ERB.new(template).result(binding_with_assigns(assigns)).squeeze("\n")
89
+ end
90
+
91
+ def template(name)
92
+ @templates ||= {}
93
+ @templates[name] ||= File.read(template_path(name))
94
+ end
95
+
96
+ def template_path(name)
97
+ File.expand_path(
98
+ File.join("..", "..", "..", "..", "templates", "#{name}.mdoc.erb"),
99
+ __FILE__,
100
+ )
101
+ end
102
+
103
+ def binding_with_assigns(assigns)
104
+ RenderContext.new(assigns).binding
105
+ end
106
+ end
@@ -0,0 +1,33 @@
1
+ require "rdoc/generator/mdoc/comment"
2
+
3
+ class RDoc::Generator::Mdoc
4
+ class Attribute
5
+ def initialize(rdoc_attribute)
6
+ @rdoc_attribute = rdoc_attribute
7
+ end
8
+
9
+ def name
10
+ rdoc_attribute.name
11
+ end
12
+
13
+ def rw
14
+ rdoc_attribute.rw
15
+ end
16
+
17
+ def described?
18
+ !description.empty?
19
+ end
20
+
21
+ def description
22
+ comment.mdoc_formatted_content
23
+ end
24
+
25
+ private
26
+
27
+ def comment
28
+ @comment ||= Comment.new(rdoc_attribute.comment.text)
29
+ end
30
+
31
+ attr_reader :rdoc_attribute
32
+ end
33
+ end
@@ -0,0 +1,20 @@
1
+ require "rdoc/generator/mdoc/unknown_class"
2
+ require "rdoc/generator/mdoc/module"
3
+
4
+ class RDoc::Generator::Mdoc
5
+ class Class < Module
6
+ def superclass
7
+ if rdoc_class.superclass.is_a? String
8
+ UnknownClass.new(rdoc_class.superclass)
9
+ else
10
+ self.class.new(rdoc_class.superclass, mandb_section)
11
+ end
12
+ end
13
+
14
+ private
15
+
16
+ def rdoc_class
17
+ rdoc_module
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,38 @@
1
+ require "rdoc"
2
+ require "rdoc/generator/mdoc/formatter"
3
+
4
+ class RDoc::Generator::Mdoc
5
+ class Comment
6
+ def initialize(markup)
7
+ @markup = markup
8
+ end
9
+
10
+ def first_paragraph
11
+ paragraph = rdoc_document.parts.find do |part|
12
+ part.is_a? RDoc::Markup::Paragraph
13
+ end
14
+
15
+ if paragraph
16
+ paragraph.text
17
+ else
18
+ ""
19
+ end
20
+ end
21
+
22
+ def mdoc_formatted_content
23
+ rdoc_document.accept formatter
24
+ end
25
+
26
+ private
27
+
28
+ attr_reader :markup
29
+
30
+ def rdoc_document
31
+ @rdoc_document ||= RDoc::Markup.parse(markup)
32
+ end
33
+
34
+ def formatter
35
+ Formatter.new
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,33 @@
1
+ require "rdoc/generator/mdoc/comment"
2
+
3
+ class RDoc::Generator::Mdoc
4
+ class Constant
5
+ def initialize(rdoc_constant)
6
+ @rdoc_constant = rdoc_constant
7
+ end
8
+
9
+ def name
10
+ rdoc_constant.name
11
+ end
12
+
13
+ def value
14
+ rdoc_constant.value
15
+ end
16
+
17
+ def description
18
+ comment.mdoc_formatted_content
19
+ end
20
+
21
+ def described?
22
+ !description.empty?
23
+ end
24
+
25
+ private
26
+
27
+ attr_reader :rdoc_constant
28
+
29
+ def comment
30
+ @comment ||= Comment.new(rdoc_constant.comment.text)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,170 @@
1
+ require "rdoc"
2
+ require "rdoc/generator/mdoc/helpers"
3
+
4
+ class RDoc::Generator::Mdoc
5
+ ##
6
+ # Format an RDoc::Document into mdoc.
7
+ class Formatter < RDoc::Markup::Formatter
8
+ include Helpers
9
+
10
+ ##
11
+ # Instantiate a mdoc formatter that escapes special mdoc characters.
12
+ def initialize(options=nil, markup = nil)
13
+ super
14
+ init_attribute_manager_tags
15
+ end
16
+
17
+ ##
18
+ # Initialize the formatter with an empty array of parts and lists.
19
+ def start_accepting
20
+ @parts = []
21
+ @list_types = []
22
+ end
23
+
24
+ ##
25
+ # Compile the parts together.
26
+ def end_accepting
27
+ handle_leading_punctuation parts.join.squeeze("\n")
28
+ end
29
+
30
+ ##
31
+ # Turn a heading into a subsection header.
32
+ def accept_heading(heading)
33
+ parts << ".Ss #{heading.text}\n"
34
+ end
35
+
36
+ ##
37
+ # Output a paragraph macro for the escaped paragraph.
38
+ def accept_paragraph(paragraph)
39
+ parts << handle_inline_attributes(paragraph.text)
40
+ parts << "\n.Pp\n"
41
+ end
42
+
43
+ ##
44
+ # Turn a large quoted section into a block display.
45
+ def accept_block_quote(block_quote)
46
+ parts << ".Bd -offset indent\n"
47
+ block_quote.parts.each { |part| part.accept self }
48
+ parts << "\n.Ed\n.Pp\n"
49
+ end
50
+
51
+ ##
52
+ # Output paragraph macros for blank lines.
53
+ def accept_blank_line(blank_line)
54
+ parts << "\n.Pp\n"
55
+ end
56
+
57
+ ##
58
+ # Open an enumerated, dictionary, or bulleted list.
59
+ #
60
+ # The list must be closed using #accept_list_start.
61
+ def accept_list_start(list)
62
+ list_types.push(list.type)
63
+
64
+ case current_list_type
65
+ when :NUMBER, :LALPHA, :UALPHA
66
+ parts << ".Bl -enum\n"
67
+ when :LABEL, :NOTE
68
+ parts << ".Bl -hang -offset -indent\n"
69
+ else
70
+ parts << ".Bl -bullet\n"
71
+ end
72
+ end
73
+
74
+ ##
75
+ # Close a list.
76
+ #
77
+ # This works for all list types.
78
+ def accept_list_end(list)
79
+ list_types.pop
80
+ parts << ".El\n"
81
+ end
82
+
83
+ ##
84
+ # Open a list item.
85
+ #
86
+ # If the list has a label, that label is the list item. Otherwise, the
87
+ # list item has no content.
88
+ #
89
+ # Also see #accept_list_item_end.
90
+ def accept_list_item_start(list_item)
91
+ case current_list_type
92
+ when :LABEL, :NOTE
93
+ labels = Array(list_item.label).join(", ")
94
+ parts << ".It #{labels}\n"
95
+ else
96
+ parts << ".It\n"
97
+ end
98
+ end
99
+
100
+ ##
101
+ # Finish a list item.
102
+ #
103
+ # This works for all list types.
104
+ def accept_list_item_end(list_item)
105
+ end
106
+
107
+ ##
108
+ # Format code as an indented block.
109
+ def accept_verbatim(verbatim)
110
+ parts << ".Bd -literal -offset indent\n"
111
+ parts << verbatim.text
112
+ parts << "\n.Ed\n.Pp\n"
113
+ end
114
+
115
+ ##
116
+ # Format a horizontal ruler.
117
+ #
118
+ # This is a no-op.
119
+ def accept_rule(rule)
120
+ end
121
+
122
+ ##
123
+ # Pass through all raw parts unparsed, separated by newlines.
124
+ def accept_raw(raw)
125
+ parts << raw.parts.join("\n")
126
+ end
127
+
128
+ private
129
+
130
+ attr_accessor :parts, :list_types
131
+
132
+ def init_attribute_manager_tags
133
+ add_tag :BOLD, "\n.Sy ", "\n"
134
+ add_tag :EM, "\n.Em ", "\n"
135
+ add_tag :TT, "\n.Li ", "\n"
136
+ end
137
+
138
+ def handle_inline_attributes(text)
139
+ flow = attribute_manager.flow(text.dup)
140
+ convert_flow flow
141
+ end
142
+
143
+ def attribute_manager
144
+ @am
145
+ end
146
+
147
+ def current_list_type
148
+ list_types.last
149
+ end
150
+
151
+ def convert_string(string)
152
+ escape(string.strip)
153
+ end
154
+
155
+ ##
156
+ # Return a string with all new-lines immediately followed by one of:
157
+ #
158
+ # .,:;()[]?!
159
+ #
160
+ # immediately followed by whitespace or the end of line replaced with a
161
+ # space, the matched character and a space.
162
+ #
163
+ # This is to prevent lines to start with `.` and to avoid whitespace
164
+ # between the last word of a sentence and the following punctuation
165
+ # character.
166
+ def handle_leading_punctuation(string) # :doc:
167
+ string.gsub(/\n([.,:;()\[\]?!])(\s|$)/, " \\1\n")
168
+ end
169
+ end
170
+ end
@@ -0,0 +1,33 @@
1
+ class RDoc::Generator::Mdoc
2
+ ##
3
+ # A module of helpers when outputting mdoc formatted text
4
+ module Helpers
5
+ ##
6
+ # Returns a new string where characters that mdoc percieve as special have
7
+ # been escaped.
8
+ #
9
+ # This is in line with the advice given in +mdoc.samples(7)+:
10
+ #
11
+ # > To remove the special meaning from a punctuation character escape it
12
+ # > with ‘\&’. Troff is limited as a macro language, and has difficulty
13
+ # > when pre‐ sented with a string containing a member of the mathematical,
14
+ # > logical or quotation set:
15
+ # >
16
+ # > {+,-,/,*,%,<,>,<=,>=,=,==,&,`,',"}
17
+ # >
18
+ # > The problem is that troff may assume it is supposed to actually perform
19
+ # > the operation or evaluation suggested by the characters. To prevent
20
+ # > the accidental evaluation of these characters, escape them with ‘\&’.
21
+ # > Typical syntax is shown in the first content macro displayed below,
22
+ # > ‘.Ad’.
23
+ def escape(string)
24
+ string.gsub(%r|[+\-/*%<>=&`'"]|, '\\\&\0')
25
+ end
26
+
27
+ ##
28
+ # Returns a new string enclosed in double quotes.
29
+ def quote(string)
30
+ string.gsub(/^|$/, '"')
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,129 @@
1
+ require "active_support/core_ext/string/filters"
2
+ require "rdoc/generator/mdoc/comment"
3
+
4
+ class RDoc::Generator::Mdoc
5
+ class Method
6
+ attr_reader :visibility, :mandb_section
7
+
8
+ def initialize(rdoc_method, mandb_section, visibility = nil)
9
+ @rdoc_method = rdoc_method
10
+ @mandb_section = mandb_section
11
+ @visibility = visibility.to_s
12
+ end
13
+
14
+ def name
15
+ rdoc_method.name
16
+ end
17
+
18
+ def full_name
19
+ @full_name ||= if class_method?
20
+ replace_last_double_colon_with_dot(rdoc_method.full_name)
21
+ else
22
+ rdoc_method.full_name
23
+ end
24
+ end
25
+
26
+ def parameters
27
+ rdoc_method.params.gsub(/[\(\)]/, '').split(", ")
28
+ end
29
+
30
+ def short_description
31
+ comment.first_paragraph.truncate(50)
32
+ end
33
+
34
+ def described?
35
+ !description.empty?
36
+ end
37
+
38
+ def description
39
+ comment.mdoc_formatted_content
40
+ end
41
+
42
+ def has_invocation_examples?
43
+ !invocation_examples.empty?
44
+ end
45
+
46
+ def invocation_examples
47
+ @invocation_examples ||= if rdoc_method.call_seq.nil?
48
+ []
49
+ else
50
+ extract_invocation_examples(rdoc_method.call_seq)
51
+ end
52
+ end
53
+
54
+ def calls_super?
55
+ !superclass_method.nil?
56
+ end
57
+
58
+ def superclass_method
59
+ @superclass_method ||= rdoc_method.superclass_method &&
60
+ self.class.new(rdoc_method.superclass_method, mandb_section)
61
+ end
62
+
63
+ def has_source?
64
+ !source.nil?
65
+ end
66
+
67
+ def source
68
+ @source ||= rdoc_method.token_stream &&
69
+ strip_source_file_path(rdoc_method.tokens_to_s)
70
+ end
71
+
72
+ def alias?
73
+ !aliased_method.nil?
74
+ end
75
+
76
+ def aliased_method
77
+ @aliased_method ||= rdoc_method.is_alias_for &&
78
+ self.class.new(rdoc_method.is_alias_for, mandb_section)
79
+ end
80
+
81
+ def aliased?
82
+ !aliases.empty?
83
+ end
84
+
85
+ def aliases
86
+ @aliases ||= rdoc_method.aliases.map do |_alias|
87
+ self.class.new(_alias, mandb_section)
88
+ end
89
+ end
90
+
91
+ def reference
92
+ "#{full_name} #{mandb_section}"
93
+ end
94
+
95
+ def object
96
+ @object ||= Module.new(rdoc_method.parent, mandb_section)
97
+ end
98
+
99
+ private
100
+
101
+ attr_reader :rdoc_method
102
+
103
+ def class_method?
104
+ rdoc_method.singleton
105
+ end
106
+
107
+ def replace_last_double_colon_with_dot(string)
108
+ string.sub(/(.*)::(.*)/, "\\1.\\2")
109
+ end
110
+
111
+ def comment
112
+ @comment ||= Comment.new(rdoc_method.comment.text)
113
+ end
114
+
115
+ def extract_invocation_examples(call_seq)
116
+ call_seq.split("\n").map do |invocation_example|
117
+ strip_receiver(invocation_example)
118
+ end
119
+ end
120
+
121
+ def strip_receiver(invocation_example)
122
+ invocation_example.gsub(/^\w+\./, '')
123
+ end
124
+
125
+ def strip_source_file_path(source)
126
+ source.lines[1..-1].join
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,86 @@
1
+ require "active_support/core_ext/string/filters"
2
+ require "rdoc/generator/mdoc/comment"
3
+ require "rdoc/generator/mdoc/section"
4
+ require "rdoc/generator/mdoc/unknown_module"
5
+
6
+ class RDoc::Generator::Mdoc
7
+ class Module
8
+ attr_reader :mandb_section
9
+
10
+ def initialize(rdoc_module, mandb_section)
11
+ @rdoc_module = rdoc_module
12
+ @mandb_section = mandb_section
13
+ end
14
+
15
+ def full_name
16
+ rdoc_module.full_name
17
+ end
18
+
19
+ def reference
20
+ "#{full_name} #{mandb_section}"
21
+ end
22
+
23
+ def short_description
24
+ comment.first_paragraph.truncate(50)
25
+ end
26
+
27
+ def described?
28
+ !description.empty?
29
+ end
30
+
31
+ def description
32
+ comment.mdoc_formatted_content
33
+ end
34
+
35
+ def extended_modules
36
+ @extended_modules ||= decorate_rdoc_mixins(rdoc_module.extends)
37
+ end
38
+
39
+ def included_modules
40
+ @included_modules ||= decorate_rdoc_mixins(rdoc_module.includes)
41
+ end
42
+
43
+ def methods
44
+ sections.flat_map(&:methods)
45
+ end
46
+
47
+ def sections
48
+ @sections ||=
49
+ rdoc_module.
50
+ each_section.
51
+ map do |rdoc_section, rdoc_constants, rdoc_attributes|
52
+ Section.new(
53
+ rdoc_section,
54
+ rdoc_constants,
55
+ rdoc_attributes,
56
+ mandb_section,
57
+ )
58
+ end
59
+ end
60
+
61
+ private
62
+
63
+ def comment
64
+ @comment ||= Comment.new(markup)
65
+ end
66
+
67
+ def markup
68
+ rdoc_module.
69
+ comment_location.
70
+ map { |rdoc_comment, _| rdoc_comment.text }.
71
+ join("\n")
72
+ end
73
+
74
+ def decorate_rdoc_mixins(rdoc_mixins)
75
+ rdoc_mixins.map(&:module).map do |rdoc_module|
76
+ if rdoc_module.is_a? String
77
+ UnknownModule.new(rdoc_module)
78
+ else
79
+ self.class.new(rdoc_module, mandb_section)
80
+ end
81
+ end
82
+ end
83
+
84
+ attr_reader :rdoc_module
85
+ end
86
+ end
@@ -0,0 +1,17 @@
1
+ require "rdoc/generator/mdoc/helpers"
2
+
3
+ class RDoc::Generator::Mdoc
4
+ class RenderContext
5
+ include Helpers
6
+
7
+ def initialize(assigns)
8
+ assigns.each do |name, value|
9
+ instance_variable_set("@#{name}", value)
10
+ end
11
+ end
12
+
13
+ def binding
14
+ super
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,77 @@
1
+ require "rdoc/generator/mdoc/constant"
2
+ require "rdoc/generator/mdoc/comment"
3
+ require "rdoc/generator/mdoc/attribute"
4
+ require "rdoc/generator/mdoc/method"
5
+
6
+ class RDoc::Generator::Mdoc
7
+ class Section
8
+ def self.method_types
9
+ [:class, :instance]
10
+ end
11
+
12
+ def initialize(rdoc_section, rdoc_constants, rdoc_attributes, mandb_section)
13
+ @rdoc_section = rdoc_section
14
+ @rdoc_constants = rdoc_constants
15
+ @rdoc_attributes = rdoc_attributes
16
+ @mandb_section = mandb_section
17
+ end
18
+
19
+ def titled?
20
+ !title.nil?
21
+ end
22
+
23
+ def title
24
+ rdoc_section.title
25
+ end
26
+
27
+ def described?
28
+ !description.empty?
29
+ end
30
+
31
+ def description
32
+ comment.mdoc_formatted_content
33
+ end
34
+
35
+ def constants
36
+ @constants ||= rdoc_constants.map do |rdoc_constant|
37
+ Constant.new(rdoc_constant)
38
+ end
39
+ end
40
+
41
+ def attributes
42
+ @attributes ||= rdoc_attributes.map do |rdoc_attribute|
43
+ Attribute.new(rdoc_attribute)
44
+ end
45
+ end
46
+
47
+ def methods
48
+ self.class.method_types.flat_map { |type| methods_of_type(type) }
49
+ end
50
+
51
+ def methods_of_type(type)
52
+ @methods_of_type ||= {}
53
+ @methods_of_type[type] ||=
54
+ rdoc_section.
55
+ parent.
56
+ methods_by_type(rdoc_section)[type.to_s].
57
+ flat_map do |visibility, rdoc_methods|
58
+ rdoc_methods.map do
59
+ |rdoc_method| Method.new(rdoc_method, mandb_section, visibility)
60
+ end
61
+ end
62
+ end
63
+
64
+ private
65
+
66
+ attr_reader :rdoc_section, :rdoc_constants, :rdoc_attributes,
67
+ :mandb_section
68
+
69
+ def markup
70
+ rdoc_section.comments.map(&:normalize).map(&:text).join
71
+ end
72
+
73
+ def comment
74
+ @comment ||= Comment.new(markup)
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,11 @@
1
+ class RDoc::Generator::Mdoc
2
+ class UnknownClass
3
+ def initialize(full_name)
4
+ @full_name = full_name
5
+ end
6
+
7
+ def reference
8
+ @full_name
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ class RDoc::Generator::Mdoc
2
+ class UnknownModule
3
+ def initialize(full_name)
4
+ @full_name = full_name
5
+ end
6
+
7
+ def reference
8
+ @full_name
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,7 @@
1
+ module RDoc
2
+ module Generator
3
+ class Mdoc
4
+ VERSION = "0.0.1"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,21 @@
1
+ lib = File.expand_path("../lib", __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "rdoc/generator/mdoc/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "rdoc-generator-mdoc"
7
+ spec.version = RDoc::Generator::Mdoc::VERSION
8
+ spec.authors = ["Calle Erlandsson", "Mike Burns"]
9
+ spec.email = ["calle@thoughtbot.com", "hello@thoughtbot.com"]
10
+ spec.summary = "An mdoc(7) generator for RDoc"
11
+ spec.homepage = "https://github.com/thoughtbot/rdoc-generator-mdoc"
12
+ spec.license = "MIT"
13
+ spec.files = `git ls-files -z`.split("\x0")
14
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
15
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
16
+ spec.require_paths = ["lib"]
17
+ spec.add_development_dependency "bundler", "~> 1.6"
18
+ spec.add_development_dependency "rake", "~> 10.0"
19
+ spec.add_dependency "rdoc", "~> 4"
20
+ spec.add_dependency "activesupport", "~> 4"
21
+ end
@@ -0,0 +1,48 @@
1
+ .Dd <%= Time.now.strftime "%B %-d, %Y" %>
2
+ .Dt <%= @method.full_name.upcase %> <%= @method.mandb_section %>
3
+ .Os
4
+ .Sh NAME
5
+ .Nm <%= @method.full_name %>
6
+ .Nd <%= @method.short_description %>
7
+ <% if @method.has_invocation_examples? %>
8
+ .Sh SYNPOSIS
9
+ .Bd -literal
10
+ <%= @method.invocation_examples.join("\n") %>
11
+ .Ed
12
+ .Pp
13
+ <% end %>
14
+ .Sh DESCRIPTION
15
+ <% if @method.described? %>
16
+ <%= @method.description %>
17
+ <% else %>
18
+ Not documented.
19
+ .Pp
20
+ <% end %>
21
+ <% if @method.calls_super? %>
22
+ .Ss Calls superclass method
23
+ .Xr <%= escape @method.superclass_method.reference %>
24
+ .Pp
25
+ <% end %>
26
+ <% if @method.alias? %>
27
+ .Ss Alias for
28
+ .Xr <%= escape @method.aliased_method.reference %>
29
+ .Pp
30
+ <% end %>
31
+ <% if @method.aliased? %>
32
+ .Ss Also aliased as
33
+ .Bl -bullet -compact
34
+ <% @method.aliases.each do |_alias| %>
35
+ .It
36
+ .Xr <%= escape _alias.reference %>
37
+ <% end %>
38
+ .El
39
+ <% end %>
40
+ <% if @method.has_source? %>
41
+ .Sh SOURCE
42
+ .Bd -literal
43
+ <%= @method.source %>
44
+ .Ed
45
+ .Pp
46
+ <% end %>
47
+ .Sh SEE ALSO
48
+ .Xr <%= @method.object.reference %>
@@ -0,0 +1,114 @@
1
+ .Dd <%= Time.now.strftime "%B %-d, %Y" %>
2
+ .Dt <%= @module.full_name.upcase %> <%= @module.mandb_section %>
3
+ .Os
4
+ .Sh NAME
5
+ .Nm <%= @module.full_name %>
6
+ .Nd <%= @module.short_description %>
7
+ .Sh DESCRIPTION
8
+ <% if @module.described? %>
9
+ <%= @module.description %>
10
+ <% else %>
11
+ Not documented.
12
+ .Pp
13
+ <% end %>
14
+ <% if @module.respond_to?(:superclass) %>
15
+ .Ss Superclass
16
+ .Xr <%= escape @module.superclass.reference %> .
17
+ .Pp
18
+ <% end %>
19
+ <% unless @module.extended_modules.empty? %>
20
+ .Ss Extended Modules
21
+ .Bl -bullet -compact
22
+ <% @module.extended_modules.each do |_module| %>
23
+ .It
24
+ .Xr <%= escape _module.reference %>
25
+ <% end %>
26
+ .El
27
+ <% end %>
28
+ <% unless @module.included_modules.empty? %>
29
+ .Ss Included Modules
30
+ .Bl -bullet -compact
31
+ <% @module.included_modules.each do |_module| %>
32
+ .It
33
+ .Xr <%= escape _module.reference %>
34
+ <% end %>
35
+ .El
36
+ <% end %>
37
+ <% @module.sections.each do |section| %>
38
+ <% if section.titled? %>
39
+ .Sh <%= section.title.upcase %>
40
+ <% end %>
41
+ <% if section.described? %>
42
+ <%= section.description %>
43
+ <% end %>
44
+ <% unless section.constants.empty? %>
45
+ .Ss Constants
46
+ .Bl -tag
47
+ <% section.constants.each do |constant| %>
48
+ .It Dv <%= constant.name %> Li = <%= escape constant.value %>
49
+ <% if constant.described? %>
50
+ <%= constant.description %>
51
+ <% else %>
52
+ Not documented.
53
+ .Pp
54
+ <% end %>
55
+ <% end %>
56
+ .El
57
+ <% end %>
58
+ <% unless section.attributes.empty? %>
59
+ .Ss Attributes
60
+ .Bl -tag
61
+ <% section.attributes.each do |attribute| %>
62
+ .It Va <%= attribute.name %> Pq <%= attribute.rw %>
63
+ <% if attribute.described? %>
64
+ <%= attribute.description %>
65
+ <% else %>
66
+ Not documented.
67
+ .Pp
68
+ <% end %>
69
+ <% end %>
70
+ .El
71
+ <% end %>
72
+ <% section.class.method_types.each do |type| %>
73
+ <% unless section.methods_of_type(type).empty? %>
74
+ .Ss <%= type.capitalize %> Methods
75
+ .Bl -tag
76
+ <% section.methods_of_type(type).each do |method| %>
77
+ .It Fn "<%= escape method.visibility %> <%= escape method.name %>" <%=
78
+ method.parameters.map { |p| quote(escape(p)) }.join(" ") %>
79
+ <% if method.has_invocation_examples? %>
80
+ .Bd -literal
81
+ <%= method.invocation_examples.join("\n") %>
82
+ .Ed
83
+ .Pp
84
+ <% end %>
85
+ <% if method.described? %>
86
+ <%= method.description %>
87
+ <% else %>
88
+ Not documented.
89
+ .Pp
90
+ <% end %>
91
+ <% if method.calls_super? %>
92
+ Calls superclass method
93
+ .Xr <%= escape method.superclass_method.reference %> .
94
+ .Pp
95
+ <% end %>
96
+ <% if method.alias? %>
97
+ Alias for
98
+ .Xr <%= escape method.aliased_method.reference %> .
99
+ .Pp
100
+ <% end %>
101
+ <% if method.aliased? %>
102
+ Also aliased as:
103
+ .Bl -bullet -compact
104
+ <% method.aliases.each do |_alias| %>
105
+ .It
106
+ .Xr <%= escape _alias.reference %>
107
+ <% end %>
108
+ .El
109
+ <% end %>
110
+ <% end %>
111
+ .El
112
+ <% end %>
113
+ <% end %>
114
+ <% end %>
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rdoc-generator-mdoc
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Calle Erlandsson
8
+ - Mike Burns
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-08-07 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '1.6'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '1.6'
28
+ - !ruby/object:Gem::Dependency
29
+ name: rake
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '10.0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '10.0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rdoc
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '4'
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '4'
56
+ - !ruby/object:Gem::Dependency
57
+ name: activesupport
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: '4'
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '4'
70
+ description:
71
+ email:
72
+ - calle@thoughtbot.com
73
+ - hello@thoughtbot.com
74
+ executables: []
75
+ extensions: []
76
+ extra_rdoc_files: []
77
+ files:
78
+ - ".gitignore"
79
+ - Gemfile
80
+ - LICENSE.txt
81
+ - README.md
82
+ - Rakefile
83
+ - lib/rdoc/discover.rb
84
+ - lib/rdoc/generator/mdoc.rb
85
+ - lib/rdoc/generator/mdoc/attribute.rb
86
+ - lib/rdoc/generator/mdoc/class.rb
87
+ - lib/rdoc/generator/mdoc/comment.rb
88
+ - lib/rdoc/generator/mdoc/constant.rb
89
+ - lib/rdoc/generator/mdoc/formatter.rb
90
+ - lib/rdoc/generator/mdoc/helpers.rb
91
+ - lib/rdoc/generator/mdoc/method.rb
92
+ - lib/rdoc/generator/mdoc/module.rb
93
+ - lib/rdoc/generator/mdoc/render_context.rb
94
+ - lib/rdoc/generator/mdoc/section.rb
95
+ - lib/rdoc/generator/mdoc/unknown_class.rb
96
+ - lib/rdoc/generator/mdoc/unknown_module.rb
97
+ - lib/rdoc/generator/mdoc/version.rb
98
+ - rdoc-generator-mdoc.gemspec
99
+ - templates/method.mdoc.erb
100
+ - templates/module.mdoc.erb
101
+ homepage: https://github.com/thoughtbot/rdoc-generator-mdoc
102
+ licenses:
103
+ - MIT
104
+ metadata: {}
105
+ post_install_message:
106
+ rdoc_options: []
107
+ require_paths:
108
+ - lib
109
+ required_ruby_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ requirements: []
120
+ rubyforge_project:
121
+ rubygems_version: 2.2.2
122
+ signing_key:
123
+ specification_version: 4
124
+ summary: An mdoc(7) generator for RDoc
125
+ test_files: []
126
+ has_rdoc: