lib/collapser.rb in markdown_exec-2.6.0 vs lib/collapser.rb in markdown_exec-2.7.0

- old
+ new

@@ -1,5 +1,10 @@ +#!/usr/bin/env bundle exec ruby +# frozen_string_literal: true + +# encoding=utf-8 +# v2024-12-02 require_relative 'constants' class Collapser attr_accessor :options, :state @@ -10,15 +15,15 @@ state: Hash.new(nil) ) @collapsed_level = collapsed_level @collapsible_types = collapsible_types.dup @options = options.dup - @state = state.dup # do not dup + @state = state # do not dup end def collapse_per_options?(fcb, options: @options) - criteria = options["#{fcb.type}#{fcb.level}_collapse".to_sym] + criteria = options[:"#{fcb.type}#{fcb.level}_collapse"] return false if criteria.nil? criteria end @@ -34,11 +39,11 @@ def collapse_per_token?(fcb) fcb.token == COLLAPSIBLE_TOKEN_COLLAPSE end def collapsible_per_options?(fcb, options: @options) - criteria = options["#{fcb.type}#{fcb.level}_collapsible".to_sym] + criteria = options[:"#{fcb.type}#{fcb.level}_collapsible"] return false if criteria.nil? criteria end @@ -81,23 +86,21 @@ # Currently collapsed; evaluate for the current block fcb.collapse = collapse?(fcb, initialize: initialize) collapsed_level = fcb.level if fcb.collapse fcb.hide = true # block is at a deeper level thus hidden - else + elsif fcb.collapsible # Currently expanded; evaluate for the current block - if fcb.collapsible - fcb.collapse = collapse?(fcb, initialize: initialize) - collapsed_level = fcb.collapse ? fcb.level : nil - fcb.hide = false - elsif collapsible_per_type?(fcb) - fcb.collapsible = false - fcb.collapse = false - fcb.hide = false - else - fcb.hide = true - end + fcb.collapse = collapse?(fcb, initialize: initialize) + collapsed_level = fcb.collapse ? fcb.level : nil + fcb.hide = false + elsif collapsible_per_type?(fcb) + fcb.collapsible = false + fcb.collapse = false + fcb.hide = false + else + fcb.hide = true end @state[fcb.id] = fcb.level if fcb.collapse collapsed_level end @@ -145,11 +148,11 @@ end def test_analyze # Define test scenarios as arrays of FCB objects and expected filtered results - # :id, :type, :level, :token + # :id, :type, :level, :token (in order for FCB.new) ff_h1a = ['h1a', 'heading', 1, ''] ff_h1b = ['h1b', 'heading', 1, ''] ff_h2a = ['h2a', 'heading', 2, ''] ff_h2b = ['h2b', 'heading', 2, ''] ff_t1 = ['t1', 'text', nil, ''] @@ -157,67 +160,98 @@ ff_t3 = ['t3', 'text', nil, ''] ff_t4 = ['t4', 'text', nil, ''] ff_h1a_collapse = ['h1a', 'heading', 1, COLLAPSIBLE_TOKEN_COLLAPSE] ff_h1a_expand = ['h1a', 'heading', 1, COLLAPSIBLE_TOKEN_EXPAND] ff_h1b_expand = ['h1b', 'heading', 1, COLLAPSIBLE_TOKEN_EXPAND] + ff_h2a_collapse = ['h2a', 'heading', 2, COLLAPSIBLE_TOKEN_COLLAPSE] + ff_h2b_collapse = ['h2b', 'heading', 2, COLLAPSIBLE_TOKEN_COLLAPSE] - # :collapse, :collapsible, :hide + # :collapse, :collapsible, :hide (in order for FCB.new) cc_init = [false, false, false] cc_collapse = [true, false, false] cc_collapse_collapsible = [true, true, false] cc_collapsible = [false, true, false] cc_collapsible_hide = [false, true, true] cc_hide = [false, false, true] cc_undefined_hide = [nil, nil, false] + fc_h1a__collapse = FCB.new(*ff_h1a, *cc_collapse) + fc_h1a__collapse_collapsible = FCB.new(*ff_h1a, *cc_collapse_collapsible) + fc_h1a__collapsed_init = FCB.new(*ff_h1a_collapse, *cc_init) + fc_h1a__collapsible = FCB.new(*ff_h1a, *cc_collapsible) + fc_h1a__collapsible_hide = FCB.new(*ff_h1a, *cc_collapsible_hide) + fc_h1a__expanded_init = FCB.new(*ff_h1a_expand, *cc_init) fc_h1a__init = FCB.new(*ff_h1a, *cc_init) + fc_h1b__init = FCB.new(*ff_h1b, *cc_init) - fc_h2a__init = FCB.new(*ff_h2a, *cc_init) - fc_h2b__init = FCB.new(*ff_h2b, *cc_init) - fc_t1__init = FCB.new(*ff_t1, *cc_init) - fc_t2__init = FCB.new(*ff_t2, *cc_init) - fc_t3__init = FCB.new(*ff_t3, *cc_init) - fc_t4__init = FCB.new(*ff_t4, *cc_init) - fc_h1a__collapse = FCB.new(*ff_h1a, *cc_collapse) - - fc_h1a__collapse_collapsible = FCB.new(*ff_h1a, *cc_collapse_collapsible) + fc_h2a__collapse = FCB.new(*ff_h2a, *cc_collapse) fc_h2a__collapse_collapsible = FCB.new(*ff_h2a, *cc_collapse_collapsible) - - fc_h1a__collapsible = FCB.new(*ff_h1a, *cc_collapsible) + fc_h2a__collapsed_collapsible = FCB.new(*ff_h2a_collapse, *cc_collapsible) fc_h2a__collapsible = FCB.new(*ff_h2a, *cc_collapsible) + fc_h2a__hide = FCB.new(*ff_h2a, *cc_hide) + fc_h2a__init = FCB.new(*ff_h2a, *cc_init) - fc_h1a__collapsible_hide = FCB.new(*ff_h1a, *cc_collapsible_hide) + fc_h2b__init = FCB.new(*ff_h2b, *cc_init) fc_t1__hide = FCB.new(*ff_t1, *cc_hide) + fc_t1__init = FCB.new(*ff_t1, *cc_init) fc_t2__hide = FCB.new(*ff_t2, *cc_hide) - fc_h2a__hide = FCB.new(*ff_h2a, *cc_hide) + fc_t2__init = FCB.new(*ff_t2, *cc_init) + fc_t3__init = FCB.new(*ff_t3, *cc_init) + fc_t4__hide = FCB.new(*ff_t4, *cc_hide) + fc_t4__init = FCB.new(*ff_t4, *cc_init) analyze_cases = { with_token: [ { name: 'collapse', - fcbs: [FCB.new(*ff_h1a_collapse, *cc_init)], + fcbs: [fc_h1a__collapsed_init], expected: [FCB.new(*ff_h1a_collapse, *cc_collapse)] }, { name: 'expand', - fcbs: [FCB.new(*ff_h1a_expand, *cc_init)], - expected: [FCB.new(*ff_h1a_expand, *cc_init)] }, + fcbs: [fc_h1a__expanded_init], + expected: [fc_h1a__expanded_init] }, { name: 'collapse, against options', - fcbs: [FCB.new(*ff_h1a_collapse, *cc_init)], + fcbs: [fc_h1a__collapsed_init], options: { heading1_collapse: false }, expected: [FCB.new(*ff_h1a_collapse, *cc_collapse)] }, { name: 'expand, against options', - fcbs: [FCB.new(*ff_h1a_expand, *cc_init)], + fcbs: [fc_h1a__expanded_init], options: { heading1_collapse: true }, - expected: [FCB.new(*ff_h1a_expand, *cc_init)] }, + expected: [fc_h1a__expanded_init] } ], with_no_state: [ - { name: ' ', - fcbs: [FCB.new(*ff_h1a_expand, *cc_init), fc_t1__init, fc_h2a__init, fc_t2__init, FCB.new(*ff_h1b_expand, *cc_init), fc_t3__init, fc_h2b__init, fc_t4__init], + { name: 'heading2_collapse', + fcbs: [ + fc_h1a__init, + fc_h2a__init, + fc_h1b__init, + fc_h2b__init + ], options: { heading2_collapse: true }, - expected: [FCB.new(*ff_h1a_expand, *cc_init), fc_t1__init, FCB.new(*ff_h2a, *cc_collapse), FCB.new(*ff_h1b_expand, *cc_init), fc_t3__init, FCB.new(*ff_h2b, *cc_collapse)] }, + expected: [ + fc_h1a__init, + fc_h2a__collapse, # s/b fc_h2a__collapse_collapsible, ok for test + fc_h1b__init, + fc_h2b__init # s/b fc_h2b__collapse_collapsible, ok for test + ] }, + { name: 'hide subsections', + fcbs: [ + fc_h1a__init, fc_t1__init, + fc_h2a__init, fc_t2__init, + fc_h1b__init, fc_t3__init, + fc_h2b__init, fc_t4__init + ], + options: { heading2_collapse: true }, + expected: [ + fc_h1a__init, fc_t1__init, + fc_h2a__collapse, fc_t2__hide, + fc_h1b__init, fc_t3__init, + fc_h2b__init, fc_t4__hide + ] }, + { name: 'not collapsible', fcbs: [fc_h1a__init], options: {}, expected: [fc_h1a__init] }, @@ -261,36 +295,38 @@ fcbs: [fc_h1a__init, fc_h2a__init, fc_t1__init], options: { heading2_collapse: true, heading2_collapsible: true }, expected: [fc_h1a__init, fc_h2a__collapse_collapsible, - fc_t1__hide] }, + fc_t1__hide] } ], with_empty_state: [ { name: 'expanded remains expanded', fcbs: [fc_h1a__init], options: { heading1_collapsible: true }, initialize: false, - expected: [fc_h1a__collapsible] }, + expected: [fc_h1a__collapsible] } ], with_collapsed_state: [ { name: 'collapsed remains collapsed', fcbs: [fc_h1a__collapse_collapsible], options: { heading1_collapsible: true }, - state: { "h1a" => 1 }, + state: { 'h1a' => 1 }, initialize: false, - expected: [fc_h1a__collapse_collapsible] }, + expected: [fc_h1a__collapse_collapsible] } ] } analyze_cases.each do |name, test_cases| test_cases.each_with_index do |test_case, index| - @collapser = Collapser.new(collapsed_level: test_case[:collapsed_level], - collapsible_types: test_case[:collapsible_types] || COLLAPSIBLE_TYPES, - options: (test_case[:options] || OPTIONS).dup, - state: (test_case[:state] || STATE).dup) + @collapser = Collapser.new( + collapsed_level: test_case[:collapsed_level], + collapsible_types: test_case[:collapsible_types] || COLLAPSIBLE_TYPES, + options: (test_case[:options] || OPTIONS).dup, + state: (test_case[:state] || STATE).dup + ) analysis = @collapser.analyze( test_case[:fcbs], initialize: test_case[:initialize].nil? ? true : test_case[:initialize] ) assert_equal test_case[:expected], analysis,