File: formatter.rb

package info (click to toggle)
ruby-eim-xml 0.0.4-3
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd, wheezy
  • size: 192 kB
  • ctags: 171
  • sloc: ruby: 1,993; makefile: 7
file content (123 lines) | stat: -rw-r--r-- 2,072 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
require "eim_xml"

module EimXML
	class Formatter
		attr_reader :out

		def self.write(element, opt={})
			opt = {:out=>""}.merge(opt)
			new(opt).write(element)
			opt[:out]
		end

		def initialize(opt)
			@out = opt[:out]
			@preservers = opt[:preservers]
			@preserve_space = false
			@indent_string = "  "
			@indent_depth = 0
			@option = opt.dup.tap{|h| [:out, :preservers].each{|k| h.delete(k)}}
		end

		def write(src)
			case src
			when ElementWrapper
				write_wrapper(src)
			when Comment
				write_comment(src)
			when Element
				write_element(src)
			when PCString
				write_pcstring(src)
			else
				write_string(src.to_s)
			end
		end

		def indent(&proc)
			@indent_depth += 1
			proc.call
		ensure
			@indent_depth -= 1
		end

		def preserve_space_element?(elm)
			@preservers && @preservers.any? do |e|
				case e
				when Symbol
					e==elm.name
				when Class
					e===elm
				end
			end
		end

		def write_indent
			out << @indent_string*@indent_depth unless @preserve_space
		end

		def write_newline
			out << "\n" unless @preserve_space
		end

		def write_comment(c)
			write_indent
			c.write_to(out)
			write_newline
		end

		def write_contents_of(elm)
			flag = @preserve_space
			@preserve_space = true if preserve_space_element?(elm)
			write_newline
			indent do
				elm.contents.each do |c|
					write(c)
				end
			end
			write_indent
		ensure
			@preserve_space = flag
		end

		def write_element(elm)
			write_indent
			out << "<"
			elm.name_and_attributes(out)
			case elm.contents.size
			when 0
				out << " />"
				write_newline
			else
				out << ">"
				write_contents_of(elm)
				out << "</#{elm.name}>"
				write_newline
			end
		end

		def write_pcstring(pcs)
			pcs.encoded_string.each_line do |l|
				write_indent
				out << l
			end
			write_newline
		end

		def write_string(str)
			PCString.encode(str).each_line do |l|
				write_indent
				out << l
			end
			write_newline
		end

		def write_wrapper(wrapper)
			wrapper.each(@option) do |i|
				write(i)
			end
		end
	end
end

require "eim_xml/formatter/element_wrapper"