Skip to content

A simple, clean DSL for describing, writing, and parsing fixed-width text files.

License

Notifications You must be signed in to change notification settings

ryanwood/slither

Repository files navigation

Slither

by Ryan Wood http://ryanwood.com

Documentation: https://www.rubydoc.info/gems/slither

Description:

A simple, clean DSL for describing, writing, and parsing fixed-width text files.

Features:

  • Easy DSL syntax
  • Can parse and format fixed width files
  • Templated sections for reuse
  • Helpful error messages for invalid data

Synopsis:

Create a Slither::Defintion to describe a file format

  Slither.define :simple, :by_bytes => false do |d|

    # This is a template section that can be reused in other sections
    d.template :boundary do |t|
      t.column :record_type, 4
      t.column :company_id, 12
    end

    # Create a header section
    #   alternatively, you can define the section on the fly by using metaprogramming
    #   ex: d.header(:align => :left) { |header| ... }
    d.section(:header, :align => :left) do |header|
      # The trap tells Slither which lines should fall into this section
      header.trap { |line| line[0,4] == 'HEAD' }
      # Use the boundary template for the columns
      header.template :boundary
    end

    d.section(:body) do |body|
      body.trap { |line| line[0,4] =~ /[^(HEAD|FOOT)]/ }
      body.column :id, 10, :type => :integer
      body.column :name, 10, :align => :left
      body.spacer 3
      body.column :state, 2
    end

    d.section(:footer) do |footer|
      footer.trap { |line| line[0,4] == 'FOOT' }
      footer.template :boundary
      footer.column :record_count, 10
    end
  end

Supported types are: string, integer, date, float, money, and money_with_implied_decimal.

Use :by_bytes => true (default) to allow newlines within rows and specify length in bytes. Use :by_bytes => false to support sections of different lengths and length specification in number of characters.

Then either feed it a nested struct with data values to create the file in the defined format:

  test_data = {
    :body => [
      { :id => 12, :name => "Ryan", :state => 'SC' },
      { :id => 23, :name => "Joe", :state => 'VA' },
      { :id => 42, :name => "Tommy", :state => 'FL' },
    ],
    :header => { :record_type => 'HEAD', :company_id => 'ABC'  },
    :footer => { :record_type => 'FOOT', :company_id => 'ABC'  }
  }

  # Generates the file as a string
  puts Slither.generate(:simple, test_data)
  # =>
  #   HEAD         ABC
  #         12Ryan         SC
  #         23Joe          VA
  #         42Tommy        FL
  # FOOT         ABC

  # Writes the file
  Slither.write(output_filename, :simple, test_data)

or parse files already in that format into a nested hash:

   parsed_data = Slither.parse(input_filename, :simple)
   parsed_data = Slither.parseIo(io_object, :simple)

The gem is available as open source under the terms of the MIT License.

Code of Conduct

Everyone interacting in the Slither project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.

About

A simple, clean DSL for describing, writing, and parsing fixed-width text files.

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages

No packages published