livetext 0.9.26 → 0.9.31

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/README.lt3 +3 -2
  3. data/imports/bookish.rb +1 -1
  4. data/lib/livetext/expansion.rb +108 -0
  5. data/lib/livetext/formatter.rb +223 -0
  6. data/lib/livetext/functions.rb +9 -0
  7. data/lib/livetext/helpers.rb +44 -28
  8. data/lib/livetext/html.rb +73 -0
  9. data/lib/livetext/more.rb +24 -4
  10. data/lib/livetext/parser/general.rb +1 -1
  11. data/lib/livetext/parser/set.rb +10 -3
  12. data/lib/livetext/parser/string.rb +14 -5
  13. data/lib/livetext/processor.rb +5 -0
  14. data/lib/livetext/skeleton.rb +0 -4
  15. data/lib/livetext/standard.rb +78 -63
  16. data/lib/livetext/userapi.rb +52 -19
  17. data/lib/livetext/version.rb +1 -1
  18. data/lib/livetext.rb +1 -2
  19. data/plugin/bookish.rb +1 -1
  20. data/plugin/bootstrap_menu.rb +140 -0
  21. data/plugin/misc/navbar.rb +162 -0
  22. data/test/extra/README.txt +149 -0
  23. data/test/extra/bracketed.rb +121 -0
  24. data/test/extra/bracketed.txt +44 -0
  25. data/test/extra/double.rb +121 -0
  26. data/test/extra/double.txt +44 -0
  27. data/test/extra/functions.rb +148 -0
  28. data/test/extra/functions.txt +58 -0
  29. data/test/extra/single.rb +139 -0
  30. data/test/extra/single.txt +52 -0
  31. data/test/extra/testgen.rb +104 -0
  32. data/test/{snapshots/basic_formatting/actual-error.txt → extra/variables..rb} +0 -0
  33. data/test/extra/variables.rb +94 -0
  34. data/test/extra/variables.txt +35 -0
  35. data/test/snapshots/basic_formatting/expected-output.txt +2 -2
  36. data/test/snapshots/simple_vars/source.lt3 +1 -1
  37. data/test/snapshots/subset.txt +49 -49
  38. data/test/unit/all.rb +1 -3
  39. data/test/unit/parser/general.rb +2 -2
  40. data/test/unit/parser/set.rb +0 -9
  41. metadata +19 -27
  42. data/lib/livetext/formatline.rb +0 -408
  43. data/lib/livetext/funcall.rb +0 -168
  44. data/lib/livetext/lineparser.rb +0 -441
  45. data/test/snapshots/basic_formatting/actual-output.txt +0 -13
  46. data/test/snapshots/basic_formatting/err-sdiff.txt +0 -1
  47. data/test/snapshots/basic_formatting/out-sdiff.txt +0 -14
  48. data/test/snapshots/error_inc_line_num/README.txt +0 -20
  49. data/test/snapshots/error_invalid_name/foo +0 -5
  50. data/test/snapshots/more_functions/actual-error.txt +0 -0
  51. data/test/snapshots/more_functions/actual-output.txt +0 -37
  52. data/test/snapshots/more_functions/err-sdiff.txt +0 -1
  53. data/test/snapshots/more_functions/out-sdiff.txt +0 -38
  54. data/test/snapshots/simple_vars/actual-error.txt +0 -0
  55. data/test/snapshots/simple_vars/actual-output.txt +0 -6
  56. data/test/snapshots/simple_vars/err-sdiff.txt +0 -1
  57. data/test/snapshots/simple_vars/out-sdiff.txt +0 -7
  58. data/test/snapshots/var_into_func/actual-error.txt +0 -0
  59. data/test/snapshots/var_into_func/actual-output.txt +0 -16
  60. data/test/snapshots/var_into_func/err-sdiff.txt +0 -1
  61. data/test/snapshots/var_into_func/out-sdiff.txt +0 -17
  62. data/test/testlines.rb +0 -37
  63. data/test/unit/formatline.rb +0 -638
  64. data/test/unit/lineparser.rb +0 -650
  65. data/test/unit/tokenizer.rb +0 -534
@@ -1,441 +0,0 @@
1
-
2
- require_relative 'parsing'
3
- require_relative 'funcall'
4
-
5
- # Class LineParser handles the parsing of comments, dot commands, and
6
- # simple formatting characters, as well as variables and functions.
7
-
8
- class Livetext::LineParser < StringParser
9
- include Livetext::ParsingConstants
10
- include Livetext::LineParser::FunCall
11
-
12
- FMTS = %w[* _ ~ `]
13
-
14
- attr_reader :out
15
- attr_reader :tokenlist
16
-
17
- def initialize(line)
18
- super
19
- @token = Null.dup
20
- @tokenlist = []
21
- @live = Livetext.new
22
- end
23
-
24
- def self.api
25
- Livetext.new.main.api
26
- end
27
-
28
- def api
29
- @live.main.api
30
- end
31
-
32
- def self.parse!(line)
33
- return nil if line.nil?
34
- line.chomp!
35
- x = self.new(line)
36
- api.tty "\n-- string: #{line.inspect}" if $testme
37
- t = x.tokenize
38
- api.tty "-- Tokens: #{t.inspect}" if $testme
39
- result = x.evaluate
40
- api.tty "-- result: #{result.inspect}" if $testme
41
- result
42
- end
43
-
44
- def parse_formatting
45
- loop do
46
- case peek
47
- when Escape; grab; add peek; grab
48
- when "*", "_", "`", "~"
49
- marker peek
50
- add peek
51
- when LF
52
- break if eos?
53
- when nil
54
- break
55
- else
56
- add peek
57
- end
58
- grab
59
- end
60
- add_token(:str)
61
- @tokenlist
62
- end
63
-
64
- def self.parse_formatting(str)
65
- fmt = self.new(str)
66
- loop do
67
- case fmt.peek
68
- when Escape; fmt.grab; fmt.add fmt.peek; fmt.grab
69
- when "*", "_", "`", "~"
70
- fmt.marker fmt.peek
71
- fmt.add fmt.peek
72
- when LF
73
- break if fmt.eos?
74
- when nil
75
- break
76
- else
77
- fmt.add fmt.peek
78
- end
79
- fmt.grab
80
- end
81
- fmt.add_token(:str)
82
- fmt.tokenlist
83
- end
84
-
85
- def self.parse_variables(str)
86
- return nil if str.nil?
87
- x = self.new(str.chomp)
88
- char = x.peek
89
- loop do
90
- char = x.grab
91
- break if char == LF || char == nil
92
- x.escaped if char == Escape
93
- x.dollar if char == "$" # Could be $$
94
- x.add char
95
- end
96
- x.add_token(:str)
97
- result = x.evaluate
98
- result
99
- end
100
-
101
- def embed(sym, str)
102
- pre, post = SimpleFormats[sym]
103
- pre + str + post
104
- end
105
-
106
- #########
107
-
108
- def handle_simple_formatting(ch)
109
- # api.tty "ch = #{ch.inspect}"
110
- marker ch
111
- add ch
112
- # api.tty "token = #{@token.inspect} #{@tokenlist.inspect}"
113
- c2 = grab
114
- # api.tty "c2 = #{c2.inspect}"
115
- end
116
-
117
- def grab_string
118
- weird = ["$", nil] # [Escape, "$", nil]
119
- ch = grab
120
- add ch # api.tty "-- gs @token = #{@token.inspect}"
121
- loop do
122
- ch = peek # api.tty "gs1 ch = #{ch.inspect}"
123
- break if weird.include?(ch)
124
- break if FMTS.include?(ch) && (self.prev == " ")
125
- break if eos? # ch = grab # advance pointer # api.tty "gs3 ch = #{ch.inspect}"
126
- add grab
127
- end # ch = grab # advance pointer # api.tty "-- gs4 ch = #{ch.inspect}"; sleep 0.01
128
- add_token :str
129
- end
130
-
131
- def grab_token(ch)
132
- finish = false
133
- # api.tty "#{__method__}: ch = #{ch.inspect}"
134
- case ch
135
- when nil; finish = true # do nothing
136
- when LF; finish = true # do nothing - break if eos?
137
- when Escape; ch = self.escaped; add ch
138
- when "$"; dollar
139
- when *FMTS; handle_simple_formatting(ch)
140
- else grab_string
141
- end
142
- # api.tty "#{__method__}: AFTER CASE: api.data = #{api.data.inspect}"
143
- [ch, finish, @token, @tokenlist]
144
- end
145
-
146
- def tokenize
147
- ch = peek
148
- loop do
149
- ch = peek
150
- stuff = grab_token(ch)
151
- ch, finish, t, tlist = *stuff
152
- break if finish
153
- end
154
- # api.tty "tokenize: i = #{self.i}"
155
- # api.tty "tokenize: token = #{@token.inspect} tokenlist = #{@tokenlist.inspect}"
156
- @tokenlist
157
- end
158
-
159
- # def self.get_vars
160
- # grab
161
- # case peek
162
- # when LF, " ", nil
163
- # add "$"
164
- # add_token :str
165
- # when "$"; double_dollar
166
- ## when "."; dollar_dot
167
- # when /[A-Za-z]/
168
- # add_token :str
169
- # var = peek + grab_alpha_dot
170
- # add_token(:var, var)
171
- # else
172
- # add "$" + peek
173
- # add_token(:str)
174
- # end
175
- # end
176
- #
177
- # def self.parse_var_func # FIXME Hmm...
178
- # loop do
179
- # case peek
180
- # when "$"
181
- # dollar
182
- # when LF
183
- # break if eos?
184
- # when nil
185
- # break
186
- # else
187
- # add peek
188
- # end
189
- # grab
190
- # end
191
- # add_token(:str)
192
- # @tokenlist
193
- # end
194
-
195
- def terminate?(terminators, ch)
196
- if terminators.is_a? Regexp
197
- terminators === ch
198
- else
199
- terminators.include?(ch)
200
- end
201
- end
202
-
203
- def var_func_parse
204
- char = self.peek
205
- loop do
206
- char = self.grab
207
- break if char == LF || char == nil
208
- self.escaped if char == Escape
209
- self.dollar if char == "$" # Could be $$
210
- self.add char
211
- end
212
- self.add_token(:str)
213
- result = self.evaluate
214
- result
215
- end
216
-
217
- def self.var_func_parse(str)
218
- return nil if str.nil?
219
- x = self.new(str.chomp)
220
- char = x.peek
221
- loop do
222
- char = x.grab
223
- break if char == LF || char == nil
224
- x.escaped if char == Escape
225
- x.dollar if char == "$" # Could be $$
226
- x.add char
227
- end
228
- x.add_token(:str)
229
- result = x.evaluate
230
- result
231
- end
232
-
233
- def evaluate(tokens = @tokenlist)
234
- @out = ""
235
- return "" if tokens.empty?
236
- gen = tokens.each
237
- token = gen.next
238
- loop do
239
- break if token.nil?
240
- sym, val = *token
241
- case sym
242
- when :str; eval_str(val)
243
- when :var; eval_var(val)
244
- when :func; eval_func(val, gen)
245
- when *BITS; eval_bits(sym, val)
246
- else
247
- add_token :str
248
- end
249
- token = gen.next
250
- end
251
- @out
252
- end
253
-
254
- def add(str)
255
- @token << str unless str.nil?
256
- end
257
-
258
- def add_token(kind, token = @token)
259
- return if token.nil?
260
- @tokenlist << [kind, token] unless token.empty?
261
- @token = Null.dup
262
- end
263
-
264
- def grab_alpha
265
- str = grab
266
- loop do
267
- break if eos?
268
- break if terminate?(NoAlpha, peek)
269
- str << grab
270
- end
271
- str
272
- end
273
-
274
- def grab_alpha_dot
275
- str = grab # Null.dup
276
- loop do
277
- break if eos?
278
- break if terminate?(NoAlphaDot, peek)
279
- str << grab
280
- end
281
- str
282
- end
283
-
284
- def dollar
285
- c1 = grab # $
286
- c2 = grab # ...
287
- case c2
288
- when " "; add_token :str, "$ "
289
- when LF, nil; add_token :str, "$"
290
- when "$"; double_dollar
291
- when "."; dollar_dot
292
- when /[A-Za-z]/; add_token(:var, c2 + grab_alpha_dot)
293
- else add_token(:str, "$" + c2)
294
- end
295
- end
296
-
297
- def finish_token(str, kind)
298
- add str
299
- add_token :str
300
- grab
301
- end
302
-
303
- def marker(char)
304
- add_token :str
305
- sym = Syms[char]
306
- return if embedded?
307
- grab
308
- case peek
309
- when Space; finish_token(char + " ", :str)
310
- when LF, nil; finish_token(char, :str)
311
- when char; double_marker(char)
312
- when LBrack; long_marker(char)
313
- else
314
- str = peek + collect!(sym, Blank)
315
- add str
316
- add_token sym, str
317
- grab
318
- end
319
- end
320
-
321
- def double_marker(char)
322
- sym = Syms[char]
323
- kind = sym
324
- case lookahead # first char after **
325
- when Space, LF, nil
326
- pre, post = SimpleFormats[sym]
327
- add_token kind
328
- else
329
- str = collect!(sym, Punc)
330
- add_token kind, str
331
- grab
332
- end
333
- end
334
-
335
- def long_marker(char)
336
- sym = Syms[char]
337
- grab # skip left bracket
338
- kind = sym # "param_#{sym}".to_sym
339
- arg = collect!(sym, Param, true)
340
- add_token kind, arg
341
- end
342
-
343
- def collect_bracketed(sym, terminators)
344
- str = Null.dup # next is not " ","*","["
345
- grab # ZZZ
346
- loop do
347
- if peek == Escape
348
- grab
349
- str << grab
350
- next
351
- end
352
- if terminate?(terminators, peek)
353
- break
354
- end
355
- str << peek # not a terminator
356
- grab
357
- end
358
-
359
- if peek == "]" # skip right bracket
360
- grab
361
- end
362
- add str
363
- str
364
- rescue => err
365
- ::STDERR.puts "ERR = #{err}\n#{err.backtrace}"
366
- end
367
-
368
- def escaped
369
- grab # Eat the backslash
370
- ch = grab # Take next char
371
- ch
372
- end
373
-
374
- def collect!(sym, terminators, bracketed=nil)
375
- return collect_bracketed(sym, terminators) if bracketed
376
- str = Null.dup # next is not " ","*","["
377
- grab # ZZZ
378
- loop do
379
- case
380
- when peek.nil?
381
- return str
382
- when peek == Escape
383
- str << escaped
384
- next
385
- when terminate?(terminators, peek)
386
- break
387
- else
388
- str << peek # not a terminator
389
- end
390
- grab
391
- end
392
- ungrab
393
- add str
394
- str
395
- rescue => err
396
- ::STDERR.puts "ERR = #{err}\n#{err.backtrace}"
397
- end
398
-
399
- def varsub(name)
400
- live = Livetext.new
401
- value = live.vars[name]
402
- result = value || "[#{name} is undefined]"
403
- result
404
- end
405
-
406
- def embedded?
407
- ! (['"', "'", " ", nil].include? prev)
408
- end
409
-
410
- # private
411
-
412
- def eval_bits(sym, val)
413
- # api.tty "eb: #{[sym, val].inspect}"
414
- val = Livetext.interpolate(val)
415
- @out << embed(sym, val)
416
- end
417
-
418
- def eval_func(val, gen)
419
- param = nil
420
- arg = gen.peek rescue :bogus
421
- unless arg == :bogus
422
- if [:colon, :brackets].include? arg[0]
423
- arg = gen.next # for real
424
- param = arg[1]
425
- # FIXME - unsure - interpolate again??
426
- # param = Livetext.interpolate(param)
427
- end
428
- end
429
- str = funcall(val, param)
430
- @out << str
431
- end
432
-
433
- def eval_var(val)
434
- @out << varsub(val)
435
- end
436
-
437
- def eval_str(val)
438
- @out << val unless val == "\n" # BUG
439
- end
440
-
441
- end
@@ -1,13 +0,0 @@
1
- Here are examples of <b>boldface</b>
2
- and <i>italics</i>
3
- and <font size=+1><tt>code</tt></font>
4
- as well as <b>ore complex</b>*examples
5
- of <i>talicized text</i>
6
- and <font size=+1><tt>ode font</tt></font>
7
- <p>
8
-
9
- Here are some random punctuation marks:
10
- ; # . * * ` ` @ % ^ & $
11
- <p>
12
-
13
- No need to escape these: * * `
@@ -1 +0,0 @@
1
- ACTUAL | EXPECTED
@@ -1,14 +0,0 @@
1
- ACTUAL | EXPECTED
2
- Here are examples of <b>boldface</b> | Here are examples of <b>boldface</b>
3
- and <i>italics</i> and <i>italics</i>
4
- and <font size=+1><tt>code</tt></font> and <font size=+1><tt>code</tt></font>
5
- as well as <b>ore complex</b>*examples | as well as <b>more complex</b> examples
6
- of <i>talicized text</i> | of <i>italicized text</i>
7
- and <font size=+1><tt>ode font</tt></font> | and <font size=+1><tt>code font</tt></font>.
8
- <p> <p>
9
-
10
- Here are some random punctuation marks: Here are some random punctuation marks:
11
- ; # . * * ` ` @ % ^ & $ | ; # . * _ ` : @ % ^ & $
12
- <p> <p>
13
-
14
- No need to escape these: * * ` | No need to escape these: * _ `
@@ -1,20 +0,0 @@
1
- ---- File: source.lt3
2
-
3
- This is my
4
- source file
5
- which includes file2 here:
6
- .include file2.lt3
7
-
8
- And here we are
9
- back in the
10
- original file.
11
-
12
- --- File: file2.lt3
13
-
14
- This is file2
15
- which has an error
16
- about an unknown command
17
- in line 5
18
- .foobar
19
-
20
- And this is file2 line 7.
@@ -1,5 +0,0 @@
1
- T
2
- a
3
- t
4
- <p>
5
-
File without changes
@@ -1,37 +0,0 @@
1
- Testing some more functions here...
2
- <p>
3
-
4
- Here I am calling a function with
5
- a colon parameter...
6
- <p>
7
-
8
- <p>
9
-
10
- Next let's <b>do</b>*something with our parameter:
11
- <p>
12
-
13
- I'll call these variants...
14
- <p>
15
-
16
- "Motel" spelled backwards is letom :)
17
- <p>
18
-
19
- "lamina" reversed is animal
20
- <p>
21
-
22
- I can also use the erutaef tekcarb here.
23
- <p>
24
-
25
- If I don't use a parameter for [Error evaluating $$reverse()] - it gives
26
- me an error. (Bug or feature??)
27
- <p>
28
-
29
- What if a function doesn't use parameters at all, but
30
- we pass them? Hmm...
31
- <p>
32
-
33
- Now we succeed and succeed some more
34
- and finally we succeed in life.
35
- <p>
36
-
37
- But can we succeed, when our beds are burning?
@@ -1 +0,0 @@
1
- ACTUAL | EXPECTED
@@ -1,38 +0,0 @@
1
- ACTUAL | EXPECTED
2
- Testing some more functions here... Testing some more functions here...
3
- <p> <p>
4
-
5
- Here I am calling a function with Here I am calling a function with
6
- a colon parameter... a colon parameter...
7
- <p> <p>
8
-
9
- <p> <p>
10
-
11
- Next let's <b>do</b>*something with our parameter: | Next let's <b>do</b> something with our parameter:
12
- <p> <p>
13
-
14
- I'll call these variants... I'll call these variants...
15
- <p> <p>
16
-
17
- "Motel" spelled backwards is letom :) "Motel" spelled backwards is letom :)
18
- <p> <p>
19
-
20
- "lamina" reversed is animal "lamina" reversed is animal
21
- <p> <p>
22
-
23
- I can also use the erutaef tekcarb here. I can also use the erutaef tekcarb here.
24
- <p> <p>
25
-
26
- If I don't use a parameter for [Error evaluating $$reverse( If I don't use a parameter for [Error evaluating $$reverse(
27
- me an error. (Bug or feature??) me an error. (Bug or feature??)
28
- <p> <p>
29
-
30
- What if a function doesn't use parameters at all, but What if a function doesn't use parameters at all, but
31
- we pass them? Hmm... we pass them? Hmm...
32
- <p> <p>
33
-
34
- Now we succeed and succeed some more Now we succeed and succeed some more
35
- and finally we succeed in life. and finally we succeed in life.
36
- <p> <p>
37
-
38
- But can we succeed, when our beds are burning? But can we succeed, when our beds are burning?
File without changes
@@ -1,6 +0,0 @@
1
- Just
2
- some text.
3
- Hi, there.
4
- GulliverFoyle is my name, and Terra is my nation.
5
- I'm GulliverFoyle, from Terra
6
- That's all.
@@ -1 +0,0 @@
1
- ACTUAL | EXPECTED
@@ -1,7 +0,0 @@
1
- ACTUAL | EXPECTED
2
- Just Just
3
- some text. some text.
4
- Hi, there. Hi, there.
5
- GulliverFoyle is my name, and Terra is my nation. GulliverFoyle is my name, and Terra is my nation.
6
- I'm GulliverFoyle, from Terra | I'm GulliverFoyle, from Terra.
7
- That's all. That's all.
File without changes
@@ -1,16 +0,0 @@
1
- <p>
2
-
3
- Testing STILL more functions here...
4
- <p>
5
-
6
- <p>
7
-
8
- Now... let's try passing a variable to a function. Will this work??
9
- <p>
10
-
11
- Variable \regal is regal, which reversed is ahpla$
12
- <p>
13
-
14
- That's all.
15
- <p>
16
-
@@ -1 +0,0 @@
1
- ACTUAL | EXPECTED
@@ -1,17 +0,0 @@
1
- ACTUAL | EXPECTED
2
- <p> <p>
3
-
4
- Testing STILL more functions here... Testing STILL more functions here...
5
- <p> <p>
6
-
7
- <p> <p>
8
-
9
- Now... let's try passing a variable to a function. Will thi Now... let's try passing a variable to a function. Will thi
10
- <p> <p>
11
-
12
- Variable \regal is regal, which reversed is ahpla$ | Variable $alpha is regal, which reversed is lager
13
- <p> <p>
14
-
15
- That's all. That's all.
16
- <p> <p>
17
-
data/test/testlines.rb DELETED
@@ -1,37 +0,0 @@
1
- require '../lib/livetext'
2
- require '../lib/formatline'
3
-
4
- def red(str)
5
- "" + str + ""
6
- end
7
-
8
- input = ARGV.first || "test/data/lines.txt"
9
- data = File.readlines(input)
10
-
11
- pass = fail = 0
12
- data.each_slice(4).with_index do |lines, i|
13
- title, input, expected, blank = *lines
14
- lnum = i*4 + 1
15
- input.chomp!
16
- expected.chomp!
17
- expected = eval(expected) if expected[0] == "/"
18
-
19
-
20
- actual = FormatLine.parse!(input)
21
- if expected === actual
22
- pass += 1
23
- # puts "PASS: #{title}"
24
- next
25
- end
26
-
27
- fail += 1
28
- puts "----------------------------- (line #{lnum})"
29
- puts "Test: #{title}"
30
- puts "Input: #{input}"
31
- puts " #{red('FAIL Expected: ')} #{expected.inspect}"
32
- puts " #{red(' Actual : ')} #{actual.inspect}"
33
- puts
34
- end
35
-
36
- puts
37
- puts "#{pass} passes #{fail} fails"