livetext 0.9.25 → 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/imports/bookish.rb +1 -2
- data/lib/livetext/errors.rb +3 -0
- data/lib/livetext/formatline.rb +102 -15
- data/lib/livetext/funcall.rb +86 -2
- data/lib/livetext/global_helpers.rb +5 -0
- data/lib/livetext/handler/import.rb +2 -6
- data/lib/livetext/handler/mixin.rb +2 -6
- data/lib/livetext/helpers.rb +9 -11
- data/lib/livetext/lineparser.rb +441 -0
- data/lib/livetext/more.rb +158 -0
- data/lib/livetext/processor.rb +3 -1
- data/lib/livetext/skeleton.rb +5 -0
- data/lib/livetext/standard.rb +12 -8
- data/lib/livetext/userapi.rb +27 -10
- data/lib/livetext/version.rb +1 -1
- data/lib/livetext.rb +3 -152
- data/test/snapshots/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/error_invalid_name/foo +5 -0
- data/test/snapshots/import_bookish/expected-output.txt +4 -4
- data/test/snapshots/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/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/subset.txt +2 -0
- data/test/snapshots/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/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/unit/all.rb +3 -1
- data/test/unit/formatline.rb +143 -274
- data/test/unit/lineparser.rb +650 -0
- data/test/unit/parser/set.rb +13 -12
- data/test/unit/tokenizer.rb +534 -0
- metadata +26 -5
- data/test/snapshots/error_inc_line_num/OUT +0 -17
- data/test/snapshots/error_no_such_copy/duh +0 -26
- data/test/snapshots/error_no_such_copy/mystery.txt +0 -36
data/lib/livetext/userapi.rb
CHANGED
@@ -1,10 +1,16 @@
|
|
1
1
|
|
2
|
-
require_relative 'formatline'
|
2
|
+
# require_relative 'formatline' # FIXME meh, because of #format
|
3
|
+
require_relative 'lineparser' # FIXME meh, because of #format
|
3
4
|
|
4
5
|
# Encapsulate the UserAPI as a class
|
5
6
|
|
6
7
|
class Livetext::UserAPI
|
7
8
|
|
9
|
+
KBD = File.new("/dev/tty", "r")
|
10
|
+
TTY = File.new("/dev/tty", "w")
|
11
|
+
|
12
|
+
DotSpace = ". " # Livetext::Sigil + Livetext::Space
|
13
|
+
|
8
14
|
attr_accessor :data, :args
|
9
15
|
|
10
16
|
def initialize(live)
|
@@ -12,11 +18,16 @@ class Livetext::UserAPI
|
|
12
18
|
@vars = live.vars
|
13
19
|
end
|
14
20
|
|
21
|
+
def api
|
22
|
+
@live.api
|
23
|
+
end
|
24
|
+
|
25
|
+
def dot
|
26
|
+
@live
|
27
|
+
end
|
28
|
+
|
15
29
|
def setvar(var, val)
|
16
|
-
#
|
17
|
-
str, sym = var.to_s, var.to_sym
|
18
|
-
Livetext::Vars[str] = val
|
19
|
-
Livetext::Vars[sym] = val
|
30
|
+
Livetext::Vars[var] = val # Now indifferent and "safe"
|
20
31
|
end
|
21
32
|
|
22
33
|
def check_existence(file, msg)
|
@@ -24,6 +35,7 @@ class Livetext::UserAPI
|
|
24
35
|
end
|
25
36
|
|
26
37
|
def data=(value)
|
38
|
+
# TTY.puts "in #{__FILE__}: api = #{@live.api.inspect}"
|
27
39
|
@data = value
|
28
40
|
@args = format(@data).chomp.split
|
29
41
|
end
|
@@ -45,9 +57,7 @@ class Livetext::UserAPI
|
|
45
57
|
end
|
46
58
|
|
47
59
|
def comment?(str)
|
48
|
-
|
49
|
-
c1 = sigil + Livetext::Space
|
50
|
-
str.index(c1) == 0
|
60
|
+
str.index(DotSpace) == 0
|
51
61
|
end
|
52
62
|
|
53
63
|
def trailing?(char)
|
@@ -110,8 +120,7 @@ class Livetext::UserAPI
|
|
110
120
|
|
111
121
|
def format(line)
|
112
122
|
return "" if line == "\n" || line.nil?
|
113
|
-
line2 = Livetext::
|
114
|
-
# line.replace(line2)
|
123
|
+
line2 = Livetext::LineParser.parse!(line)
|
115
124
|
line2
|
116
125
|
end
|
117
126
|
|
@@ -133,6 +142,14 @@ class Livetext::UserAPI
|
|
133
142
|
@live.body << str # no newline
|
134
143
|
end
|
135
144
|
|
145
|
+
def tty(*args)
|
146
|
+
TTY.puts *args
|
147
|
+
end
|
148
|
+
|
149
|
+
def err(*args)
|
150
|
+
STDERR.puts *args
|
151
|
+
end
|
152
|
+
|
136
153
|
def puts(*args)
|
137
154
|
@live.output.puts *args
|
138
155
|
end
|
data/lib/livetext/version.rb
CHANGED
data/lib/livetext.rb
CHANGED
@@ -9,160 +9,11 @@ require_relative 'livetext/errors'
|
|
9
9
|
require_relative 'livetext/standard'
|
10
10
|
require_relative 'livetext/functions'
|
11
11
|
require_relative 'livetext/userapi'
|
12
|
-
require_relative 'livetext/formatline'
|
12
|
+
# require_relative 'livetext/formatline'
|
13
|
+
require_relative 'livetext/lineparser'
|
13
14
|
require_relative 'livetext/processor'
|
14
15
|
require_relative 'livetext/helpers'
|
15
16
|
require_relative 'livetext/handler'
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
make_exception(:EndWithoutOpening, "Error: found .end with no opening command")
|
20
|
-
make_exception(:UnknownMethod, "Error: name '%1' is unknown")
|
21
|
-
|
22
|
-
# Class Livetext reopened (top level).
|
23
|
-
|
24
|
-
class Livetext
|
25
|
-
|
26
|
-
include Helpers
|
27
|
-
|
28
|
-
Vars = {}
|
29
|
-
|
30
|
-
TTY = ::File.open("/dev/tty", "w")
|
31
|
-
|
32
|
-
attr_reader :main, :sources
|
33
|
-
attr_accessor :nopass, :nopara
|
34
|
-
attr_accessor :body, :indentation
|
35
|
-
|
36
|
-
class << self
|
37
|
-
attr_accessor :output # bad solution?
|
38
|
-
end
|
39
|
-
|
40
|
-
def vars
|
41
|
-
@_vars
|
42
|
-
end
|
43
|
-
|
44
|
-
def self.interpolate(str)
|
45
|
-
# FIXME There are issues here...
|
46
|
-
# Livetext::FormatLine.var_func_parse(str)
|
47
|
-
parse = Livetext::FormatLine.new(str)
|
48
|
-
parse.var_func_parse
|
49
|
-
end
|
50
|
-
|
51
|
-
def self.customize(mix: [], call: [], vars: {})
|
52
|
-
obj = self.new
|
53
|
-
mix = Array(mix)
|
54
|
-
call = Array(call)
|
55
|
-
mix.each {|lib| obj.mixin(lib) }
|
56
|
-
call.each {|cmd| obj.main.send(cmd[1..-1]) } # ignores leading dot, no param
|
57
|
-
vars.each_pair {|var, val| obj.setvar(var, val.to_s) }
|
58
|
-
obj
|
59
|
-
end
|
60
|
-
|
61
|
-
def peek_nextline
|
62
|
-
@main.peek_nextline # delegate
|
63
|
-
end
|
64
|
-
|
65
|
-
def nextline
|
66
|
-
@main.nextline # delegate
|
67
|
-
end
|
68
|
-
|
69
|
-
def sources
|
70
|
-
@main.sources # delegate
|
71
|
-
end
|
72
|
-
|
73
|
-
def save_location
|
74
|
-
@save_location # delegate
|
75
|
-
end
|
76
|
-
|
77
|
-
def save_location=(where)
|
78
|
-
@save_location = where # delegate
|
79
|
-
end
|
80
|
-
|
81
|
-
def dump(file = nil) # not a dot command!
|
82
|
-
file ||= ::STDOUT
|
83
|
-
file.puts @body
|
84
|
-
rescue => err
|
85
|
-
TTY.puts "#dump had an error: #{err.inspect}"
|
86
|
-
end
|
87
|
-
|
88
|
-
def graceful_error(err)
|
89
|
-
dump
|
90
|
-
raise err
|
91
|
-
end
|
92
|
-
|
93
|
-
def customize(mix: [], call: [], vars: {})
|
94
|
-
mix = Array(mix)
|
95
|
-
call = Array(call)
|
96
|
-
mix.each {|lib| mixin(lib) }
|
97
|
-
call.each {|cmd| @main.send(cmd[1..-1]) } # ignores leading dot, no param
|
98
|
-
vars.each_pair {|var, val| setvar(var, val.to_s) }
|
99
|
-
self
|
100
|
-
end
|
101
|
-
|
102
|
-
def initialize(output = ::STDOUT)
|
103
|
-
@source = nil
|
104
|
-
@_mixins = []
|
105
|
-
@_imports = []
|
106
|
-
@_outdir = "."
|
107
|
-
@no_puts = output.nil?
|
108
|
-
@body = ""
|
109
|
-
@main = Processor.new(self, output)
|
110
|
-
@indentation = [0]
|
111
|
-
@_vars = Livetext::Vars
|
112
|
-
initial_vars
|
113
|
-
@api = UserAPI.new(self)
|
114
|
-
end
|
115
|
-
|
116
|
-
def api
|
117
|
-
@api
|
118
|
-
end
|
119
|
-
|
120
|
-
def interpolate(str)
|
121
|
-
end
|
122
|
-
|
123
|
-
def initial_vars
|
124
|
-
# Other predefined variables (see also setfile)
|
125
|
-
setvar(:User, `whoami`.chomp)
|
126
|
-
setvar(:Version, Livetext::VERSION)
|
127
|
-
end
|
128
|
-
|
129
|
-
def transform(text)
|
130
|
-
setfile!("(string)")
|
131
|
-
enum = text.each_line
|
132
|
-
front = text.match(/.*?\n/).to_a.first.chomp rescue ""
|
133
|
-
@main.source(enum, "STDIN: '#{front}...'", 0)
|
134
|
-
loop do
|
135
|
-
line = @main.nextline
|
136
|
-
break if line.nil?
|
137
|
-
process_line(line)
|
138
|
-
end
|
139
|
-
result = @body
|
140
|
-
# @body = ""
|
141
|
-
result
|
142
|
-
end
|
143
|
-
|
144
|
-
# EXPERIMENTAL and incomplete
|
145
|
-
def xform(*args, file: nil, text: nil, vars: {})
|
146
|
-
case
|
147
|
-
when file && text.nil?
|
148
|
-
xform_file(file)
|
149
|
-
when file.nil? && text
|
150
|
-
transform(text)
|
151
|
-
when file.nil? && text.nil?
|
152
|
-
raise "Must specify file or text"
|
153
|
-
when file && text
|
154
|
-
raise "Cannot specify file and text"
|
155
|
-
end
|
156
|
-
self.process_file(file)
|
157
|
-
self.body
|
158
|
-
end
|
159
|
-
|
160
|
-
def xform_file(file, vars: nil)
|
161
|
-
Livetext::Vars.replace(vars) unless vars.nil?
|
162
|
-
@_vars.replace(vars) unless vars.nil?
|
163
|
-
self.process_file(file)
|
164
|
-
self.body
|
165
|
-
end
|
166
|
-
|
167
|
-
end
|
18
|
+
require_relative 'livetext/more'
|
168
19
|
|
File without changes
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Here are examples of <b>boldface</b>
|
2
|
+
and <i>italics</i>
|
3
|
+
and <font size=+1><tt>code</tt></font>
|
4
|
+
as well as <b>ore complex</b>*examples
|
5
|
+
of <i>talicized text</i>
|
6
|
+
and <font size=+1><tt>ode font</tt></font>
|
7
|
+
<p>
|
8
|
+
|
9
|
+
Here are some random punctuation marks:
|
10
|
+
; # . * * ` ` @ % ^ & $
|
11
|
+
<p>
|
12
|
+
|
13
|
+
No need to escape these: * * `
|
@@ -0,0 +1 @@
|
|
1
|
+
ACTUAL | EXPECTED
|
@@ -0,0 +1,14 @@
|
|
1
|
+
ACTUAL | EXPECTED
|
2
|
+
Here are examples of <b>boldface</b> | Here are examples of <b>boldface</b>
|
3
|
+
and <i>italics</i> and <i>italics</i>
|
4
|
+
and <font size=+1><tt>code</tt></font> and <font size=+1><tt>code</tt></font>
|
5
|
+
as well as <b>ore complex</b>*examples | as well as <b>more complex</b> examples
|
6
|
+
of <i>talicized text</i> | of <i>italicized text</i>
|
7
|
+
and <font size=+1><tt>ode font</tt></font> | and <font size=+1><tt>code font</tt></font>.
|
8
|
+
<p> <p>
|
9
|
+
|
10
|
+
Here are some random punctuation marks: Here are some random punctuation marks:
|
11
|
+
; # . * * ` ` @ % ^ & $ | ; # . * _ ` : @ % ^ & $
|
12
|
+
<p> <p>
|
13
|
+
|
14
|
+
No need to escape these: * * ` | No need to escape these: * _ `
|
@@ -1,10 +1,10 @@
|
|
1
1
|
<table cellpadding=2>
|
2
2
|
<tr>
|
3
|
-
<td width=
|
4
|
-
<td width=
|
3
|
+
<td width=0% valign=top>this</td>
|
4
|
+
<td width=0% valign=top>that</td>
|
5
5
|
</tr>
|
6
6
|
<tr>
|
7
|
-
<td width=
|
8
|
-
<td width=
|
7
|
+
<td width=0% valign=top>foo</td>
|
8
|
+
<td width=0% valign=top>bar</td>
|
9
9
|
</tr>
|
10
10
|
</table>
|
File without changes
|
@@ -0,0 +1,37 @@
|
|
1
|
+
Testing some more functions here...
|
2
|
+
<p>
|
3
|
+
|
4
|
+
Here I am calling a function with
|
5
|
+
a colon parameter...
|
6
|
+
<p>
|
7
|
+
|
8
|
+
<p>
|
9
|
+
|
10
|
+
Next let's <b>do</b>*something with our parameter:
|
11
|
+
<p>
|
12
|
+
|
13
|
+
I'll call these variants...
|
14
|
+
<p>
|
15
|
+
|
16
|
+
"Motel" spelled backwards is letom :)
|
17
|
+
<p>
|
18
|
+
|
19
|
+
"lamina" reversed is animal
|
20
|
+
<p>
|
21
|
+
|
22
|
+
I can also use the erutaef tekcarb here.
|
23
|
+
<p>
|
24
|
+
|
25
|
+
If I don't use a parameter for [Error evaluating $$reverse()] - it gives
|
26
|
+
me an error. (Bug or feature??)
|
27
|
+
<p>
|
28
|
+
|
29
|
+
What if a function doesn't use parameters at all, but
|
30
|
+
we pass them? Hmm...
|
31
|
+
<p>
|
32
|
+
|
33
|
+
Now we succeed and succeed some more
|
34
|
+
and finally we succeed in life.
|
35
|
+
<p>
|
36
|
+
|
37
|
+
But can we succeed, when our beds are burning?
|
@@ -0,0 +1 @@
|
|
1
|
+
ACTUAL | EXPECTED
|
@@ -0,0 +1,38 @@
|
|
1
|
+
ACTUAL | EXPECTED
|
2
|
+
Testing some more functions here... Testing some more functions here...
|
3
|
+
<p> <p>
|
4
|
+
|
5
|
+
Here I am calling a function with Here I am calling a function with
|
6
|
+
a colon parameter... a colon parameter...
|
7
|
+
<p> <p>
|
8
|
+
|
9
|
+
<p> <p>
|
10
|
+
|
11
|
+
Next let's <b>do</b>*something with our parameter: | Next let's <b>do</b> something with our parameter:
|
12
|
+
<p> <p>
|
13
|
+
|
14
|
+
I'll call these variants... I'll call these variants...
|
15
|
+
<p> <p>
|
16
|
+
|
17
|
+
"Motel" spelled backwards is letom :) "Motel" spelled backwards is letom :)
|
18
|
+
<p> <p>
|
19
|
+
|
20
|
+
"lamina" reversed is animal "lamina" reversed is animal
|
21
|
+
<p> <p>
|
22
|
+
|
23
|
+
I can also use the erutaef tekcarb here. I can also use the erutaef tekcarb here.
|
24
|
+
<p> <p>
|
25
|
+
|
26
|
+
If I don't use a parameter for [Error evaluating $$reverse( If I don't use a parameter for [Error evaluating $$reverse(
|
27
|
+
me an error. (Bug or feature??) me an error. (Bug or feature??)
|
28
|
+
<p> <p>
|
29
|
+
|
30
|
+
What if a function doesn't use parameters at all, but What if a function doesn't use parameters at all, but
|
31
|
+
we pass them? Hmm... we pass them? Hmm...
|
32
|
+
<p> <p>
|
33
|
+
|
34
|
+
Now we succeed and succeed some more Now we succeed and succeed some more
|
35
|
+
and finally we succeed in life. and finally we succeed in life.
|
36
|
+
<p> <p>
|
37
|
+
|
38
|
+
But can we succeed, when our beds are burning? But can we succeed, when our beds are burning?
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
ACTUAL | EXPECTED
|
@@ -0,0 +1,7 @@
|
|
1
|
+
ACTUAL | EXPECTED
|
2
|
+
Just Just
|
3
|
+
some text. some text.
|
4
|
+
Hi, there. Hi, there.
|
5
|
+
GulliverFoyle is my name, and Terra is my nation. GulliverFoyle is my name, and Terra is my nation.
|
6
|
+
I'm GulliverFoyle, from Terra | I'm GulliverFoyle, from Terra.
|
7
|
+
That's all. That's all.
|
data/test/snapshots/subset.txt
CHANGED
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
ACTUAL | EXPECTED
|
File without changes
|
@@ -0,0 +1,17 @@
|
|
1
|
+
ACTUAL | EXPECTED
|
2
|
+
<p> <p>
|
3
|
+
|
4
|
+
Testing STILL more functions here... Testing STILL more functions here...
|
5
|
+
<p> <p>
|
6
|
+
|
7
|
+
<p> <p>
|
8
|
+
|
9
|
+
Now... let's try passing a variable to a function. Will thi Now... let's try passing a variable to a function. Will thi
|
10
|
+
<p> <p>
|
11
|
+
|
12
|
+
Variable \regal is regal, which reversed is ahpla$ | Variable $alpha is regal, which reversed is lager
|
13
|
+
<p> <p>
|
14
|
+
|
15
|
+
That's all. That's all.
|
16
|
+
<p> <p>
|
17
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
|
2
|
+
Testing STILL more functions here...
|
3
|
+
|
4
|
+
|
5
|
+
.func reverse
|
6
|
+
param.reverse # just reverse it
|
7
|
+
.end
|
8
|
+
|
9
|
+
Now... let's try passing a variable to a function. Will this work??
|
10
|
+
|
11
|
+
.set alpha = regal
|
12
|
+
|
13
|
+
Variable \$alpha is $alpha, which reversed is $$reverse:$alpha
|
14
|
+
|
15
|
+
That's all.
|
16
|
+
|