ansiterm 0.2.0 → 0.3.3

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 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