timl 0.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/.gitignore +2 -0
- data/.travis.yml +3 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +20 -0
- data/README.md +142 -0
- data/Rakefile +8 -0
- data/lib/timl.rb +11 -0
- data/lib/timl/timl.rb +87 -0
- data/spec/case/1.rb +3 -0
- data/spec/case/2.rb +6 -0
- data/spec/case/3.rb +5 -0
- data/spec/case/4.rb +11 -0
- data/spec/case/5.rb +23 -0
- data/spec/result/1.xml +1 -0
- data/spec/result/2.xml +1 -0
- data/spec/result/3.xml +5 -0
- data/spec/result/4.xml +8 -0
- data/spec/result/5.xml +27 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/timl_spec.rb +17 -0
- data/timl.gemspec +16 -0
- metadata +66 -0
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
diff-lcs (1.1.3)
|
5
|
+
rake (0.9.2.2)
|
6
|
+
rspec (2.10.0)
|
7
|
+
rspec-core (~> 2.10.0)
|
8
|
+
rspec-expectations (~> 2.10.0)
|
9
|
+
rspec-mocks (~> 2.10.0)
|
10
|
+
rspec-core (2.10.1)
|
11
|
+
rspec-expectations (2.10.0)
|
12
|
+
diff-lcs (~> 1.1.3)
|
13
|
+
rspec-mocks (2.10.1)
|
14
|
+
|
15
|
+
PLATFORMS
|
16
|
+
ruby
|
17
|
+
|
18
|
+
DEPENDENCIES
|
19
|
+
rake
|
20
|
+
rspec
|
data/README.md
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
# Timl
|
2
|
+
|
3
|
+
Timl is an amalgamation of Tiny XML. I created it because I find the builder DSL
|
4
|
+
to be a little bit cluttered and hard to digest at first glance.
|
5
|
+
|
6
|
+
Timl aims to be very small and very intuitive to use. The main code that does
|
7
|
+
all of the heavy lifting is less than 100 lines of code, including comments.
|
8
|
+
|
9
|
+
### Build statuses
|
10
|
+
|
11
|
+
Develop: [](http://travis-ci.org/samwho/timl)
|
12
|
+
|
13
|
+
Master: [](http://travis-ci.org/samwho/timl)
|
14
|
+
|
15
|
+
# Installation
|
16
|
+
|
17
|
+
The installation is a standard RubyGem installation:
|
18
|
+
|
19
|
+
gem install timl
|
20
|
+
|
21
|
+
# Usage
|
22
|
+
|
23
|
+
The Timl DSL is very intuitive. It relies on some Ruby metaprogramming under the
|
24
|
+
hood that will catch methods that have not been defined and define them. What
|
25
|
+
this means to you, the user, is that you can use any XML tag you want as part of
|
26
|
+
the DSL. Let's see an example:
|
27
|
+
|
28
|
+
``` ruby
|
29
|
+
require 'timl'
|
30
|
+
|
31
|
+
Timl.start do
|
32
|
+
body do
|
33
|
+
p { "This is a paragraph tag." }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
```
|
37
|
+
|
38
|
+
The return value of that code is the following XML:
|
39
|
+
|
40
|
+
``` xml
|
41
|
+
<body>
|
42
|
+
<p>
|
43
|
+
This is a paragraph tag.
|
44
|
+
</p>
|
45
|
+
</body>
|
46
|
+
```
|
47
|
+
|
48
|
+
Which is what you would expect, right?
|
49
|
+
|
50
|
+
## Attributes in XML
|
51
|
+
|
52
|
+
The above example is a bit simple. What is you want attributes in your XML? Timl
|
53
|
+
can do that too:
|
54
|
+
|
55
|
+
``` ruby
|
56
|
+
require 'timl'
|
57
|
+
|
58
|
+
Timl.start do
|
59
|
+
div id: "content" do
|
60
|
+
p style: "font-weight: bold" do
|
61
|
+
"This is a bold paragraph."
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
```
|
66
|
+
|
67
|
+
Which, unsurprisingly, produces the following XML (I realise these are HTML
|
68
|
+
examples, but the library really isn't constrained to HTML):
|
69
|
+
|
70
|
+
``` xml
|
71
|
+
<div id='content'>
|
72
|
+
<p style='font-weight: bold'>
|
73
|
+
This is a bold paragraph.
|
74
|
+
</p>
|
75
|
+
</div>
|
76
|
+
```
|
77
|
+
|
78
|
+
## XML and HTML headers
|
79
|
+
|
80
|
+
If you want to include XML and HTML header/doctype information, that's possible
|
81
|
+
as well:
|
82
|
+
|
83
|
+
``` ruby
|
84
|
+
require 'timl'
|
85
|
+
|
86
|
+
Timl.start do
|
87
|
+
xml_header
|
88
|
+
end
|
89
|
+
```
|
90
|
+
|
91
|
+
Translates to:
|
92
|
+
|
93
|
+
``` xml
|
94
|
+
<?xml version='1.0' encoding='UTF-8'?>
|
95
|
+
```
|
96
|
+
|
97
|
+
If you want to use a different encoding, that's possible too:
|
98
|
+
|
99
|
+
``` ruby
|
100
|
+
require 'timl'
|
101
|
+
|
102
|
+
Timl.start do
|
103
|
+
xml_header encoding: "UTF-16"
|
104
|
+
end
|
105
|
+
```
|
106
|
+
|
107
|
+
Translates to:
|
108
|
+
|
109
|
+
``` xml
|
110
|
+
<?xml version='1.0' encoding='UTF-16'?>
|
111
|
+
```
|
112
|
+
|
113
|
+
### HTML doctype
|
114
|
+
|
115
|
+
The HTML doctype is inserted in a very similar way:
|
116
|
+
|
117
|
+
``` ruby
|
118
|
+
require 'timl'
|
119
|
+
|
120
|
+
Timl.start do
|
121
|
+
html5_doctype
|
122
|
+
end
|
123
|
+
```
|
124
|
+
|
125
|
+
Translates to:
|
126
|
+
|
127
|
+
``` xml
|
128
|
+
<!DOCTYPE html>
|
129
|
+
```
|
130
|
+
|
131
|
+
Unfortunately doctypes before HTML5 are not currently supported. If there's
|
132
|
+
overwhelming need for it in future, I might consider adding it.
|
133
|
+
|
134
|
+
# Contributing
|
135
|
+
|
136
|
+
If you want to contribute, please feel free. File an issue, fork the repo,
|
137
|
+
submit a pull request, whatever you want to do. Please not, however, that I use
|
138
|
+
git-flow as a branching strategy. If you aren't familiar with git-flow, look it
|
139
|
+
up, learn it, love it :)
|
140
|
+
|
141
|
+
Please don't submit pull requests to master. Pull requests must go to develop
|
142
|
+
and come from a feature branch. Thanks!
|
data/Rakefile
ADDED
data/lib/timl.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
libdir = File.dirname(__FILE__)
|
2
|
+
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
|
3
|
+
|
4
|
+
module Timl
|
5
|
+
VERSION = '0.1'
|
6
|
+
ROOTDIR = File.expand_path(File.dirname(__FILE__) + '/..')
|
7
|
+
SPECDIR = ROOTDIR + '/spec'
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'rexml/document'
|
11
|
+
require 'timl/timl'
|
data/lib/timl/timl.rb
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
module Timl
|
2
|
+
# Dynamically defines a tag method so we don't have to hit method_missing all
|
3
|
+
# the time.
|
4
|
+
def self.define_tags *args
|
5
|
+
args.each do |tag|
|
6
|
+
self.class.instance_eval do
|
7
|
+
define_method tag do |*args, &block|
|
8
|
+
@@out << "<#{tag.to_s}#{parameterize args.first}>"
|
9
|
+
result = module_eval(&block)
|
10
|
+
@@out << result unless result.nil? || result.start_with?('<')
|
11
|
+
@@out << "</#{tag.to_s}>"
|
12
|
+
@@out
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Define tags to override existing methods that can mess with the DSL.
|
19
|
+
define_tags :p
|
20
|
+
|
21
|
+
# Start a Timl XML string. This is the main method for creating XML with Timl.
|
22
|
+
# It accepts a format as its first parameter, which can either be :flat or
|
23
|
+
# :pretty (defaults to :pretty). The :flat parameter gives you back XML that
|
24
|
+
# has no indentation. The :pretty option runs the generated XML through the
|
25
|
+
# REXML document formatter, which is a little slower but gives great
|
26
|
+
# readability.
|
27
|
+
#
|
28
|
+
# Timl.start then takes a block, which kicks off the DSL. Here's a simple
|
29
|
+
# example:
|
30
|
+
#
|
31
|
+
# Timl.start :flat do
|
32
|
+
# p { "This is a paragraph." }
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# #=> <p>This is a paragraph.</p>
|
36
|
+
#
|
37
|
+
# For more example please refer to the README.
|
38
|
+
def self.start format = :pretty, &block
|
39
|
+
@@out = ""
|
40
|
+
module_eval &block
|
41
|
+
case format
|
42
|
+
when :pretty
|
43
|
+
doc = REXML::Document.new(@@out)
|
44
|
+
doc.write(xml = '', 2)
|
45
|
+
when :flat
|
46
|
+
xml = @@out
|
47
|
+
else
|
48
|
+
end
|
49
|
+
|
50
|
+
@@out = ""
|
51
|
+
xml
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.method_missing name, *args, &block
|
55
|
+
define_tags name
|
56
|
+
method(name).call args, &block
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def self.parameterize hash
|
62
|
+
return "" unless hash.is_a? Hash
|
63
|
+
hash.inject("") do |memo, entry|
|
64
|
+
memo += " #{entry.first.to_s}=\"#{entry.last.to_s}\""
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Appends:
|
69
|
+
#
|
70
|
+
# <?xml version="1.0" encoding="UTF-8" ?>
|
71
|
+
#
|
72
|
+
# To the resulting XML file.
|
73
|
+
def self.xml_header options = {}
|
74
|
+
options[:version] = "1.0" unless options[:version]
|
75
|
+
options[:encoding] = "UTF-8" unless options[:encoding]
|
76
|
+
@@out << "<?xml #{parameterize(options)} ?>"
|
77
|
+
end
|
78
|
+
|
79
|
+
# Appends:
|
80
|
+
#
|
81
|
+
# <!DOCTYPE html>
|
82
|
+
#
|
83
|
+
# To the resulting XML file.
|
84
|
+
def self.html5_doctype
|
85
|
+
@@out << '<!DOCTYPE html>'
|
86
|
+
end
|
87
|
+
end
|
data/spec/case/1.rb
ADDED
data/spec/case/2.rb
ADDED
data/spec/case/3.rb
ADDED
data/spec/case/4.rb
ADDED
data/spec/case/5.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
Timl.start :pretty do
|
2
|
+
html do
|
3
|
+
head do
|
4
|
+
script do
|
5
|
+
"alert('Wassup!');"
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
body do
|
10
|
+
table do
|
11
|
+
tr do
|
12
|
+
th { "Key" }
|
13
|
+
th { "Value" }
|
14
|
+
end
|
15
|
+
|
16
|
+
tr do
|
17
|
+
td { "Foo" }
|
18
|
+
td { "Bar" }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/spec/result/1.xml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
<h1>Simple test!</h1>
|
data/spec/result/2.xml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
<div><h1>Slightly more complex.</h1><h2>Example.</h2></div>
|
data/spec/result/3.xml
ADDED
data/spec/result/4.xml
ADDED
data/spec/result/5.xml
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<script>
|
4
|
+
alert('Wassup!');
|
5
|
+
</script>
|
6
|
+
</head>
|
7
|
+
<body>
|
8
|
+
<table>
|
9
|
+
<tr>
|
10
|
+
<th>
|
11
|
+
Key
|
12
|
+
</th>
|
13
|
+
<th>
|
14
|
+
Value
|
15
|
+
</th>
|
16
|
+
</tr>
|
17
|
+
<tr>
|
18
|
+
<td>
|
19
|
+
Foo
|
20
|
+
</td>
|
21
|
+
<td>
|
22
|
+
Bar
|
23
|
+
</td>
|
24
|
+
</tr>
|
25
|
+
</table>
|
26
|
+
</body>
|
27
|
+
</html>
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../lib/timl'
|
2
|
+
|
3
|
+
module Timl
|
4
|
+
CASEDIR = SPECDIR + '/case'
|
5
|
+
RESULTDIR = SPECDIR + '/result'
|
6
|
+
|
7
|
+
CASES = Dir["#{CASEDIR}/*"].sort
|
8
|
+
RESULTS = Dir["#{RESULTDIR}/*"].sort
|
9
|
+
|
10
|
+
# Zip cases and results together in an array of arrays.
|
11
|
+
TESTPAIRS = CASES.zip(RESULTS)
|
12
|
+
end
|
data/spec/timl_spec.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Timl" do
|
4
|
+
it "should pass all examples cases in spec/case" do
|
5
|
+
Timl::TESTPAIRS.each do |pair|
|
6
|
+
test_case, result = pair
|
7
|
+
|
8
|
+
# Check that the eval'd test case is the same as the result content for
|
9
|
+
# each test pair. A test pair is a pair of numbered files from the
|
10
|
+
# spec/case and spec/result directories.
|
11
|
+
#
|
12
|
+
# The last File.read(result) has a .chomp because the File.read adds a
|
13
|
+
# newline to the end of a file for some reason.
|
14
|
+
eval(File.read(test_case)).should == File.read(result).chomp
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/timl.gemspec
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/lib/timl'
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{timl}
|
5
|
+
s.version = Timl::VERSION
|
6
|
+
s.authors = ["Sam Rose"]
|
7
|
+
s.email = %q{samwho@lbak.co.uk}
|
8
|
+
s.summary = %q{A Tiny XML building library, akin to builder.}
|
9
|
+
s.homepage = %q{http://github.com/samwho/timl}
|
10
|
+
s.description = %q{Similar to builder, Timl provides a DSL for creating XML.}
|
11
|
+
s.required_ruby_version = '>= 1.9.2'
|
12
|
+
s.license = 'MIT'
|
13
|
+
|
14
|
+
# Add all files in git to the files parameter.
|
15
|
+
s.files = `git ls-files`.split /\n/
|
16
|
+
end
|
metadata
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: timl
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.1'
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Sam Rose
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-07-03 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Similar to builder, Timl provides a DSL for creating XML.
|
15
|
+
email: samwho@lbak.co.uk
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- .gitignore
|
21
|
+
- .travis.yml
|
22
|
+
- Gemfile
|
23
|
+
- Gemfile.lock
|
24
|
+
- README.md
|
25
|
+
- Rakefile
|
26
|
+
- lib/timl.rb
|
27
|
+
- lib/timl/timl.rb
|
28
|
+
- spec/case/1.rb
|
29
|
+
- spec/case/2.rb
|
30
|
+
- spec/case/3.rb
|
31
|
+
- spec/case/4.rb
|
32
|
+
- spec/case/5.rb
|
33
|
+
- spec/result/1.xml
|
34
|
+
- spec/result/2.xml
|
35
|
+
- spec/result/3.xml
|
36
|
+
- spec/result/4.xml
|
37
|
+
- spec/result/5.xml
|
38
|
+
- spec/spec_helper.rb
|
39
|
+
- spec/timl_spec.rb
|
40
|
+
- timl.gemspec
|
41
|
+
homepage: http://github.com/samwho/timl
|
42
|
+
licenses:
|
43
|
+
- MIT
|
44
|
+
post_install_message:
|
45
|
+
rdoc_options: []
|
46
|
+
require_paths:
|
47
|
+
- lib
|
48
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 1.9.2
|
54
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ! '>='
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '0'
|
60
|
+
requirements: []
|
61
|
+
rubyforge_project:
|
62
|
+
rubygems_version: 1.8.24
|
63
|
+
signing_key:
|
64
|
+
specification_version: 3
|
65
|
+
summary: A Tiny XML building library, akin to builder.
|
66
|
+
test_files: []
|