livetext 0.9.60 → 0.9.61
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.
- checksums.yaml +4 -4
- data/lib/livetext/core.rb +3 -3
- data/lib/livetext/function_caller.rb +32 -0
- data/lib/livetext/function_registry.rb +2 -2
- data/lib/livetext/userapi.rb +7 -1
- data/lib/livetext/version.rb +1 -1
- data/test/snapshots/simple_func_api/expected-error.txt +0 -0
- data/test/snapshots/simple_func_api/match-output.txt +18 -0
- data/test/snapshots/simple_func_api/source.lt3 +31 -0
- data/test/snapshots/simple_func_api/stderr.txt +0 -0
- data/test/snapshots/system_info/match-output.txt +1 -1
- data/test/unit/all.rb +1 -0
- data/test/unit/function_caller.rb +101 -0
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0d0ba9b287008c8827a9a1d30881507700dceffae0edd52e4dd5274b5fb4f004
|
4
|
+
data.tar.gz: eb988c908dcdbbbff10710a4a62bd51cdd13b832a9121814150a484448d9c5f7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1fcc995144794c8fac0b87c42a4cd8913d57bc31c6f26cc1bd564871366c1c3d260eda87966301d81776f1322fd2c22d453b807ffc06a90e4e1f4ceca3184598
|
7
|
+
data.tar.gz: 40fe697a385ba6684df3746558674793766801933fcbd8b42766a9c2ff1121aebb75942898f32fe6184de3fb96ad2d6c9ecef980df2cf2bd8697c9f377123f08
|
data/lib/livetext/core.rb
CHANGED
@@ -60,13 +60,13 @@ class Livetext
|
|
60
60
|
def initialize(output = ::STDOUT) # Livetext
|
61
61
|
@body = ""
|
62
62
|
@indentation = [0]
|
63
|
+
@function_registry = Livetext::FunctionRegistry.new
|
64
|
+
@variables = Livetext::VariableManager.new(self)
|
65
|
+
@formatter = Livetext::Formatter.new(self)
|
63
66
|
@api = UserAPI.new(self)
|
64
67
|
@output = ::Livetext.output = output
|
65
68
|
@html = Livetext::HTML.new(@api)
|
66
69
|
@sources = []
|
67
|
-
@function_registry = Livetext::FunctionRegistry.new
|
68
|
-
@variables = Livetext::VariableManager.new(self)
|
69
|
-
@formatter = Livetext::Formatter.new(self)
|
70
70
|
# puts "------ init: self = "
|
71
71
|
# p self
|
72
72
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# FunctionCaller - Provides simple method-style access to Livetext functions
|
2
|
+
class Livetext::FunctionCaller
|
3
|
+
def initialize(function_registry)
|
4
|
+
@registry = function_registry
|
5
|
+
end
|
6
|
+
|
7
|
+
# Dynamically handle method calls to function names
|
8
|
+
def method_missing(name, *args)
|
9
|
+
# Convert method name to string and call the function registry
|
10
|
+
function_name = name.to_s
|
11
|
+
param = args.first || ""
|
12
|
+
|
13
|
+
@registry.call(function_name, param)
|
14
|
+
rescue => e
|
15
|
+
"[Error calling function #{function_name}: #{e.message}]"
|
16
|
+
end
|
17
|
+
|
18
|
+
# Check if a function exists
|
19
|
+
def respond_to_missing?(name, include_private = false)
|
20
|
+
@registry.function_exists?(name.to_s) || super
|
21
|
+
end
|
22
|
+
|
23
|
+
# List all available functions
|
24
|
+
def list
|
25
|
+
@registry.list_functions.map { |f| f[:name] }
|
26
|
+
end
|
27
|
+
|
28
|
+
# Check if a specific function exists
|
29
|
+
def exists?(name)
|
30
|
+
@registry.function_exists?(name.to_s)
|
31
|
+
end
|
32
|
+
end
|
@@ -5,7 +5,7 @@ class Livetext::FunctionRegistry
|
|
5
5
|
@builtin_functions = {}
|
6
6
|
@metadata = {}
|
7
7
|
register_builtin_functions
|
8
|
-
puts "DEBUG: Registered #{@builtin_functions.size} builtin functions" if ENV['DEBUG']
|
8
|
+
# puts "DEBUG: Registered #{@builtin_functions.size} builtin functions" if ENV['DEBUG']
|
9
9
|
end
|
10
10
|
|
11
11
|
def register_user(name, function, source: :inline, filename: nil)
|
@@ -98,7 +98,7 @@ class Livetext::FunctionRegistry
|
|
98
98
|
end
|
99
99
|
end)
|
100
100
|
register_builtin(:br, ->(param) do
|
101
|
-
n = (param
|
101
|
+
n = (param && !param.empty?) ? param.to_i : 1
|
102
102
|
"<br>" * n
|
103
103
|
end)
|
104
104
|
register_builtin(:reverse, ->(param) do
|
data/lib/livetext/userapi.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require_relative 'expansion'
|
2
2
|
require_relative 'html'
|
3
|
+
require_relative 'function_caller'
|
3
4
|
|
4
5
|
# Encapsulate the UserAPI as a class
|
5
6
|
|
@@ -19,6 +20,7 @@ class Livetext::UserAPI
|
|
19
20
|
@vars = live.vars
|
20
21
|
@html = Livetext::HTML.new(self)
|
21
22
|
@expander = Livetext::Expansion.new(live)
|
23
|
+
@funcs = Livetext::FunctionCaller.new(live.function_registry)
|
22
24
|
end
|
23
25
|
|
24
26
|
def api
|
@@ -53,7 +55,7 @@ class Livetext::UserAPI
|
|
53
55
|
end
|
54
56
|
|
55
57
|
def expand_functions(str)
|
56
|
-
@expander.
|
58
|
+
@expander.expand_function_calls(str)
|
57
59
|
end
|
58
60
|
|
59
61
|
def setvar(var, val) # FIXME
|
@@ -244,5 +246,9 @@ class Livetext::UserAPI
|
|
244
246
|
def debug(*args)
|
245
247
|
TTY.puts *args if @live.debug
|
246
248
|
end
|
249
|
+
|
250
|
+
def funcs
|
251
|
+
@funcs
|
252
|
+
end
|
247
253
|
end
|
248
254
|
|
data/lib/livetext/version.rb
CHANGED
File without changes
|
@@ -0,0 +1,18 @@
|
|
1
|
+
1 <h3>Testing Simple Function API</h3>
|
2
|
+
2 <p>Date: 2025-09-09</p>
|
3
|
+
3 /<p>Time: \d{2}:\d{2}:\d{2}</p>/
|
4
|
+
4 /<p>Directory: .*livetext.*</p>/
|
5
|
+
5 <p>Platform: universal.x86_64-darwin22</p>
|
6
|
+
6 <p>Ruby version: 2.6.10</p>
|
7
|
+
7 <p>Livetext version: 0.9.60</p>
|
8
|
+
8 <p>Reverse of 'hello': olleh</p>
|
9
|
+
9 <p>Square root of 16: 4</p>
|
10
|
+
10 /<p>Random \(1-10\): \d+</p>/
|
11
|
+
11 /<p>Link: <a style='text-decoration: none' href='https://google\.com'>Google</a></p>/
|
12
|
+
12 <p>Line breaks: <br><br></p>
|
13
|
+
13 <p>Date exists: true</p>
|
14
|
+
14 <p>Nonexistent exists: false</p>
|
15
|
+
15 <p>Total functions: 23</p>
|
16
|
+
16 /<p>First 5 functions: br, date, day, days_ago, days_from_now</p>/
|
17
|
+
17 <p><strong>Simple API works!</strong></p>
|
18
|
+
18 </p>
|
@@ -0,0 +1,31 @@
|
|
1
|
+
.dot_def test_simple_func_api args
|
2
|
+
api.out "<h3>Testing Simple Function API</h3>"
|
3
|
+
|
4
|
+
# Test basic function calls
|
5
|
+
api.out "<p>Date: #{api.funcs.date()}</p>"
|
6
|
+
api.out "<p>Time: #{api.funcs.time()}</p>"
|
7
|
+
api.out "<p>Directory: #{api.funcs.pwd()}</p>"
|
8
|
+
api.out "<p>Platform: #{api.funcs.platform()}</p>"
|
9
|
+
api.out "<p>Ruby version: #{api.funcs.ruby_version()}</p>"
|
10
|
+
api.out "<p>Livetext version: #{api.funcs.livetext_version()}</p>"
|
11
|
+
|
12
|
+
# Test functions with parameters
|
13
|
+
api.out "<p>Reverse of 'hello': #{api.funcs.reverse('hello')}</p>"
|
14
|
+
api.out "<p>Square root of 16: #{api.funcs.isqrt('16')}</p>"
|
15
|
+
api.out "<p>Random (1-10): #{api.funcs.rand('1 10')}</p>"
|
16
|
+
api.out "<p>Link: #{api.funcs.link('Google|https://google.com')}</p>"
|
17
|
+
api.out "<p>Line breaks: #{api.funcs.br('2')}</p>"
|
18
|
+
|
19
|
+
# Test function existence
|
20
|
+
api.out "<p>Date exists: #{api.funcs.exists?('date')}</p>"
|
21
|
+
api.out "<p>Nonexistent exists: #{api.funcs.exists?('nonexistent')}</p>"
|
22
|
+
|
23
|
+
# Test function listing
|
24
|
+
functions = api.funcs.list
|
25
|
+
api.out "<p>Total functions: #{functions.length}</p>"
|
26
|
+
api.out "<p>First 5 functions: #{functions.first(5).join(', ')}</p>"
|
27
|
+
|
28
|
+
api.out "<p><strong>Simple API works!</strong></p>"
|
29
|
+
.end
|
30
|
+
|
31
|
+
.test_simple_func_api
|
File without changes
|
data/test/unit/all.rb
CHANGED
@@ -10,6 +10,7 @@ require_relative 'variables'
|
|
10
10
|
require_relative 'variable_manager'
|
11
11
|
require_relative 'functions'
|
12
12
|
require_relative 'function_registry'
|
13
|
+
require_relative 'function_caller'
|
13
14
|
require_relative 'mixin_functions_class'
|
14
15
|
require_relative 'formatter'
|
15
16
|
require_relative 'formatter_component'
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require_relative '../../lib/livetext'
|
3
|
+
require_relative '../../lib/livetext/function_caller'
|
4
|
+
|
5
|
+
class TestFunctionCaller < Minitest::Test
|
6
|
+
def setup
|
7
|
+
@registry = Livetext::FunctionRegistry.new
|
8
|
+
@caller = Livetext::FunctionCaller.new(@registry)
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_calls_builtin_functions
|
12
|
+
# Test date function
|
13
|
+
result = @caller.date
|
14
|
+
assert_match(/\d{4}-\d{2}-\d{2}/, result)
|
15
|
+
|
16
|
+
# Test time function
|
17
|
+
result = @caller.time
|
18
|
+
assert_match(/\d{2}:\d{2}:\d{2}/, result)
|
19
|
+
|
20
|
+
# Test pwd function
|
21
|
+
result = @caller.pwd
|
22
|
+
assert_equal(Dir.pwd, result)
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_calls_functions_with_parameters
|
26
|
+
# Test reverse function
|
27
|
+
result = @caller.reverse("hello")
|
28
|
+
assert_equal("olleh", result)
|
29
|
+
|
30
|
+
# Test isqrt function
|
31
|
+
result = @caller.isqrt("16")
|
32
|
+
assert_equal("4", result)
|
33
|
+
|
34
|
+
# Test rand function
|
35
|
+
result = @caller.rand("1 10")
|
36
|
+
num = result.to_i
|
37
|
+
assert(num >= 1 && num <= 10, "Random number should be between 1 and 10, got #{result}")
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_calls_functions_with_no_parameters
|
41
|
+
# Test platform function
|
42
|
+
result = @caller.platform
|
43
|
+
assert_equal(RUBY_PLATFORM, result)
|
44
|
+
|
45
|
+
# Test ruby_version function
|
46
|
+
result = @caller.ruby_version
|
47
|
+
assert_equal(RUBY_VERSION, result)
|
48
|
+
|
49
|
+
# Test livetext_version function
|
50
|
+
result = @caller.livetext_version
|
51
|
+
assert_equal(Livetext::VERSION, result)
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_handles_nonexistent_functions
|
55
|
+
result = @caller.nonexistent_function("param")
|
56
|
+
assert_match(/Error evaluating \$\$nonexistent_function/, result)
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_function_existence_check
|
60
|
+
assert(@caller.exists?("date"))
|
61
|
+
assert(@caller.exists?("time"))
|
62
|
+
assert(@caller.exists?("pwd"))
|
63
|
+
refute(@caller.exists?("nonexistent"))
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_list_functions
|
67
|
+
functions = @caller.list
|
68
|
+
assert_instance_of(Array, functions)
|
69
|
+
assert(functions.include?("date"))
|
70
|
+
assert(functions.include?("time"))
|
71
|
+
assert(functions.include?("pwd"))
|
72
|
+
assert(functions.include?("reverse"))
|
73
|
+
assert(functions.include?("isqrt"))
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_respond_to_missing
|
77
|
+
assert(@caller.respond_to?(:date))
|
78
|
+
assert(@caller.respond_to?(:time))
|
79
|
+
assert(@caller.respond_to?(:pwd))
|
80
|
+
refute(@caller.respond_to?(:nonexistent))
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_link_function
|
84
|
+
result = @caller.link("Google|https://google.com")
|
85
|
+
expected = "<a style='text-decoration: none' href='https://google.com'>Google</a>"
|
86
|
+
assert_equal(expected, result)
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_br_function
|
90
|
+
result = @caller.br("3")
|
91
|
+
assert_equal("<br><br><br>", result)
|
92
|
+
|
93
|
+
# Test with empty parameter (default to 1)
|
94
|
+
result = @caller.br("")
|
95
|
+
assert_equal("<br>", result)
|
96
|
+
|
97
|
+
# Test with nil parameter (default to 1)
|
98
|
+
result = @caller.br(nil)
|
99
|
+
assert_equal("<br>", result)
|
100
|
+
end
|
101
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: livetext
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.61
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hal Fulton
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-09-
|
10
|
+
date: 2025-09-09 00:00:00.000000000 Z
|
11
11
|
dependencies: []
|
12
12
|
description: A smart text processor extensible in Ruby
|
13
13
|
email: rubyhacker@gmail.com
|
@@ -35,6 +35,7 @@ files:
|
|
35
35
|
- lib/livetext/expansion.rb
|
36
36
|
- lib/livetext/formatter.rb
|
37
37
|
- lib/livetext/formatter_component.rb
|
38
|
+
- lib/livetext/function_caller.rb
|
38
39
|
- lib/livetext/function_registry.rb
|
39
40
|
- lib/livetext/functions.rb
|
40
41
|
- lib/livetext/global_helpers.rb
|
@@ -197,6 +198,10 @@ files:
|
|
197
198
|
- test/snapshots/simple_copy/expected-output.txt
|
198
199
|
- test/snapshots/simple_copy/simplefile.inc
|
199
200
|
- test/snapshots/simple_copy/source.lt3
|
201
|
+
- test/snapshots/simple_func_api/expected-error.txt
|
202
|
+
- test/snapshots/simple_func_api/match-output.txt
|
203
|
+
- test/snapshots/simple_func_api/source.lt3
|
204
|
+
- test/snapshots/simple_func_api/stderr.txt
|
200
205
|
- test/snapshots/simple_import/expected-error.txt
|
201
206
|
- test/snapshots/simple_import/expected-output.txt
|
202
207
|
- test/snapshots/simple_import/simple_import.rb
|
@@ -236,6 +241,7 @@ files:
|
|
236
241
|
- test/unit/double.rb
|
237
242
|
- test/unit/formatter.rb
|
238
243
|
- test/unit/formatter_component.rb
|
244
|
+
- test/unit/function_caller.rb
|
239
245
|
- test/unit/function_registry.rb
|
240
246
|
- test/unit/functions.rb
|
241
247
|
- test/unit/html.rb
|