module DocumentsWithFooterToPdf

Constants

VERSION

Public Class Methods

generate( folder, silent, options={} ) click to toggle source
# File lib/documents_with_footer_to_pdf.rb, line 144
def self.generate( folder, silent, options={} )
  
  hash = Marshal.load( Marshal.dump( self.get_options() ) )
  if self.validate_generate( folder, silent, options, hash )
          
    hash[:path][:root] = folder
    hash[:params][:console][:silent] = silent == :silent ? true : false
    hash[:params][:console][:mode] = !hash[:params][:console][:silent] ? silent : ''
    hash[:path] = LocalPathBuilder.generate( hash[:path], :silent, Time.now.to_i.to_s )
    hash = self.options_update( options, hash, 'set_options' )  

    self.footer_image( hash )
    prepares = self.footer_prepare( hash )
    self.footer_generate( prepares, hash )
    self.footer_merge( hash )
    FileUtils.rm_rf( hash[:path][:children][:tmp][:full] )
  end
end
get_options() click to toggle source

Your code goes here…

# File lib/documents_with_footer_to_pdf.rb, line 14
def self.get_options()
  return {
    path: {
      root: nil,
      name: '',
      children: {
        tmp: {
          name: 'tmp-{{SALT}}',
          children: {
            jpg: {
              name: '0-jpg'
            },
              pdf_single: {
                name: '1-pdf-single--w-footer'
            }
          }
        },
        pdf_combined: {
          name: '0-result-{{SALT}}',
          files: {
            result: {
              name: '0-result-{{SALT}}.pdf'
            }
          }
        }
      }
    },
    footer: {
      position: {
        top: [ 0, 20 ],
        bottom: [ 0, 10 ]
      },
      table: {
        left: {
          top: {
            text: '<<--FILENAME-->>'
          },
          bottom: {
            text: ''
          }
        },
        center: {
          top: {
            text: ''
          },
          bottom: {
            text: ''
          }
        },
        right: {
          top: {
            text: '<<--TIMESTAMP-->>'
          },
          bottom: {
            text: '<<--PAGE_CURRENT-->> from <<--PAGE_TOTAL-->>'
          }
        }
      }
    },
    selectors: {
      timestamp: {
        gsub: '<<--TIMESTAMP-->>',
        key: :timestamp,
        strf: '%d.%m.%Y',
      },
      page_current: {
        gsub: '<<--PAGE_CURRENT-->>',
        key: :page__current
      },
      page_total: {
        gsub: '<<--PAGE_TOTAL-->>',
        key: :page__total
      },
      enumerator_original: {
        gsub: '<<--ENUMERATOR_ORIGINAL-->>',
        key: :enumerator__original
      },
      enumerator_integer: {
        gsub: '<<--ENUMERATOR_INTEGER-->>',
        key: :enumerator__integer
      },
      enumerator_char: {
        gsub: '<<--ENUMERATOR_CHAR-->>',
        key: :enumerator__char
      },
      enumerator_roman: {
        gsub: '<<--ENUMERATOR_ROMAN-->>',
        key: :enumerator__roman
      },
      filename: {
        gsub: '<<--FILENAME-->>',
        key: :filename
      },
      path: {
        gsub: '<<--PATH-->>',
        key: :path
      },
      heading: {
        gsub: '<<--HEADLINE-->>',
        key: :heading
      },
      subheading: {
        gsub: '<<--SUBHEADING-->>',
        key: :subheading
      }
    },
    params: {
      footer: {
        font_size: 9
      },
      document: {
        width: 500
      },
      image: {
        density: 300
      },
      search: {
        subfolders: false,
        suffixs: [ 'jpg', 'png', 'pdf' ]
      },
      console: {
        silent: nil,
        mode: nil,
        length: 50
      }
    }
  }
end

Private Class Methods

console_mode( file, index, obj ) click to toggle source
# File lib/documents_with_footer_to_pdf.rb, line 537
def self.console_mode( file, index, obj )
  if !self.debug( obj )
    case obj[:params][:console][:mode]
      when :short
        index%obj[:params][:console][:length] == 0 ? print( "\n\t" ) : ''
        print( '.' )
      when :detail
        puts ( "\t" )
        p = ''
        if file.length > obj[:params][:console][:length]
          _start = obj[:params][:console][:length] / 5
          _end = obj[:params][:console][:length] - _start
          p += file[ 0, _start ]
          p += '...'
          p += file[ file.length - _end, file.length]
        else
          p = file
        end
        print( "\t- #{p}" )
    end
  else
  end
end
create_selectors( str, item, alpha ) click to toggle source
# File lib/documents_with_footer_to_pdf.rb, line 383
def self.create_selectors( str, item, alpha )
  if str.index( '--' ) == 1
    item[:valid] = true
    a = str.split( '--' )
    item[:enumerator][:original] = a[ 0 ]
    case a.length
      when 2
        item[:heading] = a[ 1 ]
      when 3
        item[:heading] = a[ 1 ]
        item[:subheading] = a[ 2 ]
    end
  
    if /\A[-+]?[0-9]+\z/.match( item[:enumerator][:original] ).to_a.length != 0
      item[:enumerator][:style] = :integer
      item[:enumerator][:integer] = item[:enumerator][:original].to_i
      item[:enumerator][:char] = alpha[ item[:enumerator][:integer]-1 ]
      item[:enumerator][:roman] = self.roman_numerals( item[:enumerator][:integer] )
    else
      item[:enumerator][:style] = :char
      item[:enumerator][:char] = item[:enumerator][:original].upcase
      item[:enumerator][:integer] =alpha.index( item[:enumerator][:char] ) + 1
      item[:enumerator][:roman] = self.roman_numerals( alpha.index( item[:enumerator][:char] ) + 1 )
    end
  else
    item[:valid] = false
    item[:heading] = str
  end
  
  return item
end
debug( obj ) click to toggle source
# File lib/documents_with_footer_to_pdf.rb, line 167
def self.debug( obj )
  return obj[:params][:console][:silent]
end
next_lower_key( integer, values ) click to toggle source
# File lib/documents_with_footer_to_pdf.rb, line 348
def self.next_lower_key( integer, values )
  arabics = values.keys
  next_lower_index = ( arabics.push( integer ).sort.index( integer ) ) - 1
  arabics[next_lower_index]
end
options_update( vars, template, mode ) click to toggle source
# File lib/documents_with_footer_to_pdf.rb, line 172
def self.options_update( vars, template, mode )
  def self.str_difference( a, b )
    a = a.to_s.downcase.split( '_' ).join( '' )
    b = b.to_s.downcase.split( '_' ).join( '' )
    longer = [ a.size, b.size ].max
    same = a
      .each_char
      .zip( b.each_char )
      .select { | a, b | a == b }
      .size
    ( longer - same ) / a.size.to_f
  end


  allow_list = [
    :path__children__tmp__name,
    :path__children__pdf_combined__name,
    :footer__position__top,
    :footer__position__bottom,
    :footer__table__left__top__text,
    :footer__table__left__bottom__text,
    :footer__table__center__top__text,
    :footer__table__center__bottom__text,
    :footer__table__right__top__text,
    :footer__table__right__bottom__text,
    :selectors__timestamp__gsub,
    :selectors__timestamp__strf,
    :selectors__page_current__gsub,
    :selectors__page_total__gsub,
    :selectors__enumerator_original__gsub,
    :selectors__enumerator_integer__gsub,
    :selectors__enumerator_char__gsub,
    :selectors__enumerator_roman__gsub,
    :selectors__filename__gsub,
    :selectors__path__gsub,
    :selectors__heading__gsub,
    :selectors__subheading__gsub,
    :params__footer__font_size,
    :params__document__width,
    :params__image__density,
    :params__search__subfolders,
    :params__search__suffixs,
    :params__console__length
  ]

  messages = []
  _options = Marshal.load( Marshal.dump( template ) )
  
  vars.keys.each do | key |
    if allow_list.include?( key ) 

      keys = key.to_s.split( '__' ).map { | a | a.to_sym }
      case( keys.length )
        when 1
          _options[ keys[ 0 ] ] = vars[ key ]
        when 2
          _options[ keys[ 0 ] ][ keys[ 1 ] ] = vars[ key ]
        when 3
          _options[ keys[ 0 ] ][ keys[ 1 ] ][ keys[ 2 ] ] = vars[ key ]
        when 4
          _options[ keys[ 0 ] ][ keys[ 1 ] ][ keys[ 2 ] ][ keys[ 3 ] ] = vars[ key ]
        when 5
          _options[ keys[ 0 ] ][ keys[ 1 ] ][ keys[ 2 ] ][ keys[ 3 ] ][ keys[ 4 ] ] = vars[ key ]
        when 6
          _options[ keys[ 0 ] ][ keys[ 1 ] ][ keys[ 2 ] ][ keys[ 3 ] ][ keys[ 4 ] ][ keys[ 5   ] ] = vars[ key ]
      end
    else
      nearest = allow_list
        .map { | word | { score: self.str_difference( key, word ), word: word } }
        .min_by { | item | item[:score] }

      message = "\"#{key}\" is not a valid key, did you mean \"<--similar-->\"?"
      message = message.gsub( '<--similar-->', nearest[:word].to_s )
      messages.push( message )
    end
  end
  
  result = nil
  case mode
    when 'check_options'
      result = messages
    when 'set_options'
      result = _options
  end

  return result
end
roman_numerals( integer ) click to toggle source
# File lib/documents_with_footer_to_pdf.rb, line 347
def self.roman_numerals( integer )
  def self.next_lower_key( integer, values )
    arabics = values.keys
    next_lower_index = ( arabics.push( integer ).sort.index( integer ) ) - 1
    arabics[next_lower_index]
  end
  
  values = {
    1 => 'I',
    4 => 'IV',
    5 => 'V',
    9 => 'IX',
    10 => 'X',
    40 => 'XL',
    50 => 'L',
    90 => 'XC',
    100 => 'C',
    400 => 'CD',
    500 => 'D',
    900 => 'CM',
    1000 => 'M'
  }
  
  roman = ''
  while integer > 0
    if values[ integer ]
      roman += values[ integer ]
      return roman
    end

    roman += values[ self.next_lower_key( integer, values ) ]
    integer -= self.next_lower_key( integer, values )
  end
end
str_difference( a, b ) click to toggle source
# File lib/documents_with_footer_to_pdf.rb, line 173
def self.str_difference( a, b )
  a = a.to_s.downcase.split( '_' ).join( '' )
  b = b.to_s.downcase.split( '_' ).join( '' )
  longer = [ a.size, b.size ].max
  same = a
    .each_char
    .zip( b.each_char )
    .select { | a, b | a == b }
    .size
  ( longer - same ) / a.size.to_f
end
validate_generate( folder, silent, vars, template ) click to toggle source
# File lib/documents_with_footer_to_pdf.rb, line 261
def self.validate_generate( folder, silent, vars, template )
  messages = {
    folder: [],
    silent: [],
    options: [],
    other: []
 }

  if folder.class.to_s.eql?( 'String' )
    if File.directory?( folder )

    else
      messages[:folder].push( 'Is not a valid path or not exist.')
    end
  else
    messages[:folder].push( 'Is not Type "String"')
  end

  if silent.class.to_s.eql?( 'Symbol' )
    if [:silent, :short, :detail].include?( silent )

    else
      messages[:silent].push( 'Is not :silent, :short or :detail')
    end
  else
    messages[:silent].push( 'Is not Type "Symbol"')
  end

  if vars.class.to_s.eql?( 'Hash' )
    messages[:options] = self.options_update( vars, template, 'check_options' )
  else
    messages[:options].push( 'Is not Type "Hash".') 
  end

  valid = messages.keys.map { | key | messages[ key ].length }.sum == 0

  if !valid
    puts 'Following errors occured:'
    messages.keys.each do | key |
      if messages[ key ].length != 0
        puts "  #{key[ 0, 1 ].upcase}#{key[ 1, key.length ]}"
        messages[ key ].each do | m |
          puts "  - #{m}"
        end
      end
    end
  end
  return valid
end