android-xml 1.0.0
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 +7 -0
- data/README.md +127 -0
- data/lib/android-xml.rb +6 -0
- data/lib/android-xml/defaults.rb +44 -0
- data/lib/android-xml/file.rb +42 -0
- data/lib/android-xml/main.rb +115 -0
- data/lib/android-xml/tag.rb +132 -0
- data/lib/android-xml/version.rb +3 -0
- data/spec/android_manifest_spec.rb +55 -0
- data/spec/android_menu_spec.rb +70 -0
- data/spec/android_resources_spec.rb +68 -0
- data/spec/generate_spec.rb +124 -0
- metadata +76 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 86309a38baac267caea7eea59fde2d5b2212b118
|
4
|
+
data.tar.gz: ac749e5475b16b96a535fa907dbe15b133bda2ea
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a8753e1c48772ebdc4f521c42e4d482a6027e9c51303029d5c5e091a6ce75e6f3417e5f3a84046e8303ce43d6bac2c9e1e8bbb86ae048456e57bbae4354800a4
|
7
|
+
data.tar.gz: 291e6376163cce849152830086d4e975630c2dc1b600f7e64288c3818a476f39a14add0663dfcde58f684da07fcb9711644ba3d4a9f2bc02295ecd642aa5640a
|
data/README.md
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
AndroidXml
|
2
|
+
---------
|
3
|
+
|
4
|
+
gem install android-xml
|
5
|
+
|
6
|
+
# Quick start
|
7
|
+
|
8
|
+
###### generate_xml.rb
|
9
|
+
```ruby
|
10
|
+
require 'android-xml'
|
11
|
+
|
12
|
+
AndroidXml.file('res/values/strings.xml') do
|
13
|
+
resource do
|
14
|
+
string(name: 'app_name') { 'AppityApp' }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
AndroidXml.write_all
|
19
|
+
```
|
20
|
+
|
21
|
+
> ruby generate_xml.rb
|
22
|
+
✓ res/values/strings.xml
|
23
|
+
|
24
|
+
> cat res/values/strings.xml
|
25
|
+
<?xml version="1.0" encoding="utf-8"?>
|
26
|
+
<!-- Do not edit this file. It was generated by AndroidXml -->
|
27
|
+
<resources>
|
28
|
+
<string name="app_name">AppityApp</string>
|
29
|
+
</resources>
|
30
|
+
|
31
|
+
# About
|
32
|
+
|
33
|
+
With **AndroidXml** you can generate an XML file with much less fuss. It will
|
34
|
+
take care of prefixing attributes with `android:` when required, it includes the
|
35
|
+
`<?xml ?>` tag, includes the `xmlns:` attribute on your root node (but only when
|
36
|
+
required)... all that good stuff!
|
37
|
+
|
38
|
+
You still need to understand the format that the various Android XML files
|
39
|
+
expect, but hopefully you get a good productivity boost.
|
40
|
+
|
41
|
+
# More examples
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
# The dreaded AndroidManifest file!
|
45
|
+
AndroidXml.file('AndroidManifest.xml') do
|
46
|
+
manifest package: 'com.your_name_here.AppityApp', versionCode: 1, versionName: 1.0 do
|
47
|
+
uses_sdk minSdkVersion: 11
|
48
|
+
|
49
|
+
application label: '@string/app_name', icon: '@drawable/ic_launcher' do
|
50
|
+
activity name: 'MainActivity', label: '@string/app_name' do
|
51
|
+
intent_filter do
|
52
|
+
# these helpers are defined in `android-xml/defaults.rb`,
|
53
|
+
# and you can easily add your own with an AndroidXml.setup block (see
|
54
|
+
# below)
|
55
|
+
main_action
|
56
|
+
launcher_category
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
activity name: 'DisplayMessageActivity',
|
61
|
+
label: '@string/app_name',
|
62
|
+
parentActivityName: 'com.your_name_here.AppityApp.MainActivity'
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# You can generate multiple files from one .rb file
|
68
|
+
AndroidXml.file('res/values-jp/strings.xml') do
|
69
|
+
resource do
|
70
|
+
string(name: 'app_name') { 'アッピティアップ' }
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
AndroidXml.write_all
|
75
|
+
```
|
76
|
+
|
77
|
+
# Helpers
|
78
|
+
|
79
|
+
Here's how we create the main_action helper, or if you need to specify that some
|
80
|
+
attributes don't need the `android:` prefix.
|
81
|
+
|
82
|
+
```ruby
|
83
|
+
AndroidXml.setup do
|
84
|
+
# the hash syntax specifies the `shortcut => actual-tag-name`
|
85
|
+
tag :main_action => 'action' do
|
86
|
+
# then we can assign default attributes
|
87
|
+
defaults name: 'android.intent.action.MAIN'
|
88
|
+
end
|
89
|
+
tag :style do
|
90
|
+
# <style name="..."> is correct - NOT <style android:name="...">
|
91
|
+
rename :name
|
92
|
+
end
|
93
|
+
|
94
|
+
# if you want to add your own shorthands, go nuts:
|
95
|
+
tag :activity do
|
96
|
+
rename :parent => :parentActivityName
|
97
|
+
end
|
98
|
+
|
99
|
+
# global changes
|
100
|
+
all do
|
101
|
+
rename :style # always style="", never android:style=""
|
102
|
+
end
|
103
|
+
|
104
|
+
# adds the xmlns attribute to the root node, no matter WHAT the root node is
|
105
|
+
root do
|
106
|
+
defaults 'xmlns:android' => 'http://schemas.android.com/apk/res/android'
|
107
|
+
end
|
108
|
+
|
109
|
+
# disable the xmlns attribute on the resource node
|
110
|
+
tag :resources do
|
111
|
+
defaults 'xmlns:android' => nil
|
112
|
+
end
|
113
|
+
end
|
114
|
+
```
|
115
|
+
|
116
|
+
# Errata
|
117
|
+
|
118
|
+
```ruby
|
119
|
+
# If you want to check the output before committing to `write_all`
|
120
|
+
AndroidXml.output_all
|
121
|
+
|
122
|
+
# If you want to wipe out all the defaults and settings
|
123
|
+
AndroidXml.reset
|
124
|
+
|
125
|
+
# If you want the defaults back
|
126
|
+
AndroidXml.setup_defaults
|
127
|
+
```
|
data/lib/android-xml.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'android-xml'
|
2
|
+
|
3
|
+
|
4
|
+
module AndroidXml
|
5
|
+
module_function
|
6
|
+
|
7
|
+
def setup_defaults
|
8
|
+
setup do
|
9
|
+
# assign the xmlns to all root nodes
|
10
|
+
root do
|
11
|
+
defaults 'xmlns:android' => 'http://schemas.android.com/apk/res/android'
|
12
|
+
end
|
13
|
+
|
14
|
+
all do
|
15
|
+
# suppress 'android:' prefix to all style attributes
|
16
|
+
rename :style
|
17
|
+
end
|
18
|
+
|
19
|
+
# disable the xmlns attribute on the resource node
|
20
|
+
tag :resources do
|
21
|
+
defaults 'xmlns:android' => nil
|
22
|
+
end
|
23
|
+
|
24
|
+
# remove the 'android:' prefix
|
25
|
+
tag :string, :style, :item do
|
26
|
+
rename :name
|
27
|
+
end
|
28
|
+
tag :style do
|
29
|
+
rename :parent
|
30
|
+
end
|
31
|
+
tag :manifest do
|
32
|
+
rename :package
|
33
|
+
end
|
34
|
+
|
35
|
+
# creates a couple "tag shortcuts"
|
36
|
+
tag :main_action => 'action' do
|
37
|
+
defaults name: 'android.intent.action.MAIN'
|
38
|
+
end
|
39
|
+
tag :launcher_category => 'category' do
|
40
|
+
defaults name: 'android.intent.category.LAUNCHER'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module AndroidXml
|
2
|
+
|
3
|
+
class XmlFile < Tag
|
4
|
+
|
5
|
+
attr :filename
|
6
|
+
|
7
|
+
def initialize(filename, &block)
|
8
|
+
@filename = filename
|
9
|
+
super(nil, &block)
|
10
|
+
AndroidXml.files << self
|
11
|
+
end
|
12
|
+
|
13
|
+
def method_missing(method_name, *args, &block)
|
14
|
+
raise "There can be only one (new: #{method_name}, old: #{@root})" if @root
|
15
|
+
|
16
|
+
@root = super
|
17
|
+
@root.is_root = true
|
18
|
+
@root
|
19
|
+
end
|
20
|
+
|
21
|
+
def generate
|
22
|
+
output = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
|
23
|
+
output << "<!-- Do not edit this file. It was generated by AndroidXml -->\n"
|
24
|
+
output << generate_block
|
25
|
+
end
|
26
|
+
|
27
|
+
def out
|
28
|
+
puts "---- filename: #{@filename} ----"
|
29
|
+
super
|
30
|
+
puts "---------------#{'-' * @filename.to_s.length}-----"
|
31
|
+
end
|
32
|
+
|
33
|
+
def write
|
34
|
+
File.open(self.filename, 'w') do |f|
|
35
|
+
f.write(self.to_s)
|
36
|
+
end
|
37
|
+
puts "✓ #{self.filename}"
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
module AndroidXml
|
2
|
+
ROOT = '__root_node_with_a_long_special_name__'
|
3
|
+
ALL = '__all_node_with_a_long_special_name__'
|
4
|
+
|
5
|
+
module_function
|
6
|
+
|
7
|
+
def tab=(value)
|
8
|
+
@tab = value
|
9
|
+
end
|
10
|
+
|
11
|
+
def file(filename, &block)
|
12
|
+
XmlFile.new(filename, &block)
|
13
|
+
end
|
14
|
+
|
15
|
+
def files
|
16
|
+
@files ||= []
|
17
|
+
end
|
18
|
+
|
19
|
+
def write_all
|
20
|
+
files.each do |xml_file|
|
21
|
+
xml_file.write
|
22
|
+
end
|
23
|
+
|
24
|
+
@files = nil
|
25
|
+
end
|
26
|
+
|
27
|
+
def output_all
|
28
|
+
files.each do |xml_file|
|
29
|
+
xml_file.out
|
30
|
+
puts
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def diff_all
|
35
|
+
files.each do |xml_file|
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def tags
|
40
|
+
@tags ||= Hash.new do |hash, key|
|
41
|
+
hash[key] = {
|
42
|
+
attrs: {},
|
43
|
+
defaults: {},
|
44
|
+
rename: nil,
|
45
|
+
}
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def tab
|
50
|
+
@tab ||= ' '
|
51
|
+
end
|
52
|
+
|
53
|
+
def reset
|
54
|
+
@tab = nil
|
55
|
+
@tags = nil
|
56
|
+
@files = nil
|
57
|
+
end
|
58
|
+
|
59
|
+
def setup(&block)
|
60
|
+
instance_exec(&block)
|
61
|
+
end
|
62
|
+
|
63
|
+
def root_tag
|
64
|
+
tags[ROOT]
|
65
|
+
end
|
66
|
+
|
67
|
+
def root(&block)
|
68
|
+
tag(ROOT, &block)
|
69
|
+
end
|
70
|
+
|
71
|
+
def all_tag
|
72
|
+
tags[ALL]
|
73
|
+
end
|
74
|
+
|
75
|
+
def all(&block)
|
76
|
+
tag(ALL, &block)
|
77
|
+
end
|
78
|
+
|
79
|
+
def tag(*names, &block)
|
80
|
+
context_was = @context
|
81
|
+
|
82
|
+
names.each do |name|
|
83
|
+
if name.is_a?(Hash)
|
84
|
+
@context = nil
|
85
|
+
name.each do |shortcut, tag_name|
|
86
|
+
raise "There can be only one key-value pair" if @context
|
87
|
+
|
88
|
+
@context = shortcut.to_s
|
89
|
+
tags[@context][:rename] = tag_name.to_s
|
90
|
+
end
|
91
|
+
else
|
92
|
+
@context = name.to_s
|
93
|
+
end
|
94
|
+
|
95
|
+
instance_exec(&block)
|
96
|
+
end
|
97
|
+
|
98
|
+
@context = context_was
|
99
|
+
end
|
100
|
+
|
101
|
+
def rename(attrs)
|
102
|
+
if attrs.is_a?(Hash)
|
103
|
+
attrs.each do |attr_name, attr_rename|
|
104
|
+
tags[@context][:attrs][attr_name.to_s] = attr_rename.to_s
|
105
|
+
end
|
106
|
+
else
|
107
|
+
tags[@context][:attrs][attrs.to_s] = attrs.to_s
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def defaults(attrs)
|
112
|
+
tags[@context][:defaults].merge!(attrs)
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
module AndroidXml
|
2
|
+
|
3
|
+
class Tag
|
4
|
+
attr_accessor :is_root
|
5
|
+
|
6
|
+
def initialize(tag, *args, &block)
|
7
|
+
@buffer = []
|
8
|
+
@attrs = {}
|
9
|
+
@raw_tag = tag.to_s
|
10
|
+
@text = nil
|
11
|
+
|
12
|
+
if rename = AndroidXml.tags[tag.to_s][:rename]
|
13
|
+
@tag = rename
|
14
|
+
else
|
15
|
+
@tag = tag.to_s.gsub('_', '-')
|
16
|
+
end
|
17
|
+
|
18
|
+
args.each do |arg|
|
19
|
+
if arg.is_a?(Hash)
|
20
|
+
@attrs.merge!(arg)
|
21
|
+
elsif arg.is_a?(String)
|
22
|
+
@text = arg
|
23
|
+
else
|
24
|
+
raise ArgumentError.new("Unknown argument #{arg.inspect} in #{self.class}#new")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
@generate = block
|
29
|
+
end
|
30
|
+
|
31
|
+
def method_missing(method_name, *args, &block)
|
32
|
+
tag = Tag.new(method_name, *args, &block)
|
33
|
+
@buffer << tag
|
34
|
+
tag
|
35
|
+
end
|
36
|
+
|
37
|
+
def attrs(whitespace)
|
38
|
+
attrs = {}
|
39
|
+
|
40
|
+
attrs.merge!(AndroidXml.all_tag[:defaults])
|
41
|
+
if is_root
|
42
|
+
attrs.merge!(AndroidXml.root_tag[:defaults])
|
43
|
+
end
|
44
|
+
|
45
|
+
attrs.merge!(AndroidXml.tags[@raw_tag][:defaults])
|
46
|
+
attrs.merge!(@attrs)
|
47
|
+
|
48
|
+
output = ''
|
49
|
+
is_first = true
|
50
|
+
attrs.each do |key, value|
|
51
|
+
next if value.nil?
|
52
|
+
|
53
|
+
key = key.to_s
|
54
|
+
|
55
|
+
if AndroidXml.tags[@tag][:attrs].key?(key)
|
56
|
+
xml_key = AndroidXml.tags[@tag][:attrs][key]
|
57
|
+
elsif AndroidXml.all_tag[:attrs].key?(key)
|
58
|
+
xml_key = AndroidXml.all_tag[:attrs][key]
|
59
|
+
elsif key.to_s.include?(':')
|
60
|
+
xml_key = key.to_s
|
61
|
+
else
|
62
|
+
xml_key = "android:#{key}"
|
63
|
+
end
|
64
|
+
|
65
|
+
if is_first
|
66
|
+
output << " #{xml_key}=\"#{value}\""
|
67
|
+
is_first = false
|
68
|
+
else
|
69
|
+
output << "\n#{whitespace}#{xml_key}=\"#{value}\""
|
70
|
+
end
|
71
|
+
end
|
72
|
+
output
|
73
|
+
end
|
74
|
+
|
75
|
+
def generate(tab='')
|
76
|
+
whitespace = "#{tab} #{' ' * @tag.length}"
|
77
|
+
output = "#{tab}<#{@tag}#{attrs(whitespace)}"
|
78
|
+
if @generate
|
79
|
+
inside = generate_block(tab + AndroidXml.tab)
|
80
|
+
if !inside || inside.strip.empty?
|
81
|
+
output << " />\n"
|
82
|
+
else
|
83
|
+
output << ">"
|
84
|
+
if inside.lstrip.start_with?('<')
|
85
|
+
output << "\n" << inside << "#{tab}</#{@tag}>\n"
|
86
|
+
else
|
87
|
+
output << inside << "</#{@tag}>\n"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
else
|
91
|
+
output << " />\n"
|
92
|
+
end
|
93
|
+
|
94
|
+
output
|
95
|
+
end
|
96
|
+
|
97
|
+
def generate_block(tab='')
|
98
|
+
return @block_output if @block_output
|
99
|
+
|
100
|
+
output = ''
|
101
|
+
if @generate
|
102
|
+
text = instance_exec(&@generate)
|
103
|
+
@buffer.each do |tag|
|
104
|
+
output << tag.generate(tab)
|
105
|
+
end
|
106
|
+
if text.is_a?(String)
|
107
|
+
if output.empty?
|
108
|
+
output << text
|
109
|
+
else
|
110
|
+
output << tab << text << "\n"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
@block_output = output
|
116
|
+
end
|
117
|
+
|
118
|
+
def to_s
|
119
|
+
generate
|
120
|
+
end
|
121
|
+
|
122
|
+
def to_ary
|
123
|
+
[to_s]
|
124
|
+
end
|
125
|
+
|
126
|
+
def out
|
127
|
+
puts to_s
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'android-xml'
|
2
|
+
|
3
|
+
|
4
|
+
describe 'AndroidManifest.xml' do
|
5
|
+
|
6
|
+
before do
|
7
|
+
AndroidXml.reset
|
8
|
+
AndroidXml.setup_defaults
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should generate a sensible AndroidManifest file' do
|
12
|
+
xml = AndroidXml.file('AndroidManifest.xml') do
|
13
|
+
manifest package: 'com.your_name_here.AnyAndroidApp', versionCode: 1, versionName: 1.0 do
|
14
|
+
uses_sdk minSdkVersion: 11
|
15
|
+
|
16
|
+
application label: '@string/app_name', icon: '@drawable/ic_launcher' do
|
17
|
+
activity name: 'MainActivity', label: '@string/app_name' do
|
18
|
+
intent_filter do
|
19
|
+
main_action
|
20
|
+
launcher_category
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
activity name: 'AnotherActivity', label: '@string/app_name', parentActivityName: 'com.your_name_here.AnyAndroidApp.MainActivity'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
expect(xml.to_s).to eql <<-XML
|
30
|
+
<?xml version="1.0" encoding="utf-8"?>
|
31
|
+
<!-- Do not edit this file. It was generated by AndroidXml -->
|
32
|
+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
33
|
+
package="com.your_name_here.AnyAndroidApp"
|
34
|
+
android:versionCode="1"
|
35
|
+
android:versionName="1.0">
|
36
|
+
<uses-sdk android:minSdkVersion="11" />
|
37
|
+
<application android:label="@string/app_name"
|
38
|
+
android:icon="@drawable/ic_launcher">
|
39
|
+
<activity android:name="MainActivity"
|
40
|
+
android:label="@string/app_name">
|
41
|
+
<intent-filter>
|
42
|
+
<action android:name="android.intent.action.MAIN" />
|
43
|
+
<category android:name="android.intent.category.LAUNCHER" />
|
44
|
+
</intent-filter>
|
45
|
+
</activity>
|
46
|
+
<activity android:name="AnotherActivity"
|
47
|
+
android:label="@string/app_name"
|
48
|
+
android:parentActivityName="com.your_name_here.AnyAndroidApp.MainActivity" />
|
49
|
+
</application>
|
50
|
+
</manifest>
|
51
|
+
XML
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'android-xml'
|
2
|
+
|
3
|
+
|
4
|
+
describe 'Android menu files' do
|
5
|
+
|
6
|
+
before do
|
7
|
+
AndroidXml.reset
|
8
|
+
AndroidXml.setup_defaults
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should generate a sensible menu.xml file' do
|
12
|
+
xml = AndroidXml.file('res/menu/menu.xml') do
|
13
|
+
menu do
|
14
|
+
item id: '@+id/action_search',
|
15
|
+
icon: '@drawable/ic_action_search',
|
16
|
+
title: '@string/action_search',
|
17
|
+
showAsAction: 'ifRoom'
|
18
|
+
|
19
|
+
item id: '@+id/action_settings',
|
20
|
+
title: '@string/action_settings',
|
21
|
+
showAsAction: 'never'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
expect(xml.to_s).to eql <<-XML
|
26
|
+
<?xml version="1.0" encoding="utf-8"?>
|
27
|
+
<!-- Do not edit this file. It was generated by AndroidXml -->
|
28
|
+
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
29
|
+
<item android:id="@+id/action_search"
|
30
|
+
android:icon="@drawable/ic_action_search"
|
31
|
+
android:title="@string/action_search"
|
32
|
+
android:showAsAction="ifRoom" />
|
33
|
+
<item android:id="@+id/action_settings"
|
34
|
+
android:title="@string/action_settings"
|
35
|
+
android:showAsAction="never" />
|
36
|
+
</menu>
|
37
|
+
XML
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should generate a sensible strings.xml file' do
|
41
|
+
xml = AndroidXml.file('res/values/strings.xml') do
|
42
|
+
resources do
|
43
|
+
string(name: 'app_name') { 'Harroo' }
|
44
|
+
string(name: 'hello') { 'Well, Harroo!' }
|
45
|
+
string(name: 'portrait') { 'portrait' }
|
46
|
+
string(name: 'landscape') { 'landscape' }
|
47
|
+
string(name: 'button_send') { 'Send' }
|
48
|
+
string(name: 'action_search') { 'Search' }
|
49
|
+
string(name: 'action_settings') { 'Settings' }
|
50
|
+
string(name: 'title_activity_main') { 'MainActivity' }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
expect(xml.to_s).to eql <<-XML
|
55
|
+
<?xml version="1.0" encoding="utf-8"?>
|
56
|
+
<!-- Do not edit this file. It was generated by AndroidXml -->
|
57
|
+
<resources>
|
58
|
+
<string name="app_name">Harroo</string>
|
59
|
+
<string name="hello">Well, Harroo!</string>
|
60
|
+
<string name="portrait">portrait</string>
|
61
|
+
<string name="landscape">landscape</string>
|
62
|
+
<string name="button_send">Send</string>
|
63
|
+
<string name="action_search">Search</string>
|
64
|
+
<string name="action_settings">Settings</string>
|
65
|
+
<string name="title_activity_main">MainActivity</string>
|
66
|
+
</resources>
|
67
|
+
XML
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'android-xml'
|
2
|
+
|
3
|
+
|
4
|
+
describe 'Android resource files' do
|
5
|
+
|
6
|
+
before do
|
7
|
+
AndroidXml.reset
|
8
|
+
AndroidXml.setup_defaults
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should generate a sensible style.xml file' do
|
12
|
+
xml = AndroidXml.file('res/values/style.xml') do
|
13
|
+
resources do
|
14
|
+
style(name: 'CodeFont', parent: '@android:style/TextAppearance.Medium') do
|
15
|
+
item(name: "android:layout_width") { 'fill_parent' }
|
16
|
+
item(name: "android:layout_height") { 'wrap_content' }
|
17
|
+
item(name: "android:textColor") { '#00FF00' }
|
18
|
+
item(name: "android:typeface") { 'monospace' }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
expect(xml.to_s).to eql <<-XML
|
24
|
+
<?xml version="1.0" encoding="utf-8"?>
|
25
|
+
<!-- Do not edit this file. It was generated by AndroidXml -->
|
26
|
+
<resources>
|
27
|
+
<style name="CodeFont"
|
28
|
+
parent="@android:style/TextAppearance.Medium">
|
29
|
+
<item name="android:layout_width">fill_parent</item>
|
30
|
+
<item name="android:layout_height">wrap_content</item>
|
31
|
+
<item name="android:textColor">#00FF00</item>
|
32
|
+
<item name="android:typeface">monospace</item>
|
33
|
+
</style>
|
34
|
+
</resources>
|
35
|
+
XML
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should generate a sensible strings.xml file' do
|
39
|
+
xml = AndroidXml.file('res/values/strings.xml') do
|
40
|
+
resources do
|
41
|
+
string(name: 'app_name') { 'Harroo' }
|
42
|
+
string(name: 'hello') { 'Well, Harroo!' }
|
43
|
+
string(name: 'portrait') { 'portrait' }
|
44
|
+
string(name: 'landscape') { 'landscape' }
|
45
|
+
string(name: 'button_send') { 'Send' }
|
46
|
+
string(name: 'action_search') { 'Search' }
|
47
|
+
string(name: 'action_settings') { 'Settings' }
|
48
|
+
string(name: 'title_activity_main') { 'MainActivity' }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
expect(xml.to_s).to eql <<-XML
|
53
|
+
<?xml version="1.0" encoding="utf-8"?>
|
54
|
+
<!-- Do not edit this file. It was generated by AndroidXml -->
|
55
|
+
<resources>
|
56
|
+
<string name="app_name">Harroo</string>
|
57
|
+
<string name="hello">Well, Harroo!</string>
|
58
|
+
<string name="portrait">portrait</string>
|
59
|
+
<string name="landscape">landscape</string>
|
60
|
+
<string name="button_send">Send</string>
|
61
|
+
<string name="action_search">Search</string>
|
62
|
+
<string name="action_settings">Settings</string>
|
63
|
+
<string name="title_activity_main">MainActivity</string>
|
64
|
+
</resources>
|
65
|
+
XML
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'android-xml'
|
2
|
+
|
3
|
+
describe AndroidXml do
|
4
|
+
|
5
|
+
before do
|
6
|
+
AndroidXml.reset
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'should generate <any-tag />' do
|
10
|
+
xml = AndroidXml.file('tmp/test.xml') do
|
11
|
+
any_tag
|
12
|
+
end
|
13
|
+
|
14
|
+
expect(xml.to_s).to eql <<-XML
|
15
|
+
<?xml version="1.0" encoding="utf-8"?>
|
16
|
+
<!-- Do not edit this file. It was generated by AndroidXml -->
|
17
|
+
<any-tag />
|
18
|
+
XML
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should generate <any-tag with="properties" />' do
|
22
|
+
xml = AndroidXml.file('tmp/test.xml') do
|
23
|
+
any_tag with: 'properties'
|
24
|
+
end
|
25
|
+
|
26
|
+
expect(xml.to_s).to eql <<-XML
|
27
|
+
<?xml version="1.0" encoding="utf-8"?>
|
28
|
+
<!-- Do not edit this file. It was generated by AndroidXml -->
|
29
|
+
<any-tag android:with="properties" />
|
30
|
+
XML
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should generate <any-tag>with text</any-tag>' do
|
34
|
+
xml = AndroidXml.file('tmp/test.xml') do
|
35
|
+
any_tag { 'with text' }
|
36
|
+
end
|
37
|
+
|
38
|
+
expect(xml.to_s).to eql <<-XML
|
39
|
+
<?xml version="1.0" encoding="utf-8"?>
|
40
|
+
<!-- Do not edit this file. It was generated by AndroidXml -->
|
41
|
+
<any-tag>with text</any-tag>
|
42
|
+
XML
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should generate <nested><tags /></nested>' do
|
46
|
+
xml = AndroidXml.file('tmp/test.xml') do
|
47
|
+
nested do
|
48
|
+
tags
|
49
|
+
tags
|
50
|
+
tags
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
expect(xml.to_s).to eql <<-XML
|
55
|
+
<?xml version="1.0" encoding="utf-8"?>
|
56
|
+
<!-- Do not edit this file. It was generated by AndroidXml -->
|
57
|
+
<nested>
|
58
|
+
<tags />
|
59
|
+
<tags />
|
60
|
+
<tags />
|
61
|
+
</nested>
|
62
|
+
XML
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'should generate <nested><tags /></nested> with custom whitespace' do
|
66
|
+
xml = AndroidXml.file('tmp/test.xml') do
|
67
|
+
nested do
|
68
|
+
tags
|
69
|
+
tags
|
70
|
+
tags
|
71
|
+
end
|
72
|
+
end
|
73
|
+
AndroidXml.tab = ' '
|
74
|
+
|
75
|
+
expect(xml.to_s).to eql <<-XML
|
76
|
+
<?xml version="1.0" encoding="utf-8"?>
|
77
|
+
<!-- Do not edit this file. It was generated by AndroidXml -->
|
78
|
+
<nested>
|
79
|
+
<tags />
|
80
|
+
<tags />
|
81
|
+
<tags />
|
82
|
+
</nested>
|
83
|
+
XML
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'should generate <nested><tags />with text</nested>' do
|
87
|
+
xml = AndroidXml.file('tmp/test.xml') do
|
88
|
+
nested do
|
89
|
+
tags
|
90
|
+
tags
|
91
|
+
'with text'
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
expect(xml.to_s).to eql <<-XML
|
96
|
+
<?xml version="1.0" encoding="utf-8"?>
|
97
|
+
<!-- Do not edit this file. It was generated by AndroidXml -->
|
98
|
+
<nested>
|
99
|
+
<tags />
|
100
|
+
<tags />
|
101
|
+
with text
|
102
|
+
</nested>
|
103
|
+
XML
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'should generate <nested with="" many="properties"><tags with="" many="properties" /></nested>' do
|
107
|
+
xml = AndroidXml.file('tmp/test.xml') do
|
108
|
+
nested with: '', many: 'properties' do
|
109
|
+
tags with: '', many: 'properties'
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
expect(xml.to_s).to eql <<-XML
|
114
|
+
<?xml version="1.0" encoding="utf-8"?>
|
115
|
+
<!-- Do not edit this file. It was generated by AndroidXml -->
|
116
|
+
<nested android:with=""
|
117
|
+
android:many="properties">
|
118
|
+
<tags android:with=""
|
119
|
+
android:many="properties" />
|
120
|
+
</nested>
|
121
|
+
XML
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
metadata
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: android-xml
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Colin T.A. Gray
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-06-18 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
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
|
+
description: |
|
28
|
+
Add this to your build process, and never write XML again!
|
29
|
+
|
30
|
+
Plus, you can have multiple files generated from one file.
|
31
|
+
email:
|
32
|
+
- colinta@gmail.com
|
33
|
+
executables: []
|
34
|
+
extensions: []
|
35
|
+
extra_rdoc_files: []
|
36
|
+
files:
|
37
|
+
- lib/android-xml/defaults.rb
|
38
|
+
- lib/android-xml/file.rb
|
39
|
+
- lib/android-xml/main.rb
|
40
|
+
- lib/android-xml/tag.rb
|
41
|
+
- lib/android-xml/version.rb
|
42
|
+
- lib/android-xml.rb
|
43
|
+
- README.md
|
44
|
+
- spec/android_manifest_spec.rb
|
45
|
+
- spec/android_menu_spec.rb
|
46
|
+
- spec/android_resources_spec.rb
|
47
|
+
- spec/generate_spec.rb
|
48
|
+
homepage: https://github.com/colinta/android-xml
|
49
|
+
licenses:
|
50
|
+
- BSD
|
51
|
+
metadata: {}
|
52
|
+
post_install_message:
|
53
|
+
rdoc_options: []
|
54
|
+
require_paths:
|
55
|
+
- lib
|
56
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - '>='
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
requirements: []
|
67
|
+
rubyforge_project:
|
68
|
+
rubygems_version: 2.0.3
|
69
|
+
signing_key:
|
70
|
+
specification_version: 4
|
71
|
+
summary: Generates Android XML files.
|
72
|
+
test_files:
|
73
|
+
- spec/android_manifest_spec.rb
|
74
|
+
- spec/android_menu_spec.rb
|
75
|
+
- spec/android_resources_spec.rb
|
76
|
+
- spec/generate_spec.rb
|