diff --git a/.rubocop.yml b/.rubocop.yml index f5b9e9f57a..3b768252e9 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -2,6 +2,7 @@ inherit_from: .rubocop_todo.yml require: - ./lib/rubocop/cop/rouge/no_building_alternation_pattern_in_regexp.rb + - ./lib/rubocop/cop/rouge/no_huge_collections.rb plugins: - rubocop-performance @@ -18,6 +19,9 @@ AllCops: - "lib/rouge/lexers/**/builtins.rb" NewCops: enable +Rouge: + Enabled: true + Style: Enabled: false @@ -76,12 +80,41 @@ Lint/IneffectiveAccessModifier: Lint/AmbiguousOperatorPrecedence: Enabled: false +# this just is plain broken, disabling +Lint/OutOfRangeRegexpRef: + Enabled: false + +# there are actual reasons to do this +Lint/MissingSuper: + Enabled: false + +# sometimes the arguments are deprecated you guys +Lint/ToEnumArguments: + Enabled: false + +# sometimes we deal with very gnarly strings, this is not useful +Lint/NestedPercentLiteral: + Enabled: false + +# usually not actionable +Lint/DuplicateBranch: + Enabled: false + Naming/BlockForwarding: Enabled: false Naming/PredicateMethod: Enabled: false +Naming/MethodParameterName: + Enabled: false + +Naming/HeredocDelimiterNaming: + Enabled: false + +Naming/VariableNumber: + Enabled: false + Performance/RegexpMatch: Enabled: false diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index f8fd2ea29b..fa63fe2363 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,115 +1,23 @@ # This configuration was generated by # `rubocop --auto-gen-config --exclude-limit 50` -# on 2026-02-27 15:13:26 UTC using RuboCop version 1.85.0. +# on 2026-03-20 18:54:21 UTC using RuboCop version 1.84.2. # 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 # versions of RuboCop, may require this file to be generated again. -# Offense count: 8 -# Configuration parameters: AllowedMethods. -# AllowedMethods: enums -Lint/ConstantDefinitionInBlock: - Exclude: - - 'spec/formatters/html_spec.rb' - - 'spec/lexer_spec.rb' - - 'spec/theme_spec.rb' - -# Offense count: 38 -# Configuration parameters: IgnoreLiteralBranches, IgnoreConstantBranches, IgnoreDuplicateElseBranch. -Lint/DuplicateBranch: - Exclude: - - 'lib/rouge/cli.rb' - - 'lib/rouge/lexers/apache.rb' - - 'lib/rouge/lexers/apex.rb' - - 'lib/rouge/lexers/batchfile.rb' - - 'lib/rouge/lexers/brightscript.rb' - - 'lib/rouge/lexers/common_lisp.rb' - - 'lib/rouge/lexers/coq.rb' - - 'lib/rouge/lexers/css.rb' - - 'lib/rouge/lexers/cython.rb' - - 'lib/rouge/lexers/ecl.rb' - - 'lib/rouge/lexers/idlang.rb' - - 'lib/rouge/lexers/llvm.rb' - - 'lib/rouge/lexers/php.rb' - - 'lib/rouge/lexers/python.rb' - - 'lib/rouge/lexers/robot_framework.rb' - - 'lib/rouge/lexers/ruby.rb' - - 'lib/rouge/lexers/sas.rb' - - 'lib/rouge/lexers/sqf.rb' - - 'lib/rouge/lexers/stan.rb' - - 'lib/rouge/lexers/varnish.rb' - - 'lib/rouge/lexers/viml.rb' - - 'lib/rouge/lexers/yang.rb' - -# Offense count: 3 +# Offense count: 1 # Configuration parameters: AllowComments, AllowEmptyLambdas. Lint/EmptyBlock: Exclude: - 'lib/rouge/lexers/nix.rb' - - 'spec/lexers/terraform_spec.rb' - -# Offense count: 27 -# Configuration parameters: AllowedParentClasses. -Lint/MissingSuper: - Exclude: - - 'lib/rouge/cli.rb' - - 'lib/rouge/formatters/html_inline.rb' - - 'lib/rouge/formatters/html_legacy.rb' - - 'lib/rouge/formatters/html_line_highlighter.rb' - - 'lib/rouge/formatters/html_line_table.rb' - - 'lib/rouge/formatters/html_linewise.rb' - - 'lib/rouge/formatters/html_pygments.rb' - - 'lib/rouge/formatters/html_table.rb' - - 'lib/rouge/formatters/null.rb' - - 'lib/rouge/formatters/terminal256.rb' - - 'lib/rouge/formatters/tex.rb' - - 'lib/rouge/guesser.rb' - - 'lib/rouge/guessers/disambiguation.rb' - - 'lib/rouge/guessers/filename.rb' - - 'lib/rouge/guessers/glob_mapping.rb' - - 'lib/rouge/guessers/mimetype.rb' - - 'lib/rouge/guessers/modeline.rb' - - 'lib/rouge/guessers/source.rb' - - 'lib/rouge/regex_lexer.rb' - - 'lib/rouge/theme.rb' - - 'lib/rouge/util.rb' # Offense count: 4 -Lint/NestedPercentLiteral: - Exclude: - - 'lib/rouge/lexers/hylang.rb' - - 'lib/rouge/lexers/janet.rb' - - 'lib/rouge/lexers/powershell.rb' - - 'spec/lexers/j_spec.rb' - -# Offense count: 1 -Lint/OutOfRangeRegexpRef: - Exclude: - - 'lib/rouge/tex_theme_renderer.rb' - -# Offense count: 1 -Lint/ToEnumArguments: - Exclude: - - 'lib/rouge/lexer.rb' - -# Offense count: 43 Naming/ConstantName: Exclude: - 'lib/rouge/lexers/eiffel.rb' - - 'lib/rouge/themes/gruvbox.rb' - -# Offense count: 8 -# Configuration parameters: ForbiddenDelimiters. -# ForbiddenDelimiters: (?i-mx:(^|\s)(EO[A-Z]{1}|END)(\s|$)) -Naming/HeredocDelimiterNaming: - Exclude: - - 'lib/rouge/tex_theme_renderer.rb' - - 'spec/lexers/mason_spec.rb' - - 'spec/lexers/matlab_spec.rb' - - 'spec/lexers/swift_spec.rb' -# Offense count: 8 +# Offense count: 5 # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: EnforcedStyleForLeadingUnderscores. # SupportedStylesForLeadingUnderscores: disallowed, required, optional @@ -120,7 +28,6 @@ Naming/MemoizedInstanceVariableName: - 'lib/rouge/lexers/hack.rb' - 'lib/rouge/lexers/python.rb' - 'lib/rouge/lexers/verilog.rb' - - 'lib/rouge/lexers/yang.rb' # Offense count: 16 # Configuration parameters: EnforcedStyle, AllowedPatterns, ForbiddenIdentifiers, ForbiddenPatterns. @@ -131,35 +38,6 @@ Naming/MethodName: - 'lib/rouge/lexers/igorpro.rb' - 'lib/rouge/lexers/xpath.rb' -# Offense count: 68 -# Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames. -# AllowedNames: as, at, by, cc, db, id, if, in, io, ip, of, on, os, pp, to -Naming/MethodParameterName: - Exclude: - - 'lib/rouge.rb' - - 'lib/rouge/cli.rb' - - 'lib/rouge/formatter.rb' - - 'lib/rouge/formatters/html.rb' - - 'lib/rouge/formatters/html_legacy.rb' - - 'lib/rouge/formatters/html_line_table.rb' - - 'lib/rouge/formatters/html_linewise.rb' - - 'lib/rouge/formatters/html_pygments.rb' - - 'lib/rouge/formatters/html_table.rb' - - 'lib/rouge/formatters/null.rb' - - 'lib/rouge/formatters/terminal256.rb' - - 'lib/rouge/formatters/tex.rb' - - 'lib/rouge/guessers/disambiguation.rb' - - 'lib/rouge/lexer.rb' - - 'lib/rouge/lexers/coq.rb' - - 'lib/rouge/lexers/escape.rb' - - 'lib/rouge/lexers/plain_text.rb' - - 'lib/rouge/regex_lexer.rb' - - 'lib/rouge/tex_theme_renderer.rb' - - 'lib/rouge/theme.rb' - - 'lib/rouge/token.rb' - - 'lib/rouge/util.rb' - - 'spec/support/lexing.rb' - # Offense count: 40 # Configuration parameters: EnforcedStyle, AllowedIdentifiers, AllowedPatterns, ForbiddenIdentifiers, ForbiddenPatterns. # SupportedStyles: snake_case, camelCase @@ -172,15 +50,6 @@ Naming/VariableName: - 'lib/rouge/lexers/kotlin.rb' - 'lib/rouge/lexers/xpath.rb' -# Offense count: 5 -# Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers, AllowedPatterns. -# SupportedStyles: snake_case, normalcase, non_integer -# AllowedIdentifiers: TLS1_1, TLS1_2, capture3, iso8601, rfc1123_date, rfc822, rfc2822, rfc3339, x86_64 -Naming/VariableNumber: - Exclude: - - 'lib/rouge/lexers/c.rb' - - 'lib/rouge/themes/gruvbox.rb' - # Offense count: 2 # This cop supports unsafe autocorrection (--autocorrect-all). Performance/StringInclude: @@ -230,3 +99,24 @@ Rouge/NoBuildingAlternationPatternInRegexp: - 'lib/rouge/lexers/vala.rb' - 'lib/rouge/lexers/wollok.rb' - 'lib/rouge/lexers/xojo.rb' + +# Offense count: 20 +Rouge/NoHugeCollections: + Exclude: + - 'lib/rouge/lexers/abap.rb' + - 'lib/rouge/lexers/apple_script.rb' + - 'lib/rouge/lexers/cobol.rb' + - 'lib/rouge/lexers/common_lisp.rb' + - 'lib/rouge/lexers/css.rb' + - 'lib/rouge/lexers/datastudio.rb' + - 'lib/rouge/lexers/freefem.rb' + - 'lib/rouge/lexers/hql.rb' + - 'lib/rouge/lexers/idlang.rb' + - 'lib/rouge/lexers/igorpro.rb' + - 'lib/rouge/lexers/janet.rb' + - 'lib/rouge/lexers/openedge.rb' + - 'lib/rouge/lexers/plsql.rb' + - 'lib/rouge/lexers/racket.rb' + - 'lib/rouge/lexers/sas.rb' + - 'lib/rouge/lexers/sql.rb' + - 'lib/rouge/lexers/stata.rb' diff --git a/lib/rouge/cli.rb b/lib/rouge/cli.rb index ef305251bc..3a5e706610 100644 --- a/lib/rouge/cli.rb +++ b/lib/rouge/cli.rb @@ -514,9 +514,7 @@ def run out = [] argv.each do |arg| case arg - when /^(--\w+)=(.*)$/ - out << $1 << $2 - when /^(-\w)(.+)$/ + when /^(--\w+)=(.*)$/, /^(-\w)(.+)$/ out << $1 << $2 else out << arg diff --git a/lib/rouge/lexers/apache.rb b/lib/rouge/lexers/apache.rb index 57de58c11b..1e65858647 100644 --- a/lib/rouge/lexers/apache.rb +++ b/lib/rouge/lexers/apache.rb @@ -17,15 +17,11 @@ class Apache < RegexLexer end def name_for_token(token, tktype) - if SECTIONS.include? token - tktype - elsif DIRECTIVES.include? token - tktype - elsif VALUES.include? token - tktype - else - Text - end + return tktype if SECTIONS.include?(token) + return tktype if DIRECTIVES.include?(token) + return tktype if VALUES.include?(token) + + Text end state :whitespace do diff --git a/lib/rouge/lexers/viml.rb b/lib/rouge/lexers/viml.rb index 066e32dd03..55c7ff3cb7 100644 --- a/lib/rouge/lexers/viml.rb +++ b/lib/rouge/lexers/viml.rb @@ -49,11 +49,11 @@ class VimL < RegexLexer if KEYWORDS[:command].include? name token Keyword - elsif KEYWORDS[:function].include? name - token Name::Builtin - elsif KEYWORDS[:option].include? name - token Name::Builtin - elsif KEYWORDS[:auto].include? name + elsif ( + KEYWORDS[:function].include?(name) || + KEYWORDS[:option].include?(name) || + KEYWORDS[:auto].include?(name) + ) token Name::Builtin else token Text diff --git a/lib/rouge/lexers/yang.rb b/lib/rouge/lexers/yang.rb index a9d54f0663..71352c1c0c 100644 --- a/lib/rouge/lexers/yang.rb +++ b/lib/rouge/lexers/yang.rb @@ -13,74 +13,56 @@ class YANG < RegexLexer id = /[\w-]+(?=[^\w\-\:])\b/ #Keywords from RFC7950 ; oriented at BNF style - def self.top_stmts_keywords - @top_stms_keywords ||= Set.new %w( - module submodule - ) - end + top_keywords = Set.new %w(module submodule) - def self.module_header_stmts_keywords - @module_header_stmts_keywords ||= Set.new %w( - belongs-to namespace prefix yang-version - ) - end + module_header_keywords = Set.new %w(belongs-to namespace prefix yang-version) - def self.meta_stmts_keywords - @meta_stmts_keywords ||= Set.new %w( - contact description organization reference revision - ) - end + meta_keywords = Set.new %w(contact description organization reference revision) - def self.linkage_stmts_keywords - @linkage_stmts_keywords ||= Set.new %w( - import include revision-date - ) - end + linkage_keywords = Set.new %w(import include revision-date) - def self.body_stmts_keywords - @body_stms_keywords ||= Set.new %w( - action argument augment deviation extension feature grouping identity - if-feature input notification output rpc typedef - ) - end + body_keywords = Set.new %w( + action argument augment deviation extension feature grouping identity + if-feature input notification output rpc typedef + ) - def self.data_def_stmts_keywords - @data_def_stms_keywords ||= Set.new %w( - anydata anyxml case choice config container deviate leaf leaf-list - list must presence refine uses when - ) - end + data_def_keywords = Set.new %w( + anydata anyxml case choice config container deviate leaf leaf-list + list must presence refine uses when + ) - def self.type_stmts_keywords - @type_stmts_keywords ||= Set.new %w( - base bit default enum error-app-tag error-message fraction-digits - length max-elements min-elements modifier ordered-by path pattern - position range require-instance status type units value yin-element - ) - end + type_keywords = Set.new %w( + base bit default enum error-app-tag error-message fraction-digits + length max-elements min-elements modifier ordered-by path pattern + position range require-instance status type units value yin-element + ) - def self.list_stmts_keywords - @list_stmts_keywords ||= Set.new %w( - key mandatory unique - ) - end + list_keywords = Set.new %w( + key mandatory unique + ) #RFC7950 other keywords - def self.constants_keywords - @constants_keywords ||= Set.new %w( - add current delete deprecated false invert-match max min - not-supported obsolete replace true unbounded user - ) - end + CONSTANTS = Set.new %w( + add current delete deprecated false invert-match max min + not-supported obsolete replace true unbounded user + ) #RFC7950 Built-In Types - def self.types - @types ||= Set.new %w( - binary bits boolean decimal64 empty enumeration identityref - instance-identifier int16 int32 int64 int8 leafref string uint16 - uint32 uint64 uint8 union - ) - end + TYPES = Set.new %w( + binary bits boolean decimal64 empty enumeration identityref + instance-identifier int16 int32 int64 int8 leafref string uint16 + uint32 uint64 uint8 union + ) + + DECLARATIONS = + top_keywords + + module_header_keywords + + meta_keywords + + linkage_keywords + + body_keywords + + data_def_keywords + + type_keywords + + list_keywords state :comment do rule %r/[^*\/]/, Comment @@ -115,25 +97,11 @@ def self.types rule id do |m| name = m[0].downcase - if self.class.top_stmts_keywords.include? name - token Keyword::Declaration - elsif self.class.module_header_stmts_keywords.include? name - token Keyword::Declaration - elsif self.class.meta_stmts_keywords.include? name - token Keyword::Declaration - elsif self.class.linkage_stmts_keywords.include? name - token Keyword::Declaration - elsif self.class.body_stmts_keywords.include? name - token Keyword::Declaration - elsif self.class.data_def_stmts_keywords.include? name - token Keyword::Declaration - elsif self.class.type_stmts_keywords.include? name - token Keyword::Declaration - elsif self.class.list_stmts_keywords.include? name + if DECLARATIONS.include?(name) token Keyword::Declaration - elsif self.class.types.include? name + elsif TYPES.include? name token Keyword::Type - elsif self.class.constants_keywords.include? name + elsif CONSTANTS.include? name token Name::Constant else token Name diff --git a/lib/rouge/themes/gruvbox.rb b/lib/rouge/themes/gruvbox.rb index 8faf4cc5f6..7baebaca1f 100644 --- a/lib/rouge/themes/gruvbox.rb +++ b/lib/rouge/themes/gruvbox.rb @@ -10,6 +10,7 @@ module Themes class Gruvbox < CSSTheme name 'gruvbox' + # rubocop:disable Naming/ConstantName # global Gruvbox colours {{{ C_dark0_hard = '#1d2021' C_dark0 ='#282828' @@ -122,6 +123,8 @@ def self.make_light! palette orange: C_faded_orange end + # rubocop:enable Naming/ConstantName + dark! mode :light diff --git a/lib/rubocop/cop/rouge/no_huge_collections.rb b/lib/rubocop/cop/rouge/no_huge_collections.rb new file mode 100644 index 0000000000..26036ad3bb --- /dev/null +++ b/lib/rubocop/cop/rouge/no_huge_collections.rb @@ -0,0 +1,37 @@ +module RuboCop + module Cop + module Rouge + class NoHugeCollections < RuboCop::Cop::Base + MSG = 'Avoid collections of over 300 elements. ' \ + 'Place those in a lazy-loaded file, ideally ' \ + 'generated by a Rake task from the relevant documentation.' + + + def_node_matcher :set_literal?, <<~PATTERN + (send (const nil? :Set) :[] ...) + PATTERN + + RESTRICT_ON_SEND = [:[]] + MAX_SIZE = 300 + + Set["1", "2", "3"] + Set.new %w(1 2 3) + + def on_send(node) + return unless set_literal?(node) + + # adjust by 2 for the target and method name + if node.children.size - 2 > MAX_SIZE + add_offense(node) + end + end + + def on_array(node) + if node.children.size >= MAX_SIZE + add_offense(node) + end + end + end + end + end +end diff --git a/spec/formatters/html_spec.rb b/spec/formatters/html_spec.rb index af0266a747..f0d817d837 100644 --- a/spec/formatters/html_spec.rb +++ b/spec/formatters/html_spec.rb @@ -16,11 +16,11 @@ end describe '#inline_theme' do - class InlineTheme < Rouge::CSSTheme - style Name, :bold => true + inline_theme = Class.new(Rouge::CSSTheme) do + style self::Name, :bold => true end - let(:options) { { :inline_theme => InlineTheme.new, :wrap => false } } + let(:options) { { :inline_theme => inline_theme.new, :wrap => false } } let(:output) { subject.format([[Token['Name'], 'foo']]) diff --git a/spec/lexer_spec.rb b/spec/lexer_spec.rb index 8101d83946..5a358d067c 100644 --- a/spec/lexer_spec.rb +++ b/spec/lexer_spec.rb @@ -156,61 +156,61 @@ def incr end it 'delegates' do - class MasterLexer < Rouge::RegexLexer + braces_lexer = Class.new(Rouge::RegexLexer) do + state :root do + rule %r/b/, 'B' + end + end + + master_lexer = Class.new(Rouge::RegexLexer) do state :root do rule %r/a/, 'A' rule %r/{(.*?)}/ do |m| token 'brace', '{' - delegate BracesLexer.new, m[1] + delegate braces_lexer.new, m[1] token 'brace', '}' end end end - class BracesLexer < Rouge::RegexLexer - state :root do - rule %r/b/, 'B' - end - end - - assert_no_errors 'a{b}a', MasterLexer + assert_no_errors 'a{b}a', master_lexer end it 'detects the beginnings of lines with ^ rules' do - class MyLexer < Rouge::RegexLexer + my_lexer = Class.new(Rouge::RegexLexer) do state :root do rule %r/^a/, 'start' rule %r/a/, 'not-start' end end - assert_has_token('start', 'a', MyLexer) - assert_has_token('start', "\na", MyLexer) - deny_has_token('not-start', 'a', MyLexer) - assert_has_token('not-start', 'aa', MyLexer) + assert_has_token('start', 'a', my_lexer) + assert_has_token('start', "\na", my_lexer) + deny_has_token('not-start', 'a', my_lexer) + assert_has_token('not-start', 'aa', my_lexer) end it 'is undetectable by default' do - UndetectableLexer = Class.new(Rouge::Lexer) + undetectable_lexer = Class.new(Rouge::Lexer) - refute { UndetectableLexer.methods(false).include?(:detect?) } - refute { UndetectableLexer.detectable? } + refute { undetectable_lexer.methods(false).include?(:detect?) } + refute { undetectable_lexer.detectable? } end it 'can only be detectable within current scope' do - class DetectableLexer < Rouge::Lexer + detectable_lexer = Class.new(Rouge::Lexer) do def self.detect? text.shebang?('foobar') end end - assert { DetectableLexer.methods(false).include?(:detect?) } - assert { DetectableLexer.detectable? } + assert { detectable_lexer.methods(false).include?(:detect?) } + assert { detectable_lexer.detectable? } - NonDetectableLexer = Class.new(DetectableLexer) + non_detectable_lexer = Class.new(detectable_lexer) - refute { NonDetectableLexer.methods(false).include?(:detect?) } - refute { NonDetectableLexer.detectable? } + refute { non_detectable_lexer.methods(false).include?(:detect?) } + refute { non_detectable_lexer.detectable? } end it 'handles boolean options' do diff --git a/spec/lexers/terraform_spec.rb b/spec/lexers/terraform_spec.rb index 56f3ceedc6..f3a3c113a3 100644 --- a/spec/lexers/terraform_spec.rb +++ b/spec/lexers/terraform_spec.rb @@ -20,11 +20,5 @@ assert_guess :filename => 'foo.tofu' deny_guess :filename => 'foo' end - - it 'guesses by mimetype' do - end - - it 'guesses by source' do - end end end diff --git a/spec/theme_spec.rb b/spec/theme_spec.rb index d059cde82b..dfc231fb67 100644 --- a/spec/theme_spec.rb +++ b/spec/theme_spec.rb @@ -1,17 +1,17 @@ # -*- coding: utf-8 -*- # # frozen_string_literal: true +class TestTheme < Rouge::CSSTheme + style Literal::String, :fg => '#003366', :bold => true + style Literal::String::Backtick, :fg => '#555555', :italic => true +end + describe Rouge::Theme do def squish(str) str.strip.gsub(/\s+/, ' ') end - class MyTheme < Rouge::CSSTheme - style Literal::String, :fg => '#003366', :bold => true - style Literal::String::Backtick, :fg => '#555555', :italic => true - end - - let(:theme) { MyTheme.new } + let(:theme) { TestTheme.new } it 'auto-fills css classes' do rendered = theme.render