comicinfo 1.0.0 โ†’ 2.0.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: f66dfb29761ad9d67b58cb229eeb3806205ecc417162830fa7688075b7886fba
4
- data.tar.gz: bec2db8b6b877f0f6b35a7e3123653a7216dc653d847bcd16fa1112b5fe896a2
3
+ metadata.gz: ed9c12d2685a70526b85e3be44e9524720b7f90bba6548a09541290df18bdbf7
4
+ data.tar.gz: 9856df6a2adbc6a7e81381992b7ae7c1fae68f184b47400f68a95fbe9ab7ac63
5
5
  SHA512:
6
- metadata.gz: f3094240a2e409a5dd41834ba35c2a4cc3ce73ad0e834b14db06d93dd344629dc318dba0760d1a1f8e56a7e6876832d9422b9d34264caca489ea2561f05eda37
7
- data.tar.gz: 9de5a0f9c1f14a79139fa6837051a290deb5a1fb43eaa0dc2631153466daf2659d9914befae597669a5fd7c7198496ef5245f28a9554b957aada6ace71d4589e
6
+ metadata.gz: 6ca41d4b00d7413aec6d2d78297a17c828fcd2ae79f9309b89fe7aebbf575ed2ed4970f09c620d558d89befde9991092a4d629b168675a5724f6602a6dcff49a
7
+ data.tar.gz: 329402c1d139d5668651834900a2ba08c463cda8d258b3161fc2a1b73e4b34dcb76d3ea5c6449a1310b8449326c098e0206da750570a4797dc86e0502945fc4b
data/CHANGELOG.md CHANGED
@@ -5,6 +5,40 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [2.0.0] - 2025-11-10
9
+
10
+ ### Added
11
+ - **XML Generation**: Complete ComicInfo XML writing functionality
12
+ - `ComicInfo::Issue#to_xml` method for generating XML strings
13
+ - `ComicInfo::Issue#save(file_path_or_io)` method for writing to files or IO objects
14
+ - Valid ComicInfo v2.0 compliant XML output with UTF-8 encoding and schema namespaces
15
+ - Only includes non-default/non-empty values for clean XML output
16
+ - Proper XML entity escaping for special characters
17
+ - Full Pages section generation with all page attributes
18
+ - Round-trip consistency (load -> save -> load maintains data integrity)
19
+
20
+ ### Changed - BREAKING
21
+ - **Multi-value field method naming**: Changed from singular/plural pattern to plural/raw_data pattern
22
+ - Plural methods (e.g., `genres`, `characters`) now return arrays
23
+ - Raw data methods (e.g., `genres_raw_data`, `characters_raw_data`) return original comma-separated strings
24
+ - Singular schema elements now alias to plural methods (e.g., `genre` aliases to `genres`)
25
+ - Export hashes include both raw data keys and _raw_data keys with duplicate values for backward compatibility
26
+ - This affects: `genre`/`genres`, `character`/`characters`, `team`/`teams`, `location`/`locations`, `story_arc`/`story_arcs`, `story_arc_number`/`story_arc_numbers`
27
+
28
+ ### Migration Guide
29
+ - Replace `.genre` calls with `.genres` (now returns array) or `.genres_raw_data` (for string)
30
+ - Replace `.character` calls with `.characters_raw_data` (for string) - `.characters` was already array
31
+ - Replace `.team` calls with `.teams_raw_data` (for string) - `.teams` was already array
32
+ - Replace `.location` calls with `.locations_raw_data` (for string) - `.locations` was already array
33
+ - Replace `.story_arc` calls with `.story_arcs` (now returns array) or `.story_arcs_raw_data` (for string)
34
+ - Replace `.story_arc_number` calls with `.story_arc_numbers` (now returns array) or `.story_arc_numbers_raw_data` (for string)
35
+
36
+ ### Export Hash Changes
37
+ - Hash exports now include both `:genre` and `:genres_raw_data` keys with identical raw string values
38
+ - Hash exports now include both `:story_arc` and `:story_arcs_raw_data` keys with identical raw string values
39
+ - Hash exports now include both `:story_arc_number` and `:story_arc_numbers_raw_data` keys with identical raw string values
40
+ - This maintains backward compatibility while supporting the new API design
41
+
8
42
  ## [1.0.0] - 2025-10-05
9
43
 
10
44
  ### Added
@@ -33,7 +67,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
33
67
  - **Pages**: Complete page object model with type predicates and attributes
34
68
  - **Multi-value**: Smart handling of comma/space-separated field values
35
69
 
36
- ## [0.1.0] - 2025-01-XX
70
+ ## [0.1.0] - 2025-10-05
37
71
 
38
72
  ### Added
39
73
  - Initial project structure
data/README.md CHANGED
@@ -17,7 +17,8 @@ following the official ComicInfo schema specifications from the
17
17
  - ๐Ÿ“– **Manga Support**: Right-to-left reading direction and manga-specific fields
18
18
  - โœ… **Comprehensive Validation**: Schema-compliant enum validation and type coercion
19
19
  - ๐Ÿšจ **Detailed Error Handling**: Custom exception classes with helpful error messages
20
- - ๐Ÿ“Š **Export Support**: JSON and YAML serialization with hash representation (in progress)
20
+ - ๐Ÿ“Š **Export Support**: JSON, YAML, and XML serialization with hash representation
21
+ - โœ๏ธ **XML Generation**: Complete ComicInfo.xml writing with round-trip consistency
21
22
 
22
23
  ## Installation
23
24
 
@@ -108,6 +109,16 @@ teams = comic.teams #=> ["Avengers"]
108
109
  locations = comic.locations #=> ["New York City", "Manhattan", ...]
109
110
  genres = comic.genres #=> ["Superhero", "Action", "Adventure"]
110
111
  web_urls = comic.web_urls #=> ["https://marvel.com/...", "https://comicvine.com/..."]
112
+
113
+ # Raw data methods for original comma-separated strings
114
+ genres_raw = comic.genres_raw_data #=> "Superhero, Action, Adventure"
115
+ characters_raw = comic.characters_raw_data #=> "Spider-Man, Peter Parker, J. Jonah Jameson, Aunt May"
116
+ story_arcs_raw = comic.story_arcs_raw_data #=> "Brand New Day, Spider-Island"
117
+
118
+ # Singular schema elements alias to plural arrays
119
+ genre = comic.genre #=> ["Superhero", "Action", "Adventure"] (same as genres)
120
+ story_arc = comic.story_arc #=> ["Brand New Day", "Spider-Island"] (same as story_arcs)
121
+ story_arc_num = comic.story_arc_number #=> ["1", "5"] (same as story_arc_numbers)
111
122
  ```
112
123
 
113
124
  ### Working with Pages
@@ -131,7 +142,7 @@ puts page.deleted? #=> true for Deleted pages
131
142
 
132
143
  ```ruby
133
144
  # Load a manga ComicInfo file
134
- manga = ComicInfo.load 'path/to/manga/ComicInfo.xml')
145
+ manga = ComicInfo.load 'path/to/manga/ComicInfo.xml'
135
146
 
136
147
  puts manga.title #=> "้€ฒๆ’ƒใฎๅทจไบบ"
137
148
  puts manga.series #=> "Attack on Titan"
@@ -167,9 +178,17 @@ This gem fully supports the ComicInfo v2.0 XSD schema with all field types:
167
178
  ### String Fields
168
179
  - Title, Series, Number, Summary, Notes
169
180
  - Creator fields (Writer, Penciller, Inker, Colorist, Letterer, CoverArtist, Editor, Translator)
170
- - Publication fields (Publisher, Imprint, Genre, Web, LanguageISO, Format)
171
- - Character/Location fields (Characters, Teams, Locations, MainCharacterOrTeam)
172
- - Story fields (StoryArc, StoryArcNumber, SeriesGroup, ScanInformation, Review)
181
+ - Publication fields (Publisher, Imprint, Web, LanguageISO, Format)
182
+ - Character/Location fields (MainCharacterOrTeam)
183
+ - Story fields (SeriesGroup, ScanInformation, Review)
184
+
185
+ ### Multi-value Fields (String + Array Access)
186
+ - Genre/Genres: Raw comma-separated string + parsed array
187
+ - Characters: Raw comma-separated string + parsed array
188
+ - Teams: Raw comma-separated string + parsed array
189
+ - Locations: Raw comma-separated string + parsed array
190
+ - StoryArc/StoryArcs: Raw comma-separated string + parsed array
191
+ - StoryArcNumber/StoryArcNumbers: Raw comma-separated string + parsed array
173
192
 
174
193
  ### Integer Fields
175
194
  - Count, Volume, AlternateCount, PageCount
@@ -190,9 +209,10 @@ This gem fully supports the ComicInfo v2.0 XSD schema with all field types:
190
209
  ### Export Formats
191
210
  - **JSON**: Complete serialization with all fields
192
211
  - **YAML**: Human-readable format with array structures
212
+ - **XML**: Valid ComicInfo v2.0 compliant XML generation
193
213
  - **Hash**: Ruby hash representation with symbol keys
194
214
 
195
- ### Data Export
215
+ ### Data Export & XML Generation
196
216
 
197
217
  ```ruby
198
218
  comic = ComicInfo.load 'path/to/ComicInfo.xml'
@@ -205,11 +225,27 @@ puts JSON.pretty_generate(JSON.parse(json_string))
205
225
  yaml_string = comic.to_yaml
206
226
  puts yaml_string
207
227
 
228
+ # Generate XML
229
+ xml_string = comic.to_xml
230
+ puts xml_string
231
+
232
+ # Save to file
233
+ comic.save 'path/to/new/ComicInfo.xml'
234
+
235
+ # Save to IO object
236
+ File.open('path/to/new/ComicInfo.xml', 'w') do |file|
237
+ comic.save file
238
+ end
239
+
208
240
  # Export as Hash
209
241
  hash = comic.to_h
210
- puts hash[:title] #=> "The Amazing Spider-Man"
211
- puts hash[:characters] #=> ["Spider-Man", "Peter Parker", ...]
212
- puts hash[:pages].length #=> 12
242
+ puts hash[:title] #=> "The Amazing Spider-Man"
243
+ puts hash[:genre] #=> "Superhero, Action, Adventure" (raw data)
244
+ puts hash[:genres] #=> ["Superhero", "Action", "Adventure"] (parsed array)
245
+ puts hash[:genres_raw_data] #=> "Superhero, Action, Adventure" (same as :genre)
246
+ puts hash[:characters] #=> ["Spider-Man", "Peter Parker", ...]
247
+ puts hash[:characters_raw_data] #=> "Spider-Man, Peter Parker, J. Jonah Jameson, Aunt May"
248
+ puts hash[:pages].length #=> 12
213
249
  ```
214
250
 
215
251
  ## Development
@@ -252,18 +288,18 @@ bundle exec rubocop --autocorrect
252
288
 
253
289
  ### Current Features โœ…
254
290
  - **Core Reading**: Complete ComicInfo.xml parsing
291
+ - **XML Writing**: Full ComicInfo.xml generation with round-trip consistency
255
292
  - **Schema Compliance**: Full ComicInfo v2.0 support
256
293
  - **Field Types**: String, Integer, Decimal, Enum, Boolean, Arrays
257
294
  - **Multi-value Fields**: Both string and array access methods
258
295
  - **Issue &Page Support**: Complete Issue and nested Page objects
259
296
  - **Error Handling**: Custom exceptions with detailed messages
260
- - **Data Export**: JSON and YAML serialization
297
+ - **Data Export**: JSON, YAML, and XML serialization
261
298
  - **Validation**: Enum values, ranges, type coercion
262
299
  - **Unicode Support**: International characters and special symbols
263
- - **Test Coverage**: 156 comprehensive test cases
300
+ - **Test Coverage**: 178 comprehensive test cases
264
301
 
265
302
  ### Planned Features ๐Ÿšง
266
- - **XML Generation**: Writing ComicInfo.xml files
267
303
  - **CLI Tool**: Command-line interface for file manipulation
268
304
  - **Schema Migration**: Support for multiple ComicInfo versions
269
305
 
@@ -48,6 +48,7 @@ module ComicInfo
48
48
  DEFAULT_PAGE_TYPE = 'Story'.freeze
49
49
  DEFAULT_DOUBLE_PAGE = false
50
50
  DEFAULT_IMAGE_SIZE = 0
51
+ DEFAULT_COMMUNITY_RATING = -1.0
51
52
 
52
53
  # Validation methods
53
54
  module Validators
@@ -2,6 +2,7 @@ require 'nokogiri'
2
2
  require 'date'
3
3
  require 'json'
4
4
  require 'yaml'
5
+ require 'fileutils'
5
6
  require_relative 'enums'
6
7
  require_relative 'errors'
7
8
  require_relative 'page'
@@ -11,12 +12,10 @@ module ComicInfo
11
12
  # Follows the ComicInfo XSD schema v2.0 specification
12
13
  class Issue
13
14
  # String fields from ComicInfo schema
14
- attr_reader :title, :series, :number, :alternate_series, :alternate_number,
15
- :summary, :notes, :writer, :penciller, :inker, :colorist,
16
- :letterer, :cover_artist, :editor, :translator, :publisher,
17
- :imprint, :genre, :web, :language_iso, :format, :character,
18
- :team, :location, :scan_information, :story_arc, :story_arc_number,
19
- :series_group, :main_character_or_team, :review
15
+ attr_reader :alternate_number, :alternate_series, :colorist, :cover_artist, :editor,
16
+ :format, :imprint, :inker, :language_iso, :letterer, :main_character_or_team,
17
+ :notes, :number, :penciller, :publisher, :review, :scan_information, :series,
18
+ :series_group, :summary, :title, :translator, :web, :writer
20
19
 
21
20
  # Integer fields from ComicInfo schema
22
21
  attr_reader :count, :volume, :alternate_count, :year, :month, :day, :page_count
@@ -137,34 +136,115 @@ module ComicInfo
137
136
  end
138
137
 
139
138
  # Plural methods that return arrays
140
- def genres
141
- split_comma_separated(@genre)
142
- end
143
-
144
- def characters
145
- split_comma_separated(@character)
146
- end
139
+ def genres = split_comma_separated @genre
140
+ def characters = split_comma_separated @character
141
+ def teams = split_comma_separated @team
142
+ def locations = split_comma_separated @location
143
+ def story_arcs = split_comma_separated @story_arc
144
+ def story_arc_numbers = split_comma_separated @story_arc_number
147
145
 
148
- def teams
149
- split_comma_separated(@team)
150
- end
146
+ def web_urls
147
+ return [] if @web.empty?
151
148
 
152
- def locations
153
- split_comma_separated(@location)
149
+ @web.split(/\s+/)
154
150
  end
155
151
 
156
- def story_arcs
157
- split_comma_separated(@story_arc)
158
- end
152
+ # Raw data methods that return the original string values
153
+ def genres_raw_data = @genre
154
+ def characters_raw_data = @character
155
+ def teams_raw_data = @team
156
+ def locations_raw_data = @location
157
+ def story_arcs_raw_data = @story_arc
158
+ def story_arc_numbers_raw_data = @story_arc_number
159
+
160
+ # Singular aliases for schema elements that are singular
161
+ alias genre genres
162
+ alias story_arc story_arcs
163
+ alias story_arc_number story_arc_numbers
164
+
165
+ # Convert to XML representation
166
+ def to_xml
167
+ doc = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
168
+ xml.ComicInfo('xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
169
+ 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema') do
170
+ # String fields in schema order
171
+ xml.Title(@title) unless @title == Enums::DEFAULT_STRING
172
+ xml.Series(@series) unless @series == Enums::DEFAULT_STRING
173
+ xml.Number(@number) unless @number == Enums::DEFAULT_STRING
174
+ xml.Count(@count) unless @count == Enums::DEFAULT_INTEGER
175
+ xml.Volume(@volume) unless @volume == Enums::DEFAULT_INTEGER
176
+ xml.AlternateSeries(@alternate_series) unless @alternate_series == Enums::DEFAULT_STRING
177
+ xml.AlternateNumber(@alternate_number) unless @alternate_number == Enums::DEFAULT_STRING
178
+ xml.AlternateCount(@alternate_count) unless @alternate_count == Enums::DEFAULT_INTEGER
179
+ xml.Summary(@summary) unless @summary == Enums::DEFAULT_STRING
180
+ xml.Notes(@notes) unless @notes == Enums::DEFAULT_STRING
181
+ xml.Year(@year) unless @year == Enums::DEFAULT_INTEGER
182
+ xml.Month(@month) unless @month == Enums::DEFAULT_INTEGER
183
+ xml.Day(@day) unless @day == Enums::DEFAULT_INTEGER
184
+ xml.Writer(@writer) unless @writer == Enums::DEFAULT_STRING
185
+ xml.Penciller(@penciller) unless @penciller == Enums::DEFAULT_STRING
186
+ xml.Inker(@inker) unless @inker == Enums::DEFAULT_STRING
187
+ xml.Colorist(@colorist) unless @colorist == Enums::DEFAULT_STRING
188
+ xml.Letterer(@letterer) unless @letterer == Enums::DEFAULT_STRING
189
+ xml.CoverArtist(@cover_artist) unless @cover_artist == Enums::DEFAULT_STRING
190
+ xml.Editor(@editor) unless @editor == Enums::DEFAULT_STRING
191
+ xml.Translator(@translator) unless @translator == Enums::DEFAULT_STRING
192
+ xml.Publisher(@publisher) unless @publisher == Enums::DEFAULT_STRING
193
+ xml.Imprint(@imprint) unless @imprint == Enums::DEFAULT_STRING
194
+ xml.Genre(@genre) unless @genre == Enums::DEFAULT_STRING
195
+ xml.Web(@web) unless @web == Enums::DEFAULT_STRING
196
+ xml.PageCount(@page_count) unless @page_count == Enums::DEFAULT_PAGE_COUNT
197
+ xml.LanguageISO(@language_iso) unless @language_iso == Enums::DEFAULT_STRING
198
+ xml.Format(@format) unless @format == Enums::DEFAULT_STRING
199
+ xml.BlackAndWhite(@black_and_white) unless @black_and_white == Enums::DEFAULT_ENUM_UNKNOWN
200
+ xml.Manga(@manga) unless @manga == Enums::DEFAULT_ENUM_UNKNOWN
201
+ xml.Characters(@character) unless @character == Enums::DEFAULT_STRING
202
+ xml.Teams(@team) unless @team == Enums::DEFAULT_STRING
203
+ xml.Locations(@location) unless @location == Enums::DEFAULT_STRING
204
+ xml.ScanInformation(@scan_information) unless @scan_information == Enums::DEFAULT_STRING
205
+ xml.StoryArc(@story_arc) unless @story_arc == Enums::DEFAULT_STRING
206
+ xml.StoryArcNumber(@story_arc_number) unless @story_arc_number == Enums::DEFAULT_STRING
207
+ xml.SeriesGroup(@series_group) unless @series_group == Enums::DEFAULT_STRING
208
+ xml.AgeRating(@age_rating) unless @age_rating == Enums::DEFAULT_ENUM_UNKNOWN
209
+ xml.MainCharacterOrTeam(@main_character_or_team) unless @main_character_or_team == Enums::DEFAULT_STRING
210
+ xml.CommunityRating(@community_rating) unless @community_rating.nil?
211
+ xml.Review(@review) unless @review == Enums::DEFAULT_STRING
212
+
213
+ # Pages section
214
+ if @pages && !@pages.empty?
215
+ xml.Pages do
216
+ @pages.each do |page|
217
+ xml.Page(page.to_xml_attributes)
218
+ end
219
+ end
220
+ end
221
+ end
222
+ end
159
223
 
160
- def story_arc_numbers
161
- split_comma_separated(@story_arc_number)
224
+ doc.to_xml
162
225
  end
163
226
 
164
- def web_urls
165
- return [] if @web.empty?
166
-
167
- @web.split(/\s+/)
227
+ # Save to file or IO object
228
+ def save file_path_or_io
229
+ xml_content = to_xml
230
+
231
+ case file_path_or_io
232
+ when String
233
+ begin
234
+ FileUtils.mkdir_p(File.dirname(file_path_or_io))
235
+ File.write(file_path_or_io, xml_content)
236
+ rescue StandardError => e
237
+ raise Errors::FileError, "Failed to write file '#{file_path_or_io}': #{e.message}"
238
+ end
239
+ when IO
240
+ begin
241
+ file_path_or_io.write(xml_content)
242
+ rescue StandardError => e
243
+ raise Errors::FileError, "Failed to write to IO object: #{e.message}"
244
+ end
245
+ else
246
+ raise Errors::FileError, 'Invalid file path or IO object'
247
+ end
168
248
  end
169
249
 
170
250
  # Convert to JSON representation
@@ -180,55 +260,58 @@ module ComicInfo
180
260
  # Convert to hash representation for JSON serialization
181
261
  def to_h
182
262
  {
183
- title: @title,
184
- series: @series,
185
- number: @number,
186
- count: @count,
187
- volume: @volume,
188
- alternate_series: @alternate_series,
189
- alternate_number: @alternate_number,
190
- alternate_count: @alternate_count,
191
- summary: @summary,
192
- notes: @notes,
193
- year: @year,
194
- month: @month,
195
- day: @day,
196
- writer: @writer,
197
- penciller: @penciller,
198
- inker: @inker,
199
- colorist: @colorist,
200
- letterer: @letterer,
201
- cover_artist: @cover_artist,
202
- editor: @editor,
203
- translator: @translator,
204
- publisher: @publisher,
205
- imprint: @imprint,
206
- genre: @genre,
207
- genres: genres,
208
- web: @web,
209
- web_urls: web_urls,
210
- page_count: @page_count,
211
- language_iso: @language_iso,
212
- format: @format,
213
- black_and_white: @black_and_white,
214
- manga: @manga,
215
- character: @character,
216
- characters: characters,
217
- team: @team,
218
- teams: teams,
219
- location: @location,
220
- locations: locations,
221
- scan_information: @scan_information,
222
- story_arc: @story_arc,
223
- story_arcs: story_arcs,
224
- story_arc_number: @story_arc_number,
225
- story_arc_numbers: story_arc_numbers,
226
- series_group: @series_group,
227
- age_rating: @age_rating,
228
- main_character_or_team: @main_character_or_team,
229
- community_rating: @community_rating,
230
- review: @review,
231
- pages: @pages.map(&:to_h)
263
+ title: @title,
264
+ series: @series,
265
+ number: @number,
266
+ count: @count,
267
+ volume: @volume,
268
+ alternate_series: @alternate_series,
269
+ alternate_number: @alternate_number,
270
+ alternate_count: @alternate_count,
271
+ summary: @summary,
272
+ notes: @notes,
273
+ year: @year,
274
+ month: @month,
275
+ day: @day,
276
+ writer: @writer,
277
+ penciller: @penciller,
278
+ inker: @inker,
279
+ colorist: @colorist,
280
+ letterer: @letterer,
281
+ cover_artist: @cover_artist,
282
+ editor: @editor,
283
+ translator: @translator,
284
+ publisher: @publisher,
285
+ imprint: @imprint,
286
+ genre: @genre,
287
+ genres_raw_data: genres_raw_data,
288
+ genres: genres,
289
+ web: @web,
290
+ web_urls: web_urls,
291
+ page_count: @page_count,
292
+ language_iso: @language_iso,
293
+ format: @format,
294
+ black_and_white: @black_and_white,
295
+ manga: @manga,
296
+ characters_raw_data: characters_raw_data,
297
+ characters: characters,
298
+ teams_raw_data: teams_raw_data,
299
+ teams: teams,
300
+ locations_raw_data: locations_raw_data,
301
+ locations: locations,
302
+ scan_information: @scan_information,
303
+ story_arc: @story_arc,
304
+ story_arcs_raw_data: story_arcs_raw_data,
305
+ story_arcs: story_arcs,
306
+ story_arc_number: @story_arc_number,
307
+ story_arc_numbers_raw_data: story_arc_numbers_raw_data,
308
+ story_arc_numbers: story_arc_numbers,
309
+ series_group: @series_group,
310
+ age_rating: @age_rating,
311
+ main_character_or_team: @main_character_or_team,
312
+ community_rating: @community_rating,
313
+ review: @review,
314
+ pages: @pages.map(&:to_h)
232
315
  }.compact
233
316
  end
234
317
 
@@ -1,3 +1,3 @@
1
1
  module ComicInfo
2
- VERSION = '1.0.0'.freeze
2
+ VERSION = '2.0.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: comicinfo
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shane Becker
@@ -73,7 +73,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
73
73
  - !ruby/object:Gem::Version
74
74
  version: '0'
75
75
  requirements: []
76
- rubygems_version: 3.6.9
76
+ rubygems_version: 3.7.2
77
77
  specification_version: 4
78
78
  summary: Ruby interface for working with ComicInfo.xml files
79
79
  test_files: []