pipetext 0.2.6 → 0.2.8

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.
@@ -1,1229 +1,12 @@
1
- # frozen_string_literal: true
2
-
3
- module PipeText
4
-
5
- public
6
-
7
- def pipetext_init(box_mode=true, ampersand_mode=false)
8
- attributes = {
9
- 'pipe' => false, # Pipe already been found?
10
- 'repeat_pattern' => false, # Used by |<#>~repeat pattern~
11
- 'pattern' => String.new, # Used by |<#>~repeat pattern~ to capture
12
- 'escape' => false, # Has an escape \ already been found in front of this character?
13
- 'ampersand' => false, # Has an ampersand already been found in front of this character?
14
- 'ampersand_mode' => ampersand_mode, # Do we even process ampersands for background colors?
15
- 'blink' => false, # Is blink turned on?
16
- 'bold' => false,
17
- 'crossed_out' => false,
18
- 'faint' => false,
19
- 'found' => false, # At the end -- did we find a match?
20
- 'italic' => false,
21
- 'inverse' => false,
22
- 'underline' => false,
23
- 'box' => -1, # Default to |O (no boxes)
24
- 'box_mode' => box_mode,
25
- 'num' => 0, # Number of times to repeat pattern
26
- 'end_capture' => false, # Used to capture the end column number
27
- 'end' => 0, # Number which current denotes the end of the column
28
- 'position' => 0, # Number which current position in the column
29
- 'center_capture' => false, # Used to capture text for centering
30
- 'center' => String.new, # Text to be centered
31
- 'variable_capture' => false, # Used to capture a variable for update or to display
32
- 'variable' => String.new, # Variable captured
33
- 'variables' => Hash.new, # Stores all captured variables
34
- 'emoji_capture' => false, # Used to capture emoji description or bell/move to position
35
- 'emoji' => String.new, # Used to capture emoji description or bell/move to position
36
- 'unicode_capture' => 0, # Used to capture Unicode using 6 character UTF-16 hex format
37
- 'unicode' => String.new,
38
- 'palette_capture' => 0, # Used to capture 8-bit color using 2 character hex format
39
- 'p' => String.new, # |p00 to |pFF
40
- 'color_capture' => 0, # Used to capture RGB color using #RRGGBB format
41
- 'r' => String.new,
42
- 'g' => String.new,
43
- 'b' => String.new,
44
- 'fg' => String.new, # Needed to restore after background change
45
- 'bg' => String.new, # Needed to restore after foreground change
46
- 'shell_prompt' => false # Used to add \[ and \] around non-printables for prompts
47
- }
48
- attributes['variables']['height'] = `tput lines`.chomp
49
- attributes['variables']['width'] = `tput cols`.chomp
50
- return attributes
51
- end
52
-
53
- def pipe(text, attributes)
54
- new_text = String.new
55
- text.chars.each do |character|
56
- process_character(character, new_text, attributes)
57
- if(new_text =~ /.*\n(.*)$/m)
58
- attributes['position'] = printable_length($1)
59
- else
60
- attributes['position'] += printable_length(new_text)
61
- end
62
- end
63
- # Clean up in case we've captured something we didn't process yet
64
- if(attributes['color_capture'] > 0)
65
- emit_color(new_text, attributes)
66
- elsif(attributes['palette_capture'] > 0)
67
- emit_palette_color(new_text, attributes)
68
- elsif(attributes['unicode_capture'] > 0)
69
- emit_unicode(new_text, attributes)
70
- elsif(attributes['emoji_capture'] == true)
71
- new_text << "|[" + attributes['emoji']
72
- elsif(attributes['center_capture'] == true)
73
- new_text << "|{" + attributes['center']
74
- elsif(attributes['variable_capture'] == true)
75
- new_text << "|(" + attributes['variable']
76
- end
77
- return new_text
78
- end
79
-
80
- def pipetext(text, box_mode=true, ampersand_mode=false)
81
- pipe(text, pipetext_init(box_mode, ampersand_mode))
82
- end
83
-
84
- # Immediate output to screen, no string buffer
85
- def fastpipe(text, attributes)
86
- new_text = String.new
87
- text.chars.each do |character|
88
- process_character(character, new_text, attributes)
89
- if(new_text != "")
90
- print(new_text)
91
- if(new_text =~ /\n(.*)$/)
92
- attributes['position'] = printable_length($1)
93
- else
94
- attributes['position'] += printable_length(new_text)
95
- end
96
- new_text = String.new
97
- end
98
- end
99
- # Clean up in case we've captured something we didn't process yet
100
- if(attributes['color_capture'] > 0)
101
- emit_color(new_text, attributes)
102
- elsif(attributes['palette_capture'] > 0)
103
- emit_palette_color(new_text, attributes)
104
- elsif(attributes['unicode_capture'] > 0)
105
- emit_unicode(new_text, attributes)
106
- elsif(attributes['emoji_capture'] == true)
107
- new_text << "|[" + attributes['emoji']
108
- elsif(attributes['center_capture'] == true)
109
- new_text << "|{" + attributes['center']
110
- elsif(attributes['variable_capture'] == true)
111
- new_text << "|(" + attributes['variable']
112
- end
113
- print(new_text)
114
- end
115
-
116
- def fastpipetext(text, box_mode=true, ampersand_mode=false)
117
- fastpipe(text, pipetext_init(box_mode, ampersand_mode))
118
- end
119
-
120
- def write(text, box_mode=true, ampersand_mode=false)
121
- fastpipetext(text, box_mode, ampersand_mode)
122
- end
123
-
124
- # Defaults to using & for background colors
125
- def paint(text, box_mode=true, ampersand_mode=true)
126
- fastpipetext(text, box_mode, ampersand_mode)
127
- end
128
-
129
- def ignored_character(character, ignored_characters)
130
- ignored_characters.chars.each do |ignored|
131
- if(character == ignored)
132
- return true
133
- end
134
- end
135
- return false
136
- end
137
-
138
- # Match abbreviated text descriptions for emojis by default ignore case and punctuation
139
- # Allows for 'space anchoring' so you can use |[smi f w he e] as an abbreviation for
140
- # |[smiling face with heart-eyes]
141
- def abbreviated_match(input, match, case_match=false, ignored_characters=",.':-")
142
- if(!input || !match)
143
- return 0
144
- end
145
- count = 0
146
- offset = 0
147
- input.chars.each_with_index do |character, index|
148
- while(ignored_character(match[index + offset], ignored_characters))
149
- offset += 1
150
- end
151
- if(character == match[index + offset].chr)
152
- count += 1
153
- elsif(case_match == false && character.downcase == match[index + offset].chr.downcase)
154
- count += 1
155
- elsif(character == ' ' && match[index + offset..-1] =~ / /)
156
- count += 1
157
- while(match[index + offset].chr != character)
158
- offset += 1
159
- end
160
- else
161
- count = 0
162
- offset = 0
163
- break
164
- end
165
- end
166
- return count + offset
167
- end
168
-
169
- # This is not entirely accurate because of emojis, which we assume are 2 characters
170
- def printable_length(string)
171
- if(string == "")
172
- return 0
173
- end
174
- length = 0
175
- escape = false
176
- wide = false
177
- wide_count = 0
178
- string.chars.each do |character|
179
- if(character[0].ord == 27)
180
- escape = true
181
- elsif(character[0].ord == 226 && wide == false)
182
- wide = true
183
- elsif(character[0].ord == 240 && wide == false)
184
- wide = true
185
- elsif(character[0].ord >= 32)
186
- if(escape == true && character[0].ord == 109)
187
- escape = false
188
- elsif(character[0].ord > 9600) # ~ Emoji / Unicode - double wide characters start
189
- length += 2
190
- elsif(escape == false && wide == false)
191
- length += 1
192
- elsif(wide == true)
193
- wide_count += 1
194
- end
195
- if(wide == true && wide_count >= 2)
196
- if(character[0].ord == 147)
197
- length += 1
198
- end
199
- length += 1
200
- wide = false
201
- wide_count = 0
202
- end
203
- end
204
- end
205
- if(wide == true && wide_count > 0)
206
- length += 1
207
- end
208
- return length
209
- end
210
-
211
- private
212
-
213
- def process_character(character, new_text, attributes)
214
- if(attributes['repeat_pattern'] == false)
215
- # Will still need to process character, first process incorrect formats
216
- if(attributes['color_capture'] > 0 && character !~ /[0-9,A-F,a-f]/)
217
- emit_color(new_text, attributes)
218
- elsif(attributes['palette_capture'] > 0 && character !~ /[0-9,A-F,a-f]/)
219
- emit_palette_color(new_text, attributes)
220
- elsif(attributes['unicode_capture'] > 0 && character !~ /[0-9,A-F,a-f,+]/ ||
221
- (attributes['unicode_capture'] != 1 && character == '+'))
222
- emit_unicode(new_text, attributes)
223
- end
224
- end
225
- if(attributes['end_capture'] == true && character !~ /[0-9]/)
226
- attributes['end'] = attributes['num']
227
- attributes['num'] = 0
228
- attributes['end_capture'] = false
229
- end
230
- if(attributes['end_capture'] == true && character =~ /[0-9]/)
231
- if(character == '0') # |10+
232
- if(attributes['num'] > 0)
233
- attributes['num'] *= 10
234
- end
235
- elsif(character >= '1' && character <= '9') # |1+ through |9+
236
- if(attributes['num'] > 0)
237
- attributes['num'] *= 10
238
- end
239
- attributes['num'] += character.to_i
240
- end
241
- elsif(character == ')' && attributes['variable_capture'] == true && attributes['escape'] == false)
242
- if(attributes['variable'] =~ /=/ && attributes['variable'][0] != '#') # Update
243
- update_variable(attributes)
244
- else # Display
245
- emit_variable(new_text, attributes)
246
- end
247
- elsif(attributes['variable_capture'] == true)
248
- if(character == '\\')
249
- attributes['escape'] = true
250
- else
251
- if(attributes['escape'] == true)
252
- attributes['variable'] << "\\#{character}"
253
- attributes['escape'] = false
254
- else
255
- attributes['variable'] << character
256
- end
257
- end
258
- elsif(attributes['center_capture'] == true)
259
- if(character == '\\')
260
- attributes['escape'] = true
261
- else
262
- if(attributes['escape'] == true)
263
- attributes['center'] << "\\#{character}"
264
- attributes['escape'] = false
265
- elsif(character == '}')
266
- emit_center(new_text, attributes)
267
- else
268
- attributes['center'] << character
269
- end
270
- end
271
- elsif(attributes['emoji_capture'] == true)
272
- if(character == ']')
273
- if(attributes['emoji'] =~ /bell/)
274
- new_text << "\a"
275
- attributes['emoji'] = String.new
276
- attributes['emoji_capture'] = false
277
- elsif(attributes['emoji'] =~ /^([0-9]*)[,;]([0-9]*)$/)
278
- if(attributes['shell_prompt'] == true)
279
- new_text << "\\[\e[#{$1};#{$2}H\\]"
280
- else
281
- new_text << "\e[#{$1};#{$2}H"
282
- end
283
- attributes['emoji'] = String.new
284
- attributes['emoji_capture'] = false
285
- elsif(attributes['emoji'] =~ /^([0-9]*)s$/i) # Sleep in seconds
286
- attributes['emoji'] = String.new
287
- attributes['emoji_capture'] = false
288
- sleep($1.to_i)
289
- elsif(attributes['emoji'] =~ /^([0-9]*)ms$/i) # Sleep in milliseconds
290
- attributes['emoji'] = String.new
291
- attributes['emoji_capture'] = false
292
- sleep($1.to_i / 1000.0)
293
- else
294
- emit_emoji(new_text, attributes)
295
- end
296
- else
297
- attributes['emoji'] << character
298
- end
299
- elsif(character == '|' && attributes['repeat_pattern'] == false)
300
- process_pipe(character, new_text, attributes)
301
- elsif(character == '~' && attributes['pipe'] == true &&
302
- attributes['num'] > 0 && attributes['escape'] == false)
303
- process_repeat_pattern(character, new_text, attributes)
304
- elsif(attributes['repeat_pattern'] == true)
305
- capture_character_pattern(character, attributes)
306
- elsif(attributes['color_capture'] > 0 && character =~ /[0-9,A-F,a-f]/)
307
- capture_color(character, new_text, attributes)
308
- elsif(attributes['palette_capture'] > 0 && character =~ /[0-9,A-F,a-f]/)
309
- capture_palette_color(character, new_text, attributes)
310
- elsif(attributes['unicode_capture'] == 1 && character == '+') # Skip
311
- return
312
- elsif(attributes['unicode_capture'] > 0 && character =~ /[0-9,A-F,a-f]/)
313
- capture_unicode(character, new_text, attributes)
314
- elsif(attributes['pipe'] == true &&
315
- attributes['repeat_pattern'] == false &&
316
- attributes['escape'] == true)
317
- process_escaped_character(character, new_text, attributes)
318
- elsif(character == '&' && attributes['ampersand_mode'] == true &&
319
- attributes['pipe'] == false)
320
- process_ampersand(character, new_text, attributes)
321
- elsif(attributes['pipe'] == true)
322
- process_piped_character(character, new_text, attributes)
323
- elsif(attributes['ampersand'] == true)
324
- process_ampersanded_character(character, new_text, attributes)
325
- elsif(attributes['box'] == 0)
326
- new_text << process_box_zero_replace(character)
327
- elsif(attributes['box'] == 1)
328
- new_text << process_box_one_replace(character)
329
- elsif(attributes['box'] == 2)
330
- new_text << process_box_two_replace(character)
331
- else
332
- new_text << character
333
- end
334
- end
335
-
336
- def emit_color(new_text, attributes)
337
- r = attributes['r'].to_i(16).to_s
338
- g = attributes['g'].to_i(16).to_s
339
- b = attributes['b'].to_i(16).to_s
340
- if(attributes['ampersand'] == true) # Background Color
341
- if(attributes['shell_prompt'] == true)
342
- new_text << "\\[\e[48;2;#{r};#{g};#{b}m\\]"
343
- else
344
- new_text << "\e[48;2;#{r};#{g};#{b}m"
345
- end
346
- attributes['ampersand'] = false
347
- else # Foreground Color
348
- if(attributes['shell_prompt'] == true)
349
- new_text << "\\[\e[38;2;#{r};#{g};#{b}m\\]"
350
- else
351
- new_text << "\e[38;2;#{r};#{g};#{b}m"
352
- end
353
- end
354
- attributes['color_capture'] = 0
355
- attributes['r'] = String.new
356
- attributes['g'] = String.new
357
- attributes['b'] = String.new
358
- end
359
-
360
- def emit_palette_color(new_text, attributes)
361
- p = attributes['p'].to_i(16).to_s
362
- if(attributes['ampersand'] == true) # Background Color
363
- if(attributes['shell_prompt'] == true)
364
- new_text << "\\[\e[48;5;#{p}m\\]"
365
- else
366
- new_text << "\e[48;5;#{p}m"
367
- end
368
- attributes['ampersand'] = false
369
- else # Foreground Color
370
- if(attributes['shell_prompt'] == true)
371
- new_text << "\\[\e[38;5;#{p}m\\]"
372
- else
373
- new_text << "\e[38;5;#{p}m"
374
- end
375
- end
376
- attributes['palette_capture'] = 0
377
- attributes['p'] = String.new
378
- end
379
-
380
- def emit_unicode(new_text, attributes)
381
- new_text << [attributes['unicode'].to_i(16)].pack('U*')
382
- attributes['unicode_capture'] = 0
383
- attributes['unicode'] = String.new
384
- end
385
-
386
- def number?(text)
387
- text.chars.each do |character|
388
- if(character !~ /[0-9 ]/)
389
- return false
390
- end
391
- end
392
- return true
393
- end
394
-
395
- def update_variable(attributes)
396
- if(attributes['variable'] =~ /(.*)\-=(.*)/)
397
- if(!number?($2) || !number?(attributes['variables'][$1]))
398
- attributes['variables'][$1].slice!($2)
399
- elsif(attributes['variable'] =~ /(.*) \-= ?(.*)/ || attributes['variable'] =~ /(.*)\-= ?(.*)/)
400
- value = attributes['variables'][$1].to_i - $2.to_i
401
- attributes['variables'][$1] = value.to_s
402
- end
403
- elsif(attributes['variable'] =~ /(.*)\+=(.*)/)
404
- if(!number?($2) || !number?(attributes['variables'][$1]))
405
- attributes['variables'][$1] += $2
406
- elsif(attributes['variable'] =~ /(.*) \+= ?(.*)/ || attributes['variable'] =~ /(.*)\+= ?(.*)/)
407
- value = attributes['variables'][$1].to_i + $2.to_i
408
- attributes['variables'][$1] = value.to_s
409
- end
410
- elsif(attributes['variable'] =~ /(.*) \*= ?(.*)/ || attributes['variable'] =~ /(.*)\*= ?(.*)/)
411
- value = attributes['variables'][$1].to_i * $2.to_i
412
- attributes['variables'][$1] = value.to_s
413
- elsif(attributes['variable'] =~ /(.*) \/= ?(.*)/ || attributes['variable'] =~ /(.*)\/= ?(.*)/)
414
- value = attributes['variables'][$1].to_i / $2.to_i
415
- attributes['variables'][$1] = value.to_s
416
- elsif(attributes['variable'] =~ /(.*) = ?(.*)/ || attributes['variable'] =~ /(.*)= ?(.*)/)
417
- attributes['variables'][$1] = $2
418
- end
419
- attributes['variable_capture'] = false
420
- attributes['variable'] = String.new
421
- end
422
-
423
- def emit_variable(new_text, attributes)
424
- if(attributes['variable'][0] == '#') # We are manipulating attributes['num']
425
- if(attributes['variable'][1..-1] =~ /(.*) \-= ?(.*)/ ||
426
- attributes['variable'][1..-1] =~ /(.*)\-= ?(.*)/)
427
- attributes['num'] = pipetext(escape_fix(attributes['variables'][$1]), attributes['box_mode'],
428
- attributes['ampersand_mode']).to_i - $2.to_i
429
- elsif(attributes['variable'][1..-1] =~ /(.*) \+= ?(.*)/ ||
430
- attributes['variable'][1..-1] =~ /(.*)\+= ?(.*)/)
431
- attributes['num'] = pipetext(escape_fix(attributes['variables'][$1]), attributes['box_mode'],
432
- attributes['ampersand_mode']).to_i + $2.to_i
433
- elsif(attributes['variable'][1..-1] =~ /(.*) \*= ?(.*)/ ||
434
- attributes['variable'][1..-1] =~ /(.*)\*= ?(.*)/)
435
- attributes['num'] = pipetext(escape_fix(attributes['variables'][$1]), attributes['box_mode'],
436
- attributes['ampersand_mode']).to_i * $2.to_i
437
- elsif(attributes['variable'][1..-1] =~ /(.*) \/= ?(.*)/ ||
438
- attributes['variable'][1..-1] =~ /(.*)\/= ?(.*)/)
439
- attributes['num'] = pipetext(escape_fix(attributes['variables'][$1]), attributes['box_mode'],
440
- attributes['ampersand_mode']).to_i / $2.to_i
441
- else
442
- attributes['num'] = pipetext(escape_fix(attributes['variables'][attributes['variable'][1..-1]]),
443
- attributes['box_mode'], attributes['ampersand_mode']).to_i
444
- end
445
- attributes['pipe'] = true
446
- attributes['found'] = false
447
- elsif(attributes['variables'][attributes['variable']])
448
- new_text << pipetext(escape_fix(attributes['variables'][attributes['variable']]),
449
- attributes['box_mode'], attributes['ampersand_mode'])
450
- else
451
- new_text << "|(" + attributes['variable'] + ")"
452
- end
453
- attributes['variable_capture'] = false
454
- attributes['variable'] = String.new
455
- end
456
-
457
- def emit_center(new_text, attributes)
458
- spaces = attributes['end'] - attributes['position'] - printable_length(attributes['center'])
459
- if(printable_length(attributes['center']) % 2)
460
- spaces += 1
461
- end
462
- if(spaces > 0)
463
- spaces /= 2
464
- spaces.times do
465
- new_text << " "
466
- end
467
- end
468
- new_text << attributes['center']
469
- attributes['center_capture'] = false
470
- attributes['center'] = String.new
471
- end
472
-
473
- def emit_emoji(new_text, attributes)
474
- emoji = String.new
475
- match_length = 0
476
- value_length = 0
477
- $substitute_emoji_names.each do |key, value|
478
- if(attributes['emoji'] == key) # Use the most precise match first
479
- emoji = value
480
- break
481
- elsif(attributes['emoji'].length <= key.length) # Otherwise use shortest match
482
- match = abbreviated_match(attributes['emoji'], key)
483
- if(match == 0 && key =~ /-/)
484
- match = abbreviated_match(attributes['emoji'], key.sub(/-/, ' '))
485
- end
486
- if(match > 0 && (match <= match_length || match_length == 0) &&
487
- (value.length <= value_length || value_length == 0))
488
- emoji = value
489
- match_length = match
490
- value_length = value.length
491
- end
492
- end
493
- end
494
- if(emoji == String.new) # No match, put copy input
495
- new_text << "|[" + attributes['emoji'] + "]"
496
- else
497
- emoji.split(/\|U/).each do |e|
498
- if(e != "")
499
- attributes['unicode'] = e.sub(/^\+?/, '')
500
- emit_unicode(new_text, attributes)
501
- end
502
- end
503
- attributes['emoji'] = String.new
504
- end
505
- attributes['emoji_capture'] = false
506
- end
507
-
508
- def process_pipe(character, new_text, attributes)
509
- if(attributes['pipe'] == true && attributes['num'] == 0) # ||
510
- attributes['pipe'] = false
511
- new_text << character
512
- else
513
- attributes['pipe'] = true
514
- end
515
- end
516
-
517
- def process_repeat_pattern(character, new_text, attributes)
518
- if(attributes['repeat_pattern'] == true) # ~ at end of |5~Repeat 5 times~
519
- attributes['num'].times do
520
- new_text << pipetext(attributes['pattern'], attributes['box_mode'], attributes['ampersand_mode'])
521
- end
522
- attributes['num'] = 0
523
- attributes['pipe'] = false
524
- attributes['escape'] = false
525
- attributes['repeat_pattern'] = false
526
- attributes['pattern'] = String.new
527
- else # ~ after number in |5~Repeat 5 times~
528
- attributes['repeat_pattern'] = true
529
- end
530
- end
531
-
532
- def escape_fix(text) # Done this way for old Ruby versions
533
- text = text.gsub(/\\a/, "\a").gsub(/\\b/, "\b").gsub(/\\e/, "\e").gsub(/\\f/, "\f")
534
- text = text.gsub(/\\n/, "\n").gsub(/\\r/, "\r").gsub(/\\t/, "\t").gsub(/\\v/, "\v")
535
- text = text.gsub(/\\~/, '~').gsub(/\\\(/, '(').gsub(/\\\)/, ')')
536
- end
537
-
538
- def process_escaped_character(character, new_text, attributes)
539
- if(attributes['num'] > 0)
540
- attributes['num'].times do
541
- new_text << escape_fix("\\#{character}")
542
- end
543
- else
544
- new_text << escape_fix("\\#{character}")
545
- end
546
- attributes['num'] = 0
547
- attributes['pipe'] = false
548
- attributes['escape'] = false
549
- attributes['pattern'] = String.new
550
- attributes['repeat_pattern'] = false
551
- end
552
-
553
- def capture_color(character, new_text, attributes)
554
- if(character =~ /[0-9,A-F,a-f]/)
555
- if(attributes['color_capture'] <= 2)
556
- attributes['r'] << character
557
- elsif(attributes['color_capture'] <= 4)
558
- attributes['g'] << character
559
- elsif(attributes['color_capture'] <= 6)
560
- attributes['b'] << character
561
- end
562
- if(attributes['color_capture'] == 6)
563
- emit_color(new_text, attributes)
564
- else
565
- attributes['color_capture'] += 1
566
- end
567
- end
568
- end
569
-
570
- def capture_character_pattern(character, attributes)
571
- if(character == '\\')
572
- attributes['escape'] = true
573
- else
574
- if(attributes['escape'] == true)
575
- attributes['pattern'] << "\\#{character}"
576
- attributes['escape'] = false
577
- else
578
- attributes['pattern'] << character
579
- end
580
- end
581
- end
582
-
583
- def capture_palette_color(character, new_text, attributes)
584
- if(character =~ /[0-9,A-F,a-f]/)
585
- if(attributes['palette_capture'] <= 2)
586
- attributes['p'] << character
587
- end
588
- if(attributes['palette_capture'] == 2)
589
- emit_palette_color(new_text, attributes)
590
- else
591
- attributes['palette_capture'] += 1
592
- end
593
- end
594
- end
595
-
596
- def capture_unicode(character, new_text, attributes)
597
- if(character =~ /[0-9,A-F,a-f]/)
598
- if(attributes['unicode_capture'] <= 6)
599
- attributes['unicode'] << character
600
- end
601
- if(attributes['unicode_capture'] == 6)
602
- emit_unicode(new_text, attributes)
603
- else
604
- attributes['unicode_capture'] += 1
605
- end
606
- end
607
- end
608
-
609
- def process_ampersand(character, new_text, attributes)
610
- if(attributes['ampersand'] == true) # &&
611
- attributes['ampersand'] = false
612
- new_text << character
613
- else
614
- attributes['ampersand'] = true
615
- end
616
- end
617
-
618
- def update_attributes(new_text, attributes)
619
- if(attributes['shell_prompt'] == true)
620
- new_text << "\\["
621
- end
622
- if(attributes['bold'] == true)
623
- new_text << "\e[1m"
624
- end
625
- if(attributes['faint'] == true)
626
- new_text << "\e[2m"
627
- end
628
- if(attributes['italic'] == true)
629
- new_text << "\e[3m"
630
- end
631
- if(attributes['underline'] == true)
632
- new_text << "\e[4m"
633
- end
634
- if(attributes['blink'] == true)
635
- new_text << "\e[5m"
636
- end
637
- if(attributes['inverse'] == true)
638
- new_text << "\e[7m"
639
- end
640
- if(attributes['crossed_out'] == true)
641
- new_text << "\e[9m"
642
- end
643
- if(attributes['shell_prompt'] == true)
644
- new_text << "\\]"
645
- end
646
- end
647
-
648
- def process_piped_character(character, new_text, attributes)
649
- attributes['found'] = true # Assume we will find the next character
650
- if(attributes['num'] == 0) # We are not in repeat character mode
651
- case character
652
- when '&' # |& - Toggle & on/off for Background Colors
653
- if(attributes['ampersand_mode'] == true)
654
- attributes['ampersand_mode'] = false
655
- else
656
- attributes['ampersand_mode'] = true
657
- end
658
- attributes['pipe'] = false
659
- when '!' # |! - Clear screen
660
- if(attributes['shell_prompt'] == true)
661
- new_text << "\\[\e[H\e[J\\]"
662
- else
663
- new_text << "\e[H\e[J"
664
- end
665
- when '+' # |+ - Bold
666
- if(attributes['shell_prompt'] == true)
667
- new_text << "\\["
668
- end
669
- if(attributes['bold'] == false)
670
- new_text << "\e[1m"
671
- attributes['bold'] = true
672
- else
673
- new_text << "\e[22m"
674
- attributes['bold'] = false
675
- end
676
- if(attributes['shell_prompt'] == true)
677
- new_text << "\\]"
678
- end
679
- when '.' # |. - Faint / Dim
680
- if(attributes['shell_prompt'] == true)
681
- new_text << "\\["
682
- end
683
- if(attributes['faint'] == false)
684
- new_text << "\e[2m"
685
- attributes['faint'] = true
686
- else
687
- new_text << "\e[22m"
688
- attributes['faint'] = false
689
- end
690
- if(attributes['shell_prompt'] == true)
691
- new_text << "\\]"
692
- end
693
- when '~' # |~ - Italic
694
- if(attributes['shell_prompt'] == true)
695
- new_text << "\\["
696
- end
697
- if(attributes['italic'] == false)
698
- new_text << "\e[3m"
699
- attributes['italic'] = true
700
- else
701
- new_text << "\e[23m"
702
- attributes['italic'] = false
703
- end
704
- if(attributes['shell_prompt'] == true)
705
- new_text << "\\]"
706
- end
707
- when '_' # |_ - Underline
708
- if(attributes['shell_prompt'] == true)
709
- new_text << "\\["
710
- end
711
- if(attributes['underline'] == false)
712
- new_text << "\e[4m"
713
- attributes['underline'] = true
714
- else
715
- new_text << "\e[24m"
716
- attributes['underline'] = false
717
- end
718
- if(attributes['shell_prompt'] == true)
719
- new_text << "\\]"
720
- end
721
- when '@' # |@ - Blink
722
- if(attributes['shell_prompt'] == true)
723
- new_text << "\\["
724
- end
725
- if(attributes['blink'] == false)
726
- new_text << "\e[5m"
727
- attributes['blink'] = true
728
- else
729
- new_text << "\e[25m"
730
- attributes['blink'] = false
731
- end
732
- if(attributes['shell_prompt'] == true)
733
- new_text << "\\]"
734
- end
735
- when '^' # |^ - Move up 1 line
736
- new_text << "\e[A"
737
- when 'v', 'V' # |v - Move down 1 line
738
- new_text << "\e[B"
739
- when '>' # |> - Move forward 1 character
740
- new_text << "\e[C"
741
- when '<' # |< - Move back 1 character
742
- new_text << "\e[D"
743
- when 'h' # |h - Hide cursor
744
- if(attributes['shell_prompt'] == true)
745
- new_text << "\\[\e[?25l\\]"
746
- else
747
- new_text << "\e[?25l"
748
- end
749
- when 'H' # |H - Unhide cursor
750
- if(attributes['shell_prompt'] == true)
751
- new_text << "\\[\e[?25h\\]"
752
- else
753
- new_text << "\e[?25h"
754
- end
755
- when 'i', 'I' # |i - Inverse
756
- if(attributes['shell_prompt'] == true)
757
- new_text << "\\["
758
- end
759
- if(attributes['inverse'] == false)
760
- new_text << "\e[7m"
761
- attributes['inverse'] = true
762
- else
763
- new_text << "\e[27m"
764
- attributes['inverse'] = false
765
- end
766
- if(attributes['shell_prompt'] == true)
767
- new_text << "\\]"
768
- end
769
- when 'x', 'X' # |x - Crossed Out
770
- if(attributes['shell_prompt'] == true)
771
- new_text << "\\["
772
- end
773
- if(attributes['crossed_out'] == false)
774
- new_text << "\e[9m"
775
- attributes['crossed_out'] = true
776
- else
777
- new_text << "\e[29m"
778
- attributes['crossed_out'] = false
779
- end
780
- if(attributes['shell_prompt'] == true)
781
- new_text << "\\]"
782
- end
783
- when '#' # |#RRGGBB
784
- attributes['color_capture'] = 1
785
- when 'P', 'p' # |P or |p - 2 character hex format color (256 colors)
786
- attributes['palette_capture'] = 1
787
- when 'U', 'u' # |U or |u - Unicode 6 character hex format
788
- attributes['unicode_capture'] = 1
789
- when 'K', 'k' # |K or |k - Foreground text black
790
- attributes['fg'] = "\e[30m"
791
- if(attributes['shell_prompt'] == true)
792
- new_text << "\\[\e[0;30m\\]"
793
- else
794
- new_text << "\e[0;30m"
795
- end
796
- attributes['bold'] = false
797
- update_attributes(new_text, attributes)
798
- new_text << attributes['bg'] == "\e[0m" ? "" : attributes['bg']
799
- when 'S', 's' # |S or |s - Foreground text smoke
800
- attributes['fg'] = "\e[1;30m"
801
- if(attributes['shell_prompt'] == true)
802
- new_text << "\\[\e[1;30m\\]"
803
- else
804
- new_text << "\e[1;30m"
805
- end
806
- attributes['bold'] = false
807
- update_attributes(new_text, attributes)
808
- attributes['bold'] = true
809
- new_text << attributes['bg'] == "\e[0m" ? "" : attributes['bg']
810
- when 'r' # |r - Foreground text red
811
- attributes['fg'] = "\e[31m"
812
- if(attributes['shell_prompt'] == true)
813
- new_text << "\\[\e[0;31m\\]"
814
- else
815
- new_text << "\e[0;31m"
816
- end
817
- attributes['bold'] = false
818
- update_attributes(new_text, attributes)
819
- new_text << attributes['bg'] == "\e[0m" ? "" : attributes['bg']
820
- when 'R' # |R - Foreground text bright red
821
- attributes['fg'] = "\e[1;31m"
822
- if(attributes['shell_prompt'] == true)
823
- new_text << "\\[\e[1;31m\\]"
824
- else
825
- new_text << "\e[1;31m"
826
- end
827
- attributes['bold'] = false
828
- update_attributes(new_text, attributes)
829
- attributes['bold'] = true
830
- new_text << attributes['bg'] == "\e[0m" ? "" : attributes['bg']
831
- when 'g' # |g - Foreground text green
832
- attributes['fg'] = "\e[32m"
833
- if(attributes['shell_prompt'] == true)
834
- new_text << "\\[\e[0;32m\\]"
835
- else
836
- new_text << "\e[0;32m"
837
- end
838
- attributes['bold'] = false
839
- update_attributes(new_text, attributes)
840
- new_text << attributes['bg'] == "\e[0m" ? "" : attributes['bg']
841
- when 'G' # |G - Foreground text bright green
842
- attributes['fg'] = "\e[1;32m"
843
- if(attributes['shell_prompt'] == true)
844
- new_text << "\\[\e[1;32m\\]"
845
- else
846
- new_text << "\e[1;32m"
847
- end
848
- attributes['bold'] = false
849
- update_attributes(new_text, attributes)
850
- attributes['bold'] = true
851
- new_text << attributes['bg'] == "\e[0m" ? "" : attributes['bg']
852
- when 'y' # |y - Foreground text yellow (brown)
853
- attributes['fg'] = "\e[33m"
854
- if(attributes['shell_prompt'] == true)
855
- new_text << "\\[\e[0;33m\\]"
856
- else
857
- new_text << "\e[0;33m"
858
- end
859
- attributes['bold'] = false
860
- update_attributes(new_text, attributes)
861
- new_text << attributes['bg'] == "\e[0m" ? "" : attributes['bg']
862
- when 'Y' # |Y - Foreground text bright yellow
863
- attributes['fg'] = "\e[1;33m"
864
- if(attributes['shell_prompt'] == true)
865
- new_text << "\\[\e[1;33m\\]"
866
- else
867
- new_text << "\e[1;33m"
868
- end
869
- attributes['bold'] = false
870
- update_attributes(new_text, attributes)
871
- attributes['bold'] = true
872
- new_text << attributes['bg'] == "\e[0m" ? "" : attributes['bg']
873
- when 'b' # |b - Foreground text blue
874
- attributes['fg'] = "\e[34m"
875
- if(attributes['shell_prompt'] == true)
876
- new_text << "\\[\e[0;34m\\]"
877
- else
878
- new_text << "\e[0;34m"
879
- end
880
- attributes['bold'] = false
881
- update_attributes(new_text, attributes)
882
- new_text << attributes['bg'] == "\e[0m" ? "" : attributes['bg']
883
- when 'B' # |B - Foreground text bright blue
884
- attributes['fg'] = "\e[1;34m"
885
- if(attributes['shell_prompt'] == true)
886
- new_text << "\\[\e[1;34m\\]"
887
- else
888
- new_text << "\e[1;34m"
889
- end
890
- attributes['bold'] = false
891
- update_attributes(new_text, attributes)
892
- attributes['bold'] = true
893
- new_text << attributes['bg'] == "\e[0m" ? "" : attributes['bg']
894
- when 'm' # |m - Foreground text magenta
895
- attributes['fg'] = "\e[35m"
896
- if(attributes['shell_prompt'] == true)
897
- new_text << "\\[\e[0;35m\\]"
898
- else
899
- new_text << "\e[0;35m"
900
- end
901
- attributes['bold'] = false
902
- update_attributes(new_text, attributes)
903
- new_text << attributes['bg'] == "\e[0m" ? "" : attributes['bg']
904
- when 'M' # |M - Foreground text bright magenta
905
- attributes['fg'] = "\e[1;35m"
906
- if(attributes['shell_prompt'] == true)
907
- new_text << "\\[\e[1;35m\\]"
908
- else
909
- new_text << "\e[1;35m"
910
- end
911
- attributes['bold'] = false
912
- update_attributes(new_text, attributes)
913
- attributes['bold'] = true
914
- new_text << attributes['bg'] == "\e[0m" ? "" : attributes['bg']
915
- when 'c' # |c - Foreground text cyan
916
- attributes['fg'] = "\e[36m"
917
- if(attributes['shell_prompt'] == true)
918
- new_text << "\\[\e[0;36m\\]"
919
- else
920
- new_text << "\e[0;36m"
921
- end
922
- attributes['bold'] = false
923
- update_attributes(new_text, attributes)
924
- new_text << attributes['bg'] == "\e[0m" ? "" : attributes['bg']
925
- when 'C' # |C - Foreground text bright cyan
926
- attributes['fg'] = "\e[1;36m"
927
- if(attributes['shell_prompt'] == true)
928
- new_text << "\\[\e[1;36m\\]"
929
- else
930
- new_text << "\e[1;36m"
931
- end
932
- attributes['bold'] = false
933
- update_attributes(new_text, attributes)
934
- attributes['bold'] = true
935
- new_text << attributes['bg'] == "\e[0m" ? "" : attributes['bg']
936
- when 'W', 'w' # |W or |w - Foreground text white
937
- attributes['fg'] = "\e[1;37m"
938
- if(attributes['shell_prompt'] == true)
939
- new_text << "\\[\e[1;37m\\]"
940
- else
941
- new_text << "\e[1;37m"
942
- end
943
- attributes['bold'] = false
944
- update_attributes(new_text, attributes)
945
- attributes['bold'] = true
946
- new_text << attributes['bg'] == "\e[0m" ? "" : attributes['bg']
947
- when 'N', 'n' # |N or |n - Foreground text normal
948
- attributes['fg'] = ""
949
- if(attributes['shell_prompt'] == true)
950
- new_text << "\\[\e[0;37m\\]"
951
- else
952
- new_text << "\e[0;37m"
953
- end
954
- attributes['bold'] = false
955
- update_attributes(new_text, attributes)
956
- if(attributes['shell_prompt'] == true)
957
- new_text << attributes['bg'] == "\e[0m" ? "" : "\\[" + attributes['bg'] + "\\]"
958
- else
959
- new_text << attributes['bg'] == "\e[0m" ? "" : attributes['bg']
960
- end
961
- when 'O' # |O - Box mode off
962
- attributes['box'] = -1
963
- when 'o' # |o - Box mode 0
964
- attributes['box'] = 0
965
- when '-' # |- - Box mode 1
966
- if(attributes['box_mode'] == true)
967
- attributes['box'] = 1
968
- else # We didn't find the next character
969
- attributes['found'] = false
970
- end
971
- when '=' # |= - Box mode 2
972
- if(attributes['box_mode'] == true)
973
- attributes['box'] = 2
974
- else # We didn't find the next character
975
- attributes['found'] = false
976
- end
977
- when '{' # center
978
- attributes['center_capture'] = true
979
- when ';' # extend to end column with spaces
980
- spaces = attributes['end'] - attributes['position']
981
- spaces.times do
982
- new_text << " "
983
- end
984
- when ']' # |]0-9* - end column number
985
- attributes['end_capture'] = true
986
- when '[' # |[emoji]
987
- attributes['emoji_capture'] = true
988
- when '(' # |(variable) or |(variable=Some value)
989
- attributes['variable_capture'] = true
990
- when '\\' # |\ - Escape mode
991
- attributes['escape'] = true
992
- when '$' # |$ - Toggle shell prompt mode
993
- if(attributes['shell_prompt'] == true)
994
- attributes['shell_prompt'] = false
995
- else
996
- attributes['shell_prompt'] = true
997
- end
998
- else # We didn't find the next character
999
- attributes['found'] = false
1000
- end
1001
- elsif(character == '\\')
1002
- attributes['escape'] = true
1003
- else # We didn't find the next character
1004
- attributes['found'] = false
1005
- end
1006
- if(attributes['found'] == false)
1007
- if(character == '0') # |10+
1008
- if(attributes['num'] > 0)
1009
- attributes['num'] *= 10
1010
- end
1011
- elsif(character >= '1' && character <= '9') # |1+ through |9+
1012
- if(attributes['num'] > 0)
1013
- attributes['num'] *= 10
1014
- end
1015
- attributes['num'] += character.to_i
1016
- else
1017
- if(attributes['num'] <= 0) # No replacement found
1018
- new_text << '|' + character
1019
- else # Repeat number replacement found
1020
- if(attributes['box'] == 1)
1021
- attributes['num'].times do
1022
- new_text << process_box_one_replace(character)
1023
- end
1024
- attributes['num'] = 0
1025
- elsif(attributes['box'] == 2)
1026
- attributes['num'].times do
1027
- new_text << process_box_two_replace(character)
1028
- end
1029
- attributes['num'] = 0
1030
- else
1031
- attributes['num'].times do
1032
- new_text << character
1033
- end
1034
- attributes['num'] = 0
1035
- end
1036
- end
1037
- attributes['pipe'] = false
1038
- end
1039
- elsif(attributes['escape'] == false)
1040
- attributes['pipe'] = false
1041
- end
1042
- end
1043
-
1044
- def process_ampersanded_character(character, new_text, attributes)
1045
- case character
1046
- when '#' # &#RRGGBB
1047
- attributes['color_capture'] = 1
1048
- return
1049
- when 'P', 'p' # |P or |p - 2 character hex format color (256 colors)
1050
- attributes['palette_capture'] = 1
1051
- return
1052
- when 'W', 'w' # &W or &w - Background white
1053
- if(attributes['shell_prompt'] == true)
1054
- new_text << "\\[\e[0;47m\\]"
1055
- else
1056
- new_text << "\e[0;47m"
1057
- end
1058
- attributes['bg'] = "\e[47m"
1059
- update_attributes(new_text, attributes)
1060
- new_text << attributes['fg'] == "\e[0m" ? "" : attributes['fg']
1061
- when 'C', 'c' # &C or &c - Background cyan
1062
- if(attributes['shell_prompt'] == true)
1063
- new_text << "\\[\e[0;46m\\]"
1064
- else
1065
- new_text << "\e[0;46m"
1066
- end
1067
- attributes['bg'] = "\e[46m"
1068
- update_attributes(new_text, attributes)
1069
- new_text << attributes['fg'] == "\e[0m" ? "" : attributes['fg']
1070
- when 'M', 'm' # &M or &m - Background magenta
1071
- if(attributes['shell_prompt'] == true)
1072
- new_text << "\\[\e[0;45m\\]"
1073
- else
1074
- new_text << "\e[0;45m"
1075
- end
1076
- attributes['bg'] = "\e[45m"
1077
- update_attributes(new_text, attributes)
1078
- new_text << attributes['fg'] == "\e[0m" ? "" : attributes['fg']
1079
- when 'B', 'b' # &B or &b - Background blue
1080
- if(attributes['shell_prompt'] == true)
1081
- new_text << "\\[\e[0;44m\\]"
1082
- else
1083
- new_text << "\e[0;44m"
1084
- end
1085
- attributes['bg'] = "\e[44m"
1086
- update_attributes(new_text, attributes)
1087
- new_text << attributes['fg'] == "\e[0m" ? "" : attributes['fg']
1088
- when 'Y', 'y' # &Y or &y - Background yellow (brown)
1089
- if(attributes['shell_prompt'] == true)
1090
- new_text << "\\[\e[0;43m\\]"
1091
- else
1092
- new_text << "\e[0;43m"
1093
- end
1094
- attributes['bg'] = "\e[43m"
1095
- update_attributes(new_text, attributes)
1096
- new_text << attributes['fg'] == "\e[0m" ? "" : attributes['fg']
1097
- when 'G', 'g' # &G or &g - Background green
1098
- if(attributes['shell_prompt'] == true)
1099
- new_text << "\\[\e[0;42m\\]"
1100
- else
1101
- new_text << "\e[0;42m"
1102
- end
1103
- attributes['bg'] = "\e[42m"
1104
- update_attributes(new_text, attributes)
1105
- new_text << attributes['fg'] == "\e[0m" ? "" : attributes['fg']
1106
- when 'R', 'r' # &R or &r - Background red
1107
- if(attributes['shell_prompt'] == true)
1108
- new_text << "\\[\e[0;41m\\]"
1109
- else
1110
- new_text << "\e[0;41m"
1111
- end
1112
- attributes['bg'] ="\e[41m"
1113
- update_attributes(new_text, attributes)
1114
- new_text << attributes['fg'] == "\e[0m" ? "" : attributes['fg']
1115
- when 'S', 's', 'K', 'k' # &S, &s, &K, &k - Background black/smoke
1116
- if(attributes['shell_prompt'] == true)
1117
- new_text << "\\[\e[0;40m\\]"
1118
- else
1119
- new_text << "\e[0;40m"
1120
- end
1121
- attributes['bg'] = "\e[40m"
1122
- update_attributes(new_text, attributes)
1123
- new_text << attributes['fg'] == "\e[0m" ? "" : attributes['fg']
1124
- when 'N', 'n' # &N or &n - Background normal
1125
- if(attributes['shell_prompt'] == true)
1126
- new_text << "\\[\e[0m\\]"
1127
- else
1128
- new_text << "\e[0m"
1129
- end
1130
- attributes['bg'] = ""
1131
- update_attributes(new_text, attributes)
1132
- if(attributes['shell_prompt'] == true)
1133
- new_text << attributes['fg'] == "\e[0m" ? "" : "\\[" + attributes['fg'] + "\\]"
1134
- else
1135
- new_text << attributes['fg'] == "\e[0m" ? "" : attributes['fg']
1136
- end
1137
- else
1138
- new_text << '&' + character
1139
- end
1140
- attributes['ampersand'] = false
1141
- end
1142
-
1143
- def process_box_zero_replace(character)
1144
- case character
1145
- when '['
1146
- '+'
1147
- when ']'
1148
- '+'
1149
- when '-'
1150
- '-'
1151
- when '!'
1152
- '|'
1153
- when '>'
1154
- '+'
1155
- when '<'
1156
- '+'
1157
- when '+'
1158
- '+'
1159
- when '{'
1160
- '+'
1161
- when '}'
1162
- '+'
1163
- when 'v'
1164
- '+'
1165
- when '^'
1166
- '+'
1167
- else
1168
- character
1169
- end
1170
- end
1171
-
1172
- def process_box_one_replace(character)
1173
- case character
1174
- when '['
1175
- '┌'
1176
- when ']'
1177
- '┐'
1178
- when '-'
1179
- '─'
1180
- when '!'
1181
- '│'
1182
- when '>'
1183
- '├'
1184
- when '<'
1185
- '┤'
1186
- when '+'
1187
- '┼'
1188
- when '{'
1189
- '└'
1190
- when '}'
1191
- '┘'
1192
- when 'v'
1193
- '┬'
1194
- when '^'
1195
- '┴'
1196
- else
1197
- character
1198
- end
1199
- end
1200
-
1201
- def process_box_two_replace(character)
1202
- case character
1203
- when '['
1204
- '╔'
1205
- when ']'
1206
- '╗'
1207
- when '-'
1208
- '═'
1209
- when '!'
1210
- '║'
1211
- when '>'
1212
- '╠'
1213
- when '<'
1214
- '╣'
1215
- when '+'
1216
- '╬'
1217
- when '{'
1218
- '╚'
1219
- when '}'
1220
- '╝'
1221
- when 'v'
1222
- '╦'
1223
- when '^'
1224
- '╩'
1225
- else
1226
- character
1
+ # Allow older versions of Ruby to respond to the require_relative method
2
+ if(!Kernel.respond_to?(:require_relative))
3
+ module Kernel
4
+ def require_relative(path)
5
+ require File.join(File.dirname(caller[0]), path.to_str)
1227
6
  end
1228
7
  end
1229
8
  end
9
+
10
+ require_relative File.join("pipetext", "version.rb")
11
+ require_relative File.join("pipetext", "pipetext.rb")
12
+ require_relative File.join("pipetext", "substitute_emoji_names.rb")