iniparse 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +19 -0
- data/README.rdoc +75 -0
- data/Rakefile +102 -0
- data/lib/iniparse.rb +68 -0
- data/lib/iniparse/document.rb +62 -0
- data/lib/iniparse/generator.rb +200 -0
- data/lib/iniparse/line_collection.rb +164 -0
- data/lib/iniparse/lines.rb +290 -0
- data/lib/iniparse/parser.rb +92 -0
- data/lib/iniparse/version.rb +3 -0
- data/spec/document_spec.rb +72 -0
- data/spec/fixture_spec.rb +166 -0
- data/spec/fixtures/openttd.ini +397 -0
- data/spec/fixtures/race07.ini +133 -0
- data/spec/fixtures/smb.ini +102 -0
- data/spec/generator/method_missing_spec.rb +104 -0
- data/spec/generator/with_section_blocks_spec.rb +322 -0
- data/spec/generator/without_section_blocks_spec.rb +136 -0
- data/spec/iniparse_spec.rb +21 -0
- data/spec/line_collection_spec.rb +212 -0
- data/spec/lines_spec.rb +409 -0
- data/spec/parser/document_parsing_spec.rb +50 -0
- data/spec/parser/line_parsing_spec.rb +367 -0
- data/spec/spec_fixtures.rb +46 -0
- data/spec/spec_helper.rb +164 -0
- data/spec/spec_helper_spec.rb +201 -0
- metadata +92 -0
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2008-2009 Anthony Williams
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
11
|
+
copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
|
+
SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
= IniParse
|
2
|
+
|
3
|
+
IniParse is a pure Ruby library for parsing
|
4
|
+
INI[http://en.wikipedia.org/wiki/INI_file] configuration and data
|
5
|
+
files.
|
6
|
+
|
7
|
+
This rubygem is in ongoing development and - specs aside - hasn't yet been
|
8
|
+
properly tested in a production environment. If you think you've found a bug,
|
9
|
+
or you feed it an INI file which doesn't work as you'd expected, please mail
|
10
|
+
me at +anthony at ninecraft dot com+, ideally with a copy of the INI file in
|
11
|
+
question.
|
12
|
+
|
13
|
+
=== Main features
|
14
|
+
|
15
|
+
* <b>Support for duplicate options.</b> While not common, some INI files
|
16
|
+
contain an option more than once. IniParse does not overwrite previous
|
17
|
+
options, but allows you to access all of the duplicate values.
|
18
|
+
|
19
|
+
* <b>Preservation of white space and blank lines.</b> When writing back to
|
20
|
+
your INI file, line indents, white space and comments (and their indents)
|
21
|
+
are preserved. Only trailing white space (which has no significance in INI
|
22
|
+
files) will be removed.
|
23
|
+
|
24
|
+
* <b>Preservation of section and option ordering.</b> Sections and options
|
25
|
+
are kept in the same order they are in the original document ensuring that
|
26
|
+
nothing gets mangled when writing back to the file.
|
27
|
+
|
28
|
+
If you don't need the above mentioned features, you may find the simpler
|
29
|
+
IniFile gem does all you need.
|
30
|
+
|
31
|
+
=== Opening an INI file
|
32
|
+
|
33
|
+
Parsing an INI file is fairly simple:
|
34
|
+
|
35
|
+
IniParse.parse( File.open('path/to/my/file.ini') ) # => IniParse::Document
|
36
|
+
|
37
|
+
IniParse.parse returns an IniParse::Document instance which represents the
|
38
|
+
passed "INI string". Assuming you know the structure of the document, you can
|
39
|
+
access the sections in the INI document with IniParse::Document#[]. For
|
40
|
+
example:
|
41
|
+
|
42
|
+
document = IniParse.parse( File.read('path/to/my/file.ini') )
|
43
|
+
|
44
|
+
document['a_section']
|
45
|
+
# => IniParse::Lines::Section
|
46
|
+
|
47
|
+
document['a_section']['an_option']
|
48
|
+
# => "a value"
|
49
|
+
document['a_section']['another_option']
|
50
|
+
# => "another value"
|
51
|
+
|
52
|
+
In the event that duplicate options were found, an array of the values will
|
53
|
+
be supplied to you.
|
54
|
+
|
55
|
+
document = IniParse.parse <<-EOS
|
56
|
+
[my_section]
|
57
|
+
key = value
|
58
|
+
key = another value
|
59
|
+
key = a third value
|
60
|
+
EOS
|
61
|
+
|
62
|
+
document['my_section']['key']
|
63
|
+
# => ['value', 'another value', 'third value']
|
64
|
+
|
65
|
+
=== Updating an INI file
|
66
|
+
|
67
|
+
document['a_section']['an_option']
|
68
|
+
# => "a value"
|
69
|
+
document['a_section']['an_option'] = 'a new value'
|
70
|
+
document['a_section']['an_option']
|
71
|
+
# => "a new value"
|
72
|
+
|
73
|
+
=== Creating a new INI file
|
74
|
+
|
75
|
+
See IniParse::Generator.
|
data/Rakefile
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake/clean'
|
3
|
+
require 'rake/gempackagetask'
|
4
|
+
require 'rubygems/specification'
|
5
|
+
require 'date'
|
6
|
+
require 'spec/rake/spectask'
|
7
|
+
|
8
|
+
begin
|
9
|
+
require 'hanna/rdoctask'
|
10
|
+
rescue LoadError
|
11
|
+
require 'rake/rdoctask'
|
12
|
+
end
|
13
|
+
|
14
|
+
require 'lib/iniparse/version'
|
15
|
+
|
16
|
+
GEM = 'iniparse'
|
17
|
+
GEM_VERSION = IniParse::VERSION
|
18
|
+
|
19
|
+
##############################################################################
|
20
|
+
# Packaging & Installation
|
21
|
+
##############################################################################
|
22
|
+
|
23
|
+
CLEAN.include ['pkg', '*.gem', 'doc', 'coverage']
|
24
|
+
|
25
|
+
spec = Gem::Specification.new do |s|
|
26
|
+
s.name = GEM
|
27
|
+
s.version = GEM_VERSION
|
28
|
+
s.platform = Gem::Platform::RUBY
|
29
|
+
s.summary = "A pure Ruby library for parsing INI documents."
|
30
|
+
s.description = s.summary
|
31
|
+
s.author = 'Anthony Williams'
|
32
|
+
s.email = 'anthony@ninecraft.com'
|
33
|
+
s.homepage = 'http://github.com/anthonyw/iniparse'
|
34
|
+
|
35
|
+
# rdoc
|
36
|
+
s.has_rdoc = true
|
37
|
+
s.extra_rdoc_files = %w(README.rdoc LICENSE)
|
38
|
+
|
39
|
+
# Dependencies
|
40
|
+
s.add_dependency 'extlib', '>= 0.9.9'
|
41
|
+
|
42
|
+
s.require_path = 'lib'
|
43
|
+
s.files = %w(LICENSE README.rdoc Rakefile) + Dir.glob("{lib,spec}/**/*")
|
44
|
+
|
45
|
+
s.rubyforge_project = 'iniparse'
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
50
|
+
pkg.gem_spec = spec
|
51
|
+
end
|
52
|
+
|
53
|
+
desc "Run :package and install the resulting .gem"
|
54
|
+
task :install => :package do
|
55
|
+
sh %(gem install --local pkg/#{GEM}-#{GEM_VERSION}.gem)
|
56
|
+
end
|
57
|
+
|
58
|
+
desc "Run :clean and uninstall the .gem"
|
59
|
+
task :uninstall => :clean do
|
60
|
+
sh %(gem uninstall #{GEM})
|
61
|
+
end
|
62
|
+
|
63
|
+
desc "Create a gemspec file"
|
64
|
+
task :make_spec do
|
65
|
+
File.open("#{GEM}.gemspec", "w") do |file|
|
66
|
+
file.puts spec.to_ruby
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
##############################################################################
|
71
|
+
# Documentation
|
72
|
+
##############################################################################
|
73
|
+
task :doc => ['doc:rdoc']
|
74
|
+
namespace :doc do
|
75
|
+
|
76
|
+
Rake::RDocTask.new do |rdoc|
|
77
|
+
rdoc.rdoc_files.add(%w(LICENSE README.rdoc lib/**/*.rb))
|
78
|
+
rdoc.main = "README.rdoc"
|
79
|
+
rdoc.title = "IniParse API Documentation"
|
80
|
+
rdoc.options << "--line-numbers" << "--inline-source"
|
81
|
+
rdoc.rdoc_dir = 'doc'
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
##############################################################################
|
87
|
+
# rSpec & rcov
|
88
|
+
##############################################################################
|
89
|
+
|
90
|
+
desc "Run all examples"
|
91
|
+
Spec::Rake::SpecTask.new('spec') do |t|
|
92
|
+
t.spec_files = FileList['spec/**/*.rb']
|
93
|
+
t.spec_opts = ['-c -f s']
|
94
|
+
end
|
95
|
+
|
96
|
+
desc "Run all examples with RCov"
|
97
|
+
Spec::Rake::SpecTask.new('spec:rcov') do |t|
|
98
|
+
t.spec_files = FileList['spec/**/*.rb']
|
99
|
+
t.spec_opts = ['-c -f s']
|
100
|
+
t.rcov = true
|
101
|
+
t.rcov_opts = ['--exclude', 'spec']
|
102
|
+
end
|
data/lib/iniparse.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'extlib'
|
3
|
+
|
4
|
+
dir = Pathname(__FILE__).dirname.expand_path / 'iniparse'
|
5
|
+
|
6
|
+
require dir / 'document'
|
7
|
+
require dir / 'generator'
|
8
|
+
require dir / 'line_collection'
|
9
|
+
require dir / 'lines'
|
10
|
+
require dir / 'parser'
|
11
|
+
require dir / 'version'
|
12
|
+
|
13
|
+
module IniParse
|
14
|
+
# A base class for IniParse errors.
|
15
|
+
class IniParseError < StandardError; end
|
16
|
+
|
17
|
+
# Raised if an error occurs parsing an INI document.
|
18
|
+
class ParseError < IniParseError; end
|
19
|
+
|
20
|
+
# Raised when an option line is found during parsing before the first
|
21
|
+
# section.
|
22
|
+
class NoSectionError < ParseError; end
|
23
|
+
|
24
|
+
# Raised when a line is added to a collection which isn't allowed (e.g.
|
25
|
+
# adding a Section line into an OptionCollection).
|
26
|
+
class LineNotAllowed < IniParseError; end
|
27
|
+
|
28
|
+
module_function
|
29
|
+
|
30
|
+
# Parse given given INI document source +source+.
|
31
|
+
#
|
32
|
+
# See IniParse::Parser.parse
|
33
|
+
#
|
34
|
+
# ==== Parameters
|
35
|
+
# source<String>:: The source from the INI document.
|
36
|
+
#
|
37
|
+
# ==== Returns
|
38
|
+
# IniParse::Document
|
39
|
+
#
|
40
|
+
def parse(source)
|
41
|
+
IniParse::Parser.new(source).parse
|
42
|
+
end
|
43
|
+
|
44
|
+
# Opens the file at +path+, reads and parses it's contents.
|
45
|
+
#
|
46
|
+
# ==== Parameters
|
47
|
+
# path<String>:: The path to the INI document.
|
48
|
+
#
|
49
|
+
# ==== Returns
|
50
|
+
# IniParse::Document
|
51
|
+
#
|
52
|
+
def open(path)
|
53
|
+
document = IniParse::Parser.new(File.read(path)).parse
|
54
|
+
document.path = path
|
55
|
+
document
|
56
|
+
end
|
57
|
+
|
58
|
+
# Creates a new IniParse::Document using the specification you provide.
|
59
|
+
#
|
60
|
+
# See IniParse::Generator.
|
61
|
+
#
|
62
|
+
# ==== Returns
|
63
|
+
# IniParse::Document
|
64
|
+
#
|
65
|
+
def gen(&blk)
|
66
|
+
IniParse::Generator.new.gen(&blk)
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module IniParse
|
2
|
+
# Represents an INI document.
|
3
|
+
class Document
|
4
|
+
attr_reader :lines
|
5
|
+
attr_accessor :path
|
6
|
+
|
7
|
+
# Creates a new Document instance.
|
8
|
+
def initialize(path = nil)
|
9
|
+
@path = path
|
10
|
+
@lines = IniParse::SectionCollection.new
|
11
|
+
end
|
12
|
+
|
13
|
+
# Enumerates through each Section in this document.
|
14
|
+
#
|
15
|
+
# Does not yield blank and comment lines by default; if you want _all_
|
16
|
+
# lines to be yielded, pass true.
|
17
|
+
#
|
18
|
+
# ==== Parameters
|
19
|
+
# include_blank<Boolean>:: Include blank/comment lines?
|
20
|
+
#
|
21
|
+
def each(*args, &blk)
|
22
|
+
@lines.each(*args, &blk)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Returns the section identified by +key+.
|
26
|
+
#
|
27
|
+
# Returns nil if there is no Section with the given key.
|
28
|
+
#
|
29
|
+
def [](key)
|
30
|
+
@lines[key.to_s]
|
31
|
+
end
|
32
|
+
|
33
|
+
# Returns this document as a string suitable for saving to a file.
|
34
|
+
def to_ini
|
35
|
+
@lines.to_a.map { |line| line.to_ini }.join($/)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Returns true if a section with the given +key+ exists in this document.
|
39
|
+
def has_section?(key)
|
40
|
+
@lines.has_key?(key.to_s)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Saves a copy of this Document to disk.
|
44
|
+
#
|
45
|
+
# If a path was supplied when the Document was initialized then nothing
|
46
|
+
# needs to be given to Document#save. If Document was not given a file
|
47
|
+
# path, or you wish to save the document elsewhere, supply a path when
|
48
|
+
# calling Document#save.
|
49
|
+
#
|
50
|
+
# ==== Parameters
|
51
|
+
# path<String>:: A path to which this document will be saved.
|
52
|
+
#
|
53
|
+
# ==== Raises
|
54
|
+
# IniParseError:: If your document couldn't be saved.
|
55
|
+
#
|
56
|
+
def save(path = nil)
|
57
|
+
@path = path if path
|
58
|
+
raise IniParseError, 'No path given to Document#save' if @path.blank?
|
59
|
+
File.open(@path, 'w') { |f| f.write(self.to_ini) }
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,200 @@
|
|
1
|
+
module IniParse
|
2
|
+
# Generator provides a means for easily creating new INI documents.
|
3
|
+
#
|
4
|
+
# Rather than trying to hack together new INI documents by manually creating
|
5
|
+
# Document, Section and Option instances, it is preferable to use Generator
|
6
|
+
# which will handle it all for you.
|
7
|
+
#
|
8
|
+
# The Generator is exposed through IniParse.gen.
|
9
|
+
#
|
10
|
+
# IniParse.gen do |doc|
|
11
|
+
# doc.section("vehicle") do |vehicle|
|
12
|
+
# vehicle.option("road_side", "left")
|
13
|
+
# vehicle.option("realistic_acceleration", true)
|
14
|
+
# vehicle.option("max_trains", 500)
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# doc.section("construction") do |construction|
|
18
|
+
# construction.option("build_on_slopes", true)
|
19
|
+
# construction.option("autoslope", true)
|
20
|
+
# end
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# # => IniParse::Document
|
24
|
+
#
|
25
|
+
# This can be simplified further if you don't mind the small overhead
|
26
|
+
# which comes with +method_missing+:
|
27
|
+
#
|
28
|
+
# IniParse.gen do |doc|
|
29
|
+
# doc.vehicle do |vehicle|
|
30
|
+
# vehicle.road_side = "left"
|
31
|
+
# vehicle.realistic_acceleration = true
|
32
|
+
# vehicle.max_trains = 500
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# doc.construction do |construction|
|
36
|
+
# construction.build_on_slopes = true
|
37
|
+
# construction.autoslope = true
|
38
|
+
# end
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# # => IniParse::Document
|
42
|
+
#
|
43
|
+
# If you want to add slightly more complicated formatting to your document,
|
44
|
+
# each line type (except blanks) takes a number of optional parameters:
|
45
|
+
#
|
46
|
+
# :comment::
|
47
|
+
# Adds an inline comment at the end of the line.
|
48
|
+
# :comment_offset::
|
49
|
+
# Indent the comment. Measured in characters from _beginning_ of the line.
|
50
|
+
# See String#ljust.
|
51
|
+
# :indent::
|
52
|
+
# Adds the supplied text to the beginning of the line.
|
53
|
+
#
|
54
|
+
# If you supply +:indent+, +:comment_sep+, or +:comment_offset+ options when
|
55
|
+
# adding a section, the same options will be inherited by all of the options
|
56
|
+
# which belong to it.
|
57
|
+
#
|
58
|
+
# IniParse.gen do |doc|
|
59
|
+
# doc.section("vehicle",
|
60
|
+
# :comment => "Options for vehicles", :indent => " "
|
61
|
+
# ) do |vehicle|
|
62
|
+
# vehicle.option("road_side", "left")
|
63
|
+
# vehicle.option("realistic_acceleration", true)
|
64
|
+
# vehicle.option("max_trains", 500, :comment => "More = slower")
|
65
|
+
# end
|
66
|
+
# end.to_ini
|
67
|
+
#
|
68
|
+
# [vehicle] ; Options for vehicles
|
69
|
+
# road_side = left
|
70
|
+
# realistic_acceleration = true
|
71
|
+
# max_trains = 500 ; More = slower
|
72
|
+
#
|
73
|
+
class Generator
|
74
|
+
attr_reader :context
|
75
|
+
attr_reader :document
|
76
|
+
|
77
|
+
def initialize(opts = {}) # :nodoc:
|
78
|
+
@document = IniParse::Document.new
|
79
|
+
@context = @document
|
80
|
+
|
81
|
+
@in_section = false
|
82
|
+
@opt_stack = [opts]
|
83
|
+
end
|
84
|
+
|
85
|
+
def gen # :nodoc:
|
86
|
+
yield self
|
87
|
+
@document
|
88
|
+
end
|
89
|
+
|
90
|
+
# Creates a new IniParse::Document with the given sections and options.
|
91
|
+
#
|
92
|
+
# ==== Returns
|
93
|
+
# IniParse::Document
|
94
|
+
#
|
95
|
+
def self.gen(opts = {}, &blk)
|
96
|
+
new(opts).gen(&blk)
|
97
|
+
end
|
98
|
+
|
99
|
+
# Creates a new section with the given name and adds it to the document.
|
100
|
+
#
|
101
|
+
# You can optionally supply a block (as detailed in the documentation for
|
102
|
+
# Generator#gen) in order to add options to the section.
|
103
|
+
#
|
104
|
+
# ==== Parameters
|
105
|
+
# name<String>:: A name for the given section.
|
106
|
+
#
|
107
|
+
def section(name, opts = {})
|
108
|
+
if @in_section
|
109
|
+
# Nesting sections is bad, mmmkay?
|
110
|
+
raise LineNotAllowed, "You can't nest sections in INI files."
|
111
|
+
end
|
112
|
+
|
113
|
+
@context = Lines::Section.new(name, line_options(opts))
|
114
|
+
@document.lines << @context
|
115
|
+
|
116
|
+
if block_given?
|
117
|
+
begin
|
118
|
+
@in_section = true
|
119
|
+
with_options(opts) { yield self }
|
120
|
+
@context = @document
|
121
|
+
blank()
|
122
|
+
ensure
|
123
|
+
@in_section = false
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
# Adds a new option to the current section.
|
129
|
+
#
|
130
|
+
# Can only be called as part of a section block, or after at least one
|
131
|
+
# section has been added to the document.
|
132
|
+
#
|
133
|
+
# ==== Parameters
|
134
|
+
# key<String>:: The key (name) for this option.
|
135
|
+
# value:: The option's value.
|
136
|
+
# opts<Hash>:: Extra options for the line (formatting, etc).
|
137
|
+
#
|
138
|
+
# ==== Raises
|
139
|
+
# IniParse::NoSectionError::
|
140
|
+
# If no section has been added to the document yet.
|
141
|
+
#
|
142
|
+
def option(key, value, opts = {})
|
143
|
+
@context.lines << Lines::Option.new(
|
144
|
+
key, value, line_options(opts)
|
145
|
+
)
|
146
|
+
rescue LineNotAllowed
|
147
|
+
# Tried to add an Option to a Document.
|
148
|
+
raise NoSectionError, <<-EOS.compress_lines
|
149
|
+
Your INI document contains an option before the first section is
|
150
|
+
declared which is not allowed.
|
151
|
+
EOS
|
152
|
+
end
|
153
|
+
|
154
|
+
# Adds a new comment line to the document.
|
155
|
+
#
|
156
|
+
# ==== Parameters
|
157
|
+
# comment<String>:: The text for the comment line.
|
158
|
+
#
|
159
|
+
def comment(comment, opts = {})
|
160
|
+
@context.lines << Lines::Comment.new(
|
161
|
+
line_options(opts.merge(:comment => comment))
|
162
|
+
)
|
163
|
+
end
|
164
|
+
|
165
|
+
# Adds a new blank line to the document.
|
166
|
+
def blank
|
167
|
+
@context.lines << Lines::Blank.new
|
168
|
+
end
|
169
|
+
|
170
|
+
# Wraps lines, setting default options for each.
|
171
|
+
def with_options(opts = {}) # :nodoc:
|
172
|
+
opts = opts.dup
|
173
|
+
opts.delete(:comment)
|
174
|
+
@opt_stack.push( @opt_stack.last.merge(opts))
|
175
|
+
yield self
|
176
|
+
@opt_stack.pop
|
177
|
+
end
|
178
|
+
|
179
|
+
def method_missing(name, *args, &blk) # :nodoc:
|
180
|
+
if m = name.to_s.match(/(.*)=$/)
|
181
|
+
option(m[1], *args)
|
182
|
+
else
|
183
|
+
section(name.to_s, *args, &blk)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
#######
|
188
|
+
private
|
189
|
+
#######
|
190
|
+
|
191
|
+
# Returns options for a line.
|
192
|
+
#
|
193
|
+
# If the context is a section, we use the section options as a base,
|
194
|
+
# rather than the global defaults.
|
195
|
+
#
|
196
|
+
def line_options(given_opts) # :nodoc:
|
197
|
+
@opt_stack.last.empty? ? given_opts : @opt_stack.last.merge(given_opts)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|