rdoc 2.4.3 → 2.5
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rdoc might be problematic. Click here for more details.
- data.tar.gz.sig +0 -0
- data/.autotest +3 -1
- data/History.txt +68 -0
- data/LICENSE.txt +57 -0
- data/Manifest.txt +37 -19
- data/README.txt +2 -12
- data/Rakefile +12 -12
- data/bin/rdoc +4 -4
- data/lib/rdoc.rb +32 -9
- data/lib/rdoc/alias.rb +2 -2
- data/lib/rdoc/any_method.rb +108 -16
- data/lib/rdoc/attr.rb +87 -1
- data/lib/rdoc/class_module.rb +131 -5
- data/lib/rdoc/code_object.rb +28 -5
- data/lib/rdoc/constant.rb +22 -0
- data/lib/rdoc/context.rb +80 -37
- data/lib/rdoc/gauntlet.rb +48 -0
- data/lib/rdoc/generator/darkfish.rb +25 -23
- data/lib/rdoc/generator/markup.rb +6 -29
- data/lib/rdoc/generator/ri.rb +39 -189
- data/lib/rdoc/generator/template/darkfish/classpage.rhtml +17 -1
- data/lib/rdoc/generator/template/darkfish/filepage.rhtml +10 -0
- data/lib/rdoc/generator/template/darkfish/images/brick.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/brick_link.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/bullet_black.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/bullet_toggle_minus.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/bullet_toggle_plus.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/date.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/find.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/package.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/page_green.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/page_white_text.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/page_white_width.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/plugin.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/ruby.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/tag_green.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/wrench.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/wrench_orange.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/zoom.png +0 -0
- data/lib/rdoc/generator/template/darkfish/index.rhtml +2 -2
- data/lib/rdoc/generator/template/darkfish/rdoc.css +38 -33
- data/lib/rdoc/include.rb +22 -0
- data/lib/rdoc/markup.rb +10 -262
- data/lib/rdoc/markup/attribute_manager.rb +57 -50
- data/lib/rdoc/markup/blank_line.rb +19 -0
- data/lib/rdoc/markup/document.rb +72 -0
- data/lib/rdoc/markup/formatter.rb +118 -0
- data/lib/rdoc/markup/formatter_test_case.rb +341 -0
- data/lib/rdoc/markup/heading.rb +17 -0
- data/lib/rdoc/markup/inline.rb +6 -5
- data/lib/rdoc/markup/list.rb +78 -0
- data/lib/rdoc/markup/list_item.rb +83 -0
- data/lib/rdoc/markup/paragraph.rb +66 -0
- data/lib/rdoc/markup/parser.rb +528 -0
- data/lib/rdoc/markup/rule.rb +17 -0
- data/lib/rdoc/markup/to_ansi.rb +72 -0
- data/lib/rdoc/markup/to_bs.rb +74 -0
- data/lib/rdoc/markup/to_html.rb +106 -172
- data/lib/rdoc/markup/to_html_crossref.rb +10 -4
- data/lib/rdoc/markup/to_rdoc.rb +243 -0
- data/lib/rdoc/markup/to_test.rb +27 -16
- data/lib/rdoc/markup/verbatim.rb +42 -0
- data/lib/rdoc/normal_class.rb +38 -1
- data/lib/rdoc/normal_module.rb +38 -8
- data/lib/rdoc/options.rb +39 -151
- data/lib/rdoc/parser.rb +36 -18
- data/lib/rdoc/parser/c.rb +102 -109
- data/lib/rdoc/parser/ruby.rb +359 -1662
- data/lib/rdoc/parser/ruby_tools.rb +157 -0
- data/lib/rdoc/parser/simple.rb +0 -2
- data/lib/rdoc/rdoc.rb +142 -82
- data/lib/rdoc/ri.rb +10 -0
- data/lib/rdoc/ri/driver.rb +674 -444
- data/lib/rdoc/ri/formatter.rb +2 -651
- data/lib/rdoc/ri/paths.rb +70 -45
- data/lib/rdoc/ri/store.rb +248 -0
- data/lib/rdoc/ruby_lex.rb +1284 -0
- data/lib/rdoc/ruby_token.rb +416 -0
- data/lib/rdoc/single_class.rb +5 -0
- data/lib/rdoc/stats.rb +152 -83
- data/lib/rdoc/task.rb +27 -49
- data/lib/rdoc/text.rb +130 -0
- data/lib/rdoc/tokenstream.rb +28 -9
- data/lib/rdoc/top_level.rb +49 -43
- data/test/hidden.zip.txt +1 -0
- data/test/test_attribute_manager.rb +9 -16
- data/test/test_rdoc_any_method.rb +23 -0
- data/test/test_rdoc_attr.rb +40 -0
- data/test/test_rdoc_class_module.rb +100 -0
- data/test/test_rdoc_code_object.rb +18 -2
- data/test/test_rdoc_context.rb +41 -0
- data/test/test_rdoc_generator_ri.rb +56 -0
- data/test/test_rdoc_markup.rb +21 -610
- data/test/test_rdoc_markup_attribute_manager.rb +14 -17
- data/test/test_rdoc_markup_document.rb +51 -0
- data/test/test_rdoc_markup_paragraph.rb +27 -0
- data/test/test_rdoc_markup_parser.rb +1327 -0
- data/test/test_rdoc_markup_to_ansi.rb +426 -0
- data/test/test_rdoc_markup_to_bs.rb +443 -0
- data/test/test_rdoc_markup_to_html.rb +183 -18
- data/test/test_rdoc_markup_to_html_crossref.rb +1 -3
- data/test/test_rdoc_markup_to_rdoc.rb +426 -0
- data/test/test_rdoc_normal_class.rb +17 -0
- data/test/test_rdoc_normal_module.rb +6 -6
- data/test/test_rdoc_options.rb +41 -0
- data/test/test_rdoc_parser.rb +66 -13
- data/test/test_rdoc_parser_c.rb +93 -38
- data/test/test_rdoc_parser_perl.rb +2 -3
- data/test/test_rdoc_parser_ruby.rb +291 -28
- data/test/test_rdoc_parser_simple.rb +48 -0
- data/test/test_rdoc_rdoc.rb +66 -0
- data/test/test_rdoc_ri_driver.rb +752 -38
- data/test/test_rdoc_ri_paths.rb +39 -0
- data/test/test_rdoc_ri_store.rb +309 -0
- data/test/test_rdoc_text.rb +157 -0
- data/test/test_rdoc_top_level.rb +35 -9
- data/test/xref_data.rb +9 -1
- data/test/xref_test_case.rb +8 -3
- metadata +110 -38
- metadata.gz.sig +0 -0
- data/lib/rdoc/cache.rb +0 -41
- data/lib/rdoc/diagram.rb +0 -340
- data/lib/rdoc/dot.rb +0 -249
- data/lib/rdoc/markup/fragments.rb +0 -377
- data/lib/rdoc/markup/lines.rb +0 -156
- data/lib/rdoc/markup/to_flow.rb +0 -211
- data/lib/rdoc/markup/to_latex.rb +0 -328
- data/lib/rdoc/markup/to_texinfo.rb +0 -73
- data/lib/rdoc/ri/cache.rb +0 -187
- data/lib/rdoc/ri/descriptions.rb +0 -156
- data/lib/rdoc/ri/display.rb +0 -340
- data/lib/rdoc/ri/reader.rb +0 -106
- data/lib/rdoc/ri/util.rb +0 -79
- data/lib/rdoc/ri/writer.rb +0 -68
- data/test/test_rdoc_ri_attribute_formatter.rb +0 -44
- data/test/test_rdoc_ri_default_display.rb +0 -302
- data/test/test_rdoc_ri_formatter.rb +0 -320
- data/test/test_rdoc_ri_html_formatter.rb +0 -141
- data/test/test_rdoc_ri_overstrike_formatter.rb +0 -71
@@ -0,0 +1,17 @@
|
|
1
|
+
##
|
2
|
+
# A heading with a level (1-6) and text
|
3
|
+
|
4
|
+
class RDoc::Markup::Heading < Struct.new :level, :text
|
5
|
+
|
6
|
+
def accept visitor
|
7
|
+
visitor.accept_heading self
|
8
|
+
end
|
9
|
+
|
10
|
+
def pretty_print q # :nodoc:
|
11
|
+
q.group 2, "[head: #{level} ", ']' do
|
12
|
+
q.pp text
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
data/lib/rdoc/markup/inline.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'rdoc/markup'
|
2
|
-
|
3
1
|
class RDoc::Markup
|
4
2
|
|
5
3
|
##
|
@@ -7,6 +5,10 @@ class RDoc::Markup
|
|
7
5
|
# value.
|
8
6
|
|
9
7
|
class Attribute
|
8
|
+
|
9
|
+
##
|
10
|
+
# Special attribute type. See RDoc::Markup#add_special
|
11
|
+
|
10
12
|
SPECIAL = 1
|
11
13
|
|
12
14
|
@@name_to_bitmap = { :_SPECIAL_ => SPECIAL }
|
@@ -40,7 +42,7 @@ class RDoc::Markup
|
|
40
42
|
|
41
43
|
end
|
42
44
|
|
43
|
-
AttrChanger = Struct.new :turn_on, :turn_off
|
45
|
+
AttrChanger = Struct.new :turn_on, :turn_off # :nodoc:
|
44
46
|
|
45
47
|
##
|
46
48
|
# An AttrChanger records a change in attributes. It contains a bitmap of the
|
@@ -48,7 +50,7 @@ class RDoc::Markup
|
|
48
50
|
|
49
51
|
class AttrChanger
|
50
52
|
def to_s # :nodoc:
|
51
|
-
"Attr: +#{Attribute.as_string
|
53
|
+
"Attr: +#{Attribute.as_string turn_on}/-#{Attribute.as_string turn_on}"
|
52
54
|
end
|
53
55
|
end
|
54
56
|
|
@@ -123,4 +125,3 @@ class RDoc::Markup
|
|
123
125
|
|
124
126
|
end
|
125
127
|
|
126
|
-
require 'rdoc/markup/attribute_manager'
|
@@ -0,0 +1,78 @@
|
|
1
|
+
##
|
2
|
+
# A List of ListItems
|
3
|
+
|
4
|
+
class RDoc::Markup::List
|
5
|
+
|
6
|
+
##
|
7
|
+
# The list's type
|
8
|
+
|
9
|
+
attr_accessor :type
|
10
|
+
|
11
|
+
##
|
12
|
+
# Items in the list
|
13
|
+
|
14
|
+
attr_reader :items
|
15
|
+
|
16
|
+
##
|
17
|
+
# Creates a new list of +type+ with +items+
|
18
|
+
|
19
|
+
def initialize type = nil, *items
|
20
|
+
@type = type
|
21
|
+
@items = []
|
22
|
+
@items.push(*items)
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
# Appends +item+ to the list
|
27
|
+
|
28
|
+
def << item
|
29
|
+
@items << item
|
30
|
+
end
|
31
|
+
|
32
|
+
def == other # :nodoc:
|
33
|
+
self.class == other.class and
|
34
|
+
@type == other.type and
|
35
|
+
@items == other.items
|
36
|
+
end
|
37
|
+
|
38
|
+
def accept visitor
|
39
|
+
visitor.accept_list_start self
|
40
|
+
|
41
|
+
@items.each do |item|
|
42
|
+
item.accept visitor
|
43
|
+
end
|
44
|
+
|
45
|
+
visitor.accept_list_end self
|
46
|
+
end
|
47
|
+
|
48
|
+
##
|
49
|
+
# Is the list empty?
|
50
|
+
|
51
|
+
def empty?
|
52
|
+
@items.empty?
|
53
|
+
end
|
54
|
+
|
55
|
+
##
|
56
|
+
# Returns the last item in the list
|
57
|
+
|
58
|
+
def last
|
59
|
+
@items.last
|
60
|
+
end
|
61
|
+
|
62
|
+
def pretty_print q # :nodoc:
|
63
|
+
q.group 2, "[list: #{@type} ", ']' do
|
64
|
+
q.seplist @items do |item|
|
65
|
+
q.pp item
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
##
|
71
|
+
# Appends +items+ to the list
|
72
|
+
|
73
|
+
def push *items
|
74
|
+
@items.push(*items)
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
@@ -0,0 +1,83 @@
|
|
1
|
+
##
|
2
|
+
# An item within a List that contains paragraphs, headings, etc.
|
3
|
+
|
4
|
+
class RDoc::Markup::ListItem
|
5
|
+
|
6
|
+
##
|
7
|
+
# The label for the ListItem
|
8
|
+
|
9
|
+
attr_accessor :label
|
10
|
+
|
11
|
+
##
|
12
|
+
# Parts of the ListItem
|
13
|
+
|
14
|
+
attr_reader :parts
|
15
|
+
|
16
|
+
##
|
17
|
+
# Creates a new ListItem with an optional +label+ containing +parts+
|
18
|
+
|
19
|
+
def initialize label = nil, *parts
|
20
|
+
@label = label
|
21
|
+
@parts = []
|
22
|
+
@parts.push(*parts)
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
# Appends +part+ to the ListItem
|
27
|
+
|
28
|
+
def << part
|
29
|
+
@parts << part
|
30
|
+
end
|
31
|
+
|
32
|
+
def == other # :nodoc:
|
33
|
+
self.class == other.class and
|
34
|
+
@label == other.label and
|
35
|
+
@parts == other.parts
|
36
|
+
end
|
37
|
+
|
38
|
+
def accept visitor
|
39
|
+
visitor.accept_list_item_start self
|
40
|
+
|
41
|
+
@parts.each do |part|
|
42
|
+
part.accept visitor
|
43
|
+
end
|
44
|
+
|
45
|
+
visitor.accept_list_item_end self
|
46
|
+
end
|
47
|
+
|
48
|
+
##
|
49
|
+
# Is the ListItem empty?
|
50
|
+
|
51
|
+
def empty?
|
52
|
+
@parts.empty?
|
53
|
+
end
|
54
|
+
|
55
|
+
##
|
56
|
+
# Length of parts in the ListItem
|
57
|
+
|
58
|
+
def length
|
59
|
+
@parts.length
|
60
|
+
end
|
61
|
+
|
62
|
+
def pretty_print q # :nodoc:
|
63
|
+
q.group 2, '[item: ', ']' do
|
64
|
+
if @label then
|
65
|
+
q.text @label
|
66
|
+
q.breakable
|
67
|
+
end
|
68
|
+
|
69
|
+
q.seplist @parts do |part|
|
70
|
+
q.pp part
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
##
|
76
|
+
# Adds +parts+ to the ListItem
|
77
|
+
|
78
|
+
def push *parts
|
79
|
+
@parts.push(*parts)
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
@@ -0,0 +1,66 @@
|
|
1
|
+
##
|
2
|
+
# A Paragraph of text
|
3
|
+
|
4
|
+
class RDoc::Markup::Paragraph
|
5
|
+
|
6
|
+
##
|
7
|
+
# The component parts of the list
|
8
|
+
|
9
|
+
attr_reader :parts
|
10
|
+
|
11
|
+
##
|
12
|
+
# Creates a new Paragraph containing +parts+
|
13
|
+
|
14
|
+
def initialize *parts
|
15
|
+
@parts = []
|
16
|
+
@parts.push(*parts)
|
17
|
+
end
|
18
|
+
|
19
|
+
##
|
20
|
+
# Appends +text+ to the Paragraph
|
21
|
+
|
22
|
+
def << text
|
23
|
+
@parts << text
|
24
|
+
end
|
25
|
+
|
26
|
+
def == other # :nodoc:
|
27
|
+
self.class == other.class and text == other.text
|
28
|
+
end
|
29
|
+
|
30
|
+
def accept visitor
|
31
|
+
visitor.accept_paragraph self
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# Appends +other+'s parts into this Paragraph
|
36
|
+
|
37
|
+
def merge other
|
38
|
+
@parts.push(*other.parts)
|
39
|
+
end
|
40
|
+
|
41
|
+
def pretty_print q # :nodoc:
|
42
|
+
self.class.name =~ /.*::(\w{4})/i
|
43
|
+
|
44
|
+
q.group 2, "[#{$1.downcase}: ", ']' do
|
45
|
+
q.seplist @parts do |part|
|
46
|
+
q.pp part
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
##
|
52
|
+
# Appends +texts+ onto this Paragraph
|
53
|
+
|
54
|
+
def push *texts
|
55
|
+
self.parts.push(*texts)
|
56
|
+
end
|
57
|
+
|
58
|
+
##
|
59
|
+
# The text of this paragraph
|
60
|
+
|
61
|
+
def text
|
62
|
+
@parts.join ' '
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
@@ -0,0 +1,528 @@
|
|
1
|
+
require 'strscan'
|
2
|
+
require 'rdoc/text'
|
3
|
+
|
4
|
+
##
|
5
|
+
# A recursive-descent parser for RDoc markup.
|
6
|
+
#
|
7
|
+
# The parser tokenizes an input string then parses the tokens into a Document.
|
8
|
+
# Documents can be converted into output formats by writing a visitor like
|
9
|
+
# RDoc::Markup::ToHTML.
|
10
|
+
#
|
11
|
+
# The parser only handles the block-level constructs Paragraph, List,
|
12
|
+
# ListItem, Heading, Verbatim, BlankLine and Rule. Inline markup such as
|
13
|
+
# <tt>\+blah\+</tt> is handled separately by RDoc::Markup::AttributeManager.
|
14
|
+
#
|
15
|
+
# To see what markup the Parser implements read RDoc. To see how to use
|
16
|
+
# RDoc markup to format text in your program read RDoc::Markup.
|
17
|
+
|
18
|
+
class RDoc::Markup::Parser
|
19
|
+
|
20
|
+
include RDoc::Text
|
21
|
+
|
22
|
+
##
|
23
|
+
# List token types
|
24
|
+
|
25
|
+
LIST_TOKENS = [
|
26
|
+
:BULLET,
|
27
|
+
:LABEL,
|
28
|
+
:LALPHA,
|
29
|
+
:NOTE,
|
30
|
+
:NUMBER,
|
31
|
+
:UALPHA,
|
32
|
+
]
|
33
|
+
|
34
|
+
##
|
35
|
+
# Parser error subclass
|
36
|
+
|
37
|
+
class Error < RuntimeError; end
|
38
|
+
|
39
|
+
##
|
40
|
+
# Raised when the parser is unable to handle the given markup
|
41
|
+
|
42
|
+
class ParseError < Error; end
|
43
|
+
|
44
|
+
##
|
45
|
+
# Enables display of debugging information
|
46
|
+
|
47
|
+
attr_accessor :debug
|
48
|
+
|
49
|
+
##
|
50
|
+
# Token accessor
|
51
|
+
|
52
|
+
attr_reader :tokens
|
53
|
+
|
54
|
+
##
|
55
|
+
# Parsers +str+ into a Document
|
56
|
+
|
57
|
+
def self.parse str
|
58
|
+
parser = new
|
59
|
+
#parser.debug = true
|
60
|
+
parser.tokenize str
|
61
|
+
RDoc::Markup::Document.new(*parser.parse)
|
62
|
+
end
|
63
|
+
|
64
|
+
##
|
65
|
+
# Returns a token stream for +str+, for testing
|
66
|
+
|
67
|
+
def self.tokenize str
|
68
|
+
parser = new
|
69
|
+
parser.tokenize str
|
70
|
+
parser.tokens
|
71
|
+
end
|
72
|
+
|
73
|
+
##
|
74
|
+
# Creates a new Parser. See also ::parse
|
75
|
+
|
76
|
+
def initialize
|
77
|
+
@tokens = []
|
78
|
+
@current_token = nil
|
79
|
+
@debug = false
|
80
|
+
|
81
|
+
@line = 0
|
82
|
+
@line_pos = 0
|
83
|
+
end
|
84
|
+
|
85
|
+
##
|
86
|
+
# Builds a Heading of +level+
|
87
|
+
|
88
|
+
def build_heading level
|
89
|
+
heading = RDoc::Markup::Heading.new level, text
|
90
|
+
skip :NEWLINE
|
91
|
+
|
92
|
+
heading
|
93
|
+
end
|
94
|
+
|
95
|
+
##
|
96
|
+
# Builds a List flush to +margin+
|
97
|
+
|
98
|
+
def build_list margin
|
99
|
+
p :list_start => margin if @debug
|
100
|
+
|
101
|
+
list = RDoc::Markup::List.new
|
102
|
+
|
103
|
+
until @tokens.empty? do
|
104
|
+
type, data, column, = get
|
105
|
+
|
106
|
+
case type
|
107
|
+
when :BULLET, :LABEL, :LALPHA, :NOTE, :NUMBER, :UALPHA then
|
108
|
+
list_type = type
|
109
|
+
|
110
|
+
if column < margin then
|
111
|
+
unget
|
112
|
+
break
|
113
|
+
end
|
114
|
+
|
115
|
+
if list.type and list.type != list_type then
|
116
|
+
unget
|
117
|
+
break
|
118
|
+
end
|
119
|
+
|
120
|
+
list.type = list_type
|
121
|
+
|
122
|
+
case type
|
123
|
+
when :NOTE, :LABEL then
|
124
|
+
_, indent, = get # SPACE
|
125
|
+
if :NEWLINE == peek_token.first then
|
126
|
+
get
|
127
|
+
peek_type, new_indent, peek_column, = peek_token
|
128
|
+
indent = new_indent if
|
129
|
+
peek_type == :INDENT and peek_column >= column
|
130
|
+
unget
|
131
|
+
end
|
132
|
+
else
|
133
|
+
data = nil
|
134
|
+
_, indent, = get
|
135
|
+
end
|
136
|
+
|
137
|
+
list_item = build_list_item(margin + indent, data)
|
138
|
+
|
139
|
+
list << list_item if list_item
|
140
|
+
else
|
141
|
+
unget
|
142
|
+
break
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
p :list_end => margin if @debug
|
147
|
+
|
148
|
+
return nil if list.empty?
|
149
|
+
|
150
|
+
list
|
151
|
+
end
|
152
|
+
|
153
|
+
##
|
154
|
+
# Builds a ListItem that is flush to +indent+ with type +item_type+
|
155
|
+
|
156
|
+
def build_list_item indent, item_type = nil
|
157
|
+
p :list_item_start => [indent, item_type] if @debug
|
158
|
+
|
159
|
+
list_item = RDoc::Markup::ListItem.new item_type
|
160
|
+
|
161
|
+
until @tokens.empty? do
|
162
|
+
type, data, column = get
|
163
|
+
|
164
|
+
if column < indent and
|
165
|
+
not type == :NEWLINE and
|
166
|
+
(type != :INDENT or data < indent) then
|
167
|
+
unget
|
168
|
+
break
|
169
|
+
end
|
170
|
+
|
171
|
+
case type
|
172
|
+
when :INDENT then
|
173
|
+
unget
|
174
|
+
list_item.push(*parse(indent))
|
175
|
+
when :TEXT then
|
176
|
+
unget
|
177
|
+
list_item << build_paragraph(indent)
|
178
|
+
when :HEADER then
|
179
|
+
list_item << build_heading(data)
|
180
|
+
when :NEWLINE then
|
181
|
+
list_item << RDoc::Markup::BlankLine.new
|
182
|
+
when *LIST_TOKENS then
|
183
|
+
unget
|
184
|
+
list_item << build_list(column)
|
185
|
+
else
|
186
|
+
raise ParseError, "Unhandled token #{@current_token.inspect}"
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
p :list_item_end => [indent, item_type] if @debug
|
191
|
+
|
192
|
+
return nil if list_item.empty?
|
193
|
+
|
194
|
+
list_item.parts.shift if
|
195
|
+
RDoc::Markup::BlankLine === list_item.parts.first and
|
196
|
+
list_item.length > 1
|
197
|
+
|
198
|
+
list_item
|
199
|
+
end
|
200
|
+
|
201
|
+
##
|
202
|
+
# Builds a Paragraph that is flush to +margin+
|
203
|
+
|
204
|
+
def build_paragraph margin
|
205
|
+
p :paragraph_start => margin if @debug
|
206
|
+
|
207
|
+
paragraph = RDoc::Markup::Paragraph.new
|
208
|
+
|
209
|
+
until @tokens.empty? do
|
210
|
+
type, data, column, = get
|
211
|
+
|
212
|
+
case type
|
213
|
+
when :INDENT then
|
214
|
+
next if data == margin and peek_token[0] == :TEXT
|
215
|
+
|
216
|
+
unget
|
217
|
+
break
|
218
|
+
when :TEXT then
|
219
|
+
if column != margin then
|
220
|
+
unget
|
221
|
+
break
|
222
|
+
end
|
223
|
+
|
224
|
+
paragraph << data
|
225
|
+
skip :NEWLINE
|
226
|
+
else
|
227
|
+
unget
|
228
|
+
break
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
p :paragraph_end => margin if @debug
|
233
|
+
|
234
|
+
paragraph
|
235
|
+
end
|
236
|
+
|
237
|
+
##
|
238
|
+
# Builds a Verbatim that is flush to +margin+
|
239
|
+
|
240
|
+
def build_verbatim margin
|
241
|
+
p :verbatim_begin => margin if @debug
|
242
|
+
verbatim = RDoc::Markup::Verbatim.new
|
243
|
+
|
244
|
+
until @tokens.empty? do
|
245
|
+
type, data, column, = get
|
246
|
+
|
247
|
+
case type
|
248
|
+
when :INDENT then
|
249
|
+
if margin >= data then
|
250
|
+
unget
|
251
|
+
break
|
252
|
+
end
|
253
|
+
|
254
|
+
indent = data - margin
|
255
|
+
|
256
|
+
verbatim << ' ' * indent
|
257
|
+
when :HEADER then
|
258
|
+
verbatim << '=' * data
|
259
|
+
|
260
|
+
_, _, peek_column, = peek_token
|
261
|
+
peek_column ||= column + data
|
262
|
+
verbatim << ' ' * (peek_column - column - data)
|
263
|
+
when :RULE then
|
264
|
+
width = 2 + data
|
265
|
+
verbatim << '-' * width
|
266
|
+
|
267
|
+
_, _, peek_column, = peek_token
|
268
|
+
peek_column ||= column + data + 2
|
269
|
+
verbatim << ' ' * (peek_column - column - width)
|
270
|
+
when :TEXT then
|
271
|
+
verbatim << data
|
272
|
+
when *LIST_TOKENS then
|
273
|
+
if column <= margin then
|
274
|
+
unget
|
275
|
+
break
|
276
|
+
end
|
277
|
+
|
278
|
+
list_marker = case type
|
279
|
+
when :BULLET then '*'
|
280
|
+
when :LABEL then "[#{data}]"
|
281
|
+
when :LALPHA, :NUMBER, :UALPHA then "#{data}."
|
282
|
+
when :NOTE then "#{data}::"
|
283
|
+
end
|
284
|
+
|
285
|
+
verbatim << list_marker
|
286
|
+
|
287
|
+
_, data, = get
|
288
|
+
|
289
|
+
verbatim << ' ' * (data - list_marker.length)
|
290
|
+
when :NEWLINE then
|
291
|
+
verbatim << data
|
292
|
+
break unless [:INDENT, :NEWLINE].include? peek_token[0]
|
293
|
+
else
|
294
|
+
unget
|
295
|
+
break
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
verbatim.normalize
|
300
|
+
|
301
|
+
p :verbatim_end => margin if @debug
|
302
|
+
|
303
|
+
verbatim
|
304
|
+
end
|
305
|
+
|
306
|
+
##
|
307
|
+
# Pulls the next token from the stream.
|
308
|
+
|
309
|
+
def get
|
310
|
+
@current_token = @tokens.shift
|
311
|
+
p :get => @current_token if @debug
|
312
|
+
@current_token
|
313
|
+
end
|
314
|
+
|
315
|
+
##
|
316
|
+
# Parses the tokens into a Document
|
317
|
+
|
318
|
+
def parse indent = 0
|
319
|
+
p :parse_start => indent if @debug
|
320
|
+
|
321
|
+
document = []
|
322
|
+
|
323
|
+
until @tokens.empty? do
|
324
|
+
type, data, column, = get
|
325
|
+
|
326
|
+
if type != :INDENT and column < indent then
|
327
|
+
unget
|
328
|
+
break
|
329
|
+
end
|
330
|
+
|
331
|
+
case type
|
332
|
+
when :HEADER then
|
333
|
+
document << build_heading(data)
|
334
|
+
when :INDENT then
|
335
|
+
if indent > data then
|
336
|
+
unget
|
337
|
+
break
|
338
|
+
elsif indent == data then
|
339
|
+
next
|
340
|
+
end
|
341
|
+
|
342
|
+
unget
|
343
|
+
document << build_verbatim(indent)
|
344
|
+
when :NEWLINE then
|
345
|
+
document << RDoc::Markup::BlankLine.new
|
346
|
+
skip :NEWLINE, false
|
347
|
+
when :RULE then
|
348
|
+
document << RDoc::Markup::Rule.new(data)
|
349
|
+
skip :NEWLINE
|
350
|
+
when :TEXT then
|
351
|
+
unget
|
352
|
+
document << build_paragraph(indent)
|
353
|
+
|
354
|
+
# we're done with this paragraph (indent mismatch)
|
355
|
+
break if peek_token[0] == :TEXT
|
356
|
+
when *LIST_TOKENS then
|
357
|
+
unget
|
358
|
+
|
359
|
+
list = build_list(indent)
|
360
|
+
|
361
|
+
document << list if list
|
362
|
+
|
363
|
+
# we're done with this list (indent mismatch)
|
364
|
+
break if LIST_TOKENS.include? peek_token.first and indent > 0
|
365
|
+
else
|
366
|
+
type, data, column, line = @current_token
|
367
|
+
raise ParseError,
|
368
|
+
"Unhandled token #{type} (#{data.inspect}) at #{line}:#{column}"
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
372
|
+
p :parse_end => indent if @debug
|
373
|
+
|
374
|
+
document
|
375
|
+
end
|
376
|
+
|
377
|
+
##
|
378
|
+
# Returns the next token on the stream without modifying the stream
|
379
|
+
|
380
|
+
def peek_token
|
381
|
+
token = @tokens.first || []
|
382
|
+
p :peek => token if @debug
|
383
|
+
token
|
384
|
+
end
|
385
|
+
|
386
|
+
##
|
387
|
+
# Skips a token of +token_type+, optionally raising an error.
|
388
|
+
|
389
|
+
def skip token_type, error = true
|
390
|
+
type, data, = get
|
391
|
+
|
392
|
+
return unless type # end of stream
|
393
|
+
|
394
|
+
return @current_token if token_type == type
|
395
|
+
|
396
|
+
unget
|
397
|
+
|
398
|
+
raise ParseError, "expected #{token_type} got #{@current_token.inspect}" if
|
399
|
+
error
|
400
|
+
end
|
401
|
+
|
402
|
+
##
|
403
|
+
# Consumes tokens until NEWLINE and turns them back into text
|
404
|
+
|
405
|
+
def text
|
406
|
+
text = ''
|
407
|
+
|
408
|
+
loop do
|
409
|
+
type, data, = get
|
410
|
+
|
411
|
+
text << case type
|
412
|
+
when :BULLET then
|
413
|
+
_, space, = get # SPACE
|
414
|
+
"*#{' ' * (space - 1)}"
|
415
|
+
when :LABEL then
|
416
|
+
_, space, = get # SPACE
|
417
|
+
"[#{data}]#{' ' * (space - data.length - 2)}"
|
418
|
+
when :LALPHA, :NUMBER, :UALPHA then
|
419
|
+
_, space, = get # SPACE
|
420
|
+
"#{data}.#{' ' * (space - 2)}"
|
421
|
+
when :NOTE then
|
422
|
+
_, space = get # SPACE
|
423
|
+
"#{data}::#{' ' * (space - data.length - 2)}"
|
424
|
+
when :TEXT then
|
425
|
+
data
|
426
|
+
when :NEWLINE then
|
427
|
+
unget
|
428
|
+
break
|
429
|
+
when nil then
|
430
|
+
break
|
431
|
+
else
|
432
|
+
raise ParseError, "unhandled token #{@current_token.inspect}"
|
433
|
+
end
|
434
|
+
end
|
435
|
+
|
436
|
+
text
|
437
|
+
end
|
438
|
+
|
439
|
+
##
|
440
|
+
# Calculates the column and line of the current token based on +offset+.
|
441
|
+
|
442
|
+
def token_pos offset
|
443
|
+
[offset - @line_pos, @line]
|
444
|
+
end
|
445
|
+
|
446
|
+
##
|
447
|
+
# Turns text +input+ into a stream of tokens
|
448
|
+
|
449
|
+
def tokenize input
|
450
|
+
s = StringScanner.new input
|
451
|
+
|
452
|
+
@line = 0
|
453
|
+
@line_pos = 0
|
454
|
+
|
455
|
+
until s.eos? do
|
456
|
+
pos = s.pos
|
457
|
+
|
458
|
+
@tokens << case
|
459
|
+
when s.scan(/\r?\n/) then
|
460
|
+
token = [:NEWLINE, s.matched, *token_pos(pos)]
|
461
|
+
@line_pos = s.pos
|
462
|
+
@line += 1
|
463
|
+
token
|
464
|
+
when s.scan(/ +/) then
|
465
|
+
[:INDENT, s.matched_size, *token_pos(pos)]
|
466
|
+
when s.scan(/(=+)\s+/) then
|
467
|
+
level = s[1].length
|
468
|
+
level = 6 if level > 6
|
469
|
+
@tokens << [:HEADER, level, *token_pos(pos)]
|
470
|
+
|
471
|
+
pos = s.pos
|
472
|
+
s.scan(/.*/)
|
473
|
+
[:TEXT, s.matched, *token_pos(pos)]
|
474
|
+
when s.scan(/^(-{3,}) *$/) then
|
475
|
+
[:RULE, s[1].length - 2, *token_pos(pos)]
|
476
|
+
when s.scan(/([*-])\s+/) then
|
477
|
+
@tokens << [:BULLET, :BULLET, *token_pos(pos)]
|
478
|
+
[:SPACE, s.matched_size, *token_pos(pos)]
|
479
|
+
when s.scan(/([a-z]|\d+)\.[ \t]+\S/i) then
|
480
|
+
list_label = s[1]
|
481
|
+
width = s.matched_size - 1
|
482
|
+
|
483
|
+
s.pos -= 1 # unget \S
|
484
|
+
|
485
|
+
list_type = case list_label
|
486
|
+
when /[a-z]/ then :LALPHA
|
487
|
+
when /[A-Z]/ then :UALPHA
|
488
|
+
when /\d/ then :NUMBER
|
489
|
+
else
|
490
|
+
raise ParseError, "BUG token #{list_label}"
|
491
|
+
end
|
492
|
+
|
493
|
+
@tokens << [list_type, list_label, *token_pos(pos)]
|
494
|
+
[:SPACE, width, *token_pos(pos)]
|
495
|
+
when s.scan(/\[(.*?)\]( +|$)/) then
|
496
|
+
@tokens << [:LABEL, s[1], *token_pos(pos)]
|
497
|
+
[:SPACE, s.matched_size, *token_pos(pos)]
|
498
|
+
when s.scan(/(.*?)::( +|$)/) then
|
499
|
+
@tokens << [:NOTE, s[1], *token_pos(pos)]
|
500
|
+
[:SPACE, s.matched_size, *token_pos(pos)]
|
501
|
+
else s.scan(/.*/)
|
502
|
+
[:TEXT, s.matched, *token_pos(pos)]
|
503
|
+
end
|
504
|
+
end
|
505
|
+
|
506
|
+
self
|
507
|
+
end
|
508
|
+
|
509
|
+
##
|
510
|
+
# Returns the current token or +token+ to the token stream
|
511
|
+
|
512
|
+
def unget token = @current_token
|
513
|
+
p :unget => token if @debug
|
514
|
+
raise Error, 'too many #ungets' if token == @tokens.first
|
515
|
+
@tokens.unshift token if token
|
516
|
+
end
|
517
|
+
|
518
|
+
end
|
519
|
+
|
520
|
+
require 'rdoc/markup/blank_line'
|
521
|
+
require 'rdoc/markup/document'
|
522
|
+
require 'rdoc/markup/heading'
|
523
|
+
require 'rdoc/markup/list'
|
524
|
+
require 'rdoc/markup/list_item'
|
525
|
+
require 'rdoc/markup/paragraph'
|
526
|
+
require 'rdoc/markup/rule'
|
527
|
+
require 'rdoc/markup/verbatim'
|
528
|
+
|