livetext 0.9.30 → 0.9.31
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 +1 -1
- data/lib/livetext/expansion.rb +15 -13
- data/lib/livetext/formatter.rb +206 -87
- data/lib/livetext/helpers.rb +24 -13
- data/lib/livetext/standard.rb +62 -57
- data/lib/livetext/userapi.rb +13 -2
- data/lib/livetext/version.rb +1 -1
- data/plugin/bookish.rb +1 -1
- data/test/extra/README.txt +149 -0
- data/test/extra/bracketed.rb +121 -0
- data/test/extra/bracketed.txt +44 -0
- data/test/extra/double.rb +121 -0
- data/test/extra/double.txt +44 -0
- data/test/extra/functions.rb +148 -0
- data/test/extra/functions.txt +58 -0
- data/test/extra/single.rb +139 -0
- data/test/extra/single.txt +52 -0
- data/test/extra/testgen.rb +104 -0
- data/test/{snapshots/bootstrap_menu/expected-error.txt → extra/variables..rb} +0 -0
- data/test/extra/variables.rb +94 -0
- data/test/extra/variables.txt +35 -0
- data/test/snapshots/basic_formatting/expected-output.txt +2 -1
- data/test/snapshots/import_bookish/toc.tmp +0 -0
- data/test/snapshots/mixin_bookish/toc.tmp +0 -0
- data/test/snapshots/simple_vars/source.lt3 +1 -1
- data/test/snapshots/subset.txt +0 -2
- data/test/unit/all.rb +1 -2
- metadata +17 -9
- data/test/snapshots/bootstrap_menu/expected-output.txt +0 -4
- data/test/snapshots/bootstrap_menu/source.lt3 +0 -17
- data/test/snapshots/error_inc_line_num/README.txt +0 -20
- data/test/snapshots/error_invalid_name/foo +0 -5
- data/test/unit/lineparser.rb +0 -359
- data/test/unit/new_lineparser.rb +0 -359
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 769c4da93282df68e38011277d71ee8334fd14d4f87061c803d3d9643564afc7
|
4
|
+
data.tar.gz: 9b8611007ecbc2d4e899575cf504e6f87c9b1887df2b59ef8ff56a072f5e9e92
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2904613247a614b01a8b80ecefb9197ba070e69ebad4d292e3ce77b3f4ddf5b60850ad554333c1e2f8a54cf56b765c799ae52fd7491fd24648b570313ba401c6
|
7
|
+
data.tar.gz: e698ca1431dc18d64d1b44fc9edebe033c382dcc49252602cbf74c398c8f6fc38fea2dbe3d3a056fe550eca6291157bfba53e240d416a97bd1f3cca8ea4ec141
|
data/imports/bookish.rb
CHANGED
data/lib/livetext/expansion.rb
CHANGED
@@ -12,21 +12,23 @@ class Livetext::Expansion
|
|
12
12
|
@live = instance
|
13
13
|
end
|
14
14
|
|
15
|
-
def format(line)
|
15
|
+
def format(line)
|
16
16
|
return "" if line == "\n" || line.nil?
|
17
|
-
|
18
|
-
with_vars = expand_variables(formatted)
|
17
|
+
with_vars = expand_variables(line)
|
19
18
|
with_func = expand_function_calls(with_vars)
|
19
|
+
formatted = Formatter.format(with_func)
|
20
20
|
end
|
21
21
|
|
22
22
|
def expand_variables(str)
|
23
23
|
rx = Regexp.compile("(?<result>" + Var + Dotted + ")")
|
24
|
-
enum = str.each_char
|
25
24
|
buffer = ""
|
26
25
|
loop do |i|
|
27
26
|
case # var or func or false alarm
|
28
27
|
when str.empty? # end of string
|
29
28
|
break
|
29
|
+
when str.slice(0..1) == "\\$" # escaped, ignore it
|
30
|
+
str.slice!(0..1)
|
31
|
+
buffer << "$"
|
30
32
|
when str.slice(0..1) == "$$" # func?
|
31
33
|
buffer << str.slice!(0..1)
|
32
34
|
when str.slice(0) == "$" # var?
|
@@ -41,7 +43,8 @@ class Livetext::Expansion
|
|
41
43
|
vars = @live.vars
|
42
44
|
buffer << vars.get(vsym)
|
43
45
|
else # other
|
44
|
-
|
46
|
+
char = str.slice!(0)
|
47
|
+
buffer << char
|
45
48
|
end
|
46
49
|
end
|
47
50
|
buffer
|
@@ -82,14 +85,12 @@ class Livetext::Expansion
|
|
82
85
|
param = fmatch["param"] # may be nil
|
83
86
|
full = fmatch["full_param"]
|
84
87
|
fsym = fname[2..-1] # no $$
|
85
|
-
=
|
86
|
-
puts "
|
87
|
-
puts "
|
88
|
-
puts "
|
89
|
-
puts "
|
90
|
-
puts "
|
91
|
-
puts "fsym = #{fsym.inspect}"
|
92
|
-
=end
|
88
|
+
#STDERR.puts "rx = #{rx.inspect}"
|
89
|
+
#STDERR.puts "fmatch = #{fmatch.inspect}"
|
90
|
+
#STDERR.puts "fname = #{fname.inspect}"
|
91
|
+
#STDERR.puts "param = #{param.inspect}"
|
92
|
+
#STDERR.puts "full = #{full.inspect}"
|
93
|
+
#STDERR.puts "fsym = #{fsym.inspect}"
|
93
94
|
str.sub!(fname, "")
|
94
95
|
str.sub!(full, "") if full
|
95
96
|
retval = funcall(fsym, param)
|
@@ -100,6 +101,7 @@ puts "fsym = #{fsym.inspect}"
|
|
100
101
|
buffer << char
|
101
102
|
end
|
102
103
|
end
|
104
|
+
# STDERR.puts "buffer = #{buffer.inspect}"
|
103
105
|
buffer
|
104
106
|
end
|
105
107
|
end
|
data/lib/livetext/formatter.rb
CHANGED
@@ -1,104 +1,223 @@
|
|
1
1
|
module Formatter
|
2
|
-
|
3
|
-
Start = /(?<start>(^| ))/
|
4
|
-
Stop = /(?<stop> |$)/
|
5
2
|
|
6
|
-
|
7
|
-
|
3
|
+
## Hmmm...
|
4
|
+
#
|
5
|
+
# Double: b, i, t, s
|
6
|
+
# Single: bits
|
7
|
+
# Brackt: bits
|
8
|
+
#
|
9
|
+
|
10
|
+
|
11
|
+
def self.format(str)
|
12
|
+
str = str.chomp
|
13
|
+
s2 = Double.process(str.chomp)
|
14
|
+
s3 = Bracketed.process(s2)
|
15
|
+
s4 = Single.process(s3)
|
16
|
+
s4
|
8
17
|
end
|
18
|
+
|
19
|
+
class Delimited
|
20
|
+
def initialize(str, marker, tag)
|
21
|
+
@str, @marker, @tag = str.dup, marker, tag
|
22
|
+
@buffer = ""
|
23
|
+
@cdata = ""
|
24
|
+
@state = :INITIAL
|
25
|
+
end
|
9
26
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
27
|
+
def status(where)
|
28
|
+
if $debug
|
29
|
+
STDERR.printf "%-11s %-7s #{@marker.inspect} \n #{' '*11} state = %-8s str = %-20s buffer = %-20s cdata = %-20s\n",
|
30
|
+
where, self.class, @state, @str.inspect, @buffer.inspect, @cdata.inspect
|
31
|
+
end
|
14
32
|
end
|
15
|
-
str
|
16
|
-
end
|
17
33
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
sigil = Regexp.escape(char+char)
|
22
|
-
rx = make_regex(sigil, cdata, stop)
|
23
|
-
str = iterate(str, rx, tag)
|
24
|
-
str
|
25
|
-
end
|
34
|
+
def front
|
35
|
+
@str[0]
|
36
|
+
end
|
26
37
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
38
|
+
def grab(n=1)
|
39
|
+
char = @str.slice!(0..(n-1)) # grab n chars
|
40
|
+
char
|
41
|
+
end
|
42
|
+
|
43
|
+
def grab_terminator
|
44
|
+
status("** grabterm 0")
|
45
|
+
@state = :LOOPING
|
46
|
+
# goes onto buffer by default
|
47
|
+
# Don't? what if searching for space_marker?
|
48
|
+
# @buffer << grab
|
49
|
+
end
|
50
|
+
|
51
|
+
def eol?
|
52
|
+
@str.empty?
|
53
|
+
end
|
54
|
+
|
55
|
+
def space?
|
56
|
+
front == " "
|
57
|
+
end
|
58
|
+
|
59
|
+
def escape?
|
60
|
+
front == "\\"
|
61
|
+
end
|
62
|
+
|
63
|
+
def terminated?
|
64
|
+
space? # Will be overridden except in Single
|
65
|
+
end
|
66
|
+
|
67
|
+
def marker?
|
68
|
+
@str.start_with?(@marker)
|
69
|
+
end
|
70
|
+
|
71
|
+
def space_marker?
|
72
|
+
@str.start_with?(" " + @marker)
|
73
|
+
end
|
34
74
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
75
|
+
def wrap(text)
|
76
|
+
status("** wrap 0")
|
77
|
+
if text.empty?
|
78
|
+
result = @marker
|
79
|
+
result = "" if @marker[1] == "["
|
80
|
+
return result
|
81
|
+
end
|
82
|
+
"<#{@tag}>#{text}</#{@tag}>"
|
83
|
+
end
|
84
|
+
|
85
|
+
def initial
|
86
|
+
status("** init 0")
|
87
|
+
n = @marker.length
|
88
|
+
case
|
89
|
+
when escape?
|
90
|
+
status("** esc i0")
|
91
|
+
grab # backslash
|
92
|
+
status("** esc i1")
|
93
|
+
@buffer << grab # char
|
94
|
+
status("** esc i2")
|
95
|
+
when space_marker?
|
96
|
+
status("** init 1")
|
97
|
+
@buffer << grab # append the space
|
98
|
+
grab(n) # eat the marker
|
99
|
+
@state = :CDATA
|
100
|
+
when marker?
|
101
|
+
status("** init 2")
|
102
|
+
grab(n) # Eat the marker
|
103
|
+
@state = :CDATA
|
104
|
+
when eol?
|
105
|
+
status("** init 3")
|
106
|
+
@state = :FINAL
|
107
|
+
else
|
108
|
+
status("** init 4")
|
109
|
+
@state = :BUFFER
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def buffer
|
114
|
+
status("** buffer 0")
|
115
|
+
@buffer << grab
|
116
|
+
@state = :LOOPING
|
117
|
+
end
|
118
|
+
|
119
|
+
def cdata
|
120
|
+
status("** cdata 0")
|
121
|
+
case
|
122
|
+
when eol?
|
123
|
+
status("** cdata 1")
|
124
|
+
if @cdata.empty?
|
125
|
+
status("** cdata 2")
|
126
|
+
@buffer << @marker unless @marker[1] == "["
|
127
|
+
else
|
128
|
+
status("** cdata 3")
|
129
|
+
@buffer << wrap(@cdata)
|
130
|
+
end
|
131
|
+
@state = :FINAL
|
132
|
+
when terminated?
|
133
|
+
status("** cdata 4")
|
134
|
+
@buffer << wrap(@cdata)
|
135
|
+
grab_terminator # "*a *b" case???
|
136
|
+
@cdata = ""
|
137
|
+
@state = :LOOPING
|
138
|
+
else
|
139
|
+
status("** cdata 5")
|
140
|
+
@cdata << grab
|
141
|
+
@state = :CDATA
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def looping
|
146
|
+
n = @marker.length
|
147
|
+
case
|
148
|
+
when escape?
|
149
|
+
status("** esc l0")
|
150
|
+
grab # backslash
|
151
|
+
status("** esc l1")
|
152
|
+
@buffer << grab # char
|
153
|
+
status("** esc l2")
|
154
|
+
when space_marker?
|
155
|
+
@buffer << grab # append the space
|
156
|
+
grab(n) # eat the marker
|
157
|
+
@state = :CDATA
|
158
|
+
when eol?
|
159
|
+
@state = :FINAL
|
160
|
+
else # includes marker not preceded by space!
|
161
|
+
@buffer << grab
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def handle
|
166
|
+
loop do
|
167
|
+
break if @state == :FINAL
|
168
|
+
meth = @state.downcase
|
169
|
+
send(meth)
|
170
|
+
end
|
171
|
+
return @buffer
|
172
|
+
end
|
173
|
+
|
174
|
+
def self.process(str)
|
175
|
+
bold = self.new(str, "*", "b")
|
176
|
+
sb = bold.handle
|
177
|
+
# return sb
|
178
|
+
ital = self.new(sb, "_", "i")
|
179
|
+
si = ital.handle
|
180
|
+
code = self.new(si, "`", "tt")
|
181
|
+
sc = code.handle
|
182
|
+
stri = self.new(sc, "~", "strike")
|
183
|
+
si = stri.handle
|
184
|
+
si
|
185
|
+
end
|
42
186
|
end
|
43
187
|
|
44
|
-
|
45
|
-
|
46
|
-
return [str, false] if md.nil?
|
47
|
-
start, cdata, stop = md.values_at(:start, :cdata, :stop)
|
48
|
-
str = str.sub(rx, start + "<#{tag}>" + cdata + "<\/#{tag}>" + stop)
|
49
|
-
[str, true]
|
188
|
+
class Single < Delimited
|
189
|
+
# Yeah, this one is that simple
|
50
190
|
end
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
191
|
+
|
192
|
+
class Double < Delimited
|
193
|
+
def initialize(str, sigil, tag)
|
194
|
+
super
|
195
|
+
# Convention: marker is "**", sigil is "*"
|
196
|
+
@marker = sigil + sigil
|
197
|
+
end
|
198
|
+
|
199
|
+
def terminated?
|
200
|
+
terms = [" ", ".", ","]
|
201
|
+
terms.include?(front)
|
202
|
+
end
|
57
203
|
end
|
58
204
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
205
|
+
class Bracketed < Delimited
|
206
|
+
def initialize(str, sigil, tag)
|
207
|
+
super
|
208
|
+
# Convention: marker is "*[", sigil is "*"
|
209
|
+
@marker = sigil + "["
|
210
|
+
end
|
211
|
+
|
212
|
+
def terminated?
|
213
|
+
front == "]" || eol?
|
214
|
+
end
|
215
|
+
|
216
|
+
def grab_terminator
|
217
|
+
@state = :LOOPING
|
218
|
+
grab
|
219
|
+
end
|
66
220
|
end
|
67
|
-
end
|
68
221
|
|
69
|
-
if $0 == __FILE__
|
70
|
-
# str = "**bold up front... This is **bold, __italic, and ``code."
|
71
|
-
str = "*bold and *bold and **more, and even *[more boldface] and *[still more] "
|
72
|
-
max = str.length
|
73
|
-
# str = "*bold "
|
74
|
-
s2 = Formatter.format(str)
|
75
|
-
printf "%-#{max}s => %-#{max}s\n", str.inspect, s2.inspect
|
76
|
-
exit
|
77
|
-
|
78
|
-
strings = ["*bold",
|
79
|
-
" *bold",
|
80
|
-
" *bold ",
|
81
|
-
"**bold.",
|
82
|
-
"**bold,",
|
83
|
-
"**bold",
|
84
|
-
" **bold.",
|
85
|
-
" **bold,",
|
86
|
-
" **bold",
|
87
|
-
" **bold. ",
|
88
|
-
" **bold, ",
|
89
|
-
" **bold ",
|
90
|
-
"*[fiat lux]",
|
91
|
-
" *[fiat lux]",
|
92
|
-
" *[fiat lux] ",
|
93
|
-
" *[fiat lux"
|
94
|
-
]
|
95
|
-
|
96
|
-
max = strings.max_by {|s| s.length }
|
97
|
-
max = max.length + 2
|
98
|
-
|
99
|
-
strings.each do |str|
|
100
|
-
s2 = Formatter.format(str)
|
101
|
-
printf "%-#{max}s => %-#{max}s\n", str.inspect, s2.inspect
|
102
222
|
end
|
103
223
|
|
104
|
-
end
|
data/lib/livetext/helpers.rb
CHANGED
@@ -10,6 +10,8 @@ module Livetext::Helpers
|
|
10
10
|
ESCAPING = { "'" => ''', '&' => '&', '"' => '"',
|
11
11
|
'<' => '<', '>' => '>' }
|
12
12
|
|
13
|
+
TTY = ::File.open("/dev/tty", "w")
|
14
|
+
|
13
15
|
def friendly_error(err)
|
14
16
|
return graceful_error(err) if self.respond_to?(:graceful_error)
|
15
17
|
return self.parent.graceful_error(err) if self.respond_to?(:parent)
|
@@ -100,14 +102,14 @@ module Livetext::Helpers
|
|
100
102
|
when DotCmd
|
101
103
|
success = handle_dotcmd(line)
|
102
104
|
when DollarDot
|
103
|
-
success = handle_dollar_dot
|
105
|
+
success = handle_dollar_dot(line)
|
104
106
|
else
|
105
107
|
api.passthru(line) # must succeed?
|
106
108
|
end
|
107
109
|
success
|
108
110
|
end
|
109
111
|
|
110
|
-
def handle_dollar_dot
|
112
|
+
def handle_dollar_dot(line)
|
111
113
|
indent = line.index("$") + 1
|
112
114
|
@indentation.push(indent)
|
113
115
|
line.sub!(/^ *\$/, "")
|
@@ -116,25 +118,27 @@ module Livetext::Helpers
|
|
116
118
|
success
|
117
119
|
end
|
118
120
|
|
119
|
-
def invoke_dotcmd(name,
|
121
|
+
def invoke_dotcmd(name, data="")
|
120
122
|
# FIXME Add cmdargs stuff... depends on name, etc.
|
121
|
-
|
123
|
+
api.data = data # should permit _ in function names at least
|
124
|
+
args = data.split
|
125
|
+
api.args = args
|
126
|
+
retval = @main.send(name) # , *args)
|
122
127
|
retval
|
123
128
|
rescue => err
|
124
129
|
graceful_error(err)
|
125
130
|
end
|
126
131
|
|
127
132
|
def handle_dotcmd(line, indent = 0)
|
128
|
-
# FIXME api.data is broken
|
129
133
|
indent = @indentation.last # top of stack
|
130
134
|
line = line.sub(/# .*$/, "") # FIXME Could be problematic?
|
131
|
-
name =
|
135
|
+
name, data = get_name_data(line)
|
132
136
|
success = true # Be optimistic... :P
|
133
137
|
case
|
134
138
|
when name == :end # special case
|
135
139
|
graceful_error EndWithoutOpening()
|
136
140
|
when @main.respond_to?(name)
|
137
|
-
success = invoke_dotcmd(name)
|
141
|
+
success = invoke_dotcmd(name, data)
|
138
142
|
else
|
139
143
|
graceful_error UnknownMethod(name)
|
140
144
|
end
|
@@ -145,14 +149,21 @@ module Livetext::Helpers
|
|
145
149
|
return true
|
146
150
|
end
|
147
151
|
|
148
|
-
def
|
149
|
-
|
150
|
-
|
152
|
+
def get_name_data(line)
|
153
|
+
line = line.chomp
|
154
|
+
blank = line.index(" ")
|
155
|
+
if blank
|
156
|
+
name = line[1..(blank-1)]
|
157
|
+
data0 = line[(blank+1)..-1]
|
158
|
+
else
|
159
|
+
name = line[1..-1]
|
160
|
+
data0 = ""
|
161
|
+
end
|
151
162
|
name = "dot_" + name if %w[include def].include?(name)
|
152
163
|
@main.check_disallowed(name)
|
153
|
-
|
154
|
-
@main.api.data =
|
155
|
-
name.to_sym
|
164
|
+
# @main.data = data # FIXME kill this
|
165
|
+
@main.api.data = data0 # FIXME kill this?
|
166
|
+
[name.to_sym, data0]
|
156
167
|
end
|
157
168
|
|
158
169
|
def check_disallowed(name)
|