livetext 0.9.59 → 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 +4 -3
- data/lib/livetext/function_caller.rb +32 -0
- data/lib/livetext/function_registry.rb +2 -2
- data/lib/livetext/helpers.rb +1 -0
- data/lib/livetext/userapi.rb +19 -3
- data/lib/livetext/version.rb +1 -1
- data/test/snapshots/basic_formatting/expected-output.txt +6 -2
- data/test/snapshots/block_comment/expected-output.txt +2 -0
- data/test/snapshots/comments_ignored_1/expected-output.txt +2 -0
- data/test/snapshots/complex_body/expected-output.txt +4 -1
- data/test/snapshots/copy_is_raw/expected-output.txt +2 -0
- data/test/snapshots/def_method/expected-output.txt +4 -1
- data/test/snapshots/def_parameters/expected-output.txt +6 -2
- data/test/snapshots/error_inc_line_num/expected-output.txt +1 -0
- data/test/snapshots/error_invalid_name/expected-output.txt +3 -1
- data/test/snapshots/error_line_num/expected-output.txt +1 -0
- data/test/snapshots/error_mismatched_end/expected-output.txt +3 -1
- data/test/snapshots/error_missing_end/expected-output.txt +3 -1
- data/test/snapshots/error_name_not_permitted/expected-output.txt +3 -1
- data/test/snapshots/error_no_such_copy/expected-output.txt +3 -1
- data/test/snapshots/error_no_such_inc/expected-output.txt +3 -1
- data/test/snapshots/error_no_such_mixin/expected-output.txt +3 -1
- data/test/snapshots/example_alpha/expected-output.txt +6 -2
- data/test/snapshots/example_alpha2/expected-output.txt +4 -1
- data/test/snapshots/functions/expected-output.txt +12 -5
- data/test/snapshots/functions_reflection/expected-output.txt +1 -0
- data/test/snapshots/hello_world/expected-output.txt +2 -0
- data/test/snapshots/import/expected-output.txt +3 -1
- data/test/snapshots/import2/expected-output.txt +6 -2
- data/test/snapshots/import_bookish/expected-output.txt +1 -0
- data/test/snapshots/mixin_booktool/expected-output.txt +1 -0
- data/test/snapshots/mixin_functions/expected-output.txt +12 -5
- data/test/snapshots/mixin_functions_class/expected-output.txt +12 -5
- data/test/snapshots/more_complex_vars/expected-output.txt +2 -0
- data/test/snapshots/more_functions/expected-output.txt +23 -10
- data/test/snapshots/multiple_functions/expected-output.txt +4 -1
- data/test/snapshots/nested_includes/expected-output.txt +26 -11
- data/test/snapshots/parameter_handling/expected-output.txt +4 -1
- data/test/snapshots/predef_vars/match-output.txt +8 -6
- data/test/snapshots/raw_lines/expected-output.txt +4 -1
- data/test/snapshots/raw_text_block/expected-output.txt +2 -0
- data/test/snapshots/simple_copy/expected-output.txt +2 -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/simple_import/expected-output.txt +6 -2
- data/test/snapshots/simple_include/expected-output.txt +3 -0
- data/test/snapshots/simple_mixin/expected-output.txt +2 -0
- data/test/snapshots/simple_vars/expected-output.txt +2 -0
- data/test/snapshots/single_raw_line/expected-output.txt +4 -1
- data/test/snapshots/system_info/match-output.txt +22 -18
- data/test/snapshots/table_with_heredocs/expected-output.txt +4 -1
- data/test/snapshots/var_into_func/expected-output.txt +12 -5
- data/test/unit/all.rb +1 -0
- data/test/unit/function_caller.rb +101 -0
- metadata +8 -6
- data/test/snapshots/system_info/actual-output.txt +0 -20
- data/test/snapshots/system_info/err-sdiff.txt +0 -1
- data/test/snapshots/system_info/expected-output.txt +0 -20
- /data/test/snapshots/{system_info/actual-error.txt → simple_func_api/expected-error.txt} +0 -0
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
|
@@ -188,6 +188,7 @@ class Livetext
|
|
188
188
|
break if line.nil?
|
189
189
|
process_line(line)
|
190
190
|
end
|
191
|
+
api.close_paragraph # Close any open paragraph
|
191
192
|
result = @body
|
192
193
|
# @body = ""
|
193
194
|
result
|
@@ -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/helpers.rb
CHANGED
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
|
@@ -188,15 +190,25 @@ class Livetext::UserAPI
|
|
188
190
|
return if @live.nopass
|
189
191
|
if line == "\n"
|
190
192
|
unless @live.nopara
|
191
|
-
out "<p>"
|
192
|
-
out
|
193
|
+
out "</p>\n\n<p>"
|
193
194
|
end
|
194
195
|
else
|
196
|
+
# Start first paragraph if needed
|
197
|
+
if @live.body.empty? && !@live.nopara
|
198
|
+
out "<p>"
|
199
|
+
end
|
195
200
|
text = @expander.format(line.chomp)
|
196
201
|
out text
|
197
202
|
end
|
198
203
|
end
|
199
204
|
|
205
|
+
def close_paragraph
|
206
|
+
return if @live.nopara
|
207
|
+
return if @live.body.empty?
|
208
|
+
return if @live.body.end_with?("</p>")
|
209
|
+
out "</p>"
|
210
|
+
end
|
211
|
+
|
200
212
|
def out(str = "", file = nil)
|
201
213
|
return if str.nil?
|
202
214
|
return file.puts str unless file.nil?
|
@@ -234,5 +246,9 @@ class Livetext::UserAPI
|
|
234
246
|
def debug(*args)
|
235
247
|
TTY.puts *args if @live.debug
|
236
248
|
end
|
249
|
+
|
250
|
+
def funcs
|
251
|
+
@funcs
|
252
|
+
end
|
237
253
|
end
|
238
254
|
|
data/lib/livetext/version.rb
CHANGED
@@ -1,13 +1,17 @@
|
|
1
|
+
<p>
|
1
2
|
Here are examples of <b>boldface</b>
|
2
3
|
and <i>italics</i>
|
3
4
|
and <tt>code</tt>
|
4
5
|
as well as <b>more complex</b> examples
|
5
6
|
of <i>italicized text</i>
|
6
7
|
and <tt>code font</tt>.
|
7
|
-
|
8
|
+
</p>
|
8
9
|
|
10
|
+
<p>
|
9
11
|
Here are some random punctuation marks:
|
10
12
|
; # . * _ ` : @ % ^ & $
|
11
|
-
|
13
|
+
</p>
|
12
14
|
|
15
|
+
<p>
|
13
16
|
No need to escape these: * _ `
|
17
|
+
</p>
|
@@ -1,12 +1,15 @@
|
|
1
|
+
<p>
|
1
2
|
Testing no parameters:
|
2
3
|
No parameters method called
|
3
|
-
|
4
|
+
</p>
|
4
5
|
|
6
|
+
<p>
|
5
7
|
Testing with args and data:
|
6
8
|
Args: ["arg1", "arg2"], Data: "arg1 arg2"
|
7
9
|
This is the data line
|
8
|
-
|
10
|
+
</p>
|
9
11
|
|
12
|
+
<p>
|
10
13
|
Testing with body:
|
11
14
|
Args: ["arg1", "arg2"], Data: "arg1 arg2"
|
12
15
|
Body has 3 lines:
|
@@ -19,3 +22,4 @@ Raw body has 3 lines:
|
|
19
22
|
1: This is line 1 of the raw body
|
20
23
|
2: This is line 2 of the raw body
|
21
24
|
3: This is line 3 of the raw body
|
25
|
+
</p>
|
@@ -1,6 +1,8 @@
|
|
1
|
-
Here is an alphabetized list:
|
2
1
|
<p>
|
2
|
+
Here is an alphabetized list:
|
3
|
+
</p>
|
3
4
|
|
5
|
+
<p>
|
4
6
|
aardvark
|
5
7
|
anamorphic
|
6
8
|
anarchist
|
@@ -18,6 +20,8 @@ Here is an alphabetized list:
|
|
18
20
|
quark
|
19
21
|
zootrope
|
20
22
|
zymurgy
|
21
|
-
|
23
|
+
</p>
|
22
24
|
|
25
|
+
<p>
|
23
26
|
That's all.
|
27
|
+
</p>
|
@@ -1,6 +1,8 @@
|
|
1
|
-
Here is an alphabetized list:
|
2
1
|
<p>
|
2
|
+
Here is an alphabetized list:
|
3
|
+
</p>
|
3
4
|
|
5
|
+
<p>
|
4
6
|
aardvark anamorphic anarchist
|
5
7
|
bellicose cytology ectomorph
|
6
8
|
fishmonger fusillade glyph
|
@@ -8,3 +10,4 @@ gryphon halcyon manicotti
|
|
8
10
|
mataeotechny pareidolia quark
|
9
11
|
zootrope zymurgy
|
10
12
|
And that is all.
|
13
|
+
</p>
|
@@ -1,20 +1,27 @@
|
|
1
|
+
<p>
|
1
2
|
Testing out
|
2
3
|
some functions
|
3
4
|
here...
|
4
|
-
|
5
|
+
</p>
|
5
6
|
|
7
|
+
<p>
|
6
8
|
I am calling Eureka! here...
|
7
9
|
Let's see
|
8
10
|
what happens.
|
9
|
-
|
11
|
+
</p>
|
10
12
|
|
13
|
+
<p>
|
11
14
|
Functions can take a parameter in brackets
|
12
15
|
(which it can parse itself as needed):
|
13
|
-
|
16
|
+
</p>
|
14
17
|
|
15
|
-
The result is 4.0 as I see it.
|
16
18
|
<p>
|
19
|
+
The result is 4.0 as I see it.
|
20
|
+
</p>
|
17
21
|
|
18
|
-
Some functions like date and time are predefined.
|
19
22
|
<p>
|
23
|
+
Some functions like date and time are predefined.
|
24
|
+
</p>
|
20
25
|
|
26
|
+
<p>
|
27
|
+
</p>
|
@@ -1,18 +1,25 @@
|
|
1
|
-
Testing functions defined in external .rb files
|
2
1
|
<p>
|
2
|
+
Testing functions defined in external .rb files
|
3
|
+
</p>
|
3
4
|
|
5
|
+
<p>
|
4
6
|
Now calling a function defined in the .rb file:
|
5
7
|
External function called with: test_parameter
|
6
|
-
|
8
|
+
</p>
|
7
9
|
|
10
|
+
<p>
|
8
11
|
And another one with brackets:
|
9
12
|
Another function called with: with brackets
|
10
|
-
|
13
|
+
</p>
|
11
14
|
|
15
|
+
<p>
|
12
16
|
And a function with no parameters:
|
13
17
|
Simple function with no parameters
|
14
|
-
|
18
|
+
</p>
|
15
19
|
|
16
|
-
That's all.
|
17
20
|
<p>
|
21
|
+
That's all.
|
22
|
+
</p>
|
18
23
|
|
24
|
+
<p>
|
25
|
+
</p>
|
@@ -1,20 +1,27 @@
|
|
1
|
-
Testing functions defined in Livetext::Functions class
|
2
1
|
<p>
|
2
|
+
Testing functions defined in Livetext::Functions class
|
3
|
+
</p>
|
3
4
|
|
5
|
+
<p>
|
4
6
|
Now calling functions defined in Livetext::Functions class:
|
5
7
|
Class function called with: test_parameter
|
6
|
-
|
8
|
+
</p>
|
7
9
|
|
10
|
+
<p>
|
8
11
|
And another one with brackets:
|
9
12
|
Another class function called with: with brackets
|
10
|
-
|
13
|
+
</p>
|
11
14
|
|
15
|
+
<p>
|
12
16
|
And a function with no parameters:
|
13
17
|
Simple class function with no parameters
|
14
|
-
|
18
|
+
</p>
|
15
19
|
|
20
|
+
<p>
|
16
21
|
Testing that the functions have access to Livetext::Vars:
|
17
22
|
Vars test: param=some_value, View=[View is undefined]
|
18
|
-
|
23
|
+
</p>
|
19
24
|
|
25
|
+
<p>
|
20
26
|
That's all.
|
27
|
+
</p>
|
@@ -1,37 +1,50 @@
|
|
1
|
-
Testing some more functions here...
|
2
1
|
<p>
|
2
|
+
Testing some more functions here...
|
3
|
+
</p>
|
3
4
|
|
5
|
+
<p>
|
4
6
|
Here I am calling a function with
|
5
7
|
a colon parameter...
|
6
|
-
|
8
|
+
</p>
|
7
9
|
|
8
10
|
<p>
|
11
|
+
</p>
|
9
12
|
|
10
|
-
Next let's <b>do</b> something with our parameter:
|
11
13
|
<p>
|
14
|
+
Next let's <b>do</b> something with our parameter:
|
15
|
+
</p>
|
12
16
|
|
13
|
-
I'll call these variants...
|
14
17
|
<p>
|
18
|
+
I'll call these variants...
|
19
|
+
</p>
|
15
20
|
|
16
|
-
"Motel" spelled backwards is letom :)
|
17
21
|
<p>
|
22
|
+
"Motel" spelled backwards is letom :)
|
23
|
+
</p>
|
18
24
|
|
19
|
-
"lamina" reversed is animal
|
20
25
|
<p>
|
26
|
+
"lamina" reversed is animal
|
27
|
+
</p>
|
21
28
|
|
22
|
-
I can also use the erutaef tekcarb here.
|
23
29
|
<p>
|
30
|
+
I can also use the erutaef tekcarb here.
|
31
|
+
</p>
|
24
32
|
|
33
|
+
<p>
|
25
34
|
If I don't use a parameter for [Error evaluating $$reverse()] - it gives
|
26
35
|
me an error. (Bug or feature??)
|
27
|
-
|
36
|
+
</p>
|
28
37
|
|
38
|
+
<p>
|
29
39
|
What if a function doesn't use parameters at all, but
|
30
40
|
we pass them? Hmm...
|
31
|
-
|
41
|
+
</p>
|
32
42
|
|
43
|
+
<p>
|
33
44
|
Now we succeed and succeed some more
|
34
45
|
and finally we succeed in life.
|
35
|
-
|
46
|
+
</p>
|
36
47
|
|
48
|
+
<p>
|
37
49
|
But can we succeed, when our beds are burning?
|
50
|
+
</p>
|
@@ -1,68 +1,83 @@
|
|
1
|
+
<p>
|
1
2
|
# Main file - Level 1
|
2
3
|
# This file includes level2 and tests all variables and functions from all levels
|
3
|
-
|
4
|
+
</p>
|
4
5
|
|
6
|
+
<p>
|
5
7
|
# Include level2 (which includes level3)
|
6
8
|
# Level 2 - Middle level
|
7
9
|
# This file includes level3 and defines its own variables and functions
|
8
|
-
|
10
|
+
</p>
|
9
11
|
|
12
|
+
<p>
|
10
13
|
# Level 3 - Deepest level
|
11
14
|
# This file defines variables and functions that should be accessible to all higher levels
|
12
|
-
|
15
|
+
</p>
|
13
16
|
|
17
|
+
<p>
|
14
18
|
This is content from level 3.
|
15
19
|
The deep variable is: I am from level 3
|
16
20
|
The deep number is: 42
|
21
|
+
</p>
|
17
22
|
This is content from level 2.
|
18
23
|
The middle variable is: I am from level 2
|
19
24
|
The middle number is: 100
|
20
|
-
|
25
|
+
</p>
|
21
26
|
|
27
|
+
<p>
|
22
28
|
# Test using deep level variables and functions
|
23
29
|
Deep variable from level 2: I am from level 3
|
24
30
|
Deep function call: Deep function called with: from level 2
|
25
31
|
Deep math: 42 = 42
|
26
|
-
|
32
|
+
</p>
|
27
33
|
|
34
|
+
<p>
|
28
35
|
# Test our own variables and functions
|
29
36
|
Middle function call: Middle function called with: from level 2
|
30
37
|
Combined variables: Deep: I am from level 3, Middle: I am from level 2
|
31
|
-
|
38
|
+
</p>
|
32
39
|
|
40
|
+
<p>
|
33
41
|
# Test deep method from level 3
|
34
42
|
Deep method called from level 3
|
43
|
+
</p>
|
35
44
|
# Test all variables from all levels
|
36
45
|
Main variable: I am from main level
|
37
46
|
Middle variable: I am from level 2
|
38
47
|
Deep variable: I am from level 3
|
39
|
-
|
48
|
+
</p>
|
40
49
|
|
50
|
+
<p>
|
41
51
|
# Test all functions from all levels
|
42
52
|
Main function: Main function called with: from main
|
43
53
|
Middle function: Middle function called with: from main
|
44
54
|
Deep function: Deep function called with: from main
|
45
|
-
|
55
|
+
</p>
|
46
56
|
|
57
|
+
<p>
|
47
58
|
# Test math functions
|
48
59
|
Deep math: 20 = 20
|
49
60
|
Main number: 999
|
50
61
|
Middle number: 100
|
51
62
|
Deep number: 42
|
52
|
-
|
63
|
+
</p>
|
53
64
|
|
65
|
+
<p>
|
54
66
|
# Test combined functions
|
55
67
|
Combine vars: Deep: I am from level 3, Middle: I am from level 2
|
56
68
|
Test all levels: Main: I am from main level, Middle: I am from level 2, Deep: I am from level 3
|
57
|
-
|
69
|
+
</p>
|
58
70
|
|
71
|
+
<p>
|
59
72
|
# Test methods from all levels
|
60
73
|
Main method called from main level
|
61
74
|
Middle method called from level 2
|
62
75
|
Deep method called from level 3
|
63
|
-
|
76
|
+
</p>
|
64
77
|
|
78
|
+
<p>
|
65
79
|
# Test that we can still access everything after the include
|
66
80
|
Final test - deep function: Deep function called with: final call
|
67
81
|
Final test - middle function: Middle function called with: final call
|
68
82
|
Final test - main function: Main function called with: final call
|
83
|
+
</p>
|
@@ -1,6 +1,8 @@
|
|
1
|
-
1
|
2
|
-
2
|
3
|
-
3
|
4
|
-
4 /
|
5
|
-
5 /
|
6
|
-
6
|
1
|
+
1 <p>
|
2
|
+
2 Here we go...
|
3
|
+
3 File = source.lt3
|
4
|
+
4 /FileDir = .*.test.snapshots.predef_vars/
|
5
|
+
5 /User = [A-Za-z][A-Za-z0-9]*/
|
6
|
+
6 /Version = 0\.\d{1,2}\.\d{1,2}/
|
7
|
+
7 NoSuchVar = [NoSuchVar is undefined]
|
8
|
+
8 </p>
|
@@ -1,7 +1,9 @@
|
|
1
|
+
<p>
|
1
2
|
The .r can be used to output single lines
|
2
3
|
without interpretation:
|
3
|
-
|
4
|
+
</p>
|
4
5
|
|
6
|
+
<p>
|
5
7
|
Ordinary line... plus two blank lines:
|
6
8
|
|
7
9
|
|
@@ -9,3 +11,4 @@ No formatting: *foo `foo _foo ~foo
|
|
9
11
|
No variables: $alpha $beta
|
10
12
|
No functions: $$this $$that
|
11
13
|
That's all.
|
14
|
+
</p>
|
@@ -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
|
@@ -1,18 +1,22 @@
|
|
1
|
-
1
|
2
|
-
2
|
3
|
-
3
|
4
|
-
4 /
|
5
|
-
5
|
6
|
-
6
|
7
|
-
7
|
8
|
-
8
|
9
|
-
9
|
10
|
-
10
|
11
|
-
11
|
12
|
-
12
|
13
|
-
13
|
14
|
-
14
|
15
|
-
15
|
16
|
-
16
|
17
|
-
17
|
18
|
-
18
|
1
|
+
1 <p>
|
2
|
+
2 System Info Variables:
|
3
|
+
3 Hostname: HAL9000
|
4
|
+
4 /Platform: .*x86_64-darwin\d+/
|
5
|
+
5 /Ruby Version: \d+\.\d+\.\d+/
|
6
|
+
6 Livetext Version: 0.9.60
|
7
|
+
7 </p>
|
8
|
+
8
|
9
|
+
9 <p>
|
10
|
+
10 System Info Functions:
|
11
|
+
11 Hostname: HAL9000
|
12
|
+
12 /Platform: .*x86_64-darwin\d+/
|
13
|
+
13 /Ruby Version: \d+\.\d+\.\d+/
|
14
|
+
14 /Livetext Version: \d+\.\d+\.\d+/
|
15
|
+
15 </p>
|
16
|
+
16
|
17
|
+
17 <p>
|
18
|
+
18 Date Formatting Functions:
|
19
|
+
19 /Default: \d{4}-\d{2}-\d{2}/
|
20
|
+
20 /Days ago: \d{4}-\d{2}-\d{2}/
|
21
|
+
21 /Days from now: \d{4}-\d{2}-\d{2}/
|
22
|
+
22 </p>
|
@@ -1,16 +1,23 @@
|
|
1
|
-
|
1
|
+
</p>
|
2
2
|
|
3
|
-
Testing STILL more functions here...
|
4
3
|
<p>
|
4
|
+
Testing STILL more functions here...
|
5
|
+
</p>
|
5
6
|
|
6
7
|
<p>
|
8
|
+
</p>
|
7
9
|
|
8
|
-
Now... let's try passing a variable to a function. Will this work??
|
9
10
|
<p>
|
11
|
+
Now... let's try passing a variable to a function. Will this work??
|
12
|
+
</p>
|
10
13
|
|
11
|
-
Variable $alpha is regal, which reversed is lager
|
12
14
|
<p>
|
15
|
+
Variable $alpha is regal, which reversed is lager
|
16
|
+
</p>
|
13
17
|
|
14
|
-
That's all.
|
15
18
|
<p>
|
19
|
+
That's all.
|
20
|
+
</p>
|
16
21
|
|
22
|
+
<p>
|
23
|
+
</p>
|
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
|
@@ -216,11 +221,7 @@ files:
|
|
216
221
|
- test/snapshots/single_raw_line/expected-output.txt
|
217
222
|
- test/snapshots/single_raw_line/source.lt3
|
218
223
|
- test/snapshots/subset.txt
|
219
|
-
- test/snapshots/system_info/actual-error.txt
|
220
|
-
- test/snapshots/system_info/actual-output.txt
|
221
|
-
- test/snapshots/system_info/err-sdiff.txt
|
222
224
|
- test/snapshots/system_info/expected-error.txt
|
223
|
-
- test/snapshots/system_info/expected-output.txt
|
224
225
|
- test/snapshots/system_info/match-output.txt
|
225
226
|
- test/snapshots/system_info/source.lt3
|
226
227
|
- test/snapshots/table_with_heredocs/expected-error.txt
|
@@ -240,6 +241,7 @@ files:
|
|
240
241
|
- test/unit/double.rb
|
241
242
|
- test/unit/formatter.rb
|
242
243
|
- test/unit/formatter_component.rb
|
244
|
+
- test/unit/function_caller.rb
|
243
245
|
- test/unit/function_registry.rb
|
244
246
|
- test/unit/functions.rb
|
245
247
|
- test/unit/html.rb
|
@@ -1,20 +0,0 @@
|
|
1
|
-
System Info Variables:
|
2
|
-
Hostname: HAL9000
|
3
|
-
Platform: x86_64-darwin22
|
4
|
-
Ruby Version: 3.2.3
|
5
|
-
Livetext Version: 0.9.58
|
6
|
-
</p>
|
7
|
-
|
8
|
-
<p>
|
9
|
-
System Info Functions:
|
10
|
-
Hostname: HAL9000
|
11
|
-
Platform: x86_64-darwin22
|
12
|
-
Ruby Version: 3.2.3
|
13
|
-
Livetext Version: 0.9.58
|
14
|
-
</p>
|
15
|
-
|
16
|
-
<p>
|
17
|
-
Date Formatting Functions:
|
18
|
-
Default: 2025-09-06
|
19
|
-
Days ago: 2025-08-30
|
20
|
-
Days from now: 2025-09-13
|
@@ -1 +0,0 @@
|
|
1
|
-
ACTUAL | EXPECTED
|
@@ -1,20 +0,0 @@
|
|
1
|
-
System Info Variables:
|
2
|
-
Hostname: HAL9000
|
3
|
-
Platform: x86_64-darwin22
|
4
|
-
Ruby Version: 3.2.3
|
5
|
-
Livetext Version: 0.9.58
|
6
|
-
</p>
|
7
|
-
|
8
|
-
<p>
|
9
|
-
System Info Functions:
|
10
|
-
Hostname: HAL9000
|
11
|
-
Platform: x86_64-darwin22
|
12
|
-
Ruby Version: 3.2.3
|
13
|
-
Livetext Version: 0.9.58
|
14
|
-
</p>
|
15
|
-
|
16
|
-
<p>
|
17
|
-
Date Formatting Functions:
|
18
|
-
Default: 2025-09-06
|
19
|
-
Days ago: 2025-08-30
|
20
|
-
Days from now: 2025-09-13
|
File without changes
|