ansiterm 0.2.0 → 0.3.3

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
- SHA1:
3
- metadata.gz: 0df537615fddd8fe2fed0443af028139d1444979
4
- data.tar.gz: c5c72311de8e4022f7d8f951038f782ef8eadf57
2
+ SHA256:
3
+ metadata.gz: 594990b07d22ef5777b36348387c47a3061c4772f5e830a2240294c77574b3ea
4
+ data.tar.gz: 772aa91059ffa9d4e59bd06b33fd607726befacd0ecfafa61db3a5df862897a9
5
5
  SHA512:
6
- metadata.gz: e61b1784d2b29c07bca256043698320180542b7b1a44a3a3af5680e8eaa6c4ebf15bbf1a84cc620772b193e7321733a24d030df990684943b177b69e1fb09f82
7
- data.tar.gz: 6e1a7d0b76d5f7f11f85761fabddf6372294681d3f744fa4522d76fc30cab08bd27ce3426d3e01f780b1825135a4e876b1b3dd58e7bce31f67d7c97500b8420e
6
+ metadata.gz: d3e0fba3540ea67e4126c9ccc6918b778d7fffd971f407c3d4045148dda5b5edf2ef00761ec2465eea55e1e930da15e8a111e62a214753cbfd8a2c6d77fd753b
7
+ data.tar.gz: 59a9fa226a211ce692a446c7e895631bc19c30e729d3597a7f5f6f97e1de267ac16e4593fe363f460d4a37e3c02bbfb01112772d1cd7489e05cc6ae0406d471c
data/lib/ansiterm/attr.rb CHANGED
@@ -1,6 +1,8 @@
1
1
 
2
2
  module AnsiTerm
3
3
 
4
+ # # Attr #
5
+ #
4
6
  # Attr represents the attributes of a given character.
5
7
  # It is intended to follow the "Flyweight" GOF pattern
6
8
  # in that any object representing a given combination
@@ -10,7 +12,7 @@ module AnsiTerm
10
12
  # whether to e.g. encode a string as spans with one Attr,
11
13
  # or characters with one Attr per character.
12
14
  #
13
- # Use Attr#transition(other_attr) to retrieve an ANSI
15
+ # Use `Attr#transition(other_attr)` to retrieve an ANSI
14
16
  # sequence that represents the changes from self to
15
17
  # other_attr.
16
18
  #
@@ -20,7 +22,7 @@ module AnsiTerm
20
22
  ITALICS = 2
21
23
  UNDERLINE = 4
22
24
  CROSSED_OUT = 8
23
-
25
+
24
26
  attr_reader :fgcol, :bgcol, :flags
25
27
 
26
28
  def initialize(fgcol: nil, bgcol: nil, flags: 0)
@@ -30,12 +32,27 @@ module AnsiTerm
30
32
  freeze
31
33
  end
32
34
 
35
+ def ==(other)
36
+ return false if !other.kind_of?(self.class)
37
+ return fgcol == other.fgcol &&
38
+ bgcol == other.bgcol &&
39
+ flags == other.flags
40
+ end
41
+
33
42
  def merge(attrs)
43
+ return self if self == attrs
44
+ if attrs.kind_of?(self.class)
45
+ old = attrs
46
+ attrs = {}
47
+ attrs[:bgcol] = old.bgcol if old.bgcol
48
+ attrs[:fgcol] = old.fgcol if old.fgcol
49
+ attrs[:flags] = old.flags if old.flags
50
+ end
34
51
  self.class.new({bgcol: @bgcol, fgcol: @fgcol, flags: @flags}.merge(attrs))
35
52
  end
36
-
53
+
37
54
  def add_flag(flags); merge({flags: @flags | flags}); end
38
- def clear_flag(flags); merge({flags: @flags & ~BOLD}); end
55
+ def clear_flag(flags); merge({flags: @flags & ~flags}); end
39
56
 
40
57
  def reset; self.class.new; end
41
58
  def normal; clear_flag(BOLD); end
@@ -55,23 +72,23 @@ module AnsiTerm
55
72
 
56
73
  def transition_to(other)
57
74
  t = []
58
- t << [other.fgcol] if other.fgcol != self.fgcol
59
- t << [other.bgcol] if other.bgcol != self.bgcol
60
-
75
+ t << [other.fgcol] if other.fgcol != self.fgcol && other.fgcol
76
+ t << [other.bgcol] if other.bgcol != self.fgcol && other.bgcol
77
+
61
78
  if other.bold? != self.bold?
62
79
  t << [other.bold? ? 1 : 22]
63
80
  end
64
-
81
+
65
82
  if other.underline? != self.underline?
66
83
  t << [other.underline? ? 4 : 24]
67
84
  end
68
-
85
+
69
86
  if other.crossed_out? != self.crossed_out?
70
87
  t << [other.crossed_out? ? 9 : 29]
71
88
  end
72
89
 
73
90
  return "\e[0m" if other.normal? && !self.normal? && t.length != 1
74
-
91
+
75
92
  if t.empty?
76
93
  ""
77
94
  else
@@ -80,4 +97,7 @@ module AnsiTerm
80
97
  end
81
98
  end
82
99
 
100
+ def self.attr(*args)
101
+ Attr.new(*args)
102
+ end
83
103
  end
@@ -1,11 +1,20 @@
1
-
1
+ # coding: utf-8
2
2
  module AnsiTerm
3
3
 
4
4
  class String
5
- def initialize(str="")
6
- parse(str)
5
+ def initialize(str=nil)
6
+ if str
7
+ parse(str)
8
+ else
9
+ @str = ""
10
+ @attrs = []
11
+ end
7
12
  end
8
-
13
+
14
+ def to_plain_str
15
+ @str.dup
16
+ end
17
+
9
18
  def to_str
10
19
  out = ""
11
20
  a = Attr.new
@@ -20,6 +29,10 @@ module AnsiTerm
20
29
  out
21
30
  end
22
31
 
32
+ def to_s
33
+ to_str
34
+ end
35
+
23
36
  def encoding
24
37
  @str.encoding
25
38
  end
@@ -28,10 +41,57 @@ module AnsiTerm
28
41
  @str.length
29
42
  end
30
43
 
44
+ def index str, off = 0
45
+ @str.index(str,off)
46
+ end
47
+
31
48
  def set(str,attrs)
32
49
  @str, @attrs = str,Array(attrs)
33
50
  end
34
51
 
52
+ def raw
53
+ return @str, Array(@attrs)
54
+ end
55
+
56
+ def set_attr(range, attr)
57
+ min = [range.first - 1,0].max
58
+ fattr = @attrs[min]
59
+ attr = fattr.merge(attr)
60
+ r = Array(@attrs[range]).count # Inefficient, but saves dealing with negative offsets etc. "manually"
61
+ last = nil
62
+ @attrs[range] = @attrs[range].map do |a|
63
+ n = a.merge(attr)
64
+ last == n ? last : n
65
+ end
66
+ rm = range.last
67
+ if a = @attrs[rm]
68
+ @attrs[rm] = Attr.new(bgcol:40).merge(fattr).merge(a)
69
+ end
70
+ end
71
+
72
+ def merge_attr_below(range, attr)
73
+ min = [0,range.first - 1].max
74
+ fattr = @attrs[min]
75
+ r = Array(@attrs[range]).count # Inefficient, but saves dealing with negative offsets etc. "manually"
76
+ last = nil
77
+ @attrs[range] = @attrs[range].map do |a|
78
+ if a.bgcol == 49
79
+ a.merge(attr)
80
+ else
81
+ attr.merge(a)
82
+ end
83
+ end
84
+ #fattr #@attrs[min+r].merge(fattr)
85
+ end
86
+
87
+ def[]= range, str
88
+ s = @str
89
+ a = @attrs
90
+ parse(str)
91
+ @str = s[0..(range.min-1)].to_s + @str + s[(range.max)..-1].to_s
92
+ @attrs = a[0..(range.min-1)].to_a + @attrs + a[(range.max)..-1].to_a
93
+ end
94
+
35
95
  def[] i
36
96
  str = @str[i]
37
97
  if str
@@ -43,7 +103,27 @@ module AnsiTerm
43
103
  end
44
104
  end
45
105
 
106
+ def char_at(index)
107
+ @str[index]
108
+ end
46
109
 
110
+ def attr_at(index)
111
+ @attrs[index]
112
+ end
113
+
114
+ def << str
115
+ return self if str.nil?
116
+ if !str.kind_of?(self.class)
117
+ parse(self.to_str + "\e[0m" + str.to_str)
118
+ return self
119
+ end
120
+
121
+ s,a = str.raw
122
+ @str.concat(s)
123
+ @attrs.concat(a)
124
+ self
125
+ end
126
+
47
127
  private
48
128
 
49
129
  def parse_color(par, params, a, attr_name)
@@ -53,7 +133,8 @@ module AnsiTerm
53
133
  if par == "5"
54
134
  col = [col,5,params.shift].join(";")
55
135
  elsif par == "2"
56
- col = [col,5,params.shift,params.shift, params.shift].join(";")
136
+ col = ([col,2] << params.slice!(0..2)).join(";")
137
+ # ,params.shift,params.shift, params.shift].join(";")
57
138
  end
58
139
  end
59
140
  a.merge(attr_name => col)
@@ -70,16 +151,22 @@ module AnsiTerm
70
151
  while i < max
71
152
  c = str[i]
72
153
  if c == "\e" && str[i+1] == "[" # CSI
73
- params = ""
154
+ params = []
74
155
  i += 2
156
+ par = ""
75
157
  while i < max && str[i].ord < 0x40
76
- params << str[i]
158
+ if str[i] == ";"
159
+ params << par
160
+ par = ""
161
+ else
162
+ par << str[i]
163
+ end
77
164
  i+=1
78
165
  end
166
+ params << par if !par.empty?
79
167
  final = str[i]
80
168
 
81
169
  if final == "m"
82
- params = params.split(";")
83
170
  while par = params.shift
84
171
  par = par.to_i
85
172
  case par
@@ -94,12 +181,13 @@ module AnsiTerm
94
181
  when 22
95
182
  a = a.normal
96
183
  when 24
184
+ old = a
97
185
  a = a.clear_flag(Attr::UNDERLINE)
98
186
  when 29
99
187
  a = a.clear_flag(Attr::CROSSED_OUT)
100
- when 30..39
188
+ when 30..39, 90..98
101
189
  a = parse_color(par, params, a, :fgcol)
102
- when 40..49
190
+ when 40..49, 100..107
103
191
  a = parse_color(par, params, a, :bgcol)
104
192
  else
105
193
  @str << "[unknown escape: #{par}]"
@@ -115,4 +203,8 @@ module AnsiTerm
115
203
  self
116
204
  end
117
205
  end
206
+
207
+ def self.str(*args)
208
+ AnsiTerm::String.new(*args)
209
+ end
118
210
  end
@@ -1,3 +1,3 @@
1
1
  module AnsiTerm
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.3"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ansiterm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vidar Hokstad
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-12-31 00:00:00.000000000 Z
11
+ date: 2021-11-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -91,8 +91,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
91
91
  - !ruby/object:Gem::Version
92
92
  version: '0'
93
93
  requirements: []
94
- rubyforge_project:
95
- rubygems_version: 2.5.2
94
+ rubygems_version: 3.1.4
96
95
  signing_key:
97
96
  specification_version: 4
98
97
  summary: ANSI/VT102 terminal output with windowing