raf 0.0.0 → 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.
@@ -0,0 +1,356 @@
1
+ class BlockParser
2
+ token HEADER WHITELINE HEADLINE PLAIN DESCLINE_TITLE DESCLINE QUOTE INDENT DEDENT ITEMLIST ITEMLISTCONTINUE NUMLIST TABLELINE
3
+ preclow
4
+ nonassoc DUMMY
5
+ prechigh
6
+ options no_result_var
7
+
8
+ rule
9
+ document : blocks{ val[0].compact }
10
+
11
+ blocks : block { val }
12
+ | blocks block { [val[0], val[1]].flatten }
13
+
14
+ block : header
15
+ | paragraph { val[0] }
16
+ | quote_block
17
+ | itemlist_blocks { ItemList.new(val[0].flatten) }
18
+ | numlist_blocks { NumList.new(val[0].flatten) }
19
+ | desc_block
20
+ | table_block
21
+ | headline
22
+ | WHITELINE { WhiteLine.new }
23
+
24
+ # ----- header
25
+ header : HEADER {
26
+ name, val = val[0].split(":",2)
27
+ if name.nil? or val.nil?
28
+ else
29
+ @info.update({name.strip.to_sym => val.strip })
30
+ end
31
+ nil }
32
+
33
+ # ----- headline
34
+ headline : HEADLINE { # val[0] is like [level, title, index]
35
+ title = val[0][1]
36
+ level = val[0][0]
37
+ if level == 1
38
+ @info[:subject] ||= title
39
+ else
40
+ @head_index.update(level)
41
+ end
42
+
43
+ @index[:head] ||= []
44
+ @index[:head] << {:title => title, :level => level, :index => @head_index.to_s}
45
+ HeadLine.new([level, title, @index[:head].size, @head_index.to_s]) }
46
+ # ----- paragraph
47
+ paragraph : plain_texts { Paragraph.new @inline_parser.parse(val) }
48
+
49
+ plain_texts : PLAIN { val[0] }
50
+ | plain_texts PLAIN { val[0] + val[1] }
51
+
52
+ # ----- desc
53
+ desc_block : DESCLINE_TITLE desclines {
54
+ if val[1].nil?
55
+ lines = [Plain.new("")]
56
+ else
57
+ lines = @inline_parser.parse(val[1])
58
+ end
59
+ Desc.new([val[0], lines])
60
+ }
61
+
62
+
63
+ desclines : DESCLINE { val[0] }
64
+ | desclines DESCLINE { val[0] + val[1] }
65
+ |
66
+
67
+
68
+ # ----- quote
69
+ quote_block : quotes { qu = val[0].strip ; Quote.new([qu]) unless qu.empty? }
70
+
71
+ quotes : QUOTE { val[0] }
72
+ | quotes QUOTE { val[0] + val[1] }
73
+
74
+ # ----- quote end
75
+ # ----- itemlist
76
+ itemlist_blocks : itemlist_block { val[0] }
77
+ | itemlist_blocks itemlist_block { val[0] << val[1] }
78
+
79
+ itemlist_block : itemlists { val[0] }
80
+ | itemlist_indent_blocks { val[0] }
81
+
82
+ itemlist_indent_blocks : INDENT itemlist_blocks DEDENT { val }
83
+
84
+ itemlists : itemlistitems {[PlainTextBlock.new(@inline_parser.parse(val[0]))]}
85
+ | itemlists itemlistitems { val[0] << PlainTextBlock.new(@inline_parser.parse(val[1])) }
86
+
87
+ itemlistitems : ITEMLIST { val[0] }
88
+ | ITEMLIST itemlist_continues { val[0] + val[1] }
89
+
90
+ itemlist_continues : ITEMLISTCONTINUE { "\n" + val[0] }
91
+ | itemlist_continues ITEMLISTCONTINUE { val[0] + "\n" + val[1] }
92
+
93
+ # ----- itemlist end
94
+ # ----- numlist
95
+ numlist_blocks : numlist_block { val[0] }
96
+ | numlist_blocks numlist_block { val[0] << val[1] }
97
+
98
+ numlist_block : numlists { val[0] }
99
+ | numlist_indent_blocks { val[0] }
100
+
101
+ numlist_indent_blocks : INDENT numlist_blocks DEDENT { val }
102
+
103
+ numlists : NUMLIST { [PlainTextBlock.new(@inline_parser.parse(val[0]))] }
104
+ | numlists NUMLIST { val[0] << PlainTextBlock.new(@inline_parser.parse(val[1])) }
105
+
106
+ # ----- numlist end
107
+
108
+ # ----- tableblock
109
+ table_block : tablelines { Table.new(val[0]) }
110
+
111
+ tablelines : TABLELINE { val }
112
+ | tablelines TABLELINE { val[0] << val[1] }
113
+
114
+ # ----- tableblock end
115
+ end # end of rule
116
+
117
+ ---- inner
118
+ include ParserUtility
119
+
120
+ class Line
121
+ def initialize(line)
122
+ @content = line
123
+ # @indent = get_line_indent(line)
124
+ # @type = nil
125
+ end
126
+ attr_reader :indent, :no
127
+ attr_accessor :type, :content
128
+ alias indent_size indent
129
+
130
+ def get_line_indent
131
+ return 0 if @content.nil?
132
+ @content =~ /(\s*)/
133
+ $1.size
134
+ end
135
+ alias indent get_line_indent
136
+ end
137
+
138
+
139
+ def initialize
140
+ @inline_parser = InlineParser.new
141
+ @info = {}
142
+ @inline_index = @inline_parser.index
143
+ @index = {}
144
+ @head_index = HeadIndex.new
145
+ end
146
+ attr_reader :info, :inline_index, :index
147
+
148
+ def parse(src)
149
+ @no = 0
150
+ @src = src.to_a
151
+ @line = Line.new("")
152
+ @line_pre = @line.dup
153
+ @indent_stack = []
154
+ @current_indent = 0
155
+ @current_type = :header
156
+ @yydebug = true
157
+ @view_token_type = false
158
+ do_parse
159
+ end
160
+
161
+ def on_error(token_id, value, stack)
162
+ lineno = @src[0..@no].to_s.split("\n").size
163
+ raise Racc::ParseError,
164
+ "rafblockpaser: line #{lineno}: syntax error on #{value.inspect}"
165
+ end
166
+
167
+ def next_token
168
+ @line_pre = @line.dup
169
+ @line = Line.new(@src[@no])
170
+ # puts "line: #{@line.content}" if @view_token_type
171
+ case @line.content
172
+ when nil
173
+ @line.content = ""
174
+ if_current_indent_equal("") do
175
+ puts "b: false: #{@line.content}" if @view_token_type
176
+ [false, false]
177
+ end
178
+ when /^$/
179
+ @line.content = ""
180
+ if_current_indent_equal("") do
181
+ if @current_type == :quote
182
+ puts "b: QUOTE: #{@line.content}" if @view_token_type
183
+ [:QUOTE, "\n"]
184
+ elsif @current_type == :descline
185
+ puts "b: DESCLINE: #{@line.content}" if @view_token_type
186
+ [:DESCLINE, " "]
187
+ else
188
+ puts "b: WHITELINE: #{@line.content}" if @view_token_type
189
+ @current_type = :whiteline
190
+ [:WHITELINE, :WHITELINE]
191
+ end
192
+ end
193
+ when /^\#(.*)/ # comment line
194
+ @no += 1
195
+ if @current_type == :header
196
+ puts "b: HEADER: #{@line.content}" if @view_token_type
197
+ [:HEADER, $1.strip]
198
+ else
199
+ puts "b: COMMENT(noop): #{@line.content}" if @view_token_type
200
+ next_token
201
+ end
202
+ when /^(={1,4})(?!=)\s*(?=\S)/, /^(\+{1,2})(?!\+)\s*(?=\S)/
203
+ rest = $' # '
204
+ rest.strip!
205
+ mark = $1
206
+ # if_current_indent_equal("") do
207
+ if_current_indent_equal(@line.indent) do
208
+ @current_type = :headline
209
+ puts "b: HEADLINE: #{@line.content}" if @view_token_type
210
+ [:HEADLINE, [mark_to_level(mark), rest]]
211
+ end
212
+ when /^\s\s+(.*)/ # type == quote
213
+ puts "b: 2 WHITE SPACE(#{@current_type}) : #{@line.content}" if @view_token_type
214
+ case @current_type
215
+ when :itemlist
216
+ if @line.content =~ /^(\s*)(\*)(\s+)(.*)/
217
+ line = $4.strip
218
+ if line.empty?
219
+ @no += 1
220
+ next_token
221
+ else
222
+ if_current_indent_equal(@line.indent) do
223
+ puts "b: ITEMLIST: [#{line}]" if @view_token_type
224
+ @current_type = :itemlist
225
+ [:ITEMLIST, line]
226
+ end
227
+ end
228
+ else
229
+ line = @line.content.strip
230
+ if line.empty?
231
+ @no += 1
232
+ next_token
233
+ else
234
+ puts "b: ITEMLISTCONTINUE: [#{line.empty?}] --" if @view_token_type
235
+ @no += 1
236
+ @current_type = :itemlist
237
+ [:ITEMLISTCONTINUE, line]
238
+ end
239
+ end
240
+ when :numlist
241
+ @line.content =~ /^(\s*)(\(\d+\))(\s+)(.*)/
242
+ if $4.nil?
243
+ @line.content =~ /^(\s*)(\d\.)(\s+)(.*)/
244
+ end
245
+ line = $4
246
+ line ||= @line.content.strip
247
+ if line.empty?
248
+ @no += 1
249
+ next_token
250
+ else
251
+ if_current_indent_equal(@line.indent) do
252
+ puts "b: NUMLIST: [#{line}]" if @view_token_type
253
+ @current_type = :numlist
254
+ [:NUMLIST, line]
255
+ end
256
+ end
257
+ else
258
+ @no += 1
259
+ if @current_type == :descline
260
+ @current_type = :descline
261
+ puts "b: DESCLINE: #{@line.content}" if @view_token_type
262
+ [:DESCLINE, $1 + "\n"]
263
+ else
264
+ @current_type = :quote
265
+ puts "b: QUOTE: #{$1}" if @view_token_type
266
+ [:QUOTE, @line.content.sub(" ","")]
267
+ end
268
+ end
269
+ when /^(\:)(.*)/ # type = desclist
270
+ if_current_indent_equal(@line.indent) do
271
+ @current_type = :descline
272
+ puts "b: DESCLINE_TILTE: #{$2.strip}" if @view_token_type
273
+ [:DESCLINE_TITLE, $2.strip]
274
+ end
275
+ when /^(\s*)(\*)(\s+)(.*)/ # type = itemlist
276
+ if_current_indent_equal(@line.indent) do
277
+ puts "b: ITEMLIST: #{@line.content}" if @view_token_type
278
+ @current_type = :itemlist
279
+ [:ITEMLIST, $4]
280
+ end
281
+ when /^(\s*)(\(\d+\))(\s+)(.*)/
282
+ if_current_indent_equal(@line.indent) do
283
+ puts "b: NUMLIST: #{@line.content}" if @view_token_type
284
+ @current_type = :numlist
285
+ [:NUMLIST, $4]
286
+ end
287
+ when /^(\s*)(\d+\.)(\s+)(.*)/ # type = numlist
288
+ if_current_indent_equal(@line.indent) do
289
+ puts "b: NUMLIST: #{@line.content}" if @view_token_type
290
+ @current_type = :numlist
291
+ [:NUMLIST, $4]
292
+ end
293
+ when /^\|.*/ # type = table
294
+ @no += 1
295
+ @current_type = :table
296
+ lines = @line.content.chomp.split("|")
297
+ lines.shift
298
+ [:TABLELINE, lines]
299
+ when /(.*)/ # type == plain
300
+ @current_type = :plain
301
+ if_current_indent_equal(@line.indent) do
302
+ puts "b: PLAIN: #{@line.content}" if @view_token_type
303
+ [:PLAIN, @line.content]
304
+ end
305
+ else
306
+ puts "raise : #{@line}"
307
+ end
308
+ end
309
+
310
+ def if_current_indent_equal(ident)
311
+ indent_space = 2
312
+ puts "current: #{@current_indent}, line: #{@line.indent}, stack #{@indent_stack.size}:" if @view_token_type
313
+ indent_sabun = @current_indent - @line.indent
314
+ if indent_sabun >= -1 and indent_sabun <= 1
315
+ @no += 1
316
+ yield
317
+ elsif @current_indent < @line.indent
318
+ ((@line.indent - @current_indent) / indent_space).times do
319
+ @indent_stack.push("")
320
+ end
321
+ @current_indent = @line.indent
322
+ puts "b: INDENT" if @view_token_type
323
+ [:INDENT, :INDENT]
324
+ else
325
+ @indent_stack.pop
326
+ @current_indent = @line.indent if @line.indent == @indent_stack.size * indent_space
327
+ puts "b: DEDENT" if @view_token_type
328
+ [:DEDENT, :DEDENT]
329
+ end
330
+ end
331
+
332
+ ---- header
333
+ require "parserutility"
334
+ require "rafinlineparser.tab"
335
+ require "rafelement"
336
+
337
+ module Raf
338
+
339
+ ---- footer
340
+ if __FILE__ == $0
341
+ raf = BlockParser.new
342
+ src = $stdin.readlines
343
+ nodes = raf.parse(src)
344
+ puts "----- index -----"
345
+ raf.index.each do |key,val|
346
+ puts key
347
+ val.each do |v| p v end
348
+ end
349
+ puts "----- info -----"
350
+ p raf.info
351
+ puts "----- output -----"
352
+ nodes.each do |n|
353
+ puts n.apply
354
+ end
355
+ end
356
+ end # end of module Raf