hemingway 0.0.0 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/.travis.yml +4 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +297 -0
  7. data/Rakefile +1 -0
  8. data/hemingway.gemspec +23 -0
  9. data/lib/hemingway/block/block.rb +378 -0
  10. data/lib/hemingway/block/block.treetop +36 -0
  11. data/lib/hemingway/block/block_nodes.rb +9 -0
  12. data/lib/hemingway/block/list/list.rb +412 -0
  13. data/lib/hemingway/block/list/list.treetop +51 -0
  14. data/lib/hemingway/block/list/list_nodes.rb +39 -0
  15. data/lib/hemingway/block/quote/quote.rb +192 -0
  16. data/lib/hemingway/block/quote/quote.treetop +27 -0
  17. data/lib/hemingway/block/quote/quote_nodes.rb +25 -0
  18. data/lib/hemingway/block/verbatim/verbatim.rb +159 -0
  19. data/lib/hemingway/block/verbatim/verbatim.treetop +21 -0
  20. data/lib/hemingway/block/verbatim/verbatim_nodes.rb +9 -0
  21. data/lib/hemingway/build.rb +65 -0
  22. data/lib/hemingway/footnote/footnote.rb +83 -0
  23. data/lib/hemingway/footnote/footnote.treetop +11 -0
  24. data/lib/hemingway/footnote/footnote_nodes.rb +21 -0
  25. data/lib/hemingway/latex.rb +409 -0
  26. data/lib/hemingway/latex.treetop +81 -0
  27. data/lib/hemingway/latex_nodes.rb +45 -0
  28. data/lib/hemingway/math/math.rb +135 -0
  29. data/lib/hemingway/math/math.treetop +29 -0
  30. data/lib/hemingway/math/math_nodes.rb +7 -0
  31. data/lib/hemingway/special/special.rb +164 -0
  32. data/lib/hemingway/special/special.treetop +17 -0
  33. data/lib/hemingway/special/special_nodes.rb +7 -0
  34. data/lib/hemingway/symbol/symbol.rb +460 -0
  35. data/lib/hemingway/symbol/symbol.treetop +47 -0
  36. data/lib/hemingway/symbol/symbol_nodes.rb +7 -0
  37. data/lib/hemingway/tag/tag.rb +538 -0
  38. data/lib/hemingway/tag/tag.treetop +63 -0
  39. data/lib/hemingway/tag/tag_nodes.rb +49 -0
  40. data/lib/hemingway/text/text.rb +121 -0
  41. data/lib/hemingway/text/text.treetop +35 -0
  42. data/lib/hemingway/text/text_nodes.rb +7 -0
  43. data/lib/hemingway/version.rb +3 -0
  44. data/lib/hemingway.rb +7 -0
  45. data/script/build +22 -0
  46. data/script/test +2 -0
  47. data/spec/build_spec.rb +65 -0
  48. data/spec/nodes/block/list_spec.rb +91 -0
  49. data/spec/nodes/block/quote_spec.rb +31 -0
  50. data/spec/nodes/block/verbatim_spec.rb +27 -0
  51. data/spec/nodes/block_spec.rb +21 -0
  52. data/spec/nodes/footnote_spec.rb +42 -0
  53. data/spec/nodes/math_spec.rb +31 -0
  54. data/spec/nodes/special_spec.rb +27 -0
  55. data/spec/nodes/tag_spec.rb +98 -0
  56. data/spec/parser_spec.rb +48 -0
  57. data/spec/spec_helper.rb +5 -0
  58. metadata +110 -18
@@ -0,0 +1,409 @@
1
+ # Autogenerated from a Treetop grammar. Edits may be lost.
2
+
3
+
4
+ require 'hemingway/build'
5
+ require 'hemingway/latex_nodes'
6
+ require "hemingway/block/block"
7
+ require "hemingway/footnote/footnote"
8
+ require "hemingway/math/math"
9
+ require "hemingway/special/special"
10
+ require "hemingway/symbol/symbol"
11
+ require "hemingway/tag/tag"
12
+ require "hemingway/text/text"
13
+
14
+ module Hemingway
15
+ module Latex
16
+ include Treetop::Runtime
17
+
18
+ def root
19
+ @root ||= :document
20
+ end
21
+
22
+ include Block
23
+
24
+ include Footnote
25
+
26
+ include Math
27
+
28
+ include Special
29
+
30
+ include Symbol
31
+
32
+ include Tag
33
+
34
+ include Text
35
+
36
+ def _nt_document
37
+ start_index = index
38
+ if node_cache[:document].has_key?(index)
39
+ cached = node_cache[:document][index]
40
+ if cached
41
+ cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
42
+ @index = cached.interval.end
43
+ end
44
+ return cached
45
+ end
46
+
47
+ r0 = _nt_entry
48
+
49
+ node_cache[:document][start_index] = r0
50
+
51
+ r0
52
+ end
53
+
54
+ def _nt_entry
55
+ start_index = index
56
+ if node_cache[:entry].has_key?(index)
57
+ cached = node_cache[:entry][index]
58
+ if cached
59
+ cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
60
+ @index = cached.interval.end
61
+ end
62
+ return cached
63
+ end
64
+
65
+ s0, i0 = [], index
66
+ loop do
67
+ i1 = index
68
+ r2 = _nt_paragraph
69
+ if r2
70
+ r1 = r2
71
+ else
72
+ r3 = _nt_last_paragraph
73
+ if r3
74
+ r1 = r3
75
+ else
76
+ @index = i1
77
+ r1 = nil
78
+ end
79
+ end
80
+ if r1
81
+ s0 << r1
82
+ else
83
+ break
84
+ end
85
+ end
86
+ r0 = instantiate_node(EntryNode,input, i0...index, s0)
87
+
88
+ node_cache[:entry][start_index] = r0
89
+
90
+ r0
91
+ end
92
+
93
+ module Paragraph0
94
+ def sequence
95
+ elements[0]
96
+ end
97
+
98
+ def eop
99
+ elements[1]
100
+ end
101
+ end
102
+
103
+ def _nt_paragraph
104
+ start_index = index
105
+ if node_cache[:paragraph].has_key?(index)
106
+ cached = node_cache[:paragraph][index]
107
+ if cached
108
+ cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
109
+ @index = cached.interval.end
110
+ end
111
+ return cached
112
+ end
113
+
114
+ i0, s0 = index, []
115
+ s1, i1 = [], index
116
+ loop do
117
+ i2 = index
118
+ r3 = _nt_content
119
+ if r3
120
+ r2 = r3
121
+ else
122
+ r4 = _nt_footnote
123
+ if r4
124
+ r2 = r4
125
+ else
126
+ @index = i2
127
+ r2 = nil
128
+ end
129
+ end
130
+ if r2
131
+ s1 << r2
132
+ else
133
+ break
134
+ end
135
+ end
136
+ r1 = instantiate_node(SyntaxNode,input, i1...index, s1)
137
+ s0 << r1
138
+ if r1
139
+ r5 = _nt_eop
140
+ s0 << r5
141
+ end
142
+ if s0.last
143
+ r0 = instantiate_node(ParagraphNode,input, i0...index, s0)
144
+ r0.extend(Paragraph0)
145
+ else
146
+ @index = i0
147
+ r0 = nil
148
+ end
149
+
150
+ node_cache[:paragraph][start_index] = r0
151
+
152
+ r0
153
+ end
154
+
155
+ module LastParagraph0
156
+ def sequence
157
+ elements[0]
158
+ end
159
+
160
+ end
161
+
162
+ def _nt_last_paragraph
163
+ start_index = index
164
+ if node_cache[:last_paragraph].has_key?(index)
165
+ cached = node_cache[:last_paragraph][index]
166
+ if cached
167
+ cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
168
+ @index = cached.interval.end
169
+ end
170
+ return cached
171
+ end
172
+
173
+ i0, s0 = index, []
174
+ s1, i1 = [], index
175
+ loop do
176
+ i2 = index
177
+ r3 = _nt_content
178
+ if r3
179
+ r2 = r3
180
+ else
181
+ r4 = _nt_footnote
182
+ if r4
183
+ r2 = r4
184
+ else
185
+ @index = i2
186
+ r2 = nil
187
+ end
188
+ end
189
+ if r2
190
+ s1 << r2
191
+ else
192
+ break
193
+ end
194
+ end
195
+ if s1.empty?
196
+ @index = i1
197
+ r1 = nil
198
+ else
199
+ r1 = instantiate_node(SyntaxNode,input, i1...index, s1)
200
+ end
201
+ s0 << r1
202
+ if r1
203
+ r6 = _nt_eop
204
+ if r6
205
+ r5 = r6
206
+ else
207
+ r5 = instantiate_node(SyntaxNode,input, index...index)
208
+ end
209
+ s0 << r5
210
+ end
211
+ if s0.last
212
+ r0 = instantiate_node(ParagraphNode,input, i0...index, s0)
213
+ r0.extend(LastParagraph0)
214
+ else
215
+ @index = i0
216
+ r0 = nil
217
+ end
218
+
219
+ node_cache[:last_paragraph][start_index] = r0
220
+
221
+ r0
222
+ end
223
+
224
+ def _nt_content
225
+ start_index = index
226
+ if node_cache[:content].has_key?(index)
227
+ cached = node_cache[:content][index]
228
+ if cached
229
+ cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
230
+ @index = cached.interval.end
231
+ end
232
+ return cached
233
+ end
234
+
235
+ i0 = index
236
+ r1 = _nt_special
237
+ if r1
238
+ r0 = r1
239
+ else
240
+ r2 = _nt_tag
241
+ if r2
242
+ r0 = r2
243
+ else
244
+ r3 = _nt_block
245
+ if r3
246
+ r0 = r3
247
+ else
248
+ r4 = _nt_math
249
+ if r4
250
+ r0 = r4
251
+ else
252
+ r5 = _nt_text
253
+ if r5
254
+ r0 = r5
255
+ else
256
+ @index = i0
257
+ r0 = nil
258
+ end
259
+ end
260
+ end
261
+ end
262
+ end
263
+
264
+ node_cache[:content][start_index] = r0
265
+
266
+ r0
267
+ end
268
+
269
+ def _nt_whitespace
270
+ start_index = index
271
+ if node_cache[:whitespace].has_key?(index)
272
+ cached = node_cache[:whitespace][index]
273
+ if cached
274
+ cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
275
+ @index = cached.interval.end
276
+ end
277
+ return cached
278
+ end
279
+
280
+ s0, i0 = [], index
281
+ loop do
282
+ i1 = index
283
+ if has_terminal?(" ", false, index)
284
+ r2 = instantiate_node(SyntaxNode,input, index...(index + 1))
285
+ @index += 1
286
+ else
287
+ terminal_parse_failure(" ")
288
+ r2 = nil
289
+ end
290
+ if r2
291
+ r1 = r2
292
+ else
293
+ r3 = _nt_newline
294
+ if r3
295
+ r1 = r3
296
+ else
297
+ @index = i1
298
+ r1 = nil
299
+ end
300
+ end
301
+ if r1
302
+ s0 << r1
303
+ else
304
+ break
305
+ end
306
+ end
307
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
308
+
309
+ node_cache[:whitespace][start_index] = r0
310
+
311
+ r0
312
+ end
313
+
314
+ def _nt_spaces
315
+ start_index = index
316
+ if node_cache[:spaces].has_key?(index)
317
+ cached = node_cache[:spaces][index]
318
+ if cached
319
+ cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
320
+ @index = cached.interval.end
321
+ end
322
+ return cached
323
+ end
324
+
325
+ s0, i0 = [], index
326
+ loop do
327
+ if has_terminal?(" ", false, index)
328
+ r1 = instantiate_node(SyntaxNode,input, index...(index + 1))
329
+ @index += 1
330
+ else
331
+ terminal_parse_failure(" ")
332
+ r1 = nil
333
+ end
334
+ if r1
335
+ s0 << r1
336
+ else
337
+ break
338
+ end
339
+ end
340
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
341
+
342
+ node_cache[:spaces][start_index] = r0
343
+
344
+ r0
345
+ end
346
+
347
+ def _nt_eop
348
+ start_index = index
349
+ if node_cache[:eop].has_key?(index)
350
+ cached = node_cache[:eop][index]
351
+ if cached
352
+ cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
353
+ @index = cached.interval.end
354
+ end
355
+ return cached
356
+ end
357
+
358
+ s0, i0 = [], index
359
+ loop do
360
+ r1 = _nt_newline
361
+ if r1
362
+ s0 << r1
363
+ else
364
+ break
365
+ end
366
+ end
367
+ if s0.size < 2
368
+ @index = i0
369
+ r0 = nil
370
+ else
371
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
372
+ end
373
+
374
+ node_cache[:eop][start_index] = r0
375
+
376
+ r0
377
+ end
378
+
379
+ def _nt_newline
380
+ start_index = index
381
+ if node_cache[:newline].has_key?(index)
382
+ cached = node_cache[:newline][index]
383
+ if cached
384
+ cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
385
+ @index = cached.interval.end
386
+ end
387
+ return cached
388
+ end
389
+
390
+ if has_terminal?("\n", false, index)
391
+ r0 = instantiate_node(SyntaxNode,input, index...(index + 1))
392
+ @index += 1
393
+ else
394
+ terminal_parse_failure("\n")
395
+ r0 = nil
396
+ end
397
+
398
+ node_cache[:newline][start_index] = r0
399
+
400
+ r0
401
+ end
402
+
403
+ end
404
+
405
+ class LatexParser < Treetop::Runtime::CompiledParser
406
+ include Latex
407
+ end
408
+
409
+ end
@@ -0,0 +1,81 @@
1
+ require 'hemingway/build'
2
+ require 'hemingway/latex_nodes'
3
+ require "hemingway/block/block"
4
+ require "hemingway/footnote/footnote"
5
+ require "hemingway/math/math"
6
+ require "hemingway/special/special"
7
+ require "hemingway/symbol/symbol"
8
+ require "hemingway/tag/tag"
9
+ require "hemingway/text/text"
10
+
11
+ module Hemingway
12
+ grammar Latex
13
+
14
+ include Block
15
+ include Footnote
16
+ include Math
17
+ include Special
18
+ include Symbol
19
+ include Tag
20
+ include Text
21
+
22
+ rule document
23
+ entry
24
+ end
25
+
26
+ rule entry
27
+ ( paragraph / last_paragraph )* <EntryNode>
28
+ end
29
+
30
+ # Example: These aren't the \n\n droids you're looking for \n\n.
31
+ # Notes:
32
+ # - Okay so this is interesting. When you reference something with a * or
33
+ # a +, then you're creating a top level array-like structure that you'll
34
+ # have to dig past to get at the list. elements[0] refers to the array of
35
+ # tags or texts here.
36
+ rule paragraph
37
+ sequence:( content / footnote )* eop <ParagraphNode>
38
+ end
39
+
40
+ # The last paragraph in an entry need not end with \n\n. Because this
41
+ # comes second in the ordered choice for entry, it will only be used
42
+ # if a paragraph has concluded for some reason and there wasn't an eop
43
+ # to consume. The only time I can imagine this happening would be at
44
+ # the end of an entry.
45
+ rule last_paragraph
46
+ sequence:( content / footnote )+ eop? <ParagraphNode>
47
+ end
48
+
49
+ # Example: \tag{text} or just text or $\Delta$
50
+ # Notes:
51
+ # - So I can define methods based on the ordered choice in the top
52
+ # level of this rule. Text is already its own thing though, so an html
53
+ # method need not be defined on it because alas, it already exists as
54
+ # defined in the text rule itself!
55
+ rule content
56
+ special / tag / block / math / text
57
+ end
58
+
59
+ # Treetop does not separate lexing from parsing. Must consume all input.
60
+ rule whitespace
61
+ ( " " / newline )*
62
+ end
63
+
64
+ rule spaces
65
+ ( " " )*
66
+ end
67
+
68
+ # End of paragraph. Originally this had a choice for EOF, but I can't
69
+ # seem to find a good way for Treetop to process that. My workaround
70
+ # strategy will be to append some newlines onto the end of the input
71
+ # string.
72
+ rule eop
73
+ newline 2..
74
+ end
75
+
76
+ rule newline
77
+ "\n"
78
+ end
79
+
80
+ end
81
+ end
@@ -0,0 +1,45 @@
1
+ module Hemingway
2
+
3
+ module EntryNode
4
+ def html
5
+ footnote_content = []
6
+ paragraph_html = ""
7
+
8
+ elements.each do |e|
9
+ paragraph_html += e.html(footnote_content.size)
10
+ footnote_content += e.footnote_html(footnote_content.size)
11
+ end
12
+
13
+ footnote_html = footnote_content.join
14
+
15
+ Build.tag("div", paragraph_html + footnote_html, :class => "entry")
16
+ end
17
+ end
18
+
19
+ module ParagraphNode
20
+ def html(footnote_seed)
21
+ paragraph_content = sequence.elements.map do |element|
22
+ if element.respond_to?(:footnote_html)
23
+ footnote_seed += 1
24
+ element.html(footnote_seed)
25
+ else
26
+ element.html
27
+ end
28
+ end.join
29
+
30
+ Build.tag("p", paragraph_content)
31
+ end
32
+
33
+ def footnote_html(footnote_seed)
34
+ footnote_content = sequence.elements.reduce([]) do |memo, element|
35
+ if element.respond_to?(:footnote_html)
36
+ footnote_seed += 1
37
+ memo + [element.footnote_html(footnote_seed)]
38
+ else
39
+ memo
40
+ end
41
+ end
42
+ end
43
+
44
+ end
45
+ end
@@ -0,0 +1,135 @@
1
+ # Autogenerated from a Treetop grammar. Edits may be lost.
2
+
3
+
4
+ require "hemingway/math/math_nodes"
5
+
6
+ module Hemingway
7
+ module Math
8
+ include Treetop::Runtime
9
+
10
+ def root
11
+ @root ||= :math
12
+ end
13
+
14
+ module Math0
15
+ def math_start
16
+ elements[0]
17
+ end
18
+
19
+ def symbol
20
+ elements[1]
21
+ end
22
+
23
+ def math_end
24
+ elements[2]
25
+ end
26
+ end
27
+
28
+ def _nt_math
29
+ start_index = index
30
+ if node_cache[:math].has_key?(index)
31
+ cached = node_cache[:math][index]
32
+ if cached
33
+ cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
34
+ @index = cached.interval.end
35
+ end
36
+ return cached
37
+ end
38
+
39
+ i0, s0 = index, []
40
+ r1 = _nt_math_start
41
+ s0 << r1
42
+ if r1
43
+ r2 = _nt_symbol
44
+ s0 << r2
45
+ if r2
46
+ r3 = _nt_math_end
47
+ s0 << r3
48
+ end
49
+ end
50
+ if s0.last
51
+ r0 = instantiate_node(MathNode,input, i0...index, s0)
52
+ r0.extend(Math0)
53
+ else
54
+ @index = i0
55
+ r0 = nil
56
+ end
57
+
58
+ node_cache[:math][start_index] = r0
59
+
60
+ r0
61
+ end
62
+
63
+ def _nt_symbol
64
+ start_index = index
65
+ if node_cache[:symbol].has_key?(index)
66
+ cached = node_cache[:symbol][index]
67
+ if cached
68
+ cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
69
+ @index = cached.interval.end
70
+ end
71
+ return cached
72
+ end
73
+
74
+ r0 = _nt_math_symbol
75
+
76
+ node_cache[:symbol][start_index] = r0
77
+
78
+ r0
79
+ end
80
+
81
+ def _nt_math_start
82
+ start_index = index
83
+ if node_cache[:math_start].has_key?(index)
84
+ cached = node_cache[:math_start][index]
85
+ if cached
86
+ cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
87
+ @index = cached.interval.end
88
+ end
89
+ return cached
90
+ end
91
+
92
+ if has_terminal?("$", false, index)
93
+ r0 = instantiate_node(SyntaxNode,input, index...(index + 1))
94
+ @index += 1
95
+ else
96
+ terminal_parse_failure("$")
97
+ r0 = nil
98
+ end
99
+
100
+ node_cache[:math_start][start_index] = r0
101
+
102
+ r0
103
+ end
104
+
105
+ def _nt_math_end
106
+ start_index = index
107
+ if node_cache[:math_end].has_key?(index)
108
+ cached = node_cache[:math_end][index]
109
+ if cached
110
+ cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
111
+ @index = cached.interval.end
112
+ end
113
+ return cached
114
+ end
115
+
116
+ if has_terminal?("$", false, index)
117
+ r0 = instantiate_node(SyntaxNode,input, index...(index + 1))
118
+ @index += 1
119
+ else
120
+ terminal_parse_failure("$")
121
+ r0 = nil
122
+ end
123
+
124
+ node_cache[:math_end][start_index] = r0
125
+
126
+ r0
127
+ end
128
+
129
+ end
130
+
131
+ class MathParser < Treetop::Runtime::CompiledParser
132
+ include Math
133
+ end
134
+
135
+ end
@@ -0,0 +1,29 @@
1
+ require "hemingway/math/math_nodes"
2
+
3
+ module Hemingway
4
+ grammar Math
5
+
6
+ # Example: $ \Pi = 3.14159 $
7
+ rule math
8
+ math_start symbol math_end <MathNode>
9
+ end
10
+
11
+ # Example : \Pi
12
+ # Notes:
13
+ # - Once again, math_symbol need not have an html method defined on it.
14
+ # When .html is called on symbol, it knows the match is actually a
15
+ # math_symbol, so that is what symbol.html is actually calling.
16
+ rule symbol
17
+ math_symbol
18
+ end
19
+
20
+ rule math_start
21
+ "$"
22
+ end
23
+
24
+ rule math_end
25
+ "$"
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,7 @@
1
+ module Hemingway
2
+ module MathNode
3
+ def html
4
+ symbol.html
5
+ end
6
+ end
7
+ end