pipetext 0.1.4 → 0.1.6
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/bin/pipetext +16 -7
- data/lib/pipetext/pipetext.rb +901 -0
- data/lib/{substitute_emoji_names.rb → pipetext/substitute_emoji_names.rb} +1 -0
- data/lib/pipetext/version.rb +9 -0
- data/lib/pipetext.rb +10 -831
- metadata +15 -11
data/lib/pipetext.rb
CHANGED
|
@@ -1,835 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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
|
-
'pattern_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
|
-
'emoji_capture' => false, # Used to capture emoji description or bell/move to position
|
|
29
|
-
'emoji' => String.new, # Used to capture emoji description or bell/move to position
|
|
30
|
-
'unicode_capture' => 0, # Used to capture Unicode using 6 character UTF-16 hex format
|
|
31
|
-
'unicode' => String.new,
|
|
32
|
-
'palette_capture' => 0, # Used to capture 8-bit color using 2 character hex format
|
|
33
|
-
'p' => String.new, # |p00 to |pFF
|
|
34
|
-
'color_capture' => 0, # Used to capture RGB color using #RRGGBB format
|
|
35
|
-
'r' => String.new,
|
|
36
|
-
'g' => String.new,
|
|
37
|
-
'b' => String.new,
|
|
38
|
-
'fg' => String.new, # Needed to restore after background change
|
|
39
|
-
'bg' => String.new # Needed to restore after foreground change
|
|
40
|
-
}
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def pipe(text, attributes)
|
|
44
|
-
new_text = String.new
|
|
45
|
-
text.chars.each do |character|
|
|
46
|
-
process_character(character, new_text, attributes)
|
|
47
|
-
end
|
|
48
|
-
# Clean up in case we've captured something we didn't process yet
|
|
49
|
-
if(attributes['color_capture'] > 0)
|
|
50
|
-
emit_color(new_text, attributes)
|
|
51
|
-
elsif(attributes['palette_capture'] > 0)
|
|
52
|
-
emit_palette_color(new_text, attributes)
|
|
53
|
-
elsif(attributes['unicode_capture'] > 0)
|
|
54
|
-
emit_unicode(new_text, attributes)
|
|
55
|
-
elsif(attributes['emoji_capture'] == true)
|
|
56
|
-
new_text << "|[" + attributes['emoji']
|
|
57
|
-
end
|
|
58
|
-
return new_text
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
def pipetext(text, box_mode=true, ampersand_mode=false)
|
|
62
|
-
pipe(text, pipetext_init(box_mode, ampersand_mode))
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
def write(text, box_mode=true, ampersand_mode=false)
|
|
66
|
-
puts(pipetext(text, box_mode, ampersand_mode))
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
# Defaults to using & for background colors
|
|
70
|
-
def paint(text, box_mode=true, ampersand_mode=true)
|
|
71
|
-
puts(pipetext(text, box_mode, ampersand_mode))
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def ignored_character(character, ignored_characters)
|
|
75
|
-
ignored_characters.chars.each do |ignored|
|
|
76
|
-
if(character == ignored)
|
|
77
|
-
return true
|
|
78
|
-
end
|
|
79
|
-
end
|
|
80
|
-
return false
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
# Match abbreviated text descriptions for emojis by default ignore case and punctuation
|
|
84
|
-
# Allows for 'space anchoring' so you can use |[smi f w he e] as an abbreviation for
|
|
85
|
-
# |[smiling face with heart-eyes]
|
|
86
|
-
def abbreviated_match(input, match, case_match=false, ignored_characters=",.':-")
|
|
87
|
-
if(!input || !match)
|
|
88
|
-
return 0
|
|
89
|
-
end
|
|
90
|
-
count = 0
|
|
91
|
-
offset = 0
|
|
92
|
-
input.chars.each_with_index do |character, index|
|
|
93
|
-
while(ignored_character(match[index + offset], ignored_characters))
|
|
94
|
-
offset += 1
|
|
95
|
-
end
|
|
96
|
-
if(character == match[index + offset])
|
|
97
|
-
count += 1
|
|
98
|
-
elsif(case_match == false && character.downcase == match[index + offset].downcase)
|
|
99
|
-
count += 1
|
|
100
|
-
elsif(character == ' ' && match[index + offset..-1] =~ / /)
|
|
101
|
-
count += 1
|
|
102
|
-
while(match[index + offset] != character)
|
|
103
|
-
offset += 1
|
|
104
|
-
end
|
|
105
|
-
else
|
|
106
|
-
count = 0
|
|
107
|
-
offset = 0
|
|
108
|
-
break
|
|
109
|
-
end
|
|
110
|
-
end
|
|
111
|
-
return count + offset
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
# This is not entirely accurate because of emojis
|
|
115
|
-
def printable_length(string)
|
|
116
|
-
length = 0
|
|
117
|
-
escape = false
|
|
118
|
-
string.chars.each do |character|
|
|
119
|
-
if(character.ord == 27)
|
|
120
|
-
escape = true
|
|
121
|
-
elsif(character.ord >= 32)
|
|
122
|
-
if(escape == true && character.ord == 109)
|
|
123
|
-
escape = false
|
|
124
|
-
elsif(escape == false)
|
|
125
|
-
length += 1
|
|
126
|
-
end
|
|
127
|
-
end
|
|
128
|
-
end
|
|
129
|
-
return length
|
|
130
|
-
end
|
|
131
|
-
|
|
132
|
-
private
|
|
133
|
-
|
|
134
|
-
def process_character(character, new_text, attributes)
|
|
135
|
-
if(attributes['repeat_pattern'] == false)
|
|
136
|
-
# Will still need to process character, first process incorrect formats
|
|
137
|
-
if(attributes['color_capture'] > 0 && character !~ /[0-9,A-F,a-f]/)
|
|
138
|
-
emit_color(new_text, attributes)
|
|
139
|
-
elsif(attributes['palette_capture'] > 0 && character !~ /[0-9,A-F,a-f]/)
|
|
140
|
-
emit_palette_color(new_text, attributes)
|
|
141
|
-
elsif(attributes['unicode_capture'] > 0 && character !~ /[0-9,A-F,a-f,+]/ ||
|
|
142
|
-
(attributes['unicode_capture'] != 1 && character == '+'))
|
|
143
|
-
emit_unicode(new_text, attributes)
|
|
144
|
-
end
|
|
145
|
-
end
|
|
146
|
-
if(attributes['end_capture'] == true && character !~ /[0-9]/)
|
|
147
|
-
attributes['end'] = attributes['num']
|
|
148
|
-
attributes['num'] = 0
|
|
149
|
-
attributes['end_capture'] = false
|
|
150
|
-
end
|
|
151
|
-
if(attributes['end_capture'] == true && character =~ /[0-9]/)
|
|
152
|
-
if(character == '0') # |10+
|
|
153
|
-
if(attributes['num'] > 0)
|
|
154
|
-
attributes['num'] *= 10
|
|
155
|
-
end
|
|
156
|
-
elsif(character >= '1' && character <= '9') # |1+ through |9+
|
|
157
|
-
if(attributes['num'] > 0)
|
|
158
|
-
attributes['num'] *= 10
|
|
159
|
-
end
|
|
160
|
-
attributes['num'] += character.to_i
|
|
161
|
-
end
|
|
162
|
-
elsif(character == '|' && attributes['repeat_pattern'] == false)
|
|
163
|
-
process_pipe(character, new_text, attributes)
|
|
164
|
-
elsif(character == '~' && attributes['pipe'] == true &&
|
|
165
|
-
attributes['num'] > 0 && attributes['pattern_escape'] == false)
|
|
166
|
-
process_repeat_pattern(character, new_text, attributes)
|
|
167
|
-
elsif(attributes['repeat_pattern'] == true)
|
|
168
|
-
capture_character_pattern(character, attributes)
|
|
169
|
-
elsif(attributes['color_capture'] > 0 && character =~ /[0-9,A-F,a-f]/)
|
|
170
|
-
capture_color(character, new_text, attributes)
|
|
171
|
-
elsif(attributes['palette_capture'] > 0 && character =~ /[0-9,A-F,a-f]/)
|
|
172
|
-
capture_palette_color(character, new_text, attributes)
|
|
173
|
-
elsif(attributes['emoji_capture'] == true)
|
|
174
|
-
if(character == ']')
|
|
175
|
-
if(attributes['emoji'] =~ /bell/)
|
|
176
|
-
new_text << "\a"
|
|
177
|
-
attributes['emoji'] = String.new
|
|
178
|
-
attributes['emoji_capture'] = false
|
|
179
|
-
elsif(attributes['emoji'] =~ /^([0-9]*)[,;]([0-9]*)$/)
|
|
180
|
-
new_text << "\e[#{$1};#{$2}H"
|
|
181
|
-
attributes['emoji'] = String.new
|
|
182
|
-
attributes['emoji_capture'] = false
|
|
183
|
-
elsif(attributes['emoji'] =~ /^([\.0-9]*)[zZ]$/)
|
|
184
|
-
attributes['emoji'] = String.new
|
|
185
|
-
attributes['emoji_capture'] = false
|
|
186
|
-
sleep($1.to_f)
|
|
187
|
-
else
|
|
188
|
-
emit_emoji(new_text, attributes)
|
|
189
|
-
end
|
|
190
|
-
else
|
|
191
|
-
attributes['emoji'] << character
|
|
192
|
-
end
|
|
193
|
-
elsif(attributes['unicode_capture'] == 1 && character == '+') # Skip
|
|
194
|
-
return
|
|
195
|
-
elsif(attributes['unicode_capture'] > 0 && character =~ /[0-9,A-F,a-f]/)
|
|
196
|
-
capture_unicode(character, new_text, attributes)
|
|
197
|
-
elsif(attributes['pipe'] == true &&
|
|
198
|
-
attributes['repeat_pattern'] == false &&
|
|
199
|
-
attributes['pattern_escape'] == true)
|
|
200
|
-
process_escaped_character(character, new_text, attributes)
|
|
201
|
-
elsif(character == '&' && attributes['ampersand_mode'] == true &&
|
|
202
|
-
attributes['pipe'] == false)
|
|
203
|
-
process_ampersand(character, new_text, attributes)
|
|
204
|
-
elsif(attributes['pipe'] == true)
|
|
205
|
-
process_piped_character(character, new_text, attributes)
|
|
206
|
-
elsif(attributes['ampersand'] == true)
|
|
207
|
-
process_ampersanded_character(character, new_text, attributes)
|
|
208
|
-
elsif(attributes['box'] == 0)
|
|
209
|
-
new_text << process_box_zero_replace(character)
|
|
210
|
-
elsif(attributes['box'] == 1)
|
|
211
|
-
new_text << process_box_one_replace(character)
|
|
212
|
-
elsif(attributes['box'] == 2)
|
|
213
|
-
new_text << process_box_two_replace(character)
|
|
214
|
-
else
|
|
215
|
-
new_text << character
|
|
216
|
-
end
|
|
217
|
-
end
|
|
218
|
-
|
|
219
|
-
def emit_color(new_text, attributes)
|
|
220
|
-
r = attributes['r'].to_i(16).to_s
|
|
221
|
-
g = attributes['g'].to_i(16).to_s
|
|
222
|
-
b = attributes['b'].to_i(16).to_s
|
|
223
|
-
if(attributes['ampersand'] == true) # Background Color
|
|
224
|
-
new_text << "\e[48;2;#{r};#{g};#{b}m"
|
|
225
|
-
attributes['ampersand'] = false
|
|
226
|
-
else # Foreground Color
|
|
227
|
-
new_text << "\e[38;2;#{r};#{g};#{b}m"
|
|
228
|
-
end
|
|
229
|
-
attributes['color_capture'] = 0
|
|
230
|
-
attributes['r'] = String.new
|
|
231
|
-
attributes['g'] = String.new
|
|
232
|
-
attributes['b'] = String.new
|
|
233
|
-
end
|
|
234
|
-
|
|
235
|
-
def emit_palette_color(new_text, attributes)
|
|
236
|
-
p = attributes['p'].to_i(16).to_s
|
|
237
|
-
if(attributes['ampersand'] == true) # Background Color
|
|
238
|
-
new_text << "\e[48;5;#{p}m"
|
|
239
|
-
attributes['ampersand'] = false
|
|
240
|
-
else # Foreground Color
|
|
241
|
-
new_text << "\e[38;5;#{p}m"
|
|
242
|
-
end
|
|
243
|
-
attributes['palette_capture'] = 0
|
|
244
|
-
attributes['p'] = String.new
|
|
245
|
-
end
|
|
246
|
-
|
|
247
|
-
def emit_unicode(new_text, attributes)
|
|
248
|
-
new_text << [attributes['unicode'].to_i(16)].pack('U*')
|
|
249
|
-
attributes['unicode_capture'] = 0
|
|
250
|
-
attributes['unicode'] = String.new
|
|
251
|
-
end
|
|
252
|
-
|
|
253
|
-
def emit_emoji(new_text, attributes)
|
|
254
|
-
emoji = String.new
|
|
255
|
-
match_length = 0
|
|
256
|
-
value_length = 0
|
|
257
|
-
$substitute_emoji_names.each do |key, value|
|
|
258
|
-
if(attributes['emoji'] == key) # Use the most precise match first
|
|
259
|
-
emoji = value
|
|
260
|
-
break
|
|
261
|
-
elsif(attributes['emoji'].length <= key.length) # Otherwise use shortest match
|
|
262
|
-
match = abbreviated_match(attributes['emoji'], key)
|
|
263
|
-
if(match == 0 && key =~ /-/)
|
|
264
|
-
match = abbreviated_match(attributes['emoji'], key.sub(/-/, ' '))
|
|
265
|
-
end
|
|
266
|
-
if(match > 0 && (match <= match_length || match_length == 0) &&
|
|
267
|
-
(value.length <= value_length || value_length == 0))
|
|
268
|
-
emoji = value
|
|
269
|
-
match_length = match
|
|
270
|
-
value_length = value.length
|
|
271
|
-
end
|
|
272
|
-
end
|
|
273
|
-
end
|
|
274
|
-
if(emoji == String.new) # No match, put copy input
|
|
275
|
-
new_text << "|[" + attributes['emoji'] + "]"
|
|
276
|
-
else
|
|
277
|
-
emoji.split(/\|U/).each do |e|
|
|
278
|
-
if(e != "")
|
|
279
|
-
attributes['unicode'] = e.sub(/^\+?/, '')
|
|
280
|
-
emit_unicode(new_text, attributes)
|
|
281
|
-
end
|
|
282
|
-
end
|
|
283
|
-
attributes['emoji'] = String.new
|
|
284
|
-
end
|
|
285
|
-
attributes['emoji_capture'] = false
|
|
286
|
-
end
|
|
287
|
-
|
|
288
|
-
def process_pipe(character, new_text, attributes)
|
|
289
|
-
if(attributes['pipe'] == true && attributes['num'] == 0) # ||
|
|
290
|
-
attributes['pipe'] = false
|
|
291
|
-
new_text << character
|
|
292
|
-
else
|
|
293
|
-
attributes['pipe'] = true
|
|
294
|
-
end
|
|
295
|
-
end
|
|
296
|
-
|
|
297
|
-
def process_repeat_pattern(character, new_text, attributes)
|
|
298
|
-
if(attributes['repeat_pattern'] == true) # ~ at end of |5~Repeat 5 times~
|
|
299
|
-
attributes['num'].times do
|
|
300
|
-
new_text << pipetext(attributes['pattern'], attributes['box_mode'], attributes['ampersand_mode'])
|
|
301
|
-
end
|
|
302
|
-
attributes['num'] = 0
|
|
303
|
-
attributes['pipe'] = false
|
|
304
|
-
attributes['pattern_escape'] = false
|
|
305
|
-
attributes['repeat_pattern'] = false
|
|
306
|
-
attributes['pattern'] = String.new
|
|
307
|
-
else # ~ after number in |5~Repeat 5 times~
|
|
308
|
-
attributes['repeat_pattern'] = true
|
|
309
|
-
end
|
|
310
|
-
end
|
|
311
|
-
|
|
312
|
-
def escape_fix(text)
|
|
313
|
-
text.gsub(/\\a/, "\a").gsub(/\\b/, "\b").gsub(/\\e/, "\e")
|
|
314
|
-
.gsub(/\\f/, "\f").gsub(/\\n/, "\n").gsub(/\\r/, "\r")
|
|
315
|
-
.gsub(/\\t/, "\t").gsub(/\\v/, "\v").gsub(/\\~/, '~')
|
|
316
|
-
end
|
|
317
|
-
|
|
318
|
-
def process_escaped_character(character, new_text, attributes)
|
|
319
|
-
if(attributes['num'] > 0)
|
|
320
|
-
attributes['num'].times do
|
|
321
|
-
new_text << escape_fix("\\#{character}")
|
|
322
|
-
end
|
|
323
|
-
else
|
|
324
|
-
new_text << escape_fix("\\#{character}")
|
|
325
|
-
end
|
|
326
|
-
attributes['num'] = 0
|
|
327
|
-
attributes['pipe'] = false
|
|
328
|
-
attributes['pattern_escape'] = false
|
|
329
|
-
attributes['pattern'] = String.new
|
|
330
|
-
attributes['repeat_pattern'] = false
|
|
331
|
-
end
|
|
332
|
-
|
|
333
|
-
def capture_color(character, new_text, attributes)
|
|
334
|
-
if(character =~ /[0-9,A-F,a-f]/)
|
|
335
|
-
if(attributes['color_capture'] <= 2)
|
|
336
|
-
attributes['r'] << character
|
|
337
|
-
elsif(attributes['color_capture'] <= 4)
|
|
338
|
-
attributes['g'] << character
|
|
339
|
-
elsif(attributes['color_capture'] <= 6)
|
|
340
|
-
attributes['b'] << character
|
|
341
|
-
end
|
|
342
|
-
if(attributes['color_capture'] == 6)
|
|
343
|
-
emit_color(new_text, attributes)
|
|
344
|
-
else
|
|
345
|
-
attributes['color_capture'] += 1
|
|
346
|
-
end
|
|
347
|
-
end
|
|
348
|
-
end
|
|
349
|
-
|
|
350
|
-
def capture_character_pattern(character, attributes)
|
|
351
|
-
if(character == '\\')
|
|
352
|
-
attributes['pattern_escape'] = true
|
|
353
|
-
else
|
|
354
|
-
if(attributes['pattern_escape'] == true)
|
|
355
|
-
attributes['pattern'] << "\\#{character}"
|
|
356
|
-
attributes['pattern_escape'] = false
|
|
357
|
-
else
|
|
358
|
-
attributes['pattern'] << character
|
|
359
|
-
end
|
|
360
|
-
end
|
|
361
|
-
end
|
|
362
|
-
|
|
363
|
-
def capture_palette_color(character, new_text, attributes)
|
|
364
|
-
if(character =~ /[0-9,A-F,a-f]/)
|
|
365
|
-
if(attributes['palette_capture'] <= 2)
|
|
366
|
-
attributes['p'] << character
|
|
367
|
-
end
|
|
368
|
-
if(attributes['palette_capture'] == 2)
|
|
369
|
-
emit_palette_color(new_text, attributes)
|
|
370
|
-
else
|
|
371
|
-
attributes['palette_capture'] += 1
|
|
372
|
-
end
|
|
373
|
-
end
|
|
374
|
-
end
|
|
375
|
-
|
|
376
|
-
def capture_unicode(character, new_text, attributes)
|
|
377
|
-
if(character =~ /[0-9,A-F,a-f]/)
|
|
378
|
-
if(attributes['unicode_capture'] <= 6)
|
|
379
|
-
attributes['unicode'] << character
|
|
380
|
-
end
|
|
381
|
-
if(attributes['unicode_capture'] == 6)
|
|
382
|
-
emit_unicode(new_text, attributes)
|
|
383
|
-
else
|
|
384
|
-
attributes['unicode_capture'] += 1
|
|
385
|
-
end
|
|
386
|
-
end
|
|
387
|
-
end
|
|
388
|
-
|
|
389
|
-
def process_ampersand(character, new_text, attributes)
|
|
390
|
-
if(attributes['ampersand'] == true) # &&
|
|
391
|
-
attributes['ampersand'] = false
|
|
392
|
-
new_text << character
|
|
393
|
-
else
|
|
394
|
-
attributes['ampersand'] = true
|
|
395
|
-
end
|
|
396
|
-
end
|
|
397
|
-
|
|
398
|
-
def update_attributes(new_text, attributes)
|
|
399
|
-
if(attributes['bold'] == true)
|
|
400
|
-
new_text << "\e[1m"
|
|
401
|
-
end
|
|
402
|
-
if(attributes['faint'] == true)
|
|
403
|
-
new_text << "\e[2m"
|
|
404
|
-
end
|
|
405
|
-
if(attributes['italic'] == true)
|
|
406
|
-
new_text << "\e[3m"
|
|
407
|
-
end
|
|
408
|
-
if(attributes['underline'] == true)
|
|
409
|
-
new_text << "\e[4m"
|
|
410
|
-
end
|
|
411
|
-
if(attributes['blink'] == true)
|
|
412
|
-
new_text << "\e[5m"
|
|
413
|
-
end
|
|
414
|
-
if(attributes['inverse'] == true)
|
|
415
|
-
new_text << "\e[7m"
|
|
416
|
-
end
|
|
417
|
-
if(attributes['crossed_out'] == true)
|
|
418
|
-
new_text << "\e[9m"
|
|
419
|
-
end
|
|
420
|
-
end
|
|
421
|
-
|
|
422
|
-
def process_piped_character(character, new_text, attributes)
|
|
423
|
-
attributes['found'] = true # Assume we will find the next character
|
|
424
|
-
if(attributes['num'] == 0) # We are not in repeat character mode
|
|
425
|
-
case character
|
|
426
|
-
when '&' # |& - Toggle & on/off for Background Colors
|
|
427
|
-
if(attributes['ampersand_mode'] == true)
|
|
428
|
-
attributes['ampersand_mode'] = false
|
|
429
|
-
else
|
|
430
|
-
attributes['ampersand_mode'] = true
|
|
431
|
-
end
|
|
432
|
-
attributes['pipe'] = false
|
|
433
|
-
when '!' # |! - Clear screen
|
|
434
|
-
new_text << "\e[H\e[J"
|
|
435
|
-
when '+' # |+ - Bold
|
|
436
|
-
if(attributes['bold'] == false)
|
|
437
|
-
new_text << "\e[1m"
|
|
438
|
-
attributes['bold'] = true
|
|
439
|
-
else
|
|
440
|
-
new_text << "\e[22m"
|
|
441
|
-
attributes['bold'] = false
|
|
442
|
-
end
|
|
443
|
-
when '.' # |. - Faint / Dim
|
|
444
|
-
if(attributes['faint'] == false)
|
|
445
|
-
new_text << "\e[2m"
|
|
446
|
-
attributes['faint'] = true
|
|
447
|
-
else
|
|
448
|
-
new_text << "\e[22m"
|
|
449
|
-
attributes['faint'] = false
|
|
450
|
-
end
|
|
451
|
-
when '~' # |~ - Italic
|
|
452
|
-
if(attributes['italic'] == false)
|
|
453
|
-
new_text << "\e[3m"
|
|
454
|
-
attributes['italic'] = true
|
|
455
|
-
else
|
|
456
|
-
new_text << "\e[23m"
|
|
457
|
-
attributes['italic'] = false
|
|
458
|
-
end
|
|
459
|
-
when '_' # |_ - Underline
|
|
460
|
-
if(attributes['underline'] == false)
|
|
461
|
-
new_text << "\e[4m"
|
|
462
|
-
attributes['underline'] = true
|
|
463
|
-
else
|
|
464
|
-
new_text << "\e[24m"
|
|
465
|
-
attributes['underline'] = false
|
|
466
|
-
end
|
|
467
|
-
when '@' # |@ - Blink
|
|
468
|
-
if(attributes['blink'] == false)
|
|
469
|
-
new_text << "\e[5m"
|
|
470
|
-
attributes['blink'] = true
|
|
471
|
-
else
|
|
472
|
-
new_text << "\e[25m"
|
|
473
|
-
attributes['blink'] = false
|
|
474
|
-
end
|
|
475
|
-
when '^' # |^ - Move up 1 line
|
|
476
|
-
new_text << "\e[A"
|
|
477
|
-
when 'v', 'V' # |v - Move down 1 line
|
|
478
|
-
new_text << "\e[B"
|
|
479
|
-
when '>' # |> - Move forward 1 character
|
|
480
|
-
new_text << "\e[C"
|
|
481
|
-
when '<' # |< - Move back 1 character
|
|
482
|
-
new_text << "\e[D"
|
|
483
|
-
when 'h' # |h - Hide cursor
|
|
484
|
-
new_text << "\e[?25l"
|
|
485
|
-
when 'H' # |H - Unhide cursor
|
|
486
|
-
new_text << "\e[?25h"
|
|
487
|
-
when 'i', 'I' # |i - Inverse
|
|
488
|
-
if(attributes['inverse'] == false)
|
|
489
|
-
new_text << "\e[7m"
|
|
490
|
-
attributes['inverse'] = true
|
|
491
|
-
else
|
|
492
|
-
new_text << "\e[27m"
|
|
493
|
-
attributes['inverse'] = false
|
|
494
|
-
end
|
|
495
|
-
when 'x', 'X' # |x - Crossed Out
|
|
496
|
-
if(attributes['crossed_out'] == false)
|
|
497
|
-
new_text << "\e[9m"
|
|
498
|
-
attributes['crossed_out'] = true
|
|
499
|
-
else
|
|
500
|
-
new_text << "\e[29m"
|
|
501
|
-
attributes['crossed_out'] = false
|
|
502
|
-
end
|
|
503
|
-
when '#' # |#RRGGBB
|
|
504
|
-
attributes['color_capture'] = 1
|
|
505
|
-
when 'P', 'p' # |P or |p - 2 character hex format color (256 colors)
|
|
506
|
-
attributes['palette_capture'] = 1
|
|
507
|
-
when 'U', 'u' # |U or |u - Unicode 6 character hex format
|
|
508
|
-
attributes['unicode_capture'] = 1
|
|
509
|
-
when 'K', 'k' # |K or |k - Foreground text black
|
|
510
|
-
attributes['fg'] = "\e[30m"
|
|
511
|
-
new_text << "\e[0;30m"
|
|
512
|
-
attributes['bold'] = false
|
|
513
|
-
update_attributes(new_text, attributes)
|
|
514
|
-
new_text << attributes['bg'] == "\e[0m" ? "" : attributes['bg']
|
|
515
|
-
when 'S', 's' # |S or |s - Foreground text smoke
|
|
516
|
-
attributes['fg'] = "\e[1;30m"
|
|
517
|
-
new_text << "\e[1;30m"
|
|
518
|
-
attributes['bold'] = false
|
|
519
|
-
update_attributes(new_text, attributes)
|
|
520
|
-
attributes['bold'] = true
|
|
521
|
-
new_text << attributes['bg'] == "\e[0m" ? "" : attributes['bg']
|
|
522
|
-
when 'r' # |r - Foreground text red
|
|
523
|
-
attributes['fg'] = "\e[31m"
|
|
524
|
-
new_text << "\e[0;31m"
|
|
525
|
-
attributes['bold'] = false
|
|
526
|
-
update_attributes(new_text, attributes)
|
|
527
|
-
new_text << attributes['bg'] == "\e[0m" ? "" : attributes['bg']
|
|
528
|
-
when 'R' # |R - Foreground text bright red
|
|
529
|
-
attributes['fg'] = "\e[1;31m"
|
|
530
|
-
new_text << "\e[1;31m"
|
|
531
|
-
attributes['bold'] = false
|
|
532
|
-
update_attributes(new_text, attributes)
|
|
533
|
-
attributes['bold'] = true
|
|
534
|
-
new_text << attributes['bg'] == "\e[0m" ? "" : attributes['bg']
|
|
535
|
-
when 'g' # |g - Foreground text green
|
|
536
|
-
attributes['fg'] = "\e[32m"
|
|
537
|
-
new_text << "\e[0;32m"
|
|
538
|
-
attributes['bold'] = false
|
|
539
|
-
update_attributes(new_text, attributes)
|
|
540
|
-
new_text << attributes['bg'] == "\e[0m" ? "" : attributes['bg']
|
|
541
|
-
when 'G' # |G - Foreground text bright green
|
|
542
|
-
attributes['fg'] = "\e[1;32m"
|
|
543
|
-
new_text << "\e[1;32m"
|
|
544
|
-
attributes['bold'] = false
|
|
545
|
-
update_attributes(new_text, attributes)
|
|
546
|
-
attributes['bold'] = true
|
|
547
|
-
new_text << attributes['bg'] == "\e[0m" ? "" : attributes['bg']
|
|
548
|
-
when 'y' # |y - Foreground text yellow (brown)
|
|
549
|
-
attributes['fg'] = "\e[33m"
|
|
550
|
-
new_text << "\e[0;33m"
|
|
551
|
-
attributes['bold'] = false
|
|
552
|
-
update_attributes(new_text, attributes)
|
|
553
|
-
new_text << attributes['bg'] == "\e[0m" ? "" : attributes['bg']
|
|
554
|
-
when 'Y' # |Y - Foreground text bright yellow
|
|
555
|
-
attributes['fg'] = "\e[1;33m"
|
|
556
|
-
new_text << "\e[1;33m"
|
|
557
|
-
attributes['bold'] = false
|
|
558
|
-
update_attributes(new_text, attributes)
|
|
559
|
-
attributes['bold'] = true
|
|
560
|
-
new_text << attributes['bg'] == "\e[0m" ? "" : attributes['bg']
|
|
561
|
-
when 'b' # |b - Foreground text blue
|
|
562
|
-
attributes['fg'] = "\e[34m"
|
|
563
|
-
new_text << "\e[0;34m"
|
|
564
|
-
attributes['bold'] = false
|
|
565
|
-
update_attributes(new_text, attributes)
|
|
566
|
-
new_text << attributes['bg'] == "\e[0m" ? "" : attributes['bg']
|
|
567
|
-
when 'B' # |B - Foreground text bright blue
|
|
568
|
-
attributes['fg'] = "\e[1;34m"
|
|
569
|
-
new_text << "\e[1;34m"
|
|
570
|
-
attributes['bold'] = false
|
|
571
|
-
update_attributes(new_text, attributes)
|
|
572
|
-
attributes['bold'] = true
|
|
573
|
-
new_text << attributes['bg'] == "\e[0m" ? "" : attributes['bg']
|
|
574
|
-
when 'm' # |m - Foreground text magenta
|
|
575
|
-
attributes['fg'] = "\e[35m"
|
|
576
|
-
new_text << "\e[0;35m"
|
|
577
|
-
attributes['bold'] = false
|
|
578
|
-
update_attributes(new_text, attributes)
|
|
579
|
-
new_text << attributes['bg'] == "\e[0m" ? "" : attributes['bg']
|
|
580
|
-
when 'M' # |M - Foreground text bright magenta
|
|
581
|
-
attributes['fg'] = "\e[1;35m"
|
|
582
|
-
new_text << "\e[1;35m"
|
|
583
|
-
attributes['bold'] = false
|
|
584
|
-
update_attributes(new_text, attributes)
|
|
585
|
-
attributes['bold'] = true
|
|
586
|
-
new_text << attributes['bg'] == "\e[0m" ? "" : attributes['bg']
|
|
587
|
-
when 'c' # |c - Foreground text cyan
|
|
588
|
-
attributes['fg'] = "\e[36m"
|
|
589
|
-
new_text << "\e[0;36m"
|
|
590
|
-
attributes['bold'] = false
|
|
591
|
-
update_attributes(new_text, attributes)
|
|
592
|
-
new_text << attributes['bg'] == "\e[0m" ? "" : attributes['bg']
|
|
593
|
-
when 'C' # |C - Foreground text bright cyan
|
|
594
|
-
attributes['fg'] = "\e[1;36m"
|
|
595
|
-
new_text << "\e[1;36m"
|
|
596
|
-
attributes['bold'] = false
|
|
597
|
-
update_attributes(new_text, attributes)
|
|
598
|
-
attributes['bold'] = true
|
|
599
|
-
new_text << attributes['bg'] == "\e[0m" ? "" : attributes['bg']
|
|
600
|
-
when 'W', 'w' # |W or |w - Foreground text white
|
|
601
|
-
attributes['fg'] = "\e[1;37m"
|
|
602
|
-
new_text << "\e[1;37m"
|
|
603
|
-
attributes['bold'] = false
|
|
604
|
-
update_attributes(new_text, attributes)
|
|
605
|
-
attributes['bold'] = true
|
|
606
|
-
new_text << attributes['bg'] == "\e[0m" ? "" : attributes['bg']
|
|
607
|
-
when 'N', 'n' # |N or |n - Foreground text normal
|
|
608
|
-
attributes['fg'] = ""
|
|
609
|
-
new_text << "\e[0;37m"
|
|
610
|
-
attributes['bold'] = false
|
|
611
|
-
update_attributes(new_text, attributes)
|
|
612
|
-
new_text << attributes['bg'] == "\e[0m" ? "" : attributes['bg']
|
|
613
|
-
when 'O' # |O - Box mode off
|
|
614
|
-
attributes['box'] = -1
|
|
615
|
-
when 'o' # |o - Box mode 0
|
|
616
|
-
attributes['box'] = 0
|
|
617
|
-
when '-' # |- - Box mode 1
|
|
618
|
-
if(attributes['box_mode'] == true)
|
|
619
|
-
attributes['box'] = 1
|
|
620
|
-
else # We didn't find the next character
|
|
621
|
-
attributes['found'] = false
|
|
622
|
-
end
|
|
623
|
-
when '=' # |= - Box mode 2
|
|
624
|
-
if(attributes['box_mode'] == true)
|
|
625
|
-
attributes['box'] = 2
|
|
626
|
-
else # We didn't find the next character
|
|
627
|
-
attributes['found'] = false
|
|
628
|
-
end
|
|
629
|
-
when ';' # extend to end column with spaces
|
|
630
|
-
if(new_text =~ /\n?(.*)\Z/)
|
|
631
|
-
spaces = attributes['end'] - printable_length($1)
|
|
632
|
-
else
|
|
633
|
-
spaces = attributes['end']
|
|
634
|
-
end
|
|
635
|
-
spaces.times do
|
|
636
|
-
new_text << " "
|
|
637
|
-
end
|
|
638
|
-
when ']' # |]0-9 - end column number
|
|
639
|
-
attributes['end_capture'] = true
|
|
640
|
-
when '[' # |[emoji]
|
|
641
|
-
attributes['emoji_capture'] = true
|
|
642
|
-
when '\\' # |\ - Escape mode
|
|
643
|
-
attributes['pattern_escape'] = true
|
|
644
|
-
else # We didn't find the next character
|
|
645
|
-
attributes['found'] = false
|
|
646
|
-
end
|
|
647
|
-
elsif(character == '\\')
|
|
648
|
-
attributes['pattern_escape'] = true
|
|
649
|
-
else # We didn't find the next character
|
|
650
|
-
attributes['found'] = false
|
|
651
|
-
end
|
|
652
|
-
if(attributes['found'] == false)
|
|
653
|
-
if(character == '0') # |10+
|
|
654
|
-
if(attributes['num'] > 0)
|
|
655
|
-
attributes['num'] *= 10
|
|
656
|
-
end
|
|
657
|
-
elsif(character >= '1' && character <= '9') # |1+ through |9+
|
|
658
|
-
if(attributes['num'] > 0)
|
|
659
|
-
attributes['num'] *= 10
|
|
660
|
-
end
|
|
661
|
-
attributes['num'] += character.to_i
|
|
662
|
-
else
|
|
663
|
-
if(attributes['num'] <= 0) # No replacement found
|
|
664
|
-
new_text << '|' + character
|
|
665
|
-
else # Repeat number replacement found
|
|
666
|
-
if(attributes['box'] == 1)
|
|
667
|
-
attributes['num'].times do
|
|
668
|
-
new_text << process_box_one_replace(character)
|
|
669
|
-
end
|
|
670
|
-
attributes['num'] = 0
|
|
671
|
-
elsif(attributes['box'] == 2)
|
|
672
|
-
attributes['num'].times do
|
|
673
|
-
new_text << process_box_two_replace(character)
|
|
674
|
-
end
|
|
675
|
-
attributes['num'] = 0
|
|
676
|
-
else
|
|
677
|
-
attributes['num'].times do
|
|
678
|
-
new_text << character
|
|
679
|
-
end
|
|
680
|
-
attributes['num'] = 0
|
|
681
|
-
end
|
|
682
|
-
end
|
|
683
|
-
attributes['pipe'] = false
|
|
684
|
-
end
|
|
685
|
-
elsif(attributes['pattern_escape'] == false)
|
|
686
|
-
attributes['pipe'] = false
|
|
687
|
-
end
|
|
688
|
-
end
|
|
689
|
-
|
|
690
|
-
def process_ampersanded_character(character, new_text, attributes)
|
|
691
|
-
case character
|
|
692
|
-
when '#' # &#RRGGBB
|
|
693
|
-
attributes['color_capture'] = 1
|
|
694
|
-
return
|
|
695
|
-
when 'P', 'p' # |P or |p - 2 character hex format color (256 colors)
|
|
696
|
-
attributes['palette_capture'] = 1
|
|
697
|
-
return
|
|
698
|
-
when 'W', 'w' # &W or &w - Background white
|
|
699
|
-
new_text << "\e[0;47m"
|
|
700
|
-
attributes['bg'] = "\e[47m"
|
|
701
|
-
update_attributes(new_text, attributes)
|
|
702
|
-
new_text << attributes['fg'] == "\e[0m" ? "" : attributes['fg']
|
|
703
|
-
when 'C', 'c' # &C or &c - Background cyan
|
|
704
|
-
new_text << "\e[0;46m"
|
|
705
|
-
attributes['bg'] = "\e[46m"
|
|
706
|
-
update_attributes(new_text, attributes)
|
|
707
|
-
new_text << attributes['fg'] == "\e[0m" ? "" : attributes['fg']
|
|
708
|
-
when 'M', 'm' # &M or &m - Background magenta
|
|
709
|
-
new_text << "\e[0;45m"
|
|
710
|
-
attributes['bg'] = "\e[45m"
|
|
711
|
-
update_attributes(new_text, attributes)
|
|
712
|
-
new_text << attributes['fg'] == "\e[0m" ? "" : attributes['fg']
|
|
713
|
-
when 'B', 'b' # &B or &b - Background blue
|
|
714
|
-
new_text << "\e[0;44m"
|
|
715
|
-
attributes['bg'] = "\e[44m"
|
|
716
|
-
update_attributes(new_text, attributes)
|
|
717
|
-
new_text << attributes['fg'] == "\e[0m" ? "" : attributes['fg']
|
|
718
|
-
when 'Y', 'y' # &Y or &y - Background yellow (brown)
|
|
719
|
-
new_text << "\e[0;43m"
|
|
720
|
-
attributes['bg'] = "\e[43m"
|
|
721
|
-
update_attributes(new_text, attributes)
|
|
722
|
-
new_text << attributes['fg'] == "\e[0m" ? "" : attributes['fg']
|
|
723
|
-
when 'G', 'g' # &G or &g - Background green
|
|
724
|
-
new_text << "\e[0;42m"
|
|
725
|
-
attributes['bg'] = "\e[42m"
|
|
726
|
-
update_attributes(new_text, attributes)
|
|
727
|
-
new_text << attributes['fg'] == "\e[0m" ? "" : attributes['fg']
|
|
728
|
-
when 'R', 'r' # &R or &r - Background red
|
|
729
|
-
new_text << "\e[0;41m"
|
|
730
|
-
attributes['bg'] ="\e[41m"
|
|
731
|
-
update_attributes(new_text, attributes)
|
|
732
|
-
new_text << attributes['fg'] == "\e[0m" ? "" : attributes['fg']
|
|
733
|
-
when 'S', 's', 'K', 'k' # &S, &s, &K, &k - Background black/smoke
|
|
734
|
-
new_text << "\e[0;40m"
|
|
735
|
-
attributes['bg'] = "\e[40m"
|
|
736
|
-
update_attributes(new_text, attributes)
|
|
737
|
-
new_text << attributes['fg'] == "\e[0m" ? "" : attributes['fg']
|
|
738
|
-
when 'N', 'n' # &N or &n - Background normal
|
|
739
|
-
new_text << "\e[0m"
|
|
740
|
-
attributes['bg'] = ""
|
|
741
|
-
update_attributes(new_text, attributes)
|
|
742
|
-
new_text << attributes['fg'] == "\e[0m" ? "" : attributes['fg']
|
|
743
|
-
else
|
|
744
|
-
new_text << '&' + character
|
|
745
|
-
end
|
|
746
|
-
attributes['ampersand'] = false
|
|
747
|
-
end
|
|
748
|
-
|
|
749
|
-
def process_box_zero_replace(character)
|
|
750
|
-
case character
|
|
751
|
-
when '['
|
|
752
|
-
'+'
|
|
753
|
-
when ']'
|
|
754
|
-
'+'
|
|
755
|
-
when '-'
|
|
756
|
-
'-'
|
|
757
|
-
when '!'
|
|
758
|
-
'|'
|
|
759
|
-
when '>'
|
|
760
|
-
'+'
|
|
761
|
-
when '<'
|
|
762
|
-
'+'
|
|
763
|
-
when '+'
|
|
764
|
-
'+'
|
|
765
|
-
when '{'
|
|
766
|
-
'+'
|
|
767
|
-
when '}'
|
|
768
|
-
'+'
|
|
769
|
-
when 'v'
|
|
770
|
-
'+'
|
|
771
|
-
when '^'
|
|
772
|
-
'+'
|
|
773
|
-
else
|
|
774
|
-
character
|
|
775
|
-
end
|
|
776
|
-
end
|
|
777
|
-
|
|
778
|
-
def process_box_one_replace(character)
|
|
779
|
-
case character
|
|
780
|
-
when '['
|
|
781
|
-
'┌'
|
|
782
|
-
when ']'
|
|
783
|
-
'┐'
|
|
784
|
-
when '-'
|
|
785
|
-
'─'
|
|
786
|
-
when '!'
|
|
787
|
-
'│'
|
|
788
|
-
when '>'
|
|
789
|
-
'├'
|
|
790
|
-
when '<'
|
|
791
|
-
'┤'
|
|
792
|
-
when '+'
|
|
793
|
-
'┼'
|
|
794
|
-
when '{'
|
|
795
|
-
'└'
|
|
796
|
-
when '}'
|
|
797
|
-
'┘'
|
|
798
|
-
when 'v'
|
|
799
|
-
'┬'
|
|
800
|
-
when '^'
|
|
801
|
-
'┴'
|
|
802
|
-
else
|
|
803
|
-
character
|
|
804
|
-
end
|
|
805
|
-
end
|
|
806
|
-
|
|
807
|
-
def process_box_two_replace(character)
|
|
808
|
-
case character
|
|
809
|
-
when '['
|
|
810
|
-
'╔'
|
|
811
|
-
when ']'
|
|
812
|
-
'╗'
|
|
813
|
-
when '-'
|
|
814
|
-
'═'
|
|
815
|
-
when '!'
|
|
816
|
-
'║'
|
|
817
|
-
when '>'
|
|
818
|
-
'╠'
|
|
819
|
-
when '<'
|
|
820
|
-
'╣'
|
|
821
|
-
when '+'
|
|
822
|
-
'╬'
|
|
823
|
-
when '{'
|
|
824
|
-
'╚'
|
|
825
|
-
when '}'
|
|
826
|
-
'╝'
|
|
827
|
-
when 'v'
|
|
828
|
-
'╦'
|
|
829
|
-
when '^'
|
|
830
|
-
'╩'
|
|
831
|
-
else
|
|
832
|
-
character
|
|
3
|
+
# Allow older versions of Ruby to respond to the require_relative method
|
|
4
|
+
if(!Kernel.respond_to?(:require_relative))
|
|
5
|
+
module Kernel
|
|
6
|
+
def require_relative(path)
|
|
7
|
+
require File.join(File.dirname(caller[0]), path.to_str)
|
|
833
8
|
end
|
|
834
9
|
end
|
|
835
10
|
end
|
|
11
|
+
|
|
12
|
+
require_relative 'pipetext/version.rb'
|
|
13
|
+
require_relative 'pipetext/pipetext.rb'
|
|
14
|
+
require_relative 'pipetext/substitute_emoji_names.rb'
|