From 08381b86f0182240654f67b3755def09fdbeba8d Mon Sep 17 00:00:00 2001 From: Andy Meneely Date: Tue, 20 Oct 2015 18:20:53 -0400 Subject: [PATCH] Add quantity explosion to xlsx and csv Closes #78 --- README.md | 4 + lib/squib/api/data.rb | 22 +- lib/squib/args/import.rb | 8 +- samples/csv_import.rb | 10 +- samples/excel.rb | 12 ++ samples/explode_quantities.xlsx | Bin 0 -> 8333 bytes samples/quantity_explosion.csv | 3 + spec/api/api_data_spec.rb | 14 ++ spec/data/csv/qty.csv | 3 + spec/data/csv/qty_named.csv | 3 + spec/data/samples/csv_import.rb.txt | 137 ++++++++++++ spec/data/samples/excel.rb.txt | 318 ++++++++++++++++++++++++++++ 12 files changed, 528 insertions(+), 6 deletions(-) create mode 100644 samples/explode_quantities.xlsx create mode 100644 samples/quantity_explosion.csv create mode 100644 spec/data/csv/qty.csv create mode 100644 spec/data/csv/qty_named.csv diff --git a/README.md b/README.md index 92a24d5..e942d29 100644 --- a/README.md +++ b/README.md @@ -484,6 +484,10 @@ Squib supports importing data from `xlsx` files and `csv` files. These methods a Of course, you can always import your game data other ways using just Ruby. There's nothing special about Squib's methods other than their convenience. +###Quantity Explosion + +If you want more than one copy of a card, then have a column called `Qty` and fill it with counts. Squib's `xlsx` and `csv` methods will automatically expand those rows according to those counts. You can also customize that "Qty" to anything you like by setting the `explode` option (e.g. `explode: 'Quantity'`). See the `excel.rb` and the `csv_import.rb` samples found [here](https://github.com/andymeneely/squib/tree/master/samples/) for an example. + ## Making Squib Verbose By default, Squib's logger is set to WARN, but more fine-grained logging is embedded in the code. To set the logger, just put this at the top of your script: diff --git a/lib/squib/api/data.rb b/lib/squib/api/data.rb index 97ec66d..90c40bd 100644 --- a/lib/squib/api/data.rb +++ b/lib/squib/api/data.rb @@ -22,7 +22,7 @@ module Squib # @option opts file [String] the file to open. Must end in `.xlsx`. Opens relative to the current directory. # @option opts sheet [Integer] (0) The zero-based index of the sheet from which to read. # @option opts strip [Boolean] (true) When true, strips leading and trailing whitespace on values and headers - # @option opts qty_header [String] ('qty']) Quantity explosion will be applied to the column this name + # @option opts explode [String] ('qty') Quantity explosion will be applied to the column this name. See README for example. # @return [Hash] a hash of arrays based on columns in the spreadsheet # @api public def xlsx(opts = {}) @@ -44,7 +44,7 @@ module Squib data[header] << cell end#row end#col - data + explode_quantities(data, import.explode) end#xlsx module_function :xlsx @@ -66,7 +66,7 @@ module Squib # # @option opts file [String] the CSV-formatted file to open. Opens relative to the current directory. # @option opts strip [Boolean] (true) When true, strips leading and trailing whitespace on values and headers - # @option opts qty_header [String] ('qty']) Quantity explosion will be applied to the column this name + # @option opts explode [String] ('qty') Quantity explosion will be applied to the column this name. See README for example. # @return [Hash] a hash of arrays based on columns in the table # @api public def csv(opts = {}) @@ -87,7 +87,7 @@ module Squib end hash = new_hash end - return hash + return explode_quantities(hash, import.explode) end module_function :csv @@ -101,6 +101,20 @@ module Squib end module_function :check_duplicate_csv_headers + def explode_quantities(data, qty) + return data unless data.key? qty.to_s.strip + qtys = data[qty] + new_data = {} + data.each do |col, arr| + new_data[col] = [] + qtys.each_with_index do |qty, index| + qty.to_i.times { new_data[col] << arr[index] } + end + end + return new_data + end + module_function :explode_quantities + class Deck # Convenience call on deck goes to the module function diff --git a/lib/squib/args/import.rb b/lib/squib/args/import.rb index 512b0ac..4a0194d 100644 --- a/lib/squib/args/import.rb +++ b/lib/squib/args/import.rb @@ -8,7 +8,9 @@ module Squib include ArgLoader def self.parameters - { strip: true } + { strip: true, + explode: 'Qty' + } end def self.expanding_parameters @@ -24,6 +26,10 @@ module Squib arg end + def validate_explode(arg) + arg + end + def strip? strip end diff --git a/samples/csv_import.rb b/samples/csv_import.rb index 72a9ff0..df9d7ef 100644 --- a/samples/csv_import.rb +++ b/samples/csv_import.rb @@ -15,4 +15,12 @@ Squib::Deck.new(cards: 2) do end # CSV is also a Squib-module-level function, so this also works: -data = Squib.csv file: 'sample.csv' +data = Squib.csv file: 'quantity_explosion.csv' # 2 rows... +num_cards = data['Name'].size # ...but 4 cards! + +Squib::Deck.new(cards: num_cards) do + background color: :white + rect # card border + text str: data['Name'], font: 'Arial 54' + save_sheet prefix: 'sample_csv_qty_', columns: 4 +end diff --git a/samples/excel.rb b/samples/excel.rb index 936ab20..9bf3406 100644 --- a/samples/excel.rb +++ b/samples/excel.rb @@ -14,6 +14,18 @@ Squib::Deck.new(cards: 3) do save format: :png, prefix: 'sample_excel_' #save to individual pngs end +# xlsx is also a Squib-module-level function, so this also works: +data = Squib.xlsx file: 'explode_quantities.xlsx' # 2 rows... +num_cards = data['Name'].size # ...but 4 cards! + +Squib::Deck.new(cards: num_cards) do + background color: :white + rect # card border + text str: data['Name'], font: 'Arial 54' + save_sheet prefix: 'sample_xlsx_qty_', columns: 4 +end + + # Here's another example, a bit more realistic. Here's what's going on: # * We call xlsx from Squib directly - BEFORE Squib::Deck creation. This # allows us to infer the number of cards based on the size of the "Name" diff --git a/samples/explode_quantities.xlsx b/samples/explode_quantities.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..9e8b0abc1deea4e1a2e8b473806ac8080a7e380f GIT binary patch literal 8333 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 literal 0 HcmV?d00001 diff --git a/samples/quantity_explosion.csv b/samples/quantity_explosion.csv new file mode 100644 index 0000000..efaa11c --- /dev/null +++ b/samples/quantity_explosion.csv @@ -0,0 +1,3 @@ +Name,Qty +Basilisk,3 +High Templar,1 \ No newline at end of file diff --git a/spec/api/api_data_spec.rb b/spec/api/api_data_spec.rb index 855bac5..d38750e 100644 --- a/spec/api/api_data_spec.rb +++ b/spec/api/api_data_spec.rb @@ -36,6 +36,20 @@ describe Squib::Deck do }) end + it 'explodes quantities' do + expect(Squib.csv(file: csv_file('qty.csv'))).to eq({ + 'Name' => %w(Ha Ha Ha Ho), + 'Qty' => [3, 3, 3, 1], + }) + end + + it 'explodes quantities on specified header' do + expect(Squib.csv(explode: 'Quantity', file: csv_file('qty_named.csv'))).to eq({ + 'Name' => %w(Ha Ha Ha Ho), + 'Quantity' => [3, 3, 3, 1], + }) + end + end context '#xlsx' do diff --git a/spec/data/csv/qty.csv b/spec/data/csv/qty.csv new file mode 100644 index 0000000..e99bf95 --- /dev/null +++ b/spec/data/csv/qty.csv @@ -0,0 +1,3 @@ +Name,Qty +Ha, 3 +Ho, 1 \ No newline at end of file diff --git a/spec/data/csv/qty_named.csv b/spec/data/csv/qty_named.csv new file mode 100644 index 0000000..6fa8afe --- /dev/null +++ b/spec/data/csv/qty_named.csv @@ -0,0 +1,3 @@ +Name,Quantity +Ha, 3 +Ho, 1 \ No newline at end of file diff --git a/spec/data/samples/csv_import.rb.txt b/spec/data/samples/csv_import.rb.txt index 55d2f52..e79248a 100644 --- a/spec/data/samples/csv_import.rb.txt +++ b/spec/data/samples/csv_import.rb.txt @@ -74,3 +74,140 @@ pango: ellipsized?([]) cairo: restore([]) surface: write_to_png(["_output/sample_csv_00.png"]) surface: write_to_png(["_output/sample_csv_01.png"]) +cairo: antialias=(["subpixel"]) +cairo: antialias=(["subpixel"]) +cairo: antialias=(["subpixel"]) +cairo: antialias=(["subpixel"]) +cairo: save([]) +cairo: set_source_color(["white"]) +cairo: paint([]) +cairo: restore([]) +cairo: save([]) +cairo: set_source_color(["white"]) +cairo: paint([]) +cairo: restore([]) +cairo: save([]) +cairo: set_source_color(["white"]) +cairo: paint([]) +cairo: restore([]) +cairo: save([]) +cairo: set_source_color(["white"]) +cairo: paint([]) +cairo: restore([]) +cairo: save([]) +cairo: rounded_rectangle([0, 0, 825, 1125, 0, 0]) +cairo: set_source_color(["#0000"]) +cairo: fill_preserve([]) +cairo: set_source_color(["black"]) +cairo: set_line_width([2.0]) +cairo: set_line_join([0]) +cairo: set_line_cap([0]) +cairo: set_dash([[]]) +cairo: stroke([]) +cairo: restore([]) +cairo: save([]) +cairo: rounded_rectangle([0, 0, 825, 1125, 0, 0]) +cairo: set_source_color(["#0000"]) +cairo: fill_preserve([]) +cairo: set_source_color(["black"]) +cairo: set_line_width([2.0]) +cairo: set_line_join([0]) +cairo: set_line_cap([0]) +cairo: set_dash([[]]) +cairo: stroke([]) +cairo: restore([]) +cairo: save([]) +cairo: rounded_rectangle([0, 0, 825, 1125, 0, 0]) +cairo: set_source_color(["#0000"]) +cairo: fill_preserve([]) +cairo: set_source_color(["black"]) +cairo: set_line_width([2.0]) +cairo: set_line_join([0]) +cairo: set_line_cap([0]) +cairo: set_dash([[]]) +cairo: stroke([]) +cairo: restore([]) +cairo: save([]) +cairo: rounded_rectangle([0, 0, 825, 1125, 0, 0]) +cairo: set_source_color(["#0000"]) +cairo: fill_preserve([]) +cairo: set_source_color(["black"]) +cairo: set_line_width([2.0]) +cairo: set_line_join([0]) +cairo: set_line_cap([0]) +cairo: set_dash([[]]) +cairo: stroke([]) +cairo: restore([]) +cairo: save([]) +cairo: set_source_color(["black"]) +cairo: translate([0, 0]) +cairo: rotate([0]) +cairo: move_to([0, 0]) +pango: font_description=([MockDouble]) +pango: text=(["Basilisk"]) +pango: wrap=([#]) +pango: ellipsize=([#]) +pango: alignment=([#]) +pango: justify=([false]) +cairo: move_to([0, 0]) +cairo: move_to([0, 0]) +cairo: show_pango_layout([MockDouble]) +pango: ellipsized?([]) +cairo: restore([]) +cairo: save([]) +cairo: set_source_color(["black"]) +cairo: translate([0, 0]) +cairo: rotate([0]) +cairo: move_to([0, 0]) +pango: font_description=([MockDouble]) +pango: text=(["Basilisk"]) +pango: wrap=([#]) +pango: ellipsize=([#]) +pango: alignment=([#]) +pango: justify=([false]) +cairo: move_to([0, 0]) +cairo: move_to([0, 0]) +cairo: show_pango_layout([MockDouble]) +pango: ellipsized?([]) +cairo: restore([]) +cairo: save([]) +cairo: set_source_color(["black"]) +cairo: translate([0, 0]) +cairo: rotate([0]) +cairo: move_to([0, 0]) +pango: font_description=([MockDouble]) +pango: text=(["Basilisk"]) +pango: wrap=([#]) +pango: ellipsize=([#]) +pango: alignment=([#]) +pango: justify=([false]) +cairo: move_to([0, 0]) +cairo: move_to([0, 0]) +cairo: show_pango_layout([MockDouble]) +pango: ellipsized?([]) +cairo: restore([]) +cairo: save([]) +cairo: set_source_color(["black"]) +cairo: translate([0, 0]) +cairo: rotate([0]) +cairo: move_to([0, 0]) +pango: font_description=([MockDouble]) +pango: text=(["High Templar"]) +pango: wrap=([#]) +pango: ellipsize=([#]) +pango: alignment=([#]) +pango: justify=([false]) +cairo: move_to([0, 0]) +cairo: move_to([0, 0]) +cairo: show_pango_layout([MockDouble]) +pango: ellipsized?([]) +cairo: restore([]) +cairo: set_source([MockDouble, 0, 0]) +cairo: paint([]) +cairo: set_source([MockDouble, 100, 0]) +cairo: paint([]) +cairo: set_source([MockDouble, 200, 0]) +cairo: paint([]) +cairo: set_source([MockDouble, 300, 0]) +cairo: paint([]) +surface: write_to_png(["_output/sample_csv_qty_00.png"]) diff --git a/spec/data/samples/excel.rb.txt b/spec/data/samples/excel.rb.txt index 7469999..75d3014 100644 --- a/spec/data/samples/excel.rb.txt +++ b/spec/data/samples/excel.rb.txt @@ -163,6 +163,11 @@ surface: write_to_png(["_output/sample_excel_02.png"]) cairo: antialias=(["subpixel"]) cairo: antialias=(["subpixel"]) cairo: antialias=(["subpixel"]) +cairo: antialias=(["subpixel"]) +cairo: save([]) +cairo: set_source_color(["white"]) +cairo: paint([]) +cairo: restore([]) cairo: save([]) cairo: set_source_color(["white"]) cairo: paint([]) @@ -209,6 +214,186 @@ cairo: set_dash([[]]) cairo: stroke([]) cairo: restore([]) cairo: save([]) +cairo: rounded_rectangle([0, 0, 825, 1125, 0, 0]) +cairo: set_source_color(["#0000"]) +cairo: fill_preserve([]) +cairo: set_source_color(["black"]) +cairo: set_line_width([2.0]) +cairo: set_line_join([0]) +cairo: set_line_cap([0]) +cairo: set_dash([[]]) +cairo: stroke([]) +cairo: restore([]) +cairo: save([]) +cairo: set_source_color(["black"]) +cairo: translate([0, 0]) +cairo: rotate([0]) +cairo: move_to([0, 0]) +pango: font_description=([MockDouble]) +pango: text=(["Zergling"]) +pango: wrap=([#]) +pango: ellipsize=([#]) +pango: alignment=([#]) +pango: justify=([false]) +cairo: move_to([0, 0]) +cairo: move_to([0, 0]) +cairo: show_pango_layout([MockDouble]) +pango: ellipsized?([]) +cairo: restore([]) +cairo: save([]) +cairo: set_source_color(["black"]) +cairo: translate([0, 0]) +cairo: rotate([0]) +cairo: move_to([0, 0]) +pango: font_description=([MockDouble]) +pango: text=(["Zergling"]) +pango: wrap=([#]) +pango: ellipsize=([#]) +pango: alignment=([#]) +pango: justify=([false]) +cairo: move_to([0, 0]) +cairo: move_to([0, 0]) +cairo: show_pango_layout([MockDouble]) +pango: ellipsized?([]) +cairo: restore([]) +cairo: save([]) +cairo: set_source_color(["black"]) +cairo: translate([0, 0]) +cairo: rotate([0]) +cairo: move_to([0, 0]) +pango: font_description=([MockDouble]) +pango: text=(["Zergling"]) +pango: wrap=([#]) +pango: ellipsize=([#]) +pango: alignment=([#]) +pango: justify=([false]) +cairo: move_to([0, 0]) +cairo: move_to([0, 0]) +cairo: show_pango_layout([MockDouble]) +pango: ellipsized?([]) +cairo: restore([]) +cairo: save([]) +cairo: set_source_color(["black"]) +cairo: translate([0, 0]) +cairo: rotate([0]) +cairo: move_to([0, 0]) +pango: font_description=([MockDouble]) +pango: text=(["High Templar"]) +pango: wrap=([#]) +pango: ellipsize=([#]) +pango: alignment=([#]) +pango: justify=([false]) +cairo: move_to([0, 0]) +cairo: move_to([0, 0]) +cairo: show_pango_layout([MockDouble]) +pango: ellipsized?([]) +cairo: restore([]) +cairo: set_source([MockDouble, 0, 0]) +cairo: paint([]) +cairo: set_source([MockDouble, 100, 0]) +cairo: paint([]) +cairo: set_source([MockDouble, 200, 0]) +cairo: paint([]) +cairo: set_source([MockDouble, 300, 0]) +cairo: paint([]) +surface: write_to_png(["_output/sample_xlsx_qty_00.png"]) +cairo: antialias=(["subpixel"]) +cairo: antialias=(["subpixel"]) +cairo: antialias=(["subpixel"]) +cairo: antialias=(["subpixel"]) +cairo: antialias=(["subpixel"]) +cairo: antialias=(["subpixel"]) +cairo: save([]) +cairo: set_source_color(["white"]) +cairo: paint([]) +cairo: restore([]) +cairo: save([]) +cairo: set_source_color(["white"]) +cairo: paint([]) +cairo: restore([]) +cairo: save([]) +cairo: set_source_color(["white"]) +cairo: paint([]) +cairo: restore([]) +cairo: save([]) +cairo: set_source_color(["white"]) +cairo: paint([]) +cairo: restore([]) +cairo: save([]) +cairo: set_source_color(["white"]) +cairo: paint([]) +cairo: restore([]) +cairo: save([]) +cairo: set_source_color(["white"]) +cairo: paint([]) +cairo: restore([]) +cairo: save([]) +cairo: rounded_rectangle([0, 0, 825, 1125, 0, 0]) +cairo: set_source_color(["#0000"]) +cairo: fill_preserve([]) +cairo: set_source_color(["black"]) +cairo: set_line_width([2.0]) +cairo: set_line_join([0]) +cairo: set_line_cap([0]) +cairo: set_dash([[]]) +cairo: stroke([]) +cairo: restore([]) +cairo: save([]) +cairo: rounded_rectangle([0, 0, 825, 1125, 0, 0]) +cairo: set_source_color(["#0000"]) +cairo: fill_preserve([]) +cairo: set_source_color(["black"]) +cairo: set_line_width([2.0]) +cairo: set_line_join([0]) +cairo: set_line_cap([0]) +cairo: set_dash([[]]) +cairo: stroke([]) +cairo: restore([]) +cairo: save([]) +cairo: rounded_rectangle([0, 0, 825, 1125, 0, 0]) +cairo: set_source_color(["#0000"]) +cairo: fill_preserve([]) +cairo: set_source_color(["black"]) +cairo: set_line_width([2.0]) +cairo: set_line_join([0]) +cairo: set_line_cap([0]) +cairo: set_dash([[]]) +cairo: stroke([]) +cairo: restore([]) +cairo: save([]) +cairo: rounded_rectangle([0, 0, 825, 1125, 0, 0]) +cairo: set_source_color(["#0000"]) +cairo: fill_preserve([]) +cairo: set_source_color(["black"]) +cairo: set_line_width([2.0]) +cairo: set_line_join([0]) +cairo: set_line_cap([0]) +cairo: set_dash([[]]) +cairo: stroke([]) +cairo: restore([]) +cairo: save([]) +cairo: rounded_rectangle([0, 0, 825, 1125, 0, 0]) +cairo: set_source_color(["#0000"]) +cairo: fill_preserve([]) +cairo: set_source_color(["black"]) +cairo: set_line_width([2.0]) +cairo: set_line_join([0]) +cairo: set_line_cap([0]) +cairo: set_dash([[]]) +cairo: stroke([]) +cairo: restore([]) +cairo: save([]) +cairo: rounded_rectangle([0, 0, 825, 1125, 0, 0]) +cairo: set_source_color(["#0000"]) +cairo: fill_preserve([]) +cairo: set_source_color(["black"]) +cairo: set_line_width([2.0]) +cairo: set_line_join([0]) +cairo: set_line_cap([0]) +cairo: set_dash([[]]) +cairo: stroke([]) +cairo: restore([]) +cairo: save([]) cairo: set_source_color(["black"]) cairo: translate([0, 0]) cairo: rotate([0]) @@ -235,6 +420,69 @@ cairo: translate([0, 0]) cairo: rotate([0]) cairo: move_to([0, 0]) pango: font_description=([MockDouble]) +pango: text=(["Wood"]) +pango: width=([844800]) +pango: wrap=([#]) +pango: ellipsize=([#]) +pango: alignment=([#]) +pango: justify=([false]) +cairo: move_to([0, 0]) +cairo: move_to([0, 0]) +cairo: show_pango_layout([MockDouble]) +cairo: rounded_rectangle([0, 0, 0, 0, 0, 0]) +cairo: set_source_color(["red"]) +cairo: set_line_width([2.0]) +cairo: stroke([]) +pango: ellipsized?([]) +cairo: restore([]) +cairo: save([]) +cairo: set_source_color(["black"]) +cairo: translate([0, 0]) +cairo: rotate([0]) +cairo: move_to([0, 0]) +pango: font_description=([MockDouble]) +pango: text=(["Wood"]) +pango: width=([844800]) +pango: wrap=([#]) +pango: ellipsize=([#]) +pango: alignment=([#]) +pango: justify=([false]) +cairo: move_to([0, 0]) +cairo: move_to([0, 0]) +cairo: show_pango_layout([MockDouble]) +cairo: rounded_rectangle([0, 0, 0, 0, 0, 0]) +cairo: set_source_color(["red"]) +cairo: set_line_width([2.0]) +cairo: stroke([]) +pango: ellipsized?([]) +cairo: restore([]) +cairo: save([]) +cairo: set_source_color(["black"]) +cairo: translate([0, 0]) +cairo: rotate([0]) +cairo: move_to([0, 0]) +pango: font_description=([MockDouble]) +pango: text=(["Metal"]) +pango: width=([844800]) +pango: wrap=([#]) +pango: ellipsize=([#]) +pango: alignment=([#]) +pango: justify=([false]) +cairo: move_to([0, 0]) +cairo: move_to([0, 0]) +cairo: show_pango_layout([MockDouble]) +cairo: rounded_rectangle([0, 0, 0, 0, 0, 0]) +cairo: set_source_color(["red"]) +cairo: set_line_width([2.0]) +cairo: stroke([]) +pango: ellipsized?([]) +cairo: restore([]) +cairo: save([]) +cairo: set_source_color(["black"]) +cairo: translate([0, 0]) +cairo: rotate([0]) +cairo: move_to([0, 0]) +pango: font_description=([MockDouble]) pango: text=(["Metal"]) pango: width=([844800]) pango: wrap=([#]) @@ -298,6 +546,69 @@ cairo: translate([0, 0]) cairo: rotate([0]) cairo: move_to([0, 0]) pango: font_description=([MockDouble]) +pango: text=(["$2k"]) +pango: width=([844800]) +pango: wrap=([#]) +pango: ellipsize=([#]) +pango: alignment=([#]) +pango: justify=([false]) +cairo: move_to([0, 0]) +cairo: move_to([0, 0]) +cairo: show_pango_layout([MockDouble]) +cairo: rounded_rectangle([0, 0, 0, 0, 0, 0]) +cairo: set_source_color(["red"]) +cairo: set_line_width([2.0]) +cairo: stroke([]) +pango: ellipsized?([]) +cairo: restore([]) +cairo: save([]) +cairo: set_source_color(["black"]) +cairo: translate([0, 0]) +cairo: rotate([0]) +cairo: move_to([0, 0]) +pango: font_description=([MockDouble]) +pango: text=(["$2k"]) +pango: width=([844800]) +pango: wrap=([#]) +pango: ellipsize=([#]) +pango: alignment=([#]) +pango: justify=([false]) +cairo: move_to([0, 0]) +cairo: move_to([0, 0]) +cairo: show_pango_layout([MockDouble]) +cairo: rounded_rectangle([0, 0, 0, 0, 0, 0]) +cairo: set_source_color(["red"]) +cairo: set_line_width([2.0]) +cairo: stroke([]) +pango: ellipsized?([]) +cairo: restore([]) +cairo: save([]) +cairo: set_source_color(["black"]) +cairo: translate([0, 0]) +cairo: rotate([0]) +cairo: move_to([0, 0]) +pango: font_description=([MockDouble]) +pango: text=(["$3k"]) +pango: width=([844800]) +pango: wrap=([#]) +pango: ellipsize=([#]) +pango: alignment=([#]) +pango: justify=([false]) +cairo: move_to([0, 0]) +cairo: move_to([0, 0]) +cairo: show_pango_layout([MockDouble]) +cairo: rounded_rectangle([0, 0, 0, 0, 0, 0]) +cairo: set_source_color(["red"]) +cairo: set_line_width([2.0]) +cairo: stroke([]) +pango: ellipsized?([]) +cairo: restore([]) +cairo: save([]) +cairo: set_source_color(["black"]) +cairo: translate([0, 0]) +cairo: rotate([0]) +cairo: move_to([0, 0]) +pango: font_description=([MockDouble]) pango: text=(["$3k"]) pango: width=([844800]) pango: wrap=([#]) @@ -340,4 +651,11 @@ cairo: set_source([MockDouble, 100, 0]) cairo: paint([]) cairo: set_source([MockDouble, 200, 0]) cairo: paint([]) +cairo: set_source([MockDouble, 300, 0]) +cairo: paint([]) +cairo: set_source([MockDouble, 400, 0]) +cairo: paint([]) surface: write_to_png(["_output/sample_excel_resources_00.png"]) +cairo: set_source([MockDouble, 0, 0]) +cairo: paint([]) +surface: write_to_png(["_output/sample_excel_resources_01.png"])