livetext 0.9.51 → 0.9.55
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/imports/bookish.rb +3 -3
- data/lib/livetext/core.rb +108 -53
- data/lib/livetext/expansion.rb +25 -9
- data/lib/livetext/formatter.rb +149 -162
- data/lib/livetext/formatter_component.rb +189 -0
- data/lib/livetext/function_registry.rb +163 -0
- data/lib/livetext/handler/mixin.rb +25 -0
- data/lib/livetext/helpers.rb +25 -7
- data/lib/livetext/reopen.rb +2 -0
- data/lib/livetext/skeleton.rb +0 -3
- data/lib/livetext/standard.rb +118 -70
- data/lib/livetext/variable_manager.rb +65 -0
- data/lib/livetext/variables.rb +4 -0
- data/lib/livetext/version.rb +1 -1
- data/lib/livetext.rb +9 -3
- data/plugin/booktool.rb +8 -8
- data/test/extra/testgen.rb +1 -3
- data/test/snapshots/complex_body/expected-error.txt +0 -0
- data/test/snapshots/complex_body/expected-output.txt +8 -0
- data/test/snapshots/complex_body/source.lt3 +19 -0
- data/test/snapshots/debug_command/expected-error.txt +0 -0
- data/test/snapshots/debug_command/expected-output.txt +1 -0
- data/test/snapshots/debug_command/source.lt3 +3 -0
- data/test/snapshots/def_parameters/expected-error.txt +0 -0
- data/test/snapshots/def_parameters/expected-output.txt +21 -0
- data/test/snapshots/def_parameters/source.lt3 +44 -0
- data/test/snapshots/functions_reflection/expected-error.txt +0 -0
- data/test/snapshots/functions_reflection/expected-output.txt +27 -0
- data/test/snapshots/functions_reflection/source.lt3 +5 -0
- data/test/snapshots/mixin_functions/expected-error.txt +0 -0
- data/test/snapshots/mixin_functions/expected-output.txt +18 -0
- data/test/snapshots/mixin_functions/mixin_functions.rb +11 -0
- data/test/snapshots/mixin_functions/source.lt3 +15 -0
- data/test/snapshots/multiple_functions/expected-error.txt +0 -0
- data/test/snapshots/multiple_functions/expected-output.txt +5 -0
- data/test/snapshots/multiple_functions/source.lt3 +16 -0
- data/test/snapshots/nested_includes/expected-error.txt +0 -0
- data/test/snapshots/nested_includes/expected-output.txt +68 -0
- data/test/snapshots/nested_includes/level2.inc +34 -0
- data/test/snapshots/nested_includes/level3.inc +20 -0
- data/test/snapshots/nested_includes/source.lt3 +49 -0
- data/test/snapshots/parameter_handling/expected-error.txt +0 -0
- data/test/snapshots/parameter_handling/expected-output.txt +7 -0
- data/test/snapshots/parameter_handling/source.lt3 +10 -0
- data/test/snapshots/subset.txt +1 -0
- data/test/snapshots/system_info/expected-error.txt +0 -0
- data/test/snapshots/system_info/expected-output.txt +18 -0
- data/test/snapshots/system_info/source.lt3 +16 -0
- data/test/snapshots.rb +3 -4
- data/test/test_escape.lt3 +1 -0
- data/test/unit/all.rb +4 -0
- data/test/unit/bracketed.rb +2 -2
- data/test/unit/core_methods.rb +137 -0
- data/test/unit/double.rb +1 -3
- data/test/unit/formatter.rb +84 -0
- data/test/unit/formatter_component.rb +84 -0
- data/test/unit/function_registry.rb +132 -0
- data/test/unit/functions.rb +2 -2
- data/test/unit/html.rb +2 -2
- data/test/unit/parser/general.rb +2 -2
- data/test/unit/parser/mixin.rb +2 -2
- data/test/unit/parser/set.rb +2 -2
- data/test/unit/parser/string.rb +2 -2
- data/test/unit/single.rb +1 -3
- data/test/unit/standard.rb +1 -3
- data/test/unit/stringparser.rb +2 -2
- data/test/unit/variable_manager.rb +71 -0
- data/test/unit/variables.rb +2 -2
- metadata +41 -3
- data/lib/livetext/processor.rb +0 -88
@@ -0,0 +1,189 @@
|
|
1
|
+
# Formatter - Centralized text formatting for Livetext
|
2
|
+
class Livetext::Formatter
|
3
|
+
def initialize(parent)
|
4
|
+
@parent = parent
|
5
|
+
end
|
6
|
+
|
7
|
+
def format(text)
|
8
|
+
return "" if text.nil? || text.empty?
|
9
|
+
|
10
|
+
text = text.chomp
|
11
|
+
# First, mark escaped characters so they won't be processed as formatting
|
12
|
+
text = mark_escaped_characters(text)
|
13
|
+
|
14
|
+
# Process all marker types in sequence
|
15
|
+
text = handle_double_markers(text)
|
16
|
+
text = handle_bracketed_markers(text)
|
17
|
+
text = handle_single_markers(text)
|
18
|
+
text = handle_underscore_markers(text)
|
19
|
+
text = handle_backtick_markers(text)
|
20
|
+
text = handle_tilde_markers(text)
|
21
|
+
|
22
|
+
text = unmark_escaped_characters(text)
|
23
|
+
text
|
24
|
+
end
|
25
|
+
|
26
|
+
def format_line(line)
|
27
|
+
return "" if line.nil?
|
28
|
+
format(line.chomp)
|
29
|
+
end
|
30
|
+
|
31
|
+
def format_multiple(lines)
|
32
|
+
lines.map { |line| format_line(line) }
|
33
|
+
end
|
34
|
+
|
35
|
+
# Convenience methods for common formatting patterns
|
36
|
+
def bold(text)
|
37
|
+
"<b>#{text}</b>"
|
38
|
+
end
|
39
|
+
|
40
|
+
def italic(text)
|
41
|
+
"<i>#{text}</i>"
|
42
|
+
end
|
43
|
+
|
44
|
+
def code(text)
|
45
|
+
"<tt>#{text}</tt>"
|
46
|
+
end
|
47
|
+
|
48
|
+
def strike(text)
|
49
|
+
"<strike>#{text}</strike>"
|
50
|
+
end
|
51
|
+
|
52
|
+
def link(text, url)
|
53
|
+
"<a href='#{url}'>#{text}</a>"
|
54
|
+
end
|
55
|
+
|
56
|
+
def escape_html(text)
|
57
|
+
text.gsub(/[&<>"']/) do |char|
|
58
|
+
case char
|
59
|
+
when '&' then '&'
|
60
|
+
when '<' then '<'
|
61
|
+
when '>' then '>'
|
62
|
+
when '"' then '"'
|
63
|
+
when "'" then '''
|
64
|
+
else char
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def mark_escaped_characters(str)
|
72
|
+
# Replace escaped characters with a null byte marker (safe for internal use)
|
73
|
+
str.gsub(/\\([*_`~])/, "\u0000\\1")
|
74
|
+
end
|
75
|
+
|
76
|
+
def unmark_escaped_characters(str)
|
77
|
+
# Restore escaped characters
|
78
|
+
str.gsub(/\u0000([*_`~])/, '\1')
|
79
|
+
end
|
80
|
+
|
81
|
+
def handle_double_markers(str)
|
82
|
+
# **word -> <b>word</b> (terminated by space, comma, period)
|
83
|
+
# But ignore standalone ** or ** surrounded by spaces
|
84
|
+
str.gsub(/(?<=\s|^)\*\*([^\s,.]*)/) do |match|
|
85
|
+
if $1.empty?
|
86
|
+
"**" # standalone ** should be literal
|
87
|
+
else
|
88
|
+
"<b>#{$1}</b>"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def handle_bracketed_markers(str)
|
94
|
+
# Handle all bracketed markers: *[content], _[content], `[content]
|
95
|
+
# *[content] -> <b>content</b>
|
96
|
+
# _[content] -> <i>content</i>
|
97
|
+
# `[content] -> <tt>content</tt>
|
98
|
+
# And handle unclosed brackets with end-of-line termination
|
99
|
+
# Empty brackets disappear
|
100
|
+
# But ignore if the marker was originally escaped
|
101
|
+
# And ignore embedded markers (like abc*[)
|
102
|
+
|
103
|
+
# First handle complete brackets for all marker types
|
104
|
+
str = str.gsub(/(?<!\u0000)([*_`])\[([^\]]*)\]/) do |match|
|
105
|
+
marker, content = $1, $2
|
106
|
+
if content.empty?
|
107
|
+
"" # empty brackets disappear
|
108
|
+
else
|
109
|
+
case marker
|
110
|
+
when "*" then "<b>#{content}</b>"
|
111
|
+
when "_" then "<i>#{content}</i>"
|
112
|
+
when "`" then "<tt>#{content}</tt>"
|
113
|
+
else match # fallback
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# Then handle unclosed brackets (end of line replaces closing bracket)
|
119
|
+
# But only if it's at start of line or preceded by whitespace
|
120
|
+
str = str.gsub(/(?<!\u0000)(?<=\s|^)([*_`])\[([^\]]*)$/) do |match|
|
121
|
+
marker, content = $1, $2
|
122
|
+
if content.empty?
|
123
|
+
"" # standalone marker[ disappears
|
124
|
+
else
|
125
|
+
case marker
|
126
|
+
when "*" then "<b>#{content}</b>"
|
127
|
+
when "_" then "<i>#{content}</i>"
|
128
|
+
when "`" then "<tt>#{content}</tt>"
|
129
|
+
else match # fallback
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
str
|
135
|
+
end
|
136
|
+
|
137
|
+
def handle_single_markers(str)
|
138
|
+
# *word -> <b>word</b> (only at start of word or after space)
|
139
|
+
# But ignore standalone * or * surrounded by spaces
|
140
|
+
# Also ignore * that are part of ** patterns (already processed)
|
141
|
+
# And ignore * that are part of *[ patterns (already processed)
|
142
|
+
str.gsub(/(?<=\s|^)\*(?!\[)([^\s]*)/) do |match|
|
143
|
+
if $1.empty?
|
144
|
+
"*" # standalone * should be literal
|
145
|
+
elsif $1.start_with?('*')
|
146
|
+
# This is part of a ** pattern, leave it as literal
|
147
|
+
match
|
148
|
+
else
|
149
|
+
"<b>#{$1}</b>"
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def handle_underscore_markers(str)
|
155
|
+
# _word -> <i>word</i> (only at start of word or after space)
|
156
|
+
# But ignore standalone _ or _ surrounded by spaces
|
157
|
+
str.gsub(/(?<=\s|^)_([^\s]*)/) do |match|
|
158
|
+
if $1.empty?
|
159
|
+
"_" # standalone _ should be literal
|
160
|
+
else
|
161
|
+
"<i>#{$1}</i>"
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def handle_backtick_markers(str)
|
167
|
+
# `word -> <tt>word</tt> (only at start of word or after space)
|
168
|
+
# But ignore standalone ` or ` surrounded by spaces
|
169
|
+
str.gsub(/(?<=\s|^)`([^\s]*)/) do |match|
|
170
|
+
if $1.empty?
|
171
|
+
"`" # standalone ` should be literal
|
172
|
+
else
|
173
|
+
"<tt>#{$1}</tt>"
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def handle_tilde_markers(str)
|
179
|
+
# ~word -> <strike>word</strike> (only at start of word or after space)
|
180
|
+
# But ignore standalone ~ or ~ surrounded by spaces
|
181
|
+
str.gsub(/(?<=\s|^)~([^\s]*)/) do |match|
|
182
|
+
if $1.empty?
|
183
|
+
"~" # standalone ~ should be literal
|
184
|
+
else
|
185
|
+
"<strike>#{$1}</strike>"
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
@@ -0,0 +1,163 @@
|
|
1
|
+
# Function Registry - Unified function management for Livetext
|
2
|
+
class Livetext::FunctionRegistry
|
3
|
+
def initialize
|
4
|
+
@user_functions = {}
|
5
|
+
@builtin_functions = {}
|
6
|
+
@metadata = {}
|
7
|
+
register_builtin_functions
|
8
|
+
puts "DEBUG: Registered #{@builtin_functions.size} builtin functions" if ENV['DEBUG']
|
9
|
+
end
|
10
|
+
|
11
|
+
def register_user(name, function, source: :inline, filename: nil)
|
12
|
+
name_sym = name.to_sym
|
13
|
+
@user_functions[name_sym] = function
|
14
|
+
@metadata[name_sym] = { source: source, filename: filename }
|
15
|
+
end
|
16
|
+
|
17
|
+
def register_builtin(name, function)
|
18
|
+
@builtin_functions[name] = function
|
19
|
+
@metadata[name] = { source: :builtin, filename: "builtin" }
|
20
|
+
end
|
21
|
+
|
22
|
+
def call(name, param)
|
23
|
+
# Convert name to symbol for consistent lookup
|
24
|
+
name_sym = name.to_sym
|
25
|
+
|
26
|
+
if @user_functions[name_sym]
|
27
|
+
call_function(name, @user_functions[name_sym], param)
|
28
|
+
elsif @builtin_functions[name_sym]
|
29
|
+
call_function(name, @builtin_functions[name_sym], param)
|
30
|
+
else
|
31
|
+
"[Error evaluating $$#{name}(#{param})]"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def list_functions
|
36
|
+
result = []
|
37
|
+
@user_functions.each { |name, _| result << { name: name.to_s, source: get_source(name) } }
|
38
|
+
@builtin_functions.each { |name, _| result << { name: name.to_s, source: get_source(name) } }
|
39
|
+
result.sort_by { |f| f[:name] }
|
40
|
+
end
|
41
|
+
|
42
|
+
def get_function_info(name)
|
43
|
+
name_sym = name.to_sym
|
44
|
+
metadata = @metadata[name_sym]
|
45
|
+
return nil unless metadata
|
46
|
+
|
47
|
+
{
|
48
|
+
name: name.to_s,
|
49
|
+
source: get_source(name),
|
50
|
+
filename: metadata[:filename],
|
51
|
+
type: @user_functions.key?(name_sym) ? :user : :builtin
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
def function_exists?(name)
|
56
|
+
name_sym = name.to_sym
|
57
|
+
@user_functions.key?(name_sym) || @builtin_functions.key?(name_sym)
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def call_function(name, function, param)
|
63
|
+
function.call(param)
|
64
|
+
rescue => e
|
65
|
+
"[Error evaluating $$#{name}(#{param})]"
|
66
|
+
end
|
67
|
+
|
68
|
+
def get_source(name)
|
69
|
+
name_sym = name.to_sym
|
70
|
+
metadata = @metadata[name_sym]
|
71
|
+
case metadata[:source]
|
72
|
+
when :inline then "inline (#{metadata[:filename] || 'unknown'})"
|
73
|
+
when :mixin then "mixin (#{metadata[:filename] || 'unknown'})"
|
74
|
+
when :builtin then "builtin"
|
75
|
+
else "unknown"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def register_builtin_functions
|
80
|
+
# Move all current Livetext::Functions methods here
|
81
|
+
register_builtin(:date, ->(param) { Time.now.strftime("%F") })
|
82
|
+
register_builtin(:time, ->(param) { Time.now.strftime("%T") })
|
83
|
+
register_builtin(:pwd, ->(param) { Dir.pwd })
|
84
|
+
register_builtin(:rand, ->(param) do
|
85
|
+
if param && !param.empty?
|
86
|
+
n1, n2 = param.split.map(&:to_i)
|
87
|
+
Kernel.rand(n1..n2).to_s
|
88
|
+
else
|
89
|
+
Kernel.rand.to_s
|
90
|
+
end
|
91
|
+
end)
|
92
|
+
register_builtin(:link, ->(param) do
|
93
|
+
if param && param.include?("|")
|
94
|
+
text, url = param.split("|", 2)
|
95
|
+
"<a style='text-decoration: none' href='#{url}'>#{text}</a>"
|
96
|
+
else
|
97
|
+
"[Error in function $$link: expected 'text|url' format]"
|
98
|
+
end
|
99
|
+
end)
|
100
|
+
register_builtin(:br, ->(param) do
|
101
|
+
n = (param || "1").to_i
|
102
|
+
"<br>" * n
|
103
|
+
end)
|
104
|
+
register_builtin(:reverse, ->(param) do
|
105
|
+
if param && !param.empty?
|
106
|
+
param.reverse
|
107
|
+
else
|
108
|
+
"(reverse: No parameter)"
|
109
|
+
end
|
110
|
+
end)
|
111
|
+
register_builtin(:isqrt, ->(param) do
|
112
|
+
arg = num = param
|
113
|
+
if num.nil? || num.empty?
|
114
|
+
arg = "NO PARAM"
|
115
|
+
end
|
116
|
+
num = num.include?(".") ? Float(num) : Integer(num)
|
117
|
+
Math.sqrt(num).to_i.to_s
|
118
|
+
rescue => err
|
119
|
+
"[Error evaluating $$isqrt(#{arg})]"
|
120
|
+
end)
|
121
|
+
|
122
|
+
# System info functions (return current values)
|
123
|
+
register_builtin(:hostname, ->(param) { `hostname`.chomp })
|
124
|
+
register_builtin(:platform, ->(param) { RUBY_PLATFORM })
|
125
|
+
register_builtin(:ruby_version, ->(param) { RUBY_VERSION })
|
126
|
+
register_builtin(:livetext_version, ->(param) { Livetext::VERSION })
|
127
|
+
|
128
|
+
# Date/time functions
|
129
|
+
register_builtin(:year, ->(param) { Time.now.year.to_s })
|
130
|
+
register_builtin(:month, ->(param) { Time.now.mon.to_s })
|
131
|
+
register_builtin(:day, ->(param) { Time.now.day.to_s })
|
132
|
+
register_builtin(:hour, ->(param) { Time.now.hour.to_s })
|
133
|
+
register_builtin(:minute, ->(param) { Time.now.min.to_s })
|
134
|
+
register_builtin(:second, ->(param) { Time.now.sec.to_s })
|
135
|
+
register_builtin(:weekday, ->(param) { Time.now.wday.to_s })
|
136
|
+
register_builtin(:week, ->(param) { Time.now.strftime("%U") })
|
137
|
+
|
138
|
+
# Date formatting functions
|
139
|
+
register_builtin(:format_date, ->(param) do
|
140
|
+
if param && !param.empty?
|
141
|
+
Time.now.strftime(param)
|
142
|
+
else
|
143
|
+
Time.now.strftime("%F") # Default format
|
144
|
+
end
|
145
|
+
end)
|
146
|
+
register_builtin(:days_ago, ->(param) do
|
147
|
+
if param && !param.empty?
|
148
|
+
days = param.to_i
|
149
|
+
(Time.now - (days * 24 * 60 * 60)).strftime("%F")
|
150
|
+
else
|
151
|
+
"[Error evaluating $$days_ago: requires number of days]"
|
152
|
+
end
|
153
|
+
end)
|
154
|
+
register_builtin(:days_from_now, ->(param) do
|
155
|
+
if param && !param.empty?
|
156
|
+
days = param.to_i
|
157
|
+
(Time.now + (days * 24 * 60 * 60)).strftime("%F")
|
158
|
+
else
|
159
|
+
"[Error evaluating $$days_from_now: requires number of days]"
|
160
|
+
end
|
161
|
+
end)
|
162
|
+
end
|
163
|
+
end
|
@@ -24,6 +24,10 @@ class Livetext::Handler::Mixin
|
|
24
24
|
# STDERR.puts "After eval"
|
25
25
|
newmod = Object.const_get("::" + modname)
|
26
26
|
# STDERR.puts "After const_get"
|
27
|
+
|
28
|
+
# Register functions from the mixin with the registry
|
29
|
+
handler.register_mixin_functions(newmod, parent)
|
30
|
+
|
27
31
|
newmod # return actual module
|
28
32
|
end
|
29
33
|
|
@@ -33,5 +37,26 @@ class Livetext::Handler::Mixin
|
|
33
37
|
[modname, "module ::#{modname}; #{meths}\nend"]
|
34
38
|
end
|
35
39
|
|
40
|
+
def register_mixin_functions(module_obj, parent)
|
41
|
+
# Get all instance methods from the module
|
42
|
+
methods = module_obj.instance_methods(false)
|
43
|
+
|
44
|
+
methods.each do |method_name|
|
45
|
+
# Create a lambda that calls the method on the parent (Livetext instance)
|
46
|
+
function = ->(param) do
|
47
|
+
# Check if the method expects parameters
|
48
|
+
method = parent.method(method_name)
|
49
|
+
if method.parameters.empty?
|
50
|
+
parent.send(method_name)
|
51
|
+
else
|
52
|
+
parent.send(method_name, param)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Register with the function registry
|
57
|
+
parent.function_registry.register_user(method_name.to_s, function, source: :mixin, filename: @file)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
36
61
|
end
|
37
62
|
|
data/lib/livetext/helpers.rb
CHANGED
@@ -81,15 +81,15 @@ module Livetext::Helpers
|
|
81
81
|
text = File.readlines(fname)
|
82
82
|
enum = text.each
|
83
83
|
@backtrace = btrace
|
84
|
-
|
84
|
+
source(enum, fname, 0)
|
85
85
|
line = nil
|
86
86
|
loop do
|
87
|
-
line =
|
87
|
+
line = nextline
|
88
88
|
break if line.nil?
|
89
89
|
success = process_line(line)
|
90
90
|
break unless success
|
91
91
|
end
|
92
|
-
val =
|
92
|
+
val = finalize rescue nil
|
93
93
|
@body # FIXME? @body.join("\n") # array
|
94
94
|
return true
|
95
95
|
end
|
@@ -125,7 +125,25 @@ module Livetext::Helpers
|
|
125
125
|
api.data = data0.dup # should permit _ in function names at least
|
126
126
|
args0 = data0.split
|
127
127
|
api.args = args0.dup
|
128
|
-
|
128
|
+
# Get method signature to determine what parameters to pass
|
129
|
+
method = method(name)
|
130
|
+
param_count = method.parameters.length
|
131
|
+
|
132
|
+
# Pass parameters based on method signature
|
133
|
+
case param_count
|
134
|
+
when 0
|
135
|
+
retval = send(name)
|
136
|
+
when 2
|
137
|
+
retval = send(name, args0, data0)
|
138
|
+
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)
|
144
|
+
else
|
145
|
+
retval = send(name) # fallback to no parameters
|
146
|
+
end
|
129
147
|
retval
|
130
148
|
rescue => err
|
131
149
|
graceful_error(err) # , "#{__method__}: name = #{name}")
|
@@ -139,7 +157,7 @@ module Livetext::Helpers
|
|
139
157
|
case
|
140
158
|
when name == :end # special case
|
141
159
|
graceful_error EndWithoutOpening()
|
142
|
-
when
|
160
|
+
when respond_to?(name)
|
143
161
|
success = invoke_dotcmd(name, data) # was 141
|
144
162
|
else
|
145
163
|
graceful_error UnknownMethod(name)
|
@@ -162,8 +180,8 @@ module Livetext::Helpers
|
|
162
180
|
data0 = ""
|
163
181
|
end
|
164
182
|
name = "dot_" + name if %w[include def].include?(name)
|
165
|
-
|
166
|
-
|
183
|
+
check_disallowed(name)
|
184
|
+
api.data = data0 # FIXME kill this?
|
167
185
|
[name.to_sym, data0]
|
168
186
|
end
|
169
187
|
|
data/lib/livetext/reopen.rb
CHANGED