livetext 0.9.23 → 0.9.26
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.lt3 +6 -6
- data/bin/livetext +57 -40
- data/imports/bookish.rb +81 -81
- data/imports/calibre.rb +3 -3
- data/imports/livemagick.rb +17 -17
- data/imports/markdown.rb +10 -10
- data/imports/pyggish.rb +13 -13
- data/imports/tutorial.rb +15 -15
- data/lib/cmdargs.rb +7 -4
- data/lib/{errors.rb → livetext/errors.rb} +4 -3
- data/lib/{formatline.rb → livetext/formatline.rb} +119 -18
- data/lib/livetext/funcall.rb +168 -0
- data/lib/{functions.rb → livetext/functions.rb} +0 -2
- data/lib/{global_helpers.rb → livetext/global_helpers.rb} +6 -3
- data/lib/{handler → livetext/handler}/import.rb +5 -9
- data/lib/livetext/handler/mixin.rb +33 -0
- data/lib/{handler.rb → livetext/handler.rb} +1 -1
- data/lib/{helpers.rb → livetext/helpers.rb} +78 -66
- data/lib/{html.rb → livetext/html.rb} +2 -3
- data/lib/livetext/lineparser.rb +441 -0
- data/lib/livetext/more.rb +158 -0
- data/lib/{parser → livetext/parser}/general.rb +0 -0
- data/lib/{parser → livetext/parser}/set.rb +0 -0
- data/lib/{parser → livetext/parser}/string.rb +0 -0
- data/lib/{parser.rb → livetext/parser.rb} +0 -3
- data/lib/{parsing.rb → livetext/parsing.rb} +0 -2
- data/lib/livetext/paths.rb +13 -0
- data/lib/{processor.rb → livetext/processor.rb} +18 -8
- data/lib/livetext/reopen.rb +12 -0
- data/lib/livetext/skeleton.rb +22 -0
- data/lib/{standard.rb → livetext/standard.rb} +150 -127
- data/lib/livetext/userapi.rb +170 -0
- data/lib/livetext/version.rb +6 -0
- data/lib/livetext.rb +14 -152
- data/plugin/bookish.rb +82 -81
- data/plugin/calibre.rb +3 -3
- data/plugin/livemagick.rb +17 -17
- data/plugin/markdown.rb +10 -10
- data/plugin/pyggish.rb +118 -118
- data/plugin/tutorial.rb +15 -15
- data/test/all.rb +6 -0
- data/test/snapshots/{error_inc_line_num → basic_formatting}/actual-error.txt +0 -0
- data/test/snapshots/basic_formatting/actual-output.txt +13 -0
- data/test/snapshots/basic_formatting/err-sdiff.txt +1 -0
- data/test/snapshots/basic_formatting/out-sdiff.txt +14 -0
- data/test/snapshots/def_method/expected-output.txt +2 -0
- data/test/snapshots/def_method/source.lt3 +4 -2
- data/test/snapshots/error_inc_line_num/{OUT → README.txt} +11 -8
- data/test/snapshots/error_inc_line_num/expected-output.txt +0 -6
- data/test/snapshots/error_inc_line_num/match-error.txt +1 -1
- data/test/snapshots/error_invalid_name/foo +5 -0
- data/test/snapshots/error_line_num/match-error.txt +1 -1
- data/test/snapshots/error_missing_end/expected-output.txt +0 -1
- data/test/snapshots/error_name_not_permitted/expected-output.txt +4 -0
- data/test/snapshots/error_name_not_permitted/match-error.txt +1 -1
- data/test/snapshots/error_no_such_copy/expected-output.txt +1 -0
- data/test/snapshots/error_no_such_mixin/expected-output.txt +1 -0
- data/test/snapshots/error_no_such_mixin/match-error.txt +1 -1
- data/test/snapshots/error_no_such_mixin/source.lt3 +1 -1
- data/test/snapshots/example_alpha/source.lt3 +2 -2
- data/test/snapshots/example_alpha2/expected-output.txt +0 -2
- data/test/snapshots/example_alpha2/source.lt3 +5 -4
- data/test/snapshots/import/expected-output.txt +2 -1
- data/test/snapshots/import/match-error.txt +1 -1
- data/test/snapshots/import/simple_import.rb +1 -1
- data/test/snapshots/import2/simple_import.rb +1 -1
- data/test/snapshots/import_bookish/expected-output.txt +4 -4
- data/test/snapshots/{error_invalid_name/actual-output.txt → more_functions/actual-error.txt} +0 -0
- data/test/snapshots/more_functions/actual-output.txt +37 -0
- data/test/snapshots/more_functions/err-sdiff.txt +1 -0
- data/test/snapshots/more_functions/expected-output.txt +1 -1
- data/test/snapshots/more_functions/out-sdiff.txt +38 -0
- data/test/snapshots/more_functions/source.lt3 +1 -1
- data/test/snapshots/raw_lines/expected-output.txt +0 -2
- data/test/snapshots/simple_import/simple_import.rb +1 -1
- data/test/snapshots/simple_mixin/simple_mixin.rb +1 -1
- data/test/snapshots/{error_missing_end/actual-output.txt → simple_vars/actual-error.txt} +0 -0
- data/test/snapshots/simple_vars/actual-output.txt +6 -0
- data/test/snapshots/simple_vars/err-sdiff.txt +1 -0
- data/test/snapshots/simple_vars/out-sdiff.txt +7 -0
- data/test/snapshots/single_raw_line/expected-output.txt +0 -2
- data/test/snapshots/subset.txt +9 -7
- data/test/snapshots/{error_no_such_copy/actual-output.txt → var_into_func/actual-error.txt} +0 -0
- data/test/snapshots/var_into_func/actual-output.txt +16 -0
- data/test/snapshots/var_into_func/err-sdiff.txt +1 -0
- data/test/snapshots/{error_no_such_inc/actual-output.txt → var_into_func/expected-error.txt} +0 -0
- data/test/snapshots/var_into_func/expected-output.txt +16 -0
- data/test/snapshots/var_into_func/out-sdiff.txt +17 -0
- data/test/snapshots/var_into_func/source.lt3 +16 -0
- data/test/snapshots.rb +16 -7
- data/test/unit/all.rb +3 -1
- data/test/unit/formatline.rb +145 -276
- data/test/unit/html.rb +1 -2
- data/test/unit/lineparser.rb +650 -0
- data/test/unit/parser/set.rb +13 -12
- data/test/unit/standard.rb +0 -1
- data/test/unit/tokenizer.rb +534 -0
- metadata +49 -39
- data/lib/funcall.rb +0 -93
- data/lib/parser/file.rb +0 -6
- data/lib/parser/mixin.rb +0 -34
- data/lib/userapi.rb +0 -164
- data/test/snapshots/error_inc_line_num/actual-output.txt +0 -17
- data/test/snapshots/error_invalid_name/actual-error.txt +0 -10
- data/test/snapshots/error_invalid_name/out-sdiff.txt +0 -6
- data/test/snapshots/error_missing_end/actual-error.txt +0 -10
- data/test/snapshots/error_missing_end/out-sdiff.txt +0 -6
- data/test/snapshots/error_no_such_copy/actual-error.txt +0 -10
- data/test/snapshots/error_no_such_copy/out-sdiff.txt +0 -5
- data/test/snapshots/error_no_such_inc/actual-error.txt +0 -10
- data/test/snapshots/error_no_such_inc/out-sdiff.txt +0 -6
- data/test/snapshots/error_no_such_mixin/actual-error.txt +0 -13
- data/test/snapshots/error_no_such_mixin/actual-output.txt +0 -0
- data/test/snapshots/error_no_such_mixin/out-sdiff.txt +0 -6
data/imports/pyggish.rb
CHANGED
@@ -83,21 +83,21 @@ module Pyggish
|
|
83
83
|
end
|
84
84
|
|
85
85
|
def fragment
|
86
|
-
lang =
|
87
|
-
|
86
|
+
lang = api.args.empty? ? :elixir : api.args.first.to_sym # ruby or elixir
|
87
|
+
api.args = []
|
88
88
|
send(lang)
|
89
|
-
|
89
|
+
api.out "\n"
|
90
90
|
end
|
91
91
|
|
92
92
|
def code # FIXME ?
|
93
93
|
text = ""
|
94
|
-
|
94
|
+
api.body {|line| api.out " " + line }
|
95
95
|
end
|
96
96
|
|
97
97
|
def mono
|
98
|
-
|
99
|
-
|
100
|
-
|
98
|
+
api.out "<pre>"
|
99
|
+
api.body {|line| api.out " " + line }
|
100
|
+
api.out "</pre>"
|
101
101
|
end
|
102
102
|
|
103
103
|
def create_code_styles
|
@@ -145,28 +145,28 @@ module Pyggish
|
|
145
145
|
end
|
146
146
|
|
147
147
|
def ruby
|
148
|
-
file =
|
148
|
+
file = api.args.first
|
149
149
|
if file.nil?
|
150
150
|
code = " # Ruby code\n\n"
|
151
|
-
|
151
|
+
api.body {|line| code << " " + line + "\n" }
|
152
152
|
else
|
153
153
|
code = "# Ruby code\n\n" + ::File.read(file)
|
154
154
|
end
|
155
155
|
|
156
156
|
html = format_ruby(code)
|
157
|
-
|
157
|
+
api.out html
|
158
158
|
end
|
159
159
|
|
160
160
|
def elixir
|
161
|
-
file =
|
161
|
+
file = api.args.first
|
162
162
|
if file.nil?
|
163
163
|
code = ""
|
164
|
-
|
164
|
+
api.body {|line| code << " " + line + "\n" }
|
165
165
|
else
|
166
166
|
code = ::File.read(file)
|
167
167
|
end
|
168
168
|
|
169
169
|
html = format_elixir(code)
|
170
|
-
|
170
|
+
api.out html
|
171
171
|
end
|
172
172
|
end
|
data/imports/tutorial.rb
CHANGED
@@ -7,22 +7,22 @@ module Tutorial
|
|
7
7
|
|
8
8
|
def title(args = nil, body = nil)
|
9
9
|
h1
|
10
|
-
|
10
|
+
api.optional_blank_line
|
11
11
|
end
|
12
12
|
|
13
13
|
def section(args = nil, body = nil)
|
14
14
|
h3
|
15
|
-
|
15
|
+
api.optional_blank_line
|
16
16
|
end
|
17
17
|
|
18
18
|
def code(args = nil, body = nil)
|
19
19
|
first = true # dumb hack! fixes blank space
|
20
|
-
|
20
|
+
api.body do |line|
|
21
21
|
tag, first = "<pre>", false if first
|
22
|
-
|
22
|
+
api.out "#{tag} #{escape_html(line)}" # indentation
|
23
23
|
end
|
24
|
-
|
25
|
-
|
24
|
+
api.out "</pre>"
|
25
|
+
api.optional_blank_line
|
26
26
|
end
|
27
27
|
|
28
28
|
def rx(str)
|
@@ -30,14 +30,14 @@ module Tutorial
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def inout(args = nil, body = nil)
|
33
|
-
src, out =
|
33
|
+
src, out = api.args
|
34
34
|
t1 = ::File.readlines(src) rescue (abort "t1 = #{src}")
|
35
35
|
t2 = ::File.readlines(out) rescue (abort "t2 = #{out}")
|
36
36
|
# To pacify markdown for README (FIXME later)
|
37
37
|
t1 = t1.map {|x| " " + x.sub(/ +$/,"").gsub(/_/, "\\_") }.join
|
38
38
|
t2 = t2.map {|x| " " + x.sub(/ +$/,"").gsub(/_/, "\\_") }.join
|
39
39
|
|
40
|
-
|
40
|
+
api.out <<-HTML
|
41
41
|
<table width=80% cellpadding=4>
|
42
42
|
<tr>
|
43
43
|
<td width=50%><b>Input</b></td>
|
@@ -53,7 +53,7 @@ module Tutorial
|
|
53
53
|
</tr>
|
54
54
|
</table>
|
55
55
|
HTML
|
56
|
-
|
56
|
+
api.optional_blank_line
|
57
57
|
end
|
58
58
|
|
59
59
|
def put_table(src, exp)
|
@@ -62,7 +62,7 @@ module Tutorial
|
|
62
62
|
t1 = t1.map {|x| " " + x.sub(/ +$/,"").gsub(/_/, "\\_") }.join
|
63
63
|
t2 = t2.map {|x| " " + x.sub(/ +$/,"").gsub(/_/, "\\_") }.join
|
64
64
|
|
65
|
-
|
65
|
+
api.out <<-HTML
|
66
66
|
<font size=+1>
|
67
67
|
<table width=80% cellpadding=4>
|
68
68
|
<tr>
|
@@ -83,13 +83,13 @@ module Tutorial
|
|
83
83
|
end
|
84
84
|
|
85
85
|
def testcase(args = nil, body = nil)
|
86
|
-
name =
|
87
|
-
|
86
|
+
name = api.args.first
|
87
|
+
api.out "\n<font size=+1><b>Test: </font><font size=+2><tt>#{name}</tt></font></b></h3><br>"
|
88
88
|
src, exp = "test/snapshots/#{name}/source.lt3", "test/snapshots/#{name}/expected-output.txt"
|
89
|
-
|
89
|
+
api.args = [src, exp] # Better way to do this??
|
90
90
|
put_table(src, exp)
|
91
|
-
|
92
|
-
|
91
|
+
api.out "<br>"
|
92
|
+
api.optional_blank_line
|
93
93
|
end
|
94
94
|
end
|
95
95
|
|
data/lib/cmdargs.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
# p __FILE__
|
2
1
|
|
3
2
|
require_relative 'livetext'
|
4
3
|
|
@@ -80,13 +79,13 @@ class Livetext::CmdData
|
|
80
79
|
def check_num_args(num)
|
81
80
|
num_range = /(\d{0,2})(\.\.)(\d{0,2})/ # Not "really" right...
|
82
81
|
min, max = 0, 9999
|
83
|
-
|
82
|
+
mdata = num_range.match(@nargs).to_a
|
84
83
|
bad_args = nil
|
85
84
|
case
|
86
85
|
when @nargs == ":N" # arbitrary
|
87
86
|
# max already set
|
88
|
-
when
|
89
|
-
vmin, vmax =
|
87
|
+
when mdata[2] == ".." # range: 4..6 1.. ..4
|
88
|
+
vmin, vmax = mdata.values_at(1, 2)
|
90
89
|
min = Integer(vmin) unless vmin.empty?
|
91
90
|
max = Integer(vmax) unless vmax.empty?
|
92
91
|
min, max = Integer(min), Integer(max)
|
@@ -100,4 +99,8 @@ class Livetext::CmdData
|
|
100
99
|
raise "Expected #{num} args but found #{@args.size}!" if bad_args
|
101
100
|
end
|
102
101
|
|
102
|
+
def strip_comments(str)
|
103
|
+
str.sub!(/ # .*/, "")
|
104
|
+
end
|
105
|
+
|
103
106
|
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# p __FILE__
|
2
|
-
|
3
1
|
|
4
2
|
# More later?
|
5
3
|
|
@@ -10,8 +8,11 @@ def make_exception(sym, str, target_class = Object)
|
|
10
8
|
define_method(sym) do |*args|
|
11
9
|
args = [] unless args.first
|
12
10
|
msg = str.dup
|
13
|
-
args.each.with_index {|arg, i| msg.sub!("%#{i+1}", arg) }
|
11
|
+
args.each.with_index {|arg, i| msg.sub!("%#{i+1}", arg.to_s) }
|
14
12
|
target_class.class_eval(klass.to_s).new(msg)
|
15
13
|
end
|
16
14
|
end
|
17
15
|
|
16
|
+
make_exception(:EndWithoutOpening, "Error: found .end with no opening command")
|
17
|
+
make_exception(:UnknownMethod, "Error: name '%1' is unknown")
|
18
|
+
|
@@ -1,4 +1,3 @@
|
|
1
|
-
# p __FILE__
|
2
1
|
|
3
2
|
require_relative 'parsing'
|
4
3
|
require_relative 'funcall'
|
@@ -21,15 +20,21 @@ class Livetext::FormatLine < StringParser
|
|
21
20
|
|
22
21
|
def self.parse!(line)
|
23
22
|
return nil if line.nil?
|
24
|
-
|
23
|
+
line.chomp!
|
24
|
+
x = self.new(line)
|
25
|
+
::Livetext::TTY.puts "\n-- string: #{line.inspect}" if $testme
|
25
26
|
t = x.tokenize
|
26
|
-
|
27
|
+
::Livetext::TTY.puts "\n-- Tokens: #{t.inspect}" if $testme
|
28
|
+
result = x.evaluate
|
29
|
+
::Livetext::TTY.puts "\n-- result: #{result.inspect}\n " if $testme
|
30
|
+
result
|
27
31
|
end
|
28
32
|
|
29
33
|
def tokenize
|
30
|
-
# add grab
|
31
34
|
loop do
|
32
|
-
|
35
|
+
ch = peek
|
36
|
+
::Livetext::TTY.puts "\n-- #{__method__}: ch1 = #{ch.inspect}\n " if $testme
|
37
|
+
case ch
|
33
38
|
when Escape; grab; add peek; grab
|
34
39
|
when "$"
|
35
40
|
dollar
|
@@ -37,7 +42,65 @@ class Livetext::FormatLine < StringParser
|
|
37
42
|
marker peek
|
38
43
|
add peek
|
39
44
|
when LF
|
40
|
-
break if eos?
|
45
|
+
break if eos?
|
46
|
+
when nil
|
47
|
+
break
|
48
|
+
else
|
49
|
+
add peek
|
50
|
+
end
|
51
|
+
ch = grab
|
52
|
+
# add ch
|
53
|
+
::Livetext::TTY.puts "\n-- #{__method__}: !!! ch2 = #{ch.inspect}\n " if $testme
|
54
|
+
end
|
55
|
+
add_token(:str)
|
56
|
+
@tokenlist
|
57
|
+
end
|
58
|
+
|
59
|
+
def parse_formatting
|
60
|
+
loop do
|
61
|
+
case peek
|
62
|
+
when Escape; grab; add peek; grab
|
63
|
+
when "*", "_", "`", "~"
|
64
|
+
marker peek
|
65
|
+
add peek
|
66
|
+
when LF
|
67
|
+
break if eos?
|
68
|
+
when nil
|
69
|
+
break
|
70
|
+
else
|
71
|
+
add peek
|
72
|
+
end
|
73
|
+
grab
|
74
|
+
end
|
75
|
+
add_token(:str)
|
76
|
+
@tokenlist
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.get_vars
|
80
|
+
grab
|
81
|
+
case peek
|
82
|
+
when LF, " ", nil
|
83
|
+
add "$"
|
84
|
+
add_token :str
|
85
|
+
when "$"; double_dollar
|
86
|
+
# when "."; dollar_dot
|
87
|
+
when /[A-Za-z]/
|
88
|
+
add_token :str
|
89
|
+
var = peek + grab_alpha_dot
|
90
|
+
add_token(:var, var)
|
91
|
+
else
|
92
|
+
add "$" + peek
|
93
|
+
add_token(:str)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.parse_var_func # FIXME Hmm...
|
98
|
+
loop do
|
99
|
+
case peek
|
100
|
+
when "$"
|
101
|
+
dollar
|
102
|
+
when LF
|
103
|
+
break if eos?
|
41
104
|
when nil
|
42
105
|
break
|
43
106
|
else
|
@@ -57,6 +120,20 @@ class Livetext::FormatLine < StringParser
|
|
57
120
|
end
|
58
121
|
end
|
59
122
|
|
123
|
+
def var_func_parse
|
124
|
+
char = self.peek
|
125
|
+
loop do
|
126
|
+
char = self.grab
|
127
|
+
break if char == LF || char == nil
|
128
|
+
self.escaped if char == Escape
|
129
|
+
self.dollar if char == "$" # Could be $$
|
130
|
+
self.add char
|
131
|
+
end
|
132
|
+
self.add_token(:str)
|
133
|
+
result = self.evaluate
|
134
|
+
result
|
135
|
+
end
|
136
|
+
|
60
137
|
def self.var_func_parse(str)
|
61
138
|
return nil if str.nil?
|
62
139
|
x = self.new(str.chomp)
|
@@ -64,7 +141,7 @@ class Livetext::FormatLine < StringParser
|
|
64
141
|
loop do
|
65
142
|
char = x.grab
|
66
143
|
break if char == LF || char == nil
|
67
|
-
x.
|
144
|
+
x.escaped if char == Escape
|
68
145
|
x.dollar if char == "$" # Could be $$
|
69
146
|
x.add char
|
70
147
|
end
|
@@ -73,9 +150,20 @@ class Livetext::FormatLine < StringParser
|
|
73
150
|
result
|
74
151
|
end
|
75
152
|
|
76
|
-
def
|
77
|
-
|
78
|
-
|
153
|
+
def self.parse_variables(str)
|
154
|
+
return nil if str.nil?
|
155
|
+
x = self.new(str.chomp)
|
156
|
+
char = x.peek
|
157
|
+
loop do
|
158
|
+
char = x.grab
|
159
|
+
break if char == LF || char == nil
|
160
|
+
x.escaped if char == Escape
|
161
|
+
x.dollar if char == "$" # Could be $$
|
162
|
+
x.add char
|
163
|
+
end
|
164
|
+
x.add_token(:str)
|
165
|
+
result = x.evaluate
|
166
|
+
result
|
79
167
|
end
|
80
168
|
|
81
169
|
def embed(sym, str)
|
@@ -139,20 +227,31 @@ class Livetext::FormatLine < StringParser
|
|
139
227
|
end
|
140
228
|
|
141
229
|
def dollar
|
142
|
-
grab
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
230
|
+
ch = grab # "$"
|
231
|
+
::Livetext::TTY.puts "\n-- #{__method__}: ch1 = #{ch.inspect}\n self = #{self.inspect}" if $testme
|
232
|
+
ch = peek
|
233
|
+
::Livetext::TTY.puts "\n-- #{__method__}: ch2 = #{ch.inspect}\n self = #{self.inspect}" if $testme
|
234
|
+
case ch
|
235
|
+
when " "
|
236
|
+
::Livetext::TTY.puts "\n-- #{__method__}: (space)" if $testme
|
237
|
+
add "$ "
|
238
|
+
add_token :str
|
239
|
+
when LF, nil
|
240
|
+
::Livetext::TTY.puts "\n-- #{__method__}: (LF/nil)" if $testme
|
241
|
+
add "$"
|
242
|
+
add_token :str
|
147
243
|
when "$"; double_dollar
|
148
244
|
# when "."; dollar_dot
|
149
245
|
when /[A-Za-z]/
|
246
|
+
::Livetext::TTY.puts "\n-- #{__method__}: (Alpha)" if $testme
|
150
247
|
add_token :str
|
151
248
|
var = peek + grab_alpha_dot
|
152
249
|
add_token(:var, var)
|
153
250
|
else
|
154
|
-
|
155
|
-
|
251
|
+
ch = grab # "$"
|
252
|
+
::Livetext::TTY.puts "\n-- ch3 = #{ch.inspect}\n self = #{self.inspect}" if $testme
|
253
|
+
add "$" + ch
|
254
|
+
add_token(:str)
|
156
255
|
end
|
157
256
|
end
|
158
257
|
|
@@ -267,7 +366,9 @@ class Livetext::FormatLine < StringParser
|
|
267
366
|
end
|
268
367
|
|
269
368
|
def varsub(name)
|
270
|
-
|
369
|
+
live = Livetext.new
|
370
|
+
value = live.vars[name]
|
371
|
+
result = value || "[#{name} is undefined]"
|
271
372
|
result
|
272
373
|
end
|
273
374
|
|
@@ -0,0 +1,168 @@
|
|
1
|
+
|
2
|
+
require_relative '../livetext'
|
3
|
+
|
4
|
+
# Parse function calls
|
5
|
+
|
6
|
+
module Livetext::LineParser::FunCall
|
7
|
+
|
8
|
+
include Livetext::ParsingConstants
|
9
|
+
|
10
|
+
def param_loop(char)
|
11
|
+
param = ""
|
12
|
+
loop do
|
13
|
+
case peek
|
14
|
+
when Escape
|
15
|
+
param << escaped
|
16
|
+
when char, LF, nil
|
17
|
+
break
|
18
|
+
else
|
19
|
+
param << grab
|
20
|
+
end
|
21
|
+
end
|
22
|
+
param = nil if param.empty?
|
23
|
+
param
|
24
|
+
end
|
25
|
+
|
26
|
+
def grab_colon_param
|
27
|
+
grab # grab :
|
28
|
+
param = param_loop(Space)
|
29
|
+
end
|
30
|
+
|
31
|
+
def grab_bracket_param
|
32
|
+
grab # [
|
33
|
+
param = param_loop("]")
|
34
|
+
grab # "]"
|
35
|
+
param
|
36
|
+
end
|
37
|
+
|
38
|
+
def funcall(name, param)
|
39
|
+
err = "[Error evaluating $$#{name}(#{param})]"
|
40
|
+
result =
|
41
|
+
if self.send?(name, param)
|
42
|
+
# do nothing
|
43
|
+
else
|
44
|
+
fobj = ::Livetext::Functions.new
|
45
|
+
fobj.send(name, param) rescue err
|
46
|
+
end
|
47
|
+
result.to_s
|
48
|
+
end
|
49
|
+
|
50
|
+
def grab_func_with_param
|
51
|
+
add_token(:str, @token)
|
52
|
+
func = grab_alpha
|
53
|
+
add_token(:func, func)
|
54
|
+
param = grab_func_param # may be null/missing
|
55
|
+
param
|
56
|
+
end
|
57
|
+
|
58
|
+
def double_dollar
|
59
|
+
case peek
|
60
|
+
when Space; add_token :string, "$$ "; grab
|
61
|
+
when LF, nil; add "$$ "; add_token :str
|
62
|
+
when Alpha; param = grab_func_with_param
|
63
|
+
else grab; add_token :str, "$$" + peek
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def grab_func_param
|
68
|
+
case peek
|
69
|
+
when "["
|
70
|
+
param = grab_bracket_param
|
71
|
+
add_token(:brackets, param)
|
72
|
+
when ":"
|
73
|
+
param = grab_colon_param
|
74
|
+
add_token(:colon, param)
|
75
|
+
else # do nothing
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def escaped
|
80
|
+
grab # Eat the backslash
|
81
|
+
ch = grab # Take next char
|
82
|
+
ch
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
# FIXME...
|
89
|
+
|
90
|
+
module Livetext::FormatLine::FunCall
|
91
|
+
|
92
|
+
include Livetext::ParsingConstants
|
93
|
+
|
94
|
+
def param_loop(char)
|
95
|
+
param = ""
|
96
|
+
loop do
|
97
|
+
case peek
|
98
|
+
when Escape
|
99
|
+
param << escaped
|
100
|
+
when char, LF, nil
|
101
|
+
break
|
102
|
+
else
|
103
|
+
param << peek
|
104
|
+
grab
|
105
|
+
end
|
106
|
+
end
|
107
|
+
param = nil if param.empty?
|
108
|
+
param
|
109
|
+
end
|
110
|
+
|
111
|
+
def grab_colon_param
|
112
|
+
grab # grab :
|
113
|
+
param = param_loop(Space)
|
114
|
+
end
|
115
|
+
|
116
|
+
def grab_bracket_param
|
117
|
+
grab # [
|
118
|
+
param = param_loop("]")
|
119
|
+
grab # "]"
|
120
|
+
param
|
121
|
+
end
|
122
|
+
|
123
|
+
def funcall(name, param)
|
124
|
+
err = "[Error evaluating $$#{name}(#{param})]"
|
125
|
+
func_name = name # "func_" + name.to_s
|
126
|
+
result =
|
127
|
+
if self.send?(func_name, param) # self.respond_to?(func_name)
|
128
|
+
# do nothing
|
129
|
+
else
|
130
|
+
fobj = ::Livetext::Functions.new
|
131
|
+
fobj.send(name, param) rescue err
|
132
|
+
end
|
133
|
+
result.to_s
|
134
|
+
end
|
135
|
+
|
136
|
+
def double_dollar
|
137
|
+
case lookahead
|
138
|
+
when Space; add_token :string, "$$ "; grab; return
|
139
|
+
when LF, nil; add "$$"; add_token :str
|
140
|
+
when Alpha
|
141
|
+
add_token(:str, @token)
|
142
|
+
func = grab_alpha
|
143
|
+
add_token(:func, func)
|
144
|
+
param = grab_func_param # may be null/missing
|
145
|
+
else
|
146
|
+
grab; add_token :str, "$$" + peek; return
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def grab_func_param
|
151
|
+
case lookahead
|
152
|
+
when "["
|
153
|
+
param = grab_bracket_param
|
154
|
+
add_token(:brackets, param)
|
155
|
+
when ":"
|
156
|
+
param = grab_colon_param
|
157
|
+
add_token(:colon, param)
|
158
|
+
else # do nothing
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def escaped
|
163
|
+
grab # Eat the backslash
|
164
|
+
ch = grab # Take next char
|
165
|
+
ch
|
166
|
+
end
|
167
|
+
|
168
|
+
end
|
@@ -1,14 +1,13 @@
|
|
1
|
-
# p __FILE__
|
2
|
-
|
3
1
|
|
4
2
|
module GlobalHelpers
|
5
3
|
|
6
4
|
def check_disallowed(name)
|
5
|
+
api.tty "GLOBAL cdis"
|
7
6
|
raise DisallowedName(name) if disallowed?(name)
|
8
7
|
end
|
9
8
|
|
10
9
|
def check_file_exists(file)
|
11
|
-
|
10
|
+
graceful_error FileNotFound(file) unless File.exist?(file)
|
12
11
|
end
|
13
12
|
|
14
13
|
def grab_file(fname)
|
@@ -36,4 +35,8 @@ module GlobalHelpers
|
|
36
35
|
return nil
|
37
36
|
end
|
38
37
|
|
38
|
+
def cwd_root?
|
39
|
+
File.dirname(File.expand_path(".")) == "/"
|
40
|
+
end
|
41
|
+
|
39
42
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
|
2
2
|
require_relative '../helpers'
|
3
|
-
|
3
|
+
|
4
|
+
# Handle a .import
|
4
5
|
|
5
6
|
class Livetext::Handler::Import
|
6
7
|
include Livetext::Helpers
|
@@ -24,21 +25,16 @@ class Livetext::Handler::Import
|
|
24
25
|
name
|
25
26
|
end
|
26
27
|
|
27
|
-
def self.get_module(filename)
|
28
|
+
def self.get_module(filename, parent)
|
29
|
+
# TTY.puts "#{__method__}: filename = #{filename.inspect}"
|
28
30
|
handler = self.new(filename)
|
31
|
+
parent.graceful_error FileNotFound(filename) if handler.file.nil?
|
29
32
|
@file = handler.file.sub(/.rb$/, "")
|
30
33
|
require @file # + ".rb"
|
31
34
|
modname = get_mod_name
|
32
|
-
# TTY.puts "modname = #{modname.inspect}"
|
33
35
|
newmod = Object.const_get("::" + modname)
|
34
36
|
newmod # return actual module
|
35
37
|
end
|
36
38
|
|
37
|
-
private
|
38
|
-
|
39
|
-
def cwd_root?
|
40
|
-
File.dirname(File.expand_path(".")) == "/"
|
41
|
-
end
|
42
|
-
|
43
39
|
end
|
44
40
|
|
@@ -0,0 +1,33 @@
|
|
1
|
+
|
2
|
+
require_relative '../helpers'
|
3
|
+
|
4
|
+
# Handle a .mixin
|
5
|
+
|
6
|
+
class Livetext::Handler::Mixin
|
7
|
+
include Livetext::Helpers
|
8
|
+
include GlobalHelpers
|
9
|
+
|
10
|
+
attr_reader :file
|
11
|
+
|
12
|
+
def initialize(name, parent)
|
13
|
+
@name = name
|
14
|
+
@file = find_file(name, ".rb", "plugin")
|
15
|
+
parent.graceful_error FileNotFound(name) if @file.nil?
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.get_module(filename, parent)
|
19
|
+
handler = self.new(filename, parent)
|
20
|
+
modname, code = handler.read_mixin
|
21
|
+
eval(code) # Avoid in the future
|
22
|
+
newmod = Object.const_get("::" + modname)
|
23
|
+
newmod # return actual module
|
24
|
+
end
|
25
|
+
|
26
|
+
def read_mixin
|
27
|
+
modname = @name.gsub("/","_").capitalize
|
28
|
+
meths = grab_file(@file) # already has .rb?
|
29
|
+
[modname, "module ::#{modname}; #{meths}\nend"]
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|