Skip to content

Commit

Permalink
resolves #6 add support for AsciiDoc table cells (including nested ta…
Browse files Browse the repository at this point in the history
…bles) (PR #707)

- use custom Cell implementation to support AsciiDoc table cells
- supports colspan, rowspan and vertical alignment
- works best if column is assigned an explicit (relative) width
- does not permit content that exceeds the height of one page
- extra padding from last block is added to bottom of cell
- does not (yet) inherit font properties from table cell

Also resolves duplicates #315, #445 and #358.
  • Loading branch information
mojavelinux authored Dec 20, 2016
1 parent 32de10e commit ad41d04
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 7 deletions.
12 changes: 5 additions & 7 deletions lib/asciidoctor-pdf/converter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1460,16 +1460,14 @@ def convert_table node
cell_data[:content] = preserve_indentation cell.text, (node.document.attr 'tabsize')
cell_data[:inline_format] = true
when :asciidoc
unless defined? @asciidoc_cell_warning
@asciidoc_cell_warning = true
warn 'asciidoctor: WARNING: The \'a\' (AsciiDoc) table cell style is not supported by this converter. The source of these cells will be treated as paragraph content.'
end
# TODO finish me
asciidoc_cell = ::Prawn::Table::Cell::AsciiDoc.new self,
(cell_data.merge content: cell.inner_document, font_style: (val = theme.table_font_style) ? val.to_sym : nil)
cell_data = { content: asciidoc_cell }
else
cell_data[:font_style] = (val = theme.table_font_style) ? val.to_sym : nil
end
unless cell_data.key? :content
# NOTE effectively the same as calling cell.content
# NOTE effectively the same as calling cell.content (should we use that instead?)
# TODO hard breaks not quite the same result as separate paragraphs; need custom cell impl
if (cell_text = cell.text).include? LF
cell_data[:content] = cell_text.split(BlankLineRx).map {|l| l.tr_s(WhitespaceChars, ' ') }.join(DoubleLF)
Expand Down Expand Up @@ -1561,7 +1559,7 @@ def convert_table node
theme_margin :block, :top

table table_data, table_settings do
# NOTE capture resolved table width
# NOTE call width to capture resolved table width
table_width = width
@pdf.layout_table_caption node, table_width, alignment if node.title? && caption_side == :top
if grid == 'none' && frame == 'none'
Expand Down
1 change: 1 addition & 0 deletions lib/asciidoctor-pdf/prawn-table_ext.rb
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
require 'prawn/table' unless defined? Prawn::Table::VERSION
require_relative 'prawn-table_ext/cell/asciidoc'
require_relative 'prawn-table_ext/cell/text'
69 changes: 69 additions & 0 deletions lib/asciidoctor-pdf/prawn-table_ext/cell/asciidoc.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
module Prawn; class Table; class Cell
class AsciiDoc < Cell
attr_accessor :align
attr_accessor :valign

def initialize pdf, opts = {}
@font_options = {}
super pdf, [], opts
end

def font_style= val
@font_options[:style] = val
end

def text_color= val
@font_options[:color] = val
end

def size= val
@font_options[:size] = val
end

def font= val
@font_options[:family] = val
end

# NOTE automatic image sizing only works if cell has fixed width
def dry_run
cell = self
max_height = nil
height, _, _ = @pdf.dry_run do
max_height = bounds.height
# NOTE we should be able to use cell.max_width, but returns 0 in some conditions (like when colspan > 1)
indent cell.padding_left, bounds.width - cell.width + cell.padding_right do
# HACK force margin_top to be applied
move_down 0.0001
# TODO truncate margin bottom of last block
convert_content_for_block cell.content
end
end
# FIXME prawn-table doesn't support cell taller than a single page
[max_height, height].min
end

def natural_content_width
# QUESTION can we get a better estimate of the natural width?
@natural_width ||= (@pdf.bounds.width - padding_left - padding_right)
end

def natural_content_height
# NOTE when natural_content_height is called, we already know max width
@natural_height ||= dry_run
end

def draw_content
pdf = @pdf
# NOTE draw_bounded_content adds FPTolerance to width and height, which causes content to overflow
pdf.bounds.instance_variable_set :@width, spanned_content_width
pdf.bounds.instance_variable_set :@height, spanned_content_height
if @valign != :top && (excess_y = spanned_content_height - natural_content_height) > 0
pdf.move_down(@valign == :center ? (excess_y.fdiv 2) : excess_y)
end
# TODO apply horizontal alignment (right now must use alignment on content block)
# QUESTION inherit table cell font properties?
pdf.convert_content_for_block content
nil
end
end
end; end; end

0 comments on commit ad41d04

Please sign in to comment.