ems 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/app/assets/stylesheets/ems/active_admin/components/_asset_store.scss +5 -1
- data/app/models/ems/asset.rb +1 -1
- data/app/views/ems/articles/_form.html.haml +1 -1
- data/app/views/ems/globals/_lead_image.html.haml +2 -0
- data/app/views/ems/news/_form.html.haml +1 -1
- data/app/views/ems/reports/_form.html.haml +1 -1
- data/config/initializers/bean_kramdown.rb +1 -0
- data/lib/ems/engine.rb +1 -1
- data/lib/ems/version.rb +1 -1
- data/lib/kramdown/bean_kramdown.rb +26 -0
- data/lib/kramdown/bean_kramdown/info_box.rb +52 -0
- data/lib/kramdown/bean_kramdown/oembed.rb +230 -0
- data/lib/kramdown/converter/bean_html.rb +71 -0
- data/lib/kramdown/parser/bean_kramdown/info_box.rb +52 -0
- data/lib/kramdown/parser/bean_kramdown/oembed.rb +230 -0
- data/test/dummy/log/development.log +1706 -0
- data/test/dummy/public/system/ems/articles/images/000/000/012/image228x126/nandos.png +0 -0
- data/test/dummy/public/system/ems/articles/images/000/000/012/image312x126/nandos.png +0 -0
- data/test/dummy/public/system/ems/articles/images/000/000/012/image312x189/nandos.png +0 -0
- data/test/dummy/public/system/ems/articles/images/000/000/012/image564x252/nandos.png +0 -0
- data/test/dummy/public/system/ems/articles/images/000/000/012/original/nandos.png +0 -0
- data/test/dummy/public/system/ems/assets/assets/000/000/001/original/CATs.jpeg +0 -0
- data/test/dummy/public/system/ems/assets/assets/000/000/002/original/test.pdf +0 -0
- data/test/dummy/tmp/cache/assets/C40/AE0/sprockets%2Ff6a5272156a29d410b210e23096595a4 +0 -0
- data/test/dummy/tmp/cache/assets/C93/990/sprockets%2F5a674ff04789264c4d9d30662c784b83 +0 -0
- metadata +43 -5
- data/config/environments/production.rb +0 -10
- data/test/dummy/tmp/pids/server.pid +0 -1
data/app/models/ems/asset.rb
CHANGED
@@ -6,7 +6,7 @@ module Ems
|
|
6
6
|
|
7
7
|
belongs_to :assetable, :polymorphic => true
|
8
8
|
|
9
|
-
has_attached_file :asset, :styles =>{:original => "564x252>"}
|
9
|
+
has_attached_file :asset, :styles => {:original => "564x252>"}
|
10
10
|
|
11
11
|
# virtual alt text accessor - returns the title of the image otherwise the path
|
12
12
|
def alt
|
@@ -0,0 +1 @@
|
|
1
|
+
require "#{Ems::Engine.root}/lib/kramdown/bean_kramdown"
|
data/lib/ems/engine.rb
CHANGED
@@ -3,7 +3,7 @@ module Ems
|
|
3
3
|
isolate_namespace Ems
|
4
4
|
# Add a load path for this specific Engine
|
5
5
|
config.autoload_paths << File.expand_path("#{Engine.root}/lib/query_builder/", __FILE__)
|
6
|
-
config.autoload_paths << File.expand_path("#{Engine.root}/lib/kramdown
|
6
|
+
config.autoload_paths << File.expand_path("#{Engine.root}/lib/kramdown", __FILE__)
|
7
7
|
config.generators do |g|
|
8
8
|
g.template_engine :haml
|
9
9
|
end
|
data/lib/ems/version.rb
CHANGED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'kramdown/parser/kramdown'
|
2
|
+
|
3
|
+
module Kramdown
|
4
|
+
module Parser
|
5
|
+
class BeanKramdown < Kramdown
|
6
|
+
|
7
|
+
# Array with all the parsing methods that should be removed from the standard kramdown parser.
|
8
|
+
EXCEPT = [:codeblock_fenced, :block_extensions, :span_extensions]
|
9
|
+
|
10
|
+
# initialise new parsers
|
11
|
+
def initialize(source, options)
|
12
|
+
super
|
13
|
+
|
14
|
+
@block_parsers.unshift(:info_box)
|
15
|
+
@span_parsers.unshift(:oembed)
|
16
|
+
|
17
|
+
@block_parsers.delete_if {|i| EXCEPT.include?(i)}
|
18
|
+
@span_parsers.delete_if {|i| EXCEPT.include?(i)}
|
19
|
+
end
|
20
|
+
|
21
|
+
require "kramdown/bean_kramdown/info_box"
|
22
|
+
require "kramdown/bean_kramdown/oembed"
|
23
|
+
require 'kramdown/converter/bean_html'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
#--
|
4
|
+
# Copyright (C) 2009-2012 Thomas Leitner <t_leitner@gmx.at>
|
5
|
+
#
|
6
|
+
# This file is part of kramdown.
|
7
|
+
#
|
8
|
+
# kramdown is free software: you can redistribute it and/or modify
|
9
|
+
# it under the terms of the GNU General Public License as published by
|
10
|
+
# the Free Software Foundation, either version 3 of the License, or
|
11
|
+
# (at your option) any later version.
|
12
|
+
#
|
13
|
+
# This program is distributed in the hope that it will be useful,
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
# GNU General Public License for more details.
|
17
|
+
#
|
18
|
+
# You should have received a copy of the GNU General Public License
|
19
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
20
|
+
#++
|
21
|
+
#
|
22
|
+
|
23
|
+
require 'kramdown/parser/kramdown/blank_line'
|
24
|
+
require 'kramdown/parser/kramdown/extensions'
|
25
|
+
require 'kramdown/parser/kramdown/eob'
|
26
|
+
|
27
|
+
module Kramdown
|
28
|
+
module Parser
|
29
|
+
class BeanKramdown
|
30
|
+
|
31
|
+
INFO_BOX_START = /^#{OPT_SPACE}% ?/
|
32
|
+
|
33
|
+
# Parse the info box at the current location.
|
34
|
+
def parse_info_box
|
35
|
+
result = @src.scan(PARAGRAPH_MATCH)
|
36
|
+
while !@src.match?(self.class::LAZY_END)
|
37
|
+
result << @src.scan(PARAGRAPH_MATCH)
|
38
|
+
end
|
39
|
+
result.gsub!(INFO_BOX_START, '')
|
40
|
+
|
41
|
+
el = new_block_el(:info_box)
|
42
|
+
@tree.children << el
|
43
|
+
parse_blocks(el, result)
|
44
|
+
true
|
45
|
+
end
|
46
|
+
|
47
|
+
define_parser(:info_box, INFO_BOX_START)
|
48
|
+
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,230 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
#--
|
4
|
+
# Copyright (C) 2009-2012 Thomas Leitner <t_leitner@gmx.at>
|
5
|
+
#
|
6
|
+
# This file is part of kramdown.
|
7
|
+
#
|
8
|
+
# kramdown is free software: you can redistribute it and/or modify
|
9
|
+
# it under the terms of the GNU General Public License as published by
|
10
|
+
# the Free Software Foundation, either version 3 of the License, or
|
11
|
+
# (at your option) any later version.
|
12
|
+
#
|
13
|
+
# This program is distributed in the hope that it will be useful,
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
# GNU General Public License for more details.
|
17
|
+
#
|
18
|
+
# You should have received a copy of the GNU General Public License
|
19
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
20
|
+
#++
|
21
|
+
#
|
22
|
+
|
23
|
+
#
|
24
|
+
# This file has been edited to suit the needs of The Beans Group Ltd. Changes were made to the types of media availbable
|
25
|
+
# images keep their ! however new types are ? for oembedd etc
|
26
|
+
# If you wish to change the types of media you need to change the OEMBED_START constant to include your special symbol
|
27
|
+
# for the new media object as well as change the reg ex on the parser definition towards the bottom of this file.
|
28
|
+
#
|
29
|
+
|
30
|
+
require 'open-uri'
|
31
|
+
require 'cgi'
|
32
|
+
require 'json'
|
33
|
+
|
34
|
+
module Kramdown
|
35
|
+
module Parser
|
36
|
+
class BeanKramdown
|
37
|
+
|
38
|
+
# Normalize the oembed identifier.
|
39
|
+
def normalize_oembed_id(id)
|
40
|
+
id.gsub(/(\s|\n)+/, ' ').downcase
|
41
|
+
end
|
42
|
+
|
43
|
+
OEMBED_DEFINITION_START = /^#{OPT_SPACE}\[([^\n\]]+)\]:[ \t]*(?:<(.*?)>|([^'"\n]*?\S[^'"\n]*?))[ \t]*?(?:\n?[ \t]*?(["'])(.+?)\4[ \t]*?)?\n/
|
44
|
+
|
45
|
+
# Parse the oembed definition at the current location.
|
46
|
+
def parse_oembed_definition
|
47
|
+
@src.pos += @src.matched_size
|
48
|
+
oembed_id, oembed_url, oembed_title = normalize_oembed_id(@src[1]), @src[2] || @src[3], @src[5]
|
49
|
+
warning("Duplicate oembed ID '#{oembed_id}' - overwriting") if @oembed_defs[oembed_id]
|
50
|
+
@oembed_defs[oembed_id] = [oembed_url, oembed_title]
|
51
|
+
@tree.children << Element.new(:eob, :oembed_def)
|
52
|
+
true
|
53
|
+
end
|
54
|
+
define_parser(:oembed_definition, OEMBED_DEFINITION_START)
|
55
|
+
|
56
|
+
|
57
|
+
# This helper methods adds the approriate attributes to the element +el+ of type +a+ or +img+
|
58
|
+
# and the element itself to the @tree.
|
59
|
+
def add_oembed(el, href, title, alt_text = nil)
|
60
|
+
|
61
|
+
providers = {
|
62
|
+
:twitter => "https://api.twitter.com/1/statuses/oembed.json?url=%s",
|
63
|
+
:youtube => "http://www.youtube.com/oembed?url=%s&format=json&maxwidth=550",
|
64
|
+
:flickr => "http://flickr.com/services/oembed?url=%s&maxwidth=460&format=json&maxwidth=550",
|
65
|
+
:vidler => "http://lab.viddler.com/services/oembed/?url=%s&type=simple&format=json",
|
66
|
+
:qik => "http://qik.com/api/oembed.json?url=%s&maxwidth=550",
|
67
|
+
:revision3 => "http://revision3.com/api/oembed/?url=%s&format=json&maxwidth=550",
|
68
|
+
:hulu => "http://www.hulu.com/api/oembed.json?url=%s&maxwidth=550",
|
69
|
+
:vimeo => "http://vimeo.com/api/oembed.json?url=%s&maxwidth=550",
|
70
|
+
:collegehumor => "http://www.collegehumor.com/oembed.json?url=%s&maxwidth=550",
|
71
|
+
# :pollyeverywhere => "http://www.polleverywhere.com/services/oembed?url=%s&format=json",
|
72
|
+
# :opera => "http://my.opera.com/service/oembed/?url=%s",
|
73
|
+
:embedly => "http://api.embed.ly/1/oembed?url=%w&maxwidth=550",
|
74
|
+
:ifixit => "http://www.ifixit.com/Embed?url=%s&format=json",
|
75
|
+
:smugmug => "http://api.smugmug.com/services/oembed/?url=%s&format=json",
|
76
|
+
:slideshare => "http://www.slideshare.net/api/oembed/2?url=%s&format=json&maxwidth=550",
|
77
|
+
:wordpress => "http://public-api.wordpress.com/oembed/1.0/?format=json&url=%s&maxwidth=550"
|
78
|
+
}
|
79
|
+
# ready the hash for matching
|
80
|
+
provider_names = (providers.keys.each { |name| name.to_s }).join('|')
|
81
|
+
# match possible providers to see if we have a provider suitable for embedding the current href/url
|
82
|
+
result = href.match provider_names
|
83
|
+
if result and result[0]
|
84
|
+
safe_href = CGI.escape(href)
|
85
|
+
provider = result[0].to_sym
|
86
|
+
oembed_url = providers[provider] % safe_href
|
87
|
+
# unique figure id
|
88
|
+
fig_id = rand(1000)
|
89
|
+
# oembed
|
90
|
+
el = Element.new :oembed
|
91
|
+
begin
|
92
|
+
# get the oEmbed content
|
93
|
+
result = JSON.parse(open(oembed_url).read)
|
94
|
+
el.attr['provider_name'] = result['provider_name']
|
95
|
+
case result['type']
|
96
|
+
when "photo"
|
97
|
+
title = result['title']
|
98
|
+
el.attr['role'] = "img"
|
99
|
+
img = Element.new(:img)
|
100
|
+
img.attr['src'] = result['url']
|
101
|
+
img.attr['alt'] = result['title']
|
102
|
+
img.attr['width'] = result['width']
|
103
|
+
img.attr['height'] = result['height']
|
104
|
+
img.children.clear
|
105
|
+
el.children << img
|
106
|
+
when "video"
|
107
|
+
title = result['title']
|
108
|
+
el.attr['html'] = CGI.unescapeHTML(result['html'])
|
109
|
+
when "rich"
|
110
|
+
el.attr['html'] = CGI.unescapeHTML(result['html'])
|
111
|
+
end
|
112
|
+
|
113
|
+
if title
|
114
|
+
# unique figure id
|
115
|
+
el_id = rand(1000)
|
116
|
+
el.attr['id'] = el_id
|
117
|
+
cap = Element.new(:figCaption, title)
|
118
|
+
cap.attr['id'] = el_id
|
119
|
+
if el.attr['role'] === "img"
|
120
|
+
link = Element.new(:a, result['author_name'])
|
121
|
+
link.attr['href'] = result['author_url']
|
122
|
+
cap.children << link
|
123
|
+
end
|
124
|
+
el.children << cap
|
125
|
+
end
|
126
|
+
@tree.children << el
|
127
|
+
|
128
|
+
rescue
|
129
|
+
warning("Could not retrieve oEmbed information for URL #{oembed_url}")
|
130
|
+
end
|
131
|
+
else
|
132
|
+
warning("No oEmbed provider found for URL #{href}")
|
133
|
+
end
|
134
|
+
|
135
|
+
|
136
|
+
|
137
|
+
# if el.type == :a
|
138
|
+
# el.attr['href'] = href
|
139
|
+
# else
|
140
|
+
# el.attr['src'] = href
|
141
|
+
# el.attr['alt'] = alt_text
|
142
|
+
# el.children.clear
|
143
|
+
# end
|
144
|
+
# el.attr['title'] = title if title
|
145
|
+
# @tree.children << el
|
146
|
+
end
|
147
|
+
|
148
|
+
OEMBED_BRACKET_STOP_RE = /(\])|!?\[/
|
149
|
+
OEMBED_PAREN_STOP_RE = /(\()|(\))|\s(?=['"])/
|
150
|
+
OEMBED_INLINE_ID_RE = /\s*?\[([^\]]+)?\]/
|
151
|
+
OEMBED_INLINE_TITLE_RE = /\s*?(["'])(.+?)\1\s*?\)/
|
152
|
+
OEMBED_START = /\?\[(?=[^^])/
|
153
|
+
|
154
|
+
# Parse the oembed at the current scanner position. This method is used to parse normal oembeds as
|
155
|
+
# well as image oembeds.
|
156
|
+
def parse_oembed
|
157
|
+
result = @src.scan(OEMBED_START)
|
158
|
+
reset_pos = @src.pos
|
159
|
+
oembed_type = :img
|
160
|
+
|
161
|
+
el = Element.new(oembed_type)
|
162
|
+
|
163
|
+
count = 1
|
164
|
+
found = parse_spans(el, OEMBED_BRACKET_STOP_RE) do
|
165
|
+
count = count + (@src[1] ? -1 : 1)
|
166
|
+
count - el.children.select {|c| c.type == :img}.size == 0
|
167
|
+
end
|
168
|
+
if !found || (oembed_type == :a && el.children.empty?)
|
169
|
+
@src.pos = reset_pos
|
170
|
+
add_text(result)
|
171
|
+
return
|
172
|
+
end
|
173
|
+
alt_text = extract_string(reset_pos...@src.pos, @src)
|
174
|
+
@src.scan(OEMBED_BRACKET_STOP_RE)
|
175
|
+
|
176
|
+
# reference style oembed or no oembed url
|
177
|
+
if @src.scan(OEMBED_INLINE_ID_RE) || !@src.check(/\(/)
|
178
|
+
oembed_id = normalize_oembed_id(@src[1] || alt_text)
|
179
|
+
if @oembed_defs.has_key?(oembed_id)
|
180
|
+
add_oembed(el, @oembed_defs[oembed_id].first, @oembed_defs[oembed_id].last, alt_text)
|
181
|
+
else
|
182
|
+
warning("No oembed definition for oembed ID '#{oembed_id}' found")
|
183
|
+
@src.pos = reset_pos
|
184
|
+
add_text(result)
|
185
|
+
end
|
186
|
+
return
|
187
|
+
end
|
188
|
+
|
189
|
+
# oembed url in parentheses
|
190
|
+
if @src.scan(/\(<(.*?)>/)
|
191
|
+
oembed_url = @src[1]
|
192
|
+
if @src.scan(/\)/)
|
193
|
+
add_oembed(el, oembed_url, nil, alt_text)
|
194
|
+
return
|
195
|
+
end
|
196
|
+
else
|
197
|
+
oembed_url = ''
|
198
|
+
nr_of_brackets = 0
|
199
|
+
while temp = @src.scan_until(OEMBED_PAREN_STOP_RE)
|
200
|
+
oembed_url << temp
|
201
|
+
if @src[2]
|
202
|
+
nr_of_brackets -= 1
|
203
|
+
break if nr_of_brackets == 0
|
204
|
+
elsif @src[1]
|
205
|
+
nr_of_brackets += 1
|
206
|
+
else
|
207
|
+
break
|
208
|
+
end
|
209
|
+
end
|
210
|
+
oembed_url = oembed_url[1..-2]
|
211
|
+
oembed_url.strip!
|
212
|
+
|
213
|
+
if nr_of_brackets == 0
|
214
|
+
add_oembed(el, oembed_url, nil, alt_text)
|
215
|
+
return
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
if @src.scan(OEMBED_INLINE_TITLE_RE)
|
220
|
+
add_oembed(el, oembed_url, @src[2], alt_text)
|
221
|
+
else
|
222
|
+
@src.pos = reset_pos
|
223
|
+
add_text(result)
|
224
|
+
end
|
225
|
+
end
|
226
|
+
define_parser(:oembed, OEMBED_START, '\?\[')
|
227
|
+
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'rexml/parsers/baseparser'
|
2
|
+
|
3
|
+
module Kramdown
|
4
|
+
|
5
|
+
module Converter
|
6
|
+
|
7
|
+
# Converts a Kramdown::Document to HTML.
|
8
|
+
#
|
9
|
+
# You can customize the HTML converter by sub-classing it and overriding the +convert_NAME+
|
10
|
+
# methods. Each such method takes the following parameters:
|
11
|
+
#
|
12
|
+
# [+el+] The element of type +NAME+ to be converted.
|
13
|
+
#
|
14
|
+
# [+indent+] A number representing the current amount of spaces for indent (only used for
|
15
|
+
# block-level elements).
|
16
|
+
#
|
17
|
+
# The return value of such a method has to be a string containing the element +el+ formatted as
|
18
|
+
# HTML element.
|
19
|
+
class Html < Base
|
20
|
+
|
21
|
+
def convert_info_box(el, indent)
|
22
|
+
if el.attr['class']
|
23
|
+
el.attr['class'] = el.attr['class'].include?('test') ?
|
24
|
+
el.attr['class'] :
|
25
|
+
el.attr['class'].split.unshift('test').reject(&:empty?).join(' ')
|
26
|
+
else
|
27
|
+
el.attr['class'] = 'infoBox'
|
28
|
+
end
|
29
|
+
|
30
|
+
"#{' '*indent}<div#{html_attributes(el.attr)}>\n#{inner(el, indent)}#{' '*indent}</div>\n"
|
31
|
+
end
|
32
|
+
|
33
|
+
def convert_oembed(el, indent)
|
34
|
+
provider = el.attr['provider_name']
|
35
|
+
el.attr['provider_name'] = nil
|
36
|
+
el_id = ""
|
37
|
+
if el.attr['html']
|
38
|
+
oembed_html = el.attr['html']
|
39
|
+
el.attr['html'] = nil
|
40
|
+
end
|
41
|
+
if el.attr['id']
|
42
|
+
el_id = " aria-labelledby=\"#{el.attr['id']}\""
|
43
|
+
el.attr['id'] = nil
|
44
|
+
end
|
45
|
+
if el.attr['role'] === "img"
|
46
|
+
"#{' '*indent}<figure%s#{html_attributes(el.attr)}>#{inner(el, indent)}</figure>\n" % el_id
|
47
|
+
else
|
48
|
+
if provider.casecmp "twitter"
|
49
|
+
"#{' '*indent}<figure#{html_attributes(el.attr)}>#{oembed_html}#{inner(el, indent)}</figure>\n"
|
50
|
+
else
|
51
|
+
"#{' '*indent}<figure%s#{html_attributes(el.attr)}>#{oembed_html}#{inner(el, indent)}</figure>\n" % el_id
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def convert_figure(el, indent)
|
57
|
+
"#{' '*indent}<figure#{html_attributes(el.attr)}>#{inner(el, indent)}</figure>\n"
|
58
|
+
end
|
59
|
+
|
60
|
+
def convert_figCaption(el, indent)
|
61
|
+
id = ""
|
62
|
+
if el.attr['id']
|
63
|
+
id = " id=\"#{el.attr['id']}\""
|
64
|
+
el.attr['id'] = nil
|
65
|
+
end
|
66
|
+
"#{' '*indent}<figCaption%s#{html_attributes(el.attr)}>#{escape_html(el.value)}</figCaption>\n" % id
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|