huml 0.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c226fb793dde84c7b77e8471bf67da803940ed78
4
+ data.tar.gz: a4c0c772b4f03f9f6a34d35cf28c037553314c82
5
+ SHA512:
6
+ metadata.gz: d50a2ecc4b9cd32dd2d0f11fa4e38fe7e13b07d69a23a39c43fddfe613e21adb11cd1571a504d72d9366095cea28aace224c3723c143a50684099851bcde7f5c
7
+ data.tar.gz: 4b5e1c96db2ae6ea90917a797900ed1b451c719c083e5e832360c10e004c6b4522669cd9d01b23099fa04654a15ac046edcb738c7dc33fc0ed0230629326a395
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ doc
2
+ *.swp
3
+ *.swo
4
+ .rspec
5
+ *.huml
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,36 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ huml (0.0.1)
5
+ temple
6
+ treetop
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ diff-lcs (1.2.5)
12
+ polyglot (0.3.5)
13
+ rake (10.2.2)
14
+ rspec (3.0.0)
15
+ rspec-core (~> 3.0.0)
16
+ rspec-expectations (~> 3.0.0)
17
+ rspec-mocks (~> 3.0.0)
18
+ rspec-core (3.0.0)
19
+ rspec-support (~> 3.0.0)
20
+ rspec-expectations (3.0.0)
21
+ diff-lcs (>= 1.2.0, < 2.0)
22
+ rspec-support (~> 3.0.0)
23
+ rspec-mocks (3.0.1)
24
+ rspec-support (~> 3.0.0)
25
+ rspec-support (3.0.0)
26
+ temple (0.6.7)
27
+ treetop (1.5.3)
28
+ polyglot (~> 0.3)
29
+
30
+ PLATFORMS
31
+ ruby
32
+
33
+ DEPENDENCIES
34
+ huml!
35
+ rake
36
+ rspec
data/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # Huml
2
+
3
+ Huml is a template engine derived from [Haml](github.com/haml/haml).
4
+ Like the relationship between Sass and Scss, Huml uses braces for nesting structure
5
+ when Haml uses indentations.
6
+
7
+ ## Formatting
8
+
9
+ doctype 5
10
+ %html {
11
+
12
+ %head {
13
+ %script(type="text/javascript" src="app.js")
14
+ %link(rel="stylesheet" type="text/css" media="all")
15
+ }
16
+
17
+ %body {
18
+ %div.container {
19
+ %h3.header = "page header"
20
+ %p(style="background-color: #fff;") = "Lorem Ipsum is simply dummy text of the printing and typesetting industry."
21
+ }
22
+ }
23
+
24
+ }
25
+
26
+ ## License
27
+
28
+ MIT (X11) License 2014 shelling
data/Rakefile ADDED
@@ -0,0 +1,5 @@
1
+ require "rspec/core/rake_task"
2
+
3
+ RSpec::Core::RakeTask.new(:spec)
4
+
5
+ task default: :spec
data/bin/huml ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require 'huml'
3
+
4
+ puts eval(Huml::Engine.new.call(File.open(ARGV[0]).read))
data/huml.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.dirname(__FILE__) + "/lib/huml/version"
3
+ require "date"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'huml'
7
+ s.version = Huml::VERSION
8
+ s.date = Date.today.to_s
9
+
10
+ s.authors = ['shelling']
11
+ s.email = ['navyblueshellingford@gmail.com']
12
+ s.homepage = 'https://github.com/shelling/huml'
13
+ s.description = 'Huml is to Haml what Scss is to Sass'
14
+ s.summary = 'Huml'
15
+
16
+ s.require_paths = ['lib']
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.license = 'MIT'
21
+
22
+ s.add_runtime_dependency 'temple'
23
+ s.add_runtime_dependency 'treetop'
24
+
25
+ s.add_development_dependency 'rspec'
26
+ s.add_development_dependency 'rake'
27
+ end
data/lib/huml.rb ADDED
@@ -0,0 +1,95 @@
1
+ module Huml
2
+ require "huml/version"
3
+ require "treetop"
4
+ require "huml/parser"
5
+ autoload :Engine, "huml/engine"
6
+
7
+ class Parser < Treetop::Runtime::CompiledParser
8
+ include Huml
9
+
10
+ def initialize(options = {})
11
+ super()
12
+ end
13
+
14
+ def call(string)
15
+ if result = parse(string)
16
+ result.tokenize
17
+ else
18
+ raise Exception, self.failure_reason
19
+ end
20
+ end
21
+ end
22
+
23
+ class Top < Treetop::Runtime::SyntaxNode
24
+ def tokenize
25
+ [:multi].push(doctype.empty? ? [:multi] : doctype.tokenize)
26
+ .concat( html.empty? ? [[:multi]] : html.tokenize )
27
+ end
28
+ end
29
+
30
+ class Block < Treetop::Runtime::SyntaxNode
31
+ def tokenize
32
+ [:html, :tag, name.text_value.to_sym,
33
+ [:html, :attrs].concat(selector_list.tokenize).concat(attributes.empty? ? [] : attributes.tokenize),
34
+ [:multi].concat(html.empty? ? [] : html.tokenize)]
35
+ end
36
+ end
37
+
38
+ class Assignment < Treetop::Runtime::SyntaxNode
39
+ def tokenize
40
+ [:html, :tag, name.text_value.to_sym,
41
+ [:html, :attrs].concat(selector_list.tokenize).concat(attributes.empty? ? [] : attributes.tokenize),
42
+ string.tokenize]
43
+ end
44
+ end
45
+
46
+ class Atom < Treetop::Runtime::SyntaxNode
47
+ def tokenize
48
+ [:html, :tag, name.text_value.to_sym,
49
+ [:html, :attrs].concat(selector_list.tokenize).concat(attributes.empty? ? [] : attributes.tokenize)]
50
+ end
51
+ end
52
+
53
+ class HTML < Treetop::Runtime::SyntaxNode
54
+ def tokenize
55
+ elements.map { |e| e.tokenize }
56
+ end
57
+ end
58
+
59
+ class Doctype < Treetop::Runtime::SyntaxNode
60
+ def tokenize
61
+ [:html, :doctype, typestring.text_value]
62
+ end
63
+ end
64
+
65
+ class SelectorList < Treetop::Runtime::SyntaxNode
66
+ TYPES = { "." => :class, "#" => :id }
67
+ def tokenize
68
+ elements.map { |e| [:html, :attr, TYPES[e.type.text_value], [:static, e.name.text_value]] }
69
+ end
70
+ end
71
+
72
+ class Attributes < Treetop::Runtime::SyntaxNode
73
+ def tokenize
74
+ pairs.elements.map(&:tokenize)
75
+ end
76
+ end
77
+
78
+ class Pair < Treetop::Runtime::SyntaxNode
79
+ def tokenize
80
+ [:html, :attr, attr.text_value.to_sym, value.tokenize]
81
+ end
82
+ end
83
+
84
+ class Space < Treetop::Runtime::SyntaxNode
85
+ def tokenize
86
+ [:newline] if text_value =~ /[\r\n]/
87
+ end
88
+ end
89
+
90
+ class String < Treetop::Runtime::SyntaxNode
91
+ def tokenize
92
+ [:static, literal.text_value]
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,15 @@
1
+ require "temple"
2
+
3
+ module Huml
4
+ class Engine < ::Temple::Engine
5
+ use Huml::Parser
6
+ use Temple::HTML::AttributeMerger
7
+ use Temple::HTML::AttributeRemover
8
+ use Temple::HTML::Pretty
9
+ filter :ControlFlow
10
+ filter :StaticMerger
11
+ filter :DynamicInliner
12
+ generator :ArrayBuffer
13
+ end
14
+ end
15
+
@@ -0,0 +1,45 @@
1
+ grammar Huml
2
+
3
+ rule top
4
+ space doctype:doctype? space html <Top>
5
+ end
6
+
7
+ rule block
8
+ '%' name:[a-zA-Z0-9]+ selector_list attributes:attributes? space '{' space html space '}' space <Block>
9
+ /
10
+ '%' name:[a-zA-Z0-9]+ selector_list attributes:attributes? space '=' space string space <Assignment>
11
+ /
12
+ '%' name:[a-zA-Z0-9]+ selector_list attributes:attributes? space <Atom>
13
+ end
14
+
15
+ rule doctype
16
+ "doctype " [ \t]* typestring:([a-zA-Z0-9]*) <Doctype>
17
+ end
18
+
19
+ rule selector_list
20
+ (type:[.#] name:[a-zA-Z0-9-]+)* <SelectorList>
21
+ end
22
+
23
+ rule attributes
24
+ '(' space pairs:pair* ')' <Attributes>
25
+ end
26
+
27
+ rule pair
28
+ attr:([a-zA-Z0-9]+) space '=' space value:string space <Pair>
29
+ end
30
+
31
+ rule space
32
+ [\s]* <Space>
33
+ end
34
+
35
+ rule html
36
+ block* <HTML>
37
+ end
38
+
39
+ rule string
40
+ '"' literal:([a-zA-Z0-9_!@#$%:;/\-\s\.]*) '"' <String>
41
+ /
42
+ "'" literal:([a-zA-Z0-9_!@#$%:;/\-\s\.]*) "'" <String>
43
+ end
44
+
45
+ end
@@ -0,0 +1,3 @@
1
+ module Huml
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,13 @@
1
+ require "spec_helper"
2
+
3
+ describe Huml::Engine do
4
+ subject { Huml::Engine.new }
5
+
6
+ it "outputs basic html structure" do
7
+ expect(eval(subject.call("doctype 5\n %html { }"))).to eq("<!DOCTYPE html>\n<html></html>")
8
+ end
9
+
10
+ it "outputs a divider with its content" do
11
+ expect(eval(subject.call("%div = 'content'"))).to eq("<div>\n content\n</div>")
12
+ end
13
+ end
@@ -0,0 +1,119 @@
1
+ require "spec_helper"
2
+
3
+ describe Huml::Parser do
4
+ subject { Huml::Parser.new }
5
+
6
+ it "allows blank document" do
7
+ expect(subject.parse(" ").tokenize).to eq([:multi, [:multi], [:multi]])
8
+ end
9
+
10
+ it "can recognize space" do
11
+ expect(subject.parse("\r", root: :space).tokenize).to eq([:newline])
12
+ expect(subject.parse("\n", root: :space).tokenize).to eq([:newline])
13
+ expect(subject.parse(" ", root: :space).tokenize).to eq(nil)
14
+ expect(subject.parse("\t", root: :space).tokenize).to eq(nil)
15
+ expect(subject.parse(" \t", root: :space).tokenize).to eq(nil)
16
+ expect(subject.parse(" \t\n\r", root: :space).tokenize).to eq([:newline])
17
+ end
18
+
19
+ it "can recognize doctype" do
20
+ expect(subject.parse("doctype 5", root: :doctype).tokenize).to eq([:html, :doctype, "5"])
21
+ expect(subject.parse(" doctype 5 ").tokenize).to eq([:multi, [:html, :doctype, "5"], [:multi]])
22
+ end
23
+
24
+ it "can recognize block" do
25
+ expect(subject.parse("%div {}", root: :block).tokenize).to eq([:html, :tag, :div, [:html, :attrs], [:multi]])
26
+ expect(subject.parse("%div {}").tokenize).to eq([:multi, [:multi], [:html, :tag, :div, [:html, :attrs], [:multi]]])
27
+ expect(subject.parse("%div {} %div {}", root: :html).tokenize).to eq([[:html, :tag, :div, [:html, :attrs], [:multi]],
28
+ [:html, :tag, :div, [:html, :attrs], [:multi]]])
29
+ expect(subject.parse("%div {} %div {}").tokenize).to eq([:multi, [:multi],
30
+ [:html, :tag, :div, [:html, :attrs], [:multi]],
31
+ [:html, :tag, :div, [:html, :attrs], [:multi]]])
32
+ end
33
+
34
+ it "recognizes blocks inside a block" do
35
+ expect(subject.parse("%div { %p {} %p {} }", root: :block).tokenize).to eq([:html, :tag, :div,
36
+ [:html, :attrs],
37
+ [:multi,
38
+ [:html, :tag, :p, [:html, :attrs], [:multi]],
39
+ [:html, :tag, :p, [:html, :attrs], [:multi]] ]])
40
+ end
41
+
42
+ it "recognizes css class list" do
43
+ expect(subject.parse(".foo", root: :selector_list).tokenize).to eq([[:html, :attr, :class, [:static, "foo"]]])
44
+ expect(subject.parse(".foo.bar.baz", root: :selector_list).tokenize).to eq([[:html, :attr, :class, [:static, "foo"]],
45
+ [:html, :attr, :class, [:static, "bar"]],
46
+ [:html, :attr, :class, [:static, "baz"]]])
47
+ end
48
+
49
+ it "recognizes css id list" do
50
+ expect(subject.parse("#foo", root: :selector_list).tokenize).to eq([[:html, :attr, :id, [:static, "foo"]]])
51
+ end
52
+
53
+ it "recognizes id and class list" do
54
+ expect(subject.parse(".foo#bar", root: :selector_list).tokenize).to eq([[:html, :attr, :class, [:static, "foo"]],
55
+ [:html, :attr, :id, [:static, "bar"]]])
56
+ end
57
+
58
+ it "recognizes a block with selectors" do
59
+ expect(subject.parse("%div.foo#bar {}", root: :block).tokenize).to eq([:html, :tag, :div,
60
+ [:html, :attrs,
61
+ [:html, :attr, :class, [:static, "foo"]],
62
+ [:html, :attr, :id , [:static, "bar"]]],
63
+ [:multi]])
64
+ end
65
+
66
+ it "recognizes a literal string" do
67
+ expect(subject.parse('"hello world"', root: :string).tokenize).to eq([:static, "hello world"])
68
+ expect(subject.parse("'hello world'", root: :string).tokenize).to eq([:static, "hello world"])
69
+ end
70
+
71
+ it "recognizes string composed of characters with hyphen" do
72
+ expect(subject.parse('"col-xs-6"', root: :string).tokenize).to eq([:static, "col-xs-6"])
73
+ end
74
+
75
+ it "recognizes string composed of characters with underscore" do
76
+ expect(subject.parse('"foo_bar"', root: :string).tokenize).to eq([:static, "foo_bar"])
77
+ end
78
+
79
+ it "recognizes a fragment of css" do
80
+ expect(subject.parse('"background-color: #fff;"'))
81
+ end
82
+
83
+ it "recognizes a block containing a string" do
84
+ expect(subject.parse('%div = "string here"', root: :block).tokenize).to eq([:html, :tag, :div, [:html, :attrs], [:static, "string here"]])
85
+ end
86
+
87
+ it "recognizes a pair" do
88
+ expect(subject.parse('src = "foo.png"', root: :pair).tokenize).to eq([:html, :attr, :src, [:static, "foo.png"]])
89
+ end
90
+
91
+ it "recognizes attributes" do
92
+ expect(subject.parse('( src = "foo.png" alt = "foo image" )', root: :attributes).tokenize).to eq([[:html, :attr, :src, [:static, "foo.png"]], [:html, :attr, :alt, [:static, "foo image"]]])
93
+ end
94
+
95
+ it "recognizes a block with attributes" do
96
+ expect(subject.parse('%div(class="foo") {}', root: :block).tokenize).to eq([:html, :tag, :div, [:html, :attrs, [:html, :attr, :class, [:static, "foo"]]], [:multi]])
97
+ end
98
+
99
+ it "recognizes a assignment with attributes" do
100
+ expect(subject.parse('%div(class="foo") = "string here"', root: :block).tokenize).to eq([:html, :tag, :div, [:html, :attrs, [:html, :attr, :class, [:static, "foo"]]], [:static, "string here"]])
101
+ end
102
+
103
+ it "recognizes a atomic element" do
104
+ expect(subject.parse('%div', root: :block).tokenize).to eq([:html, :tag, :div, [:html, :attrs]])
105
+ expect(subject.parse('%div()', root: :block).tokenize).to eq([:html, :tag, :div, [:html, :attrs]])
106
+ expect(subject.parse('%div(class="foo")', root: :block).tokenize).to eq([:html, :tag, :div,
107
+ [:html, :attrs,
108
+ [:html, :attr, :class, [:static, "foo"]]]])
109
+ expect(subject.parse('%div.foo#bar(role="sidebar")', root: :block).tokenize).to eq([:html, :tag, :div,
110
+ [:html, :attrs,
111
+ [:html, :attr, :class, [:static, "foo"]],
112
+ [:html, :attr, :id, [:static, "bar"]],
113
+ [:html, :attr, :role, [:static, "sidebar"]]]])
114
+ end
115
+
116
+ it "recognizes multiple atomic elements" do
117
+ expect(subject.parse("%div()\n%div()", root: :html).tokenize).to eq([[:html, :tag, :div, [:html, :attrs]], [:html, :tag, :div, [:html, :attrs]]])
118
+ end
119
+ end
@@ -0,0 +1,5 @@
1
+ require 'huml'
2
+
3
+ RSpec.configure do |config|
4
+ config.order = "random"
5
+ end
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: huml
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - shelling
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-07-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: temple
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
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: treetop
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
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: rspec
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: rake
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
+ description: Huml is to Haml what Scss is to Sass
70
+ email:
71
+ - navyblueshellingford@gmail.com
72
+ executables:
73
+ - huml
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - .gitignore
78
+ - Gemfile
79
+ - Gemfile.lock
80
+ - README.md
81
+ - Rakefile
82
+ - bin/huml
83
+ - examples/simple.huml
84
+ - huml.gemspec
85
+ - lib/huml.rb
86
+ - lib/huml/engine.rb
87
+ - lib/huml/parser.treetop
88
+ - lib/huml/version.rb
89
+ - spec/huml/engine_spec.rb
90
+ - spec/huml/parser_spec.rb
91
+ - spec/spec_helper.rb
92
+ homepage: https://github.com/shelling/huml
93
+ licenses:
94
+ - MIT
95
+ metadata: {}
96
+ post_install_message:
97
+ rdoc_options: []
98
+ require_paths:
99
+ - lib
100
+ required_ruby_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ requirements: []
111
+ rubyforge_project:
112
+ rubygems_version: 2.2.2
113
+ signing_key:
114
+ specification_version: 4
115
+ summary: Huml
116
+ test_files:
117
+ - spec/huml/engine_spec.rb
118
+ - spec/huml/parser_spec.rb
119
+ - spec/spec_helper.rb