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
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
|
|
1
2
|
require 'pathname' # For _seek - remove later??
|
|
2
3
|
|
|
3
4
|
require_relative 'parser' # nested requires
|
|
@@ -14,7 +15,7 @@ make_exception(:FileNotFound, "Error: file '%1' not found")
|
|
|
14
15
|
module Livetext::Standard
|
|
15
16
|
|
|
16
17
|
include HTMLHelper
|
|
17
|
-
include Helpers
|
|
18
|
+
include Livetext::Helpers
|
|
18
19
|
|
|
19
20
|
SimpleFormats = # Move this?
|
|
20
21
|
{ b: %w[<b> </b>],
|
|
@@ -22,321 +23,339 @@ module Livetext::Standard
|
|
|
22
23
|
t: ["<font size=+1><tt>", "</tt></font>"],
|
|
23
24
|
s: %w[<strike> </strike>] }
|
|
24
25
|
|
|
25
|
-
attr_reader :
|
|
26
|
+
attr_reader :data
|
|
26
27
|
|
|
27
28
|
def data=(val) # FIXME this is weird, let's remove it soonish
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
@
|
|
29
|
+
api.data = val.chomp
|
|
30
|
+
# @args = val.split rescue []
|
|
31
|
+
@mixins = []
|
|
32
|
+
@imports = []
|
|
33
|
+
###
|
|
34
|
+
# api.data = val
|
|
31
35
|
end
|
|
32
36
|
|
|
33
37
|
# dumb name - bold, italic, teletype, striketrough
|
|
34
|
-
|
|
35
|
-
|
|
38
|
+
|
|
39
|
+
def bits(args = nil, body = nil) # FIXME umm what is this?
|
|
40
|
+
b0, b1, i0, i1, t0, t1, s0, s1 = *api.args
|
|
36
41
|
SimpleFormats[:b] = [b0, b1]
|
|
37
42
|
SimpleFormats[:i] = [i0, i1]
|
|
38
43
|
SimpleFormats[:t] = [t0, t1]
|
|
39
44
|
SimpleFormats[:s] = [s0, s1]
|
|
45
|
+
api.optional_blank_line
|
|
40
46
|
end
|
|
41
47
|
|
|
42
48
|
def backtrace(args = nil, body = nil)
|
|
43
|
-
@backtrace = onoff(
|
|
44
|
-
|
|
49
|
+
@backtrace = onoff(api.args.first)
|
|
50
|
+
api.optional_blank_line
|
|
45
51
|
end
|
|
46
52
|
|
|
47
53
|
def comment(args = nil, body = nil)
|
|
48
|
-
|
|
49
|
-
|
|
54
|
+
api.body
|
|
55
|
+
api.optional_blank_line
|
|
50
56
|
end
|
|
51
57
|
|
|
52
58
|
def shell(args = nil, body = nil)
|
|
53
|
-
cmd =
|
|
59
|
+
cmd = api.data
|
|
54
60
|
system(cmd)
|
|
55
|
-
|
|
61
|
+
api.optional_blank_line
|
|
56
62
|
end
|
|
57
63
|
|
|
58
64
|
def func(args = nil, body = nil)
|
|
59
|
-
funcname =
|
|
65
|
+
funcname = api.args[0]
|
|
60
66
|
check_disallowed(funcname)
|
|
61
67
|
func_def = <<~EOS
|
|
62
68
|
def #{funcname}(param)
|
|
63
|
-
#{
|
|
69
|
+
#{api.body.to_a.join("\n")}
|
|
64
70
|
end
|
|
65
71
|
EOS
|
|
66
|
-
|
|
72
|
+
api.optional_blank_line
|
|
67
73
|
Livetext::Functions.class_eval func_def
|
|
74
|
+
return true
|
|
68
75
|
end
|
|
69
76
|
|
|
70
|
-
def h1(args = nil, body = nil);
|
|
71
|
-
def h2(args = nil, body = nil);
|
|
72
|
-
def h3(args = nil, body = nil);
|
|
73
|
-
def h4(args = nil, body = nil);
|
|
74
|
-
def h5(args = nil, body = nil);
|
|
75
|
-
def h6(args = nil, body = nil);
|
|
77
|
+
def h1(args = nil, body = nil); api.out wrapped(api.data, :h1); return true; end
|
|
78
|
+
def h2(args = nil, body = nil); api.out wrapped(api.data, :h2); return true; end
|
|
79
|
+
def h3(args = nil, body = nil); api.out wrapped(api.data, :h3); return true; end
|
|
80
|
+
def h4(args = nil, body = nil); api.out wrapped(api.data, :h4); return true; end
|
|
81
|
+
def h5(args = nil, body = nil); api.out wrapped(api.data, :h5); return true; end
|
|
82
|
+
def h6(args = nil, body = nil); api.out wrapped(api.data, :h6); return true; end
|
|
76
83
|
|
|
77
84
|
def list(args = nil, body = nil)
|
|
78
85
|
wrap :ul do
|
|
79
|
-
|
|
86
|
+
api.body {|line| api.out wrapped(line, :li) }
|
|
80
87
|
end
|
|
81
|
-
|
|
88
|
+
api.optional_blank_line
|
|
82
89
|
end
|
|
83
90
|
|
|
84
91
|
def list!(args = nil, body = nil)
|
|
85
92
|
wrap(:ul) do
|
|
86
|
-
lines =
|
|
93
|
+
lines = api.body.each # enumerator
|
|
87
94
|
loop do
|
|
88
95
|
line = lines.next
|
|
89
|
-
line =
|
|
96
|
+
line = api.format(line)
|
|
90
97
|
str = line[0] == " " ? line : wrapped(line, :li)
|
|
91
|
-
|
|
98
|
+
api.out str
|
|
92
99
|
end
|
|
93
100
|
end
|
|
94
|
-
|
|
101
|
+
api.optional_blank_line
|
|
95
102
|
end
|
|
96
103
|
|
|
97
104
|
def shell!(args = nil, body = nil)
|
|
98
|
-
cmd =
|
|
105
|
+
cmd = api.data
|
|
99
106
|
system(cmd)
|
|
100
|
-
|
|
107
|
+
api.optional_blank_line
|
|
101
108
|
end
|
|
102
109
|
|
|
103
110
|
def errout(args = nil, body = nil)
|
|
104
|
-
STDERR.puts
|
|
105
|
-
|
|
111
|
+
::STDERR.puts api.data
|
|
112
|
+
api.optional_blank_line
|
|
106
113
|
end
|
|
107
114
|
|
|
108
115
|
def ttyout(args = nil, body = nil)
|
|
109
|
-
TTY.puts
|
|
110
|
-
|
|
116
|
+
TTY.puts api.data
|
|
117
|
+
api.optional_blank_line
|
|
111
118
|
end
|
|
112
119
|
|
|
113
120
|
def say(args = nil, body = nil)
|
|
114
|
-
str =
|
|
121
|
+
str = api.format(api.data)
|
|
115
122
|
TTY.puts str
|
|
116
|
-
|
|
123
|
+
api.optional_blank_line
|
|
117
124
|
end
|
|
118
125
|
|
|
119
126
|
def banner(args = nil, body = nil)
|
|
120
|
-
str =
|
|
127
|
+
str = api.format(api.data)
|
|
121
128
|
num = str.length
|
|
122
129
|
decor = "-"*num + "\n"
|
|
123
130
|
puts decor + str + "\n" + decor
|
|
124
131
|
end
|
|
125
132
|
|
|
126
133
|
def quit(args = nil, body = nil)
|
|
127
|
-
puts @body
|
|
128
|
-
@body = ""
|
|
129
134
|
@output.close
|
|
130
135
|
end
|
|
131
136
|
|
|
132
137
|
def cleanup(args = nil, body = nil)
|
|
133
|
-
|
|
138
|
+
api.args.each do |item|
|
|
134
139
|
cmd = ::File.directory?(item) ? "rm -f #{item}/*" : "rm #{item}"
|
|
135
140
|
system(cmd)
|
|
136
141
|
end
|
|
142
|
+
api.optional_blank_line
|
|
137
143
|
end
|
|
138
144
|
|
|
139
145
|
def dot_def(args = nil, body = nil)
|
|
140
|
-
name =
|
|
146
|
+
name = api.args[0]
|
|
141
147
|
str = "def #{name}\n"
|
|
142
148
|
check_disallowed(name)
|
|
143
149
|
# Difficult to avoid eval here
|
|
144
|
-
str <<
|
|
150
|
+
str << api.body(true).join("\n")
|
|
145
151
|
str << "\nend\n"
|
|
146
152
|
eval str
|
|
153
|
+
api.optional_blank_line
|
|
147
154
|
end
|
|
148
155
|
|
|
149
156
|
def set(args = nil, body = nil)
|
|
150
|
-
line =
|
|
157
|
+
line = api.data.chomp
|
|
151
158
|
pairs = Livetext::ParseSet.new(line).parse
|
|
152
159
|
set_variables(pairs)
|
|
160
|
+
api.optional_blank_line
|
|
153
161
|
end
|
|
154
162
|
|
|
155
163
|
# FIXME really these should be one method...
|
|
156
164
|
|
|
157
165
|
def variables!(args = nil, body = nil) # cwd, not FileDir - weird, fix later
|
|
158
|
-
prefix =
|
|
159
|
-
file =
|
|
166
|
+
prefix = api.args[0]
|
|
167
|
+
file = api.args[1]
|
|
160
168
|
prefix = nil if prefix == "-" # FIXME dumb hack
|
|
161
169
|
if file
|
|
162
170
|
here = "" # different for ! version
|
|
163
171
|
lines = File.readlines(here + file)
|
|
164
172
|
else
|
|
165
|
-
lines =
|
|
173
|
+
lines = api.body
|
|
166
174
|
end
|
|
167
175
|
pairs = Livetext::ParseGeneral.parse_vars(prefix, lines)
|
|
168
176
|
set_variables(pairs)
|
|
177
|
+
api.optional_blank_line
|
|
169
178
|
end
|
|
170
179
|
|
|
171
180
|
def variables(args = nil, body = nil)
|
|
172
|
-
prefix =
|
|
173
|
-
file =
|
|
181
|
+
prefix = api.args[0]
|
|
182
|
+
file = api.args[1]
|
|
174
183
|
prefix = nil if prefix == "-" # FIXME dumb hack
|
|
175
184
|
if file
|
|
176
185
|
here = ::Livetext::Vars[:FileDir] + "/"
|
|
177
186
|
lines = File.readlines(here + file)
|
|
178
187
|
else
|
|
179
|
-
lines =
|
|
188
|
+
lines = api.body
|
|
180
189
|
end
|
|
181
190
|
pairs = Livetext::ParseGeneral.parse_vars(prefix, lines)
|
|
182
191
|
set_variables(pairs)
|
|
192
|
+
api.optional_blank_line
|
|
183
193
|
end
|
|
184
194
|
|
|
185
195
|
def heredoc(args = nil, body = nil)
|
|
186
|
-
var =
|
|
187
|
-
text =
|
|
196
|
+
var = api.args[0]
|
|
197
|
+
text = api.body.join("\n")
|
|
188
198
|
rhs = ""
|
|
189
199
|
text.each_line do |line|
|
|
190
|
-
str =
|
|
200
|
+
str = api.format(line.chomp)
|
|
191
201
|
rhs << str + "<br>"
|
|
192
202
|
end
|
|
193
203
|
indent = @parent.indentation.last
|
|
194
204
|
indented = " " * indent
|
|
195
|
-
|
|
196
|
-
|
|
205
|
+
api.setvar(var, rhs.chomp)
|
|
206
|
+
# @parent.setvar(var, rhs.chomp)
|
|
207
|
+
api.optional_blank_line
|
|
197
208
|
end
|
|
198
209
|
|
|
199
210
|
def seek(args = nil, body = nil) # like include, but search upward as needed
|
|
200
|
-
file =
|
|
211
|
+
file = api.args.first
|
|
201
212
|
file = search_upward(file)
|
|
202
213
|
check_file_exists(file)
|
|
203
214
|
@parent.process_file(file)
|
|
204
|
-
|
|
215
|
+
api.optional_blank_line
|
|
205
216
|
end
|
|
206
217
|
|
|
207
218
|
def dot_include(args = nil, body = nil) # dot command
|
|
208
|
-
file =
|
|
219
|
+
file = api.format(api.args.first) # allows for variables
|
|
209
220
|
check_file_exists(file)
|
|
210
221
|
@parent.process_file(file)
|
|
211
|
-
|
|
222
|
+
api.optional_blank_line
|
|
212
223
|
end
|
|
213
224
|
|
|
214
225
|
def inherit(args = nil, body = nil)
|
|
215
|
-
file =
|
|
226
|
+
file = api.args.first
|
|
216
227
|
upper = "../#{file}"
|
|
217
228
|
got_upper, got_file = File.exist?(upper), File.exist?(file)
|
|
218
229
|
good = got_upper || got_file
|
|
219
|
-
|
|
230
|
+
STDERR.puts "File #{file} not found (local or parent)" unless good
|
|
220
231
|
|
|
221
232
|
@parent.process_file(upper) if got_upper
|
|
222
233
|
@parent.process_file(file) if got_file
|
|
223
|
-
|
|
234
|
+
api.optional_blank_line
|
|
224
235
|
end
|
|
225
236
|
|
|
226
237
|
def mixin(args = nil, body = nil)
|
|
227
|
-
name =
|
|
228
|
-
return if @
|
|
229
|
-
@
|
|
230
|
-
mod = Livetext::
|
|
238
|
+
name = api.args.first # Expect a module name
|
|
239
|
+
return if @mixins.include?(name)
|
|
240
|
+
@mixins << name
|
|
241
|
+
mod = Livetext::Handler::Mixin.get_module(name, @parent)
|
|
231
242
|
self.extend(mod)
|
|
232
243
|
init = "init_#{name}"
|
|
233
|
-
self.send(init) if self.respond_to? init
|
|
234
|
-
|
|
244
|
+
self.send(init) rescue nil # if self.respond_to? init
|
|
245
|
+
api.optional_blank_line
|
|
235
246
|
end
|
|
236
247
|
|
|
237
|
-
def
|
|
238
|
-
name =
|
|
239
|
-
return if @
|
|
240
|
-
@
|
|
241
|
-
mod = Livetext::Handler::
|
|
248
|
+
def import(args = nil, body = nil)
|
|
249
|
+
name = api.args.first # Expect a module name
|
|
250
|
+
return if @imports.include?(name)
|
|
251
|
+
@imports << name
|
|
252
|
+
mod = Livetext::Handler::Import.get_module(name, @parent)
|
|
242
253
|
self.extend(mod)
|
|
243
254
|
init = "init_#{name}"
|
|
244
|
-
self.send(init) if self.respond_to? init
|
|
245
|
-
|
|
246
|
-
end
|
|
247
|
-
|
|
248
|
-
def import(args = nil, body = nil)
|
|
249
|
-
name = @_args.first # Expect a module name
|
|
250
|
-
return if @_mixins.include?(name)
|
|
251
|
-
@_mixins << name
|
|
252
|
-
mod = Livetext::ParseImport.get_module(name)
|
|
253
|
-
parse.use_import(name)
|
|
254
|
-
_optional_blank_line
|
|
255
|
+
self.send(init) rescue nil # if self.respond_to? init
|
|
256
|
+
api.optional_blank_line
|
|
255
257
|
end
|
|
256
258
|
|
|
257
259
|
def copy(args = nil, body = nil)
|
|
258
|
-
file =
|
|
259
|
-
check_file_exists(file)
|
|
260
|
-
|
|
261
|
-
|
|
260
|
+
file = api.args.first
|
|
261
|
+
ok = check_file_exists(file)
|
|
262
|
+
|
|
263
|
+
self.parent.graceful_error FileNotFound(file) unless ok # FIXME seems weird?
|
|
264
|
+
api.out grab_file(file)
|
|
265
|
+
api.optional_blank_line
|
|
266
|
+
[ok, file]
|
|
262
267
|
end
|
|
263
268
|
|
|
264
269
|
def r(args = nil, body = nil)
|
|
265
|
-
|
|
270
|
+
api.out api.data # No processing at all
|
|
271
|
+
api.optional_blank_line
|
|
266
272
|
end
|
|
267
273
|
|
|
268
274
|
def raw(args = nil, body = nil)
|
|
269
275
|
# No processing at all (terminate with __EOF__)
|
|
270
|
-
|
|
276
|
+
api.raw_body {|line| api.out line } # no formatting
|
|
277
|
+
api.optional_blank_line
|
|
271
278
|
end
|
|
272
279
|
|
|
273
280
|
def debug(args = nil, body = nil)
|
|
274
|
-
self._debug = onoff(
|
|
281
|
+
self._debug = onoff(api.args.first)
|
|
282
|
+
api.optional_blank_line
|
|
275
283
|
end
|
|
276
284
|
|
|
277
285
|
def passthru(args = nil, body = nil)
|
|
278
286
|
# FIXME - add check for args size? (helpers)
|
|
279
|
-
@
|
|
287
|
+
@nopass = ! onoff(api.args.first)
|
|
288
|
+
api.optional_blank_line
|
|
280
289
|
end
|
|
281
290
|
|
|
282
291
|
def nopass(args = nil, body = nil)
|
|
283
|
-
@
|
|
292
|
+
@nopass = true
|
|
293
|
+
api.optional_blank_line
|
|
284
294
|
end
|
|
285
295
|
|
|
286
296
|
def para(args = nil, body = nil)
|
|
287
297
|
# FIXME - add check for args size? (helpers)
|
|
288
|
-
@
|
|
298
|
+
@nopara = ! onoff(api.args.first)
|
|
299
|
+
api.optional_blank_line
|
|
289
300
|
end
|
|
290
301
|
|
|
291
302
|
def nopara(args = nil, body = nil)
|
|
292
|
-
@
|
|
303
|
+
@nopara = true
|
|
304
|
+
api.optional_blank_line
|
|
293
305
|
end
|
|
294
306
|
|
|
295
307
|
def heading(args = nil, body = nil)
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
308
|
+
api.print "<center><font size=+1><b>"
|
|
309
|
+
api.print api.data
|
|
310
|
+
api.print "</b></font></center>"
|
|
311
|
+
api.optional_blank_line
|
|
299
312
|
end
|
|
300
313
|
|
|
301
314
|
def newpage(args = nil, body = nil)
|
|
302
|
-
|
|
303
|
-
|
|
315
|
+
api.out '<p style="page-break-after:always;"></p>'
|
|
316
|
+
api.out "<p/>"
|
|
317
|
+
api.optional_blank_line
|
|
304
318
|
end
|
|
305
319
|
|
|
306
320
|
def mono(args = nil, body = nil)
|
|
307
321
|
wrap ":pre" do
|
|
308
|
-
|
|
322
|
+
api.body(true) {|line| api.out line }
|
|
309
323
|
end
|
|
310
|
-
|
|
324
|
+
api.optional_blank_line
|
|
311
325
|
end
|
|
312
326
|
|
|
313
327
|
def dlist(args = nil, body = nil)
|
|
314
|
-
delim =
|
|
328
|
+
delim = api.args.first
|
|
315
329
|
wrap(:dl) do
|
|
316
|
-
|
|
317
|
-
line =
|
|
330
|
+
api.body do |line|
|
|
331
|
+
line = api.format(line)
|
|
318
332
|
term, defn = line.split(delim)
|
|
319
|
-
|
|
320
|
-
|
|
333
|
+
api.out wrapped(term, :dt)
|
|
334
|
+
api.out wrapped(defn, :dd)
|
|
321
335
|
end
|
|
322
336
|
end
|
|
337
|
+
api.optional_blank_line
|
|
323
338
|
end
|
|
324
339
|
|
|
325
340
|
def link(args = nil, body = nil)
|
|
326
|
-
url =
|
|
327
|
-
text =
|
|
328
|
-
|
|
341
|
+
url = api.args.first
|
|
342
|
+
text = api.args[2..-1].join(" ")
|
|
343
|
+
api.out "<a style='text-decoration: none' href='#{url}'>#{text}</a>"
|
|
344
|
+
api.optional_blank_line
|
|
329
345
|
end
|
|
330
346
|
|
|
331
347
|
def xtable(args = nil, body = nil) # Borrowed from bookish - FIXME
|
|
332
|
-
|
|
348
|
+
# TTY.puts "=== #{__method__} #{__FILE__} #{__LINE__}"
|
|
349
|
+
title = api.data
|
|
333
350
|
delim = " :: "
|
|
334
|
-
|
|
335
|
-
lines =
|
|
351
|
+
api.out "<br><center><table width=90% cellpadding=5>"
|
|
352
|
+
lines = api.body(true)
|
|
336
353
|
maxw = nil
|
|
354
|
+
processed = []
|
|
337
355
|
lines.each do |line|
|
|
338
|
-
line =
|
|
356
|
+
line = api.format(line)
|
|
339
357
|
line.gsub!(/\n+/, "<br>")
|
|
358
|
+
processed << line
|
|
340
359
|
cells = line.split(delim)
|
|
341
360
|
wide = cells.map {|cell| cell.length }
|
|
342
361
|
maxw = [0] * cells.size
|
|
@@ -346,25 +365,36 @@ module Livetext::Standard
|
|
|
346
365
|
sum = maxw.inject(0, :+)
|
|
347
366
|
maxw.map! {|x| (x/sum*100).floor }
|
|
348
367
|
|
|
349
|
-
|
|
368
|
+
processed.each do |line|
|
|
350
369
|
cells = line.split(delim)
|
|
351
370
|
wrap :tr do
|
|
352
|
-
cells.each {|cell|
|
|
371
|
+
cells.each {|cell| api.out " <td valign=top>#{cell}</td>" }
|
|
353
372
|
end
|
|
354
373
|
end
|
|
355
|
-
|
|
374
|
+
api.out "</table></center>"
|
|
375
|
+
api.optional_blank_line
|
|
356
376
|
end
|
|
357
377
|
|
|
358
378
|
def image(args = nil, body = nil)
|
|
359
|
-
name =
|
|
360
|
-
|
|
379
|
+
name = api.args[0]
|
|
380
|
+
api.out "<img src='#{name}'></img>"
|
|
381
|
+
api.optional_blank_line
|
|
361
382
|
end
|
|
362
383
|
|
|
363
384
|
def br(args = nil, body = nil)
|
|
364
|
-
num =
|
|
365
|
-
|
|
366
|
-
num.to_i.times {
|
|
367
|
-
|
|
385
|
+
num = api.args.first || "1"
|
|
386
|
+
str = ""
|
|
387
|
+
num.to_i.times { str << "<br>" }
|
|
388
|
+
api.out str
|
|
389
|
+
api.optional_blank_line
|
|
368
390
|
end
|
|
369
391
|
|
|
392
|
+
def reflection # strictly experimental!
|
|
393
|
+
list = self.methods
|
|
394
|
+
obj = Object.instance_methods
|
|
395
|
+
diff = (list - obj).sort
|
|
396
|
+
api.out "#{diff.size} methods:"
|
|
397
|
+
api.out diff.inspect
|
|
398
|
+
api.optional_blank_line
|
|
399
|
+
end
|
|
370
400
|
end
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
|
|
2
|
+
require_relative 'formatline'
|
|
3
|
+
|
|
4
|
+
# Encapsulate the UserAPI as a class
|
|
5
|
+
|
|
6
|
+
class Livetext::UserAPI
|
|
7
|
+
|
|
8
|
+
attr_accessor :data, :args
|
|
9
|
+
|
|
10
|
+
def initialize(live)
|
|
11
|
+
@live = live
|
|
12
|
+
@vars = live.vars
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def setvar(var, val)
|
|
16
|
+
# FIXME don't like this...
|
|
17
|
+
str, sym = var.to_s, var.to_sym
|
|
18
|
+
Livetext::Vars[str] = val
|
|
19
|
+
Livetext::Vars[sym] = val
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def check_existence(file, msg)
|
|
23
|
+
STDERR.puts msg unless File.exist?(file)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def data=(value)
|
|
27
|
+
@data = value
|
|
28
|
+
@args = format(@data).chomp.split
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def args
|
|
32
|
+
return @args unless block_given?
|
|
33
|
+
@args.each {|arg| yield arg }
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def vars
|
|
37
|
+
@vars
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def optional_blank_line
|
|
41
|
+
peek = @live.peek_nextline # ???
|
|
42
|
+
return if peek.nil?
|
|
43
|
+
@line = @live.nextline if peek =~ /^ *$/
|
|
44
|
+
return true # This way, dot commands will usually return true
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def comment?(str)
|
|
48
|
+
sigil = Livetext::Sigil
|
|
49
|
+
c1 = sigil + Livetext::Space
|
|
50
|
+
str.index(c1) == 0
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def trailing?(char)
|
|
54
|
+
return true if ["\n", " ", nil].include?(char)
|
|
55
|
+
return false
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def end?(str)
|
|
59
|
+
return true if str == ".end" || str =~ / *\$\.end/
|
|
60
|
+
return false
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def raw_body(tag = "__EOF__")
|
|
64
|
+
lines = []
|
|
65
|
+
@live.save_location = @live.sources.last
|
|
66
|
+
loop do
|
|
67
|
+
@line = @live.nextline
|
|
68
|
+
break if @line.nil?
|
|
69
|
+
break if @line.chomp.strip == tag
|
|
70
|
+
lines << @line
|
|
71
|
+
end
|
|
72
|
+
optional_blank_line
|
|
73
|
+
return lines unless block_given?
|
|
74
|
+
lines.each {|line| yield line }
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def body(raw=false)
|
|
78
|
+
lines = []
|
|
79
|
+
end_found = false
|
|
80
|
+
loop do
|
|
81
|
+
@line = @live.nextline
|
|
82
|
+
break if @line.nil?
|
|
83
|
+
@line.chomp!
|
|
84
|
+
break if end?(@line)
|
|
85
|
+
next if comment?(@line)
|
|
86
|
+
@line = format(@line) unless raw
|
|
87
|
+
lines << @line
|
|
88
|
+
end
|
|
89
|
+
raise "Expected .end, found end of file" unless end?(@line) # use custom exception
|
|
90
|
+
optional_blank_line # FIXME Delete this??
|
|
91
|
+
return lines unless block_given?
|
|
92
|
+
lines.each {|line| yield line } # FIXME what about $. ?
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def body_text(raw=false)
|
|
96
|
+
raw_body.join("\n")
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def raw_body!
|
|
100
|
+
raw_body(Livetext::Sigil).join("\n")
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def handle_escapes(str, set)
|
|
104
|
+
str = str.dup
|
|
105
|
+
set.each_char do |ch|
|
|
106
|
+
str.gsub!("\\#{ch}", ch)
|
|
107
|
+
end
|
|
108
|
+
str
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def format(line)
|
|
112
|
+
return "" if line == "\n" || line.nil?
|
|
113
|
+
line2 = Livetext::FormatLine.parse!(line)
|
|
114
|
+
# line.replace(line2)
|
|
115
|
+
line2
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def passthru(line)
|
|
119
|
+
return if @live.nopass
|
|
120
|
+
out "<p>" if line == "\n" and ! @live.nopara
|
|
121
|
+
line = format(line)
|
|
122
|
+
out line
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def out(str = "", file = nil)
|
|
126
|
+
return if str.nil?
|
|
127
|
+
return file.puts str unless file.nil?
|
|
128
|
+
@live.body << str
|
|
129
|
+
@live.body << "\n" unless str.end_with?("\n")
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def out!(str = "")
|
|
133
|
+
@live.body << str # no newline
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def puts(*args)
|
|
137
|
+
@live.output.puts *args
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def print(*args)
|
|
141
|
+
@live.output.print *args
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def debug=(val)
|
|
145
|
+
@live.debug = val
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def debug(*args)
|
|
149
|
+
TTY.puts *args if @live.debug
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
end
|
|
153
|
+
|