livetext 0.8.77 → 0.8.78

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 904d935b6923cb3dd8a70dc6042b03a95dcd18851d7e3dfb4d9cae61cc0653b9
4
- data.tar.gz: afdfa6c79db3beeb644bd12de6ab2ee061c48b786f87fdc4b6fb10dbeb706f45
3
+ metadata.gz: 14f8d44bfa9cd1fbcd49da2f848df5ed1e8dd6086555a8b163d43e0137303284
4
+ data.tar.gz: f695e704124133507245e5ec0c7e596aa1b4c97117e14c2ac79b6497a83224c8
5
5
  SHA512:
6
- metadata.gz: 7f18d43dd7672ad30d7c4029e39ddda2eb27316d31f0312cc68f2e751ad34f818949150cb6306dd513194e73d2d54e88b457ce34b37003162f12df3aae476264
7
- data.tar.gz: c533499a1aeb11bcdaf5937dd9ce25fed799c0e8c02034cff9c6fe845ae57159b8d2a8f5211eeece89eb09e34d1777b69bb36a65d54b40b142dfb877f22b53a0
6
+ metadata.gz: 39c10beb0b76dbcfa9221bba0b0dccde17294b943d4a50639b7b1e66766040ce32a780d1849df3512efdfeb016abbccdd78298bde802001d8f131bee06f0ee39
7
+ data.tar.gz: 794dbdb41daed694e3d1f3fce433c7cfaa2a5846ffb7b03610b35ce9ab8b52d48b4d1ebf66a7a1bb15da41dd59baa380fcfc82f97d0d719512034372799f99a0
@@ -0,0 +1,297 @@
1
+ class FormatLine
2
+
3
+ EOL = :eol
4
+ Alpha = /[a-z]/
5
+ Alpha2 = /[a-z0-9_]/
6
+ Other = Object
7
+
8
+ SimpleFormats = {}
9
+ SimpleFormats[:b] = %w[<b> </b>]
10
+ SimpleFormats[:i] = %w[<i> </i>]
11
+ SimpleFormats[:t] = ["<font size=+1><tt>", "</tt></font>"]
12
+ SimpleFormats[:s] = %w[<strike> </strike>]
13
+
14
+ def initialize
15
+ @buffer, @vname, @fname, @param, @substr = "", "", "", "", ""
16
+ end
17
+
18
+ def peek
19
+ @enum.peek
20
+ rescue StopIteration
21
+ EOL
22
+ end
23
+
24
+ def grab
25
+ @enum.next
26
+ rescue StopIteration
27
+ EOL
28
+ end
29
+
30
+ def skip
31
+ @enum.next
32
+ @enum.peek
33
+ rescue StopIteration
34
+ EOL
35
+ end
36
+
37
+ def keep(initial = "")
38
+ @buffer << initial
39
+ @buffer << @enum.next
40
+ rescue StopIteration
41
+ EOL
42
+ end
43
+
44
+ def emit(str = "")
45
+ @buffer << str
46
+ end
47
+
48
+ def funcall(name, param)
49
+ if self.respond_to?("func_" + name.to_s)
50
+ self.send("func_" + name.to_s, param)
51
+ else
52
+ fobj = ::Livetext::Functions.new
53
+ ::Livetext::Functions.param = param # is this
54
+ ::Livetext::Functions.context = @context # screwed up???
55
+ fobj.send(name)
56
+ end
57
+ end
58
+
59
+ def vsub
60
+ @buffer << Livetext::Vars[@vname]
61
+ @vname = ""
62
+ end
63
+
64
+ def fcall
65
+ @buffer << funcall(@fname, @param)
66
+ @fname, @param = "", ""
67
+ end
68
+
69
+ # FIXME Much of this should be done via CSS
70
+ # FIXME In particular, strike is deprecated.
71
+
72
+ def bold
73
+ d0, d1 = SimpleFormats[:b]
74
+ @buffer << "#{d0}#@substr#{d1}"
75
+ @substr = ""
76
+ end
77
+
78
+ def ttype
79
+ d0, d1 = SimpleFormats[:t]
80
+ @buffer << "#{d0}#@substr#{d1}"
81
+ @substr = ""
82
+ end
83
+
84
+ def italics
85
+ d0, d1 = SimpleFormats[:i]
86
+ @buffer << "#{d0}#@substr#{d1}"
87
+ @substr = ""
88
+ end
89
+
90
+ def strike
91
+ d0, d1 = SimpleFormats[:s]
92
+ @buffer << "#{d0}#@substr#{d1}"
93
+ @substr = ""
94
+ end
95
+
96
+ def parse(line, context = nil)
97
+ context ||= binding
98
+ @context = context
99
+ @enum = line.chomp.each_char
100
+ @buffer = ""
101
+ @substr = ""
102
+ @fname = ""
103
+ @vname = ""
104
+ @param = ""
105
+
106
+ # FIXME - refactor, generalize, clarify
107
+
108
+ loop do # starting state
109
+ char = peek
110
+ case char
111
+ when "\\"
112
+ char = skip
113
+ case char
114
+ when "$", "*", "_", "`", "~"
115
+ emit(char)
116
+ skip
117
+ when " "
118
+ emit("\\ ")
119
+ skip
120
+ when EOL
121
+ emit("\\")
122
+ break
123
+ when Other
124
+ emit("\\") # logic??
125
+ end
126
+ when EOL
127
+ break
128
+ when "$" # var or func or $
129
+ case skip
130
+ when EOL
131
+ emit("$")
132
+ break
133
+ when Alpha
134
+ loop { ch = peek; break if ch == EOL; @vname << grab; break unless Alpha2 === peek }
135
+ vsub
136
+ when "$"
137
+ case skip
138
+ when EOL
139
+ emit("$$")
140
+ break
141
+ when Alpha
142
+ loop { ch = peek; break if ch == EOL; @fname << grab; break unless Alpha2 === peek }
143
+ case peek
144
+ when " " # no param - just call
145
+ @param = nil
146
+ fcall # no param? Hmm
147
+ when "[" # long param
148
+ skip
149
+ loop do
150
+ if peek == "\\"
151
+ skip
152
+ @param << grab
153
+ end
154
+ break if ["]", EOL].include?(peek)
155
+ @param << grab
156
+ end
157
+ skip
158
+ fcall
159
+ when ":" # param (single token or to-eol)
160
+ case skip
161
+ when ":" # param to eol
162
+ skip
163
+ loop { break if peek == EOL; @param << grab }
164
+ when Other # grab until space or eol
165
+ loop { @param << grab; break if [" ", EOL].include?(peek) }
166
+ fcall
167
+ end
168
+ when Other # no param - just call
169
+ fcall
170
+ end
171
+ when Other
172
+ emit "$$"
173
+ end
174
+ when Other
175
+ emit "$"
176
+ end
177
+ when "*"
178
+ case skip
179
+ when EOL
180
+ emit "*"
181
+ when " "
182
+ emit "*"
183
+ when "["
184
+ skip
185
+ loop do
186
+ if peek == "\\"
187
+ skip
188
+ @substr << grab
189
+ next
190
+ end
191
+ break if ["]", EOL].include?(peek)
192
+ @substr << grab
193
+ end
194
+ skip
195
+ bold
196
+ when Other
197
+ loop { @substr << grab; break if [" ", EOL].include?(peek) }
198
+ bold
199
+ end
200
+ when "_"
201
+ case skip
202
+ when EOL
203
+ emit "_"
204
+ when " "
205
+ emit "_"
206
+ when "["
207
+ skip
208
+ loop do
209
+ if peek == "\\"
210
+ skip
211
+ @substr << grab
212
+ next
213
+ end
214
+ break if ["]", EOL].include?(peek)
215
+ @substr << grab
216
+ end
217
+ skip
218
+ italics
219
+ when "_" # doubled...
220
+ skip
221
+ loop do
222
+ if peek == "\\"
223
+ skip
224
+ @substr << grab
225
+ next
226
+ end
227
+ break if [".", ",", ")", EOL].include?(peek)
228
+ @substr << grab
229
+ end
230
+ italics
231
+ when Other
232
+ loop { @substr << grab; break if [" ", EOL].include?(peek) }
233
+ italics
234
+ end
235
+ when "`"
236
+ case skip
237
+ when EOL
238
+ emit "`"
239
+ when " "
240
+ emit "`"
241
+ when "["
242
+ skip
243
+ loop do
244
+ if peek == "\\"
245
+ skip
246
+ @substr << grab
247
+ next
248
+ end
249
+ break if ["]", EOL].include?(peek)
250
+ @substr << grab
251
+ end
252
+ skip
253
+ ttype
254
+ when "`" # doubled...
255
+ skip
256
+ loop { break if [".", ",", ")", EOL].include?(peek); @substr << grab } # ";" ?? FIXME
257
+ ttype
258
+ when Other
259
+ loop { @substr << grab; break if [" ", EOL].include?(peek) }
260
+ ttype
261
+ end
262
+ when "~"
263
+ case skip
264
+ when EOL
265
+ emit "~"
266
+ when " "
267
+ emit "~"
268
+ when "["
269
+ skip
270
+ loop do
271
+ if peek == "\\"
272
+ skip
273
+ @substr << grab
274
+ next
275
+ end
276
+ break if ["]", EOL].include?(peek)
277
+ @substr << grab
278
+ end
279
+ skip
280
+ strike
281
+ when "~" # doubled...
282
+ skip
283
+ loop { break if [".", ",", ")", EOL].include?(peek); @substr << grab } # ";" ?? FIXME
284
+ strike
285
+ when Other
286
+ loop { @substr << grab; break if [" ", EOL].include?(peek) }
287
+ strike
288
+ end
289
+ when Other
290
+ keep
291
+ end
292
+ end
293
+
294
+ @buffer
295
+ end
296
+ end
297
+
@@ -0,0 +1,707 @@
1
+ class FormatLine
2
+
3
+ SimpleFormats = {}
4
+ SimpleFormats[:b] = %w[<b> </b>]
5
+ SimpleFormats[:i] = %w[<i> </i>]
6
+ SimpleFormats[:t] = ["<font size=+1><tt>", "</tt></font>"]
7
+ SimpleFormats[:s] = %w[<strike> </strike>]
8
+
9
+ Null = ""
10
+ Space = " "
11
+ Alpha = /[A-Za-z]/
12
+ AlNum = /[A-Za-z0-9_]/
13
+ LF = "\n"
14
+ LBrack = "["
15
+
16
+ Blank = [" ", nil, "\n"]
17
+ Punc = [")", ",", ".", " ", "\n"]
18
+ NoAlpha = /[^A-Za-z0-9_]/
19
+ Param = ["]", "\n", nil]
20
+ Escape = "\\" # not an ESC char
21
+
22
+ def terminate?(terminators, ch)
23
+ if terminators.is_a? Regexp
24
+ terminators === ch
25
+ else
26
+ terminators.include?(ch)
27
+ end
28
+ end
29
+
30
+ attr_reader :out
31
+
32
+ def initialize(line, context)
33
+ context ||= binding
34
+ @context = context
35
+ @line = line
36
+ @i = -1
37
+ @token = Null.dup
38
+ @tokenlist = []
39
+ end
40
+
41
+ def old_initialize(line, context)
42
+ context ||= binding
43
+ @context = context
44
+ @line = line
45
+ chars = [nil] + line.scan(/./) + [nil] + [nil]
46
+ @gen = chars.each_cons(3)
47
+ @cc = 0 # char count
48
+ go # @prev, @ch, @next = *@gen.next
49
+ @out = ""
50
+ loop do
51
+ case @ch
52
+ when "\\"
53
+ go
54
+ emit @ch
55
+ next
56
+ when "$"; dollar
57
+ when "*"; asterisk
58
+ when "_"; underscore
59
+ when "`"; backtick
60
+ when "~"; tilde; # showme("after tilde")
61
+ when nil; break
62
+ else
63
+ emit @ch; # STDERR.puts "--- else - emitted #{@ch.inspect}"
64
+ end
65
+ go
66
+ end
67
+ end
68
+
69
+ def self.parse(line, context = nil)
70
+ x = self.new(line, context)
71
+ x.out
72
+ end
73
+
74
+ def self.parse!(line, context = nil)
75
+ x = self.new(line.chomp, context)
76
+ x.tokenize(line)
77
+ # x.evaluate # (context)
78
+ # x.out
79
+ x.evaluate
80
+ end
81
+
82
+ ############ new methods
83
+
84
+ def tokenize(line)
85
+ grab
86
+ loop do
87
+ # puts "*** char #{curr}"
88
+ case curr
89
+ when Escape; go; add curr; grab
90
+ when "$"
91
+ _dollar
92
+ when "*", "_", "`", "~"
93
+ marker curr
94
+ add curr
95
+ when LF, nil
96
+ break
97
+ else
98
+ add curr
99
+ end
100
+ grab
101
+ # add_token(:str)
102
+ end
103
+ add_token(:str)
104
+ # p @tokenlist
105
+ @tokenlist
106
+ end
107
+
108
+ def embed(sym, str)
109
+ pre, post = SimpleFormats[sym]
110
+ pre + str + post
111
+ end
112
+
113
+ def evaluate(tokens = @tokenlist)
114
+ @out = ""
115
+ return "" if tokens.empty?
116
+ gen = tokens.each
117
+ token = gen.next
118
+ loop do
119
+ break if token.nil?
120
+ sym, val = *token
121
+ case sym
122
+ when :str
123
+ @out << val unless val == "\n" # BUG
124
+ when :var
125
+ @out << varsub(val)
126
+ when :func
127
+ param = nil
128
+ arg = gen.peek
129
+ if [:colon, :brackets].include? arg[0]
130
+ arg = gen.next # for real
131
+ param = arg[1]
132
+ end
133
+ @out << funcall(val, param)
134
+ when :b, :i, :t, :s
135
+ @out << embed(sym, val)
136
+ else
137
+ add_token :str
138
+ end
139
+ token = gen.next
140
+ end
141
+ # p @out
142
+ @out
143
+ end
144
+
145
+ def curr
146
+ @line[@i]
147
+ end
148
+
149
+ def prev
150
+ @line[@i-1]
151
+ end
152
+
153
+ def next!
154
+ @line[@i+1]
155
+ end
156
+
157
+ def grab
158
+ @line[@i+=1]
159
+ end
160
+
161
+ def grab_colon_param
162
+ grab # grab :
163
+ param = ""
164
+ loop do
165
+ case next!
166
+ when Escape
167
+ grab
168
+ param << next!
169
+ grab
170
+ when Space, LF, nil; break
171
+ else
172
+ param << next!
173
+ grab
174
+ end
175
+ end
176
+
177
+ param = nil if param.empty?
178
+ param
179
+ end
180
+
181
+ def grab_func_param
182
+ grab # [
183
+ param = ""
184
+ loop do
185
+ case next!
186
+ when Escape
187
+ grab
188
+ param << next!
189
+ grab
190
+ when "]", LF, nil; break
191
+ else
192
+ param << next!
193
+ grab
194
+ end
195
+ end
196
+
197
+ add curr
198
+ grab
199
+ param = nil if param.empty?
200
+ param
201
+ end
202
+
203
+ def add(str)
204
+ @token << str unless str.nil?
205
+ end
206
+
207
+ Syms = { "*" => :b, "_" => :i, "`" => :t, "~" => :s }
208
+
209
+ def self.format(line, context = nil)
210
+ x = self.new(line, context)
211
+ x.format
212
+ end
213
+
214
+ def format
215
+ grab
216
+ loop do
217
+ case curr
218
+ when Escape; go; add curr; grab
219
+ when "$"
220
+ _dollar
221
+ when "*", "_", "`", "~"
222
+ marker curr
223
+ when LF, nil
224
+ break
225
+ else
226
+ add curr
227
+ end
228
+ grab
229
+ end
230
+ add_token(:str)
231
+ @tokenlist
232
+ end
233
+
234
+ def add_token(kind, token = @token)
235
+ @tokenlist << [kind, token] unless token.empty?
236
+ @token = Null.dup
237
+ end
238
+
239
+ def grab_alpha
240
+ str = Null.dup
241
+ grab
242
+ loop do
243
+ break if curr.nil?
244
+ str << curr
245
+ break if terminate?(NoAlpha, next!)
246
+ grab
247
+ end
248
+ str
249
+ end
250
+
251
+ def _dollar
252
+ grab
253
+ case curr
254
+ when LF; add "$"; add_token :str
255
+ when " "; add "$ "; add_token :str
256
+ when nil; add "$"; add_token :str
257
+ when "$"; _double_dollar
258
+ when "."; _dollar_dot
259
+ when /[A-Za-z]/
260
+ add_token :str
261
+ var = curr + grab_alpha
262
+ add_token(:var, var)
263
+ else
264
+ add "$" + curr
265
+ add_token(:string)
266
+ end
267
+ end
268
+
269
+ def handle_function_call
270
+ end
271
+
272
+ def _double_dollar
273
+ case next!
274
+ when Space; add_token :string, "$$ "; grab; return
275
+ when LF, nil; add "$$"; add_token :str
276
+ when Alpha
277
+ add_token(:str, @token)
278
+ func = grab_alpha
279
+ add_token(:func, func)
280
+ case next!
281
+ when ":"; param = grab_colon_param; add_token(:colon, param)
282
+ when "["; param = grab_func_param; add_token(:brackets, param)
283
+ else # do nothing
284
+ end
285
+ else
286
+ grab; add_token :str, "$$" + curr; return
287
+ end
288
+ end
289
+
290
+ def dollar_dot
291
+ add_token :ddot, @line[@i..-1]
292
+ end
293
+
294
+ def marker(char)
295
+ add_token :str
296
+ sym = Syms[char]
297
+ if embedded?
298
+ add char # ??? add_token "*", :string
299
+ return
300
+ end
301
+ grab
302
+ case curr
303
+ when Space
304
+ add char + " "
305
+ add_token :str
306
+ grab
307
+ when LF, nil
308
+ add char
309
+ add_token :str
310
+ when char; double_marker(char)
311
+ when LBrack; long_marker(char)
312
+ else
313
+ add curr
314
+ str = collect!(sym, Blank)
315
+ add_token sym, str
316
+ add curr # next char onto next token...
317
+ end
318
+ end
319
+
320
+ def double_marker(char)
321
+ sym = Syms[char]
322
+ grab
323
+ kind = sym # "string_#{char}".to_sym
324
+ case next! # first char after **
325
+ when Space, LF, nil
326
+ pre, post = SimpleFormats[sym]
327
+ add_token kind
328
+ else
329
+ str = collect!(sym, Punc)
330
+ grab unless next!.nil?
331
+ add_token kind, str
332
+ end
333
+ end
334
+
335
+ def long_marker(char)
336
+ sym = Syms[char]
337
+ # grab # skip left bracket
338
+ kind = sym # "param_#{sym}".to_sym
339
+ arg = collect!(sym, Param, true)
340
+ add_token kind, arg
341
+ # add curr
342
+ end
343
+
344
+ def collect!(sym, terminators, param=false)
345
+ str = Null.dup # next is not " ","*","["
346
+ grab
347
+ loop do
348
+ if curr == Escape
349
+ str << grab # ch = escaped char
350
+ grab
351
+ next
352
+ end
353
+ break if terminate?(terminators, curr)
354
+ str << curr # not a terminator
355
+ grab
356
+ end
357
+ grab if param && curr == "]" # skip right bracket
358
+ # str << curr # if @ch
359
+ # add curr # next char onto next token...
360
+ add str
361
+ end
362
+
363
+ ############
364
+
365
+ ### From FormatLine:
366
+
367
+ def funcall(name, param)
368
+ result =
369
+ if self.respond_to?("func_" + name.to_s)
370
+ self.send("func_" + name.to_s, param)
371
+ else
372
+ fobj = ::Livetext::Functions.new
373
+ ::Livetext::Functions.param = param # is this
374
+ ::Livetext::Functions.context = @context # screwed up???
375
+ fobj.send(name)
376
+ end
377
+ result
378
+ end
379
+
380
+ def varsub(name)
381
+ result = Livetext::Vars[name]
382
+ result
383
+ end
384
+
385
+ #####
386
+
387
+ def showme(tag)
388
+ char = @line[@cc]
389
+ puts "--- #{tag}: ch=#{@ch.inspect} next=#{@next.inspect} (cc=#@cc:#{char.inspect}) out=#{@out.inspect}"
390
+ end
391
+
392
+ def accumulate!(sym, terminators, param=false)
393
+ # already ate *[ - ch=[
394
+ str = "" # next is not " ","*","["
395
+ go
396
+ loop do
397
+ if @ch == "\\"
398
+ go # ch = escaped char
399
+ str << @ch
400
+ go
401
+ next
402
+ end
403
+ break if terminate?(terminators, @ch)
404
+ str << @ch # not a terminator
405
+ go
406
+ end
407
+ pre, post = SimpleFormats[sym]
408
+ str = (pre + str + post)
409
+ go if param && @ch == "]" # skip right bracket
410
+ str << @ch if @ch
411
+ emit str
412
+ end
413
+
414
+ def go
415
+ @cc += 1 # char count
416
+ @prev, @ch, @next = *@gen.next
417
+ end
418
+
419
+ def blank?(ch)
420
+ [" ", nil, "\n"].include? ch
421
+ end
422
+
423
+ def term_punc?(ch)
424
+ [")", ",", ".", " ", "\n"].include? ch
425
+ end
426
+
427
+ def not_alphanum?(ch)
428
+ ch !~ /[A-Za-z0-9_]/
429
+ end
430
+
431
+ def term_param?(ch)
432
+ ["]", "\n", nil].include? ch
433
+ end
434
+
435
+ def embedded?
436
+ ! (['"', "'", " ", nil].include? @prev)
437
+ end
438
+
439
+ def _embedded?
440
+ ! (['"', "'", " ", nil].include? prev)
441
+ end
442
+
443
+ def emit(str)
444
+ return if str.nil? || str.empty?
445
+ str ||= ""
446
+ @out << str
447
+ end
448
+
449
+ ### dollar...
450
+
451
+ def dollar
452
+ go
453
+ case @ch
454
+ when " "; emit "$ "
455
+ when nil; emit "$"
456
+ when "$"; double_dollar
457
+ when "."; dollar_dot
458
+ when /[A-Za-z]/
459
+ var = @ch + get_alpha
460
+ str = varsub(var)
461
+ emit str
462
+ else
463
+ emit "$" + @ch
464
+ end
465
+ end
466
+
467
+ def get_alpha
468
+ str = ""
469
+ grab
470
+ loop do
471
+ str << @ch
472
+ break if terminate?(NoAlpha, @next)
473
+ grab
474
+ end
475
+ str
476
+ end
477
+
478
+ def collect(terminators = NoAlpha)
479
+ str = ""
480
+ go
481
+ loop do
482
+ if @ch == "\\"
483
+ go # ch = escaped char
484
+ str << @ch
485
+ go
486
+ next
487
+ else
488
+ str << @ch
489
+ end
490
+ break if terminate?(terminators, @ch)
491
+ go
492
+ end
493
+ str
494
+ end
495
+
496
+ def get_colon_param
497
+ go # grab :
498
+ param = ""
499
+ loop do
500
+ case @next
501
+ when "\\"
502
+ go
503
+ param << @next
504
+ go
505
+ when " ", "\n", nil; break
506
+ else
507
+ param << @next
508
+ go
509
+ end
510
+ end
511
+
512
+ param = nil if param.empty?
513
+ param
514
+ end
515
+
516
+ def get_func_param
517
+ go # grab [
518
+ param = ""
519
+ loop do
520
+ case @next
521
+ when "\\"
522
+ go
523
+ param << @next
524
+ go
525
+ when "]", "\n", nil; break
526
+ else
527
+ param << @next
528
+ go
529
+ end
530
+ end
531
+
532
+ go
533
+ param = nil if param.empty?
534
+ param
535
+ end
536
+
537
+ def get_func_call
538
+ func = get_alpha
539
+ param = nil
540
+ case @next
541
+ when "["
542
+ param = get_func_param
543
+ when ":"
544
+ param = get_colon_param
545
+ end
546
+ [func, param]
547
+ end
548
+
549
+ def double_dollar
550
+ case @next
551
+ when " "
552
+ emit "$$ "
553
+ go
554
+ return
555
+ when /[A-Za-z]/
556
+ func, param = get_func_call
557
+ else
558
+ go
559
+ emit "$$" + (@ch || "")
560
+ return
561
+ end
562
+
563
+ str = funcall(func, param)
564
+ save = @ch.dup # save last char
565
+ emit str # if str && ! @ch.nil?
566
+ # emit save if @next.nil? ### HERE
567
+ end
568
+
569
+ def dollar_dot
570
+ go
571
+ dot = collect { not_alphanum?(@ch) }
572
+ emit "DOT(#{dot})" # not implemented yet
573
+ end
574
+
575
+ ### asterisk...
576
+
577
+ def asterisk
578
+ return emit("*") if embedded?
579
+ case @next
580
+ when " ", nil; emit "*"
581
+ when "*"; double_asterisk
582
+ when "["; long_asterisk
583
+ else
584
+ accumulate!(:b, Blank)
585
+ end
586
+ end
587
+
588
+ def double_asterisk
589
+ go
590
+ case @next # first char after **
591
+ when " ", nil; emit "<b>*</b>"
592
+ else
593
+ accumulate!(:b, Punc)
594
+ go unless @next.nil?
595
+ emit @ch
596
+ end
597
+ end
598
+
599
+ def long_asterisk
600
+ go # skip left bracket
601
+ accumulate!(:b, Param, true)
602
+ end
603
+
604
+ ### underscore...
605
+
606
+ def underscore
607
+ return emit("_") if embedded?
608
+ case @next
609
+ when " ", nil; emit "_"
610
+ when "_"; double_underscore
611
+ when "["; long_underscore
612
+ else
613
+ accumulate!(:i, Blank)
614
+ # emit @ch unless @ch.nil?
615
+ end
616
+ end
617
+
618
+ def double_underscore
619
+ go
620
+ case @next # first char after __
621
+ when " ", nil; emit "<i>_</i>"
622
+ else
623
+ accumulate!(:i, Punc)
624
+ go unless @next.nil?
625
+ emit @ch
626
+ end
627
+ end
628
+
629
+ def long_underscore
630
+ go # skip left bracket
631
+ accumulate!(:i, Param, true)
632
+ end
633
+
634
+ ### backtick...
635
+
636
+ def backtick
637
+ return emit("`") if embedded?
638
+ case @next
639
+ when " ", nil; emit "`"
640
+ when "`"; double_backtick
641
+ when "["; long_backtick
642
+ else
643
+ accumulate!(:t, Blank)
644
+ end
645
+ end
646
+
647
+ def double_backtick
648
+ go
649
+ case @next # first char after ``
650
+ when " ", nil; emit "<tt>*</tt>"
651
+ else
652
+ accumulate!(:t, Punc)
653
+ go unless @next.nil?
654
+ emit @ch
655
+ end
656
+ end
657
+
658
+ def long_backtick
659
+ go # skip left bracket
660
+ accumulate!(:t, Param, true)
661
+ end
662
+
663
+ ### tilde...
664
+
665
+ def tilde
666
+ return emit("~") if embedded?
667
+ case @next
668
+ when " ", nil; emit "~"
669
+ when "~"; double_tilde
670
+ when "["; long_tilde
671
+ else
672
+ accumulate!(:s, Blank)
673
+ end
674
+ end
675
+
676
+ def double_tilde
677
+ go
678
+ case @next # first char after ~~
679
+ when " ", nil; emit "<strike>~</strike>"
680
+ else
681
+ accumulate!(:s, Punc)
682
+ go unless @next.nil?
683
+ emit @ch
684
+ end
685
+ end
686
+
687
+ def long_tilde
688
+ go # skip left bracket
689
+ accumulate!(:s, Param, true)
690
+ end
691
+
692
+ end
693
+
694
+
695
+ # LineParser.new("Here's a $ dollar sign, a $$function, a $variable, and a $.dot_command.")
696
+ # LineParser.new("This is *bold and _italics and `code and ~strike")
697
+ # LineParser.new("This is **bold, but with two asterisks.")
698
+ # LineParser.new("Bold asterisk ** here.")
699
+ # LineParser.new("What about an embedded asterisk like X*Y situation?")
700
+ # LineParser.new("What about multiple_embedded_underscores and such?")
701
+ # LineParser.new("Try a bolded *string_with_underscores")
702
+ # LineParser.new("Bolded *[arbitrary parameter with stuff: * _ ` ~ ]...")
703
+ # LineParser.new("Bold *[until end of line")
704
+ # LineParser.new("This is **bold, __italics, ``code, and ~~strike.")
705
+ # LineParser.new("This is *[bold stuff], _[italics stuff], `[code stuff], and ~[strike stuff].")
706
+
707
+