diff --git a/.rubocop.yml b/.rubocop.yml index c7c5fae..f34db8d 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -5,7 +5,7 @@ require: - rubocop-rake AllCops: - TargetRubyVersion: 3.3 + TargetRubyVersion: 3.2 DisplayCopNames: true NewCops: enable @@ -21,9 +21,6 @@ Lint/AmbiguousOperatorPrecedence: Lint/ReturnInVoidContext: Enabled: false -Metrics/ClassLength: - Max: 200 - Style/AndOr: EnforcedStyle: conditionals @@ -36,9 +33,6 @@ Style/HashAsLastArrayItem: Style/PerlBackrefs: Enabled: false -Style/SuperWithArgsParentheses: - Enabled: false - Style/TrailingCommaInArguments: EnforcedStyleForMultiline: comma diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 986620e..47477d5 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2024-10-18 19:44:25 UTC using RuboCop version 1.67.0. +# on 2024-10-18 14:41:13 UTC using RuboCop version 1.67.0. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new @@ -22,10 +22,23 @@ Layout/LineLength: Exclude: - 'lib/repubmark/elems/footnote.rb' -# Offense count: 2 +# Offense count: 1 +# 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. Metrics/AbcSize: - Max: 36 + Max: 35 + +# Offense count: 1 +# Configuration parameters: CountComments, CountAsOne. +Metrics/ClassLength: + Max: 104 # Offense count: 1 # Configuration parameters: AllowedMethods, AllowedPatterns. @@ -35,14 +48,32 @@ Metrics/CyclomaticComplexity: # Offense count: 5 # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns. Metrics/MethodLength: - Max: 31 + Max: 33 # Offense count: 1 # Configuration parameters: AllowedMethods, AllowedPatterns. Metrics/PerceivedComplexity: Max: 11 -# Offense count: 36 +# Offense count: 2 +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. Style/Documentation: Enabled: false @@ -66,3 +97,33 @@ Style/RedundantFreeze: Exclude: - 'lib/repubmark/elems/fraction.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 diff --git a/Gemfile b/Gemfile index c787375..d3b131c 100644 --- a/Gemfile +++ b/Gemfile @@ -6,7 +6,7 @@ source 'https://rubygems.org' gemspec group :development do - gem 'bundler', '~> 2.5' + gem 'bundler', '~> 2.4' gem 'pry', '~> 0.14' gem 'rake', '~> 13.2' gem 'rubocop', '~> 1.67' diff --git a/Rakefile b/Rakefile index 628f9d2..1b2cd40 100644 --- a/Rakefile +++ b/Rakefile @@ -27,8 +27,8 @@ task test: :tests desc 'Run code analysis tools' task lint: %i[rubocop yard:cov] -desc 'Fix code style (rubocop --autocorrect)' -task fix: 'rubocop:autocorrect' +desc 'Fix code style (rubocop --auto-correct)' +task fix: 'rubocop:auto_correct' Rake::Task['release'].prereqs.unshift 'default' Rake::Task['release:rubygem_push'].clear @@ -68,6 +68,6 @@ namespace :yard do coverage = m[1].to_f.round(2) puts "Documentation coverage: #{coverage}%" - raise 'Not fully documented!' if coverage < 36 + raise 'Not fully documented!' if coverage < 38 end end diff --git a/lib/repubmark.rb b/lib/repubmark.rb index e91fdcf..a244dd4 100644 --- a/lib/repubmark.rb +++ b/lib/repubmark.rb @@ -16,9 +16,6 @@ require_relative 'repubmark/titled_ref' require_relative 'repubmark/config' require_relative 'repubmark/config/css_classes' -require_relative 'repubmark/references/author' -require_relative 'repubmark/references/item' - require_relative 'repubmark/elems/base' # Top-level element @@ -75,10 +72,7 @@ require_relative 'repubmark/elems/footnote' module Repubmark FORMATS = %i[chapters gemtext html summary_plain word_count].freeze - 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/ + SLUG_RE = /\A[[:word:]]+(-[[:word:]]+)*\z/ UNICODE_SUPS = { '0' => '⁰', @@ -123,46 +117,6 @@ module Repubmark slug 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) String(val).each_char.map { |chr| UNICODE_SUPS.fetch chr }.join.freeze end diff --git a/lib/repubmark/elems/annotation.rb b/lib/repubmark/elems/annotation.rb index dd43ee8..74f0b3f 100644 --- a/lib/repubmark/elems/annotation.rb +++ b/lib/repubmark/elems/annotation.rb @@ -6,7 +6,7 @@ module Repubmark parents :Article def initialize(parent) - super + super parent @canvas = Canvas.new self end diff --git a/lib/repubmark/elems/article.rb b/lib/repubmark/elems/article.rb index adc0e21..bec8aa3 100644 --- a/lib/repubmark/elems/article.rb +++ b/lib/repubmark/elems/article.rb @@ -45,7 +45,7 @@ module Repubmark ].compact.join("\n\n\n").freeze end - def chapters = (@chapter&.chapters || {})[:chapters] || [].freeze + def chapters = @chapter&.chapters[:chapters] || [].freeze ################### # Builder methods # diff --git a/lib/repubmark/elems/blockquote.rb b/lib/repubmark/elems/blockquote.rb index bc36789..c019e50 100644 --- a/lib/repubmark/elems/blockquote.rb +++ b/lib/repubmark/elems/blockquote.rb @@ -6,7 +6,7 @@ module Repubmark parents :Canvas def initialize(parent) - super + super parent @canvas = Canvas.new self @caption = nil diff --git a/lib/repubmark/elems/canvas.rb b/lib/repubmark/elems/canvas.rb index 9af10aa..43762e8 100644 --- a/lib/repubmark/elems/canvas.rb +++ b/lib/repubmark/elems/canvas.rb @@ -6,7 +6,7 @@ module Repubmark parents :Annotation, :Blockquote, :Chapter def initialize(parent) - super + super parent @items = [] end @@ -41,14 +41,14 @@ module Repubmark nil end - def code_block(*, **) - code_block = CodeBlock.new(self, *, **) + def code_block(*args, **kwargs) + code_block = CodeBlock.new self, *args, **kwargs @items << code_block nil end - def iframe(*, **) - iframe = Iframe.new(self, *, **) + def iframe(*args, **kwargs) + iframe = Iframe.new self, *args, **kwargs @items << iframe nil end diff --git a/lib/repubmark/elems/caption.rb b/lib/repubmark/elems/caption.rb index 96eff05..b3b5264 100644 --- a/lib/repubmark/elems/caption.rb +++ b/lib/repubmark/elems/caption.rb @@ -8,7 +8,7 @@ module Repubmark parents :Blockquote, :Figure, :Footnote, :ListItem, :Paragraph def initialize(parent) - super + super parent @items = [] end diff --git a/lib/repubmark/elems/figures.rb b/lib/repubmark/elems/figures.rb index 817132a..b109e18 100644 --- a/lib/repubmark/elems/figures.rb +++ b/lib/repubmark/elems/figures.rb @@ -6,7 +6,7 @@ module Repubmark parents :Canvas def initialize(parent) - super + super parent @figures = [] end diff --git a/lib/repubmark/elems/footnote.rb b/lib/repubmark/elems/footnote.rb index d376ceb..167d1b6 100644 --- a/lib/repubmark/elems/footnote.rb +++ b/lib/repubmark/elems/footnote.rb @@ -30,10 +30,12 @@ module Repubmark end if url scheme = Addressable::URI.parse(url).scheme&.downcase - if scheme && !%w[http https].include?(scheme) - result += %(\n) - result += %(#{scheme}://\n) - result += "\n" + if scheme + unless %w[http https].include? scheme + result += %(\n) + result += %(#{scheme}://\n) + result += "\n" + end end result += %(#{link_text}\n) else @@ -43,7 +45,7 @@ module Repubmark if alt_urls&.any? result += %[(#{ alt_urls.map do |alt_url| - %(#{alt_url[:name]}) + %(#{alt_url[:name]}) end.join ', ' })\n] end diff --git a/lib/repubmark/elems/footnotes_category.rb b/lib/repubmark/elems/footnotes_category.rb index 6a3a320..cc1985c 100644 --- a/lib/repubmark/elems/footnotes_category.rb +++ b/lib/repubmark/elems/footnotes_category.rb @@ -20,7 +20,7 @@ module Repubmark

#@title

    - #{@footnotes.map { |footnote| footnote.to_html.strip }.join("\n")} + #{@footnotes.map(&:to_html).map(&:strip).join("\n")}
HTML end @@ -29,7 +29,7 @@ module Repubmark <<~GEMTEXT ## #@title - #{@footnotes.map { |footnote| footnote.to_gemtext.strip }.join("\n")} + #{@footnotes.map(&:to_gemtext).map(&:strip).join("\n")} GEMTEXT end @@ -37,8 +37,8 @@ module Repubmark # Builder methods # ################### - def footnote(**) - footnote = Footnote.new(self, **) + def footnote(**kwargs) + footnote = Footnote.new(self, **kwargs) @footnotes << footnote yield footnote if block_given? nil diff --git a/lib/repubmark/elems/joint.rb b/lib/repubmark/elems/joint.rb index 3988f97..b48b463 100644 --- a/lib/repubmark/elems/joint.rb +++ b/lib/repubmark/elems/joint.rb @@ -6,7 +6,7 @@ module Repubmark parents :Caption, :Quote def initialize(parent) - super + super parent @raw1 = nil @base = nil @@ -92,7 +92,7 @@ module Repubmark base quote end - def section(*) = base Section.new(self, *) + def section(*args) = base Section.new self, *args def text(str) = base Text.new self, str diff --git a/lib/repubmark/elems/link.rb b/lib/repubmark/elems/link.rb index 6e326f5..df306d2 100644 --- a/lib/repubmark/elems/link.rb +++ b/lib/repubmark/elems/link.rb @@ -7,8 +7,8 @@ module Repubmark SCHEMES = %w[http https].freeze - def initialize(parent, str, uri, **) - super(parent, str, **) + def initialize(parent, str, uri, **kwargs) + super parent, str, **kwargs self.uri = uri validate_uri! diff --git a/lib/repubmark/elems/paragraph.rb b/lib/repubmark/elems/paragraph.rb index 5568362..979e8e4 100644 --- a/lib/repubmark/elems/paragraph.rb +++ b/lib/repubmark/elems/paragraph.rb @@ -6,7 +6,7 @@ module Repubmark parents :Canvas def initialize(parent) - super + super parent @caption = Caption.new self end diff --git a/lib/repubmark/references/author.rb b/lib/repubmark/references/author.rb deleted file mode 100644 index 200934d..0000000 --- a/lib/repubmark/references/author.rb +++ /dev/null @@ -1,31 +0,0 @@ -# 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 diff --git a/lib/repubmark/references/item.rb b/lib/repubmark/references/item.rb deleted file mode 100644 index 851a613..0000000 --- a/lib/repubmark/references/item.rb +++ /dev/null @@ -1,52 +0,0 @@ -# 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 diff --git a/repubmark.gemspec b/repubmark.gemspec index ee763a7..da87d41 100644 --- a/repubmark.gemspec +++ b/repubmark.gemspec @@ -14,7 +14,7 @@ Gem::Specification.new do |spec| spec.license = 'MIT' spec.homepage = home - spec.required_ruby_version = '~> 3.3' + spec.required_ruby_version = '~> 3.2' spec.authors = ['Alex Kotov'] spec.email = [mail]