typewrite 1.1.0 → 1.2.0

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
2
  SHA256:
3
- metadata.gz: efa86fb7cf794c1ea05096594de6f93085685516349f1b6f5e858cccf5c09e84
4
- data.tar.gz: e808a5d20615b4fc265486ab7cd09e8d74d717235557c1521b68ac1e68538670
3
+ metadata.gz: 1ee853e9212af73f1b12a6518946393a40beccc0cbe5df5e7b12dee147337d50
4
+ data.tar.gz: 7c3d96dcde6fbd358ceb4a05ac6769da6aba5a5bdc08e007618ec0a59cc64dae
5
5
  SHA512:
6
- metadata.gz: 361c42d76a638ea30e048af83371de0d8f45b7ca57085cfb93904b7a1cc1c0830e052b29736783b29433f229728e2dac32428f583e0aae3093954f47536cf8f1
7
- data.tar.gz: 80aeecf5215198c8fd787afe40f3460549a6553adde9a42e7f442bdb51263c83dbcc2d45808bf823d1dffd9a93dd4206ff51c241a5843ad66aeb2396c5f1b6c4
6
+ metadata.gz: 4d05e589cf61fc51a40dd96272045680c873474a5cf64327aecc224986c4d4b863873bbdf70ca500ceb8cc56ab5e51c84d06c8dce5e3f1d6fdb356f2b3f1b9cc
7
+ data.tar.gz: '09bad21d5cf41ad3d1b2bf756a9b6f65af663dce54abfdae984d4fc82485a84d7d7ab198d2318224d773374d4e1d667cb2ffc9c0b8ee0c0c45419fef796377ce'
@@ -0,0 +1,48 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [ main ]
6
+ pull_request:
7
+ branches: [ main ]
8
+
9
+ jobs:
10
+ lint:
11
+ runs-on: ubuntu-latest
12
+ name: Lint
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+
16
+ - name: Set up Ruby
17
+ uses: ruby/setup-ruby@v1
18
+ with:
19
+ ruby-version: '3.4'
20
+ bundler-cache: true
21
+
22
+ - name: Run RuboCop
23
+ run: bundle exec rubocop
24
+
25
+ test:
26
+ runs-on: ubuntu-latest
27
+ strategy:
28
+ fail-fast: false
29
+ matrix:
30
+ ruby-version:
31
+ - '3.0'
32
+ - '3.1'
33
+ - '3.2'
34
+ - '3.3'
35
+ - '3.4'
36
+
37
+ name: Ruby ${{ matrix.ruby-version }}
38
+ steps:
39
+ - uses: actions/checkout@v4
40
+
41
+ - name: Set up Ruby
42
+ uses: ruby/setup-ruby@v1
43
+ with:
44
+ ruby-version: ${{ matrix.ruby-version }}
45
+ bundler-cache: true
46
+
47
+ - name: Run tests
48
+ run: bundle exec rspec
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --require spec_helper
2
+ --format documentation
3
+ --color
data/.rubocop.yml ADDED
@@ -0,0 +1,36 @@
1
+ AllCops:
2
+ NewCops: enable
3
+ TargetRubyVersion: 3.0
4
+ Exclude:
5
+ - "vendor/**/*"
6
+ - "pkg/**/*"
7
+
8
+ # Gem-specific relaxations
9
+ Style/Documentation:
10
+ Enabled: false # Small gem, README is sufficient
11
+
12
+ Metrics/BlockLength:
13
+ Exclude:
14
+ - "spec/**/*"
15
+ - "*.gemspec"
16
+
17
+ Metrics/AbcSize:
18
+ Max: 18 # Allow slightly higher for interrupt logic
19
+
20
+ Metrics/MethodLength:
21
+ Max: 20 # Allow slightly higher for interrupt logic
22
+
23
+ # Prefer double quotes (common in gems)
24
+ Style/StringLiterals:
25
+ EnforcedStyle: double_quotes
26
+
27
+ Style/StringLiteralsInInterpolation:
28
+ EnforcedStyle: double_quotes
29
+
30
+ # Frozen string literal is good practice
31
+ Style/FrozenStringLiteralComment:
32
+ EnforcedStyle: always
33
+
34
+ # Allow boolean parameters for backwards compatibility
35
+ Style/OptionalBooleanParameter:
36
+ Enabled: false
data/CHANGELOG.md ADDED
@@ -0,0 +1,48 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [1.2.0] - 2026-02-02
9
+
10
+ ### Added
11
+ - Keyboard interrupt support to skip typewriter animation
12
+ - `interrupt: true` or `interrupt: :enter` - Skip with Enter key
13
+ - `interrupt: :any` - Skip with any key press
14
+ - `interrupt: ["q", "x", " "]` - Skip with specific keys
15
+ - When interrupted, remaining text prints immediately
16
+ - Non-blocking keyboard input detection using `io/console`
17
+
18
+ ### Changed
19
+ - Updated README with interrupt mode documentation and examples
20
+ - Adjusted RuboCop metrics configuration for interrupt logic
21
+ - **Note:** Undocumented keyword argument syntax (e.g., `type_rate: 0.05`) is no longer supported due to Ruby 3.0+ keyword argument separation. All documented positional argument usage remains fully compatible.
22
+
23
+ ### Technical
24
+ - Added `write_interruptible` and `key_matches?` private methods
25
+ - Uses `IO.select` for non-blocking input polling (Ruby 3.0+ compatible)
26
+ - 100% backwards compatible for all documented usage patterns
27
+
28
+ ## [1.1.0] - 2025-01-XX
29
+
30
+ ### Changed
31
+ - Modernized codebase to idiomatic Ruby gem standards
32
+ - Added RuboCop linting to development workflow
33
+
34
+ ### Added
35
+ - RSpec testing infrastructure
36
+ - GitHub Actions CI workflow
37
+ - Comprehensive test coverage for timing and output behavior
38
+
39
+ ## [1.0.0] - Earlier
40
+
41
+ ### Added
42
+ - Initial typewriter effect implementation
43
+ - Basic timing controls (type_rate, punc_rate)
44
+ - Line break control
45
+
46
+ [1.2.0]: https://github.com/CJGlitter/typewrite/compare/v1.1.0...v1.2.0
47
+ [1.1.0]: https://github.com/CJGlitter/typewrite/compare/v1.0.0...v1.1.0
48
+ [1.0.0]: https://github.com/CJGlitter/typewrite/releases/tag/v1.0.0
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gemspec
6
+
7
+ group :development, :test do
8
+ gem "rake", "~> 13.0"
9
+ gem "rspec", "~> 3.12"
10
+ gem "rubocop", "~> 1.60", require: false
11
+ end
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2023 Cory Davis
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,85 @@
1
+ ## Typewrite ##
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/typewrite.svg)](https://badge.fury.io/rb/typewrite)
4
+
5
+ Typewrite is a Ruby library that prints console messages "typewriter" style, or letter-by-letter.
6
+
7
+ ### Installation ###
8
+ #Installing as Ruby gem
9
+ $gem install typewrite
10
+
11
+ #Cloning the repsository
12
+ $git clone git@github.com:CJGlitter/typewrite.git
13
+ ### Usage ###
14
+
15
+ ```ruby
16
+ require "typewrite"
17
+ Typewrite.write("Your message here!")
18
+ ```
19
+
20
+ ### Options ###
21
+
22
+ The variable options include type rate, pause length, line breaks, and interrupt behavior. By default, the type rate is one character per 0.1 second with a 1.5 second pause after each punctuation character `['.','?','!']` with a new line after each message.
23
+
24
+ #### Basic Options
25
+
26
+ You can adjust the type rate and pause length with numbers and turn off the newlines with a boolean:
27
+
28
+ ```ruby
29
+ message = "Here's your message"
30
+ Typewrite.write(message, 0.05, 0, false)
31
+ ```
32
+
33
+ That would result in a message that types a character every 0.05 seconds with no punctuation pauses and no newlines after each message.
34
+
35
+ #### Interrupt Mode
36
+
37
+ You can allow users to skip the typewriter animation by pressing keys during output:
38
+
39
+ ```ruby
40
+ # Allow interruption with Enter key (default interrupt behavior)
41
+ Typewrite.write("Press ENTER to skip...", interrupt: true)
42
+ Typewrite.write("Press ENTER to skip...", interrupt: :enter)
43
+
44
+ # Allow interruption with any key
45
+ Typewrite.write("Press ANY key to skip...", interrupt: :any)
46
+
47
+ # Allow interruption with specific keys
48
+ Typewrite.write("Press Q, X, or SPACE to skip...", interrupt: ["q", "x", " "])
49
+ ```
50
+
51
+ When interrupted, the remaining text prints immediately so users see the complete message.
52
+
53
+ ## Development
54
+
55
+ ### Running Tests
56
+
57
+ ```bash
58
+ bundle install
59
+ bundle exec rake # Run tests + linting
60
+ bundle exec rspec # Run tests only
61
+ bundle exec rubocop # Run linting only
62
+ ```
63
+
64
+ ### Code Quality
65
+
66
+ This project uses RuboCop for linting. Please ensure your code passes linting before submitting a PR:
67
+
68
+ ```bash
69
+ bundle exec rubocop -A # Auto-fix issues
70
+ ```
71
+
72
+ ## Versioning
73
+
74
+ Typewrite follows the [Semantic Versioning](http://semver.org/) standard.
75
+
76
+ ### Contributing ###
77
+
78
+ Bug reports and pull requests are welcome on GitHub at https://github.com/CJGlitter/typewrite
79
+
80
+ ### License ###
81
+ Copywrite ©Cory Davis 2023
82
+
83
+ https://cjglitter.com
84
+
85
+ Released under the MIT license. See LICENSE file for details.
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rspec/core/rake_task"
4
+ require "rubocop/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+ RuboCop::RakeTask.new(:rubocop)
8
+
9
+ task default: %i[spec rubocop]
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Typewrite
4
+ VERSION = "1.2.0"
5
+ end
data/lib/typewrite.rb CHANGED
@@ -1,12 +1,101 @@
1
- class Typewrite
2
- def self.write(input, type_rate = 0.1, punc_rate = 1.5, line_break = true)
3
- input_array = input.split('')
4
- input_array.each do |char|
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "typewrite/version"
4
+ require "io/console"
5
+
6
+ # Prints console messages with a typewriter effect (letter-by-letter).
7
+ #
8
+ # @example Basic usage
9
+ # Typewrite.write("Hello, World!")
10
+ #
11
+ # @example Custom timing
12
+ # Typewrite.write("Fast typing", 0.05, 0.5, false)
13
+ #
14
+ module Typewrite
15
+ # Characters that trigger an extra pause
16
+ PUNCTUATION = [".", "?", "!"].freeze
17
+
18
+ # Prints a message with typewriter effect.
19
+ #
20
+ # @param input [String] the message to display
21
+ # @param type_rate [Float] seconds between each character (default: 0.1)
22
+ # @param punc_rate [Float] extra pause after punctuation (default: 1.5)
23
+ # @param line_break [Boolean] add newline at end (default: true)
24
+ # @param interrupt [Boolean, Symbol, Array] enable interrupt mode (default: false)
25
+ # - false: no interrupt (default)
26
+ # - true or :enter: interrupt on Enter key
27
+ # - :any: interrupt on any key
28
+ # - Array: interrupt on specific keys (e.g., ["q", "x", " "])
29
+ # @return [void]
30
+ def self.write(input, type_rate = 0.1, punc_rate = 1.5, line_break = true, interrupt: false)
31
+ return write_simple(input, type_rate, punc_rate, line_break) unless interrupt
32
+
33
+ write_interruptible(input, type_rate, punc_rate, line_break, interrupt)
34
+ end
35
+
36
+ # Simple non-interruptible write (original behavior)
37
+ #
38
+ # @param input [String] the message to display
39
+ # @param type_rate [Float] seconds between each character
40
+ # @param punc_rate [Float] extra pause after punctuation
41
+ # @param line_break [Boolean] add newline at end
42
+ # @return [void]
43
+ private_class_method def self.write_simple(input, type_rate, punc_rate, line_break)
44
+ input.each_char do |char|
5
45
  print char
6
- puncs = ['.','?','!',]
7
- sleep(punc_rate) if puncs.include?(char)
46
+ sleep(punc_rate) if PUNCTUATION.include?(char)
8
47
  sleep(type_rate)
9
48
  end
10
49
  print "\n" if line_break
11
50
  end
51
+
52
+ # Interruptible write with keyboard input detection
53
+ #
54
+ # @param input [String] the message to display
55
+ # @param type_rate [Float] seconds between each character
56
+ # @param punc_rate [Float] extra pause after punctuation
57
+ # @param line_break [Boolean] add newline at end
58
+ # @param interrupt_config [Boolean, Symbol, Array] interrupt configuration
59
+ # @return [void]
60
+ private_class_method def self.write_interruptible(input, type_rate, punc_rate, line_break, interrupt_config)
61
+ chars = input.chars
62
+ index = 0
63
+
64
+ $stdin.raw do |io|
65
+ while index < chars.length
66
+ # Check for keypress (non-blocking)
67
+ # rubocop:disable Lint/IncompatibleIoSelectWithFiberScheduler
68
+ if IO.select([io], nil, nil, 0)
69
+ # rubocop:enable Lint/IncompatibleIoSelectWithFiberScheduler
70
+ pressed = io.getc
71
+ if key_matches?(pressed, interrupt_config)
72
+ # Print remaining text immediately
73
+ print chars[index..].join
74
+ break
75
+ end
76
+ end
77
+
78
+ print chars[index]
79
+ sleep(punc_rate) if PUNCTUATION.include?(chars[index])
80
+ sleep(type_rate)
81
+ index += 1
82
+ end
83
+ end
84
+
85
+ print "\n" if line_break
86
+ end
87
+
88
+ # Checks if a pressed key matches the interrupt configuration
89
+ #
90
+ # @param char [String] the pressed character
91
+ # @param config [Boolean, Symbol, Array] interrupt configuration
92
+ # @return [Boolean] true if the key should trigger an interrupt
93
+ private_class_method def self.key_matches?(char, config)
94
+ case config
95
+ when true, :enter then ["\r", "\n"].include?(char)
96
+ when :any then true
97
+ when Array then config.include?(char)
98
+ else false
99
+ end
100
+ end
12
101
  end
data/typewrite.gemspec ADDED
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/typewrite/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "typewrite"
7
+ spec.version = Typewrite::VERSION
8
+ spec.authors = ["Cory Davis"]
9
+ spec.email = ["CSDavisMusic@gmail.com"]
10
+
11
+ spec.summary = "Typewriter effect for console output"
12
+ spec.description = "A simple gem to add a typewriter effect to console output."
13
+ spec.homepage = "https://github.com/CJGlitter/typewrite"
14
+ spec.license = "MIT"
15
+
16
+ spec.required_ruby_version = ">= 3.0.0"
17
+
18
+ spec.metadata = {
19
+ "homepage_uri" => spec.homepage,
20
+ "source_code_uri" => spec.homepage,
21
+ "changelog_uri" => "#{spec.homepage}/blob/main/CHANGELOG.md",
22
+ "bug_tracker_uri" => "#{spec.homepage}/issues",
23
+ "rubygems_mfa_required" => "true"
24
+ }
25
+
26
+ spec.files = Dir.chdir(__dir__) do
27
+ `git ls-files -z`.split("\x0").reject do |f|
28
+ f.match(%r{\A(?:test|spec|features)/})
29
+ end
30
+ end
31
+ spec.require_paths = ["lib"]
32
+ end
metadata CHANGED
@@ -1,28 +1,41 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: typewrite
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cory Davis
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2023-01-03 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies: []
13
12
  description: A simple gem to add a typewriter effect to console output.
14
- email: CSDavisMusic@gmail.com
13
+ email:
14
+ - CSDavisMusic@gmail.com
15
15
  executables: []
16
16
  extensions: []
17
17
  extra_rdoc_files: []
18
18
  files:
19
+ - ".github/workflows/ci.yml"
20
+ - ".rspec"
21
+ - ".rubocop.yml"
22
+ - CHANGELOG.md
23
+ - Gemfile
24
+ - LICENSE
25
+ - README.md
26
+ - Rakefile
19
27
  - lib/typewrite.rb
20
- homepage: https://rubygems.org/gems/typewrite
28
+ - lib/typewrite/version.rb
29
+ - typewrite.gemspec
30
+ homepage: https://github.com/CJGlitter/typewrite
21
31
  licenses:
22
32
  - MIT
23
33
  metadata:
34
+ homepage_uri: https://github.com/CJGlitter/typewrite
24
35
  source_code_uri: https://github.com/CJGlitter/typewrite
25
- post_install_message:
36
+ changelog_uri: https://github.com/CJGlitter/typewrite/blob/main/CHANGELOG.md
37
+ bug_tracker_uri: https://github.com/CJGlitter/typewrite/issues
38
+ rubygems_mfa_required: 'true'
26
39
  rdoc_options: []
27
40
  require_paths:
28
41
  - lib
@@ -30,15 +43,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
30
43
  requirements:
31
44
  - - ">="
32
45
  - !ruby/object:Gem::Version
33
- version: '0'
46
+ version: 3.0.0
34
47
  required_rubygems_version: !ruby/object:Gem::Requirement
35
48
  requirements:
36
49
  - - ">="
37
50
  - !ruby/object:Gem::Version
38
51
  version: '0'
39
52
  requirements: []
40
- rubygems_version: 3.3.7
41
- signing_key:
53
+ rubygems_version: 3.6.7
42
54
  specification_version: 4
43
- summary: Typewriter Effect!
55
+ summary: Typewriter effect for console output
44
56
  test_files: []