From 83f8e29486ed980cf6b2807ab56f91f889f1cb76 Mon Sep 17 00:00:00 2001 From: Kit Lawes Date: Thu, 30 Mar 2017 19:01:38 +0100 Subject: [PATCH 1/4] Support nested lists in the toc --- lib/table_of_contents/parser.rb | 47 ++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/lib/table_of_contents/parser.rb b/lib/table_of_contents/parser.rb index 359bdf1..7cfd559 100644 --- a/lib/table_of_contents/parser.rb +++ b/lib/table_of_contents/parser.rb @@ -13,13 +13,58 @@ def initialize(html) def build_toc toc = %Q{' end + # Returns the list items for entries + def build_lis(entries, min_h_num) + lis = "" + i = 0 + while i < entries.length do + entry = entries[i] + curr_h_num = entry[:node_name][1].to_i + if curr_h_num == min_h_num + + lis << %Q{
  • #{entry[:text]}
  • \n} + + elsif curr_h_num > min_h_num + + lis << %Q{\n} + i += nest_entries.length - 1 + + end + i += 1 + end + lis + end + + # Returns the entries in a nested list + # The nested list starts at the first entry in entries + # The nested list ends at the first entry in entries with depth min_h_num or greater + def get_nest_entries(entries, min_h_num) + nest_entries = [] + for i in 0..(entries.length - 1) + nest_entry = entries[i] + nest_h_num = nest_entry[:node_name][1].to_i + if nest_h_num > min_h_num + nest_entries.push(nest_entry) + else + break + end + end + nest_entries + end + def inject_anchors_into_html @entries.each do |entry| entry[:content_node].add_previous_sibling(%Q{}) From c70c4bb8eb20a129af91b7356f0439e10c02d5dd Mon Sep 17 00:00:00 2001 From: Kit Lawes Date: Thu, 30 Mar 2017 19:05:53 +0100 Subject: [PATCH 2/4] Improve comment --- lib/table_of_contents/parser.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/table_of_contents/parser.rb b/lib/table_of_contents/parser.rb index 7cfd559..588b867 100644 --- a/lib/table_of_contents/parser.rb +++ b/lib/table_of_contents/parser.rb @@ -49,8 +49,8 @@ def build_lis(entries, min_h_num) end # Returns the entries in a nested list - # The nested list starts at the first entry in entries - # The nested list ends at the first entry in entries with depth min_h_num or greater + # The nested list starts at the first entry in entries (inclusive) + # The nested list ends at the first entry in entries with depth min_h_num or greater (exclusive) def get_nest_entries(entries, min_h_num) nest_entries = [] for i in 0..(entries.length - 1) From 504cb287154d2c58e728d6696e7596542b81fd5e Mon Sep 17 00:00:00 2001 From: Kit Lawes Date: Sat, 1 Apr 2017 13:03:53 +0100 Subject: [PATCH 3/4] Make extracting heading number from node name more readable, and place nested lists between li tags --- lib/table_of_contents/parser.rb | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/lib/table_of_contents/parser.rb b/lib/table_of_contents/parser.rb index 588b867..f5e96e5 100644 --- a/lib/table_of_contents/parser.rb +++ b/lib/table_of_contents/parser.rb @@ -11,11 +11,11 @@ def initialize(html) end def build_toc - toc = %Q{
      \n} + toc = %Q{
        \n} min_h_num = 6 @entries.each do |entry| - h_num = entry[:node_name][1].to_i + h_num = entry[:node_name].delete("h").to_i min_h_num = [min_h_num, h_num].min end toc << build_lis(@entries, min_h_num) @@ -29,13 +29,30 @@ def build_lis(entries, min_h_num) i = 0 while i < entries.length do entry = entries[i] - curr_h_num = entry[:node_name][1].to_i + curr_h_num = entry[:node_name].delete("h").to_i if curr_h_num == min_h_num - lis << %Q{
      • #{entry[:text]}
      • \n} + # If the current entry should not be indented in the list, add the entry to the list + lis << %Q{
      • #{entry[:text]}} + # If the next entry should be indented in the list, generate a sublist + if i + 1 < entries.length + next_entry = entries[i + 1] + next_h_num = next_entry[:node_name].delete("h").to_i + if next_h_num > min_h_num + lis << %Q{\n} + lis << %Q{
          \n} + nest_entries = get_nest_entries(entries[i + 1, entries.length], min_h_num) + lis << build_lis(nest_entries, min_h_num + 1) + lis << %Q{
        \n} + i += nest_entries.length + end + end + # Add the closing tag for the current entry in the list + lis << %Q{
      • \n} elsif curr_h_num > min_h_num + # If the current entry should be indented in the list, generate a sublist lis << %Q{
          \n} nest_entries = get_nest_entries(entries[i, entries.length], min_h_num) lis << build_lis(nest_entries, min_h_num + 1) @@ -55,7 +72,7 @@ def get_nest_entries(entries, min_h_num) nest_entries = [] for i in 0..(entries.length - 1) nest_entry = entries[i] - nest_h_num = nest_entry[:node_name][1].to_i + nest_h_num = nest_entry[:node_name].delete("h").to_i if nest_h_num > min_h_num nest_entries.push(nest_entry) else From c412299ac91f2beab1f579c918b8525882844d0f Mon Sep 17 00:00:00 2001 From: Kit Lawes Date: Sat, 1 Apr 2017 13:15:47 +0100 Subject: [PATCH 4/4] Fix failing tests --- lib/table_of_contents/parser.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/table_of_contents/parser.rb b/lib/table_of_contents/parser.rb index f5e96e5..34b149f 100644 --- a/lib/table_of_contents/parser.rb +++ b/lib/table_of_contents/parser.rb @@ -11,7 +11,7 @@ def initialize(html) end def build_toc - toc = %Q{
            \n} + toc = %Q{
              \n} min_h_num = 6 @entries.each do |entry|