hemingway 0.0.0 → 0.0.2

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.
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