asciidoctor-pdf 1.5.0.beta.8 → 1.5.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.adoc +49 -0
  3. data/LICENSE.adoc +1 -1
  4. data/NOTICE.adoc +1 -1
  5. data/README.adoc +43 -47
  6. data/asciidoctor-pdf.gemspec +5 -1
  7. data/bin/asciidoctor-pdf-optimize +1 -1
  8. data/data/themes/base-theme.yml +4 -3
  9. data/data/themes/default-theme.yml +10 -5
  10. data/docs/theming-guide.adoc +286 -22
  11. data/lib/asciidoctor-pdf.rb +1 -0
  12. data/lib/asciidoctor-pdf/converter.rb +1 -0
  13. data/lib/asciidoctor-pdf/version.rb +1 -0
  14. data/lib/asciidoctor/pdf.rb +13 -2
  15. data/lib/asciidoctor/pdf/converter.rb +3962 -3955
  16. data/lib/asciidoctor/pdf/ext.rb +9 -0
  17. data/lib/asciidoctor/pdf/ext/asciidoctor.rb +1 -0
  18. data/lib/asciidoctor/pdf/ext/asciidoctor/abstract_block.rb +1 -0
  19. data/lib/asciidoctor/pdf/ext/asciidoctor/abstract_node.rb +1 -0
  20. data/lib/asciidoctor/pdf/ext/asciidoctor/document.rb +1 -0
  21. data/lib/asciidoctor/pdf/ext/asciidoctor/image.rb +18 -16
  22. data/lib/asciidoctor/pdf/ext/asciidoctor/list.rb +3 -2
  23. data/lib/asciidoctor/pdf/ext/asciidoctor/list_item.rb +2 -1
  24. data/lib/asciidoctor/pdf/ext/asciidoctor/logging_shim.rb +3 -4
  25. data/lib/asciidoctor/pdf/ext/asciidoctor/section.rb +8 -6
  26. data/lib/asciidoctor/pdf/ext/core.rb +2 -0
  27. data/lib/asciidoctor/pdf/ext/core/array.rb +1 -0
  28. data/lib/asciidoctor/pdf/ext/core/hash.rb +1 -0
  29. data/lib/asciidoctor/pdf/ext/core/numeric.rb +4 -3
  30. data/lib/asciidoctor/pdf/ext/core/object.rb +1 -0
  31. data/lib/asciidoctor/pdf/ext/core/quantifiable_stdout.rb +8 -1
  32. data/lib/asciidoctor/pdf/ext/core/regexp.rb +1 -0
  33. data/lib/asciidoctor/pdf/ext/core/string.rb +6 -7
  34. data/lib/asciidoctor/pdf/ext/pdf-core.rb +1 -0
  35. data/lib/asciidoctor/pdf/ext/pdf-core/page.rb +3 -4
  36. data/lib/asciidoctor/pdf/ext/pdf-core/pdf_object.rb +2 -1
  37. data/lib/asciidoctor/pdf/ext/prawn-svg.rb +1 -0
  38. data/lib/asciidoctor/pdf/ext/prawn-svg/interface.rb +11 -8
  39. data/lib/asciidoctor/pdf/ext/prawn-table.rb +2 -1
  40. data/lib/asciidoctor/pdf/ext/prawn-table/cell.rb +9 -10
  41. data/lib/asciidoctor/pdf/ext/prawn-table/cell/asciidoc.rb +62 -57
  42. data/lib/asciidoctor/pdf/ext/prawn-table/cell/text.rb +5 -3
  43. data/lib/asciidoctor/pdf/ext/prawn-templates.rb +1 -0
  44. data/lib/asciidoctor/pdf/ext/prawn.rb +1 -0
  45. data/lib/asciidoctor/pdf/ext/prawn/coderay_encoder.rb +73 -72
  46. data/lib/asciidoctor/pdf/ext/prawn/extensions.rb +814 -818
  47. data/lib/asciidoctor/pdf/ext/prawn/font/afm.rb +4 -3
  48. data/lib/asciidoctor/pdf/ext/prawn/formatted_text/box.rb +2 -1
  49. data/lib/asciidoctor/pdf/ext/prawn/formatted_text/fragment.rb +7 -2
  50. data/lib/asciidoctor/pdf/ext/prawn/images.rb +45 -44
  51. data/lib/asciidoctor/pdf/ext/pygments.rb +34 -0
  52. data/lib/asciidoctor/pdf/ext/rouge.rb +1 -1
  53. data/lib/asciidoctor/pdf/ext/rouge/formatters/prawn.rb +181 -149
  54. data/lib/asciidoctor/pdf/ext/rouge/themes/asciidoctor_pdf_default.rb +1 -0
  55. data/lib/asciidoctor/pdf/formatted_text.rb +2 -0
  56. data/lib/asciidoctor/pdf/formatted_text/formatter.rb +35 -34
  57. data/lib/asciidoctor/pdf/formatted_text/fragment_position_renderer.rb +8 -7
  58. data/lib/asciidoctor/pdf/formatted_text/inline_destination_marker.rb +13 -14
  59. data/lib/asciidoctor/pdf/formatted_text/inline_image_arranger.rb +112 -133
  60. data/lib/asciidoctor/pdf/formatted_text/inline_image_renderer.rb +43 -41
  61. data/lib/asciidoctor/pdf/formatted_text/inline_text_aligner.rb +15 -14
  62. data/lib/asciidoctor/pdf/formatted_text/source_wrap.rb +43 -0
  63. data/lib/asciidoctor/pdf/formatted_text/text_background_and_border_renderer.rb +46 -37
  64. data/lib/asciidoctor/pdf/formatted_text/transform.rb +371 -352
  65. data/lib/asciidoctor/pdf/index_catalog.rb +99 -95
  66. data/lib/asciidoctor/pdf/measurements.rb +51 -48
  67. data/lib/asciidoctor/pdf/optimizer.rb +34 -31
  68. data/lib/asciidoctor/pdf/pdfmark.rb +34 -33
  69. data/lib/asciidoctor/pdf/roman_numeral.rb +80 -79
  70. data/lib/asciidoctor/pdf/sanitizer.rb +38 -37
  71. data/lib/asciidoctor/pdf/temporary_path.rb +10 -9
  72. data/lib/asciidoctor/pdf/text_transformer.rb +101 -100
  73. data/lib/asciidoctor/pdf/theme_loader.rb +258 -256
  74. data/lib/asciidoctor/pdf/version.rb +5 -4
  75. metadata +55 -6
  76. data/lib/asciidoctor/pdf/ext/rouge/themes/bw.rb +0 -39
  77. data/lib/asciidoctor/pdf/ext/ttfunk.rb +0 -9
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'ext/core'
4
+ require_relative 'ext/asciidoctor'
5
+ require_relative 'ext/pdf-core'
6
+ require_relative 'ext/prawn'
7
+ require_relative 'ext/prawn-svg'
8
+ require_relative 'ext/prawn-table'
9
+ require_relative 'ext/prawn-templates'
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # NOTE these are either candidates for inclusion in Asciidoctor core or backports
3
4
  require_relative 'asciidoctor/logging_shim' unless defined? Asciidoctor::Logging
4
5
  require_relative 'asciidoctor/abstract_node'
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  class Asciidoctor::AbstractBlock
3
4
  def sections?
4
5
  !sections.empty?
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  class Asciidoctor::AbstractNode
3
4
  def remove_attr name
4
5
  @attributes.delete name
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  class Asciidoctor::Document
3
4
  alias catalog references unless method_defined? :catalog
4
5
  end
@@ -1,25 +1,27 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Asciidoctor
3
- module Image
4
- DataUriRx = /^data:image\/(?<fmt>png|jpe?g|gif|pdf|bmp|tiff);base64,(?<data>.*)$/
4
+ module Image
5
+ DataUriRx = /^data:image\/(?<fmt>png|jpe?g|gif|pdf|bmp|tiff|svg\+xml);base64,(?<data>.*)$/
6
+ FormatAliases = { 'jpg' => 'jpeg', 'svg+xml' => 'svg' }
5
7
 
6
- class << self
7
- def format path, attributes = nil
8
- (attributes && attributes['format']) || ((ext = ::File.extname path).downcase.slice 1, ext.length)
8
+ class << self
9
+ def format path, attributes = nil
10
+ (attributes && attributes['format']) || ((ext = ::File.extname path).downcase.slice 1, ext.length)
11
+ end
9
12
  end
10
- end
11
13
 
12
- def format
13
- (attr 'format', nil, false) || ((ext = ::File.extname(inline? ? target : (attr 'target'))).downcase.slice 1, ext.length)
14
- end
14
+ def format
15
+ (attr 'format', nil, false) || ((ext = ::File.extname(inline? ? target : (attr 'target'))).downcase.slice 1, ext.length)
16
+ end
15
17
 
16
- def target_and_format
17
- image_path = inline? ? target : (attr 'target')
18
- if (image_path.start_with? 'data:') && (m = DataUriRx.match image_path)
19
- [(m[:data].extend ::Base64), m[:fmt]]
20
- else
21
- [image_path, (attr 'format', nil, false) || ((ext = ::File.extname image_path).downcase.slice 1, ext.length)]
18
+ def target_and_format
19
+ image_path = inline? ? target : (attr 'target')
20
+ if (image_path.start_with? 'data:') && (m = DataUriRx.match image_path)
21
+ [(m[:data].extend ::Base64), (FormatAliases.fetch m[:fmt], m[:fmt])]
22
+ else
23
+ [image_path, (attr 'format', nil, false) || ((ext = ::File.extname image_path).downcase.slice 1, ext.length)]
24
+ end
22
25
  end
23
26
  end
24
27
  end
25
- end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
- # TODO add these methods to Asciidoctor core
2
+
3
+ # TODO: add these methods to Asciidoctor core
3
4
  class Asciidoctor::List
4
5
  # Check whether this list is an outline list (unordered or ordered).
5
6
  #
@@ -24,7 +25,7 @@ class Asciidoctor::List
24
25
  def outline_level
25
26
  l = 1
26
27
  ancestor = self
27
- # FIXME does not cross out of AsciiDoc table cell
28
+ # FIXME: does not cross out of AsciiDoc table cell
28
29
  while (ancestor = ancestor.parent)
29
30
  l += 1 if Asciidoctor::List === ancestor && ancestor.outline?
30
31
  end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
- # TODO add these methods to Asciidoctor core
2
+
3
+ # TODO: add these methods to Asciidoctor core
3
4
  class Asciidoctor::ListItem
4
5
  # Check whether this list item has complex content (i.e., nested blocks other than an outline list).
5
6
  #
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Asciidoctor
3
4
  class StubLogger
4
5
  class << self
@@ -7,13 +8,11 @@ module Asciidoctor
7
8
  end
8
9
 
9
10
  def warn message = nil
10
- message = block_given? ? yield : message unless message
11
- ::Kernel.warn %(asciidoctor: WARNING: #{message})
11
+ ::Kernel.warn %(asciidoctor: WARNING: #{message || (block_given? ? yield : '???')})
12
12
  end
13
13
 
14
14
  def error message = nil
15
- message = block_given? ? yield : message unless message
16
- ::Kernel.warn %(asciidoctor: ERROR: #{message})
15
+ ::Kernel.warn %(asciidoctor: ERROR: #{message || (block_given? ? yield : '???')})
17
16
  end
18
17
  end
19
18
  end
@@ -1,22 +1,24 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  class Asciidoctor::Section
3
4
  def numbered_title opts = {}
4
- unless (@cached_numbered_title ||= nil)
5
+ @cached_numbered_title ||= nil
6
+ unless @cached_numbered_title
5
7
  slevel = @level == 0 && @special ? 1 : @level
6
8
  if @numbered && !@caption && slevel <= (@document.attr 'sectnumlevels', 3).to_i
7
9
  @is_numbered = true
8
- @cached_formal_numbered_title = if @document.doctype == 'book'
10
+ if @document.doctype == 'book'
9
11
  if slevel == 0
10
12
  @cached_numbered_title = %(#{sectnum nil, ':'} #{title})
11
- %(#{@document.attr 'part-signifier', 'Part'} #{@cached_numbered_title}).lstrip
13
+ @cached_formal_numbered_title = %(#{@document.attr 'part-signifier', 'Part'} #{@cached_numbered_title}).lstrip
12
14
  elsif slevel == 1
13
15
  @cached_numbered_title = %(#{sectnum} #{title})
14
- %(#{@document.attr 'chapter-signifier', (@document.attr 'chapter-label', 'Chapter')} #{@cached_numbered_title}).lstrip
16
+ @cached_formal_numbered_title = %(#{@document.attr 'chapter-signifier', (@document.attr 'chapter-label', 'Chapter')} #{@cached_numbered_title}).lstrip
15
17
  else
16
- @cached_numbered_title = %(#{sectnum} #{title})
18
+ @cached_formal_numbered_title = @cached_numbered_title = %(#{sectnum} #{title})
17
19
  end
18
20
  else
19
- @cached_numbered_title = %(#{sectnum} #{title})
21
+ @cached_formal_numbered_title = @cached_numbered_title = %(#{sectnum} #{title})
20
22
  end
21
23
  elsif slevel == 0
22
24
  @is_numbered = false
@@ -1,7 +1,9 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative 'core/object'
3
4
  require_relative 'core/array'
4
5
  require_relative 'core/hash'
5
6
  require_relative 'core/numeric'
6
7
  require_relative 'core/string'
7
8
  require_relative 'core/regexp'
9
+ require_relative 'core/quantifiable_stdout'
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  class Array
3
4
  def delete_all *entries
4
5
  entries.map {|entry| delete entry }.compact
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  class Hash
3
4
  def compact
4
5
  select {|_, val| val }
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # NOTE remove once minimum required Ruby version is at least 2.4
3
4
  Float.prepend (Module.new do
4
5
  def truncate *args
@@ -6,10 +7,10 @@ Float.prepend (Module.new do
6
7
  if (precision = Integer args.shift) == 0
7
8
  super
8
9
  elsif precision > 0
9
- precision_factor = 10.0 ** precision
10
+ precision_factor = 10.0**precision
10
11
  (self * precision_factor).to_i / precision_factor
11
12
  else
12
- precision_factor = 10 ** precision.abs
13
+ precision_factor = 10**precision.abs
13
14
  (self / precision_factor).to_i * precision_factor
14
15
  end
15
16
  else
@@ -19,7 +20,7 @@ Float.prepend (Module.new do
19
20
  end) if (Float.instance_method :truncate).arity == 0
20
21
 
21
22
  Integer.prepend (Module.new do
22
- def truncate *args
23
+ def truncate *_args
23
24
  super()
24
25
  end
25
26
  end) if (Integer.instance_method :truncate).arity == 0
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  class Object
3
4
  # Convert the object to a serialized PDF object.
4
5
  def to_pdf_object
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'delegate'
3
4
 
4
5
  # A delegator that allows the size method to be used on the STDOUT object.
@@ -12,10 +13,16 @@ class QuantifiableStdout < SimpleDelegator
12
13
  def initialize delegate
13
14
  @size = 0
14
15
  super
16
+ delegate.binmode
17
+ end
18
+
19
+ def << content
20
+ @size += content.to_s.bytesize
21
+ super
15
22
  end
16
23
 
17
24
  def write content
18
- @size += content.bytesize
25
+ @size += content.to_s.bytesize
19
26
  super
20
27
  end
21
28
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  class Regexp
3
4
  alias match? === unless Regexp.method_defined? :match?
4
5
  end
@@ -1,13 +1,12 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  class String
3
4
  def pred
4
- begin
5
- # integers
6
- %(#{(Integer self) - 1})
7
- rescue ::ArgumentError
8
- # chars (upper alpha, lower alpha, lower greek)
9
- ([65, 97, 945].include? ord) ? '0' : ([ord - 1].pack 'U1')
10
- end
5
+ # integers
6
+ ((Integer self) - 1).to_s
7
+ rescue ::ArgumentError
8
+ # chars (upper alpha, lower alpha, lower greek)
9
+ ([65, 97, 945].include? ord) ? '0' : ([ord - 1].pack 'U1')
11
10
  end unless method_defined? :pred
12
11
 
13
12
  # If the string is ASCII only, convert it to a PDF LiteralString object. Otherwise, return self.
@@ -1,3 +1,4 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative 'pdf-core/pdf_object'
3
4
  require_relative 'pdf-core/page'
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  class PDF::Core::Page
3
4
  InitialPageContent = %(q\n)
4
5
 
@@ -11,10 +12,8 @@ class PDF::Core::Page
11
12
  # see https://github.com/prawnpdf/pdf-core/commit/67f9a08a03bcfcc5a24cf76b135c218d3d3ab05d
12
13
  def new_content_stream
13
14
  return if in_stamp_stream?
14
- unless Array === dictionary.data[:Contents]
15
- dictionary.data[:Contents] = [content]
16
- end
17
- @content = document.ref Hash.new
15
+ dictionary.data[:Contents] = [content] unless Array === dictionary.data[:Contents]
16
+ @content = document.ref({})
18
17
  dictionary.data[:Contents] << document.state.store[@content]
19
18
  document.open_graphics_state
20
19
  end unless method_defined? :new_content_stream
@@ -1,7 +1,8 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  unless (defined? PDF::Core.pdf_object) == 'method'
3
4
  module PDF::Core
4
5
  alias pdf_object PdfObject
5
- module_function :pdf_object
6
+ module_function :pdf_object # rubocop:disable Style/AccessModifierDeclarations
6
7
  end
7
8
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'prawn-svg' unless defined? Prawn::SVG::Interface
3
4
  require_relative 'prawn-svg/interface'
4
5
  # NOTE disable system fonts since they're non-portable
@@ -1,11 +1,14 @@
1
1
  # frozen_string_literal: true
2
- module Prawn; module SVG
3
- class Interface
4
- def resize opts = {}
5
- sizing = document.sizing
6
- sizing.requested_width = opts[:width]
7
- sizing.requested_height = opts[:height]
8
- sizing.calculate
2
+
3
+ module Prawn
4
+ module SVG
5
+ class Interface
6
+ def resize opts = {}
7
+ sizing = document.sizing
8
+ sizing.requested_width = opts[:width]
9
+ sizing.requested_height = opts[:height]
10
+ sizing.calculate
11
+ end
9
12
  end
10
13
  end
11
- end; end unless Prawn::SVG::Interface.method_defined? :resize
14
+ end unless Prawn::SVG::Interface.method_defined? :resize
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
- require 'prawn/table' unless defined? Prawn::Table::VERSION
2
+
3
+ require ENV['PRAWN_TABLE_REQUIRE_PATH'] || 'prawn/table' unless defined? Prawn::Table::VERSION
3
4
  require_relative 'prawn-table/cell'
4
5
  require_relative 'prawn-table/cell/asciidoc'
5
6
  require_relative 'prawn-table/cell/text'
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  class Prawn::Table::Cell
3
4
  remove_method :draw_borders
4
5
  # Draws borders around the cell. Borders are centered on the bounds of
@@ -6,10 +7,10 @@ class Prawn::Table::Cell
6
7
  # setting appropriate padding to ensure the border does not overlap with
7
8
  # cell content.
8
9
  #
9
- def draw_borders(pt)
10
+ def draw_borders pt
10
11
  x, y = pt
11
12
 
12
- @pdf.mask(:line_width, :stroke_color) do
13
+ @pdf.mask :line_width, :stroke_color do
13
14
  @borders.each do |border|
14
15
  idx = { top: 0, right: 1, bottom: 2, left: 3 }[border]
15
16
  border_color = @border_colors[idx]
@@ -22,15 +23,13 @@ class Prawn::Table::Cell
22
23
  # of the corner, so that the corners end up square.
23
24
  from, to = case border
24
25
  when :top
25
- [[x, y], [x+width, y]]
26
+ [[x, y], [x + width, y]]
26
27
  when :bottom
27
- [[x, y-height], [x+width, y-height]]
28
+ [[x, y - height], [x + width, y - height]]
28
29
  when :left
29
- [[x, y + (border_top_width / 2.0)],
30
- [x, y - height - (border_bottom_width / 2.0)]]
30
+ [[x, y + (border_top_width / 2.0)], [x, y - height - (border_bottom_width / 2.0)]]
31
31
  when :right
32
- [[x+width, y + (border_top_width / 2.0)],
33
- [x+width, y - height - (border_bottom_width / 2.0)]]
32
+ [[x + width, y + (border_top_width / 2.0)], [x + width, y - height - (border_bottom_width / 2.0)]]
34
33
  end
35
34
 
36
35
  case border_line
@@ -48,11 +47,11 @@ class Prawn::Table::Cell
48
47
  if border_color == 'transparent'
49
48
  @pdf.stroke_color = '000000'
50
49
  @pdf.transparent 0 do
51
- @pdf.stroke_line(from, to)
50
+ @pdf.stroke_line from, to
52
51
  end
53
52
  else
54
53
  @pdf.stroke_color = border_color
55
- @pdf.stroke_line(from, to)
54
+ @pdf.stroke_line from, to
56
55
  end
57
56
  @pdf.undash
58
57
  end
@@ -1,71 +1,76 @@
1
1
  # frozen_string_literal: true
2
- module Prawn; class Table; class Cell
3
- class AsciiDoc < Cell
4
- attr_accessor :align
5
- attr_accessor :valign
6
2
 
7
- def initialize pdf, opts = {}
8
- @font_options = {}
9
- super pdf, [], opts
10
- end
3
+ module Prawn
4
+ class Table
5
+ class Cell
6
+ class AsciiDoc < Cell
7
+ attr_accessor :align
8
+ attr_accessor :valign
11
9
 
12
- def font_style= val
13
- @font_options[:style] = val
14
- end
10
+ def initialize pdf, opts = {}
11
+ @font_options = {}
12
+ super pdf, [], opts
13
+ end
15
14
 
16
- def text_color= val
17
- @font_options[:color] = val
18
- end
15
+ def font_style= val
16
+ @font_options[:style] = val
17
+ end
19
18
 
20
- def size= val
21
- @font_options[:size] = val
22
- end
19
+ def text_color= val
20
+ @font_options[:color] = val
21
+ end
23
22
 
24
- def font= val
25
- @font_options[:family] = val
26
- end
23
+ def size= val
24
+ @font_options[:size] = val
25
+ end
27
26
 
28
- # NOTE automatic image sizing only works if cell has fixed width
29
- def dry_run
30
- cell = self
31
- max_height = nil
32
- height, _, _ = @pdf.dry_run do
33
- max_height = bounds.height
34
- # NOTE we should be able to use cell.max_width, but returns 0 in some conditions (like when colspan > 1)
35
- indent cell.padding_left, bounds.width - cell.width + cell.padding_right do
36
- # HACK force margin_top to be applied
37
- move_down 0.0001
38
- # TODO truncate margin bottom of last block
39
- convert_content_for_block cell.content
27
+ def font= val
28
+ @font_options[:family] = val
40
29
  end
41
- end
42
- # FIXME prawn-table doesn't support cell taller than a single page
43
- [max_height, height].min
44
- end
45
30
 
46
- def natural_content_width
47
- # QUESTION can we get a better estimate of the natural width?
48
- @natural_width ||= (@pdf.bounds.width - padding_left - padding_right)
49
- end
31
+ # NOTE: automatic image sizing only works if cell has fixed width
32
+ def dry_run
33
+ cell = self
34
+ max_height = nil
35
+ height, = @pdf.dry_run do
36
+ max_height = bounds.height
37
+ # NOTE: we should be able to use cell.max_width, but returns 0 in some conditions (like when colspan > 1)
38
+ indent cell.padding_left, bounds.width - cell.width + cell.padding_right do
39
+ # HACK: force margin_top to be applied
40
+ move_down 0.0001
41
+ # TODO: truncate margin bottom of last block
42
+ traverse cell.content
43
+ end
44
+ end
45
+ # FIXME: prawn-table doesn't support cell taller than a single page
46
+ [max_height, height].min
47
+ end
50
48
 
51
- def natural_content_height
52
- # NOTE when natural_content_height is called, we already know max width
53
- @natural_height ||= dry_run
54
- end
49
+ def natural_content_width
50
+ # QUESTION can we get a better estimate of the natural width?
51
+ @natural_content_width ||= (@pdf.bounds.width - padding_left - padding_right)
52
+ end
53
+
54
+ def natural_content_height
55
+ # NOTE when natural_content_height is called, we already know max width
56
+ @natural_content_height ||= dry_run
57
+ end
55
58
 
56
- def draw_content
57
- pdf = @pdf
58
- # NOTE draw_bounded_content automatically adds FPTolerance to width and height
59
- pdf.bounds.instance_variable_set :@width, spanned_content_width
60
- # NOTE we've already reserved the space, so just let the box stretch to the bottom of the page to avoid overflow
61
- pdf.bounds.instance_variable_set :@height, pdf.y
62
- if @valign != :top && (excess_y = spanned_content_height - natural_content_height) > 0
63
- pdf.move_down(@valign == :center ? (excess_y.fdiv 2) : excess_y)
59
+ def draw_content
60
+ pdf = @pdf
61
+ # NOTE draw_bounded_content automatically adds FPTolerance to width and height
62
+ pdf.bounds.instance_variable_set :@width, spanned_content_width
63
+ # NOTE we've already reserved the space, so just let the box stretch to the bottom of the page to avoid overflow
64
+ pdf.bounds.instance_variable_set :@height, pdf.y
65
+ if @valign != :top && (excess_y = spanned_content_height - natural_content_height) > 0
66
+ pdf.move_down(@valign == :center ? (excess_y.fdiv 2) : excess_y)
67
+ end
68
+ # TODO: apply horizontal alignment (right now must use alignment on content block)
69
+ # QUESTION inherit table cell font properties?
70
+ pdf.traverse content
71
+ nil
72
+ end
64
73
  end
65
- # TODO apply horizontal alignment (right now must use alignment on content block)
66
- # QUESTION inherit table cell font properties?
67
- pdf.convert_content_for_block content
68
- nil
69
74
  end
70
75
  end
71
- end; end; end
76
+ end