Skip to content

Commit

Permalink
Add getter and setter for the indent value of Ox::Builder (#296)
Browse files Browse the repository at this point in the history
* Add Ox::Builder#indent

This getter return the indent option of the builder.

* Add Ox::Builder#indent=

With this setter the indentation level can be changes dynamically. It
allows to build XML where some of the nodes are formatted inline within
the parent node.
This is useful for nodes that consider all spacing and line-breaking as
part of the value of the node's text.
  • Loading branch information
trekdemo authored Jun 30, 2022
1 parent d21afa3 commit 9b54734
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 0 deletions.
31 changes: 31 additions & 0 deletions ext/ox/builder.c
Original file line number Diff line number Diff line change
Expand Up @@ -881,6 +881,35 @@ builder_column(VALUE self) {
return LONG2NUM(((Builder)DATA_PTR(self))->col);
}

/* call-seq: indent()
*
* Returns the indentation level
*/
static VALUE
builder_get_indent(VALUE self) {
return INT2NUM(((Builder)DATA_PTR(self))->indent);
}

/* call-seq: indent=(indent)
*
* Sets the indentation level
*
* - +indent+ (Fixnum) indentaion level, negative values excludes terminating newline
*/
static VALUE
builder_set_indent(VALUE self, VALUE indent) {
#ifdef RUBY_INTEGER_UNIFICATION
if (rb_cInteger != rb_obj_class(indent)) {
#else
if (rb_cFixnum != rb_obj_class(indent)) {
#endif
rb_raise(ox_parse_error_class, "indent must be a fixnum.\n");
}

((Builder)DATA_PTR(self))->indent = NUM2INT(indent);
return Qnil;
}

/* call-seq: pos()
*
* Returns the number of bytes written.
Expand Down Expand Up @@ -940,4 +969,6 @@ ox_init_builder(VALUE ox) {
rb_define_method(builder_class, "line", builder_line, 0);
rb_define_method(builder_class, "column", builder_column, 0);
rb_define_method(builder_class, "pos", builder_pos, 0);
rb_define_method(builder_class, "indent", builder_get_indent, 0);
rb_define_method(builder_class, "indent=", builder_set_indent, 1);
}
26 changes: 26 additions & 0 deletions test/tests.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1471,6 +1471,7 @@ def test_prepend_child_when_nodes_not_empty

def test_builder
b = Ox::Builder.new(:indent => 2)
assert_equal(2, b.indent())
assert_equal(1, b.line())
assert_equal(1, b.column())
assert_equal(0, b.pos())
Expand Down Expand Up @@ -1510,6 +1511,31 @@ def test_builder
|, xml)
end

def test_builder_set_indent
b = Ox::Builder.new(:indent => 2)
assert_equal(2, b.indent())
b.instruct(:xml, :version => '1.0', :encoding => 'UTF-8')
b.element('one')
b.element('two')
b.indent = 0
b.text('Sample ')
b.element('three', :a => 'ack')
b.text('sample')
b.pop() # </three>
b.pop() # </two>
b.indent = 2
b.element('four')
b.pop()
b.close()
xml = b.to_s
assert_equal(%|<?xml version="1.0" encoding="UTF-8"?>
<one>
<two>Sample <three a="ack">sample</three></two>
<four/>
</one>
|, xml)
end

def test_builder_file
filename = File.join(File.dirname(__FILE__), 'create_file_test.xml')
b = Ox::Builder.file(filename, :indent => 2)
Expand Down

0 comments on commit 9b54734

Please sign in to comment.