File: paragraph_spec.rb

package info (click to toggle)
ruby-asciidoctor-pdf 2.3.19-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 15,972 kB
  • sloc: ruby: 44,316; sh: 133; java: 45; makefile: 4
file content (302 lines) | stat: -rw-r--r-- 10,554 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
# frozen_string_literal: true

require_relative 'spec_helper'

describe 'Asciidoctor::PDF::Converter - Paragraph' do
  it 'should normalize newlines and whitespace' do
    pdf = to_pdf <<~EOS, analyze: true
    He's  a  real  nowhere  man,
    Sitting in his nowhere land,
    Making all his nowhere plans\tfor nobody.
    EOS
    (expect pdf.text).to have_size 1
    text = pdf.text[0][:string]
    (expect text).not_to include '  '
    (expect text).not_to include ?\t
    (expect text).not_to include ?\n
    (expect text).to include 'man, Sitting'
  end

  it 'should allow paragraph to flow over page boundary with correct top placement' do
    pdf_theme = {
      role_outline_border_width: 0.5,
      role_outline_border_color: '0000EE',
    }
    with_content_spacer 50, 675 do |spacer_path|
      input = <<~EOS
      [.outline]#top#

      image::#{spacer_path}[]

      #{(lorem_ipsum '2-sentences-1-paragraph').sub 'non', '[.outline]#non#'}
      #{(['fillmefillme'] * 380).join ' '} [.outline]#fin#
      EOS

      pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
      (expect pdf.pages).to have_size 3
      (expect (pdf.find_unique_text 'top')[:page_number]).to eql 1
      (expect (pdf.find_unique_text 'non')[:page_number]).to eql 2
      (expect (pdf.find_unique_text 'fin')[:page_number]).to eql 3
      outlines = (to_pdf input, pdf_theme: pdf_theme, analyze: :rect).rectangles.reject {|it| it[:width] == 50.0 }
      (expect outlines).to have_size 3
      reference_outline, subject1_outline, subject2_outline = outlines
      expected_top = pdf.pages[0][:size][1] - 36 - 0.75
      initial_top = reference_outline.yield_self {|it| it[:point][1] + it[:height] }
      (expect initial_top).to eql expected_top
      top_after_first_page_break = subject1_outline.yield_self {|it| it[:point][1] + it[:height] }
      (expect top_after_first_page_break).to eql initial_top
      top_after_second_page_break = subject2_outline.yield_self {|it| it[:point][1] + it[:height] }
      (expect top_after_second_page_break).to eql initial_top
    end
  end

  it 'should indent first line of justified paragraph if prose_text_indent key is set in theme' do
    pdf = to_pdf (lorem_ipsum '2-paragraphs'), pdf_theme: { prose_text_indent: 18 }, analyze: true

    (expect pdf.text).to have_size 4
    (expect pdf.text[0][:x]).to be > pdf.text[1][:x]
    (expect pdf.text[2][:x]).to be > pdf.text[3][:x]
  end

  it 'should indent first line of left-aligned paragraph if prose_text_indent key is set in theme' do
    pdf = to_pdf (lorem_ipsum '2-paragraphs'), pdf_theme: { base_text_align: 'left', prose_text_indent: 18 }, analyze: true

    (expect pdf.text).to have_size 4
    (expect pdf.text[0][:x]).to be > pdf.text[1][:x]
    (expect pdf.text[2][:x]).to be > pdf.text[3][:x]
  end

  it 'should not indent first line of paragraph if text alignment is center' do
    input = <<~'EOS'
    [.text-center]
    x
    EOS

    expected_x = (to_pdf input, analyze: true).text[0][:x]
    actual_x = (to_pdf input, pdf_theme: { prose_text_indent: 18 }, analyze: true).text[0][:x]

    (expect actual_x).to eql expected_x
  end

  it 'should not indent first line of paragraph if text alignment is right' do
    input = <<~'EOS'
    [.text-right]
    x
    EOS

    expected_x = (to_pdf input, analyze: true).text[0][:x]
    actual_x = (to_pdf input, pdf_theme: { prose_text_indent: 18 }, analyze: true).text[0][:x]

    (expect actual_x).to eql expected_x
  end

  it 'should not alter line height of wrapped lines when prose_text_indent is set in theme that uses a TTF font' do
    input = lorem_ipsum '4-sentences-2-paragraphs'

    pdf = to_pdf input, analyze: true

    last_line_y = pdf.text[-1][:y]

    pdf = to_pdf input, pdf_theme: { prose_text_indent: 18 }, analyze: true

    (expect pdf.text[-1][:y]).to eql last_line_y
  end

  it 'should not alter line height of wrapped lines when prose_text_indent is set in theme that uses an AFM font' do
    input = lorem_ipsum '4-sentences-2-paragraphs'

    pdf = to_pdf input, pdf_theme: { extends: 'base' }, analyze: true

    last_line_y = pdf.text[-1][:y]

    pdf = to_pdf input, pdf_theme: { extends: 'base', prose_text_indent: 18 }, analyze: true

    (expect pdf.text[-1][:y]).to eql last_line_y
  end

  it 'should use prose_margin_inner between paragraphs when prose_text_indent key is set in theme' do
    pdf = to_pdf <<~EOS, pdf_theme: { prose_text_indent: 18, prose_margin_inner: 0 }, analyze: true
    #{lorem_ipsum '2-sentences-2-paragraphs'}

    * list item
    EOS

    line_spacing = 1.upto(3).map {|i| (pdf.text[i - 1][:y] - pdf.text[i][:y]).round 2 }.uniq
    (expect line_spacing).to have_size 1
    (expect line_spacing[0]).to eql 15.78
    (expect pdf.text[0][:x]).to be > pdf.text[1][:x]
    (expect pdf.text[2][:x]).to be > pdf.text[3][:x]
    list_item_text = (pdf.find_text 'list item')[0]
    (expect (pdf.text[3][:y] - list_item_text[:y]).round 2).to eql 27.78
  end

  it 'should use prose_margin_inner between paragraphs even when prose_text_indent key in theme is set to 0' do
    pdf = to_pdf <<~EOS, pdf_theme: { prose_text_indent: 0, prose_margin_inner: 0 }, analyze: true
    #{lorem_ipsum '2-sentences-2-paragraphs'}

    * list item
    EOS

    line_spacing = 1.upto(3).map {|i| (pdf.text[i - 1][:y] - pdf.text[i][:y]).round 2 }.uniq
    (expect line_spacing).to have_size 1
    (expect line_spacing[0]).to eql 15.78
    (expect pdf.text[0][:x]).to eql pdf.text[1][:x]
    (expect pdf.text[2][:x]).to eql pdf.text[3][:x]
    list_item_text = (pdf.find_text 'list item')[0]
    (expect (pdf.text[3][:y] - list_item_text[:y]).round 2).to eql 27.78
  end

  it 'should indent first line of inner paragraphs if prose_text_indent_inner key is set in theme' do
    left_margin = (to_pdf 'text', analyze: true).text[0][:x]
    pdf_theme = {
      prose_text_indent_inner: 10.5,
      prose_margin_inner: 0,
    }
    pdf = to_pdf <<~EOS, analyze: true, pdf_theme: pdf_theme
    #{lorem_ipsum '2-sentences-1-paragraph'}

    #{lorem_ipsum '2-sentences-1-paragraph'}

    > quote

    #{lorem_ipsum '2-sentences-1-paragraph'}

    #{lorem_ipsum '2-sentences-1-paragraph'}
    EOS

    lorem_texts = pdf.find_text %r/^Lorem/
    (expect lorem_texts).to have_size 4
    (expect lorem_texts[0][:x]).to eql left_margin
    (expect lorem_texts[1][:x]).to be > left_margin
    (expect lorem_texts[2][:x]).to eql left_margin
    (expect lorem_texts[3][:x]).to be > left_margin
  end

  it 'should allow text alignment to be controlled using text-align document attribute' do
    pdf = to_pdf <<~'EOS', analyze: true
    = Document Title
    :text-align: right

    right-aligned
    EOS

    center_x = (pdf.page 1)[:size][1] / 2
    paragraph_text = (pdf.find_text 'right-aligned')[0]
    (expect paragraph_text[:x]).to be > center_x
  end

  it 'should output block title for paragraph if specified' do
    pdf = to_pdf <<~'EOS', analyze: true
    .Disclaimer
    All views expressed are my own.
    EOS

    (expect pdf.lines).to eql ['Disclaimer', 'All views expressed are my own.']
    disclaimer_text = (pdf.find_text 'Disclaimer')[0]
    (expect disclaimer_text[:font_name]).to eql 'NotoSerif-Italic'
  end

  it 'should use base text align if caption align is set to inherit' do
    pdf = to_pdf <<~'EOS', pdf_theme: { base_text_align: 'right', caption_align: 'inherit' }, analyze: true
    .Title
    Text
    EOS

    center_x = (pdf.page 1)[:size][1] * 0.5
    title_text = pdf.find_unique_text 'Title'
    paragraph_text = pdf.find_unique_text 'Text'
    (expect title_text[:x]).to be > center_x
    (expect paragraph_text[:x]).to be > center_x
  end

  it 'should use value of align on caption to align text if caption_text_align key not specified' do
    pdf = to_pdf <<~'EOS', pdf_theme: { caption_align: 'right' }, analyze: true
    .Title
    Text
    EOS

    center_x = (pdf.page 1)[:size][1] * 0.5
    title_text = pdf.find_unique_text 'Title'
    paragraph_text = pdf.find_unique_text 'Text'
    (expect title_text[:x]).to be > center_x
    (expect paragraph_text[:x]).to eql 48.24
  end

  it 'should apply the lead style to a paragraph with the lead role' do
    pdf = to_pdf <<~'EOS', analyze: true
    = Document Title

    preamble content

    [.lead]
    more preamble content

    == First Section

    section content
    EOS

    preamble_text = pdf.find_text 'preamble content'
    (expect preamble_text).to have_size 1
    (expect preamble_text[0][:font_size]).to be 13
    more_preamble_text = pdf.find_text 'more preamble content'
    (expect more_preamble_text).to have_size 1
    (expect more_preamble_text[0][:font_size]).to be 13
  end

  it 'should allow the theme to control the line height of a lead paragraph' do
    input = <<~EOS
    [.lead]
    #{lorem_ipsum '2-sentences-1-paragraph'}
    EOS

    reference_texts = (to_pdf input, analyze: true).text
    default_spacing = reference_texts[0][:y] - reference_texts[1][:y]

    texts = (to_pdf input, pdf_theme: { role_lead_line_height: 2 }, analyze: true).text
    adjusted_spacing = texts[0][:y] - texts[1][:y]

    (expect adjusted_spacing).to be > default_spacing
  end

  it 'should apply font properties defined by role to paragraph' do
    pdf_theme = {
      role_custom_font_size: 14,
      role_custom_font_color: 'FF0000',
      role_custom_text_align: :center,
      role_custom_font_style: 'bold',
      role_custom_text_transform: 'lowercase',
    }

    input = <<~EOS
    reference

    [.custom]
    This is a special paragraph.
    EOS

    pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
    left_margin = pdf.text[0][:x]
    text_with_role = pdf.text[1]
    (expect text_with_role[:font_size]).to eql pdf_theme[:role_custom_font_size]
    (expect text_with_role[:font_color]).to eql pdf_theme[:role_custom_font_color]
    (expect text_with_role[:font_name]).to eql 'NotoSerif-Bold'
    (expect text_with_role[:x]).to be > left_margin
    (expect text_with_role[:string]).to eql 'this is a special paragraph.'
  end

  it 'should allow the theme to control the line height of a paragraph with a custom role' do
    input = <<~EOS
    [.spaced-out]
    #{lorem_ipsum '2-sentences-1-paragraph'}
    EOS

    reference_texts = (to_pdf input, analyze: true).text
    default_spacing = reference_texts[0][:y] - reference_texts[1][:y]

    texts = (to_pdf input, pdf_theme: { 'role_spaced-out_line_height': 2 }, analyze: true).text
    adjusted_spacing = texts[0][:y] - texts[1][:y]

    (expect adjusted_spacing).to be > default_spacing
  end
end