Skip to content

Commit

Permalink
Add configuration to enable ordered list
Browse files Browse the repository at this point in the history
* Created new configuration option to enable ordered list through use_ordered_list input
* Default behaviour is false so users will continue to have ul tags
* Using existing class configuration, user can change styling on top ol tag and sub listing ol tags separately
* No ability to update styling on sub-nested ol tags separately but code is open to this change
* Added tests for new logic
* Update README with example of usage and render
  • Loading branch information
zsyed91 authored and toshimaru committed Oct 12, 2020
1 parent 5c93fa9 commit d6c4d04
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 6 deletions.
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
- [Skip TOC Section](#skip-toc-section)
- [CSS Styling](#css-styling)
- [Custom CSS Class](#custom-css-class)
- [Using Unordered/Ordered lists](#using-unorderedordered-lists)

## Installation

Expand Down Expand Up @@ -151,6 +152,7 @@ toc:
sublist_class: ''
item_class: toc-entry
item_prefix: toc-
use_ordered_list: false
```

## Customization
Expand Down Expand Up @@ -245,3 +247,39 @@ toc:
# Default is "toc-":
item_prefix: item-
```

### Using Unordered/Ordered lists

By default the table of contents will be generated as an unordered list via `<ul></ul>` tags. This can be configured to use ordered lists instead `<ol></ol>`.
This can be configured in `_config.yml`:

```yml
toc:
use_ordered_list: true # default is false
```

In order to change the list type, use the [list-style-type](https://developer.mozilla.org/en-US/docs/Web/CSS/list-style-type) css property.
Add a class to the `sublist_class` configuration to append it to the `ol` tags so that you can add the `list-style-type` property.

Example

```yml
toc:
use_ordered_list: true
list_class: my-list-class
sublist_class: my-sublist-class
```

```css
.my-list-class {
list-style-type: upper-alpha;
}

.my-sublist-class: {
list-style-type: lower-alpha;
}
```

This will produce:

![screenshot](https://user-images.githubusercontent.com/7675276/85813980-a0ea5a80-b719-11ea-9458-ccf9b86a778b.png)
7 changes: 5 additions & 2 deletions lib/table_of_contents/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ module TableOfContents
# jekyll-toc configuration class
class Configuration
attr_reader :toc_levels, :no_toc_class, :no_toc_section_class,
:list_class, :sublist_class, :item_class, :item_prefix
:list_class, :sublist_class, :item_class, :item_prefix,
:use_ordered_list

DEFAULT_CONFIG = {
'min_level' => 1,
Expand All @@ -14,7 +15,8 @@ class Configuration
'list_class' => 'section-nav',
'sublist_class' => '',
'item_class' => 'toc-entry',
'item_prefix' => 'toc-'
'item_prefix' => 'toc-',
'use_ordered_list' => false
}.freeze

def initialize(options)
Expand All @@ -27,6 +29,7 @@ def initialize(options)
@sublist_class = options['sublist_class']
@item_class = options['item_class']
@item_prefix = options['item_prefix']
@use_ordered_list = options['use_ordered_list']
end

private
Expand Down
15 changes: 13 additions & 2 deletions lib/table_of_contents/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ module TableOfContents
class Parser
include ::Jekyll::TableOfContents::Helper

ORDERED_LIST_HTML_TAG = 'ol'
UNORDERED_LIST_HTML_TAG = 'ul'

def initialize(html, options = {})
@doc = Nokogiri::HTML::DocumentFragment.parse(html)
@configuration = Configuration.new(options)
Expand All @@ -19,7 +22,7 @@ def toc
end

def build_toc
%(<ul class="#{@configuration.list_class}">\n#{build_toc_list(@entries)}</ul>)
%(<#{list_tag} class="#{@configuration.list_class}">\n#{build_toc_list(@entries)}</#{list_tag}>)
end

def inject_anchors_into_html
Expand Down Expand Up @@ -74,7 +77,7 @@ def build_toc_list(entries)
next_i = i + 1
if next_i < entries.count && entries[next_i][:h_num] > min_h_num
nest_entries = get_nest_entries(entries[next_i, entries.count], min_h_num)
toc_list << %(\n<ul#{ul_attributes}>\n#{build_toc_list(nest_entries)}</ul>\n)
toc_list << %(\n<#{list_tag}#{ul_attributes}>\n#{build_toc_list(nest_entries)}</#{list_tag}>\n)
i += nest_entries.count
end
# Add the closing tag for the current entry in the list
Expand Down Expand Up @@ -121,6 +124,14 @@ def toc_headings_within(class_name)
def ul_attributes
@ul_attributes ||= @configuration.sublist_class.empty? ? '' : %( class="#{@configuration.sublist_class}")
end

def use_ordered_list?
@configuration.use_ordered_list
end

def list_tag
use_ordered_list? ? ORDERED_LIST_HTML_TAG : UNORDERED_LIST_HTML_TAG
end
end
end
end
76 changes: 76 additions & 0 deletions test/parser/test_ordered_list.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# frozen_string_literal: true

require 'test_helper'

class TestOrderedList < Minitest::Test
include TestHelpers

def test_default_configuration
configuration = Jekyll::TableOfContents::Configuration.new({})

assert_equal configuration.use_ordered_list, false
end

def test_disabled_ordered_list
configuration = Jekyll::TableOfContents::Configuration.new('use_ordered_list' => false)

assert_equal configuration.use_ordered_list, false
end

def test_enabled_ordered_list
configuration = Jekyll::TableOfContents::Configuration.new('use_ordered_list' => true)

assert_equal configuration.use_ordered_list, true
end

def test_basic_ordered_list_top_heading
parse_with_ordered_list
html = @parser.toc

assert_match(/^<ol class="section-nav">/, html)
end

def test_ordered_list_sub_headings
parse_with_ordered_list
html = @parser.toc

assert_match(/<ol>\n<li class="toc-entry/, html)
end

def test_ordered_list_top_heading_with_classes
parse_with_ordered_list_and_classes
html = @parser.toc

assert_match(/^<ol class="top-list-class">/, html)
end

def test_ordered_list_sub_headings_with_classes
parse_with_ordered_list_and_classes
html = @parser.toc

assert_match(/<ol class="sublist-class">/, html)
end

def test_ordered_list_subheadings_with_classes_nested_structure
parse_with_ordered_list_and_classes
html = @parser.toc

occurrences = html.scan(/<ol class="sublist-class">/).count

assert_equal occurrences, 5
end

private

def parse_with_ordered_list
read_html_and_create_parser('use_ordered_list' => true)
end

def parse_with_ordered_list_and_classes
read_html_and_create_parser(
'use_ordered_list' => true,
'list_class' => 'top-list-class',
'sublist_class' => 'sublist-class'
)
end
end
2 changes: 2 additions & 0 deletions test/test_configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ def test_default_conf1guration
assert_equal configuration.sublist_class, ''
assert_equal configuration.item_class, 'toc-entry'
assert_equal configuration.item_prefix, 'toc-'
assert_equal configuration.use_ordered_list, false
end

def test_type_error
Expand All @@ -23,5 +24,6 @@ def test_type_error
assert_equal configuration.sublist_class, ''
assert_equal configuration.item_class, 'toc-entry'
assert_equal configuration.item_prefix, 'toc-'
assert_equal configuration.use_ordered_list, false
end
end
4 changes: 2 additions & 2 deletions test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
HTML

module TestHelpers
def read_html_and_create_parser
@parser = Jekyll::TableOfContents::Parser.new(SIMPLE_HTML)
def read_html_and_create_parser(options = {})
@parser = Jekyll::TableOfContents::Parser.new(SIMPLE_HTML, options)
end
end

0 comments on commit d6c4d04

Please sign in to comment.