squib_plus 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
 - data/.gitignore +4 -0
 - data/Gemfile +4 -0
 - data/lib/squib_plus/card_size.rb +35 -0
 - data/lib/squib_plus/deck/avatar.rb +89 -0
 - data/lib/squib_plus/deck.rb +50 -0
 - data/lib/squib_plus/google_sheets.rb +37 -0
 - data/lib/squib_plus/pdf.rb +50 -0
 - data/lib/squib_plus/sprues/letter_poker_tight.yml +42 -0
 - data/lib/squib_plus/sprues/letter_poker_tight_reverse.yml +42 -0
 - data/lib/squib_plus/string.rb +5 -0
 - data/lib/squib_plus/subset.rb +21 -0
 - data/lib/squib_plus.rb +6 -0
 - data/squib_plus.gemspec +14 -0
 - metadata +55 -0
 
    
        checksums.yaml
    ADDED
    
    | 
         @@ -0,0 +1,7 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ---
         
     | 
| 
      
 2 
     | 
    
         
            +
            SHA256:
         
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 19f2f11b51db065d28f3be11cbc30293202dac9c1e9bee8b77408ab9b07d255b
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 6ee1c5d23a051ff4341ddd6957e4e80f000c1ac94909e7beb3a1cfba3babce9f
         
     | 
| 
      
 5 
     | 
    
         
            +
            SHA512:
         
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: ff9ebe8819ff49e08f99dd6d6054e86f62297748341280c4ca291f84fde4a772cff2bd42f222f8fd0513d0c9b337c86740e6f8cb5624466c44a296292d54302f
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 4b2d3ab40628d117c1c138f04d5170efb5d82fa32e43ca1479d8da48672a7018629aa64ecfc7df7ce91dd2f6973969f6afc18c6a619f2531bec01fb35743db7e
         
     | 
    
        data/.gitignore
    ADDED
    
    
    
        data/Gemfile
    ADDED
    
    
| 
         @@ -0,0 +1,35 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Squib
         
     | 
| 
      
 4 
     | 
    
         
            +
              # Default card sizes for use like
         
     | 
| 
      
 5 
     | 
    
         
            +
              #   Squib::Deck.new(**Squib.card_size(:bridge))
         
     | 
| 
      
 6 
     | 
    
         
            +
              #
         
     | 
| 
      
 7 
     | 
    
         
            +
              # Note that each of these has 0.25in extra compared
         
     | 
| 
      
 8 
     | 
    
         
            +
              # to the real-world dimensions of the card in order
         
     | 
| 
      
 9 
     | 
    
         
            +
              # to account for bleed.
         
     | 
| 
      
 10 
     | 
    
         
            +
              @@card_sizes = {
         
     | 
| 
      
 11 
     | 
    
         
            +
                bridge: { width: '2.5in', height: '3.75in' },
         
     | 
| 
      
 12 
     | 
    
         
            +
                business: { width: '2.25in', height: '3.75in' },
         
     | 
| 
      
 13 
     | 
    
         
            +
                divider: { width: '3.25in', height: '3.75in' },
         
     | 
| 
      
 14 
     | 
    
         
            +
                domino: { width: '2in', height: '3.75in' },
         
     | 
| 
      
 15 
     | 
    
         
            +
                euro_poker: { width: '2.73in', height: '3.71in' },
         
     | 
| 
      
 16 
     | 
    
         
            +
                euro_square: { width: '3.01in', height: '3.01in' },
         
     | 
| 
      
 17 
     | 
    
         
            +
                jumbo: { width: '3.75in', height: '5.75in' },
         
     | 
| 
      
 18 
     | 
    
         
            +
                micro: { width: '1.5in', height: '2in' },
         
     | 
| 
      
 19 
     | 
    
         
            +
                mini: { width: '2in', height: '2.75in' },
         
     | 
| 
      
 20 
     | 
    
         
            +
                poker: { width: '2.75in', height: '3.75in' },
         
     | 
| 
      
 21 
     | 
    
         
            +
                mint_tin: { width: '2.3in', height: '3.71in' },
         
     | 
| 
      
 22 
     | 
    
         
            +
                small_square: { width: '2.75in', height: '2.75in' },
         
     | 
| 
      
 23 
     | 
    
         
            +
                square: { width: '3.75in', height: '3.75in' },
         
     | 
| 
      
 24 
     | 
    
         
            +
                tarot: { width: '2.75in', height: '5in' },
         
     | 
| 
      
 25 
     | 
    
         
            +
                us_game: { width: '2.45in', height: '3.68in' }
         
     | 
| 
      
 26 
     | 
    
         
            +
              }
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
              def card_size(name, landscape: false)
         
     | 
| 
      
 29 
     | 
    
         
            +
                dimensions = @@card_sizes.fetch name
         
     | 
| 
      
 30 
     | 
    
         
            +
                dimensions = { width: dimensions[:height], height: dimensions[:width] } if landscape
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                { dpi: 300 }.merge dimensions
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
              module_function :card_size
         
     | 
| 
      
 35 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,89 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'fileutils'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'mechanize'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            module Squib
         
     | 
| 
      
 7 
     | 
    
         
            +
              class Deck
         
     | 
| 
      
 8 
     | 
    
         
            +
                def avatar(opts = {})
         
     | 
| 
      
 9 
     | 
    
         
            +
                  DSL::Avatar.new(self, __callee__).run(opts)
         
     | 
| 
      
 10 
     | 
    
         
            +
                end
         
     | 
| 
      
 11 
     | 
    
         
            +
              end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
              module DSL
         
     | 
| 
      
 14 
     | 
    
         
            +
                # Add an avatar for placeholder art in your games
         
     | 
| 
      
 15 
     | 
    
         
            +
                # using https://avatars.dicebear.com/. The image will
         
     | 
| 
      
 16 
     | 
    
         
            +
                # be downloaded to your configured image directory if
         
     | 
| 
      
 17 
     | 
    
         
            +
                # it doesn't already exist.
         
     | 
| 
      
 18 
     | 
    
         
            +
                #
         
     | 
| 
      
 19 
     | 
    
         
            +
                # Library can be male, female, human, identicon, initials,
         
     | 
| 
      
 20 
     | 
    
         
            +
                # bottts, avataaars, jdenticon, gridy or micah.
         
     | 
| 
      
 21 
     | 
    
         
            +
                #
         
     | 
| 
      
 22 
     | 
    
         
            +
                # Seed can be any random string
         
     | 
| 
      
 23 
     | 
    
         
            +
                #
         
     | 
| 
      
 24 
     | 
    
         
            +
                # Example:
         
     | 
| 
      
 25 
     | 
    
         
            +
                #   avatar library: 'micah', seed: '1234'
         
     | 
| 
      
 26 
     | 
    
         
            +
                class Avatar
         
     | 
| 
      
 27 
     | 
    
         
            +
                  attr_reader :dsl_method, :deck
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                  def initialize(deck, dsl_method)
         
     | 
| 
      
 30 
     | 
    
         
            +
                    @deck = deck
         
     | 
| 
      
 31 
     | 
    
         
            +
                    @dsl_method = dsl_method
         
     | 
| 
      
 32 
     | 
    
         
            +
                  end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                  def self.accepted_params
         
     | 
| 
      
 35 
     | 
    
         
            +
                    %i[
         
     | 
| 
      
 36 
     | 
    
         
            +
                      library seed
         
     | 
| 
      
 37 
     | 
    
         
            +
                      x y width height
         
     | 
| 
      
 38 
     | 
    
         
            +
                      blend mask
         
     | 
| 
      
 39 
     | 
    
         
            +
                      crop_x crop_y crop_width crop_height
         
     | 
| 
      
 40 
     | 
    
         
            +
                      crop_corner_radius crop_corner_x_radius crop_corner_y_radius
         
     | 
| 
      
 41 
     | 
    
         
            +
                      flip_horizontal flip_vertical angle
         
     | 
| 
      
 42 
     | 
    
         
            +
                      id force_id data
         
     | 
| 
      
 43 
     | 
    
         
            +
                      range layout
         
     | 
| 
      
 44 
     | 
    
         
            +
                      placeholder
         
     | 
| 
      
 45 
     | 
    
         
            +
                    ]
         
     | 
| 
      
 46 
     | 
    
         
            +
                  end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                  def run(opts)
         
     | 
| 
      
 49 
     | 
    
         
            +
                    Dir.chdir(deck.img_dir) do
         
     | 
| 
      
 50 
     | 
    
         
            +
                      defaults = { library: 'avataaars' }
         
     | 
| 
      
 51 
     | 
    
         
            +
                      options = defaults.merge opts
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                      # Extract the default svg options
         
     | 
| 
      
 54 
     | 
    
         
            +
                      range = Args.extract_range opts, deck
         
     | 
| 
      
 55 
     | 
    
         
            +
                      svg_args = Args.extract_svg_special opts, deck
         
     | 
| 
      
 56 
     | 
    
         
            +
                      paint = Args.extract_paint opts, deck
         
     | 
| 
      
 57 
     | 
    
         
            +
                      box   = Args.extract_scale_box opts, deck
         
     | 
| 
      
 58 
     | 
    
         
            +
                      trans = Args.extract_transform opts, deck
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                      deck.progress_bar.start('Loading Avatar(s)', range.size) do |bar|
         
     | 
| 
      
 61 
     | 
    
         
            +
                        range.each do |i|
         
     | 
| 
      
 62 
     | 
    
         
            +
                          library = options[:library]
         
     | 
| 
      
 63 
     | 
    
         
            +
                          seed = options[:seed][i]
         
     | 
| 
      
 64 
     | 
    
         
            +
                          next if seed.nil?
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                          file = "avatar-#{library}-#{seed}.svg"
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                          # Check if we need to download the image
         
     | 
| 
      
 69 
     | 
    
         
            +
                          unless File.exist?(file)
         
     | 
| 
      
 70 
     | 
    
         
            +
                            agent = Mechanize.new
         
     | 
| 
      
 71 
     | 
    
         
            +
                            agent.follow_meta_refresh = true
         
     | 
| 
      
 72 
     | 
    
         
            +
                            agent.keep_alive = false
         
     | 
| 
      
 73 
     | 
    
         
            +
                            agent.history.max_size = 10
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                            response = agent.get_file("https://avatars.dicebear.com/api/#{library}/#{seed}.svg")
         
     | 
| 
      
 76 
     | 
    
         
            +
                            response = response.encode('ascii-8bit').force_encoding('utf-8')
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                            File.open(file, 'w') { |f| f.write(response) }
         
     | 
| 
      
 79 
     | 
    
         
            +
                          end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                          deck.cards[i].svg(file, svg_args[i], box[i], paint[i], trans[i])
         
     | 
| 
      
 82 
     | 
    
         
            +
                          bar.increment
         
     | 
| 
      
 83 
     | 
    
         
            +
                        end
         
     | 
| 
      
 84 
     | 
    
         
            +
                      end
         
     | 
| 
      
 85 
     | 
    
         
            +
                    end
         
     | 
| 
      
 86 
     | 
    
         
            +
                  end
         
     | 
| 
      
 87 
     | 
    
         
            +
                end
         
     | 
| 
      
 88 
     | 
    
         
            +
              end
         
     | 
| 
      
 89 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,50 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'fileutils'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            module Squib
         
     | 
| 
      
 6 
     | 
    
         
            +
              class Deck
         
     | 
| 
      
 7 
     | 
    
         
            +
                # Adds a card number to the bottom right of the card by default.
         
     | 
| 
      
 8 
     | 
    
         
            +
                # Helps with tracking down a specific card in your spreadsheet in
         
     | 
| 
      
 9 
     | 
    
         
            +
                # games with many unique cards.
         
     | 
| 
      
 10 
     | 
    
         
            +
                def card_num(opts = {})
         
     | 
| 
      
 11 
     | 
    
         
            +
                  defaults = {
         
     | 
| 
      
 12 
     | 
    
         
            +
                    x: width - 100,
         
     | 
| 
      
 13 
     | 
    
         
            +
                    y: height - 100,
         
     | 
| 
      
 14 
     | 
    
         
            +
                    width: 50,
         
     | 
| 
      
 15 
     | 
    
         
            +
                    height: 50,
         
     | 
| 
      
 16 
     | 
    
         
            +
                    font: 'sans-serif',
         
     | 
| 
      
 17 
     | 
    
         
            +
                    font_size: 9,
         
     | 
| 
      
 18 
     | 
    
         
            +
                    color: '#000',
         
     | 
| 
      
 19 
     | 
    
         
            +
                    align: :center,
         
     | 
| 
      
 20 
     | 
    
         
            +
                    valign: :middle
         
     | 
| 
      
 21 
     | 
    
         
            +
                  }
         
     | 
| 
      
 22 
     | 
    
         
            +
                  range = Args.extract_range opts, self
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                  # Index from 1
         
     | 
| 
      
 25 
     | 
    
         
            +
                  text(str: range.map { |i| i + 1 }, **(defaults.merge opts))
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                # Shortcut for save_sheet with defaults that make sense for Tabletop Simulator
         
     | 
| 
      
 29 
     | 
    
         
            +
                def tts(opts = {})
         
     | 
| 
      
 30 
     | 
    
         
            +
                  defaults = { columns: 10, rows: 7, trim: 37.5 }
         
     | 
| 
      
 31 
     | 
    
         
            +
                  save_sheet(defaults.merge(opts))
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                # Shortcut for creating a Print-n-Play sheet using poker-sized cards
         
     | 
| 
      
 35 
     | 
    
         
            +
                def pnp(opts = {})
         
     | 
| 
      
 36 
     | 
    
         
            +
                  cut_zone stroke_color: '#888'
         
     | 
| 
      
 37 
     | 
    
         
            +
                  defaults = {
         
     | 
| 
      
 38 
     | 
    
         
            +
                    trim: 37.5,
         
     | 
| 
      
 39 
     | 
    
         
            +
                    sprue: if opts[:rtl]
         
     | 
| 
      
 40 
     | 
    
         
            +
                             "#{File.dirname(__FILE__)}/sprues/letter_poker_tight_reverse.yml"
         
     | 
| 
      
 41 
     | 
    
         
            +
                           else
         
     | 
| 
      
 42 
     | 
    
         
            +
                             "#{File.dirname(__FILE__)}/sprues/letter_poker_tight.yml"
         
     | 
| 
      
 43 
     | 
    
         
            +
                           end
         
     | 
| 
      
 44 
     | 
    
         
            +
                  }
         
     | 
| 
      
 45 
     | 
    
         
            +
                  save_pdf(defaults.merge(opts))
         
     | 
| 
      
 46 
     | 
    
         
            +
                end
         
     | 
| 
      
 47 
     | 
    
         
            +
              end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
              require_relative 'deck/avatar'
         
     | 
| 
      
 50 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,37 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'mechanize'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            module Squib
         
     | 
| 
      
 6 
     | 
    
         
            +
              # gsheet allows you to load Deck data using Google Sheets.
         
     | 
| 
      
 7 
     | 
    
         
            +
              #
         
     | 
| 
      
 8 
     | 
    
         
            +
              # First, share your sheet using File > Publish to the web
         
     | 
| 
      
 9 
     | 
    
         
            +
              # Select 'Entire document' and '.csv' as the format
         
     | 
| 
      
 10 
     | 
    
         
            +
              # Copy the URL like
         
     | 
| 
      
 11 
     | 
    
         
            +
              #   https://docs.google.com/spreadsheets/d/e/2PACX-.../pub?output=csv
         
     | 
| 
      
 12 
     | 
    
         
            +
              #                                            ^^^^^^^^^
         
     | 
| 
      
 13 
     | 
    
         
            +
              #   The code you need to pass is the long ID after /d/e.
         
     | 
| 
      
 14 
     | 
    
         
            +
              #
         
     | 
| 
      
 15 
     | 
    
         
            +
              # If the sheet has multiple tabs, you can specify a later tab using the gid from
         
     | 
| 
      
 16 
     | 
    
         
            +
              # the non-share URL like
         
     | 
| 
      
 17 
     | 
    
         
            +
              #   https://docs.google.com/spreadsheets/d/.../edit#gid=123456
         
     | 
| 
      
 18 
     | 
    
         
            +
              #                                                       ^^^^^^
         
     | 
| 
      
 19 
     | 
    
         
            +
              #   The gid is at the end of the URL after #gid=
         
     | 
| 
      
 20 
     | 
    
         
            +
              #
         
     | 
| 
      
 21 
     | 
    
         
            +
              # Example:
         
     | 
| 
      
 22 
     | 
    
         
            +
              #   deck = Squib.gsheet('2PACX-...', 123456)
         
     | 
| 
      
 23 
     | 
    
         
            +
              #
         
     | 
| 
      
 24 
     | 
    
         
            +
              #   Squib::Deck.new(cards: deck['name'].size) do
         
     | 
| 
      
 25 
     | 
    
         
            +
              #     ...
         
     | 
| 
      
 26 
     | 
    
         
            +
              #   end
         
     | 
| 
      
 27 
     | 
    
         
            +
              #
         
     | 
| 
      
 28 
     | 
    
         
            +
              # You can optionally specify the tab to use with the second argument
         
     | 
| 
      
 29 
     | 
    
         
            +
              def gsheet(sheet_id, index = 0)
         
     | 
| 
      
 30 
     | 
    
         
            +
                agent = Mechanize.new
         
     | 
| 
      
 31 
     | 
    
         
            +
                response = agent.get_file("https://docs.google.com/spreadsheets/d/e/#{sheet_id}/pub?gid=#{index}&output=csv")
         
     | 
| 
      
 32 
     | 
    
         
            +
                response = response.encode('ascii-8bit').force_encoding('utf-8')
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                Squib.csv data: response
         
     | 
| 
      
 35 
     | 
    
         
            +
              end
         
     | 
| 
      
 36 
     | 
    
         
            +
              module_function :gsheet
         
     | 
| 
      
 37 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,50 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'combine_pdf'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            module Squib
         
     | 
| 
      
 6 
     | 
    
         
            +
              # Merge PDFs together, collated for front/back printing
         
     | 
| 
      
 7 
     | 
    
         
            +
              # Example:
         
     | 
| 
      
 8 
     | 
    
         
            +
              #   # Deck front
         
     | 
| 
      
 9 
     | 
    
         
            +
              #   Squib::Deck.new(cards: deck['name'].size) do
         
     | 
| 
      
 10 
     | 
    
         
            +
              #     ...
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
              #     pnp file: 'front.pdf'
         
     | 
| 
      
 13 
     | 
    
         
            +
              #   end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
              #   # Deck back
         
     | 
| 
      
 16 
     | 
    
         
            +
              #   Squib::Deck.new(cards: deck['name'].size) do
         
     | 
| 
      
 17 
     | 
    
         
            +
              #     ...
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
              #     pnp file: 'back.pdf'
         
     | 
| 
      
 20 
     | 
    
         
            +
              #   end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
              #   # Combine PnP
         
     | 
| 
      
 23 
     | 
    
         
            +
              #   Squib.combine_pdfs([
         
     | 
| 
      
 24 
     | 
    
         
            +
              #     { :front => "_output/front.pdf", :back => "_output/back.pdf" },
         
     | 
| 
      
 25 
     | 
    
         
            +
              #   ], "_output/pnp.pdf")
         
     | 
| 
      
 26 
     | 
    
         
            +
              def combine_pdfs(sheets, file)
         
     | 
| 
      
 27 
     | 
    
         
            +
                pdf = CombinePDF.new
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                sheets.each do |sheet|
         
     | 
| 
      
 30 
     | 
    
         
            +
                  front = CombinePDF.load(sheet[:front])
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                  # Collate the back pages immediately after the relevant page,
         
     | 
| 
      
 33 
     | 
    
         
            +
                  # if a back-side is provided.
         
     | 
| 
      
 34 
     | 
    
         
            +
                  back = CombinePDF.load(sheet[:back]) if sheet.key?(:back)
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                  i = 0
         
     | 
| 
      
 37 
     | 
    
         
            +
                  front.pages.each do |page|
         
     | 
| 
      
 38 
     | 
    
         
            +
                    pdf << page
         
     | 
| 
      
 39 
     | 
    
         
            +
                    pdf << back.pages[i] if sheet.key?(:back)
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                    break if i == front.pages.count - 1
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                    i += 1
         
     | 
| 
      
 44 
     | 
    
         
            +
                  end
         
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                pdf.save file
         
     | 
| 
      
 48 
     | 
    
         
            +
              end
         
     | 
| 
      
 49 
     | 
    
         
            +
              module_function :combine_pdfs
         
     | 
| 
      
 50 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,42 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ---
         
     | 
| 
      
 2 
     | 
    
         
            +
            sheet_width: 8.5in
         
     | 
| 
      
 3 
     | 
    
         
            +
            sheet_height: 11in
         
     | 
| 
      
 4 
     | 
    
         
            +
            card_width: 2.5in
         
     | 
| 
      
 5 
     | 
    
         
            +
            card_height: 3.5in
         
     | 
| 
      
 6 
     | 
    
         
            +
            cards:
         
     | 
| 
      
 7 
     | 
    
         
            +
            - x: 0.5in
         
     | 
| 
      
 8 
     | 
    
         
            +
              y: 0.225in
         
     | 
| 
      
 9 
     | 
    
         
            +
            - x: 3in
         
     | 
| 
      
 10 
     | 
    
         
            +
              y: 0.225in
         
     | 
| 
      
 11 
     | 
    
         
            +
            - x: 5.5in
         
     | 
| 
      
 12 
     | 
    
         
            +
              y: 0.225in
         
     | 
| 
      
 13 
     | 
    
         
            +
            - x: 0.5in
         
     | 
| 
      
 14 
     | 
    
         
            +
              y: 3.725in
         
     | 
| 
      
 15 
     | 
    
         
            +
            - x: 3in
         
     | 
| 
      
 16 
     | 
    
         
            +
              y: 3.725in
         
     | 
| 
      
 17 
     | 
    
         
            +
            - x: 5.5in
         
     | 
| 
      
 18 
     | 
    
         
            +
              y: 3.725in
         
     | 
| 
      
 19 
     | 
    
         
            +
            - x: 0.5in
         
     | 
| 
      
 20 
     | 
    
         
            +
              y: 7.225in
         
     | 
| 
      
 21 
     | 
    
         
            +
            - x: 3in
         
     | 
| 
      
 22 
     | 
    
         
            +
              y: 7.225in
         
     | 
| 
      
 23 
     | 
    
         
            +
            - x: 5.5in
         
     | 
| 
      
 24 
     | 
    
         
            +
              y: 7.225in
         
     | 
| 
      
 25 
     | 
    
         
            +
            crop_line:
         
     | 
| 
      
 26 
     | 
    
         
            +
              lines:
         
     | 
| 
      
 27 
     | 
    
         
            +
              - type: :vertical
         
     | 
| 
      
 28 
     | 
    
         
            +
                position: 0.5in
         
     | 
| 
      
 29 
     | 
    
         
            +
              - type: :vertical
         
     | 
| 
      
 30 
     | 
    
         
            +
                position: 3in
         
     | 
| 
      
 31 
     | 
    
         
            +
              - type: :vertical
         
     | 
| 
      
 32 
     | 
    
         
            +
                position: 5.5in
         
     | 
| 
      
 33 
     | 
    
         
            +
              - type: :vertical
         
     | 
| 
      
 34 
     | 
    
         
            +
                position: 8in
         
     | 
| 
      
 35 
     | 
    
         
            +
              - type: :horizontal
         
     | 
| 
      
 36 
     | 
    
         
            +
                position: 0.225in
         
     | 
| 
      
 37 
     | 
    
         
            +
              - type: :horizontal
         
     | 
| 
      
 38 
     | 
    
         
            +
                position: 3.725in
         
     | 
| 
      
 39 
     | 
    
         
            +
              - type: :horizontal
         
     | 
| 
      
 40 
     | 
    
         
            +
                position: 7.225in
         
     | 
| 
      
 41 
     | 
    
         
            +
              - type: :horizontal
         
     | 
| 
      
 42 
     | 
    
         
            +
                position: 10.725in
         
     | 
| 
         @@ -0,0 +1,42 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ---
         
     | 
| 
      
 2 
     | 
    
         
            +
            sheet_width: 8.5in
         
     | 
| 
      
 3 
     | 
    
         
            +
            sheet_height: 11in
         
     | 
| 
      
 4 
     | 
    
         
            +
            card_width: 2.5in
         
     | 
| 
      
 5 
     | 
    
         
            +
            card_height: 3.5in
         
     | 
| 
      
 6 
     | 
    
         
            +
            cards:
         
     | 
| 
      
 7 
     | 
    
         
            +
            - x: 5.5in
         
     | 
| 
      
 8 
     | 
    
         
            +
              y: 0.225in
         
     | 
| 
      
 9 
     | 
    
         
            +
            - x: 3in
         
     | 
| 
      
 10 
     | 
    
         
            +
              y: 0.225in
         
     | 
| 
      
 11 
     | 
    
         
            +
            - x: 0.5in
         
     | 
| 
      
 12 
     | 
    
         
            +
              y: 0.225in
         
     | 
| 
      
 13 
     | 
    
         
            +
            - x: 5.5in
         
     | 
| 
      
 14 
     | 
    
         
            +
              y: 3.725in
         
     | 
| 
      
 15 
     | 
    
         
            +
            - x: 3in
         
     | 
| 
      
 16 
     | 
    
         
            +
              y: 3.725in
         
     | 
| 
      
 17 
     | 
    
         
            +
            - x: 0.5in
         
     | 
| 
      
 18 
     | 
    
         
            +
              y: 3.725in
         
     | 
| 
      
 19 
     | 
    
         
            +
            - x: 5.5in
         
     | 
| 
      
 20 
     | 
    
         
            +
              y: 7.225in
         
     | 
| 
      
 21 
     | 
    
         
            +
            - x: 3in
         
     | 
| 
      
 22 
     | 
    
         
            +
              y: 7.225in
         
     | 
| 
      
 23 
     | 
    
         
            +
            - x: 0.5in
         
     | 
| 
      
 24 
     | 
    
         
            +
              y: 7.225in
         
     | 
| 
      
 25 
     | 
    
         
            +
            crop_line:
         
     | 
| 
      
 26 
     | 
    
         
            +
              lines:
         
     | 
| 
      
 27 
     | 
    
         
            +
              - type: :vertical
         
     | 
| 
      
 28 
     | 
    
         
            +
                position: 0.5in
         
     | 
| 
      
 29 
     | 
    
         
            +
              - type: :vertical
         
     | 
| 
      
 30 
     | 
    
         
            +
                position: 3in
         
     | 
| 
      
 31 
     | 
    
         
            +
              - type: :vertical
         
     | 
| 
      
 32 
     | 
    
         
            +
                position: 5.5in
         
     | 
| 
      
 33 
     | 
    
         
            +
              - type: :vertical
         
     | 
| 
      
 34 
     | 
    
         
            +
                position: 8in
         
     | 
| 
      
 35 
     | 
    
         
            +
              - type: :horizontal
         
     | 
| 
      
 36 
     | 
    
         
            +
                position: 0.225in
         
     | 
| 
      
 37 
     | 
    
         
            +
              - type: :horizontal
         
     | 
| 
      
 38 
     | 
    
         
            +
                position: 3.725in
         
     | 
| 
      
 39 
     | 
    
         
            +
              - type: :horizontal
         
     | 
| 
      
 40 
     | 
    
         
            +
                position: 7.225in
         
     | 
| 
      
 41 
     | 
    
         
            +
              - type: :horizontal
         
     | 
| 
      
 42 
     | 
    
         
            +
                position: 10.725in
         
     | 
| 
         @@ -0,0 +1,21 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Squib
         
     | 
| 
      
 4 
     | 
    
         
            +
              # Subset a selection of cards based on some criteria. Can be passed
         
     | 
| 
      
 5 
     | 
    
         
            +
              # directly into the range argument of other DSL functions.
         
     | 
| 
      
 6 
     | 
    
         
            +
              #
         
     | 
| 
      
 7 
     | 
    
         
            +
              # Example:
         
     | 
| 
      
 8 
     | 
    
         
            +
              #   gems = Squib.subset(deck['category'], -> (c) { c === 'gem' })
         
     | 
| 
      
 9 
     | 
    
         
            +
              #   text range: gems, str: deck['gem_num'], layout: 'gem_label'
         
     | 
| 
      
 10 
     | 
    
         
            +
              #
         
     | 
| 
      
 11 
     | 
    
         
            +
              # You can invert the match using matching: false
         
     | 
| 
      
 12 
     | 
    
         
            +
              # This allows you to use a single criteria function for positive/negative
         
     | 
| 
      
 13 
     | 
    
         
            +
              # matches.
         
     | 
| 
      
 14 
     | 
    
         
            +
              def subset(column, criteria, matching: true)
         
     | 
| 
      
 15 
     | 
    
         
            +
                sub = {}
         
     | 
| 
      
 16 
     | 
    
         
            +
                column.each_with_index { |c, i| (sub[criteria.call(c)] ||= []) << i }
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                sub[matching]
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
              module_function :subset
         
     | 
| 
      
 21 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/squib_plus.rb
    ADDED
    
    
    
        data/squib_plus.gemspec
    ADDED
    
    | 
         @@ -0,0 +1,14 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Gem::Specification.new do |s|
         
     | 
| 
      
 4 
     | 
    
         
            +
              s.name = 'squib_plus'
         
     | 
| 
      
 5 
     | 
    
         
            +
              s.version       = '0.0.1'
         
     | 
| 
      
 6 
     | 
    
         
            +
              s.files         = `git ls-files -z`.split("\x0")
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
              s.authors     = ['Rob Newton']
         
     | 
| 
      
 9 
     | 
    
         
            +
              s.summary     = 'Extensions for Squib'
         
     | 
| 
      
 10 
     | 
    
         
            +
              s.description = 'Helper functions extending the functionality of Squib'
         
     | 
| 
      
 11 
     | 
    
         
            +
              s.email       = 'robert@coinflip.games'
         
     | 
| 
      
 12 
     | 
    
         
            +
              s.homepage    = 'https://rubygems.org/gems/squib_plus'
         
     | 
| 
      
 13 
     | 
    
         
            +
              s.license     = 'MIT'
         
     | 
| 
      
 14 
     | 
    
         
            +
            end
         
     | 
    
        metadata
    ADDED
    
    | 
         @@ -0,0 +1,55 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            --- !ruby/object:Gem::Specification
         
     | 
| 
      
 2 
     | 
    
         
            +
            name: squib_plus
         
     | 
| 
      
 3 
     | 
    
         
            +
            version: !ruby/object:Gem::Version
         
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.0.1
         
     | 
| 
      
 5 
     | 
    
         
            +
            platform: ruby
         
     | 
| 
      
 6 
     | 
    
         
            +
            authors:
         
     | 
| 
      
 7 
     | 
    
         
            +
            - Rob Newton
         
     | 
| 
      
 8 
     | 
    
         
            +
            autorequire:
         
     | 
| 
      
 9 
     | 
    
         
            +
            bindir: bin
         
     | 
| 
      
 10 
     | 
    
         
            +
            cert_chain: []
         
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2021-11-05 00:00:00.000000000 Z
         
     | 
| 
      
 12 
     | 
    
         
            +
            dependencies: []
         
     | 
| 
      
 13 
     | 
    
         
            +
            description: Helper functions extending the functionality of Squib
         
     | 
| 
      
 14 
     | 
    
         
            +
            email: robert@coinflip.games
         
     | 
| 
      
 15 
     | 
    
         
            +
            executables: []
         
     | 
| 
      
 16 
     | 
    
         
            +
            extensions: []
         
     | 
| 
      
 17 
     | 
    
         
            +
            extra_rdoc_files: []
         
     | 
| 
      
 18 
     | 
    
         
            +
            files:
         
     | 
| 
      
 19 
     | 
    
         
            +
            - ".gitignore"
         
     | 
| 
      
 20 
     | 
    
         
            +
            - Gemfile
         
     | 
| 
      
 21 
     | 
    
         
            +
            - lib/squib_plus.rb
         
     | 
| 
      
 22 
     | 
    
         
            +
            - lib/squib_plus/card_size.rb
         
     | 
| 
      
 23 
     | 
    
         
            +
            - lib/squib_plus/deck.rb
         
     | 
| 
      
 24 
     | 
    
         
            +
            - lib/squib_plus/deck/avatar.rb
         
     | 
| 
      
 25 
     | 
    
         
            +
            - lib/squib_plus/google_sheets.rb
         
     | 
| 
      
 26 
     | 
    
         
            +
            - lib/squib_plus/pdf.rb
         
     | 
| 
      
 27 
     | 
    
         
            +
            - lib/squib_plus/sprues/letter_poker_tight.yml
         
     | 
| 
      
 28 
     | 
    
         
            +
            - lib/squib_plus/sprues/letter_poker_tight_reverse.yml
         
     | 
| 
      
 29 
     | 
    
         
            +
            - lib/squib_plus/string.rb
         
     | 
| 
      
 30 
     | 
    
         
            +
            - lib/squib_plus/subset.rb
         
     | 
| 
      
 31 
     | 
    
         
            +
            - squib_plus.gemspec
         
     | 
| 
      
 32 
     | 
    
         
            +
            homepage: https://rubygems.org/gems/squib_plus
         
     | 
| 
      
 33 
     | 
    
         
            +
            licenses:
         
     | 
| 
      
 34 
     | 
    
         
            +
            - MIT
         
     | 
| 
      
 35 
     | 
    
         
            +
            metadata: {}
         
     | 
| 
      
 36 
     | 
    
         
            +
            post_install_message:
         
     | 
| 
      
 37 
     | 
    
         
            +
            rdoc_options: []
         
     | 
| 
      
 38 
     | 
    
         
            +
            require_paths:
         
     | 
| 
      
 39 
     | 
    
         
            +
            - lib
         
     | 
| 
      
 40 
     | 
    
         
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         
     | 
| 
      
 41 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 42 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 43 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 44 
     | 
    
         
            +
                  version: '0'
         
     | 
| 
      
 45 
     | 
    
         
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         
     | 
| 
      
 46 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 47 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 48 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 49 
     | 
    
         
            +
                  version: '0'
         
     | 
| 
      
 50 
     | 
    
         
            +
            requirements: []
         
     | 
| 
      
 51 
     | 
    
         
            +
            rubygems_version: 3.2.22
         
     | 
| 
      
 52 
     | 
    
         
            +
            signing_key:
         
     | 
| 
      
 53 
     | 
    
         
            +
            specification_version: 4
         
     | 
| 
      
 54 
     | 
    
         
            +
            summary: Extensions for Squib
         
     | 
| 
      
 55 
     | 
    
         
            +
            test_files: []
         
     |