livetext 0.9.30 → 0.9.33
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/livetext +1 -1
- data/imports/bookish.rb +1 -1
- data/lib/livetext/expansion.rb +15 -13
- data/lib/livetext/formatter.rb +186 -87
- data/lib/livetext/helpers.rb +23 -16
- data/lib/livetext/more.rb +19 -11
- data/lib/livetext/standard.rb +53 -65
- data/lib/livetext/userapi.rb +18 -5
- 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/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/{bootstrap_menu/expected-error.txt → 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 +16 -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
data/lib/livetext/standard.rb
CHANGED
@@ -17,6 +17,8 @@ module Livetext::Standard
|
|
17
17
|
include HTMLHelper
|
18
18
|
include Livetext::Helpers
|
19
19
|
|
20
|
+
TTY = ::File.open("/dev/tty", "w")
|
21
|
+
|
20
22
|
SimpleFormats = # Move this?
|
21
23
|
{ b: %w[<b> </b>],
|
22
24
|
i: %w[<i> </i>],
|
@@ -25,18 +27,9 @@ module Livetext::Standard
|
|
25
27
|
|
26
28
|
attr_reader :data
|
27
29
|
|
28
|
-
def data=(val) # FIXME this is weird, let's remove it soonish and why are there two???
|
29
|
-
# api.tty ">>>> in #{__FILE__}: api id = #{api.object_id}"
|
30
|
-
val = val.chomp
|
31
|
-
api.data = val
|
32
|
-
api.args = format(val).split rescue []
|
33
|
-
@mixins = []
|
34
|
-
@imports = []
|
35
|
-
end
|
36
|
-
|
37
30
|
# dumb name - bold, italic, teletype, striketrough
|
38
31
|
|
39
|
-
def bits
|
32
|
+
def bits # FIXME umm what is this?
|
40
33
|
b0, b1, i0, i1, t0, t1, s0, s1 = *api.args
|
41
34
|
SimpleFormats[:b] = [b0, b1]
|
42
35
|
SimpleFormats[:i] = [i0, i1]
|
@@ -51,29 +44,29 @@ module Livetext::Standard
|
|
51
44
|
# end
|
52
45
|
# end
|
53
46
|
|
54
|
-
def backtrace
|
47
|
+
def backtrace
|
55
48
|
@backtrace = onoff(api.args.first)
|
56
49
|
api.optional_blank_line
|
57
50
|
end
|
58
51
|
|
59
|
-
def comment
|
52
|
+
def comment
|
60
53
|
api.body
|
61
54
|
api.optional_blank_line
|
62
55
|
end
|
63
56
|
|
64
|
-
def shell
|
57
|
+
def shell
|
65
58
|
cmd = api.data
|
66
59
|
system(cmd)
|
67
60
|
api.optional_blank_line
|
68
61
|
end
|
69
62
|
|
70
|
-
def func
|
63
|
+
def func
|
71
64
|
funcname = api.args[0]
|
72
65
|
# check_disallowed(funcname) # should any be invalid?
|
73
66
|
funcname = funcname.gsub(/\./, "__")
|
74
67
|
func_def = <<~EOS
|
75
68
|
def #{funcname}(param)
|
76
|
-
#{api.body.to_a.join("\n")}
|
69
|
+
#{api.body(true).to_a.join("\n")}
|
77
70
|
end
|
78
71
|
EOS
|
79
72
|
api.optional_blank_line
|
@@ -81,21 +74,21 @@ module Livetext::Standard
|
|
81
74
|
return true
|
82
75
|
end
|
83
76
|
|
84
|
-
def h1
|
85
|
-
def h2
|
86
|
-
def h3
|
87
|
-
def h4
|
88
|
-
def h5
|
89
|
-
def h6
|
77
|
+
def h1; api.out wrapped(api.data, :h1); return true; end
|
78
|
+
def h2; api.out wrapped(api.data, :h2); return true; end
|
79
|
+
def h3; api.out wrapped(api.data, :h3); return true; end
|
80
|
+
def h4; api.out wrapped(api.data, :h4); return true; end
|
81
|
+
def h5; api.out wrapped(api.data, :h5); return true; end
|
82
|
+
def h6; api.out wrapped(api.data, :h6); return true; end
|
90
83
|
|
91
|
-
def list
|
84
|
+
def list
|
92
85
|
wrap :ul do
|
93
86
|
api.body {|line| api.out wrapped(line, :li) }
|
94
87
|
end
|
95
88
|
api.optional_blank_line
|
96
89
|
end
|
97
90
|
|
98
|
-
def list!
|
91
|
+
def list!
|
99
92
|
wrap(:ul) do
|
100
93
|
lines = api.body.each # enumerator
|
101
94
|
loop do
|
@@ -108,40 +101,40 @@ module Livetext::Standard
|
|
108
101
|
api.optional_blank_line
|
109
102
|
end
|
110
103
|
|
111
|
-
def shell!
|
104
|
+
def shell!
|
112
105
|
cmd = api.data
|
113
106
|
system(cmd)
|
114
107
|
api.optional_blank_line
|
115
108
|
end
|
116
109
|
|
117
|
-
def errout
|
110
|
+
def errout
|
118
111
|
::STDERR.puts api.data
|
119
112
|
api.optional_blank_line
|
120
113
|
end
|
121
114
|
|
122
|
-
def ttyout
|
115
|
+
def ttyout
|
123
116
|
TTY.puts api.data
|
124
117
|
api.optional_blank_line
|
125
118
|
end
|
126
119
|
|
127
|
-
def say
|
120
|
+
def say
|
128
121
|
str = api.format(api.data)
|
129
122
|
TTY.puts str
|
130
123
|
api.optional_blank_line
|
131
124
|
end
|
132
125
|
|
133
|
-
def banner
|
126
|
+
def banner
|
134
127
|
str = api.format(api.data)
|
135
128
|
num = str.length
|
136
129
|
decor = "-"*num + "\n"
|
137
130
|
puts decor + str + "\n" + decor
|
138
131
|
end
|
139
132
|
|
140
|
-
def quit
|
133
|
+
def quit
|
141
134
|
@output.close
|
142
135
|
end
|
143
136
|
|
144
|
-
def cleanup
|
137
|
+
def cleanup
|
145
138
|
api.args.each do |item|
|
146
139
|
cmd = ::File.directory?(item) ? "rm -f #{item}/*" : "rm #{item}"
|
147
140
|
system(cmd)
|
@@ -149,13 +142,9 @@ module Livetext::Standard
|
|
149
142
|
api.optional_blank_line
|
150
143
|
end
|
151
144
|
|
152
|
-
def dot_def
|
153
|
-
# api.tty "in #{__FILE__}: api id = #{api.inspect}"
|
145
|
+
def dot_def
|
154
146
|
name = api.args[0]
|
155
|
-
# api.tty :dd1
|
156
|
-
# api.tty name.inspect
|
157
147
|
check_disallowed(name)
|
158
|
-
# api.tty :dd2
|
159
148
|
# Difficult to avoid eval here
|
160
149
|
str = "def #{name}\n"
|
161
150
|
str << api.body(true).join("\n")
|
@@ -164,7 +153,7 @@ module Livetext::Standard
|
|
164
153
|
api.optional_blank_line
|
165
154
|
end
|
166
155
|
|
167
|
-
def set
|
156
|
+
def set
|
168
157
|
line = api.args.join(" ") # data.chomp
|
169
158
|
pairs = Livetext::ParseSet.new(line).parse
|
170
159
|
api.setvars(pairs)
|
@@ -173,7 +162,7 @@ module Livetext::Standard
|
|
173
162
|
|
174
163
|
# FIXME really these should be one method...
|
175
164
|
|
176
|
-
def variables!
|
165
|
+
def variables! # cwd, not FileDir - weird, fix later
|
177
166
|
prefix = api.args[0]
|
178
167
|
file = api.args[1]
|
179
168
|
prefix = nil if prefix == "-" # FIXME dumb hack
|
@@ -184,12 +173,11 @@ module Livetext::Standard
|
|
184
173
|
lines = api.body
|
185
174
|
end
|
186
175
|
pairs = Livetext::ParseGeneral.parse_vars(lines, prefix: nil)
|
187
|
-
STDERR.puts "! pairs = #{pairs.inspect}"
|
188
176
|
api.setvars(pairs)
|
189
177
|
api.optional_blank_line
|
190
178
|
end
|
191
179
|
|
192
|
-
def variables
|
180
|
+
def variables
|
193
181
|
prefix = api.args[0]
|
194
182
|
file = api.args[1]
|
195
183
|
prefix = nil if prefix == "-" # FIXME dumb hack
|
@@ -200,12 +188,11 @@ STDERR.puts "! pairs = #{pairs.inspect}"
|
|
200
188
|
lines = api.body
|
201
189
|
end
|
202
190
|
pairs = Livetext::ParseGeneral.parse_vars(lines, prefix: nil)
|
203
|
-
STDERR.puts "pairs = #{pairs.inspect}"
|
204
191
|
api.setvars(pairs)
|
205
192
|
api.optional_blank_line
|
206
193
|
end
|
207
194
|
|
208
|
-
def heredoc
|
195
|
+
def heredoc
|
209
196
|
var = api.args[0]
|
210
197
|
text = api.body.join("\n")
|
211
198
|
rhs = ""
|
@@ -215,11 +202,11 @@ STDERR.puts "pairs = #{pairs.inspect}"
|
|
215
202
|
end
|
216
203
|
indent = @parent.indentation.last
|
217
204
|
indented = " " * indent
|
218
|
-
api.
|
205
|
+
api.setvar(var, rhs.chomp)
|
219
206
|
api.optional_blank_line
|
220
207
|
end
|
221
208
|
|
222
|
-
def seek
|
209
|
+
def seek # like include, but search upward as needed
|
223
210
|
file = api.args.first
|
224
211
|
file = search_upward(file)
|
225
212
|
check_file_exists(file)
|
@@ -227,14 +214,14 @@ STDERR.puts "pairs = #{pairs.inspect}"
|
|
227
214
|
api.optional_blank_line
|
228
215
|
end
|
229
216
|
|
230
|
-
def dot_include
|
231
|
-
file = api.
|
217
|
+
def dot_include # dot command
|
218
|
+
file = api.expand_variables(api.args.first) # allows for variables
|
232
219
|
check_file_exists(file)
|
233
220
|
@parent.process_file(file)
|
234
221
|
api.optional_blank_line
|
235
222
|
end
|
236
223
|
|
237
|
-
def inherit
|
224
|
+
def inherit
|
238
225
|
file = api.args.first
|
239
226
|
upper = "../#{file}"
|
240
227
|
got_upper, got_file = File.exist?(upper), File.exist?(file)
|
@@ -246,8 +233,9 @@ STDERR.puts "pairs = #{pairs.inspect}"
|
|
246
233
|
api.optional_blank_line
|
247
234
|
end
|
248
235
|
|
249
|
-
def mixin
|
236
|
+
def mixin
|
250
237
|
name = api.args.first # Expect a module name
|
238
|
+
@mixins ||= []
|
251
239
|
return if @mixins.include?(name)
|
252
240
|
@mixins << name
|
253
241
|
mod = Livetext::Handler::Mixin.get_module(name, @parent)
|
@@ -257,8 +245,9 @@ STDERR.puts "pairs = #{pairs.inspect}"
|
|
257
245
|
api.optional_blank_line
|
258
246
|
end
|
259
247
|
|
260
|
-
def import
|
248
|
+
def import
|
261
249
|
name = api.args.first # Expect a module name
|
250
|
+
@imports ||= []
|
262
251
|
return if @imports.include?(name)
|
263
252
|
@imports << name
|
264
253
|
mod = Livetext::Handler::Import.get_module(name, @parent)
|
@@ -268,7 +257,7 @@ STDERR.puts "pairs = #{pairs.inspect}"
|
|
268
257
|
api.optional_blank_line
|
269
258
|
end
|
270
259
|
|
271
|
-
def copy
|
260
|
+
def copy
|
272
261
|
file = api.args.first
|
273
262
|
ok = check_file_exists(file)
|
274
263
|
|
@@ -278,67 +267,67 @@ STDERR.puts "pairs = #{pairs.inspect}"
|
|
278
267
|
[ok, file]
|
279
268
|
end
|
280
269
|
|
281
|
-
def r
|
270
|
+
def r
|
282
271
|
# FIXME api.data is broken
|
283
272
|
# api.out api.data # No processing at all
|
284
273
|
api.out api.args.join(" ")
|
285
274
|
api.optional_blank_line
|
286
275
|
end
|
287
276
|
|
288
|
-
def raw
|
277
|
+
def raw
|
289
278
|
# No processing at all (terminate with __EOF__)
|
290
279
|
api.raw_body {|line| api.out line } # no formatting
|
291
280
|
api.optional_blank_line
|
292
281
|
end
|
293
282
|
|
294
|
-
def debug
|
283
|
+
def debug
|
295
284
|
self._debug = onoff(api.args.first)
|
296
285
|
api.optional_blank_line
|
297
286
|
end
|
298
287
|
|
299
|
-
def passthru
|
288
|
+
def passthru
|
300
289
|
# FIXME - add check for args size? (helpers)
|
301
290
|
@nopass = ! onoff(api.args.first)
|
302
291
|
api.optional_blank_line
|
303
292
|
end
|
304
293
|
|
305
|
-
def nopass
|
294
|
+
def nopass
|
306
295
|
@nopass = true
|
307
296
|
api.optional_blank_line
|
308
297
|
end
|
309
298
|
|
310
|
-
def para
|
299
|
+
def para
|
311
300
|
# FIXME - add check for args size? (helpers)
|
312
301
|
@nopara = ! onoff(api.args.first)
|
313
302
|
api.optional_blank_line
|
314
303
|
end
|
315
304
|
|
316
|
-
def nopara
|
305
|
+
def nopara
|
317
306
|
@nopara = true
|
318
307
|
api.optional_blank_line
|
319
308
|
end
|
320
309
|
|
321
|
-
def heading
|
310
|
+
def heading
|
322
311
|
api.print "<center><font size=+1><b>"
|
323
312
|
api.print api.data
|
324
313
|
api.print "</b></font></center>"
|
325
314
|
api.optional_blank_line
|
326
315
|
end
|
327
316
|
|
328
|
-
def newpage
|
317
|
+
def newpage
|
329
318
|
api.out '<p style="page-break-after:always;"></p>'
|
330
319
|
api.out "<p/>"
|
331
320
|
api.optional_blank_line
|
332
321
|
end
|
333
322
|
|
334
|
-
def mono
|
323
|
+
def mono
|
335
324
|
wrap ":pre" do
|
336
325
|
api.body(true) {|line| api.out line }
|
337
326
|
end
|
338
327
|
api.optional_blank_line
|
339
328
|
end
|
340
329
|
|
341
|
-
def dlist
|
330
|
+
def dlist
|
342
331
|
delim = api.args.first
|
343
332
|
wrap(:dl) do
|
344
333
|
api.body do |line|
|
@@ -351,15 +340,14 @@ STDERR.puts "pairs = #{pairs.inspect}"
|
|
351
340
|
api.optional_blank_line
|
352
341
|
end
|
353
342
|
|
354
|
-
def link
|
343
|
+
def link
|
355
344
|
url = api.args.first
|
356
345
|
text = api.args[2..-1].join(" ")
|
357
346
|
api.out "<a style='text-decoration: none' href='#{url}'>#{text}</a>"
|
358
347
|
api.optional_blank_line
|
359
348
|
end
|
360
349
|
|
361
|
-
def xtable
|
362
|
-
# TTY.puts "=== #{__method__} #{__FILE__} #{__LINE__}"
|
350
|
+
def xtable # Borrowed from bookish - FIXME
|
363
351
|
title = api.data
|
364
352
|
delim = " :: "
|
365
353
|
api.out "<br><center><table width=90% cellpadding=5>"
|
@@ -389,13 +377,13 @@ STDERR.puts "pairs = #{pairs.inspect}"
|
|
389
377
|
api.optional_blank_line
|
390
378
|
end
|
391
379
|
|
392
|
-
def image
|
380
|
+
def image
|
393
381
|
name = api.args[0]
|
394
382
|
api.out "<img src='#{name}'></img>"
|
395
383
|
api.optional_blank_line
|
396
384
|
end
|
397
385
|
|
398
|
-
def br
|
386
|
+
def br
|
399
387
|
num = api.args.first || "1"
|
400
388
|
str = ""
|
401
389
|
num.to_i.times { str << "<br>" }
|
data/lib/livetext/userapi.rb
CHANGED
@@ -31,13 +31,26 @@ class Livetext::UserAPI
|
|
31
31
|
@live
|
32
32
|
end
|
33
33
|
|
34
|
+
def include_file(file)
|
35
|
+
api.data = file
|
36
|
+
api.dot_include
|
37
|
+
end
|
38
|
+
|
39
|
+
def expand_variables(str)
|
40
|
+
@expander.expand_variables(str)
|
41
|
+
end
|
42
|
+
|
43
|
+
def expand_functions(str)
|
44
|
+
@expander.expand_functions(str)
|
45
|
+
end
|
46
|
+
|
34
47
|
def setvar(var, val) # FIXME
|
35
|
-
# Livetext::Vars[var] = val # Now indifferent and "safe"
|
36
48
|
@live.vars.set(var, val)
|
37
49
|
end
|
38
50
|
|
39
51
|
def setvars(pairs)
|
40
|
-
pairs = pairs.
|
52
|
+
# STDERR.puts "#{__method__}: pairs = #{pairs.inspect} (#{pairs.class})"
|
53
|
+
pairs = pairs.to_a # could be Hash or Variables
|
41
54
|
pairs.each do |var, value|
|
42
55
|
@live.vars.set(var, value)
|
43
56
|
end
|
@@ -48,8 +61,9 @@ class Livetext::UserAPI
|
|
48
61
|
end
|
49
62
|
|
50
63
|
def data=(value)
|
51
|
-
@data = value
|
52
|
-
|
64
|
+
@data = value.dup
|
65
|
+
# @args = format(@data).chomp.split
|
66
|
+
@data
|
53
67
|
end
|
54
68
|
|
55
69
|
def data
|
@@ -135,7 +149,6 @@ class Livetext::UserAPI
|
|
135
149
|
end
|
136
150
|
|
137
151
|
def format(line)
|
138
|
-
return "" if line == "\n" || line.nil?
|
139
152
|
line2 = @expander.format(line)
|
140
153
|
line2
|
141
154
|
end
|
data/lib/livetext/version.rb
CHANGED
data/plugin/bookish.rb
CHANGED
@@ -0,0 +1,149 @@
|
|
1
|
+
The testgen.rb tool takes a .txt and generates a corresponding file
|
2
|
+
of MiniTest code.
|
3
|
+
|
4
|
+
$ ruby testgen.rb variables.txt # produces variables.rb
|
5
|
+
|
6
|
+
The tests here include:
|
7
|
+
|
8
|
+
variables.txt Variable expansion
|
9
|
+
functions.txt Function call evaluation
|
10
|
+
single.txt Single sigil (see Formatting below)
|
11
|
+
double.txt Double sigil (see Formatting below)
|
12
|
+
bracketed.txt Bracketed sigil (see Formatting below)
|
13
|
+
|
14
|
+
|
15
|
+
Variables:
|
16
|
+
----------
|
17
|
+
|
18
|
+
1. A variable begins with a $ and is followed by an alpha; periods may
|
19
|
+
be embedded, but each separate piece must "look like" an identifier
|
20
|
+
|
21
|
+
$x yes
|
22
|
+
$xyz yes
|
23
|
+
$xyz.abc yes
|
24
|
+
$x123 yes
|
25
|
+
$x.123 no
|
26
|
+
$345 no
|
27
|
+
|
28
|
+
2. Rather than causing an error, invalid variables are rendered "as-is"
|
29
|
+
as soon as possible:
|
30
|
+
" $ " => " $ "
|
31
|
+
" $5 " => " $5 "
|
32
|
+
"...$" => "...$" (end of line)
|
33
|
+
|
34
|
+
3. Actual variables may be user-defined or predefined. The latter usually
|
35
|
+
begin with a capital. This is only a convention so far, nothing that is
|
36
|
+
enforced.
|
37
|
+
|
38
|
+
4. The $ may be escaped as needed. This is problematic.
|
39
|
+
|
40
|
+
5. An unknown variable will not raise an error, but will be replaced with
|
41
|
+
a warning string.
|
42
|
+
|
43
|
+
|
44
|
+
Functions:
|
45
|
+
----------
|
46
|
+
|
47
|
+
1. A function looks like a variable name, but it has two $ in front.
|
48
|
+
|
49
|
+
2. If followed by space, comma, end of line, or similar delimiter, it is
|
50
|
+
called with no parameter.
|
51
|
+
|
52
|
+
3. Note that a function name may contain periods, but may not end with
|
53
|
+
one. "$$func." is parsed as a function call (with no parameter) plus a
|
54
|
+
period.
|
55
|
+
|
56
|
+
4. Use a colon to pass a single parameter delimited by a space or end of line.
|
57
|
+
Colon at end of line is valid but probably pointless.
|
58
|
+
|
59
|
+
5. Use brackets to pass a single parameter that contains spaces. The bracketed
|
60
|
+
parameter may be terminated by end of line instead of right bracket.
|
61
|
+
|
62
|
+
6. Only one parameter (a string) may be passed, but the function may parse it
|
63
|
+
however it needs to.
|
64
|
+
|
65
|
+
7. There is no enforcement of a parameter being "present or absent" except what
|
66
|
+
the function itself may enforce.
|
67
|
+
|
68
|
+
8. An unknown function will not raise an error, but will be replaced with a warning
|
69
|
+
string.
|
70
|
+
|
71
|
+
|
72
|
+
Formatting:
|
73
|
+
-----------
|
74
|
+
|
75
|
+
1. My formatting notation would be considered quirky by many people.
|
76
|
+
The sigils or markers are:
|
77
|
+
* bold
|
78
|
+
_ underscore
|
79
|
+
` code/teletype
|
80
|
+
~ strikethrough
|
81
|
+
|
82
|
+
1. A single sigil is recognized basically at beginning of line or after a space.
|
83
|
+
my_func_name No italics here
|
84
|
+
M*A*S*H No boldface here
|
85
|
+
|
86
|
+
2. A single sigil is terminated by a space or end of line.
|
87
|
+
|
88
|
+
3. A single sigil "by itself" is rendered as-is (asterisk, underscore, whatever).
|
89
|
+
|
90
|
+
4. An escaped single sigil is rendered as-is. (This is problematic.)
|
91
|
+
|
92
|
+
5. A double sigil is recognized at start of line or after a space
|
93
|
+
|
94
|
+
6. A double sigil is terminated by a space OR a comma OR a period. (The comma
|
95
|
+
and period cases seem very common to me; they are the whole justification
|
96
|
+
for the double sigil.) End of line also terminates it.
|
97
|
+
|
98
|
+
7. A double sigil by itself is rendered as-is.
|
99
|
+
|
100
|
+
8. A bracketed sigil is in general a sigil followed by: [ data ]
|
101
|
+
|
102
|
+
9. An empty bracketed sigil simply "goes away"
|
103
|
+
" *[] " => " "
|
104
|
+
|
105
|
+
10. End of line can terminate instead of right bracket -- but it may still be empty
|
106
|
+
and therefore go away.
|
107
|
+
|
108
|
+
11. NOTE: These tests use only asterisks (bold), but the logic "should" be the same
|
109
|
+
for all sigils.
|
110
|
+
|
111
|
+
|
112
|
+
|
113
|
+
Order of evaluation, etc.:
|
114
|
+
--------------------------
|
115
|
+
|
116
|
+
1. This logic is always a compromise between syntax and the code that parses it.
|
117
|
+
I prefer simplicity whenever possible, though it may introduce complexity in
|
118
|
+
other situations. I believe that the acceptable complexity of a workaround
|
119
|
+
depends on how commonplace the situation is and how onerous the workaround is.
|
120
|
+
These are both highly subjective.
|
121
|
+
|
122
|
+
2. For example: Note that the simple formatting sigils may not be nested. However,
|
123
|
+
there are functions like $$bits provided (with the silly mnemonic "bold, italic,
|
124
|
+
teletype, strikthrough"). Every combination is provided (e.g., $$bi, $$bt).
|
125
|
+
|
126
|
+
3. Note also: Formatting is only intra-line; it doesn't span lines. If you need to
|
127
|
+
work around this, use a heredoc or make your own .def for this.
|
128
|
+
|
129
|
+
4. Finally: HTML or CSS may be inserted at will (possibly with some escaping). This
|
130
|
+
can be inline or "a file at a time" via such commands as .copy and .include
|
131
|
+
|
132
|
+
5. For these reasons: Parsing is naive and simple. Variables are parsed first.
|
133
|
+
|
134
|
+
6. Next, function calls are parsed. I said variables are parsed first; this implies
|
135
|
+
that a variable can be embedded in a function parameter. But be aware these are
|
136
|
+
"naive" substitutions (like C macros).
|
137
|
+
.set alpha = "some value"
|
138
|
+
Calling $$myfunc:$alpha (means: Calling $$myfunc:some value)
|
139
|
+
Better to say $$myfunc[$alpha] (means: Better to say $$myfunc[some value]
|
140
|
+
|
141
|
+
7. Formatting is handled last. The four sigils (* _ ` ~) and their three modes
|
142
|
+
(single, double, bracketed) make 12 passes necessary for formatting. As this is
|
143
|
+
always single-line, it has not been observed to cause a delay so far.
|
144
|
+
|
145
|
+
8. The call api.format(line) essentially expands variables, calls functions, and
|
146
|
+
finally does simple formatting. See classes Expansion and Formatter.
|
147
|
+
|
148
|
+
9. User code (e.g. inside a .def) may also call expand_variables, expand_functions,
|
149
|
+
and Formatter.format separately.
|