livetext 0.9.21 → 0.9.25
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/README.lt3 +8 -8
- data/bin/livetext +57 -40
- data/imports/bookish.rb +89 -90
- data/imports/calibre.rb +3 -3
- data/imports/livemagick.rb +17 -17
- data/imports/markdown.rb +10 -10
- data/imports/pyggish.rb +15 -47
- data/imports/tutorial.rb +18 -18
- data/lib/cmdargs.rb +10 -6
- data/lib/{errors.rb → livetext/errors.rb} +1 -1
- data/lib/{formatline.rb → livetext/formatline.rb} +69 -125
- data/lib/livetext/funcall.rb +84 -0
- data/lib/{functions.rb → livetext/functions.rb} +16 -3
- data/lib/livetext/global_helpers.rb +37 -0
- data/lib/livetext/handler/import.rb +44 -0
- data/lib/livetext/handler/mixin.rb +37 -0
- data/lib/livetext/handler.rb +3 -0
- data/lib/{helpers.rb → livetext/helpers.rb} +89 -67
- data/lib/{html.rb → livetext/html.rb} +3 -2
- data/lib/{parser → livetext/parser}/general.rb +0 -3
- data/lib/{parser → livetext/parser}/set.rb +1 -6
- data/lib/{parser → livetext/parser}/string.rb +2 -2
- data/lib/{parser.rb → livetext/parser.rb} +0 -1
- data/lib/livetext/parsing.rb +29 -0
- data/lib/livetext/paths.rb +13 -0
- data/lib/livetext/processor.rb +89 -0
- data/lib/livetext/reopen.rb +12 -0
- data/lib/livetext/skeleton.rb +17 -0
- data/lib/{standard.rb → livetext/standard.rb} +152 -122
- data/lib/livetext/userapi.rb +153 -0
- data/lib/livetext/version.rb +6 -0
- data/lib/livetext.rb +66 -27
- data/plugin/bookish.rb +85 -85
- data/plugin/calibre.rb +3 -3
- data/plugin/livemagick.rb +17 -17
- data/plugin/markdown.rb +10 -10
- data/plugin/pyggish.rb +131 -162
- data/plugin/tutorial.rb +15 -16
- data/test/all.rb +6 -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 +17 -0
- data/test/snapshots/error_inc_line_num/README.txt +20 -0
- 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_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/duh +26 -0
- data/test/snapshots/error_no_such_copy/expected-output.txt +1 -0
- data/test/snapshots/error_no_such_copy/match-error.txt +1 -1
- data/test/snapshots/error_no_such_copy/mystery.txt +36 -0
- data/test/snapshots/error_no_such_inc/match-error.txt +1 -1
- 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/{icanhaz → import}/expected-output.txt +2 -1
- data/test/snapshots/import/match-error.txt +1 -0
- data/test/snapshots/{icanhaz → import}/simple_import.rb +1 -1
- data/test/snapshots/{icanhaz → import}/source.lt3 +2 -2
- data/test/snapshots/{icanhaz2 → import2}/expected-error.txt +0 -0
- data/test/snapshots/{icanhaz2 → import2}/expected-output.txt +3 -1
- data/test/snapshots/{icanhaz2/simple_canhaz.rb → import2/simple_import.rb} +1 -1
- data/test/snapshots/import2/source.lt3 +8 -0
- data/test/snapshots/import_bookish/expected-error.txt +0 -0
- data/test/snapshots/import_bookish/expected-output.txt +10 -0
- data/test/snapshots/import_bookish/source.lt3 +7 -0
- data/test/snapshots/import_bookish/toc.tmp +0 -0
- data/test/snapshots/mixin_bookish/expected-error.txt +0 -0
- data/test/snapshots/mixin_bookish/expected-output.txt +10 -0
- data/test/snapshots/mixin_bookish/source.lt3 +7 -0
- data/test/snapshots/mixin_bookish/toc.tmp +0 -0
- data/test/snapshots/more_functions/expected-error.txt +0 -0
- data/test/snapshots/more_functions/expected-output.txt +37 -0
- data/test/snapshots/more_functions/source.lt3 +40 -0
- data/test/snapshots/raw_lines/expected-output.txt +0 -2
- data/test/snapshots/simple_import/expected-output.txt +2 -0
- data/test/snapshots/simple_import/simple_import.rb +1 -1
- data/test/snapshots/simple_import/source.lt3 +3 -1
- data/test/snapshots/simple_mixin/simple_mixin.rb +1 -1
- data/test/snapshots/single_raw_line/expected-output.txt +0 -2
- data/test/snapshots/subset.txt +14 -14
- data/test/snapshots.rb +30 -13
- data/test/unit/formatline.rb +253 -134
- data/test/unit/html.rb +2 -3
- data/test/unit/parser/general.rb +1 -2
- data/test/unit/parser/mixin.rb +1 -3
- data/test/unit/parser/set.rb +8 -12
- data/test/unit/parser/string.rb +6 -6
- data/test/unit/parser.rb +0 -1
- data/test/unit/standard.rb +0 -2
- metadata +47 -30
- data/imports/markdown_importable.rb +0 -45
- data/lib/handler/icanhaz.rb +0 -35
- data/lib/handler.rb +0 -1
- data/lib/livetext/importable.rb +0 -2
- data/lib/parser/file.rb +0 -8
- data/lib/parser/import.rb +0 -15
- data/lib/parser/mixin.rb +0 -38
- data/lib/processor.rb +0 -83
- data/lib/userapi.rb +0 -160
- data/test/snapshots/icanhaz/match-error.txt +0 -1
- data/test/snapshots/icanhaz2/source.lt3 +0 -6
- data/test/unit/parser/importable.rb +0 -19
data/imports/pyggish.rb
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
require 'rouge'
|
|
2
2
|
|
|
3
|
+
# FIXME This file has suboptimal juju. See plugin/pyggish.rb also
|
|
4
|
+
|
|
3
5
|
module Pyggish
|
|
4
6
|
def self.pyg_change(code, klass, style)
|
|
5
7
|
color = style[0..6]
|
|
@@ -29,7 +31,6 @@ module Pyggish
|
|
|
29
31
|
|
|
30
32
|
def self.pyg_finalize(code, lexer=:elixir)
|
|
31
33
|
Styles.each_pair {|klass, style| pyg_change(code, klass, style) }
|
|
32
|
-
File.open("debug-pf1", "w") {|f| f.puts code }
|
|
33
34
|
code.sub!(/<pre>/, "<pre>\n")
|
|
34
35
|
code.gsub!(/<span class="[np]">/, "")
|
|
35
36
|
code.gsub!(/<\/span>/, "")
|
|
@@ -37,9 +38,7 @@ File.open("debug-pf1", "w") {|f| f.puts code }
|
|
|
37
38
|
code.sub!(/<td class="linenos"/, "<td width=2%></td><td width=5% bgcolor=#{color}")
|
|
38
39
|
code.gsub!(/<td/, "<td valign=top ")
|
|
39
40
|
code.gsub!(/ class="[^"]*?"/, "") # Get rid of remaining Pygments CSS
|
|
40
|
-
File.open("debug-pf2", "w") {|f| f.puts code }
|
|
41
41
|
lines = code.split("\n")
|
|
42
|
-
# lines.each {|line| line << "\n" }
|
|
43
42
|
n1 = lines.index {|x| x =~ /<pre>/ }
|
|
44
43
|
n2 = lines.index {|x| x =~ /<\/pre>/ }
|
|
45
44
|
# FIXME ?
|
|
@@ -48,12 +47,10 @@ File.open("debug-pf2", "w") {|f| f.puts code }
|
|
|
48
47
|
lines[n1].sub!(/ 1$/, " 1 ")
|
|
49
48
|
(n1+1).upto(n2) {|n| lines[n].replace(" " + lines[n] + " ") }
|
|
50
49
|
code = lines.join("\n")
|
|
51
|
-
File.open("debug-pf3", "w") {|f| f.puts code }
|
|
52
50
|
code
|
|
53
51
|
end
|
|
54
52
|
|
|
55
53
|
def _process_code(text)
|
|
56
|
-
File.open("debug-pc1", "w") {|f| f.puts text }
|
|
57
54
|
lines = text.split("\n")
|
|
58
55
|
lines = lines.select {|x| x !~ /##~ omit/ }
|
|
59
56
|
@refs = {}
|
|
@@ -66,7 +63,6 @@ File.open("debug-pf3", "w") {|f| f.puts code }
|
|
|
66
63
|
end
|
|
67
64
|
lines.map! {|line| " " + line }
|
|
68
65
|
text2 = lines.join("\n")
|
|
69
|
-
File.open("debug-pc2", "w") {|f| f.puts text2 }
|
|
70
66
|
text.replace(text2)
|
|
71
67
|
end
|
|
72
68
|
|
|
@@ -86,50 +82,22 @@ File.open("debug-pf3", "w") {|f| f.puts code }
|
|
|
86
82
|
result
|
|
87
83
|
end
|
|
88
84
|
|
|
89
|
-
def OLD_ruby
|
|
90
|
-
file = @_args.first
|
|
91
|
-
if file.nil?
|
|
92
|
-
code = "# Ruby code\n"
|
|
93
|
-
_body {|line| code << line + "\n" }
|
|
94
|
-
else
|
|
95
|
-
code = "# Ruby code\n\n" + ::File.read(file)
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
_process_code(code)
|
|
99
|
-
html = _colorize(code, :ruby)
|
|
100
|
-
_out "\n#{html}\n "
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
def OLD_elixir
|
|
104
|
-
file = @_args.first
|
|
105
|
-
if file.nil?
|
|
106
|
-
code = ""
|
|
107
|
-
_body {|line| code << line + "\n" }
|
|
108
|
-
else
|
|
109
|
-
code = ::File.read(file)
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
_process_code(code)
|
|
113
|
-
html = _colorize(code, :elixir)
|
|
114
|
-
_out "\n#{html}\n "
|
|
115
|
-
end
|
|
116
|
-
|
|
117
85
|
def fragment
|
|
118
|
-
lang =
|
|
119
|
-
|
|
86
|
+
lang = api.args.empty? ? :elixir : api.args.first.to_sym # ruby or elixir
|
|
87
|
+
api.args = []
|
|
120
88
|
send(lang)
|
|
121
|
-
|
|
89
|
+
api.out "\n"
|
|
122
90
|
end
|
|
123
91
|
|
|
124
92
|
def code # FIXME ?
|
|
125
93
|
text = ""
|
|
126
|
-
|
|
94
|
+
api.body {|line| api.out " " + line }
|
|
127
95
|
end
|
|
128
96
|
|
|
129
97
|
def mono
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
98
|
+
api.out "<pre>"
|
|
99
|
+
api.body {|line| api.out " " + line }
|
|
100
|
+
api.out "</pre>"
|
|
133
101
|
end
|
|
134
102
|
|
|
135
103
|
def create_code_styles
|
|
@@ -177,28 +145,28 @@ File.open("debug-pf3", "w") {|f| f.puts code }
|
|
|
177
145
|
end
|
|
178
146
|
|
|
179
147
|
def ruby
|
|
180
|
-
file =
|
|
148
|
+
file = api.args.first
|
|
181
149
|
if file.nil?
|
|
182
150
|
code = " # Ruby code\n\n"
|
|
183
|
-
|
|
151
|
+
api.body {|line| code << " " + line + "\n" }
|
|
184
152
|
else
|
|
185
153
|
code = "# Ruby code\n\n" + ::File.read(file)
|
|
186
154
|
end
|
|
187
155
|
|
|
188
156
|
html = format_ruby(code)
|
|
189
|
-
|
|
157
|
+
api.out html
|
|
190
158
|
end
|
|
191
159
|
|
|
192
160
|
def elixir
|
|
193
|
-
file =
|
|
161
|
+
file = api.args.first
|
|
194
162
|
if file.nil?
|
|
195
163
|
code = ""
|
|
196
|
-
|
|
164
|
+
api.body {|line| code << " " + line + "\n" }
|
|
197
165
|
else
|
|
198
166
|
code = ::File.read(file)
|
|
199
167
|
end
|
|
200
168
|
|
|
201
169
|
html = format_elixir(code)
|
|
202
|
-
|
|
170
|
+
api.out html
|
|
203
171
|
end
|
|
204
172
|
end
|
data/imports/tutorial.rb
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
# require 'cgi'
|
|
2
|
-
|
|
3
1
|
require 'helpers'
|
|
4
2
|
|
|
3
|
+
# Created as an "ad hoc" lib for generating the README
|
|
4
|
+
|
|
5
5
|
module Tutorial
|
|
6
|
-
include Helpers
|
|
6
|
+
include Livetext::Helpers
|
|
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,3 +1,4 @@
|
|
|
1
|
+
|
|
1
2
|
require_relative 'livetext'
|
|
2
3
|
|
|
3
4
|
=begin
|
|
@@ -65,27 +66,26 @@ class Livetext::CmdData
|
|
|
65
66
|
# body: true => this command has a body + .end
|
|
66
67
|
# how raw is raw?
|
|
67
68
|
# remove comment - always/sometimes/never?
|
|
68
|
-
#
|
|
69
|
-
#
|
|
69
|
+
# interpolate - always/sometimes/never?
|
|
70
|
+
# interpolate inside body??
|
|
70
71
|
@data = data.dup # comment? vars? funcs?
|
|
71
72
|
@raw = data.dup # comment? vars? funcs?
|
|
72
73
|
@args = data.split # simple array
|
|
73
74
|
@nargs = nargs # not really "needed"
|
|
74
75
|
check_num_args(nargs)
|
|
75
|
-
|
|
76
76
|
# @varfunc = Livetext.interpolate(data.dup)
|
|
77
77
|
end
|
|
78
78
|
|
|
79
79
|
def check_num_args(num)
|
|
80
80
|
num_range = /(\d{0,2})(\.\.)(\d{0,2})/ # Not "really" right...
|
|
81
81
|
min, max = 0, 9999
|
|
82
|
-
|
|
82
|
+
mdata = num_range.match(@nargs).to_a
|
|
83
83
|
bad_args = nil
|
|
84
84
|
case
|
|
85
85
|
when @nargs == ":N" # arbitrary
|
|
86
86
|
# max already set
|
|
87
|
-
when
|
|
88
|
-
vmin, vmax =
|
|
87
|
+
when mdata[2] == ".." # range: 4..6 1.. ..4
|
|
88
|
+
vmin, vmax = mdata.values_at(1, 2)
|
|
89
89
|
min = Integer(vmin) unless vmin.empty?
|
|
90
90
|
max = Integer(vmax) unless vmax.empty?
|
|
91
91
|
min, max = Integer(min), Integer(max)
|
|
@@ -99,4 +99,8 @@ class Livetext::CmdData
|
|
|
99
99
|
raise "Expected #{num} args but found #{@args.size}!" if bad_args
|
|
100
100
|
end
|
|
101
101
|
|
|
102
|
+
def strip_comments(str)
|
|
103
|
+
str.sub!(/ # .*/, "")
|
|
104
|
+
end
|
|
105
|
+
|
|
102
106
|
end
|
|
@@ -8,7 +8,7 @@ def make_exception(sym, str, target_class = Object)
|
|
|
8
8
|
define_method(sym) do |*args|
|
|
9
9
|
args = [] unless args.first
|
|
10
10
|
msg = str.dup
|
|
11
|
-
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) }
|
|
12
12
|
target_class.class_eval(klass.to_s).new(msg)
|
|
13
13
|
end
|
|
14
14
|
end
|
|
@@ -1,28 +1,13 @@
|
|
|
1
|
+
|
|
2
|
+
require_relative 'parsing'
|
|
3
|
+
require_relative 'funcall'
|
|
4
|
+
|
|
1
5
|
# Class FormatLine handles the parsing of comments, dot commands, and
|
|
2
6
|
# simple formatting characters.
|
|
3
7
|
|
|
4
|
-
class FormatLine < StringParser
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
SimpleFormats[:i] = %w[<i> </i>]
|
|
8
|
-
SimpleFormats[:t] = ["<font size=+1><tt>", "</tt></font>"]
|
|
9
|
-
SimpleFormats[:s] = %w[<strike> </strike>]
|
|
10
|
-
|
|
11
|
-
Null = ""
|
|
12
|
-
Space = " "
|
|
13
|
-
Alpha = /[A-Za-z]/
|
|
14
|
-
AlNum = /[A-Za-z0-9_]/
|
|
15
|
-
LF = "\n"
|
|
16
|
-
LBrack = "["
|
|
17
|
-
|
|
18
|
-
Blank = [" ", nil, "\n"]
|
|
19
|
-
Punc = [")", ",", ".", " ", "\n"]
|
|
20
|
-
NoAlpha = /[^A-Za-z0-9_]/
|
|
21
|
-
NoAlphaDot = /[^.A-Za-z0-9_]/
|
|
22
|
-
Param = ["]", "\n", nil]
|
|
23
|
-
Escape = "\\" # not an ESC char
|
|
24
|
-
|
|
25
|
-
Syms = { "*" => :b, "_" => :i, "`" => :t, "~" => :s }
|
|
8
|
+
class Livetext::FormatLine < StringParser
|
|
9
|
+
include Livetext::ParsingConstants
|
|
10
|
+
include Livetext::FormatLine::FunCall
|
|
26
11
|
|
|
27
12
|
attr_reader :out
|
|
28
13
|
attr_reader :tokenlist
|
|
@@ -37,22 +22,20 @@ class FormatLine < StringParser
|
|
|
37
22
|
return nil if line.nil?
|
|
38
23
|
x = self.new(line.chomp)
|
|
39
24
|
t = x.tokenize
|
|
40
|
-
# TTY.puts "tokens = \n#{t.inspect}\n "
|
|
41
25
|
x.evaluate
|
|
42
26
|
end
|
|
43
27
|
|
|
44
28
|
def tokenize
|
|
45
|
-
# add grab
|
|
46
29
|
loop do
|
|
47
30
|
case peek
|
|
48
|
-
when Escape; grab; add peek; grab
|
|
31
|
+
when Escape; grab; add peek; grab
|
|
49
32
|
when "$"
|
|
50
33
|
dollar
|
|
51
34
|
when "*", "_", "`", "~"
|
|
52
35
|
marker peek
|
|
53
36
|
add peek
|
|
54
37
|
when LF
|
|
55
|
-
break if eos?
|
|
38
|
+
break if eos?
|
|
56
39
|
when nil
|
|
57
40
|
break
|
|
58
41
|
else
|
|
@@ -72,6 +55,20 @@ class FormatLine < StringParser
|
|
|
72
55
|
end
|
|
73
56
|
end
|
|
74
57
|
|
|
58
|
+
def var_func_parse
|
|
59
|
+
char = self.peek
|
|
60
|
+
loop do
|
|
61
|
+
char = self.grab
|
|
62
|
+
break if char == LF || char == nil
|
|
63
|
+
self.handle_escaping if char == Escape
|
|
64
|
+
self.dollar if char == "$" # Could be $$
|
|
65
|
+
self.add char
|
|
66
|
+
end
|
|
67
|
+
self.add_token(:str)
|
|
68
|
+
result = self.evaluate
|
|
69
|
+
result
|
|
70
|
+
end
|
|
71
|
+
|
|
75
72
|
def self.var_func_parse(str)
|
|
76
73
|
return nil if str.nil?
|
|
77
74
|
x = self.new(str.chomp)
|
|
@@ -80,7 +77,7 @@ class FormatLine < StringParser
|
|
|
80
77
|
char = x.grab
|
|
81
78
|
break if char == LF || char == nil
|
|
82
79
|
x.handle_escaping if char == Escape
|
|
83
|
-
x.dollar if char == "$"
|
|
80
|
+
x.dollar if char == "$" # Could be $$
|
|
84
81
|
x.add char
|
|
85
82
|
end
|
|
86
83
|
x.add_token(:str)
|
|
@@ -107,22 +104,10 @@ class FormatLine < StringParser
|
|
|
107
104
|
break if token.nil?
|
|
108
105
|
sym, val = *token
|
|
109
106
|
case sym
|
|
110
|
-
when :str
|
|
111
|
-
|
|
112
|
-
when :
|
|
113
|
-
|
|
114
|
-
when :func
|
|
115
|
-
param = nil
|
|
116
|
-
arg = gen.peek
|
|
117
|
-
if [:colon, :brackets].include? arg[0]
|
|
118
|
-
arg = gen.next # for real
|
|
119
|
-
param = arg[1]
|
|
120
|
-
param = Livetext.interpolate(param)
|
|
121
|
-
end
|
|
122
|
-
@out << funcall(val, param)
|
|
123
|
-
when :b, :i, :t, :s
|
|
124
|
-
val = Livetext.interpolate(val)
|
|
125
|
-
@out << embed(sym, val)
|
|
107
|
+
when :str; eval_str(val)
|
|
108
|
+
when :var; eval_var(val)
|
|
109
|
+
when :func; eval_func(val, gen)
|
|
110
|
+
when *BITS; eval_bits(sym, val)
|
|
126
111
|
else
|
|
127
112
|
add_token :str
|
|
128
113
|
end
|
|
@@ -131,48 +116,6 @@ class FormatLine < StringParser
|
|
|
131
116
|
@out
|
|
132
117
|
end
|
|
133
118
|
|
|
134
|
-
def grab_colon_param
|
|
135
|
-
grab # grab :
|
|
136
|
-
param = ""
|
|
137
|
-
loop do
|
|
138
|
-
case next!
|
|
139
|
-
when Escape
|
|
140
|
-
grab
|
|
141
|
-
param << next!
|
|
142
|
-
grab
|
|
143
|
-
when Space, LF, nil; break
|
|
144
|
-
else
|
|
145
|
-
param << next!
|
|
146
|
-
grab
|
|
147
|
-
end
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
param = nil if param.empty?
|
|
151
|
-
param
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
def grab_func_param
|
|
155
|
-
grab # [
|
|
156
|
-
param = ""
|
|
157
|
-
loop do
|
|
158
|
-
case next!
|
|
159
|
-
when Escape
|
|
160
|
-
grab
|
|
161
|
-
param << next!
|
|
162
|
-
grab
|
|
163
|
-
when "]", LF, nil; break
|
|
164
|
-
else
|
|
165
|
-
param << next!
|
|
166
|
-
grab
|
|
167
|
-
end
|
|
168
|
-
end
|
|
169
|
-
|
|
170
|
-
add peek
|
|
171
|
-
grab
|
|
172
|
-
param = nil if param.empty?
|
|
173
|
-
param
|
|
174
|
-
end
|
|
175
|
-
|
|
176
119
|
def add(str)
|
|
177
120
|
@token << str unless str.nil?
|
|
178
121
|
end
|
|
@@ -189,7 +132,7 @@ class FormatLine < StringParser
|
|
|
189
132
|
loop do
|
|
190
133
|
break if eos?
|
|
191
134
|
str << peek
|
|
192
|
-
break if terminate?(NoAlpha,
|
|
135
|
+
break if terminate?(NoAlpha, lookahead)
|
|
193
136
|
grab
|
|
194
137
|
end
|
|
195
138
|
str
|
|
@@ -201,7 +144,7 @@ class FormatLine < StringParser
|
|
|
201
144
|
loop do
|
|
202
145
|
break if peek.nil? # eos?
|
|
203
146
|
str << peek
|
|
204
|
-
break if terminate?(NoAlphaDot,
|
|
147
|
+
break if terminate?(NoAlphaDot, lookahead)
|
|
205
148
|
grab
|
|
206
149
|
end
|
|
207
150
|
str
|
|
@@ -216,7 +159,7 @@ class FormatLine < StringParser
|
|
|
216
159
|
when "$"; double_dollar
|
|
217
160
|
# when "."; dollar_dot
|
|
218
161
|
when /[A-Za-z]/
|
|
219
|
-
|
|
162
|
+
add_token :str
|
|
220
163
|
var = peek + grab_alpha_dot
|
|
221
164
|
add_token(:var, var)
|
|
222
165
|
else
|
|
@@ -225,23 +168,6 @@ class FormatLine < StringParser
|
|
|
225
168
|
end
|
|
226
169
|
end
|
|
227
170
|
|
|
228
|
-
def double_dollar
|
|
229
|
-
case next!
|
|
230
|
-
when Space; add_token :string, "$$ "; grab; return
|
|
231
|
-
when LF, nil; add "$$"; add_token :str
|
|
232
|
-
when Alpha
|
|
233
|
-
add_token(:str, @token)
|
|
234
|
-
func = grab_alpha
|
|
235
|
-
add_token(:func, func)
|
|
236
|
-
case next!
|
|
237
|
-
when ":"; param = grab_colon_param; add_token(:colon, param)
|
|
238
|
-
when "["; param = grab_func_param; add_token(:brackets, param)
|
|
239
|
-
end
|
|
240
|
-
else
|
|
241
|
-
grab; add_token :str, "$$" + peek; return
|
|
242
|
-
end
|
|
243
|
-
end
|
|
244
|
-
|
|
245
171
|
# def dollar_dot
|
|
246
172
|
# add_token :ddot, @line[@i..-1]
|
|
247
173
|
# end
|
|
@@ -276,7 +202,7 @@ class FormatLine < StringParser
|
|
|
276
202
|
def double_marker(char)
|
|
277
203
|
sym = Syms[char]
|
|
278
204
|
kind = sym
|
|
279
|
-
case
|
|
205
|
+
case lookahead # first char after **
|
|
280
206
|
when Space, LF, nil
|
|
281
207
|
pre, post = SimpleFormats[sym]
|
|
282
208
|
add_token kind
|
|
@@ -317,13 +243,12 @@ class FormatLine < StringParser
|
|
|
317
243
|
add str
|
|
318
244
|
str
|
|
319
245
|
rescue => err
|
|
320
|
-
STDERR.puts "ERR = #{err}\n#{err.backtrace}"
|
|
321
|
-
STDERR.puts "=== str = #{str.inspect}"
|
|
246
|
+
::STDERR.puts "ERR = #{err}\n#{err.backtrace}"
|
|
322
247
|
end
|
|
323
248
|
|
|
324
249
|
def escaped
|
|
325
|
-
grab
|
|
326
|
-
ch = grab
|
|
250
|
+
grab # Eat the backslash
|
|
251
|
+
ch = grab # Take next char
|
|
327
252
|
ch
|
|
328
253
|
end
|
|
329
254
|
|
|
@@ -350,28 +275,47 @@ class FormatLine < StringParser
|
|
|
350
275
|
add str
|
|
351
276
|
str
|
|
352
277
|
rescue => err
|
|
353
|
-
STDERR.puts "ERR = #{err}\n#{err.backtrace}"
|
|
354
|
-
STDERR.puts "=== str = #{str.inspect}"
|
|
355
|
-
end
|
|
356
|
-
|
|
357
|
-
def funcall(name, param)
|
|
358
|
-
err = "[Error evaluating $$#{name}(#{param})]"
|
|
359
|
-
result =
|
|
360
|
-
if self.respond_to?("func_" + name.to_s)
|
|
361
|
-
self.send("func_" + name.to_s, param)
|
|
362
|
-
else
|
|
363
|
-
fobj = ::Livetext::Functions.new
|
|
364
|
-
fobj.send(name, param) rescue err
|
|
365
|
-
end
|
|
366
|
-
result
|
|
278
|
+
::STDERR.puts "ERR = #{err}\n#{err.backtrace}"
|
|
367
279
|
end
|
|
368
280
|
|
|
369
281
|
def varsub(name)
|
|
370
|
-
|
|
282
|
+
live = Livetext.new
|
|
283
|
+
value = live.vars[name]
|
|
284
|
+
result = value || "[#{name} is undefined]"
|
|
371
285
|
result
|
|
372
286
|
end
|
|
373
287
|
|
|
374
288
|
def embedded?
|
|
375
289
|
! (['"', "'", " ", nil].include? prev)
|
|
376
290
|
end
|
|
291
|
+
|
|
292
|
+
private
|
|
293
|
+
|
|
294
|
+
def eval_bits(sym, val)
|
|
295
|
+
val = Livetext.interpolate(val)
|
|
296
|
+
@out << embed(sym, val)
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
def eval_func(val, gen)
|
|
300
|
+
param = nil
|
|
301
|
+
arg = gen.peek rescue :bogus
|
|
302
|
+
unless arg == :bogus
|
|
303
|
+
if [:colon, :brackets].include? arg[0]
|
|
304
|
+
arg = gen.next # for real
|
|
305
|
+
param = arg[1]
|
|
306
|
+
# FIXME - unsure - interpolate again??
|
|
307
|
+
# param = Livetext.interpolate(param)
|
|
308
|
+
end
|
|
309
|
+
end
|
|
310
|
+
@out << funcall(val, param)
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
def eval_var(val)
|
|
314
|
+
@out << varsub(val)
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
def eval_str(val)
|
|
318
|
+
@out << val unless val == "\n" # BUG
|
|
319
|
+
end
|
|
320
|
+
|
|
377
321
|
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
|
|
2
|
+
require_relative '../livetext'
|
|
3
|
+
|
|
4
|
+
# Parse function calls
|
|
5
|
+
|
|
6
|
+
module Livetext::FormatLine::FunCall
|
|
7
|
+
|
|
8
|
+
include Livetext::ParsingConstants
|
|
9
|
+
|
|
10
|
+
def param_loop(char)
|
|
11
|
+
param = ""
|
|
12
|
+
loop do
|
|
13
|
+
case lookahead
|
|
14
|
+
when Escape
|
|
15
|
+
param << escaped
|
|
16
|
+
when char, LF, nil
|
|
17
|
+
break
|
|
18
|
+
else
|
|
19
|
+
param << lookahead
|
|
20
|
+
grab
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
param = nil if param.empty?
|
|
24
|
+
param
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def grab_colon_param
|
|
28
|
+
grab # grab :
|
|
29
|
+
param = param_loop(Space)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def grab_bracket_param
|
|
33
|
+
grab # [
|
|
34
|
+
param = param_loop("]")
|
|
35
|
+
grab # "]"
|
|
36
|
+
param
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def funcall(name, param)
|
|
40
|
+
err = "[Error evaluating $$#{name}(#{param})]"
|
|
41
|
+
func_name = name # "func_" + name.to_s
|
|
42
|
+
result =
|
|
43
|
+
if self.send?(func_name, param) # self.respond_to?(func_name)
|
|
44
|
+
# do nothing
|
|
45
|
+
else
|
|
46
|
+
fobj = ::Livetext::Functions.new
|
|
47
|
+
fobj.send(name, param) rescue err
|
|
48
|
+
end
|
|
49
|
+
result.to_s
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def double_dollar
|
|
53
|
+
case lookahead
|
|
54
|
+
when Space; add_token :string, "$$ "; grab; return
|
|
55
|
+
when LF, nil; add "$$"; add_token :str
|
|
56
|
+
when Alpha
|
|
57
|
+
add_token(:str, @token)
|
|
58
|
+
func = grab_alpha
|
|
59
|
+
add_token(:func, func)
|
|
60
|
+
param = grab_func_param # may be null/missing
|
|
61
|
+
else
|
|
62
|
+
grab; add_token :str, "$$" + peek; return
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def grab_func_param
|
|
67
|
+
case lookahead
|
|
68
|
+
when "["
|
|
69
|
+
param = grab_bracket_param
|
|
70
|
+
add_token(:brackets, param)
|
|
71
|
+
when ":"
|
|
72
|
+
param = grab_colon_param
|
|
73
|
+
add_token(:colon, param)
|
|
74
|
+
else # do nothing
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def escaped
|
|
79
|
+
grab # Eat the backslash
|
|
80
|
+
ch = grab # Take next char
|
|
81
|
+
ch
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
end
|