ems 0.1.0 → 0.1.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/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
|