Module: LTSV

Defined in:
lib/ltsv.rb

Overview

ltsv - A parser / dumper for Labelled Tab-Separated Values(LTSV)

Copyright © 2013 TOYODA Naoto.

Constant Summary collapse

VERSION =
"0.1.2"

Class Method Summary collapse

Class Method Details

.dump(value) ⇒ Object

Dumping the value given into a new String. Each special character will be escaped with backslash(‘'), and the expression should be contained in a single line.

Arguments:

  • value: a target to dump. It should respond to :to_hash.

Returns:

  • A LTSV String

Raises:

  • (ArgumentError)


71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/ltsv.rb', line 71

def dump(value)
  raise ArgumentError, "dump should take an argument of hash" unless
    value.respond_to? :to_hash

  hash = value.to_hash

  hash.inject('') do |s, kv|
    s << "\t" if s.bytesize > 0

    (k, v) = kv
    value = escape v
    s << k.to_s << ':' << value
  end
end

.escape(string) ⇒ Object

:nodoc:



133
134
135
136
137
138
139
140
141
# File 'lib/ltsv.rb', line 133

def escape(string)#:nodoc:
  value = string.kind_of?(String) ? string.dup : string.to_s

  value
    .gsub("\\", "\\\\")
    .gsub("\n", "\\n")
    .gsub("\r", "\\r")
    .gsub("\t", "\\t")
end

.load(io_or_string, options = {}) ⇒ Object

Parsing the content of the given stream or path. If you specified a stream as the first argument, this method behaves as same as #load.

Arguments:

  • io_or_string: a target to parse. Possible values are: String, IO.

    If you give the string value, it stands the path of the file to parse.

    If you give the IO value, it stands the stream which provides the contents to parse.

    Note : If you give the IO value, this method behaves like #parse.

Options:

  • symbolize_keys : Whether the label will be available as symbol or not.

    Default value is true.

  • encoding : The encoding of the stream given as the first argument.

    Default value: Encoding.default_external

Returns:

  • An Array of Hash : Each hash stands for a line of the io or the file.



51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/ltsv.rb', line 51

def load(io_or_string, options = {})
  encoding_opt = options.delete :encoding
  encoding =
    encoding_opt ? Encoding.find(encoding_opt) : Encoding.default_external

  case io_or_string
  when String
    File.open(io_or_string, "r:#{encoding}"){|f|parse_io(f, options)}
  when IO
    parse_io(io_or_string, options)
  end
end

.parse(io_or_string, options = {}) ⇒ Object

Parsing given stream or string. If you specified a stream as the first argument, this method behaves as same as #load.

Arguments:

  • io_or_string: a target to parse. Possible values are: String, IO.

    If you give the string value, it stands the content to parse.

    If you give the IO value, it stands the stream which provides the contents to parse.

Options:

  • symbolize_keys : Whether the label will be available as symbol or not.

    Default value is true.

  • encoding : The encoding of the stream given as the first argument.

    It is effective only when the first argument is an instance of IO.

    Default value: Encoding.default_external

Returns:

  • An instance of Hash : When you give the string as the first argument.

  • An Array of Hash : When you give the IO as the first argument.



26
27
28
29
30
31
32
33
# File 'lib/ltsv.rb', line 26

def parse(io_or_string, options = {})
  case io_or_string
  when String
    parse_string(io_or_string, options)
  when IO
    parse_io(io_or_string, options)
  end
end

.parse_io(io, options) ⇒ Object

:nodoc:



106
107
108
# File 'lib/ltsv.rb', line 106

def parse_io(io, options)#:nodoc:
  io.map{|l|parse_line l.chomp, options}
end

.parse_line(line, options = {}) ⇒ Object

:nodoc:



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/ltsv.rb', line 86

def parse_line(line, options={})#:nodoc:
  symbolize_keys = options.delete(:symbolize_keys)
  symbolize_keys = true if symbolize_keys.nil?

  line.split("\t").inject({}) do |h, i|
    (key, value) = i.split(':', 2)
    next unless key
    key = key.to_sym if symbolize_keys
    unescape!(value)
    h[key] = case value
         when nil then nil
         when '' then nil
         else value
         end
    h
  end
end

.parse_string(string, options) ⇒ Object

:nodoc:



110
111
112
# File 'lib/ltsv.rb', line 110

def parse_string(string, options)#:nodoc:
  string.chomp.split($/).map{|l|parse_line l, options}
end

.unescape!(string) ⇒ Object

:nodoc:



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/ltsv.rb', line 114

def unescape!(string)#:nodoc:
  return nil if !string || string == ''

  string.gsub!(/\\([a-z\\])/) do |m|
    case $1
    when 'r'
      "\r"
    when 'n'
      "\n"
    when 't'
      "\t"
    when '\\'
      '\\'
    else
      m
    end
  end
end