# frozen_string_literal: true require_relative 'spec_helper' describe 'Asciidoctor::PDF::Converter - Break' do context 'Line Breaks' do it 'should place text on separate line after explicit line break' do pdf = to_pdf <<~'END', analyze: true foo + bar + baz END (expect pdf.lines).to eql %w(foo bar baz) end it 'should preserve inner empty lines that end with hard line break' do pdf = to_pdf <<~'END', analyze: true foo + filler + filler + filler + bar END expected_gap = ((pdf.find_unique_text 'foo')[:y] - (pdf.find_unique_text 'bar')[:y]).round 4 pdf = to_pdf <<~'END', analyze: true foo + {empty} + {empty} + {empty} + bar END actual_gap = ((pdf.find_unique_text 'foo')[:y] - (pdf.find_unique_text 'bar')[:y]).round 4 (expect actual_gap).to eql (expected_gap) (expect actual_gap).to be > 75 end it 'should preserve newlines in paragraph with hardbreaks option' do pdf = to_pdf <<~'END', analyze: true [%hardbreaks] foo bar baz END (expect pdf.lines).to eql %w(foo bar baz) end end context 'Thematic Breaks' do it 'should draw line for thematic break' do input = <<~'END' before ''' after END pdf = to_pdf input, analyze: true before_text = (pdf.find_text 'before')[0] after_text = (pdf.find_text 'after')[0] pdf = to_pdf input, analyze: :line lines = pdf.lines (expect lines).to have_size 1 line = lines[0] (expect line[:color]).to eql 'EEEEEE' (expect line[:width]).to eql 0.5 (expect line[:from][:x]).to be < line[:to][:x] (expect line[:from][:y]).to eql line[:to][:y] (expect line[:from][:y]).to be < before_text[:y] (expect line[:from][:y]).to be > after_text[:y] end it 'should use solid style for thematic break if not specified' do pdf = to_pdf <<~'END', pdf_theme: { thematic_break_border_style: nil }, analyze: :line ''' END lines = pdf.lines (expect lines).to have_size 1 line = lines[0] (expect line[:width]).to eql 0.5 end it 'should allow theme to configure line width, style, and color of thematic break' do pdf_theme = { thematic_break_border_color: 'AA0000', thematic_break_border_width: 3, thematic_break_border_style: 'double', } input = <<~'END' before ''' after END pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true before_text = (pdf.find_text 'before')[0] after_text = (pdf.find_text 'after')[0] pdf = to_pdf input, pdf_theme: pdf_theme, analyze: :line lines = pdf.lines (expect lines).to have_size 2 line = lines[0] (expect line[:color]).to eql 'AA0000' (expect line[:width]).to eql 1.0 (expect line[:from][:x]).to be < line[:to][:x] (expect line[:from][:y]).to eql line[:to][:y] (expect line[:from][:y]).to be < before_text[:y] (expect line[:from][:y]).to be > after_text[:y] (expect line[:from][:y] - 2).to eql lines[1][:from][:y] end end context 'Page Breaks' do it 'should advance to next page after page break' do pdf = to_pdf <<~'END', analyze: :page foo <<< bar END (expect pdf.pages).to have_size 2 (expect pdf.pages[0][:strings]).to include 'foo' (expect pdf.pages[1][:strings]).to include 'bar' end it 'should insert page break if page does not have columns' do pdf = to_pdf <<~'END', analyze: true = Document Title :notitle: first page [.column] <<< second page END (expect pdf.pages).to have_size 2 (expect (pdf.find_unique_text 'first page')[:page_number]).to eql 1 (expect (pdf.find_unique_text 'second page')[:page_number]).to eql 2 end it 'should not advance to next page if at start of document' do pdf = to_pdf <<~'END', analyze: :page <<< foo END (expect pdf.pages).to have_size 1 end it 'should advance to next page if at start of document and always option is specified' do pdf = to_pdf <<~'END', analyze: true [%always] <<< content END (expect pdf.pages).to have_size 2 (expect (pdf.find_unique_text 'content')[:page_number]).to eql 2 end it 'should not advance to next page if preceding content forced a new page to be started' do pdf = to_pdf <<~'END', analyze: true = Book Title :doctype: book = Part <<< == Chapter END part_text = (pdf.find_text 'Part')[0] (expect part_text[:page_number]).to be 2 chapter_text = (pdf.find_text 'Chapter')[0] (expect chapter_text[:page_number]).to be 3 end it 'should not advance to next page if preceding content advanced page' do pdf = to_pdf <<~END, analyze: true .... #{(['filler'] * 50).join ?\n} .... start of page END start_of_page_text = (pdf.find_text 'start of page')[0] (expect start_of_page_text[:page_number]).to be 2 end it 'should not advance to next column if at start of column in multi-column layout' do pdf = to_pdf <<~'END', pdf_theme: { page_columns: 2 }, analyze: true = Article Title [.column] <<< column 1 END (expect pdf.pages).to have_size 1 text = pdf.find_unique_text 'column 1' (expect text[:x]).to eql 48.24 (expect text[:y]).to be < (pdf.find_unique_text 'Article Title')[:y] end it 'should advance to next column if at start of column in multi-column layout and always option is specified' do pdf = to_pdf <<~'END', pdf_theme: { page_columns: 2 }, analyze: true = Article Title [.column%always] <<< column 1 END (expect pdf.pages).to have_size 1 text = pdf.find_unique_text 'column 1' (expect text[:x]).to be > 48.24 (expect text[:y]).to be < (pdf.find_unique_text 'Article Title')[:y] end it 'should not leave blank page at the end of document' do input = <<~'END' foo <<< END [ {}, { page_background_color: 'eeeeee' }, { page_background_image: %(image:#{fixture_file 'square.svg'}[]) }, ].each do |pdf_theme| pdf = to_pdf input, pdf_theme: pdf_theme, analyze: :page (expect pdf.pages).to have_size 1 end end it 'should change layout if page break specifies page-layout attribute' do pdf = to_pdf <<~'END', analyze: true portrait [page-layout=landscape] <<< landscape END text = pdf.text (expect text).to have_size 2 (expect text[0].values_at :string, :page_number, :x, :y).to eql ['portrait', 1, 48.24, 793.926] (expect text[1].values_at :string, :page_number, :x, :y).to eql ['landscape', 2, 48.24, 547.316] end it 'should change layout if page break specifies layout role' do pdf = to_pdf <<~'END', analyze: true portrait [.landscape] <<< landscape END text = pdf.text (expect text).to have_size 2 (expect text[0].values_at :string, :page_number, :x, :y).to eql ['portrait', 1, 48.24, 793.926] (expect text[1].values_at :string, :page_number, :x, :y).to eql ['landscape', 2, 48.24, 547.316] end it 'should switch layout each time page break specifies layout role' do pdf = to_pdf <<~'END', analyze: true portrait [.landscape] <<< landscape [.portrait] <<< portrait [.landscape] <<< landscape END portrait_text = pdf.find_text 'portrait' (expect portrait_text).to have_size 2 portrait_text.each do |text| page = pdf.page text[:page_number] (expect page[:size]).to eql PDF::Core::PageGeometry::SIZES['A4'] end landscape_text = pdf.find_text 'landscape' (expect landscape_text).to have_size 2 landscape_text.each do |text| page = pdf.page text[:page_number] (expect page[:size]).to eql PDF::Core::PageGeometry::SIZES['A4'].reverse end end it 'should switch layout specified by page break even when it falls at a natural page break' do pdf = to_pdf <<~END, analyze: true portrait [.landscape] <<< #{%(landscape +\n) * 31}landscape [.portrait] <<< portrait END (expect (pdf.page 3)[:size]).to eql PDF::Core::PageGeometry::SIZES['A4'] end it 'should not switch layout specified by page break if value is unrecognized' do pdf = to_pdf <<~END, analyze: true portrait [.landscape] <<< landscape [page-layout=unknown] <<< landscape END (expect (pdf.page 3)[:size]).to eql (pdf.page 2)[:size] end it 'should insert page break in column layout' do pdf = to_pdf <<~END, pdf_theme: { page_columns: 2 }, analyze: true = Article Title column 1, page 1 <<< column 1, page 2 END c1p1_text = pdf.find_unique_text 'column 1, page 1' (expect c1p1_text[:x]).to eql 48.24 (expect c1p1_text[:page_number]).to eql 1 c1p2_text = pdf.find_unique_text 'column 1, page 2' (expect c1p2_text[:x]).to eql 48.24 (expect c1p2_text[:page_number]).to eql 2 end it 'should insert page break with custom layout in column layout' do pdf = to_pdf <<~END, pdf_theme: { page_columns: 2 }, analyze: true = Article Title column 1, page 1 [page-layout=landscape] <<< column 1, page 2 END c1p1_text = pdf.find_unique_text 'column 1, page 1' (expect c1p1_text[:x]).to eql 48.24 (expect c1p1_text[:page_number]).to eql 1 p1 = pdf.pages[0] (expect p1[:size][0]).to be < p1[:size][1] c1p2_text = pdf.find_unique_text 'column 1, page 2' (expect c1p2_text[:x]).to eql 48.24 (expect c1p2_text[:page_number]).to eql 2 p2 = pdf.pages[1] (expect p2[:size][0]).to be > p2[:size][1] end it 'should insert column break in column layout if column role is specified' do pdf = to_pdf <<~END, pdf_theme: { page_columns: 2 }, analyze: true = Article Title column 1, page 1 [.column] <<< column 2, page 1 END c1p1_text = pdf.find_unique_text 'column 1, page 1' (expect c1p1_text[:x]).to eql 48.24 (expect c1p1_text[:page_number]).to eql 1 c2p1_text = pdf.find_unique_text 'column 2, page 1' (expect c2p1_text[:x]).to be > 48.24 (expect c2p1_text[:page_number]).to eql 1 end it 'should insert page break in column layout if page layout is specified even if column role is specified' do pdf = to_pdf <<~END, pdf_theme: { page_columns: 2 }, analyze: true = Article Title column 1, page 1 [.column,page-layout=landscape] <<< column 1, page 2 END c1p1_text = pdf.find_unique_text 'column 1, page 1' (expect c1p1_text[:x]).to eql 48.24 (expect c1p1_text[:page_number]).to eql 1 c1p2_text = pdf.find_unique_text 'column 1, page 2' (expect c1p2_text[:x]).to eql 48.24 (expect c1p2_text[:page_number]).to eql 2 end end end