module TrickBag::Formatters

Public Instance Methods

array_diff(array1, array2, format = :text) click to toggle source

Shows a visual diff of 2 arrays by comparing the string representations of the arrays with one element per line. @param format can be any valid Diffy option, e.g. :color

see https://github.com/samg/diffy/blob/master/lib/diffy/format.rb
# File lib/trick_bag/formatters/formatters.rb, line 136
def array_diff(array1, array2, format = :text)
  string1 = array1.join("\n") + "\n"
  string2 = array2.join("\n") + "\n"
  Diffy::Diff.new(string1, string2).to_s(format)
end
dos2unix(string, strategy = :remove_all_cr) click to toggle source

Like the Unix dos2unix command, but on strings rather than files, strips CR (“r”, 13, 0xD) characters.

WARNING:

Currently, two strategies are supported, but they do not account for character sets that might include characters that have “r”'s numeric value, 13, or 0xd, as part of their legitimate values, so we may need to add strategies to accommodate this.

An example of a more complex implementation is at: dos2unix.sourcearchive.com/documentation/5.0-1/dos2unix_8c-source.html.

Note: The 'os' gem can be used to determine os.

@param string the string to convert @param strategy the strategy to use for the conversion (note: the default

may change over time, so if you're sure you want to use the current
default even if the default changes, don't rely on the default; specify it)
# File lib/trick_bag/formatters/formatters.rb, line 108
def dos2unix(string, strategy = :remove_all_cr)
  strategies = {
      remove_all_cr:     -> { string.gsub("\r", '') },
      remove_cr_in_crlf: -> { string.gsub("\r\n", "\n") }
  }

  unless strategies.keys.include?(strategy)
    message = "Unsupported strategy: #{strategy}. Must be one of [#{strategies.keys.sort.join(', ')}]."
    raise ArgumentError.new(message)
  end

  strategies[strategy].()
end
dos2unix!(string, strategy = :remove_all_cr) click to toggle source

Like the Unix dos2unix command, but on strings rather than files, strips CR characters. Modifies the original string. See warning in dos2unix header. Note: The 'os' gem can be used to determine os.

# File lib/trick_bag/formatters/formatters.rb, line 127
def dos2unix!(string, strategy = :remove_all_cr)
  string.replace(dos2unix(string, strategy))
end
duration_to_s(seconds) click to toggle source

Formats a number of seconds as a succinct string, with days, hours, minutes, and seconds. Examples:

duration_to_s(1_000_000) => “11 d, 13 h, 46 m, 40 s” duration_to_s(1_000) => “16 m, 40 s” duration_to_s(-1_000) => “-16 m, 40 s” duration_to_s(1.234567) => “1.234567 s” duration_to_s(1000.234567) => “16 m, 40.23456699999997 s”

# File lib/trick_bag/formatters/formatters.rb, line 17
def duration_to_s(seconds)

  unless seconds.is_a?(::Numeric)
    raise ArgumentError.new("#{seconds} must be a number but is a #{seconds.class}.")
  end

  seconds_in_minute = 60
  seconds_in_hour = 60 * seconds_in_minute
  seconds_in_day = 24 *seconds_in_hour

  str = ''

  if seconds < 0
    str << '-'
    seconds = -seconds
  end

  fractional_second = seconds - Integer(seconds)
  seconds = Integer(seconds)

  days = seconds / seconds_in_day
  print_days = days > 0
  seconds %= seconds_in_day

  hours = seconds / seconds_in_hour
  print_hours = hours > 0 || days > 0
  seconds %= seconds_in_hour

  minutes = seconds / seconds_in_minute
  print_minutes = minutes > 0 || hours > 0 || days > 0
  seconds %= seconds_in_minute

  str << "#{days} d, "     if print_days
  str << "#{hours} h, "    if print_hours
  str << "#{minutes} m, "  if print_minutes
  str << "#{seconds + fractional_second} s"

  str
end
end_with_nl(object) click to toggle source

Reverse of String#chomp. Convert to string if not already a string. Append new line to string if the string is not empty and does not already end with one. This is to disable the Diffy warning message “No newline at end of file”

# File lib/trick_bag/formatters/formatters.rb, line 62
def end_with_nl(object)
  string = object.to_s
  needs_modifying = string.size > 0 && string[-1] != "\n"
  needs_modifying ? "#{string}\n" : string
end
replace_with_timestamp(string, marker = '{dt}', datetime = DateTime.now) click to toggle source

Replaces all occurrences of marker with the current date/time in YYYYMMDD-HHMMSS format.

Useful for creating filespecs with static content that will differ by date, for example:

replace_with_timestamp('my-app-result-{dt}.txt') => “my-app-result-2014-03-24_15-25-57.txt”

# File lib/trick_bag/formatters/formatters.rb, line 84
def replace_with_timestamp(string, marker = '{dt}', datetime = DateTime.now)
  string.gsub(marker, timestamp(datetime))
end
string_to_verbose_char_list(a_string) click to toggle source

Outputs bytes verbosely one on a line for examination. The characters printed are 1 byte in length, so multibyte characters will not be output correctly. Output will look like:

Index Decimal Hex Binary Character —– ——- — —— ———

0          97         61 x          110 0001 b       a
1          49         31 x           11 0001 b       1
2          46         2e x           10 1110 b       .
# File lib/trick_bag/formatters/formatters.rb, line 153
def string_to_verbose_char_list(a_string)

  header = [
      'Index     Decimal        Hex              Binary    Character',
      '-----     -------        ---              ------    ---------',
      ''  # 3rd string is just to force a 3rd \n when joined
  ].join("\n")

  sio = StringIO.new
  sio << header

  if a_string.empty?
    sio << '(String is empty)'
  else
    format = '%5d         %3d       %+6s    %+16s       %c'
    a_string.bytes.each_with_index do |byte, index|
      hex_str = "#{byte.to_s(16)} x"

      base2_str = "#{byte.to_s(2)} b"
      if base2_str.size > 6
        base2_str.insert(base2_str.size - 6, ' ')
      end

      sio << format % [index, byte, hex_str, base2_str,  byte.chr] << "\n"
    end
  end
  sio.string
end
thousands_separated(number, separator = ',') click to toggle source

Returns a string representation of the Integer corresponding to the input parameter, with a customizable thousands separator. Does not (yet) support fractional values or decimal places.

# File lib/trick_bag/formatters/formatters.rb, line 186
def thousands_separated(number, separator = ',')
  number = Integer(number)
  triplets = []
  source_chars = number.to_s.reverse.chars
  source_chars.each_slice(3) do |slice|
    triplets << slice.join
  end
  triplets.join(separator).reverse
end
timestamp(datetime = DateTime.now) click to toggle source

Returns a timestamp string suitable for use in filespecs, whose string sort order will be the same as a chronological sort would be. @param datetime the date to format, defaults to DateTime.now

# File lib/trick_bag/formatters/formatters.rb, line 72
def timestamp(datetime = DateTime.now)
  datetime.strftime('%Y-%m-%d_%H-%M-%S')
end