ro 1.4.6 → 4.4.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 +6 -14
- data/Gemfile +2 -0
- data/Gemfile.lock +64 -0
- data/LICENSE +1 -0
- data/README.md +276 -105
- data/README.md.erb +159 -0
- data/Rakefile +129 -78
- data/bin/ro +241 -68
- data/lib/ro/_lib.rb +107 -0
- data/lib/ro/asset.rb +55 -0
- data/lib/ro/collection/list.rb +23 -0
- data/lib/ro/collection.rb +211 -0
- data/lib/ro/config.rb +72 -0
- data/lib/ro/error.rb +11 -0
- data/lib/ro/html.rb +23 -0
- data/lib/ro/html_safe.rb +143 -0
- data/lib/ro/klass.rb +25 -0
- data/lib/ro/methods.rb +295 -0
- data/lib/ro/model.rb +83 -114
- data/lib/ro/node.rb +209 -349
- data/lib/ro/pagination.rb +7 -4
- data/lib/ro/path.rb +229 -0
- data/lib/ro/root.rb +52 -31
- data/lib/ro/script/builder.rb +221 -0
- data/lib/ro/script/console.rb +47 -0
- data/lib/ro/script/server.rb +76 -0
- data/lib/ro/script.rb +189 -0
- data/lib/ro/slug.rb +19 -18
- data/lib/ro/template/rouge_formatter.rb +42 -0
- data/lib/ro/template.rb +145 -51
- data/lib/ro/text.rb +120 -0
- data/lib/ro.rb +89 -317
- data/public/api/ro/index-1.json +1065 -0
- data/public/api/ro/index.json +1055 -0
- data/public/api/ro/nerd/fastest-possible-embeddings/index.json +90 -0
- data/public/api/ro/nerd/ima/index.json +49 -0
- data/public/api/ro/nerd/index/index.json +74 -0
- data/public/api/ro/nerd/index-1.json +204 -0
- data/public/api/ro/nerd/index.json +194 -0
- data/public/api/ro/pages/about/index.json +60 -0
- data/public/api/ro/pages/contact/index.json +50 -0
- data/public/api/ro/pages/cv/index.json +49 -0
- data/public/api/ro/pages/disco/index.json +117 -0
- data/public/api/ro/pages/index/index.json +30 -0
- data/public/api/ro/pages/index-1.json +366 -0
- data/public/api/ro/pages/index.json +356 -0
- data/public/api/ro/pages/jess/index.json +62 -0
- data/public/api/ro/pages/now/index.json +43 -0
- data/public/api/ro/posts/almost-died-in-an-ice-cave/index.json +265 -0
- data/public/api/ro/posts/facebook-and-global-extremism/index.json +90 -0
- data/public/api/ro/posts/index-1.json +527 -0
- data/public/api/ro/posts/index.json +517 -0
- data/public/api/ro/posts/lemmings-considered-harmful/index.json +49 -0
- data/public/api/ro/posts/lost-in-the-desert/index.json +49 -0
- data/public/api/ro/posts/mission/index.json +49 -0
- data/public/api/ro/posts/return-your-laptop/index.json +61 -0
- data/public/ro/nerd/fastest-possible-embeddings/assets/giraffe.jpeg +0 -0
- data/public/ro/nerd/fastest-possible-embeddings/assets/let-me-in.jpg +0 -0
- data/public/ro/nerd/fastest-possible-embeddings/assets/src/fastembed.js +70 -0
- data/public/ro/nerd/fastest-possible-embeddings/assets/src/fastembed.rs +68 -0
- data/public/ro/nerd/fastest-possible-embeddings/assets/terminal.jpg +0 -0
- data/public/ro/nerd/fastest-possible-embeddings/attributes.yml +7 -0
- data/public/ro/nerd/fastest-possible-embeddings/body.md +266 -0
- data/public/ro/nerd/ima/assets/og.jpeg +0 -0
- data/public/ro/nerd/ima/attributes.yml +8 -0
- data/public/ro/nerd/ima/body.md +22 -0
- data/public/ro/nerd/index/assets/giraffe.jpeg +0 -0
- data/public/ro/nerd/index/assets/let-me-in.jpg +0 -0
- data/public/ro/nerd/index/assets/terminal.jpg +0 -0
- data/public/ro/nerd/index/attributes.yml +7 -0
- data/public/ro/nerd/index/body.md +130 -0
- data/public/ro/pages/about/assets/og.jpeg +0 -0
- data/public/ro/pages/about/assets/speak-english-pulp-fiction.gif +0 -0
- data/public/ro/pages/about/body.md +40 -0
- data/public/ro/pages/contact/assets/giraffe.jpeg +0 -0
- data/public/ro/pages/contact/attributes.yml +7 -0
- data/public/ro/pages/contact/body.md +9 -0
- data/public/ro/pages/cv/assets/ara.jpg +0 -0
- data/public/ro/pages/cv/attributes.yml +6 -0
- data/public/ro/pages/cv/body.md +122 -0
- data/public/ro/pages/disco/assets/disco.jpg +0 -0
- data/public/ro/pages/disco/assets/disco.png +0 -0
- data/public/ro/pages/disco/assets/speak-english-pulp-fiction.gif +0 -0
- data/public/ro/pages/disco/assets/src/environment.md +2354 -0
- data/public/ro/pages/disco/assets/src/fortune-500.md +2518 -0
- data/public/ro/pages/disco/assets/src/greed.md +2703 -0
- data/public/ro/pages/disco/assets/src/up-at-night.md +2337 -0
- data/public/ro/pages/disco/attributes.yml +9 -0
- data/public/ro/pages/disco/body.md +99 -0
- data/public/ro/pages/disco/samples/environment.md +2354 -0
- data/public/ro/pages/disco/samples/fortune-500.md +2518 -0
- data/public/ro/pages/disco/samples/greed.md +2703 -0
- data/public/ro/pages/disco/samples/up-at-night.md +2337 -0
- data/public/ro/pages/index/attributes.yml +1 -0
- data/public/ro/pages/index/body.md +15 -0
- data/public/ro/pages/jess/assets/og.jpg +0 -0
- data/public/ro/pages/jess/assets/speak-english-pulp-fiction.gif +0 -0
- data/public/ro/pages/jess/attributes.yml +7 -0
- data/public/ro/pages/jess/body.md +3 -0
- data/public/ro/pages/now/assets/speak-english-pulp-fiction.gif +0 -0
- data/public/ro/pages/now/attributes.yml +1 -0
- data/public/ro/pages/now/body.md +24 -0
- data/public/ro/posts/almost-died-in-an-ice-cave/assets/image1.png +0 -0
- data/public/ro/posts/almost-died-in-an-ice-cave/assets/image10.png +0 -0
- data/public/ro/posts/almost-died-in-an-ice-cave/assets/image11.png +0 -0
- data/public/ro/posts/almost-died-in-an-ice-cave/assets/image12.png +0 -0
- data/public/ro/posts/almost-died-in-an-ice-cave/assets/image13.png +0 -0
- data/public/ro/posts/almost-died-in-an-ice-cave/assets/image14.png +0 -0
- data/public/ro/posts/almost-died-in-an-ice-cave/assets/image15.png +0 -0
- data/public/ro/posts/almost-died-in-an-ice-cave/assets/image2.png +0 -0
- data/public/ro/posts/almost-died-in-an-ice-cave/assets/image3.png +0 -0
- data/public/ro/posts/almost-died-in-an-ice-cave/assets/image4.png +0 -0
- data/public/ro/posts/almost-died-in-an-ice-cave/assets/image5.png +0 -0
- data/public/ro/posts/almost-died-in-an-ice-cave/assets/image6.png +0 -0
- data/public/ro/posts/almost-died-in-an-ice-cave/assets/image7.png +0 -0
- data/public/ro/posts/almost-died-in-an-ice-cave/assets/image8.png +0 -0
- data/public/ro/posts/almost-died-in-an-ice-cave/assets/image9.png +0 -0
- data/public/ro/posts/almost-died-in-an-ice-cave/assets/josh-pointing.jpg +0 -0
- data/public/ro/posts/almost-died-in-an-ice-cave/assets/levi-rawr.png +0 -0
- data/public/ro/posts/almost-died-in-an-ice-cave/assets/og.jpg +0 -0
- data/public/ro/posts/almost-died-in-an-ice-cave/assets/purple-heart.jpg +0 -0
- data/public/ro/posts/almost-died-in-an-ice-cave/attributes.yml +6 -0
- data/public/ro/posts/almost-died-in-an-ice-cave/body.md +419 -0
- data/public/ro/posts/facebook-and-global-extremism/assets/background.html +125 -0
- data/public/ro/posts/facebook-and-global-extremism/assets/background.md +95 -0
- data/public/ro/posts/facebook-and-global-extremism/assets/og.jpg +0 -0
- data/public/ro/posts/facebook-and-global-extremism/assets/prompt.txt +122 -0
- data/public/ro/posts/facebook-and-global-extremism/assets/results.md +183 -0
- data/public/ro/posts/facebook-and-global-extremism/assets/survey.txt +190 -0
- data/public/ro/posts/facebook-and-global-extremism/attributes.yml +7 -0
- data/public/ro/posts/facebook-and-global-extremism/body.md +393 -0
- data/public/ro/posts/lemmings-considered-harmful/assets/lemming.jpeg +0 -0
- data/public/ro/posts/lemmings-considered-harmful/attributes.yml +6 -0
- data/public/ro/posts/lemmings-considered-harmful/body.md +43 -0
- data/public/ro/posts/lost-in-the-desert/assets/og.jpg +0 -0
- data/public/ro/posts/lost-in-the-desert/attributes.yml +6 -0
- data/public/ro/posts/lost-in-the-desert/body.md +7 -0
- data/public/ro/posts/mission/assets/og.jpg +0 -0
- data/public/ro/posts/mission/attributes.yml +6 -0
- data/public/ro/posts/mission/body.md +4 -0
- data/public/ro/posts/return-your-laptop/assets/og.jpg +0 -0
- data/public/ro/posts/return-your-laptop/assets/return-your-laptop.png +0 -0
- data/public/ro/posts/return-your-laptop/attributes.yml +6 -0
- data/public/ro/posts/return-your-laptop/body.md +58 -0
- data/ro.gemspec +217 -28
- data/scripts/speedtest.rb +324 -0
- data/tmp/gem-details.oe +0 -0
- metadata +214 -74
- data/TODO.md +0 -50
- data/lib/ro/blankslate.rb +0 -7
- data/lib/ro/cache.rb +0 -26
- data/lib/ro/git.rb +0 -374
- data/lib/ro/initializers/env.rb +0 -5
- data/lib/ro/initializers/tilt.rb +0 -104
- data/lib/ro/lock.rb +0 -53
- data/lib/ro/node/list.rb +0 -142
- data/notes/ara.txt +0 -215
@@ -0,0 +1,211 @@
|
|
1
|
+
module Ro
|
2
|
+
class Collection
|
3
|
+
include Klass
|
4
|
+
include Enumerable
|
5
|
+
|
6
|
+
attr_reader :path, :root
|
7
|
+
|
8
|
+
def initialize(path)
|
9
|
+
@path = Path.for(path)
|
10
|
+
@root = Root.for(@path.parent)
|
11
|
+
end
|
12
|
+
|
13
|
+
def name
|
14
|
+
@path.name
|
15
|
+
end
|
16
|
+
|
17
|
+
def id
|
18
|
+
name
|
19
|
+
end
|
20
|
+
|
21
|
+
def type
|
22
|
+
name
|
23
|
+
end
|
24
|
+
|
25
|
+
def identifier
|
26
|
+
type
|
27
|
+
end
|
28
|
+
|
29
|
+
def inspect
|
30
|
+
identifier
|
31
|
+
end
|
32
|
+
|
33
|
+
def node_for(path)
|
34
|
+
Node.new(path)
|
35
|
+
end
|
36
|
+
|
37
|
+
def subdirectories(...)
|
38
|
+
@path.subdirectories(...)
|
39
|
+
end
|
40
|
+
|
41
|
+
def subdirectory_for(name)
|
42
|
+
@path.subdirectory_for(name)
|
43
|
+
end
|
44
|
+
|
45
|
+
def each(offset:nil, limit:nil, &block)
|
46
|
+
accum = []
|
47
|
+
|
48
|
+
if offset
|
49
|
+
i = -1
|
50
|
+
n = 0
|
51
|
+
subdirectories do |subdirectory|
|
52
|
+
i += 1
|
53
|
+
next if i < offset
|
54
|
+
node = node_for(subdirectory)
|
55
|
+
block ? block.call(node) : accum.push(node)
|
56
|
+
n += 1
|
57
|
+
break if limit && n >= limit
|
58
|
+
end
|
59
|
+
else
|
60
|
+
subdirectories do |subdirectory|
|
61
|
+
node = node_for(subdirectory)
|
62
|
+
block ? block.call(node) : accum.push(node)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
block ? self : accum
|
67
|
+
end
|
68
|
+
|
69
|
+
class Page < ::Array
|
70
|
+
attr_accessor :number
|
71
|
+
|
72
|
+
def initialize(nodes = [], number: 1)
|
73
|
+
replace(nodes)
|
74
|
+
@number = number
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def page(number, size: 10)
|
79
|
+
offset = [(number - 1), 0].max * size
|
80
|
+
limit = [size, 1].max
|
81
|
+
|
82
|
+
nodes = each(offset:, limit:)
|
83
|
+
Page.new(nodes, number:)
|
84
|
+
end
|
85
|
+
|
86
|
+
def paginate(size: 10, &block)
|
87
|
+
number = 0
|
88
|
+
accum = []
|
89
|
+
|
90
|
+
loop do
|
91
|
+
number += 1
|
92
|
+
page = self.page(number, size:)
|
93
|
+
break if page.empty?
|
94
|
+
block ? block.call(page) : accum.push(page)
|
95
|
+
end
|
96
|
+
|
97
|
+
block ? self : accum
|
98
|
+
end
|
99
|
+
|
100
|
+
def load(&block)
|
101
|
+
n = 8
|
102
|
+
q = Queue.new # FIXME
|
103
|
+
o = Queue.new # FIXME
|
104
|
+
|
105
|
+
producer =
|
106
|
+
Thread.new do
|
107
|
+
Thread.current.abort_on_exception = true
|
108
|
+
|
109
|
+
subdirectories do |subdirectory|
|
110
|
+
q.push(subdirectory)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
loaders =
|
115
|
+
n.times.map do
|
116
|
+
Thread.new do
|
117
|
+
Thread.current.abort_on_exception = true
|
118
|
+
|
119
|
+
loop do
|
120
|
+
subdirectory = q.pop
|
121
|
+
|
122
|
+
begin
|
123
|
+
node = node_for(subdirectory)
|
124
|
+
o.push(node)
|
125
|
+
rescue => e
|
126
|
+
o.push(e) # FIXME
|
127
|
+
nil # FIXME
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
accum = []
|
134
|
+
|
135
|
+
consumer =
|
136
|
+
Thread.new do
|
137
|
+
Thread.current.abort_on_exception = true
|
138
|
+
loop do
|
139
|
+
node = o.pop
|
140
|
+
block ? block.call(node) : accum.push(node)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
producer.join
|
145
|
+
loaders.map{|loader| loader.join}
|
146
|
+
consumer.join
|
147
|
+
|
148
|
+
block ? self : accum
|
149
|
+
end
|
150
|
+
|
151
|
+
def to_array(...)
|
152
|
+
each(...)
|
153
|
+
end
|
154
|
+
|
155
|
+
alias to_a to_array
|
156
|
+
|
157
|
+
alias all to_array
|
158
|
+
|
159
|
+
alias nodes to_array
|
160
|
+
|
161
|
+
def first(*args)
|
162
|
+
if args.size.zero?
|
163
|
+
node_for(subdirectories.first)
|
164
|
+
else
|
165
|
+
subdirectories.first(*args).map{|subdirectory| node_for(subdirectory)}
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def last(*args)
|
170
|
+
if args.size.zero?
|
171
|
+
node_for(subdirectories.last)
|
172
|
+
else
|
173
|
+
subdirectories.last(*args).map{|subdirectory| node_for(subdirectory)}
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def size
|
178
|
+
subdirectories.size
|
179
|
+
end
|
180
|
+
|
181
|
+
def paths_for(name)
|
182
|
+
[
|
183
|
+
subdirectory_for(name),
|
184
|
+
subdirectory_for(Slug.for(name, :join => '-')),
|
185
|
+
subdirectory_for(Slug.for(name, :join => '_')),
|
186
|
+
]
|
187
|
+
end
|
188
|
+
|
189
|
+
def get(name)
|
190
|
+
paths_for(name).each do |path|
|
191
|
+
next unless path.exist?
|
192
|
+
|
193
|
+
return node_for(path)
|
194
|
+
end
|
195
|
+
|
196
|
+
nil
|
197
|
+
end
|
198
|
+
|
199
|
+
def [](name)
|
200
|
+
get(name)
|
201
|
+
end
|
202
|
+
|
203
|
+
def slice(...)
|
204
|
+
subdirectories.slice(...).map{|subdirectory| node_for(subdirectory)}
|
205
|
+
end
|
206
|
+
|
207
|
+
def method_missing(name, *args, **kws, &block)
|
208
|
+
get(name) || super
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
data/lib/ro/config.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
module Ro
|
2
|
+
class Config < ::Map
|
3
|
+
def Config.defaults
|
4
|
+
{
|
5
|
+
:root =>
|
6
|
+
(Ro.env.root || Ro.defaults.root),
|
7
|
+
|
8
|
+
:build =>
|
9
|
+
(Ro.env.build || Ro.defaults.build),
|
10
|
+
|
11
|
+
:url =>
|
12
|
+
(Ro.env.url || Ro.defaults.url),
|
13
|
+
|
14
|
+
:img_url =>
|
15
|
+
(Ro.env.img_url || Ro.defaults.img_url),
|
16
|
+
|
17
|
+
:page_size =>
|
18
|
+
(Ro.env.page_size || Ro.defaults.page_size),
|
19
|
+
|
20
|
+
:log =>
|
21
|
+
(Ro.env.log || Ro.defaults.log),
|
22
|
+
|
23
|
+
:debug =>
|
24
|
+
(Ro.env.debug || Ro.defaults.debug),
|
25
|
+
|
26
|
+
:port =>
|
27
|
+
(Ro.env.port || Ro.defaults.port),
|
28
|
+
|
29
|
+
:md_theme =>
|
30
|
+
(Ro.env.md_theme || Ro.defaults.md_theme),
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
def initialize(*args, **kws)
|
35
|
+
configure!(Config.defaults)
|
36
|
+
|
37
|
+
args.each do |arg|
|
38
|
+
configure!(arg) if arg.is_a?(Hash)
|
39
|
+
end
|
40
|
+
|
41
|
+
configure!(kws)
|
42
|
+
end
|
43
|
+
|
44
|
+
def configure!(hash)
|
45
|
+
hash.each do |key, value|
|
46
|
+
send("#{ key }=", value)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
{
|
51
|
+
:root => :root,
|
52
|
+
:build => :path,
|
53
|
+
:url => :url,
|
54
|
+
:img_url => :url,
|
55
|
+
:page_size => :int,
|
56
|
+
:log => :bool,
|
57
|
+
:debug => :bool,
|
58
|
+
:port => :int,
|
59
|
+
:md_theme => :string,
|
60
|
+
}.each do |attribute, cast|
|
61
|
+
class_eval <<-____, __FILE__, __LINE__ + 1
|
62
|
+
def #{ attribute }
|
63
|
+
get :#{ attribute }
|
64
|
+
end
|
65
|
+
|
66
|
+
def #{ attribute }=(value)
|
67
|
+
set :#{ attribute }, Ro.cast(:#{ cast }, value)
|
68
|
+
end
|
69
|
+
____
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/lib/ro/error.rb
ADDED
data/lib/ro/html.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
module Ro
|
2
|
+
require_relative 'html_safe'
|
3
|
+
|
4
|
+
class HTML < ::ActiveSupport::SafeBuffer
|
5
|
+
def initialize(*args, **kws, &block)
|
6
|
+
self.front_matter = kws.fetch(:front_matter){ {} }
|
7
|
+
|
8
|
+
super(args.join)
|
9
|
+
end
|
10
|
+
|
11
|
+
def front_matter
|
12
|
+
@front_matter ||= Map.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def front_matter=(hash = {})
|
16
|
+
@front_matter = Map.for(hash)
|
17
|
+
end
|
18
|
+
|
19
|
+
def attributes
|
20
|
+
front_matter
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/ro/html_safe.rb
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
unless defined?(ActiveSupport::SafeBuffer)
|
4
|
+
|
5
|
+
class Object
|
6
|
+
def html_safe?
|
7
|
+
false
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class Numeric
|
12
|
+
def html_safe?
|
13
|
+
true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
module ActiveSupport #:nodoc:
|
18
|
+
class SafeBuffer < String
|
19
|
+
UNSAFE_STRING_METHODS = %w(
|
20
|
+
capitalize chomp chop delete downcase gsub lstrip next reverse rstrip
|
21
|
+
slice squeeze strip sub succ swapcase tr tr_s upcase
|
22
|
+
)
|
23
|
+
|
24
|
+
alias_method :original_concat, :concat
|
25
|
+
private :original_concat
|
26
|
+
|
27
|
+
# Raised when <tt>ActiveSupport::SafeBuffer#safe_concat</tt> is called on unsafe buffers.
|
28
|
+
class SafeConcatError < StandardError
|
29
|
+
def initialize
|
30
|
+
super "Could not concatenate to the buffer because it is not html safe."
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def [](*args)
|
35
|
+
if args.size < 2
|
36
|
+
super
|
37
|
+
elsif html_safe?
|
38
|
+
new_safe_buffer = super
|
39
|
+
|
40
|
+
if new_safe_buffer
|
41
|
+
new_safe_buffer.instance_variable_set :@html_safe, true
|
42
|
+
end
|
43
|
+
|
44
|
+
new_safe_buffer
|
45
|
+
else
|
46
|
+
to_str[*args]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def safe_concat(value)
|
51
|
+
raise SafeConcatError unless html_safe?
|
52
|
+
original_concat(value)
|
53
|
+
end
|
54
|
+
|
55
|
+
def initialize(str = "")
|
56
|
+
@html_safe = true
|
57
|
+
super
|
58
|
+
end
|
59
|
+
|
60
|
+
def initialize_copy(other)
|
61
|
+
super
|
62
|
+
@html_safe = other.html_safe?
|
63
|
+
end
|
64
|
+
|
65
|
+
def clone_empty
|
66
|
+
self[0, 0]
|
67
|
+
end
|
68
|
+
|
69
|
+
def concat(value)
|
70
|
+
super(html_escape_interpolated_argument(value))
|
71
|
+
end
|
72
|
+
alias << concat
|
73
|
+
|
74
|
+
def prepend(value)
|
75
|
+
super(html_escape_interpolated_argument(value))
|
76
|
+
end
|
77
|
+
|
78
|
+
def +(other)
|
79
|
+
dup.concat(other)
|
80
|
+
end
|
81
|
+
|
82
|
+
def %(args)
|
83
|
+
case args
|
84
|
+
when Hash
|
85
|
+
escaped_args = Hash[args.map { |k, arg| [k, html_escape_interpolated_argument(arg)] }]
|
86
|
+
else
|
87
|
+
escaped_args = Array(args).map { |arg| html_escape_interpolated_argument(arg) }
|
88
|
+
end
|
89
|
+
|
90
|
+
self.class.new(super(escaped_args))
|
91
|
+
end
|
92
|
+
|
93
|
+
def html_safe?
|
94
|
+
defined?(@html_safe) && @html_safe
|
95
|
+
end
|
96
|
+
|
97
|
+
def to_s
|
98
|
+
self
|
99
|
+
end
|
100
|
+
|
101
|
+
def to_param
|
102
|
+
to_str
|
103
|
+
end
|
104
|
+
|
105
|
+
def encode_with(coder)
|
106
|
+
coder.represent_object nil, to_str
|
107
|
+
end
|
108
|
+
|
109
|
+
UNSAFE_STRING_METHODS.each do |unsafe_method|
|
110
|
+
if unsafe_method.respond_to?(unsafe_method)
|
111
|
+
class_eval <<-EOT, __FILE__, __LINE__ + 1
|
112
|
+
def #{unsafe_method}(*args, &block) # def capitalize(*args, &block)
|
113
|
+
to_str.#{unsafe_method}(*args, &block) # to_str.capitalize(*args, &block)
|
114
|
+
end # end
|
115
|
+
|
116
|
+
def #{unsafe_method}!(*args) # def capitalize!(*args)
|
117
|
+
@html_safe = false # @html_safe = false
|
118
|
+
super # super
|
119
|
+
end # end
|
120
|
+
EOT
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
private
|
125
|
+
|
126
|
+
def html_escape_interpolated_argument(arg)
|
127
|
+
(!html_safe? || arg.html_safe?) ? arg : CGI.escapeHTML(arg.to_s)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
class String
|
133
|
+
# Marks a string as trusted safe. It will be inserted into HTML with no
|
134
|
+
# additional escaping performed. It is your responsibility to ensure that the
|
135
|
+
# string contains no malicious content. This method is equivalent to the
|
136
|
+
# +raw+ helper in views. It is recommended that you use +sanitize+ instead of
|
137
|
+
# this method. It should never be called on user input.
|
138
|
+
def html_safe
|
139
|
+
ActiveSupport::SafeBuffer.new(self)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
data/lib/ro/klass.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
module Ro
|
2
|
+
module Klass
|
3
|
+
module ClassMethods
|
4
|
+
def klass(arg, *args, **kws, &block)
|
5
|
+
return arg if arg.is_a?(self.class) && args.empty? && kws.empty? && block.nil?
|
6
|
+
|
7
|
+
new(arg, *args, **kws, &block)
|
8
|
+
end
|
9
|
+
|
10
|
+
alias for klass
|
11
|
+
end
|
12
|
+
|
13
|
+
module InstanceMethods
|
14
|
+
def klass
|
15
|
+
self.class
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def Klass.included(other)
|
20
|
+
other.send(:extend, ClassMethods)
|
21
|
+
other.send(:include, InstanceMethods)
|
22
|
+
super
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|