livetext 0.9.55 → 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 (37) hide show
  1. checksums.yaml +4 -4
  2. data/lib/livetext/ast/show_ast_clean.rb +10 -0
  3. data/lib/livetext/ast/show_ast_result.rb +60 -0
  4. data/lib/livetext/ast/show_raw_arrays.rb +13 -0
  5. data/lib/livetext/ast.rb +464 -0
  6. data/lib/livetext/ast_to_html.rb +32 -0
  7. data/lib/livetext/core.rb +6 -4
  8. data/lib/livetext/errors.rb +1 -0
  9. data/lib/livetext/functions.rb +26 -0
  10. data/lib/livetext/handler/mixin.rb +28 -0
  11. data/lib/livetext/helpers.rb +19 -20
  12. data/lib/livetext/standard.rb +2 -2
  13. data/lib/livetext/userapi.rb +20 -1
  14. data/lib/livetext/variable_manager.rb +14 -1
  15. data/lib/livetext/variables.rb +5 -1
  16. data/lib/livetext/version.rb +1 -1
  17. data/plugin/booktool.rb +6 -6
  18. data/plugin/lt3scriptor.rb +914 -0
  19. data/plugin/mixin_functions_class.rb +33 -0
  20. data/test/snapshots/error_missing_end/match-error.txt +1 -1
  21. data/test/snapshots/mixin_functions_class/expected-error.txt +0 -0
  22. data/test/snapshots/mixin_functions_class/expected-output.txt +20 -0
  23. data/test/snapshots/mixin_functions_class/mixin_functions_class.rb +33 -0
  24. data/test/snapshots/mixin_functions_class/source.lt3 +17 -0
  25. data/test/snapshots/system_info/match-output.txt +18 -0
  26. data/test/unit/all.rb +3 -0
  27. data/test/unit/ast.rb +90 -0
  28. data/test/unit/ast_directives.rb +104 -0
  29. data/test/unit/ast_variables.rb +71 -0
  30. data/test/unit/core_methods.rb +180 -0
  31. data/test/unit/formatter_component.rb +1 -1
  32. data/test/unit/mixin_functions_class.rb +131 -0
  33. data/test/unit/stringparser.rb +14 -32
  34. metadata +18 -5
  35. data/imports/markdown.rb +0 -44
  36. data/plugin/markdown.rb +0 -43
  37. data/test/snapshots/system_info/expected-output.txt +0 -18
@@ -56,6 +56,34 @@ class Livetext::Handler::Mixin
56
56
  # Register with the function registry
57
57
  parent.function_registry.register_user(method_name.to_s, function, source: :mixin, filename: @file)
58
58
  end
59
+
60
+ # Also look for methods defined in Livetext::Functions class
61
+ # Get all methods from Livetext::Functions
62
+ functions_class_methods = Livetext::Functions.instance_methods(false)
63
+
64
+ functions_class_methods.each do |method_name|
65
+ # Skip methods that are already built-in (defined in the original functions.rb)
66
+ builtin_methods = [:code_lines, :ns, :isqrt, :reverse, :date, :time, :pwd, :rand, :link, :br, :yt, :simple_format,
67
+ :b, :i, :t, :s, :bi, :bt, :bs, :it, :is, :ts, :bit, :bis, :bts, :its, :bits]
68
+ next if builtin_methods.include?(method_name)
69
+
70
+ # Create a lambda that calls the method on a new Livetext::Functions instance
71
+ function = ->(param) do
72
+ fobj = ::Livetext::Functions.new
73
+ # Set the Livetext instance and its variables for access in functions
74
+ fobj.live = parent
75
+ fobj.vars = parent.vars
76
+ method = fobj.method(method_name)
77
+ if method.parameters.empty?
78
+ fobj.send(method_name)
79
+ else
80
+ fobj.send(method_name, param)
81
+ end
82
+ end
83
+
84
+ # Register with the function registry
85
+ parent.function_registry.register_user(method_name.to_s, function, source: :mixin, filename: @file)
86
+ end
59
87
  end
60
88
 
61
89
  end
@@ -122,43 +122,42 @@ module Livetext::Helpers
122
122
  end
123
123
 
124
124
  def invoke_dotcmd(name, data0="")
125
- api.data = data0.dup # should permit _ in function names at least
125
+ api.data = data0.dup
126
126
  args0 = data0.split
127
127
  api.args = args0.dup
128
- # Get method signature to determine what parameters to pass
129
128
  method = method(name)
130
- param_count = method.parameters.length
129
+ params = method.parameters
131
130
 
132
- # Pass parameters based on method signature
133
- case param_count
131
+ case params.length
134
132
  when 0
135
133
  retval = send(name)
136
134
  when 2
137
135
  retval = send(name, args0, data0)
138
136
  when 3
139
- # Check if this is a method that needs raw body content
140
- # For now, we'll check if it's dot_def and if it has 'body raw' in args
141
- raw_body = (name == :dot_def && args0.length >= 3 && args0[2] == 'raw')
142
- body_lines = raw_body ? api.body(true) : api.body(false)
143
- retval = send(name, args0, data0, body_lines)
137
+ processed_body = api.body(false)
138
+ retval = send(name, args0, data0, processed_body)
139
+ when 4
140
+ if params[3][1] == :raw
141
+ raw_body = api.body(true)
142
+ retval = send(name, args0, data0, raw_body, true)
143
+ else
144
+ raise "4th parameter is not :raw!"
145
+ end
144
146
  else
145
- retval = send(name) # fallback to no parameters
147
+ raise "#{name} has #{params.length} parameters!"
146
148
  end
147
149
  retval
148
- rescue => err
149
- graceful_error(err) # , "#{__method__}: name = #{name}")
150
150
  end
151
151
 
152
152
  def handle_dotcmd(line, indent = 0)
153
- indent = @indentation.last # top of stack
154
- line = line.sub(/# .*$/, "") # FIXME Could be problematic?
153
+ line = line.sub(/# .*$/, "")
155
154
  name, data = get_name_data(line)
156
- success = true # Be optimistic... :P
155
+ check_disallowed(name)
157
156
  case
158
- when name == :end # special case
159
- graceful_error EndWithoutOpening()
160
- when respond_to?(name)
161
- success = invoke_dotcmd(name, data) # was 141
157
+ when name == :end # special case
158
+ graceful_error EndWithoutOpening()
159
+ when respond_to?(name)
160
+ success = invoke_dotcmd(name, data) # was 141
162
161
  else
163
162
  graceful_error UnknownMethod(name)
164
163
  end
@@ -322,7 +322,7 @@ module Livetext::Standard
322
322
  end
323
323
 
324
324
  def mixin(args, data)
325
- name = api.args.first # Expect a module name
325
+ name = args.first # Expect a module name
326
326
  @mixins ||= []
327
327
  return if @mixins.include?(name)
328
328
  @mixins << name
@@ -334,7 +334,7 @@ module Livetext::Standard
334
334
  end
335
335
 
336
336
  def import(args, data)
337
- name = api.args.first # Expect a module name
337
+ name = args.first # Expect a module name
338
338
  @imports ||= []
339
339
  return if @imports.include?(name)
340
340
  @imports << name
@@ -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
@@ -25,7 +25,7 @@ class Livetext::VariableManager
25
25
  end
26
26
 
27
27
  def exists?(name)
28
- @variables[name.to_sym] != nil
28
+ @variables.exists?(name)
29
29
  end
30
30
 
31
31
  def list
@@ -40,6 +40,19 @@ class Livetext::VariableManager
40
40
  @variables = Livetext::Variables.new(vars)
41
41
  end
42
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
+
43
56
  private
44
57
 
45
58
  def initialize_default_variables
@@ -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)
@@ -50,5 +50,9 @@
50
50
  def to_h
51
51
  @vars.select { |k, v| k.is_a?(Symbol) }
52
52
  end
53
+
54
+ def exists?(var)
55
+ @vars[var.to_sym] != nil
56
+ end
53
57
  end
54
58
 
@@ -2,5 +2,5 @@
2
2
  # Defining VERSION
3
3
 
4
4
  class Livetext
5
- VERSION = "0.9.55"
5
+ VERSION = "0.9.56"
6
6
  end
data/plugin/booktool.rb CHANGED
@@ -67,12 +67,12 @@ end
67
67
 
68
68
  # These are duplicated. Remove safely
69
69
 
70
- def h1(args = nil, body = nil); api.out html.tag(:h1, api.data); return true; end
71
- def h2(args = nil, body = nil); api.out html.tag(:h2, api.data); return true; end
72
- def h3(args = nil, body = nil); api.out html.tag(:h3, api.data); return true; end
73
- def h4(args = nil, body = nil); api.out html.tag(:h4, api.data); return true; end
74
- def h5(args = nil, body = nil); api.out html.tag(:h5, api.data); return true; end
75
- def h6(args = nil, body = nil); api.out html.tag(:h6, api.data); return true; end
70
+ def h1(args = nil, body = nil); api.out html.tag(:h1, cdata: api.data); return true; end
71
+ def h2(args = nil, body = nil); api.out html.tag(:h2, cdata: api.data); return true; end
72
+ def h3(args = nil, body = nil); api.out html.tag(:h3, cdata: api.data); return true; end
73
+ def h4(args = nil, body = nil); api.out html.tag(:h4, cdata: api.data); return true; end
74
+ def h5(args = nil, body = nil); api.out html.tag(:h5, cdata: api.data); return true; end
75
+ def h6(args = nil, body = nil); api.out html.tag(:h6, cdata: api.data); return true; end
76
76
 
77
77
  def alpha_columns(args = nil, body = nil)
78
78
  n = api.args.first.to_i # FIXME: what if it's missing?