From e9fe595b06c847f8aba466c28c5585be23a8fc39 Mon Sep 17 00:00:00 2001 From: Ben Ketron Date: Tue, 14 Jan 2020 16:16:53 -0700 Subject: [PATCH] Adds .cant_split and .cant_split? table methods. `.cant_split` allows one to describe a row or rows in such a way that its contents cannot split across a page break and instead positions the entire row on a new page. For example ``` docx.table [['Header 1', 'Header 2'], ['Cell 1', 'Cell 2']] do cant_split rows[1] end ``` or ``` docx.table [['Header 1', 'Header 2'], ['Cell 1', 'Cell 2']] do cant_split rows[1...-1] end ``` --- README.md | 17 +++++++++++ lib/caracal/core/models/table_model.rb | 29 ++++++++++++++++++- lib/caracal/renderers/document_renderer.rb | 9 +++++- .../caracal/core/models/table_model_spec.rb | 20 ++++++++++++- spec/lib/caracal/core/tables_spec.rb | 2 +- 5 files changed, 73 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 56f19204..e6c65885 100644 --- a/README.md +++ b/README.md @@ -683,6 +683,23 @@ end *Note: content of cells 21 and 24 will disappear* +Row can be marked as can't split rows that re-position themselves at the top of the next if they would have otherwise split across a page break. + +``` +docx.table [['11', '22'], ['14', '25'], ['64', '23']] do + cant_split rows[1] +end +``` + +or + +``` +docx.table [['11', '22'], ['14', '25'], ['64', '23']] do + cant_split rows[1...-1] +end +``` + + ### Table Cells If your table contains more complex data (multiple paragraphs, images, lists, etc.), you will probably want to instantiate your `TableCellModel` instances directly. With the exception of page breaks, table cells can contain anything the document can contain, including another table. diff --git a/lib/caracal/core/models/table_model.rb b/lib/caracal/core/models/table_model.rb index 2f41a22e..8a10f7fe 100644 --- a/lib/caracal/core/models/table_model.rb +++ b/lib/caracal/core/models/table_model.rb @@ -22,6 +22,7 @@ class TableModel < BaseModel const_set(:DEFAULT_TABLE_BORDER_LINE, :single) const_set(:DEFAULT_TABLE_BORDER_SIZE, 0) # units in 1/8 points const_set(:DEFAULT_TABLE_BORDER_SPACING, 0) + const_set(:DEFAULT_TABLE_CANT_SPLIT_ROWS, {}) # accessors attr_reader :table_align @@ -44,6 +45,7 @@ def initialize(options={}, &block) @table_border_line = DEFAULT_TABLE_BORDER_LINE @table_border_size = DEFAULT_TABLE_BORDER_SIZE @table_border_spacing = DEFAULT_TABLE_BORDER_SPACING + @table_rows_cant_split = {} super options, &block end @@ -99,8 +101,33 @@ def cell_style(models, options={}) m.apply_styles(options) end end + + # This method allows a user to specify one or more + # rows that should be rendered with the + # property + # + # For example + # + # docx.table data do |t| + # t.cant_split r.rows[0...-1] + # end + # + # would cause all rows in the table to be rendered + # with the property. + def cant_split(models, options={}) + models = rows.include?(models) ? [models] : models + models.each do |r| + @table_rows_cant_split[rows.index(r)] = true + end + end - + # This method returns true or false depending on + # if a row has been marked as a can't split row + # via the cant_split method. + def cant_split?(row_index) + !!@table_rows_cant_split[row_index] + end + #=============== GETTERS ============================== # border attrs diff --git a/lib/caracal/renderers/document_renderer.rb b/lib/caracal/renderers/document_renderer.rb index 5b14b3fb..ea6397be 100644 --- a/lib/caracal/renderers/document_renderer.rb +++ b/lib/caracal/renderers/document_renderer.rb @@ -349,8 +349,9 @@ def render_table(xml, model) end rowspan_hash = {} - model.rows.each do |row| + model.rows.each.with_index do |row, row_index| xml['w'].tr do + render_table_row_properties(xml, model, row_index) tc_index = 0 row.each do |tc| xml['w'].tc do @@ -390,6 +391,12 @@ def render_table(xml, model) end end + def render_table_row_properties(xml, model, index) + xml['w'].trPr do + xml['w'].cantSplit if model.cant_split?(index) + end + end + #============= OPTIONS =================================== diff --git a/spec/lib/caracal/core/models/table_model_spec.rb b/spec/lib/caracal/core/models/table_model_spec.rb index b3f30083..2fe1f1af 100644 --- a/spec/lib/caracal/core/models/table_model_spec.rb +++ b/spec/lib/caracal/core/models/table_model_spec.rb @@ -72,6 +72,24 @@ describe '.cells' do it { expect(subject.cells[0]).to eq 'top left' } end + + # .cant_split and cant_split? + describe '.cant_split and .cant_split?' do + it { expect(subject.cant_split?(0)).to eq(false) } + + describe "when first row can't split" do + before { subject.cant_split subject.rows[0] } + + it { expect(subject.cant_split?(0)).to eq(true) } + end + + describe 'when no rows can be split' do + before { subject.cant_split subject.rows } + + it { expect(subject.cant_split?(0)).to eq(true) } + it { expect(subject.cant_split?(1)).to eq(true) } + end + end end @@ -219,4 +237,4 @@ end -end \ No newline at end of file +end diff --git a/spec/lib/caracal/core/tables_spec.rb b/spec/lib/caracal/core/tables_spec.rb index 7ba77839..b6f4b0c6 100644 --- a/spec/lib/caracal/core/tables_spec.rb +++ b/spec/lib/caracal/core/tables_spec.rb @@ -22,4 +22,4 @@ end -end \ No newline at end of file +end