hoshi 1.0.3 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README +36 -35
- data/Rakefile +3 -4
- data/doc/LICENSE +1 -1
- data/doc/TODO +23 -9
- data/doc/examples/blocks.rb +1 -1
- data/lib/hoshi.rb +1 -1
- data/lib/hoshi/monkey_patches.rb +8 -2
- data/lib/hoshi/view.rb +20 -4
- data/lib/hoshi/view/svg.rb +47 -0
- metadata +5 -19
- data/lib/hoshi/view-tag.rb +0 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ca598007027aa97210dfa948d34d79b3a1d9d533
|
4
|
+
data.tar.gz: 66e539e52fd1d0cf65e10a6b17447bda15b1b926
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c52c4c1f843a6bde06813bc637de617c7613b89445c23b252ff242e99f1744f8a76714996949fe1805e54024b893fb85523f05cc094ad8af18dbfd376c327022
|
7
|
+
data.tar.gz: e0c86d605ebee271e95b71d9b1f7c09812181ced4a3fe60c69d2417920a195d30dc3031953ca1c642dce1fc64f4091f7b5490b9dc88a5963b4c87cafc993b23d
|
data/README
CHANGED
@@ -2,22 +2,27 @@
|
|
2
2
|
|
3
3
|
== Summary
|
4
4
|
|
5
|
-
Hoshi is a library for creating real, first-class HTML/XML views.
|
6
|
-
unlike template libraries, you can take advantage of mixins,
|
7
|
-
inheritance, and all the other wonderful features of Ruby's object
|
8
|
-
|
5
|
+
Hoshi is a library for creating real, first-class HTML/XML views. It is a
|
6
|
+
generator, so unlike template libraries, you can take advantage of mixins,
|
7
|
+
inheritance, and all the other wonderful features of Ruby's object system.
|
8
|
+
|
9
|
+
In addition to HTML5 and plain XML, Hoshi supports RSS2 and SVG, as well as some
|
10
|
+
older standards like HTML4 and XHTML1. (If you need anything more specific, it
|
11
|
+
is easy to extend, and if you want to contribute, patches are welcome.)
|
9
12
|
|
10
13
|
Hoshi is designed to:
|
11
|
-
* Generate clean HTML/
|
12
|
-
* Be
|
14
|
+
* Generate clean HTML/XML with minimal effort
|
15
|
+
* Be simple, to avoid bugs and keep it easy to use, understand, and modify
|
13
16
|
* Take full advantage of Ruby's object sytem
|
14
17
|
* Be more readable and easier to write than bare HTML
|
15
18
|
|
16
|
-
It
|
17
|
-
implementation
|
18
|
-
inside
|
19
|
+
It was initially inspired by (and partially modeled on) Markaby, but the
|
20
|
+
implementation is more straightforward so the semantics are cleaner (e.g., no
|
21
|
+
instance_eval, meaning scope inside blocks supplied to tags has no gotcha's).
|
19
22
|
|
20
|
-
See doc/LICENSE for the license, doc/examples for examples.
|
23
|
+
See doc/LICENSE for the license, doc/examples for examples. See test/ for the
|
24
|
+
tests, and run `rake test` to execute them. (The tests take a fraction of a
|
25
|
+
second to execute.)
|
21
26
|
|
22
27
|
== Installation
|
23
28
|
|
@@ -29,7 +34,7 @@ or by downloading from github (http://github.com/pete/hoshi).
|
|
29
34
|
|
30
35
|
== Usage
|
31
36
|
|
32
|
-
These examples
|
37
|
+
These examples
|
33
38
|
Also, there is a program included called html2hoshi (and associated
|
34
39
|
lib/html2hoshi.rb; see Hoshi.from_html) that takes HTML as input and
|
35
40
|
converts it to Ruby code using Hoshi.
|
@@ -46,7 +51,7 @@ These should be fairly straightforward:
|
|
46
51
|
html {
|
47
52
|
head {
|
48
53
|
title "Hello, world!"
|
49
|
-
link :
|
54
|
+
link rel: 'stylesheet', href: '/css/hoshi.css'
|
50
55
|
}
|
51
56
|
|
52
57
|
body {
|
@@ -71,13 +76,13 @@ You can get a little more complicated:
|
|
71
76
|
html {
|
72
77
|
head {
|
73
78
|
title t
|
74
|
-
script(:
|
79
|
+
script(type: 'text/javascript') {
|
75
80
|
raw "alert(\"Hi, I'm some javascript, I suppose.\");"
|
76
81
|
}
|
77
82
|
}
|
78
83
|
|
79
84
|
body {
|
80
|
-
h1 t, :
|
85
|
+
h1 t, class: 'page_title'
|
81
86
|
|
82
87
|
yield
|
83
88
|
}
|
@@ -93,7 +98,6 @@ You can get a little more complicated:
|
|
93
98
|
end
|
94
99
|
end
|
95
100
|
|
96
|
-
|
97
101
|
class Fibonacci < Hoshi::View :xhtml1
|
98
102
|
include Layout
|
99
103
|
|
@@ -126,7 +130,8 @@ You can get a little more complicated:
|
|
126
130
|
|
127
131
|
=== Block-based
|
128
132
|
|
129
|
-
For simpler cases where you
|
133
|
+
For simpler cases where you just need to produce a little markup. Useful for
|
134
|
+
small scripts.
|
130
135
|
|
131
136
|
require 'hoshi'
|
132
137
|
|
@@ -135,7 +140,7 @@ For simpler cases where you only intend to produce markup, perhaps for use as a
|
|
135
140
|
html {
|
136
141
|
head {
|
137
142
|
title "Hello, world!"
|
138
|
-
link :
|
143
|
+
link rel: 'stylesheet', href: '/css/hoshi.css'
|
139
144
|
}
|
140
145
|
|
141
146
|
body {
|
@@ -149,37 +154,33 @@ For simpler cases where you only intend to produce markup, perhaps for use as a
|
|
149
154
|
|
150
155
|
== Bugs
|
151
156
|
|
152
|
-
There needs to be some work done on correcting the tags; I suspect I'm
|
153
|
-
|
154
|
-
|
155
|
-
I'd like to perhaps add a layer for serializing objects in the standard
|
156
|
-
HTML5 method (i.e., the Schema.org/microdata stuff). That's very
|
157
|
-
speculative at the moment.
|
157
|
+
There needs to be some work done on correcting the tags; I suspect I'm missing
|
158
|
+
or miscategorizing some of them. If you come across a case where Hoshi emits
|
159
|
+
invalid HTML/XML/etc., please let me know.
|
158
160
|
|
159
|
-
|
160
|
-
|
161
|
-
could use cleanup. Hash is monkey-patched, and using the new Ruby 2
|
162
|
-
refinements feature would be nicer.
|
161
|
+
That's the only known bug likely to affect you. See doc/TODO for a more
|
162
|
+
detailed roadmap.
|
163
163
|
|
164
164
|
== Credits
|
165
165
|
|
166
166
|
Author:
|
167
|
-
Pete Elmore -- (pete(a)debu.gs)
|
167
|
+
Pete Elmore, Rekka Labs -- ( pete(a)debu.gs )
|
168
168
|
|
169
|
-
|
169
|
+
The initial design is pretty heavily indebted to:
|
170
170
|
_why the lucky stiff's Markaby library
|
171
171
|
|
172
|
-
Initial design discussion:
|
173
|
-
Dan Yoder
|
174
|
-
|
175
172
|
Simple block version:
|
176
173
|
Nolan Darilek -- (nolan(a)thewordnerd.info)
|
177
174
|
|
178
|
-
|
179
|
-
Lars Lethonen
|
175
|
+
Friends that have reported bugs:
|
176
|
+
Lars Lethonen, opsangeles -- ( http://opsangeles.com/ )
|
177
|
+
Hunter, Spore Labs -- ( https://github.com/madhermit )
|
180
178
|
|
181
179
|
The guys that paid me to do the initial version:
|
182
|
-
AT&T Interactive.
|
180
|
+
AT&T Interactive. (Now yp.com; they have changed names and owners.)
|
181
|
+
|
182
|
+
The company that covers development now:
|
183
|
+
Rekka Labs -- http://rekka.io/ (Yes, you can hire us.)
|
183
184
|
|
184
185
|
Also, I guess I should credit Attractive Eighties Women
|
185
186
|
(http://attractiveeightieswomen.com/), since I was blasting them the
|
data/Rakefile
CHANGED
@@ -16,11 +16,10 @@ spec = Gem::Specification.new { |s|
|
|
16
16
|
Dir['bin/*'].map(&File.method(:basename)).map(&s.executables.method(:<<))
|
17
17
|
|
18
18
|
s.name = 'hoshi'
|
19
|
-
s.rubyforge_project = 'hoshi-view'
|
20
19
|
s.summary = "Nice, object-oriented, first-class views."
|
21
20
|
s.homepage = "http://debu.gs/#{s.name}"
|
22
|
-
%w(
|
23
|
-
s.version = '1.
|
21
|
+
%w(hpricot).each &s.method(:add_dependency)
|
22
|
+
s.version = '1.1.1'
|
24
23
|
}
|
25
24
|
|
26
25
|
Gem::PackageTask.new(spec) { |pkg|
|
@@ -29,7 +28,7 @@ Gem::PackageTask.new(spec) { |pkg|
|
|
29
28
|
|
30
29
|
task(:install => :package) {
|
31
30
|
g = "pkg/#{spec.name}-#{spec.version}.gem"
|
32
|
-
system "
|
31
|
+
system "gem install -l #{g}"
|
33
32
|
}
|
34
33
|
|
35
34
|
task(:test) {
|
data/doc/LICENSE
CHANGED
data/doc/TODO
CHANGED
@@ -1,10 +1,24 @@
|
|
1
|
-
TODO
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
TODO:
|
2
|
+
· Still not too happy about the way RSS feeds are done, going to rework.
|
3
|
+
· I do not use Atom as often as I use RSS, but Atom support would be nice.
|
4
|
+
· html2hoshi should move to its own gem.
|
5
|
+
· Fix some of the heuristics, default to safe() rather than raw() more often.
|
6
|
+
This is based on usage, but it breaks compatibility, so it'll require
|
7
|
+
some caution. (Possibly make it configurable or part of blocks' state.)
|
5
8
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
Ongoing:
|
10
|
+
· Separate the tags by close type in the various View sub-classes. (The most
|
11
|
+
tedious thing on the list, but required for compliance.) My current strategy
|
12
|
+
is to run things through validator.w3c.org and whenever it complains, I change
|
13
|
+
the tag. Most of the HTML I do nowadays is HTML5, so the older versions of
|
14
|
+
HTML no longer get checked very often.
|
15
|
+
|
16
|
+
Speculative (i.e., these may be bad ideas and they might not ever get done):
|
17
|
+
· HTML5 microdata serialization using Schema.org conventions. This should
|
18
|
+
work as easily as JSON serialization in a perfect world.
|
19
|
+
· Possibly add some higher-level patterns for Bootstrap/Foundation/etc.
|
20
|
+
Ideally, they end up presenting the same API, so changing a parent class
|
21
|
+
or a mixin is all that is needed to change frameworks.
|
22
|
+
· Integrate HTML validation into the tests, and make some validation tests.
|
23
|
+
· Expanding the DSL for views. There are not a lot of things I've missed in
|
24
|
+
the API so far, though, and the special-cased things are largely unused.
|
data/doc/examples/blocks.rb
CHANGED
data/lib/hoshi.rb
CHANGED
@@ -4,7 +4,7 @@ require 'hoshi/tag'
|
|
4
4
|
require 'hoshi/view'
|
5
5
|
|
6
6
|
# This is the namespace for all of Hoshi, which currently only includes
|
7
|
-
# Hoshi::View and Hoshi::Tag . For an overview, see
|
7
|
+
# Hoshi::View and Hoshi::Tag . For an overview, see the README. For
|
8
8
|
# specifics, check out Hoshi::View .
|
9
9
|
module Hoshi
|
10
10
|
# This is a cosmetic method; you may do Hoshi::View[:type],
|
data/lib/hoshi/monkey_patches.rb
CHANGED
@@ -1,14 +1,20 @@
|
|
1
|
-
# TODO:
|
1
|
+
# TODO: When 1.9 goes away, this monkey-patch should be changed to refinements, or
|
2
|
+
# just moved into a private instance method for Hoshi::Tag.
|
2
3
|
# See: http://blog.headius.com/2012/11/refining-ruby.html
|
3
4
|
|
4
5
|
class Hash
|
5
6
|
# Makes this hash fit to be put into a tag.
|
6
|
-
#
|
7
|
+
# {a: 1, b: "two", c: true, d: false}.to_html_options # => 'a="one" b="two" c'
|
8
|
+
# Note that true and false are special-cased, true to allow for attributes that
|
9
|
+
# do not have a value and false for convenience, to allow for, e.g., inline
|
10
|
+
# conditionals.
|
7
11
|
def to_html_options double_quotes = true
|
8
12
|
qchar = double_quotes ? '"' : "'"
|
9
13
|
map { |k,v|
|
10
14
|
if v == true # Intentional.
|
11
15
|
k.to_s
|
16
|
+
elsif v == false
|
17
|
+
''
|
12
18
|
else
|
13
19
|
"#{k}=#{qchar}#{v.to_s.gsub(qchar, CGI.escapeHTML(qchar))}#{qchar}"
|
14
20
|
end
|
data/lib/hoshi/view.rb
CHANGED
@@ -1,13 +1,10 @@
|
|
1
|
-
require 'metaid'
|
2
1
|
require 'cgi'
|
3
2
|
|
4
|
-
require 'hoshi/view-tag'
|
5
|
-
|
6
3
|
module Hoshi
|
7
4
|
# The View class is the super-class for views you create with Hoshi. More
|
8
5
|
# likely, though, you'll be using one of View's many sub-classes as the
|
9
6
|
# super-class for your view, like this:
|
10
|
-
# class MyView < Hoshi::View :
|
7
|
+
# class MyView < Hoshi::View :html5
|
11
8
|
# or
|
12
9
|
# class MyView < Hoshi::View::XHTML1Frameset
|
13
10
|
# Of course, using View[] is the preferred method for the sake of brevity.
|
@@ -17,6 +14,25 @@ module Hoshi
|
|
17
14
|
class View
|
18
15
|
class ValidationError < StandardError; end
|
19
16
|
|
17
|
+
# This creates an instance method for this view which appends a tag.
|
18
|
+
# Most of these are handled for you. The arguments to this method
|
19
|
+
# match those to Tag.new. See also View.permissive!.
|
20
|
+
# tag('h1')
|
21
|
+
# def show_an_h1
|
22
|
+
# h1 "I have been shown"
|
23
|
+
# end
|
24
|
+
def self.tag(name, close_type = nil)
|
25
|
+
define_method(name) { |*opts,&b|
|
26
|
+
if b
|
27
|
+
tag name, close_type, *opts, &b
|
28
|
+
else
|
29
|
+
tag name, close_type, *opts
|
30
|
+
end
|
31
|
+
}
|
32
|
+
# Inline tags.
|
33
|
+
define_method("_#{name}") { |*opts| _tag name, close_type, *opts }
|
34
|
+
end
|
35
|
+
|
20
36
|
# A short-hand for creating multiple tags via View.tag. For tags that
|
21
37
|
# do not require closing, see View.open_tags.
|
22
38
|
def self.tags *names
|
@@ -0,0 +1,47 @@
|
|
1
|
+
class Hoshi::View
|
2
|
+
class SVG < self
|
3
|
+
# camelCase looks awful on method names, and we can't have
|
4
|
+
# hyphenated ones, so we start with a tag list from MDN:
|
5
|
+
# https://developer.mozilla.org/en-US/docs/Web/SVG/Element
|
6
|
+
tag_list = %w(
|
7
|
+
a altGlyph altGlyphDef altGlyphItem animate animateColor
|
8
|
+
animateMotion animateTransform circle clipPath color-profile
|
9
|
+
cursor defs desc ellipse feBlend feColorMatrix
|
10
|
+
feComponentTransfer feComposite feConvolveMatrix
|
11
|
+
feDiffuseLighting feDisplacementMap feDistantLight feFlood
|
12
|
+
feFuncA feFuncB feFuncG feFuncR feGaussianBlur feImage feMerge
|
13
|
+
feMergeNode feMorphology feOffset fePointLight
|
14
|
+
feSpecularLighting feSpotLight feTile feTurbulence filter font
|
15
|
+
font-face font-face-format font-face-name font-face-src
|
16
|
+
font-face-uri foreignObject g glyph glyphRef hkern image line
|
17
|
+
linearGradient marker mask metadata missing-glyph mpath path
|
18
|
+
pattern polygon polyline radialGradient rect script set stop
|
19
|
+
style svg switch symbol text textPath title tref tspan use view
|
20
|
+
vkern
|
21
|
+
)
|
22
|
+
|
23
|
+
self_closing_tags *tag_list.grep(/^[a-z]+$/i)
|
24
|
+
tag_list.grep(/[A-Z]/).each { |camel|
|
25
|
+
alias_method camel.
|
26
|
+
gsub(/([a-z])([A-Z])/) { "#{$1}_#{$2}" }.downcase.to_sym,
|
27
|
+
camel.to_sym
|
28
|
+
}
|
29
|
+
tag_list.grep(/-/).each { |hyphen|
|
30
|
+
define_method(hyphen.gsub('-', '_')) { |*opts,&b|
|
31
|
+
if b
|
32
|
+
tag hyphen, :self, *opts, &b
|
33
|
+
else
|
34
|
+
tag hyphen, :self, *opts
|
35
|
+
end
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
dtd! '<?xml version="1.0" encoding="UTF-8"?>\n' \
|
40
|
+
'<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" '\
|
41
|
+
'"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">'
|
42
|
+
|
43
|
+
def self.content_type
|
44
|
+
"image/svg+xml"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hoshi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pete Elmore
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-06-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: metaid
|
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
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: hpricot
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -61,7 +47,6 @@ files:
|
|
61
47
|
- lib/hoshi.rb
|
62
48
|
- lib/hoshi/monkey_patches.rb
|
63
49
|
- lib/hoshi/tag.rb
|
64
|
-
- lib/hoshi/view-tag.rb
|
65
50
|
- lib/hoshi/view.rb
|
66
51
|
- lib/hoshi/view/html.rb
|
67
52
|
- lib/hoshi/view/html3.rb
|
@@ -70,6 +55,7 @@ files:
|
|
70
55
|
- lib/hoshi/view/html4_transitional.rb
|
71
56
|
- lib/hoshi/view/html5.rb
|
72
57
|
- lib/hoshi/view/rss2.rb
|
58
|
+
- lib/hoshi/view/svg.rb
|
73
59
|
- lib/hoshi/view/xhtml.rb
|
74
60
|
- lib/hoshi/view/xhtml1.rb
|
75
61
|
- lib/hoshi/view/xhtml1_frameset.rb
|
@@ -95,8 +81,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
95
81
|
- !ruby/object:Gem::Version
|
96
82
|
version: '0'
|
97
83
|
requirements: []
|
98
|
-
rubyforge_project:
|
99
|
-
rubygems_version: 2.
|
84
|
+
rubyforge_project:
|
85
|
+
rubygems_version: 2.6.11
|
100
86
|
signing_key:
|
101
87
|
specification_version: 4
|
102
88
|
summary: Nice, object-oriented, first-class views.
|
data/lib/hoshi/view-tag.rb
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
module Hoshi
|
2
|
-
class View
|
3
|
-
# This creates an instance method for this view which appends a tag.
|
4
|
-
# Most of these are handled for you. The arguments to this method
|
5
|
-
# match those to Tag.new. See also View#permissive!.
|
6
|
-
# tag('h1')
|
7
|
-
# def show_an_h1
|
8
|
-
# h1 "I have been shown"
|
9
|
-
# end
|
10
|
-
def self.tag(name, close_type = nil)
|
11
|
-
define_method(name) { |*opts,&b|
|
12
|
-
if b
|
13
|
-
tag name, close_type, *opts, &b
|
14
|
-
else
|
15
|
-
tag name, close_type, *opts
|
16
|
-
end
|
17
|
-
}
|
18
|
-
# Inline tags.
|
19
|
-
define_method("_#{name}") { |*opts| _tag name, close_type, *opts }
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|