Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 53 additions & 2 deletions lib/prawn_html/tags/li.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ def block?

def before_content
return if @before_content_once

@before_content_once = @counter ? "#{@counter}. " : "#{@symbol} "
@before_content_once = @counter ? "#{counter_display(@counter, parent.attrs.type)}. " : "#{@symbol} "
end

def block_styles
Expand All @@ -34,6 +33,58 @@ def on_context_add(_context)
@symbol = parent.styles[:list_style_type] || '•'
end
end

def counter_display(counter, ol_type = '1')
case ol_type
when '1'
counter.to_s
when 'a'
to_char(counter).downcase
when 'A'
to_char(counter)
when 'i'
to_roman(counter).downcase
when 'I'
to_roman(counter)
else
counter.to_s
end
end

def to_roman(num)
roman_arr = {
1000 => "M",
900 => "CM",
500 => "D",
400 => "CD",
100 => "C",
90 => "XC",
50 => "L",
40 => "XL",
10 => "X",
9 => "IX",
5 => "V",
4 => "IV",
1 => "I"
}
roman_arr.reduce(+"") do |roman_res, (arab, roman)|
whole_part, num = num.divmod(arab)
roman_res << roman * whole_part
end
end

def to_char(num)
chars = ("A".."Z").to_a
return "" if num < 1
s = +""
q = num
loop do
q, r = (q - 1).divmod(26)
s.prepend(chars[r])
break if q.zero?
end
s
end
end
end
end
100 changes: 100 additions & 0 deletions spec/units/prawn_html/tags/li_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,105 @@
it 'sets the counter in before content' do
expect(before_content).to eq('1. ')
end

let(:parent_i) { PrawnHtml::Tags::Ol.new(:ol, attributes: { 'type' => 'i' }) }
let(:parent_I) { PrawnHtml::Tags::Ol.new(:ol, attributes: { 'type' => 'I' }) }
let(:parent_a) { PrawnHtml::Tags::Ol.new(:ol, attributes: { 'type' => 'a' }) }
let(:parent_A) { PrawnHtml::Tags::Ol.new(:ol, attributes: { 'type' => 'A' }) }

it 'sets the counter in before content with type i' do
li.parent = parent_i
expect(before_content).to eq('i. ')
end

it 'sets the counter in before content with type I' do
li.parent = parent_I
expect(before_content).to eq('I. ')
end

it 'sets the counter in before content with type a' do
li.parent = parent_a
expect(before_content).to eq('a. ')
end

it 'sets the counter in before content with type A' do
li.parent = parent_A
expect(before_content).to eq('A. ')
end

end

describe 'before_content for different types' do
subject(:before_content) { li.before_content }

let(:context) { instance_double(PrawnHtml::Context) }
let(:parent) { PrawnHtml::Tags::Ol.new(:ol) }

before do
li.parent = parent
li.on_context_add(context)
end

it 'sets the counter for type i' do
expect(li.counter_display(1, 'i')).to eq('i')
expect(li.counter_display(2, 'i')).to eq('ii')
expect(li.counter_display(3, 'i')).to eq('iii')
expect(li.counter_display(4, 'i')).to eq('iv')
expect(li.counter_display(5, 'i')).to eq('v')
expect(li.counter_display(6, 'i')).to eq('vi')
expect(li.counter_display(7, 'i')).to eq('vii')
expect(li.counter_display(8, 'i')).to eq('viii')
expect(li.counter_display(9, 'i')).to eq('ix')
expect(li.counter_display(10, 'i')).to eq('x')
end
it 'sets the counter for type I' do
expect(li.counter_display(1, 'I')).to eq('I')
expect(li.counter_display(2, 'I')).to eq('II')
expect(li.counter_display(3, 'I')).to eq('III')
expect(li.counter_display(4, 'I')).to eq('IV')
expect(li.counter_display(5, 'I')).to eq('V')
expect(li.counter_display(6, 'I')).to eq('VI')
expect(li.counter_display(7, 'I')).to eq('VII')
expect(li.counter_display(8, 'I')).to eq('VIII')
expect(li.counter_display(9, 'I')).to eq('IX')
expect(li.counter_display(10, 'I')).to eq('X')
end
it 'sets the counter for type A' do
expect(li.counter_display(1, 'A')).to eq('A')
expect(li.counter_display(2, 'A')).to eq('B')
expect(li.counter_display(3, 'A')).to eq('C')
expect(li.counter_display(4, 'A')).to eq('D')
expect(li.counter_display(5, 'A')).to eq('E')
expect(li.counter_display(6, 'A')).to eq('F')
expect(li.counter_display(7, 'A')).to eq('G')
expect(li.counter_display(8, 'A')).to eq('H')
expect(li.counter_display(9, 'A')).to eq('I')
expect(li.counter_display(10, 'A')).to eq('J')
end
it 'sets the counter for type a' do
expect(li.counter_display(1, 'a')).to eq('a')
expect(li.counter_display(2, 'a')).to eq('b')
expect(li.counter_display(3, 'a')).to eq('c')
expect(li.counter_display(4, 'a')).to eq('d')
expect(li.counter_display(5, 'a')).to eq('e')
expect(li.counter_display(6, 'a')).to eq('f')
expect(li.counter_display(7, 'a')).to eq('g')
expect(li.counter_display(8, 'a')).to eq('h')
expect(li.counter_display(9, 'a')).to eq('i')
expect(li.counter_display(10, 'a')).to eq('j')
end
it 'sets the counter for type 1' do
expect(li.counter_display(1)).to eq('1')
expect(li.counter_display(2)).to eq('2')
expect(li.counter_display(3)).to eq('3')
expect(li.counter_display(4)).to eq('4')
expect(li.counter_display(5)).to eq('5')
expect(li.counter_display(6)).to eq('6')
expect(li.counter_display(7)).to eq('7')
expect(li.counter_display(8)).to eq('8')
expect(li.counter_display(9)).to eq('9')
expect(li.counter_display(10)).to eq('10')
end

end
end