rdoc-generator-mdoc 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: