hummel 0.1.0 → 0.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: 51c766a08cd0ff86bb1c6e7b24015ac5a0dcb7bccfce1afd50b97943d5e2b2e4
4
- data.tar.gz: ca7137d3dfe54500e91f34cc83f295b35096a688690168a13edcab8071522d33
3
+ metadata.gz: 4b63f273b7a493c53d0d0bdfad24ee9a273005cb0bc63cd81605d8bfd6f660dc
4
+ data.tar.gz: 446cb68dbfdf83a1182c88dcdeb40250548fc41a61bbe3f7fe440383591d0032
5
5
  SHA512:
6
- metadata.gz: 16a70da398fb107964d014cd393a18417fc6112d7bbb854f72297e9626ef718b196bd8b6a128f95c23444c4db95b81add9708d2aa19e55b8fdf1a7fc2773f275
7
- data.tar.gz: 28018bb7b58fcc429a53c8001ea643d62331aeec9432a8aa267a8c7ab03c3b1a7e1f9a4263d83621cd8b893e8067255b31918abf3d4d3529fbbc05a84ab9d5fa
6
+ metadata.gz: 6c5d709a0459493125a4caea694b7b89f93f8511207d9ff2e3a41d2389608f416860781a2b1d10633ccde5ea44aa87fee18f1dc041d49e243d50dc11b1861bac
7
+ data.tar.gz: 5a04eb2f91d13e99c060980e123f17447be47813579165c3ab6653accb6219c4dead58e5d71e5f399dfffcdef99cf54eadc190a1640329ec69475fec9fb77229
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 3.4.7
1
+ 4.0.1
data/CHANGELOG.md CHANGED
@@ -1,5 +1,39 @@
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.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
1
8
  ## [Unreleased]
2
9
 
10
+ ## [0.2.0] - 2026-02-16
11
+
12
+ ### Changed
13
+ - Update parser and encoder to HUML v0.2.0 spec
14
+ - Remove triple-backtick multiline string syntax
15
+ - Triple-quote `"""` multiline strings now preserve relative indentation (strip uniform indent)
16
+ - Enforce strict indentation for multiline vectors inside list items
17
+
18
+ ### Internal
19
+ - Abort test suite early if `tests/` submodule is missing
20
+
21
+ ## [0.1.1] - 2025-10-12
22
+
23
+ ### Changed
24
+ - Improve code coverage and remove dead code
25
+ - Update README.md with naming scheme and fixes
26
+
27
+ ### Fixed
28
+ - Fix README example
29
+
30
+ ### Internal
31
+ - Achieve 100% code coverage
32
+ - Add code coverage tracking with SimpleCov
33
+ - Update CI workflow with permissions and coverage upload
34
+ - Add matrix.ruby to artifact naming
35
+ - Add workflow_dispatch trigger to CI
36
+
3
37
  ## [0.1.0] - 2025-10-12
4
38
 
5
39
  - Initial release
data/README.md CHANGED
@@ -1,15 +1,13 @@
1
- # hummel
1
+ # Hummel
2
2
 
3
- An HUML parser implementation in ruby.
4
-
5
- > **Note:** The gem is named `hummel` because `huml` was already taken on rubygems.org.
3
+ An [HUML](https://huml.io) parser implementation in ruby.
6
4
 
7
5
  ## Installation
8
6
 
9
7
  Add this line to your application's Gemfile:
10
8
 
11
9
  ```ruby
12
- gem 'hummel', source: 'https://gem.coop'
10
+ gem 'hummel'
13
11
  ```
14
12
 
15
13
  And then execute:
@@ -21,7 +19,7 @@ bundle install
21
19
  Or install it yourself as:
22
20
 
23
21
  ```bash
24
- gem install hummel --source https://gem.coop
22
+ gem install hummel
25
23
  ```
26
24
 
27
25
  ## Usage
@@ -32,9 +30,9 @@ gem install hummel --source https://gem.coop
32
30
  require 'hummel'
33
31
 
34
32
  huml_string = <<~HUML
35
- name: John Doe
33
+ name: "John Doe"
36
34
  age: 30
37
- email: john@example.com
35
+ email: "john@example.com"
38
36
  HUML
39
37
 
40
38
  data = Hummel::Decode.parse(huml_string)
@@ -80,7 +78,24 @@ Hummel::Encode.stringify(data, include_version: true)
80
78
 
81
79
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
82
80
 
83
- 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 [gem.coop](https://gem.coop).
81
+ To install this gem onto your local machine, run `bin/rake install`.
82
+
83
+ To release a new version:
84
+
85
+ 1. Run tests and linters: `bin/rake` and address any issues in separate commits.
86
+ 2. Update the version number in `lib/hummel/version.rb`.
87
+ 3. Update the `CHANGELOG.md` to include this version and brief summaries of changes.
88
+ 4. Commit changes:
89
+
90
+ git add lib/hummel/version.rb CHANGELOG.md
91
+ git commit -m "Bump version to 0.2.0"
92
+
93
+ 5. Run `bin/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).
94
+ 6. Create a GitHub Release from the tag with the CHANGELOG.md notes.
95
+
96
+ > **Note**: In follow up commits to this release please re-add the [Unreleased] section to CHANGELOG.md for future work.
97
+
98
+ > **Note**: Make sure you're authed with rubygems.org via `gem signin` before running the release command.
84
99
 
85
100
  ## Contributing
86
101
 
@@ -93,3 +108,7 @@ The gem is available as open source under the terms of the [MIT License](https:/
93
108
  ## Code of Conduct
94
109
 
95
110
  Everyone interacting in the Hummel project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/djbender/hummel/blob/main/CODE_OF_CONDUCT.md).
111
+
112
+ ## Name
113
+
114
+ This gem is named `hummel` because `huml` was already taken on [rubygems.org](https://rubygems.org).
data/lib/hummel/decode.rb CHANGED
@@ -78,8 +78,8 @@ module Hummel
78
78
 
79
79
  if pos > starting_pos
80
80
  version = data[starting_pos...pos]
81
- if version != "v0.1.0"
82
- raise error("unsupported version '#{version}'. expected 'v0.1.0'")
81
+ if version != "v0.2.0"
82
+ raise error("unsupported version '#{version}'. expected 'v0.2.0'")
83
83
  end
84
84
  end
85
85
  end
@@ -178,7 +178,7 @@ module Hummel
178
178
  result[key] = if indicator == ":"
179
179
  assert_space("after ':'")
180
180
 
181
- multiline = peek_string("```") || peek_string('""""')
181
+ multiline = peek_string('"""')
182
182
 
183
183
  value = parse_value(current_indent)
184
184
 
@@ -249,6 +249,10 @@ module Hummel
249
249
  vector_type = multiline_vector_type(indent)
250
250
  next_indent = current_indent
251
251
 
252
+ if next_indent != indent
253
+ raise error("bad indent #{next_indent}, expected #{indent}")
254
+ end
255
+
252
256
  parse_multiline_method = method(:"parse_multiline_#{vector_type}")
253
257
  return parse_multiline_method.call(next_indent)
254
258
  end
@@ -364,11 +368,11 @@ module Hummel
364
368
  character = data[self.pos]
365
369
 
366
370
  if character == '"'
367
- return peek_string('"""') ? parse_multiline_string(key_indent, false) : parse_string
371
+ return peek_string('"""') ? parse_multiline_string(key_indent) : parse_string
368
372
  end
369
373
 
370
374
  if character == "`" && peek_string("```")
371
- return parse_multiline_string(key_indent, true)
375
+ raise error("backtick multiline strings are not supported in HUML v0.2.0")
372
376
  end
373
377
 
374
378
  SPECIAL_VALUES.each do |string, value|
@@ -450,24 +454,19 @@ module Hummel
450
454
  raise error("unclosed string")
451
455
  end
452
456
 
453
- def parse_multiline_string(key_indent, preserve_spaces)
457
+ def parse_multiline_string(key_indent)
454
458
  delimiter = data[pos, 3]
455
459
  advance(3)
456
460
  consume_line
457
461
 
458
- # define line processing base on string type
459
- process_line = if preserve_spaces
460
- ->(content, line_indent) do
461
- # strip required 2-space indent relative to key
462
- required_indent = key_indent + 2
463
- if content.length >= required_indent && space_string?(content[0, required_indent])
464
- return content[required_indent..]
465
- end
466
-
467
- content
462
+ # strip required 2-space indent relative to key
463
+ required_indent = key_indent + 2
464
+ process_line = ->(content, _line_indent) do
465
+ if content.length >= required_indent && space_string?(content[0, required_indent])
466
+ return content[required_indent..]
468
467
  end
469
- else
470
- ->(content, _line_indent) { content.strip }
468
+
469
+ content
471
470
  end
472
471
 
473
472
  lines = []
@@ -515,7 +514,7 @@ module Hummel
515
514
 
516
515
  NUMBER_BASE_PREFIXES.each do |prefix, base|
517
516
  if peek_string(prefix)
518
- parse_base(start: starting_pos, base: base, prefix:)
517
+ return parse_base(start: starting_pos, base: base, prefix:)
519
518
  end
520
519
  end
521
520
 
@@ -579,10 +578,7 @@ module Hummel
579
578
  line_start = self.pos
580
579
  skip_spaces
581
580
 
582
- if done?
583
- raise error("trailing spaces are not allowed") if self.pos > line_start
584
- return
585
- end
581
+ raise error("trailing spaces are not allowed") if done?
586
582
 
587
583
  if !["\n", "#"].include?(data[self.pos])
588
584
  return # Found content
@@ -714,9 +710,7 @@ module Hummel
714
710
  current_pos = pos
715
711
  while current_pos < data.length && !["\n", "#"].include?(data[current_pos])
716
712
  if data[current_pos] == ":"
717
- if current_pos + 1 >= data.length || data[current_pos + 1] != ":"
718
- return true
719
- end
713
+ return true
720
714
  end
721
715
  current_pos += 1
722
716
  end
@@ -733,12 +727,12 @@ module Hummel
733
727
  end
734
728
 
735
729
  def inline_dict_at_root?
736
- line_end = data.index("\n", pos) || data.length
737
- comment_index = data.index("#", pos) || data.length
730
+ line_end = data.index("\n", pos)
731
+ comment_index = data.index("#", pos)
738
732
 
739
733
  marker = [
740
- line_end,
741
- comment_index
734
+ line_end || data.length,
735
+ comment_index || data.length
742
736
  ].min
743
737
 
744
738
  line = data[pos...marker]
@@ -747,13 +741,15 @@ module Hummel
747
741
 
748
742
  return false unless has_colon && has_comma
749
743
 
750
- remaining_content = if line_end != -1
751
- data[0...line_end]
744
+ remaining_content = if line_end.nil?
745
+ # Single-line input, no subsequent lines
746
+ false
752
747
  else
753
- data
754
- end.split("\n")[1..].any? do |line|
755
- trimmed = line.strip
756
- trimmed && !trimmed.start_with?("#")
748
+ # Multi-line input, check if subsequent lines have non-comment content
749
+ data.split("\n")[1..].any? do |line|
750
+ trimmed = line.strip
751
+ trimmed && !trimmed.start_with?("#")
752
+ end
757
753
  end
758
754
 
759
755
  !remaining_content
@@ -813,8 +809,6 @@ module Hummel
813
809
  end
814
810
 
815
811
  def skip_first
816
- return unless block_given?
817
-
818
812
  @first = true if @first.nil?
819
813
  yield unless @first
820
814
  @first = false
data/lib/hummel/encode.rb CHANGED
@@ -9,7 +9,7 @@ module Hummel
9
9
  # Convert a Ruby object to HUML format
10
10
  def stringify(obj, cfg = {})
11
11
  lines = []
12
- lines.concat(["%HUML v0.1.0", ""]) if cfg[:include_version]
12
+ lines.concat(["%HUML v0.2.0", ""]) if cfg[:include_version]
13
13
 
14
14
  lines.concat(encode_value(obj, 0, true))
15
15
  lines << "" # Ensure document ends with newline
@@ -25,6 +25,7 @@ module Hummel
25
25
  def encode_value(value, indent, is_root_level = false)
26
26
  return ["null"] if value.nil?
27
27
 
28
+ # TODO: dynamic dispatch refactor?
28
29
  case value
29
30
  when TrueClass, FalseClass
30
31
  [value.to_s]
@@ -58,9 +59,8 @@ module Hummel
58
59
 
59
60
  # Multi-line string
60
61
  str_lines = str.split("\n")
61
- str_lines.pop if str_lines.last && str_lines.last.empty?
62
62
 
63
- ["```"] + str_lines.map { |line| "#{" " * indent}#{line}" } + ["#{" " * (indent - 2)}```"]
63
+ ['"""'] + str_lines.map { |line| "#{" " * indent}#{line}" } + ["#{" " * (indent - 2)}\"\"\""]
64
64
  end
65
65
 
66
66
  # Encode an array value - returns array of lines
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Hummel
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hummel
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
  - Derek Bender
@@ -54,7 +54,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
54
54
  - !ruby/object:Gem::Version
55
55
  version: '0'
56
56
  requirements: []
57
- rubygems_version: 3.6.9
57
+ rubygems_version: 4.0.4
58
58
  specification_version: 4
59
59
  summary: A Ruby parser and encoder for HUML (Human Markup Language)
60
60
  test_files: []