livetext 0.9.52 → 0.9.56

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 (74) hide show
  1. checksums.yaml +4 -4
  2. data/imports/bookish.rb +3 -3
  3. data/lib/livetext/ast/show_ast_clean.rb +10 -0
  4. data/lib/livetext/ast/show_ast_result.rb +60 -0
  5. data/lib/livetext/ast/show_raw_arrays.rb +13 -0
  6. data/lib/livetext/ast.rb +464 -0
  7. data/lib/livetext/ast_to_html.rb +32 -0
  8. data/lib/livetext/core.rb +110 -53
  9. data/lib/livetext/errors.rb +1 -0
  10. data/lib/livetext/expansion.rb +21 -21
  11. data/lib/livetext/formatter.rb +70 -200
  12. data/lib/livetext/formatter_component.rb +189 -0
  13. data/lib/livetext/function_registry.rb +163 -0
  14. data/lib/livetext/functions.rb +26 -0
  15. data/lib/livetext/handler/mixin.rb +53 -0
  16. data/lib/livetext/helpers.rb +33 -16
  17. data/lib/livetext/reopen.rb +2 -0
  18. data/lib/livetext/skeleton.rb +0 -3
  19. data/lib/livetext/standard.rb +120 -72
  20. data/lib/livetext/userapi.rb +20 -1
  21. data/lib/livetext/variable_manager.rb +78 -0
  22. data/lib/livetext/variables.rb +9 -1
  23. data/lib/livetext/version.rb +1 -1
  24. data/lib/livetext.rb +9 -3
  25. data/plugin/booktool.rb +14 -14
  26. data/plugin/lt3scriptor.rb +914 -0
  27. data/plugin/mixin_functions_class.rb +33 -0
  28. data/test/snapshots/complex_body/expected-error.txt +0 -0
  29. data/test/snapshots/complex_body/expected-output.txt +8 -0
  30. data/test/snapshots/complex_body/source.lt3 +19 -0
  31. data/test/snapshots/debug_command/expected-error.txt +0 -0
  32. data/test/snapshots/debug_command/expected-output.txt +1 -0
  33. data/test/snapshots/debug_command/source.lt3 +3 -0
  34. data/test/snapshots/def_parameters/expected-error.txt +0 -0
  35. data/test/snapshots/def_parameters/expected-output.txt +21 -0
  36. data/test/snapshots/def_parameters/source.lt3 +44 -0
  37. data/test/snapshots/error_missing_end/match-error.txt +1 -1
  38. data/test/snapshots/functions_reflection/expected-error.txt +0 -0
  39. data/test/snapshots/functions_reflection/expected-output.txt +27 -0
  40. data/test/snapshots/functions_reflection/source.lt3 +5 -0
  41. data/test/snapshots/mixin_functions_class/expected-error.txt +0 -0
  42. data/test/snapshots/mixin_functions_class/expected-output.txt +20 -0
  43. data/test/snapshots/mixin_functions_class/mixin_functions_class.rb +33 -0
  44. data/test/snapshots/mixin_functions_class/source.lt3 +17 -0
  45. data/test/snapshots/multiple_functions/expected-error.txt +0 -0
  46. data/test/snapshots/multiple_functions/expected-output.txt +5 -0
  47. data/test/snapshots/multiple_functions/source.lt3 +16 -0
  48. data/test/snapshots/nested_includes/expected-error.txt +0 -0
  49. data/test/snapshots/nested_includes/expected-output.txt +68 -0
  50. data/test/snapshots/nested_includes/level2.inc +34 -0
  51. data/test/snapshots/nested_includes/level3.inc +20 -0
  52. data/test/snapshots/nested_includes/source.lt3 +49 -0
  53. data/test/snapshots/parameter_handling/expected-error.txt +0 -0
  54. data/test/snapshots/parameter_handling/expected-output.txt +7 -0
  55. data/test/snapshots/parameter_handling/source.lt3 +10 -0
  56. data/test/snapshots/subset.txt +1 -0
  57. data/test/snapshots/system_info/expected-error.txt +0 -0
  58. data/test/snapshots/system_info/match-output.txt +18 -0
  59. data/test/snapshots/system_info/source.lt3 +16 -0
  60. data/test/unit/all.rb +7 -0
  61. data/test/unit/ast.rb +90 -0
  62. data/test/unit/ast_directives.rb +104 -0
  63. data/test/unit/ast_variables.rb +71 -0
  64. data/test/unit/core_methods.rb +317 -0
  65. data/test/unit/formatter.rb +84 -0
  66. data/test/unit/formatter_component.rb +84 -0
  67. data/test/unit/function_registry.rb +132 -0
  68. data/test/unit/mixin_functions_class.rb +131 -0
  69. data/test/unit/stringparser.rb +14 -32
  70. data/test/unit/variable_manager.rb +71 -0
  71. metadata +51 -5
  72. data/imports/markdown.rb +0 -44
  73. data/lib/livetext/processor.rb +0 -88
  74. data/plugin/markdown.rb +0 -43
@@ -41,55 +41,88 @@ module Livetext::Standard
41
41
  # end
42
42
  # end
43
43
 
44
- def backtrace(args = nil, body = nil)
44
+ def backtrace(args, data)
45
45
  @backtrace = onoff(api.args.first)
46
46
  api.optional_blank_line
47
47
  end
48
48
 
49
- def comment(args = nil, body = nil)
50
- api.body
49
+ def comment(args, data, body)
50
+ # body parameter contains the processed lines
51
51
  api.optional_blank_line
52
52
  end
53
53
 
54
- def shell(args = nil, body = nil)
54
+ def shell(args, data)
55
55
  cmd = api.data
56
56
  system(cmd)
57
57
  api.optional_blank_line
58
58
  end
59
59
 
60
- def func(args = nil, body = nil)
60
+ def func(args, data, body)
61
61
  funcname = api.args[0]
62
62
  # check_disallowed(funcname) # should any be invalid?
63
63
  funcname = funcname.gsub(/\./, "__")
64
+ function_body = body.join("\n")
64
65
  func_def = <<~EOS
65
66
  def #{funcname}(param)
66
- #{api.body(true).to_a.join("\n")}
67
+ #{function_body}
67
68
  end
68
69
  EOS
69
70
  api.optional_blank_line
71
+
72
+ # Register in old system (this works perfectly)
70
73
  Livetext::Functions.class_eval func_def
74
+
75
+ # Also register in new registry with proper delegation
76
+ function = ->(param) do
77
+ fobj = ::Livetext::Functions.new
78
+ fobj.send(funcname, param)
79
+ end
80
+
81
+ function_registry.register_user(funcname, function, source: :inline, filename: @current_file)
82
+ return true
83
+ end
84
+
85
+ def functions(args, data)
86
+ # List all available functions with their sources
87
+ registry = function_registry
88
+ functions = registry.list_functions
89
+
90
+ if functions.empty?
91
+ api.out "No functions available."
92
+ return true
93
+ end
94
+
95
+ api.out "<h3>Available Functions</h3>"
96
+ api.out "<ul>"
97
+
98
+ functions.each do |func|
99
+ api.out "<li><strong>$$#{func[:name]}</strong> - #{func[:source]}</li>"
100
+ end
101
+
102
+ api.out "</ul>"
103
+ api.optional_blank_line
71
104
  return true
72
105
  end
73
106
 
74
107
  # FIXME - move these to a single universal place in code
75
108
 
76
- def h1(args = nil, body = nil); api.out html.tag(:h1, cdata: api.data); return true; end
77
- def h2(args = nil, body = nil); api.out html.tag(:h2, cdata: api.data); return true; end
78
- def h3(args = nil, body = nil); api.out html.tag(:h3, cdata: api.data); return true; end
79
- def h4(args = nil, body = nil); api.out html.tag(:h4, cdata: api.data); return true; end
80
- def h5(args = nil, body = nil); api.out html.tag(:h5, cdata: api.data); return true; end
81
- def h6(args = nil, body = nil); api.out html.tag(:h6, cdata: api.data); return true; end
109
+ def h1(args, data); api.out html.tag(:h1, cdata: api.format(api.data)); return true; end
110
+ def h2(args, data); api.out html.tag(:h2, cdata: api.data); return true; end
111
+ def h3(args, data); api.out html.tag(:h3, cdata: api.data); return true; end
112
+ def h4(args, data); api.out html.tag(:h4, cdata: api.data); return true; end
113
+ def h5(args, data); api.out html.tag(:h5, cdata: api.data); return true; end
114
+ def h6(args, data); api.out html.tag(:h6, cdata: api.data); return true; end
82
115
 
83
- def list(args = nil, body = nil)
116
+ def list(args, data, body)
84
117
  html.wrap :ul do
85
- api.body {|line| api.out html.tag(:li, cdata: line) }
118
+ body.each {|line| api.out html.tag(:li, cdata: line) }
86
119
  end
87
120
  api.optional_blank_line
88
121
  end
89
122
 
90
- def list!(args = nil, body = nil)
123
+ def list!(args, data, body)
91
124
  html.wrap(:ul) do
92
- lines = api.body.each # enumerator
125
+ lines = body.each # enumerator
93
126
  loop do
94
127
  line = lines.next
95
128
  line = api.format(line)
@@ -100,30 +133,30 @@ module Livetext::Standard
100
133
  api.optional_blank_line
101
134
  end
102
135
 
103
- def shell!(args = nil, body = nil)
136
+ def shell!(args, data)
104
137
  cmd = api.data
105
138
  system(cmd)
106
139
  api.optional_blank_line
107
140
  end
108
141
 
109
- def errout(args = nil, body = nil)
142
+ def errout(args, data)
110
143
  ::STDERR.puts api.data
111
144
  api.optional_blank_line
112
145
  end
113
146
 
114
- def ttyout(args = nil, body = nil)
147
+ def ttyout(args, data)
115
148
  TTY.puts api.data
116
149
  api.optional_blank_line
117
150
  end
118
151
 
119
- def say(args = nil, body = nil)
152
+ def say(args, data)
120
153
  data = args || api.args.join(" ")
121
154
  str = api.format(data)
122
155
  TTY.puts str
123
156
  api.optional_blank_line
124
157
  end
125
158
 
126
- def banner(args = nil, body = nil)
159
+ def banner(args, data)
127
160
  str = api.format(api.data)
128
161
  num = str.length
129
162
  decor = "-"*num + "\n"
@@ -131,11 +164,11 @@ module Livetext::Standard
131
164
  api.optional_blank_line
132
165
  end
133
166
 
134
- def quit(args = nil, body = nil)
167
+ def quit
135
168
  @output.close
136
169
  end
137
170
 
138
- def cleanup(args = nil, body = nil)
171
+ def cleanup(args, data)
139
172
  api.args.each do |item|
140
173
  cmd = ::File.directory?(item) ? "rm -f #{item}/*" : "rm #{item}"
141
174
  system(cmd)
@@ -143,18 +176,33 @@ module Livetext::Standard
143
176
  api.optional_blank_line
144
177
  end
145
178
 
146
- def dot_def(args = nil, body = nil)
179
+ def dot_def(args, data, body)
147
180
  name = api.args[0]
148
181
  check_disallowed(name)
149
- # Difficult to avoid eval here
150
- str = "def #{name}\n"
151
- str << api.body(true).join("\n")
182
+
183
+ # Check for parameter type specification
184
+ param_type = api.args[1]&.downcase
185
+ raw_body = api.args[2]&.downcase == 'raw'
186
+
187
+ # Build method signature based on param_type
188
+ case param_type
189
+ when nil
190
+ str = "def #{name}\n"
191
+ when 'args'
192
+ str = "def #{name}(args, data)\n"
193
+ when 'body'
194
+ str = "def #{name}(args, data, body)\n"
195
+ else
196
+ raise "Invalid parameter type: #{param_type}. Use 'args' or 'body' or omit."
197
+ end
198
+
199
+ str << body.join("\n")
152
200
  str << "\nend\n"
153
201
  eval str
154
202
  api.optional_blank_line
155
203
  end
156
204
 
157
- def set(args = nil, body = nil)
205
+ def set(args, data)
158
206
  line = api.args.join(" ") # data.chomp
159
207
  pairs = Livetext::ParseSet.new(line).parse
160
208
  api.setvars(pairs)
@@ -163,7 +211,7 @@ module Livetext::Standard
163
211
 
164
212
  # FIXME really these should be one method...
165
213
 
166
- def variables!(args = nil, body = nil) # cwd, not FileDir - weird, fix later
214
+ def variables!(args, data, body) # cwd, not FileDir - weird, fix later
167
215
  prefix = api.args[0]
168
216
  file = api.args[1]
169
217
  prefix = nil if prefix == "-" # FIXME dumb hack
@@ -171,14 +219,14 @@ module Livetext::Standard
171
219
  here = "" # different for ! version
172
220
  lines = File.readlines(here + file)
173
221
  else
174
- lines = api.body
222
+ lines = body
175
223
  end
176
224
  pairs = Livetext::ParseGeneral.parse_vars(lines, prefix: nil)
177
225
  api.setvars(pairs)
178
226
  api.optional_blank_line
179
227
  end
180
228
 
181
- def variables(args = nil, body = nil)
229
+ def variables(args, data, body)
182
230
  prefix = api.args[0]
183
231
  fname = api.args[1]
184
232
  prefix = nil if prefix == "-" # FIXME dumb hack
@@ -195,7 +243,7 @@ module Livetext::Standard
195
243
  raise "No such file #{path.inspect} (file #{path})" unless fok
196
244
  lines = File.readlines(path)
197
245
  else
198
- lines = api.body
246
+ lines = body
199
247
  end
200
248
  pairs = Livetext::ParseGeneral.parse_vars(lines, prefix: nil)
201
249
  api.setvars(pairs)
@@ -204,9 +252,9 @@ module Livetext::Standard
204
252
  fatal(err)
205
253
  end
206
254
 
207
- def heredoc(args = nil, body = nil)
255
+ def heredoc(args, data, body)
208
256
  var = api.args[0]
209
- text = api.body.join("\n")
257
+ text = body.join("\n")
210
258
  rhs = ""
211
259
  text.each_line do |line|
212
260
  str = api.format(line.chomp)
@@ -218,9 +266,9 @@ module Livetext::Standard
218
266
  api.optional_blank_line
219
267
  end
220
268
 
221
- def heredoc!(args = nil, body = nil) # no <br>
269
+ def heredoc!(args, data, body) # no <br>
222
270
  var = api.args[0]
223
- text = api.body.join("\n")
271
+ text = body.join("\n")
224
272
  rhs = ""
225
273
  text.each_line do |line|
226
274
  str = api.format(line.chomp)
@@ -232,7 +280,7 @@ module Livetext::Standard
232
280
  api.optional_blank_line
233
281
  end
234
282
 
235
- def seek(args = nil, body = nil) # like include, but search upward as needed
283
+ def seek(args, data) # like include, but search upward as needed
236
284
  file = api.args.first
237
285
  file = search_upward(file)
238
286
  check_file_exists(file)
@@ -240,7 +288,7 @@ module Livetext::Standard
240
288
  api.optional_blank_line
241
289
  end
242
290
 
243
- def cinclude(args = nil, body = nil) # dot command
291
+ def cinclude(args, data) # dot command
244
292
  file = api.expand_variables(api.args.first) # allows for variables
245
293
  if api.args.size > 1 # there is an HTML file
246
294
  processed = api.expand_variables(api.args[1])
@@ -250,127 +298,127 @@ module Livetext::Standard
250
298
  end
251
299
  end
252
300
  check_file_exists(file)
253
- @parent.process_file(file)
301
+ process_file(file)
254
302
  api.optional_blank_line
255
303
  end
256
304
 
257
- def dot_include(args = nil, body = nil) # dot command
305
+ def dot_include(args, data) # dot command
258
306
  file = api.expand_variables(api.args.first) # allows for variables
259
307
  check_file_exists(file)
260
- @parent.process_file(file)
308
+ process_file(file)
261
309
  api.optional_blank_line
262
310
  end
263
311
 
264
- def inherit(args = nil, body = nil)
312
+ def inherit(args, data)
265
313
  file = api.args.first
266
314
  upper = "../#{file}"
267
315
  got_upper, got_file = File.exist?(upper), File.exist?(file)
268
316
  good = got_upper || got_file
269
317
  STDERR.puts "File #{file} not found (local or parent)" unless good
270
318
 
271
- @parent.process_file(upper) if got_upper
272
- @parent.process_file(file) if got_file
319
+ process_file(upper) if got_upper
320
+ process_file(file) if got_file
273
321
  api.optional_blank_line
274
322
  end
275
323
 
276
- def mixin(args = nil, body = nil)
277
- name = api.args.first # Expect a module name
324
+ def mixin(args, data)
325
+ name = args.first # Expect a module name
278
326
  @mixins ||= []
279
327
  return if @mixins.include?(name)
280
328
  @mixins << name
281
- mod = Livetext::Handler::Mixin.get_module(name, @parent)
329
+ mod = Livetext::Handler::Mixin.get_module(name, self)
282
330
  self.extend(mod)
283
331
  init = "init_#{name}"
284
332
  self.send(init) rescue nil # if self.respond_to? init
285
333
  api.optional_blank_line
286
334
  end
287
335
 
288
- def import(args = nil, body = nil)
289
- name = api.args.first # Expect a module name
336
+ def import(args, data)
337
+ name = args.first # Expect a module name
290
338
  @imports ||= []
291
339
  return if @imports.include?(name)
292
340
  @imports << name
293
- mod = Livetext::Handler::Import.get_module(name, @parent)
341
+ mod = Livetext::Handler::Import.get_module(name, self)
294
342
  self.extend(mod)
295
343
  init = "init_#{name}"
296
344
  self.send(init) rescue nil # if self.respond_to? init
297
345
  api.optional_blank_line
298
346
  end
299
347
 
300
- def copy(args = nil, body = nil)
348
+ def copy(args, data)
301
349
  file = api.args.first
302
350
  ok = file_exists?(file)
303
351
 
304
- self.parent.graceful_error FileNotFound(file) unless ok # FIXME seems weird?
352
+ graceful_error FileNotFound(file) unless ok # FIXME seems weird?
305
353
  api.out grab_file(file)
306
354
  api.optional_blank_line
307
355
  [ok, file]
308
356
  end
309
357
 
310
- def r(args = nil, body = nil)
358
+ def r(args, data)
311
359
  # FIXME api.data is broken
312
360
  # api.out api.data # No processing at all
313
361
  api.out api.args.join(" ")
314
362
  api.optional_blank_line
315
363
  end
316
364
 
317
- def raw(args = nil, body = nil)
365
+ def raw(args, data)
318
366
  # No processing at all (terminate with __EOF__)
319
367
  api.raw_body {|line| api.out line } # no formatting
320
368
  api.optional_blank_line
321
369
  end
322
370
 
323
- def debug(args = nil, body = nil)
371
+ def debug(args, data)
324
372
  @debug = onoff(api.args.first)
325
373
  api.optional_blank_line
326
374
  end
327
375
 
328
- def passthru(args = nil, body = nil)
376
+ def passthru(args, data)
329
377
  # FIXME - add check for args size? (helpers)
330
378
  @nopass = ! onoff(api.args.first)
331
379
  api.optional_blank_line
332
380
  end
333
381
 
334
- def nopass(args = nil, body = nil)
382
+ def nopass
335
383
  @nopass = true
336
384
  api.optional_blank_line
337
385
  end
338
386
 
339
- def para(args = nil, body = nil)
387
+ def para(args, data)
340
388
  # FIXME - add check for args size? (helpers)
341
389
  @nopara = ! onoff(api.args.first)
342
390
  api.optional_blank_line
343
391
  end
344
392
 
345
- def nopara(args = nil, body = nil)
393
+ def nopara
346
394
  @nopara = true
347
395
  api.optional_blank_line
348
396
  end
349
397
 
350
- def heading(args = nil, body = nil)
398
+ def heading(args, data)
351
399
  api.print "<center><font size=+1><b>"
352
400
  api.print api.data
353
401
  api.print "</b></font></center>"
354
402
  api.optional_blank_line
355
403
  end
356
404
 
357
- def newpage(args = nil, body = nil)
405
+ def newpage
358
406
  api.out '<p style="page-break-after:always;"></p>'
359
407
  api.out "<p/>"
360
408
  api.optional_blank_line
361
409
  end
362
410
 
363
- def mono(args = nil, body = nil)
411
+ def mono(args, data, body)
364
412
  html.wrap ":pre" do
365
413
  api.body(true) {|line| api.out line }
366
414
  end
367
415
  api.optional_blank_line
368
416
  end
369
417
 
370
- def dlist(args = nil, body = nil)
418
+ def dlist(args, data, body)
371
419
  delim = api.args.first
372
420
  html.wrap(:dl) do
373
- api.body do |line|
421
+ body.each do |line|
374
422
  line = api.format(line)
375
423
  term, defn = line.split(delim)
376
424
  api.out html.tag(:dt, cdata: term)
@@ -381,18 +429,18 @@ module Livetext::Standard
381
429
  api.optional_blank_line
382
430
  end
383
431
 
384
- def link(args = nil, body = nil)
432
+ def link(args, data)
385
433
  url = api.args.first
386
434
  text = api.args[2..-1].join(" ")
387
435
  api.out "<a style='text-decoration: none' href='#{url}'>#{text}</a>"
388
436
  api.optional_blank_line
389
437
  end
390
438
 
391
- def xtable(args = nil, body = nil) # Borrowed from bookish - FIXME
439
+ def xtable(args, data, body) # Borrowed from bookish - FIXME
392
440
  title = api.data
393
441
  delim = " :: "
394
442
  api.out "<br>\n\n<center><table width=90% cellpadding=5>"
395
- lines = api.body(true)
443
+ lines = body
396
444
  maxw = nil
397
445
  processed = []
398
446
  lines.each do |line|
@@ -418,11 +466,11 @@ module Livetext::Standard
418
466
  api.optional_blank_line
419
467
  end
420
468
 
421
- def table(args = nil, body = nil) # Same as xtable
469
+ def table(args, data, body) # Same as xtable
422
470
  title = api.data
423
471
  delim = " :: "
424
472
  api.out "<br>\n\n<center><table width=90% cellpadding=5>"
425
- lines = api.body(true)
473
+ lines = body
426
474
  maxw = nil
427
475
  processed = []
428
476
  lines.each do |line|
@@ -448,7 +496,7 @@ module Livetext::Standard
448
496
  api.optional_blank_line
449
497
  end
450
498
 
451
- def image(args = nil, body = nil)
499
+ def image(args, data)
452
500
  name, wide, high = api.args
453
501
  geom = ""
454
502
  geom = "width=#{wide} height=#{high}" if wide || high
@@ -456,7 +504,7 @@ module Livetext::Standard
456
504
  api.optional_blank_line
457
505
  end
458
506
 
459
- def br(args = nil, body = nil)
507
+ def br(args, data)
460
508
  num = api.args.first || "1"
461
509
  str = ""
462
510
  num.to_i.times { str << "<br>" }
@@ -464,7 +512,7 @@ module Livetext::Standard
464
512
  api.optional_blank_line
465
513
  end
466
514
 
467
- def reflection(args = nil, body = nil) # strictly experimental!
515
+ def reflection(args, data) # strictly experimental!
468
516
  list = self.methods
469
517
  obj = Object.instance_methods
470
518
  diff = (list - obj).sort
@@ -138,12 +138,31 @@ class Livetext::UserAPI
138
138
  @line = format(@line) unless raw
139
139
  lines << @line
140
140
  end
141
- raise "Expected .end, found end of file" unless end?(@line) # use custom exception
141
+ graceful_error ExpectedEnd() unless end?(@line) # use custom exception
142
142
  optional_blank_line # FIXME Delete this??
143
143
  return lines unless block_given?
144
144
  lines.each {|line| yield line } # FIXME what about $. ?
145
145
  end
146
146
 
147
+ def body_with_raw
148
+ processed_lines = []
149
+ raw_lines = []
150
+ end_found = false
151
+ loop do
152
+ @line = @live.nextline
153
+ break if @line.nil?
154
+ @line.chomp!
155
+ break if end?(@line)
156
+ next if comment?(@line)
157
+ raw_lines << @line
158
+ @line = format(@line)
159
+ processed_lines << @line
160
+ end
161
+ graceful_error ExpectedEnd() unless end?(@line) # use custom exception
162
+ optional_blank_line # FIXME Delete this??
163
+ [processed_lines, raw_lines]
164
+ end
165
+
147
166
  def body_text(raw=false)
148
167
  raw_body.join("\n")
149
168
  end
@@ -0,0 +1,78 @@
1
+ # Variable Manager - Centralized variable handling for Livetext
2
+ class Livetext::VariableManager
3
+ def initialize(parent)
4
+ @parent = parent
5
+ @variables = Livetext::Variables.new
6
+ initialize_default_variables
7
+ end
8
+
9
+ def set(name, value)
10
+ @variables.set(name, value)
11
+ end
12
+
13
+ def get(name)
14
+ @variables.get(name)
15
+ end
16
+
17
+ def [](name)
18
+ @variables[name]
19
+ end
20
+
21
+ def set_multiple(pairs)
22
+ pairs.each do |name, value|
23
+ set(name, value)
24
+ end
25
+ end
26
+
27
+ def exists?(name)
28
+ @variables.exists?(name)
29
+ end
30
+
31
+ def list
32
+ @variables.inspect
33
+ end
34
+
35
+ def to_h
36
+ @variables.to_h
37
+ end
38
+
39
+ def replace(vars)
40
+ @variables = Livetext::Variables.new(vars)
41
+ end
42
+
43
+ # Enable live.vars.myvar syntax
44
+ def method_missing(name, *args)
45
+ if args.empty?
46
+ @variables[name.to_sym] || "[#{name} is undefined]"
47
+ else
48
+ super
49
+ end
50
+ end
51
+
52
+ def respond_to_missing?(name, include_private = false)
53
+ true # Since method_missing always returns a value, respond_to? should always return true
54
+ end
55
+
56
+ private
57
+
58
+ def initialize_default_variables
59
+ # System info variables
60
+ set(:User, `whoami`.chomp)
61
+ set(:Version, Livetext::VERSION)
62
+ set(:Hostname, `hostname`.chomp)
63
+ set(:Platform, RUBY_PLATFORM)
64
+ set(:RubyVersion, RUBY_VERSION)
65
+ set(:LivetextVersion, Livetext::VERSION)
66
+
67
+ # Date/time variables
68
+ now = Time.now
69
+ set(:Year, now.year.to_s)
70
+ set(:Month, now.mon.to_s)
71
+ set(:Day, now.day.to_s)
72
+ set(:Hour, now.hour.to_s)
73
+ set(:Minute, now.min.to_s)
74
+ set(:Second, now.sec.to_s)
75
+ set(:Weekday, now.wday.to_s)
76
+ set(:Week, now.strftime("%U"))
77
+ end
78
+ end
@@ -21,7 +21,7 @@
21
21
  end
22
22
 
23
23
  def [](var)
24
- @vars[var.to_sym]
24
+ @vars[var.to_sym] || "[#{var} is undefined]"
25
25
  end
26
26
 
27
27
  def []=(var, value)
@@ -46,5 +46,13 @@
46
46
  def to_a
47
47
  @vars.to_a
48
48
  end
49
+
50
+ def to_h
51
+ @vars.select { |k, v| k.is_a?(Symbol) }
52
+ end
53
+
54
+ def exists?(var)
55
+ @vars[var.to_sym] != nil
56
+ end
49
57
  end
50
58
 
@@ -2,5 +2,5 @@
2
2
  # Defining VERSION
3
3
 
4
4
  class Livetext
5
- VERSION = "0.9.52"
5
+ VERSION = "0.9.56"
6
6
  end
data/lib/livetext.rb CHANGED
@@ -5,7 +5,6 @@ if !defined?(Livetext)
5
5
  require_relative 'livetext/helpers'
6
6
  require_relative 'livetext/variables'
7
7
  require_relative 'livetext/core'
8
- require_relative 'livetext/formatter'
9
8
  require_relative 'livetext/paths'
10
9
 
11
10
  require_relative 'livetext/reopen'
@@ -13,9 +12,16 @@ if !defined?(Livetext)
13
12
  require_relative 'livetext/errors'
14
13
  require_relative 'livetext/standard'
15
14
  require_relative 'livetext/functions'
15
+ require_relative 'livetext/function_registry'
16
+ require_relative 'livetext/variable_manager'
17
+ require_relative 'livetext/formatter'
16
18
  require_relative 'livetext/userapi'
17
- # require_relative 'livetext/formatter'
18
- require_relative 'livetext/processor'
19
+
19
20
 
20
21
  require_relative 'livetext/handler'
22
+
23
+ # Include Standard after it's loaded
24
+ class Livetext
25
+ include Livetext::Standard
26
+ end
21
27
  end