pretty_please 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 35a3e562b4bd340a6628de8a9c3533f2c28704b79df394864eadc91420a6dc01
4
+ data.tar.gz: b2ec7be1ae8b8f455a3571b2f5c98d2b83f876155013e2b72810a7bfc6a34e03
5
+ SHA512:
6
+ metadata.gz: 24c75e11a326b3e29c5025cdc661f446c706785f7b6921aac96d9f4dbc9ce63ba75c1264e69ee0d76434de5f4f93d192ae7956e8f9cab2f296c8e603e5368dd7
7
+ data.tar.gz: fd7a14399e83fe7d9eb05807b3126174bc54c5af1eed65ac3dd655f5e193cb85403defecf123a8c804ec122df1c02982bb3ddf67444927929ed376507f804108
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2025 Joel Drapper
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,73 @@
1
+ ## PrettyPlease - Pretty Print Ruby objects as Ruby
2
+
3
+ PrettyPlease is a pretty-printing library for Ruby that formats objects in a readable and structured way.
4
+
5
+ PrettyPlease ensures the output is **valid Ruby code**, making it human, machine, and [diff](https://github.com/joeldrapper/difftastic-ruby)-friendly.
6
+
7
+ > [!NOTE]
8
+ > PrettyPlease is used and was extracted from [`difftastic-ruby`](https://github.com/joeldrapper/difftastic-ruby).
9
+
10
+ ### Installation
11
+
12
+ Install the gem and add it to the application's `Gemfile` by executing:
13
+
14
+ ```shell
15
+ bundle add pretty_please
16
+ ```
17
+
18
+ If bundler is not being used to manage dependencies, install the gem by executing:
19
+
20
+ ```shell
21
+ gem install pretty_please
22
+ ```
23
+
24
+ ### Usage
25
+
26
+ `PrettyPlease.print(object)` prints the object with ANSI highlighting.
27
+
28
+ The `PrettyPlease.inspect` method provides a structured and human-readable representation of Ruby objects by outputting valid Ruby code.
29
+
30
+ It handles a variety of data types including Hashes, Arrays, Sets, Modules, and user-defined objects.
31
+
32
+ #### Basic Usage
33
+
34
+ ```ruby
35
+ require "pretty_please"
36
+
37
+ puts PrettyPlease.inspect({ a: 1, b: [2, 3], c: { d: 4 } })
38
+ ```
39
+
40
+ **Output:**
41
+
42
+ ```ruby
43
+ {
44
+ a: 1,
45
+ b: [2, 3],
46
+ c: { d: 4 },
47
+ }
48
+ ```
49
+
50
+ **Options:**
51
+
52
+ - `object`: (required) – The object to inspect and format.
53
+ - `tab_width`: 2 (Integer) – The number of spaces (or tabs) per indentation level.
54
+ - `max_width`: 60 (Integer) – The maximum width before elements are split into multiple lines.
55
+ - `max_depth`: 5 (Integer) – The maximum depth of nested structures before truncation.
56
+ - `max_instance_variables`: 10 (Integer) – The maximum number of instance variables to display for objects.
57
+
58
+ ### Development
59
+
60
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
61
+
62
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
63
+
64
+ ### Contributing
65
+
66
+ > [!WARNING]
67
+ > Object diffs in `assert_equal` test output are self-hosted. That means if you mess up the output, the tests might not tell you since they are driven by the output. Most of the tests use `assert_equal_ruby`, which is not driven by PrettyPlease.
68
+
69
+ Bug reports and pull requests are welcome on GitHub at https://github.com/joeldrapper/pretty_please. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/joeldrapper/pretty_please/blob/main/CODE_OF_CONDUCT.md).
70
+
71
+ ### Code of Conduct
72
+
73
+ Everyone interacting in the `PrettyPlease` project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/joeldrapper/pretty_please/blob/main/CODE_OF_CONDUCT.md).
@@ -0,0 +1,165 @@
1
+ # frozen_string_literal: true
2
+
3
+ class PrettyPlease::Inspect
4
+ Null = Object.new
5
+
6
+ def self.call(object, ...)
7
+ new(...).call(object)
8
+ end
9
+
10
+ def initialize(indent: 0, tab_width: 2, max_width: 30, max_items: 10, max_depth: 5)
11
+ @indent = indent
12
+ @tab_width = tab_width
13
+ @max_width = max_width
14
+ @max_items = max_items
15
+ @max_depth = max_depth
16
+ @indent_bytes = " " * @tab_width
17
+
18
+ @buffer = +""
19
+ @lines = 0 # note, this is not reset within a capture
20
+ @stack = []
21
+ @original_object = Null
22
+ end
23
+
24
+ def call(object)
25
+ inspect(object)
26
+ @buffer
27
+ end
28
+
29
+ def inspect(object)
30
+ original_object = @original_object
31
+
32
+ if original_object == Null
33
+ @original_object = object
34
+ else
35
+ if original_object.equal?(object)
36
+ push "self"
37
+ return
38
+ end
39
+ end
40
+
41
+ @stack.push(object)
42
+
43
+ if object.respond_to?(:pretty_please_inspect)
44
+ object.pretty_please_inspect(self)
45
+ else
46
+ case object
47
+ when Symbol, String, Integer, Float, Regexp, Range, Rational, Complex, TrueClass, FalseClass, NilClass
48
+ push object.inspect
49
+ when Module
50
+ push object.name
51
+ when Pathname, File
52
+ push %(#{object.class.name}("#{object.to_path}"))
53
+ when MatchData, (defined?(Date) && Date), (defined?(DateTime) && DateTime), (defined?(Time) && Time), (defined?(URI) && URI)
54
+ push %(#{object.class.name}("#{object}"))
55
+ when Array
56
+ push "["
57
+ map(object) { |it| capture { inspect(it) } }
58
+ push "]"
59
+ when Exception
60
+ push %(#{object.class.name}("#{object.message}"))
61
+ when Hash
62
+ push "{"
63
+ map(object, around_inline: " ") do |key, value|
64
+ case key
65
+ when Symbol
66
+ "#{key.name}: #{capture { inspect(value) }}"
67
+ else
68
+ key = capture { inspect(key) }
69
+ value = capture { inspect(value) }
70
+ "#{key} => #{value}"
71
+ end
72
+ end
73
+ push "}"
74
+ when Struct, defined?(Data) && Data
75
+ push "#{object.class.name}("
76
+ items = object.members.map { |key| [key, object.__send__(key)] }
77
+ map(items) { |key, value| "#{key}: #{capture { inspect(value) }}" }
78
+ push ")"
79
+ when defined?(Set) && Set
80
+ push "Set["
81
+ map(object.to_a.sort) { |it| capture { inspect(it) } }
82
+ push "]"
83
+ else
84
+ push "#{object.class.name}("
85
+ map(object.instance_variables) do |name|
86
+ "#{name} = #{capture { inspect(object.instance_variable_get(name)) }}"
87
+ end
88
+ push ")"
89
+ end
90
+ end
91
+
92
+ @stack.pop
93
+ end
94
+
95
+ def map(object, around_inline: nil)
96
+ if @stack.size >= @max_depth
97
+ push "..."
98
+ return
99
+ end
100
+
101
+ return unless object.any?
102
+
103
+ length = 0
104
+ length += around_inline.bytesize * 2 if around_inline
105
+
106
+ original_lines = @lines
107
+ exceeds_max_items = object.length > @max_items
108
+
109
+ items = indent do
110
+ object.take(@max_items).map do |item|
111
+ pretty_item = yield(item)
112
+ length += pretty_item.bytesize + 2 # for the ", "
113
+ pretty_item
114
+ end
115
+ end
116
+
117
+ if (@lines > original_lines) || (length > @max_width)
118
+ indent do
119
+ items.each do |item|
120
+ newline
121
+ push item
122
+ push ","
123
+ end
124
+
125
+ if exceeds_max_items
126
+ newline
127
+ push "..."
128
+ end
129
+ end
130
+ newline
131
+
132
+ else
133
+ push around_inline
134
+ push items.join(", ")
135
+ push ", ..." if exceeds_max_items
136
+ push around_inline
137
+ end
138
+ end
139
+
140
+ def indent
141
+ @indent += 1
142
+ value = yield
143
+ @indent -= 1
144
+ value
145
+ end
146
+
147
+ def newline
148
+ @lines += 1
149
+ push "\n#{@indent_bytes * @indent}"
150
+ end
151
+
152
+ def push(string)
153
+ return unless string
154
+ @buffer << string
155
+ end
156
+
157
+ def capture
158
+ original_buffer = @buffer
159
+ new_buffer = +""
160
+ @buffer = new_buffer
161
+ yield
162
+ @buffer = original_buffer
163
+ new_buffer
164
+ end
165
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PrettyPlease
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pretty_please/version"
4
+ require "dispersion"
5
+
6
+ module PrettyPlease
7
+ autoload :Inspect, "pretty_please/inspect"
8
+
9
+ def self.print(object)
10
+ puts Dispersion.ansi(inspect(object))
11
+ end
12
+
13
+ def self.inspect(...)
14
+ Inspect::(...)
15
+ end
16
+ end
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pretty_please
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Joel Drapper
8
+ - Marco Roth
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2025-02-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: dispersion
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.2'
27
+ description: Print Ruby objects as Ruby
28
+ email:
29
+ - joel@drapper.me
30
+ - marco.roth@intergga.ch
31
+ executables: []
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - LICENSE.txt
36
+ - README.md
37
+ - lib/pretty_please.rb
38
+ - lib/pretty_please/inspect.rb
39
+ - lib/pretty_please/version.rb
40
+ homepage: https://github.com/joeldrapper/pretty_please
41
+ licenses:
42
+ - MIT
43
+ metadata:
44
+ homepage_uri: https://github.com/joeldrapper/pretty_please
45
+ source_code_uri: https://github.com/joeldrapper/pretty_please
46
+ funding_uri: https://github.com/sponsors/joeldrapper
47
+ rubygems_mfa_required: 'true'
48
+ rdoc_options: []
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '3.1'
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ requirements: []
62
+ rubygems_version: 3.6.2
63
+ specification_version: 4
64
+ summary: Print Ruby objects as Ruby
65
+ test_files: []