Module: LTSV

Defined in:
lib/ltsv.rb

Overview

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

Copyright (C) 2013 TOYODA Naoto.

Constant Summary collapse

VERSION =
"0.0.1"

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:


124
125
126
127
128
129
130
131
132
133
# File 'lib/ltsv.rb', line 124

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

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

  value
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)}
  when IO
    parse_io(io)
  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 = {})
  end
end

.parse_io(io, options) ⇒ Object

:nodoc:


88
89
90
# File 'lib/ltsv.rb', line 88

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

.parse_string(string, options) ⇒ Object

:nodoc:


92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/ltsv.rb', line 92

def parse_string(string, options)#:nodoc:
  symbolize_keys = options.delete(:symbolize_keys)
  symbolize_keys = true if symbolize_keys.nil?

  string.split("\t").inject({}) do |h, i|
    (key, value) = i.split(':', 2)
    key = key.to_sym if symbolize_keys
    unescape!(value)
    h[key] = value.empty? ? nil : value
    h
  end
end

.unescape!(string) ⇒ Object

:nodoc:


105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/ltsv.rb', line 105

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