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 ADDED
@@ -0,0 +1,2 @@
1
+ .session.vim
2
+ .rvmrc
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ rvm:
2
+ - 1.9.3
3
+ - 1.9.2
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source :rubygems
2
+
3
+ group :development do
4
+ gem 'rspec'
5
+ gem 'rake'
6
+ end
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: [![Build Status](https://secure.travis-ci.org/samwho/timl.png?branch=develop)](http://travis-ci.org/samwho/timl)
12
+
13
+ Master: [![Build Status](https://secure.travis-ci.org/samwho/timl.png?branch=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
@@ -0,0 +1,8 @@
1
+ require 'rspec/core/rake_task'
2
+
3
+ task :default => 'test'
4
+
5
+ desc "Run tests"
6
+ RSpec::Core::RakeTask.new(:test) do |t|
7
+ t.rspec_opts = '-cfs'
8
+ end
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
@@ -0,0 +1,3 @@
1
+ Timl.start :flat do
2
+ h1 { "Simple test!" }
3
+ end
data/spec/case/2.rb ADDED
@@ -0,0 +1,6 @@
1
+ Timl.start :flat do
2
+ div do
3
+ h1 { "Slightly more complex." }
4
+ h2 { "Example." }
5
+ end
6
+ end
data/spec/case/3.rb ADDED
@@ -0,0 +1,5 @@
1
+ Timl.start :pretty do
2
+ div do
3
+ p { "This should be pretty." }
4
+ end
5
+ end
data/spec/case/4.rb ADDED
@@ -0,0 +1,11 @@
1
+ Timl.start :pretty do
2
+ div id: "content" do
3
+ p class: "bold" do
4
+ "Attributes, anyone?"
5
+ end
6
+
7
+ p do
8
+ "And another paragraph for fun."
9
+ end
10
+ end
11
+ end
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
@@ -0,0 +1,5 @@
1
+ <div>
2
+ <p>
3
+ This should be pretty.
4
+ </p>
5
+ </div>
data/spec/result/4.xml ADDED
@@ -0,0 +1,8 @@
1
+ <div id='content'>
2
+ <p class='bold'>
3
+ Attributes, anyone?
4
+ </p>
5
+ <p>
6
+ And another paragraph for fun.
7
+ </p>
8
+ </div>
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>
@@ -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: []