tty_string 0.1.0 → 0.2.0

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: 5cf9c99684d1bffc4b5238d85a0fbddc6c228a92
4
- data.tar.gz: 29daa63edffa32d87215419a32c0f3eb06511648
2
+ SHA256:
3
+ metadata.gz: a98f1f00566e4802bab20aa02326c6c53f9bbd164bbd5a499f64afc5a84f88cb
4
+ data.tar.gz: aa22c08116ffc776f98342bf7f8704cb5bfff7ec477fbe237d7405d1ae75752d
5
5
  SHA512:
6
- metadata.gz: c0184931cc63e842676e467f9cf1e3262f97a3e191f690bc100e075f389cdd54e3d94d09295da58a2e23a97b9f27836cd3eaf6772a67079184b1fc8030cd05ac
7
- data.tar.gz: 5804b7bcf35cb28a18feeb330662cac534b307badd16f2ebd5e138a772fcd8cf4743702181d33a208bf6b20f8d03013ac0f77fae7e1faba4eb1745bbb2687296
6
+ metadata.gz: e2f47e040687ea392c87784ffbe45cefe76c0dc0c5c644e651ecdc349f7d57a140c869dfd685492e8f02b430b3b3e92a3121d3f67edc3e9bd7109cd2cf979fba
7
+ data.tar.gz: 59ddb4338dc11b483666497ea417a30f9857172a81e3c39271b1585d94d40f1738a3f426600e037f50d110f5abeeab36d6f0b62b9495bb4207802c5333ccb181
data/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ # v0.2.0
2
+ - Stricter rendering because it turns out terminals are randomly permissive
3
+ - removed support for ruby 2.3
4
+ - added \e[S and \e[T handling
5
+
6
+ # v0.1.0
7
+ - Initial Release
data/Gemfile CHANGED
@@ -2,7 +2,5 @@
2
2
 
3
3
  source 'https://rubygems.org'
4
4
 
5
- git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6
-
7
5
  # Specify your gem's dependencies in tty_string.gemspec
8
6
  gemspec
data/README.md CHANGED
@@ -1,26 +1,35 @@
1
1
  # TTYString
2
2
 
3
- Render a string like your terminal does by parsing ANSI TTY codes.
3
+ [![Build Status](https://travis-ci.org/robotdana/tty_string.svg?branch=master)](https://travis-ci.org/robotdana/tty_string)
4
+
5
+ Render a string like your terminal does by (narrowly) parsing ANSI TTY codes.
4
6
  This is useful for testing CLI's
5
7
 
8
+ Various terminals are wildly variously permissive with what they accept,
9
+ so this doesn't even try to cover all possible cases,
10
+ instead it covers the narrowest possible case, and leaves the codes in place when unrecognised
11
+
6
12
  Supported codes
7
13
 
8
- - \b
9
- - \e[A
10
- - \e[B
11
- - \e[C
12
- - \e[D
13
- - \e[E
14
- - \e[F
15
- - \e[G
16
- - \e[H
17
- - \e[J
18
- - \e[K
19
- - \e[f
20
- - \e[m
21
- - \n
22
- - \r
23
- - \t
14
+ - `\a` # BEL, just removed.
15
+ - `\b` # backspace
16
+ - `\n` # newline
17
+ - `\r` # return, jump to the start of the line
18
+ - `\t` # tab, move to the next multiple-of-8 column
19
+ - `\e[nA` # move up n lines, default: 1
20
+ - `\e[nB` # move down n lines, default: 1
21
+ - `\e[nC` # move right n columns, default: 1
22
+ - `\e[nD` # move left n columns, default: 1
23
+ - `\e[nE` # move down n lines, and to the start of the line, default: 1
24
+ - `\e[nF` # move up n lines, and to the start of the line, default: 1
25
+ - `\e[nG` # jump to column to n
26
+ - `\e[n;mH` # jump to row n, column m, default: 1,1
27
+ - `\e[nJ` # n=0: clear the screen forward, n=1: clear backward, n=2 or 3: clear the screen. default 0
28
+ - `\e[nK` # n=0: clear the line forward, n=1: clear the line backward, n=2: clear the line. default 0
29
+ - `\e[n;mf` # jump to row n, column m, default: 1,1
30
+ - `\e[m` # styling codes, optionally suppressed with clear_style: false
31
+ - `\e[nS` # scroll down n rows, default 1
32
+ - `\e[nT` # scroll up n rows, default 1
24
33
 
25
34
  ## Installation
26
35
 
@@ -40,17 +49,20 @@ Or install it yourself as:
40
49
 
41
50
  ## Usage
42
51
 
43
- ```
44
- TTYString.new("th\ta string\e[3Gis is").to_s => "this is a string"
52
+ ```ruby
53
+ TTYString.new("th\ta string\e[3Gis is").to_s
54
+ => "this is a string"
45
55
  ```
46
56
 
47
57
  Styling information is suppressed by default:
48
- ```
49
- TTYString.new("th\ta \e[31mstring\e[0m\e[3Gis is", clear_style: false).to_s => "this is a string"
58
+ ```ruby
59
+ TTYString.new("th\ta \e[31mstring\e[0m\e[3Gis is").to_s
60
+ => "this is a string"
50
61
  ```
51
62
  But can be passed through:
52
- ```
53
- TTYString.new("th\ta \e[31mstring\e[0m\e[3Gis is", clear_style: false).to_s => "this is a \e[31mstring\e[0m"
63
+ ```ruby
64
+ TTYString.new("th\ta \e[31mstring\e[0m\e[3Gis is", clear_style: false).to_s
65
+ => "this is a \e[31mstring\e[0m"
54
66
  ```
55
67
 
56
68
  ## Development
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TTYString
4
+ class Code
5
+ class << self
6
+ def descendants
7
+ @@descendants
8
+ end
9
+
10
+ def inherited(klass)
11
+ @@descendants ||= [] # rubocop:disable Style/ClassVars I want it to be shared between subclasses.
12
+ @@descendants << klass
13
+ @@descendants.uniq!
14
+ end
15
+
16
+ def render(parser)
17
+ return unless match?(parser)
18
+
19
+ new(parser).action(*args(parser))
20
+
21
+ true
22
+ end
23
+
24
+ def char(value = nil)
25
+ @char = value if value
26
+ @char ||= name.split('::').last
27
+ end
28
+
29
+ private
30
+
31
+ def re
32
+ @re ||= /#{char}/.freeze
33
+ end
34
+
35
+ def args(_scanner)
36
+ []
37
+ end
38
+
39
+ def match?(parser)
40
+ parser.skip(re)
41
+ end
42
+ end
43
+
44
+ def initialize(parser)
45
+ @parser = parser
46
+ end
47
+
48
+ private
49
+
50
+ attr_reader :parser
51
+
52
+ def action; end
53
+
54
+ def screen
55
+ parser.screen
56
+ end
57
+
58
+ def cursor
59
+ parser.cursor
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'code'
4
+ require_relative 'csi_code'
5
+
6
+ class TTYString
7
+ class Code
8
+ class SlashA < TTYString::Code
9
+ char "\a"
10
+ end
11
+
12
+ class SlashB < TTYString::Code
13
+ char "\b"
14
+
15
+ def self.match?(scanner)
16
+ # can't use `scan(/\b/)` because it matches everything
17
+ return false unless scanner.peek(1) == "\b"
18
+
19
+ scanner.pos += 1
20
+ true
21
+ end
22
+
23
+ def action
24
+ cursor.left
25
+ screen.clear_at_cursor
26
+ end
27
+ end
28
+
29
+ class SlashN < TTYString::Code
30
+ char "\n"
31
+
32
+ def action
33
+ cursor.down
34
+ cursor.col = 0
35
+ screen.write('')
36
+ end
37
+ end
38
+
39
+ class SlashR < TTYString::Code
40
+ char "\r"
41
+
42
+ def action
43
+ cursor.col = 0
44
+ end
45
+ end
46
+
47
+ class SlashT < TTYString::Code
48
+ char "\t"
49
+
50
+ def action
51
+ cursor.right(8 - (cursor.col % 8))
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'code'
4
+
5
+ class TTYString
6
+ class CSICode < TTYString::Code
7
+ class << self
8
+ def default_arg(value = nil)
9
+ @default_arg ||= value
10
+ @default_arg || 1
11
+ end
12
+
13
+ private
14
+
15
+ def match?(parser)
16
+ parser.scan(re)
17
+ end
18
+
19
+ def args(parser)
20
+ parser.matched.slice(2..-2).split(';')
21
+ .map { |n| n.empty? ? default_arg : n.to_i }
22
+ end
23
+
24
+ def re
25
+ @re ||= /\e\[#{args_re}#{char}/
26
+ end
27
+
28
+ def args_re
29
+ case max_args
30
+ when 1 then /#{arg_re}?/
31
+ when nil then /(#{arg_re}?(;#{arg_re})*)?/
32
+ else /(#{arg_re}?(;#{arg_re}){0,#{max_args - 1}})?/
33
+ end
34
+ end
35
+
36
+ def arg_re
37
+ /\d*/
38
+ end
39
+
40
+ def max_args
41
+ @max_args ||= begin
42
+ params = instance_method(:action).parameters
43
+ return if params.assoc(:rest)
44
+
45
+ params.length
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ TTYString::Code.descendants.pop
@@ -0,0 +1,127 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'csi_code'
4
+
5
+ class TTYString
6
+ class CSICode
7
+ class A < TTYString::CSICode
8
+ def action(rows = 1)
9
+ cursor.up(rows)
10
+ end
11
+ end
12
+
13
+ class B < TTYString::CSICode
14
+ def action(rows = 1)
15
+ cursor.down(rows)
16
+ end
17
+ end
18
+
19
+ class C < TTYString::CSICode
20
+ def action(cols = 1)
21
+ cursor.right(cols)
22
+ end
23
+ end
24
+
25
+ class D < TTYString::CSICode
26
+ def action(cols = 1)
27
+ cursor.left(cols)
28
+ end
29
+ end
30
+
31
+ class E < TTYString::CSICode
32
+ def action(rows = 1)
33
+ cursor.down(rows)
34
+ cursor.col = 0
35
+ end
36
+ end
37
+
38
+ class F < TTYString::CSICode
39
+ def action(rows = 1)
40
+ cursor.up(rows)
41
+ cursor.col = 0
42
+ end
43
+ end
44
+
45
+ class G < TTYString::CSICode
46
+ def action(col = 1)
47
+ # cursor is zero indexed, arg is 1 indexed
48
+ cursor.col = col.to_i - 1
49
+ end
50
+ end
51
+
52
+ class H < TTYString::CSICode
53
+ def action(row = 1, col = 1)
54
+ # cursor is zero indexed, arg is 1 indexed
55
+ cursor.row = row.to_i - 1
56
+ cursor.col = col.to_i - 1
57
+ end
58
+ end
59
+
60
+ class LowF < TTYString::CSICode::H
61
+ char 'f'
62
+ end
63
+
64
+ class J < TTYString::CSICode
65
+ default_arg 0
66
+
67
+ def self.args_re
68
+ /[0-3]?/
69
+ end
70
+
71
+ def action(mode = 0)
72
+ # :nocov: else won't ever be called. don't worry about it
73
+ case mode
74
+ # :nocov:
75
+ when 0 then screen.clear_forward
76
+ when 1 then screen.clear_backward
77
+ when 2, 3 then screen.clear
78
+ end
79
+ end
80
+ end
81
+
82
+ class K < TTYString::CSICode
83
+ default_arg 0
84
+
85
+ def self.arg_re
86
+ /[0-2]?/
87
+ end
88
+
89
+ def action(mode = 0)
90
+ # :nocov: else won't ever be called. don't worry about it
91
+ case mode
92
+ # :nocov:
93
+ when 0 then screen.clear_line_forward
94
+ when 1 then screen.clear_line_backward
95
+ when 2 then screen.clear_line
96
+ end
97
+ end
98
+ end
99
+
100
+ class LowM < TTYString::CSICode
101
+ char 'm'
102
+
103
+ def self.arg_re
104
+ # 0-255
105
+ /(\d|\d\d|1\d\d|2[0-4]\d|25[0-5])?/
106
+ end
107
+
108
+ def self.render(renderer)
109
+ super if renderer.clear_style
110
+ end
111
+
112
+ def action(*args); end
113
+ end
114
+
115
+ class S < TTYString::CSICode
116
+ def action(rows = 1)
117
+ rows.times { screen.scroll_up }
118
+ end
119
+ end
120
+
121
+ class T < TTYString::CSICode
122
+ def action(rows = 1)
123
+ rows.times { screen.scroll_down }
124
+ end
125
+ end
126
+ end
127
+ end
@@ -11,40 +11,28 @@ class TTYString
11
11
  end
12
12
 
13
13
  def row=(value)
14
- @row = value.to_i
14
+ @row = value
15
15
  @row = 0 if @row.negative?
16
16
  end
17
17
 
18
18
  def col=(value)
19
- @col = value.to_i
19
+ @col = value
20
20
  @col = 0 if @col.negative?
21
21
  end
22
22
 
23
23
  def left(count = 1)
24
- count = count.to_i
25
- raise ArgumentError if count.negative?
26
-
27
24
  self.col -= count
28
25
  end
29
26
 
30
27
  def up(count = 1)
31
- count = count.to_i
32
- raise ArgumentError if count.negative?
33
-
34
28
  self.row -= count
35
29
  end
36
30
 
37
31
  def down(count = 1)
38
- count = count.to_i
39
- raise ArgumentError unless count >= 0
40
-
41
32
  self.row += count
42
33
  end
43
34
 
44
35
  def right(count = 1)
45
- count = count.to_i
46
- raise ArgumentError unless count >= 0
47
-
48
36
  self.col += count
49
37
  end
50
38
 
@@ -1,82 +1,40 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'strscan'
4
- require_relative 'renderer'
4
+ require_relative 'code_definitions'
5
+ require_relative 'csi_code_definitions'
6
+
7
+ require_relative 'screen'
5
8
 
6
9
  class TTYString
7
10
  # Reads the text string a
8
11
  class Parser < StringScanner
9
- def render(clear_style: true)
12
+ attr_accessor :clear_style
13
+ attr_reader :screen
14
+
15
+ def render
10
16
  reset
11
- @clear_style = clear_style
12
- @renderer = Renderer.new
17
+ @screen = Screen.new
13
18
  read until eos?
14
- renderer.to_s
19
+ screen.to_s
15
20
  end
16
21
 
17
- private
22
+ def cursor
23
+ screen.cursor
24
+ end
18
25
 
19
- attr_reader :renderer
20
- attr_reader :clear_style
26
+ private
21
27
 
22
28
  def write(string)
23
- renderer.write(string)
29
+ screen.write(string)
24
30
  end
25
31
 
26
32
  def read
27
- text || slash_n || slash_r || slash_t || slash_b || slash_e
28
- end
29
-
30
- def text
31
- write(matched) if scan(text_regexp)
32
- end
33
-
34
- def slash_n
35
- renderer.slash_n if skip(/\n/)
36
- end
37
-
38
- def slash_r
39
- renderer.slash_r if skip(/\r/)
40
- end
41
-
42
- def slash_t
43
- renderer.slash_t if skip(/\t/)
44
- end
45
-
46
- def slash_b
47
- # can't use `scan(/\b/)` because it matches everything
48
- return unless peek(1) == "\b"
49
-
50
- self.pos += 1
51
- renderer.slash_b
52
- end
53
-
54
- def slash_e
55
- return unless scan(csi_regexp)
56
-
57
- args = matched.slice(2..-2).split(';')
58
- command = matched.slice(-1)
59
- render_csi(:"csi_#{command}", *args)
60
- end
61
-
62
- def csi_regexp
63
- @csi_regexp ||= Regexp.new("\e#{csi_pattern}")
64
- end
65
-
66
- def csi_pattern
67
- "\\[(\\d+;?|;)*[ABCDEFGHJKf#{'m' if clear_style}]"
68
- end
69
-
70
- def text_regexp
71
- @text_regexp ||= Regexp.new("[^\b\t\r\n\e]|\e(?!#{csi_pattern})")
33
+ TTYString::Code.descendants.any? { |c| c.render(self) } || default
72
34
  end
73
35
 
74
- def render_csi(method, *args)
75
- method = renderer.method(method)
76
- params = method.parameters
77
- args = args.take(params.length) unless params.assoc(:rest)
78
- args = [] if args.all?(&:empty?)
79
- method.call(*args)
36
+ def default
37
+ write(getch)
80
38
  end
81
39
  end
82
40
  end
@@ -46,6 +46,16 @@ class TTYString
46
46
  @screen = []
47
47
  end
48
48
 
49
+ def scroll_up
50
+ screen.push([])
51
+ screen.shift
52
+ end
53
+
54
+ def scroll_down
55
+ screen.unshift([])
56
+ screen.pop
57
+ end
58
+
49
59
  def clear_lines_before
50
60
  screen.fill([], 0...row)
51
61
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class TTYString
4
- VERSION = '0.1.0'
4
+ VERSION = '0.2.0'
5
5
  end
data/lib/tty_string.rb CHANGED
@@ -7,11 +7,11 @@ require_relative 'tty_string/parser'
7
7
  class TTYString
8
8
  def initialize(input_string, clear_style: true)
9
9
  @parser = Parser.new(input_string)
10
- @clear_style = clear_style
10
+ @parser.clear_style = clear_style
11
11
  end
12
12
 
13
13
  def to_s
14
- parser.render(clear_style: clear_style)
14
+ parser.render
15
15
  end
16
16
 
17
17
  private
data/tty_string.gemspec CHANGED
@@ -11,21 +11,25 @@ Gem::Specification.new do |spec|
11
11
  spec.email = ['robot@dana.sh']
12
12
 
13
13
  spec.summary = 'Render a string using ANSI TTY codes'
14
- spec.homepage = "https://github.com/robotdana/tty_string"
14
+ spec.homepage = 'https://github.com/robotdana/tty_string'
15
15
  spec.license = 'MIT'
16
16
 
17
- spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
- f.match(%r{^(test|spec|features|\.?rubocop|\.travis|\.git|\.rspec)/})
19
- end
20
- spec.bindir = 'exe'
21
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
17
+ spec.files = Dir.glob('{lib}/**/*') + %w{
18
+ CHANGELOG.md
19
+ Gemfile
20
+ LICENSE.txt
21
+ README.md
22
+ tty_string.gemspec
23
+ }
24
+ spec.required_ruby_version = '>= 2.4'
22
25
  spec.require_paths = ['lib']
23
26
 
24
- spec.add_development_dependency 'bundler', '~> 1.16'
25
- spec.add_development_dependency 'pry', '~> 0.12.2'
27
+ spec.add_development_dependency 'bundler', '~> 2.0'
28
+ spec.add_development_dependency 'pry', '~> 0.12'
26
29
  spec.add_development_dependency 'rake', '~> 10.0'
27
30
  spec.add_development_dependency 'rspec', '~> 3.0'
28
- spec.add_development_dependency 'rubocop', '~> 0.74.0'
29
- spec.add_development_dependency 'rubocop-performance', '~> 1.4.1'
30
- spec.add_development_dependency 'rubocop-rspec', '~> 1.35.0'
31
+ spec.add_development_dependency 'rubocop', '~> 0.74'
32
+ spec.add_development_dependency 'rubocop-performance', '~> 1.4'
33
+ spec.add_development_dependency 'rubocop-rspec', '~> 1.35'
34
+ spec.add_development_dependency 'simplecov', '~> 0.18.5'
31
35
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tty_string
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dana Sherson
8
8
  autorequire:
9
- bindir: exe
9
+ bindir: bin
10
10
  cert_chain: []
11
- date: 2019-09-21 00:00:00.000000000 Z
11
+ date: 2020-03-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.16'
19
+ version: '2.0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.16'
26
+ version: '2.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: pry
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.12.2
33
+ version: '0.12'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.12.2
40
+ version: '0.12'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -72,42 +72,56 @@ dependencies:
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 0.74.0
75
+ version: '0.74'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 0.74.0
82
+ version: '0.74'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rubocop-performance
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: 1.4.1
89
+ version: '1.4'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: 1.4.1
96
+ version: '1.4'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: rubocop-rspec
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: 1.35.0
103
+ version: '1.35'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: 1.35.0
110
+ version: '1.35'
111
+ - !ruby/object:Gem::Dependency
112
+ name: simplecov
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 0.18.5
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 0.18.5
111
125
  description:
112
126
  email:
113
127
  - robot@dana.sh
@@ -115,22 +129,17 @@ executables: []
115
129
  extensions: []
116
130
  extra_rdoc_files: []
117
131
  files:
118
- - ".gitignore"
119
- - ".gitmodules"
120
- - ".rspec"
121
- - ".rubocop.yml"
122
- - ".travis.yml"
132
+ - CHANGELOG.md
123
133
  - Gemfile
124
- - Gemfile.lock
125
134
  - LICENSE.txt
126
135
  - README.md
127
- - Rakefile
128
- - bin/console
129
- - bin/setup
130
136
  - lib/tty_string.rb
137
+ - lib/tty_string/code.rb
138
+ - lib/tty_string/code_definitions.rb
139
+ - lib/tty_string/csi_code.rb
140
+ - lib/tty_string/csi_code_definitions.rb
131
141
  - lib/tty_string/cursor.rb
132
142
  - lib/tty_string/parser.rb
133
- - lib/tty_string/renderer.rb
134
143
  - lib/tty_string/screen.rb
135
144
  - lib/tty_string/version.rb
136
145
  - tty_string.gemspec
@@ -146,15 +155,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
146
155
  requirements:
147
156
  - - ">="
148
157
  - !ruby/object:Gem::Version
149
- version: '0'
158
+ version: '2.4'
150
159
  required_rubygems_version: !ruby/object:Gem::Requirement
151
160
  requirements:
152
161
  - - ">="
153
162
  - !ruby/object:Gem::Version
154
163
  version: '0'
155
164
  requirements: []
156
- rubyforge_project:
157
- rubygems_version: 2.5.2.1
165
+ rubygems_version: 3.1.2
158
166
  signing_key:
159
167
  specification_version: 4
160
168
  summary: Render a string using ANSI TTY codes
data/.gitignore DELETED
@@ -1,11 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /_yardoc/
4
- /coverage/
5
- /doc/
6
- /pkg/
7
- /spec/reports/
8
- /tmp/
9
-
10
- # rspec failure tracking
11
- .rspec_status
data/.gitmodules DELETED
@@ -1,3 +0,0 @@
1
- [submodule "rubocop_yml"]
2
- path = rubocop_yml
3
- url = https://github.com/robotdana/rubocop_yml.git
data/.rspec DELETED
@@ -1,3 +0,0 @@
1
- --format documentation
2
- --color
3
- --require spec_helper
data/.rubocop.yml DELETED
@@ -1 +0,0 @@
1
- rubocop_yml/rubocop.yml
data/.travis.yml DELETED
@@ -1,5 +0,0 @@
1
- sudo: false
2
- language: ruby
3
- rvm:
4
- - 2.5.1
5
- before_install: gem install bundler -v 1.16.0
data/Gemfile.lock DELETED
@@ -1,63 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- tty_string (0.1.0)
5
-
6
- GEM
7
- remote: https://rubygems.org/
8
- specs:
9
- ast (2.4.0)
10
- coderay (1.1.2)
11
- diff-lcs (1.3)
12
- jaro_winkler (1.5.3)
13
- method_source (0.9.2)
14
- parallel (1.17.0)
15
- parser (2.6.4.1)
16
- ast (~> 2.4.0)
17
- pry (0.12.2)
18
- coderay (~> 1.1.0)
19
- method_source (~> 0.9.0)
20
- rainbow (3.0.0)
21
- rake (10.5.0)
22
- rspec (3.8.0)
23
- rspec-core (~> 3.8.0)
24
- rspec-expectations (~> 3.8.0)
25
- rspec-mocks (~> 3.8.0)
26
- rspec-core (3.8.2)
27
- rspec-support (~> 3.8.0)
28
- rspec-expectations (3.8.4)
29
- diff-lcs (>= 1.2.0, < 2.0)
30
- rspec-support (~> 3.8.0)
31
- rspec-mocks (3.8.1)
32
- diff-lcs (>= 1.2.0, < 2.0)
33
- rspec-support (~> 3.8.0)
34
- rspec-support (3.8.2)
35
- rubocop (0.74.0)
36
- jaro_winkler (~> 1.5.1)
37
- parallel (~> 1.10)
38
- parser (>= 2.6)
39
- rainbow (>= 2.2.2, < 4.0)
40
- ruby-progressbar (~> 1.7)
41
- unicode-display_width (>= 1.4.0, < 1.7)
42
- rubocop-performance (1.4.1)
43
- rubocop (>= 0.71.0)
44
- rubocop-rspec (1.35.0)
45
- rubocop (>= 0.60.0)
46
- ruby-progressbar (1.10.1)
47
- unicode-display_width (1.6.0)
48
-
49
- PLATFORMS
50
- ruby
51
-
52
- DEPENDENCIES
53
- bundler (~> 1.16)
54
- pry (~> 0.12.2)
55
- rake (~> 10.0)
56
- rspec (~> 3.0)
57
- rubocop (~> 0.74.0)
58
- rubocop-performance (~> 1.4.1)
59
- rubocop-rspec (~> 1.35.0)
60
- tty_string!
61
-
62
- BUNDLED WITH
63
- 1.16.0
data/Rakefile DELETED
@@ -1,8 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'bundler/gem_tasks'
4
- require 'rspec/core/rake_task'
5
-
6
- RSpec::Core::RakeTask.new(:spec)
7
-
8
- task default: :spec
data/bin/console DELETED
@@ -1,15 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require 'bundler/setup'
5
- require 'tty_string'
6
-
7
- # You can add fixtures and/or initialization code here to make experimenting
8
- # with your gem easier. You can also use a different console, if you like.
9
-
10
- # (If you use this, don't forget to add pry to your Gemfile!)
11
- # require "pry"
12
- # Pry.start
13
-
14
- require 'irb'
15
- IRB.start(__FILE__)
data/bin/setup DELETED
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
5
-
6
- bundle install
7
-
8
- # Do any other automated setup that you need to do here
@@ -1,104 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'screen'
4
- class TTYString
5
- # turns the text string into screen instructions
6
- class Renderer
7
- attr_reader :screen
8
-
9
- def initialize
10
- @screen = Screen.new
11
- end
12
-
13
- def to_s
14
- screen.to_s
15
- end
16
-
17
- def write(string)
18
- screen.write(string)
19
- end
20
-
21
- # rubocop:disable Naming/MethodName
22
- def csi_A(rows = 1)
23
- cursor.up(rows)
24
- end
25
-
26
- def csi_B(rows = 1)
27
- cursor.down(rows)
28
- end
29
-
30
- def csi_C(cols = 1)
31
- cursor.right(cols)
32
- end
33
-
34
- def csi_D(cols = 1)
35
- cursor.left(cols)
36
- end
37
-
38
- def csi_E(rows = 1)
39
- cursor.down(rows)
40
- cursor.col = 0
41
- end
42
-
43
- def csi_F(rows = 1)
44
- cursor.up(rows)
45
- cursor.col = 0
46
- end
47
-
48
- def csi_G(col = 1)
49
- cursor.col = col.to_i - 1 # cursor is zero indexed, arg is 1 indexed
50
- end
51
-
52
- def csi_H(row = 1, col = 1)
53
- # cursor is zero indexed, arg is 1 indexed
54
- cursor.row = row.to_i - 1
55
- cursor.col = col.to_i - 1
56
- end
57
- alias csi_f csi_H
58
-
59
- def csi_J(mode = 0)
60
- case mode.to_i
61
- when 0 then screen.clear_forward
62
- when 1 then screen.clear_backward
63
- when 2, 3 then screen.clear
64
- end
65
- end
66
-
67
- def csi_K(mode = 0)
68
- case mode.to_i
69
- when 0 then screen.clear_line_forward
70
- when 1 then screen.clear_line_backward
71
- when 2 then screen.clear_line
72
- end
73
- end
74
-
75
- def csi_m(*args)
76
- end
77
- # rubocop:enable Naming/MethodName
78
-
79
- def slash_b
80
- cursor.left
81
- screen.clear_at_cursor
82
- end
83
-
84
- def slash_n
85
- cursor.down
86
- cursor.col = 0
87
- screen.write('')
88
- end
89
-
90
- def slash_r
91
- cursor.col = 0
92
- end
93
-
94
- def slash_t
95
- cursor.right(8 - (cursor.col % 8))
96
- end
97
-
98
- private
99
-
100
- def cursor
101
- screen.cursor
102
- end
103
- end
104
- end