pretty_xml 0.0.1.5

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f9ddb5c5ac6e75fbbf8834e28a558fab97eb6133
4
+ data.tar.gz: 4e12ffe7d20324d64996197f8f3d3fa6fac35a9f
5
+ SHA512:
6
+ metadata.gz: f7a38ed02a4a1a376d2ca41413262b4539e1499f9365b9b97e1ea05aebad3c31e73972936a19b04efa45d3389fb23f28034220f4a62c15e8a2b8349e988ce34f
7
+ data.tar.gz: 3c9f74139adb91e6a2fa294e66c6200aed620131906c01ed047546413fbe232f9551b8178714683ffe35537b92f0c35ce89df6ba1df76f2069baf28467b2ebb5
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013 dcorrigan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,73 @@
1
+ pretty_xml
2
+ ===============
3
+
4
+ This is pre-1.0 and probably unstable. Use at your own risk
5
+
6
+ I don't recommend using this unless you are sure a human will have to read your XML file.
7
+
8
+ Non-features:
9
+
10
+ - `pretty_xml` does not support namespaced nodes yet.
11
+ - deletes all linebreaks from input
12
+
13
+ ## Use
14
+
15
+ `pretty_xml` expects that three main parameters be passed:
16
+
17
+ 1. `block`: elements that should have internal and external linebreaks
18
+ 2. `compact`: elements that should have external linebreaks
19
+ 3. `inline`: elements that should have neither internal not external linebreaks
20
+
21
+ Additional parameters are:
22
+
23
+ 1. `preserve_whitespace`: retain standalone whitespace only text nodes within compact and inline elements
24
+ 2. `tab`: specifies the kind of space that should be used for indenting the output.
25
+
26
+ Less common parameters:
27
+
28
+ 1. `close_tags`: a list of tags that need explicit closing tags in the output (as in HTML5, `<a id="something"></a>` is correct, but a self-closing `<a id="something"/>` will not be parsed correctly in all cases)
29
+ 2. `control_chars`: options are `:named` or `:hex` for `<`, `>`, and `&` as literal characters in output; defaults to `:named`
30
+
31
+ Use these parameters within a hash to initialize an instance of the `PrettyXML::PrettyPrint` class. To prettyprint a document, pass a `Nokogiri::XML::Document` or a string as an argument to the `pp` method.
32
+
33
+ ## Example
34
+
35
+ doc = '<root> <block>
36
+ <p>
37
+ </p>
38
+
39
+ </block><p>stuff<i> </i></p>
40
+
41
+ <structure>
42
+ <div>
43
+ <p>yo yo<i/></p>
44
+ </div>
45
+ </structure></root>'
46
+
47
+ options = {
48
+ :block => %w(root block structure div),
49
+ :compact => %w(p),
50
+ :inline => %w(i),
51
+ :preserve_whitespace => true,
52
+ :delete_all_linebreaks => true,
53
+ :tab => ' '
54
+ }
55
+
56
+ puts PrettyXML::PrettyPrint.new(options).pp(doc)
57
+
58
+ returns
59
+
60
+ <?xml version="1.0"?>
61
+ <root>
62
+ <block>
63
+ <p> </p>
64
+ </block>
65
+ <p>stuff<i> </i></p>
66
+ <structure>
67
+ <div>
68
+ <p>yo yo<i/></p>
69
+ </div>
70
+ </structure>
71
+ </root>
72
+
73
+ ## Pretty HTML
data/etc/xhtml.yml ADDED
@@ -0,0 +1,117 @@
1
+ :block:
2
+ - address
3
+ - article
4
+ - aside
5
+ - blockquote
6
+ - body
7
+ - colgroup
8
+ - datalist
9
+ - details
10
+ - div
11
+ - dl
12
+ - figure
13
+ - footer
14
+ - form
15
+ - head
16
+ - header
17
+ - hgroup
18
+ - html
19
+ - iframe
20
+ - main
21
+ - map
22
+ - math
23
+ - menu
24
+ - nav
25
+ - object
26
+ - ol
27
+ - optgroup
28
+ - pre
29
+ - section
30
+ - select
31
+ - svg
32
+ - table
33
+ - tbody
34
+ - tfoot
35
+ - thead
36
+ - tr
37
+ - ul
38
+ :compact:
39
+ - area
40
+ - audio
41
+ - base
42
+ - button
43
+ - canvas
44
+ - caption
45
+ - col
46
+ - dd
47
+ - dt
48
+ - embed
49
+ - figcaption
50
+ - h1
51
+ - h2
52
+ - h3
53
+ - h4
54
+ - h5
55
+ - h6
56
+ - hr
57
+ - img
58
+ - input
59
+ - keygen
60
+ - label
61
+ - legend
62
+ - li
63
+ - link
64
+ - menuitem
65
+ - meta
66
+ - noscript
67
+ - option
68
+ - output
69
+ - p
70
+ - param
71
+ - progress
72
+ - script
73
+ - source
74
+ - style
75
+ - summary
76
+ - td
77
+ - template
78
+ - textarea
79
+ - th
80
+ - title
81
+ - track
82
+ - video
83
+ :inline:
84
+ - a
85
+ - abbr
86
+ - b
87
+ - bdi
88
+ - bdo
89
+ - br
90
+ - cite
91
+ - code
92
+ - data
93
+ - del
94
+ - dfn
95
+ - em
96
+ - i
97
+ - ins
98
+ - kbd
99
+ - mark
100
+ - meter
101
+ - q
102
+ - rp
103
+ - rt
104
+ - ruby
105
+ - s
106
+ - samp
107
+ - small
108
+ - span
109
+ - strong
110
+ - sub
111
+ - sup
112
+ - time
113
+ - u
114
+ - var
115
+ - wbr
116
+
117
+
data/lib/config.rb ADDED
@@ -0,0 +1,15 @@
1
+ require 'yaml'
2
+
3
+ module PrettyXML
4
+ def self.root
5
+ File.expand_path '../..', __FILE__
6
+ end
7
+
8
+ def self.etc
9
+ File.join(root, 'etc')
10
+ end
11
+
12
+ def self.load_config(config)
13
+ YAML.load(File.read(File.join(PrettyXML.etc, config)))
14
+ end
15
+ end
data/lib/pretty_xml.rb ADDED
@@ -0,0 +1,5 @@
1
+ require 'nokogiri'
2
+ require 'config'
3
+ require 'sax'
4
+ require 'printers'
5
+
data/lib/printers.rb ADDED
@@ -0,0 +1,2 @@
1
+ require 'printers/pretty_print'
2
+ require 'printers/xhtml'
@@ -0,0 +1,30 @@
1
+ module PrettyXML
2
+ class PrettyPrint
3
+ attr_reader :printer, :handler
4
+
5
+ def initialize(options)
6
+ @handler = SaxPrinter.new(options)
7
+ @printer = Nokogiri::XML::SAX::Parser.new(handler)
8
+ end
9
+
10
+ def pp(doc)
11
+ d = verify_doc(doc)
12
+ dn = doctype_node(doc)
13
+ instrs = []
14
+ pretty = ''
15
+ handler.pretty = pretty
16
+ handler.instructions = instrs
17
+ printer.parse(d)
18
+ instrs << dn if dn
19
+ instrs.empty? ? pretty : "#{instrs.join("\n")}\n#{pretty}"
20
+ end
21
+
22
+ def verify_doc(doc)
23
+ doc.is_a?(Nokogiri::XML::Document) ? doc.to_xml : doc
24
+ end
25
+
26
+ def doctype_node(doc)
27
+ doc[/<!DOCTYPE[^>]*>/]
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,25 @@
1
+ module PrettyXML
2
+ class XHTML < PrettyXML::PrettyPrint
3
+ VOID = %w(area base br col embed hr img input keygen link meta param source track wbr)
4
+
5
+ def initialize(options)
6
+ @elements = PrettyXML.load_config('xhtml.yml')
7
+ options[:close_tags] = explicit_closing_tags
8
+ options[:control_chars] = :hex
9
+ options.merge!(@elements)
10
+ super
11
+ end
12
+
13
+ def explicit_closing_tags
14
+ @elements.values.flatten - VOID
15
+ end
16
+
17
+ def parsed_doc?(doc)
18
+ doc.is_a?(Nokogiri::HTML::Document) or doc.is_a?(Nokogiri::XML::Document)
19
+ end
20
+
21
+ def verify_doc(doc)
22
+ parsed_doc?(doc) ? doc.to_xml : doc
23
+ end
24
+ end
25
+ end
data/lib/sax.rb ADDED
@@ -0,0 +1 @@
1
+ require 'sax/sax_printer'
@@ -0,0 +1,174 @@
1
+ class SaxPrinter < Nokogiri::XML::SAX::Document
2
+ attr_accessor :pretty, :instructions
3
+
4
+ CCS = {
5
+ amp: {named: '&amp;', hex: '&x26;'},
6
+ lt: {named: '&lt;', hex: '&x3c;'},
7
+ gt: {named: '&gt;', hex: '&x3e;'},
8
+ }
9
+ XMLDEC_ATTRS = %w(version encoding standalone)
10
+
11
+ def initialize(options)
12
+ set_options_as_ivars(options)
13
+ end
14
+
15
+ def start_element_namespace(name, attrs = [], prefix = nil, uri = nil, ns = [])
16
+ if @use_ns
17
+ super
18
+ else
19
+ start_element(name, attrs.map { |a| [a.localname, a.value] })
20
+ end
21
+ end
22
+
23
+ def xmldec_attrs(args)
24
+ XMLDEC_ATTRS.each_with_index.to_a.map { |t, i| " #{t}=\"#{args[i]}\"" if args[i] }.compact.join
25
+ end
26
+
27
+ def xmldecl(*args)
28
+ opts = xmldec_attrs(args)
29
+ instructions << "<?xml#{opts}?>"
30
+ end
31
+
32
+ def processing_instruction(name, content)
33
+ instructions << "<?#{name} #{content}?>"
34
+ end
35
+
36
+ def start_document
37
+ @depth = 0
38
+ @opens = []
39
+ end
40
+
41
+ def set_element_types(options)
42
+ @block = Set.new(options[:block])
43
+ @compact = Set.new(options[:compact])
44
+ @inline = Set.new(options[:inline])
45
+ end
46
+
47
+ def set_control_vars(options)
48
+ @whitespace = options.include?(:preserve_whitespace) ? options[:preserve_whitespace] : true
49
+ @close_tags = options[:close_tags] ? Set.new(options[:close_tags]) : []
50
+ @ccs = options[:control_chars] || :named
51
+ @use_ns = options[:use_namespaces]
52
+ @tab = options[:tab] || ' '
53
+ end
54
+
55
+ def set_options_as_ivars(options)
56
+ set_element_types(options)
57
+ set_control_vars(options)
58
+ end
59
+
60
+ def block?(name)
61
+ @block.include?(name)
62
+ end
63
+
64
+ def compact?(name)
65
+ @compact.include?(name)
66
+ end
67
+
68
+ def inline?(name)
69
+ @inline.include?(name)
70
+ end
71
+
72
+ def in_inline?
73
+ inline?(@opens[-1])
74
+ end
75
+
76
+ def in_compact?
77
+ compact?(@opens[-1])
78
+ end
79
+
80
+ def in_block?
81
+ block?(@opens[-1])
82
+ end
83
+
84
+ def ws_adder
85
+ ws = @tab * (@depth - 1)
86
+ pretty.empty? ? ws : "\n#{ws}"
87
+ end
88
+
89
+ def start_element(name, attributes)
90
+ @depth += 1
91
+ space_before_open(name)
92
+ add_opening_tag(name, attributes)
93
+ @opens << name
94
+ @open_tag = name
95
+ end
96
+
97
+ def space_before_open(name)
98
+ increment_space if block?(name) or compact?(name)
99
+ end
100
+
101
+ def increment_space
102
+ pretty << ws_adder
103
+ end
104
+
105
+ def end_element(name)
106
+ space_before_close(name)
107
+ self_closing?(name) ? pretty[-1] = '/>' : pretty << "</#{name}>"
108
+ @depth -= 1
109
+ @open_tag = nil
110
+ @opens.pop
111
+ end
112
+
113
+ def self_closing?(name)
114
+ @open_tag == name and !@close_tags.include?(name)
115
+ end
116
+
117
+ def space_before_close(name)
118
+ increment_space if block?(name) and @depth != 0
119
+ end
120
+
121
+ def add_opening_tag(name, attrs)
122
+ tag = attrs.empty? ? "<#{name}>" : tag_with_attrs(name, attrs)
123
+ pretty << tag
124
+ end
125
+
126
+ def tag_with_attrs(name, attrs)
127
+ attr_str = attrs.map { |n, v| "#{n}=\"#{v}\""}.join(' ')
128
+ "<#{name} #{attr_str}>"
129
+ end
130
+
131
+ def end_document
132
+ end
133
+
134
+ def characters(string)
135
+ return false if ws_only_in_block?(string)
136
+ handle_whitespace(string)
137
+ unless string.empty?
138
+ @open_tag = nil
139
+ sanitize(string)
140
+ pretty << string
141
+ end
142
+ end
143
+
144
+ def ws_only_in_block?(string)
145
+ string[/^\s*$/] and in_block?
146
+ end
147
+
148
+ def whitespace?
149
+ @whitespace and below_block?
150
+ end
151
+
152
+ def below_block?
153
+ in_inline? or in_compact?
154
+ end
155
+
156
+ def handle_whitespace(string)
157
+ string.gsub!(/[\r\n]/, '')
158
+ string.gsub!(/^\s+|\s+$/, '') unless whitespace?
159
+ end
160
+
161
+ def comment(string)
162
+ pretty << "<!--#{string}-->"
163
+ end
164
+
165
+ def sanitize(string)
166
+ string.gsub!(/&/, CCS[:amp][@ccs])
167
+ string.gsub!(/</, CCS[:lt][@ccs])
168
+ string.gsub!(/>/, CCS[:gt][@ccs])
169
+ end
170
+
171
+ def error(string)
172
+ fail Nokogiri::XML::SyntaxError.new(string)
173
+ end
174
+ end
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pretty_xml
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1.5
5
+ platform: ruby
6
+ authors:
7
+ - Dan Corrigan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-12-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: minitest
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: nokogiri
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: Accepts element lists as block, compact, and inline parameters and a
84
+ tab parameter to create a new instance. When pp method is called with a Nokogiri::XML::Document
85
+ or XML string as argument, the method returns a string formatted according to the
86
+ logic of the element lists. For optional parameters, see README.
87
+ email:
88
+ - df.corrigan@gmail.com
89
+ executables: []
90
+ extensions: []
91
+ extra_rdoc_files: []
92
+ files:
93
+ - LICENSE
94
+ - README.md
95
+ - etc/xhtml.yml
96
+ - lib/config.rb
97
+ - lib/pretty_xml.rb
98
+ - lib/printers.rb
99
+ - lib/printers/pretty_print.rb
100
+ - lib/printers/xhtml.rb
101
+ - lib/sax.rb
102
+ - lib/sax/sax_printer.rb
103
+ homepage: http://github.com/dcorrigan/pretty_xml
104
+ licenses: []
105
+ metadata: {}
106
+ post_install_message:
107
+ rdoc_options: []
108
+ require_paths:
109
+ - lib
110
+ required_ruby_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ required_rubygems_version: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ requirements: []
121
+ rubyforge_project:
122
+ rubygems_version: 2.2.2
123
+ signing_key:
124
+ specification_version: 4
125
+ summary: For printing human-readable XML docs
126
+ test_files: []