Compare commits
3 commits
c6f7ab5fbf
...
3af946467a
Author | SHA1 | Date | |
---|---|---|---|
3af946467a | |||
e68be90066 | |||
1421fedd7c |
19 changed files with 171 additions and 99 deletions
|
@ -5,7 +5,7 @@ require:
|
||||||
- rubocop-rake
|
- rubocop-rake
|
||||||
|
|
||||||
AllCops:
|
AllCops:
|
||||||
TargetRubyVersion: 3.2
|
TargetRubyVersion: 3.3
|
||||||
DisplayCopNames: true
|
DisplayCopNames: true
|
||||||
NewCops: enable
|
NewCops: enable
|
||||||
|
|
||||||
|
@ -21,6 +21,9 @@ Lint/AmbiguousOperatorPrecedence:
|
||||||
Lint/ReturnInVoidContext:
|
Lint/ReturnInVoidContext:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
|
Metrics/ClassLength:
|
||||||
|
Max: 200
|
||||||
|
|
||||||
Style/AndOr:
|
Style/AndOr:
|
||||||
EnforcedStyle: conditionals
|
EnforcedStyle: conditionals
|
||||||
|
|
||||||
|
@ -33,6 +36,9 @@ Style/HashAsLastArrayItem:
|
||||||
Style/PerlBackrefs:
|
Style/PerlBackrefs:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
|
Style/SuperWithArgsParentheses:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
Style/TrailingCommaInArguments:
|
Style/TrailingCommaInArguments:
|
||||||
EnforcedStyleForMultiline: comma
|
EnforcedStyleForMultiline: comma
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# This configuration was generated by
|
# This configuration was generated by
|
||||||
# `rubocop --auto-gen-config`
|
# `rubocop --auto-gen-config`
|
||||||
# on 2024-10-18 14:41:13 UTC using RuboCop version 1.67.0.
|
# on 2024-10-18 19:44:25 UTC using RuboCop version 1.67.0.
|
||||||
# The point is for the user to remove these configuration records
|
# The point is for the user to remove these configuration records
|
||||||
# one by one as the offenses are removed from the code base.
|
# one by one as the offenses are removed from the code base.
|
||||||
# Note that changes in the inspected code, or installation of new
|
# Note that changes in the inspected code, or installation of new
|
||||||
|
@ -22,23 +22,10 @@ Layout/LineLength:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'lib/repubmark/elems/footnote.rb'
|
- 'lib/repubmark/elems/footnote.rb'
|
||||||
|
|
||||||
# Offense count: 1
|
# Offense count: 2
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
|
||||||
# Configuration parameters: AllowedMethods.
|
|
||||||
# AllowedMethods: present?, blank?, presence, try, try!, in?
|
|
||||||
Lint/SafeNavigationChain:
|
|
||||||
Exclude:
|
|
||||||
- 'lib/repubmark/elems/article.rb'
|
|
||||||
|
|
||||||
# Offense count: 1
|
|
||||||
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
|
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
|
||||||
Metrics/AbcSize:
|
Metrics/AbcSize:
|
||||||
Max: 35
|
Max: 36
|
||||||
|
|
||||||
# Offense count: 1
|
|
||||||
# Configuration parameters: CountComments, CountAsOne.
|
|
||||||
Metrics/ClassLength:
|
|
||||||
Max: 104
|
|
||||||
|
|
||||||
# Offense count: 1
|
# Offense count: 1
|
||||||
# Configuration parameters: AllowedMethods, AllowedPatterns.
|
# Configuration parameters: AllowedMethods, AllowedPatterns.
|
||||||
|
@ -48,32 +35,14 @@ Metrics/CyclomaticComplexity:
|
||||||
# Offense count: 5
|
# Offense count: 5
|
||||||
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
|
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
|
||||||
Metrics/MethodLength:
|
Metrics/MethodLength:
|
||||||
Max: 33
|
Max: 31
|
||||||
|
|
||||||
# Offense count: 1
|
# Offense count: 1
|
||||||
# Configuration parameters: AllowedMethods, AllowedPatterns.
|
# Configuration parameters: AllowedMethods, AllowedPatterns.
|
||||||
Metrics/PerceivedComplexity:
|
Metrics/PerceivedComplexity:
|
||||||
Max: 11
|
Max: 11
|
||||||
|
|
||||||
# Offense count: 2
|
# Offense count: 36
|
||||||
Performance/MapMethodChain:
|
|
||||||
Exclude:
|
|
||||||
- 'lib/repubmark/elems/footnotes_category.rb'
|
|
||||||
|
|
||||||
# Offense count: 14
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
|
||||||
# Configuration parameters: AllowOnlyRestArgument, UseAnonymousForwarding, RedundantRestArgumentNames, RedundantKeywordRestArgumentNames, RedundantBlockArgumentNames.
|
|
||||||
# RedundantRestArgumentNames: args, arguments
|
|
||||||
# RedundantKeywordRestArgumentNames: kwargs, options, opts
|
|
||||||
# RedundantBlockArgumentNames: blk, block, proc
|
|
||||||
Style/ArgumentsForwarding:
|
|
||||||
Exclude:
|
|
||||||
- 'lib/repubmark/elems/canvas.rb'
|
|
||||||
- 'lib/repubmark/elems/footnotes_category.rb'
|
|
||||||
- 'lib/repubmark/elems/joint.rb'
|
|
||||||
- 'lib/repubmark/elems/link.rb'
|
|
||||||
|
|
||||||
# Offense count: 34
|
|
||||||
# Configuration parameters: AllowedConstants.
|
# Configuration parameters: AllowedConstants.
|
||||||
Style/Documentation:
|
Style/Documentation:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
@ -97,33 +66,3 @@ Style/RedundantFreeze:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'lib/repubmark/elems/fraction.rb'
|
- 'lib/repubmark/elems/fraction.rb'
|
||||||
- 'lib/repubmark/elems/power.rb'
|
- 'lib/repubmark/elems/power.rb'
|
||||||
|
|
||||||
# Offense count: 2
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
|
||||||
Style/RedundantStringEscape:
|
|
||||||
Exclude:
|
|
||||||
- 'lib/repubmark/elems/footnote.rb'
|
|
||||||
|
|
||||||
# Offense count: 1
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
|
||||||
# Configuration parameters: AllowModifier.
|
|
||||||
Style/SoleNestedConditional:
|
|
||||||
Exclude:
|
|
||||||
- 'lib/repubmark/elems/footnote.rb'
|
|
||||||
|
|
||||||
# Offense count: 7
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
|
||||||
Style/SuperArguments:
|
|
||||||
Exclude:
|
|
||||||
- 'lib/repubmark/elems/annotation.rb'
|
|
||||||
- 'lib/repubmark/elems/blockquote.rb'
|
|
||||||
- 'lib/repubmark/elems/canvas.rb'
|
|
||||||
- 'lib/repubmark/elems/caption.rb'
|
|
||||||
- 'lib/repubmark/elems/figures.rb'
|
|
||||||
- 'lib/repubmark/elems/joint.rb'
|
|
||||||
- 'lib/repubmark/elems/paragraph.rb'
|
|
||||||
|
|
||||||
# Offense count: 24
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
|
||||||
Style/SuperWithArgsParentheses:
|
|
||||||
Enabled: false
|
|
||||||
|
|
2
Gemfile
2
Gemfile
|
@ -6,7 +6,7 @@ source 'https://rubygems.org'
|
||||||
gemspec
|
gemspec
|
||||||
|
|
||||||
group :development do
|
group :development do
|
||||||
gem 'bundler', '~> 2.4'
|
gem 'bundler', '~> 2.5'
|
||||||
gem 'pry', '~> 0.14'
|
gem 'pry', '~> 0.14'
|
||||||
gem 'rake', '~> 13.2'
|
gem 'rake', '~> 13.2'
|
||||||
gem 'rubocop', '~> 1.67'
|
gem 'rubocop', '~> 1.67'
|
||||||
|
|
6
Rakefile
6
Rakefile
|
@ -27,8 +27,8 @@ task test: :tests
|
||||||
desc 'Run code analysis tools'
|
desc 'Run code analysis tools'
|
||||||
task lint: %i[rubocop yard:cov]
|
task lint: %i[rubocop yard:cov]
|
||||||
|
|
||||||
desc 'Fix code style (rubocop --auto-correct)'
|
desc 'Fix code style (rubocop --autocorrect)'
|
||||||
task fix: 'rubocop:auto_correct'
|
task fix: 'rubocop:autocorrect'
|
||||||
|
|
||||||
Rake::Task['release'].prereqs.unshift 'default'
|
Rake::Task['release'].prereqs.unshift 'default'
|
||||||
Rake::Task['release:rubygem_push'].clear
|
Rake::Task['release:rubygem_push'].clear
|
||||||
|
@ -68,6 +68,6 @@ namespace :yard do
|
||||||
|
|
||||||
coverage = m[1].to_f.round(2)
|
coverage = m[1].to_f.round(2)
|
||||||
puts "Documentation coverage: #{coverage}%"
|
puts "Documentation coverage: #{coverage}%"
|
||||||
raise 'Not fully documented!' if coverage < 38
|
raise 'Not fully documented!' if coverage < 36
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,6 +16,9 @@ require_relative 'repubmark/titled_ref'
|
||||||
require_relative 'repubmark/config'
|
require_relative 'repubmark/config'
|
||||||
require_relative 'repubmark/config/css_classes'
|
require_relative 'repubmark/config/css_classes'
|
||||||
|
|
||||||
|
require_relative 'repubmark/references/author'
|
||||||
|
require_relative 'repubmark/references/item'
|
||||||
|
|
||||||
require_relative 'repubmark/elems/base'
|
require_relative 'repubmark/elems/base'
|
||||||
|
|
||||||
# Top-level element
|
# Top-level element
|
||||||
|
@ -72,7 +75,10 @@ require_relative 'repubmark/elems/footnote'
|
||||||
module Repubmark
|
module Repubmark
|
||||||
FORMATS = %i[chapters gemtext html summary_plain word_count].freeze
|
FORMATS = %i[chapters gemtext html summary_plain word_count].freeze
|
||||||
|
|
||||||
SLUG_RE = /\A[[:word:]]+(-[[:word:]]+)*\z/
|
SLUG_RE = /\A[[:word:]]+(-[[:word:]]+)*\z/
|
||||||
|
DOI_RE = %r{\A10(\.\d+)+/\w+(\.\w+)*\z}
|
||||||
|
ISBN_RE = /\A[0-9]{13}\z/
|
||||||
|
NAME_PART_RE = /\A[[:word:]]+(-[[:word:]]+)*( [[:word:]]+(-[[:word:]]+)*)*\z/
|
||||||
|
|
||||||
UNICODE_SUPS = {
|
UNICODE_SUPS = {
|
||||||
'0' => '⁰',
|
'0' => '⁰',
|
||||||
|
@ -117,6 +123,46 @@ module Repubmark
|
||||||
slug
|
slug
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.validate_doi!(doi)
|
||||||
|
doi = String(doi).freeze
|
||||||
|
raise 'Invalid DOI' unless DOI_RE.match? doi
|
||||||
|
|
||||||
|
doi
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.validate_isbn!(isbn)
|
||||||
|
isbn = String(isbn).freeze
|
||||||
|
raise 'Invalid ISBN' unless ISBN_RE.match? isbn
|
||||||
|
|
||||||
|
isbn
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.validate_name_part!(name_part)
|
||||||
|
name_part = String(name_part).freeze
|
||||||
|
raise 'Invalid name part' unless NAME_PART_RE.match? name_part
|
||||||
|
|
||||||
|
name_part
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.validate_text!(str)
|
||||||
|
str = String(str).freeze
|
||||||
|
raise 'Invalid text' if str.empty? || str != str.strip
|
||||||
|
|
||||||
|
str
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.validate_absolute_url!(url)
|
||||||
|
url = Addressable::URI.parse(url).freeze
|
||||||
|
raise 'Invalid URL' unless url.absolute? &&
|
||||||
|
url.scheme &&
|
||||||
|
!url.scheme.strip.empty? &&
|
||||||
|
url.host &&
|
||||||
|
!url.host.strip.empty? &&
|
||||||
|
url.userinfo.nil?
|
||||||
|
|
||||||
|
url
|
||||||
|
end
|
||||||
|
|
||||||
def self.unicode_sup(val)
|
def self.unicode_sup(val)
|
||||||
String(val).each_char.map { |chr| UNICODE_SUPS.fetch chr }.join.freeze
|
String(val).each_char.map { |chr| UNICODE_SUPS.fetch chr }.join.freeze
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,7 +6,7 @@ module Repubmark
|
||||||
parents :Article
|
parents :Article
|
||||||
|
|
||||||
def initialize(parent)
|
def initialize(parent)
|
||||||
super parent
|
super
|
||||||
@canvas = Canvas.new self
|
@canvas = Canvas.new self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ module Repubmark
|
||||||
].compact.join("\n\n\n").freeze
|
].compact.join("\n\n\n").freeze
|
||||||
end
|
end
|
||||||
|
|
||||||
def chapters = @chapter&.chapters[:chapters] || [].freeze
|
def chapters = (@chapter&.chapters || {})[:chapters] || [].freeze
|
||||||
|
|
||||||
###################
|
###################
|
||||||
# Builder methods #
|
# Builder methods #
|
||||||
|
|
|
@ -6,7 +6,7 @@ module Repubmark
|
||||||
parents :Canvas
|
parents :Canvas
|
||||||
|
|
||||||
def initialize(parent)
|
def initialize(parent)
|
||||||
super parent
|
super
|
||||||
|
|
||||||
@canvas = Canvas.new self
|
@canvas = Canvas.new self
|
||||||
@caption = nil
|
@caption = nil
|
||||||
|
|
|
@ -6,7 +6,7 @@ module Repubmark
|
||||||
parents :Annotation, :Blockquote, :Chapter
|
parents :Annotation, :Blockquote, :Chapter
|
||||||
|
|
||||||
def initialize(parent)
|
def initialize(parent)
|
||||||
super parent
|
super
|
||||||
@items = []
|
@items = []
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -41,14 +41,14 @@ module Repubmark
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def code_block(*args, **kwargs)
|
def code_block(*, **)
|
||||||
code_block = CodeBlock.new self, *args, **kwargs
|
code_block = CodeBlock.new(self, *, **)
|
||||||
@items << code_block
|
@items << code_block
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def iframe(*args, **kwargs)
|
def iframe(*, **)
|
||||||
iframe = Iframe.new self, *args, **kwargs
|
iframe = Iframe.new(self, *, **)
|
||||||
@items << iframe
|
@items << iframe
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,7 +8,7 @@ module Repubmark
|
||||||
parents :Blockquote, :Figure, :Footnote, :ListItem, :Paragraph
|
parents :Blockquote, :Figure, :Footnote, :ListItem, :Paragraph
|
||||||
|
|
||||||
def initialize(parent)
|
def initialize(parent)
|
||||||
super parent
|
super
|
||||||
@items = []
|
@items = []
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ module Repubmark
|
||||||
parents :Canvas
|
parents :Canvas
|
||||||
|
|
||||||
def initialize(parent)
|
def initialize(parent)
|
||||||
super parent
|
super
|
||||||
@figures = []
|
@figures = []
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -30,12 +30,10 @@ module Repubmark
|
||||||
end
|
end
|
||||||
if url
|
if url
|
||||||
scheme = Addressable::URI.parse(url).scheme&.downcase
|
scheme = Addressable::URI.parse(url).scheme&.downcase
|
||||||
if scheme
|
if scheme && !%w[http https].include?(scheme)
|
||||||
unless %w[http https].include? scheme
|
result += %(<span class="badge text-bg-secondary">\n)
|
||||||
result += %(<span class="badge text-bg-secondary">\n)
|
result += %(#{scheme}://\n)
|
||||||
result += %(#{scheme}://\n)
|
result += "</span>\n"
|
||||||
result += "</span>\n"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
result += %(<a href="#{url}">#{link_text}</a>\n)
|
result += %(<a href="#{url}">#{link_text}</a>\n)
|
||||||
else
|
else
|
||||||
|
@ -45,7 +43,7 @@ module Repubmark
|
||||||
if alt_urls&.any?
|
if alt_urls&.any?
|
||||||
result += %[(#{
|
result += %[(#{
|
||||||
alt_urls.map do |alt_url|
|
alt_urls.map do |alt_url|
|
||||||
%(<a href=\"#{alt_url[:url]}\">#{alt_url[:name]}</a>)
|
%(<a href="#{alt_url[:url]}">#{alt_url[:name]}</a>)
|
||||||
end.join ', '
|
end.join ', '
|
||||||
})\n]
|
})\n]
|
||||||
end
|
end
|
||||||
|
|
|
@ -20,7 +20,7 @@ module Repubmark
|
||||||
<h2>#@title</h2>
|
<h2>#@title</h2>
|
||||||
|
|
||||||
<ol>
|
<ol>
|
||||||
#{@footnotes.map(&:to_html).map(&:strip).join("\n")}
|
#{@footnotes.map { |footnote| footnote.to_html.strip }.join("\n")}
|
||||||
</ol>
|
</ol>
|
||||||
HTML
|
HTML
|
||||||
end
|
end
|
||||||
|
@ -29,7 +29,7 @@ module Repubmark
|
||||||
<<~GEMTEXT
|
<<~GEMTEXT
|
||||||
## #@title
|
## #@title
|
||||||
|
|
||||||
#{@footnotes.map(&:to_gemtext).map(&:strip).join("\n")}
|
#{@footnotes.map { |footnote| footnote.to_gemtext.strip }.join("\n")}
|
||||||
GEMTEXT
|
GEMTEXT
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -37,8 +37,8 @@ module Repubmark
|
||||||
# Builder methods #
|
# Builder methods #
|
||||||
###################
|
###################
|
||||||
|
|
||||||
def footnote(**kwargs)
|
def footnote(**)
|
||||||
footnote = Footnote.new(self, **kwargs)
|
footnote = Footnote.new(self, **)
|
||||||
@footnotes << footnote
|
@footnotes << footnote
|
||||||
yield footnote if block_given?
|
yield footnote if block_given?
|
||||||
nil
|
nil
|
||||||
|
|
|
@ -6,7 +6,7 @@ module Repubmark
|
||||||
parents :Caption, :Quote
|
parents :Caption, :Quote
|
||||||
|
|
||||||
def initialize(parent)
|
def initialize(parent)
|
||||||
super parent
|
super
|
||||||
|
|
||||||
@raw1 = nil
|
@raw1 = nil
|
||||||
@base = nil
|
@base = nil
|
||||||
|
@ -92,7 +92,7 @@ module Repubmark
|
||||||
base quote
|
base quote
|
||||||
end
|
end
|
||||||
|
|
||||||
def section(*args) = base Section.new self, *args
|
def section(*) = base Section.new(self, *)
|
||||||
|
|
||||||
def text(str) = base Text.new self, str
|
def text(str) = base Text.new self, str
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,8 @@ module Repubmark
|
||||||
|
|
||||||
SCHEMES = %w[http https].freeze
|
SCHEMES = %w[http https].freeze
|
||||||
|
|
||||||
def initialize(parent, str, uri, **kwargs)
|
def initialize(parent, str, uri, **)
|
||||||
super parent, str, **kwargs
|
super(parent, str, **)
|
||||||
|
|
||||||
self.uri = uri
|
self.uri = uri
|
||||||
validate_uri!
|
validate_uri!
|
||||||
|
|
|
@ -6,7 +6,7 @@ module Repubmark
|
||||||
parents :Canvas
|
parents :Canvas
|
||||||
|
|
||||||
def initialize(parent)
|
def initialize(parent)
|
||||||
super parent
|
super
|
||||||
@caption = Caption.new self
|
@caption = Caption.new self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
31
lib/repubmark/references/author.rb
Normal file
31
lib/repubmark/references/author.rb
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Repubmark
|
||||||
|
module References
|
||||||
|
class Author
|
||||||
|
attr_reader :family, :given
|
||||||
|
|
||||||
|
def initialize(family, given)
|
||||||
|
self.family = family
|
||||||
|
self.given = given
|
||||||
|
end
|
||||||
|
|
||||||
|
def inspect = "#<#{self.class}: #{self}>".freeze
|
||||||
|
|
||||||
|
def to_s = "#{family}, #{given.join(' ')}".freeze
|
||||||
|
|
||||||
|
alias to_str to_s
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def family=(family)
|
||||||
|
@family = Repubmark.validate_name_part! family
|
||||||
|
end
|
||||||
|
|
||||||
|
def given=(given)
|
||||||
|
@given =
|
||||||
|
Array(given).map { |part| Repubmark.validate_name_part! part }.freeze
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
52
lib/repubmark/references/item.rb
Normal file
52
lib/repubmark/references/item.rb
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Repubmark
|
||||||
|
module References
|
||||||
|
class Item
|
||||||
|
ATTRIBUTES = %i[slug doi isbn title urls authors].freeze
|
||||||
|
attr_reader(*ATTRIBUTES)
|
||||||
|
|
||||||
|
def initialize(**kwargs)
|
||||||
|
ATTRIBUTES.each { |attr| send :"#{attr}=", kwargs[attr] }
|
||||||
|
end
|
||||||
|
|
||||||
|
def inspect = "#<#{self.class}:#{slug}>".freeze
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def slug=(slug)
|
||||||
|
@slug = Repubmark.validate_slug! slug
|
||||||
|
end
|
||||||
|
|
||||||
|
def doi=(doi)
|
||||||
|
@doi = Repubmark.validate_doi! doi if doi
|
||||||
|
end
|
||||||
|
|
||||||
|
def isbn=(isbn)
|
||||||
|
@isbn = Repubmark.validate_isbn! isbn if isbn
|
||||||
|
end
|
||||||
|
|
||||||
|
def title=(title)
|
||||||
|
@title = Repubmark.validate_text! title
|
||||||
|
end
|
||||||
|
|
||||||
|
def urls=(urls)
|
||||||
|
urls = Array urls
|
||||||
|
return @urls = [].freeze if urls.empty?
|
||||||
|
|
||||||
|
@urls = urls.map { |url| Repubmark.validate_absolute_url! url }.freeze
|
||||||
|
end
|
||||||
|
|
||||||
|
def authors=(authors)
|
||||||
|
authors = Array authors
|
||||||
|
return @authors = [].freeze if authors.empty?
|
||||||
|
|
||||||
|
@authors = authors.freeze.each do |author|
|
||||||
|
unless author.instance_of? Author
|
||||||
|
raise TypeError, "Expected #{Author}, got #{author.class}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -14,7 +14,7 @@ Gem::Specification.new do |spec|
|
||||||
spec.license = 'MIT'
|
spec.license = 'MIT'
|
||||||
spec.homepage = home
|
spec.homepage = home
|
||||||
|
|
||||||
spec.required_ruby_version = '~> 3.2'
|
spec.required_ruby_version = '~> 3.3'
|
||||||
|
|
||||||
spec.authors = ['Alex Kotov']
|
spec.authors = ['Alex Kotov']
|
||||||
spec.email = [mail]
|
spec.email = [mail]
|
||||||
|
|
Loading…
Reference in a new issue