markdown_videos 0.1.1 → 1.0.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 +4 -4
- data/lib/markdown_videos/base.rb +1 -1
- data/lib/markdown_videos/configuration.rb +5 -5
- data/lib/markdown_videos/renderer.rb +18 -32
- data/lib/markdown_videos/services/service_base.rb +137 -0
- data/lib/markdown_videos/services/vimeo_service.rb +15 -0
- data/lib/markdown_videos/services/youtube_service.rb +27 -0
- data/lib/markdown_videos/services.rb +13 -25
- data/lib/markdown_videos/version.rb +1 -1
- metadata +8 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b322a4f32f6b252011b2d3f74c86bbdc11ca30b0
|
4
|
+
data.tar.gz: a1a965e73e842d1e1e873ea3646d69e21e09dbc6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7c7b519ac8d8995cc303ec22de89f2e83acbb6e29364905f5d8967538f09370a08c998c6221499831f1eb180265c77a95896b9d6703a35fbbbca3772838c5177
|
7
|
+
data.tar.gz: e03271030f4aa77d050533300d4a8ee503ec08c44aa8a777b9619d85e638a21a57e0f65f21a13ca9bc2362912fd189dd2295ba202a88730b5ca9eb4dbbf727c4
|
data/lib/markdown_videos/base.rb
CHANGED
@@ -3,9 +3,9 @@ module MarkdownVideos
|
|
3
3
|
class Configuration
|
4
4
|
|
5
5
|
attr_accessor :wrapper,
|
6
|
-
|
6
|
+
:class_name
|
7
7
|
|
8
|
-
# if defined, needs to contain `%s` where HTML
|
8
|
+
# if defined, needs to contain `%s` where rendered HTML element should be included
|
9
9
|
# e.g.: WRAPPER = '<p class="embed-responsive embed-responsive-16by9">%s</p>'.freeze
|
10
10
|
def wrapper
|
11
11
|
@wrapper || nil
|
@@ -16,9 +16,9 @@ module MarkdownVideos
|
|
16
16
|
@wrapper = wrapper
|
17
17
|
end
|
18
18
|
|
19
|
-
# extra
|
20
|
-
def
|
21
|
-
@
|
19
|
+
# extra class_name(s) added to embed HTML element
|
20
|
+
def class_name
|
21
|
+
@class_name || nil
|
22
22
|
end
|
23
23
|
|
24
24
|
end
|
@@ -4,51 +4,37 @@ module MarkdownVideos
|
|
4
4
|
|
5
5
|
class Renderer
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
attr_reader :markdown_text
|
8
|
+
|
9
|
+
def initialize(markdown_text, options = {})
|
10
|
+
@markdown_text = markdown_text
|
9
11
|
@options = {
|
10
12
|
wrapper: MarkdownVideos.defaults.wrapper,
|
11
|
-
|
13
|
+
class_name: MarkdownVideos.defaults.class_name
|
12
14
|
}.merge(options || {})
|
13
15
|
end
|
14
16
|
|
15
17
|
def render
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
@markdown_text.gsub(/!\[([^\]]*)\]\(([^)]+)\)/) do
|
19
|
+
rendered = nil
|
20
|
+
match_data = Regexp.last_match
|
21
|
+
markdown = {
|
22
|
+
alt_text: match_data[1],
|
23
|
+
url: match_data[2]
|
24
|
+
}
|
21
25
|
|
22
|
-
|
26
|
+
service_class = find_service_for(markdown[:url])
|
23
27
|
|
24
|
-
|
25
|
-
|
26
|
-
@string.gsub(values[:regexp]) do |match|
|
27
|
-
match_data = Regexp.last_match
|
28
|
-
id = match_data[3]
|
29
|
-
title = match_data[1]
|
30
|
-
url = Addressable::URI.parse(match_data[2])
|
31
|
-
url_parameters = url.query_values || {}
|
32
|
-
|
33
|
-
html_markup = sprintf(values[:markup],
|
34
|
-
CGI::escapeHTML(title),
|
35
|
-
service_url(service, id, url_parameters),
|
36
|
-
@options[:classname].nil? ? "" : " class=\"#{@options[:classname]}\"")
|
37
|
-
|
38
|
-
if @options[:wrapper].nil?
|
39
|
-
html_markup
|
28
|
+
if service_class
|
29
|
+
service_class.new(markdown[:alt_text], markdown[:url], @options).render
|
40
30
|
else
|
41
|
-
|
31
|
+
match_data.string
|
42
32
|
end
|
43
33
|
end
|
44
34
|
end
|
45
35
|
|
46
|
-
def
|
47
|
-
|
48
|
-
uri = Addressable::URI.parse(url)
|
49
|
-
url_parameters.select! { |k, v| MarkdownVideos::SERVICES[service][:url_parameters].include?(k.to_sym) && (!v.nil? || !v.empty?) } if url_parameters
|
50
|
-
uri.query_values = url_parameters unless url_parameters.nil? || url_parameters.empty?
|
51
|
-
uri.to_s
|
36
|
+
def find_service_for(url)
|
37
|
+
MarkdownVideos::SERVICES.find { |service_class| service_class.support(url) }
|
52
38
|
end
|
53
39
|
|
54
40
|
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
module MarkdownVideos
|
2
|
+
module Services
|
3
|
+
|
4
|
+
class ServiceBase
|
5
|
+
|
6
|
+
attr_accessor :resource_id,
|
7
|
+
:alt_text,
|
8
|
+
:markdown_url,
|
9
|
+
:markdown_url_data,
|
10
|
+
:width,
|
11
|
+
:height,
|
12
|
+
:wrapper,
|
13
|
+
:class_name
|
14
|
+
|
15
|
+
def self.support(markdown_url)
|
16
|
+
markdown_url =~ regexp
|
17
|
+
end
|
18
|
+
|
19
|
+
# URL matcher
|
20
|
+
def self.regexp
|
21
|
+
raise NotImplementedError "#{self.class} should implement #regexp method"
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
def initialize(alt_text, markdown_url, options)
|
26
|
+
@alt_text = alt_text
|
27
|
+
@markdown_url = markdown_url
|
28
|
+
options.each { |option, value| self.send("#{option}=", value) }
|
29
|
+
end
|
30
|
+
|
31
|
+
# URL to be consumed by #to_html
|
32
|
+
def url
|
33
|
+
raise NotImplementedError "#{self.class} should implement #url method"
|
34
|
+
end
|
35
|
+
|
36
|
+
# List of authorized url parameters
|
37
|
+
#
|
38
|
+
# @return [Array<Symbol>] e.g.: [:start]
|
39
|
+
def url_parameters
|
40
|
+
[]
|
41
|
+
end
|
42
|
+
|
43
|
+
def width
|
44
|
+
@width || 500
|
45
|
+
end
|
46
|
+
|
47
|
+
def height
|
48
|
+
@height || 281
|
49
|
+
end
|
50
|
+
|
51
|
+
# @return [String] escaped alternative text given through markdown syntax
|
52
|
+
def alt_text
|
53
|
+
CGI::escapeHTML(@alt_text)
|
54
|
+
end
|
55
|
+
|
56
|
+
# @return [String] resource ID of the service resource rendered base on given URL
|
57
|
+
def resource_id
|
58
|
+
@resource_id ||= markdown_url_data[2]
|
59
|
+
end
|
60
|
+
|
61
|
+
# @return [MatchData] match data from matching URL to service regexp
|
62
|
+
def markdown_url_data
|
63
|
+
@markdown_url_data ||= self.class.regexp.match(markdown_url)
|
64
|
+
end
|
65
|
+
|
66
|
+
# @return [String] service URL to be consumed by #to_html
|
67
|
+
def service_url
|
68
|
+
given_url = Addressable::URI.parse(markdown_url)
|
69
|
+
given_url_parameters = given_url.query_values || {}
|
70
|
+
given_url_parameters.select! { |attribute, value| url_parameters.include?(attribute.to_sym) && (!value.nil? || !value.empty?) }
|
71
|
+
|
72
|
+
service_url = Addressable::URI.parse(url)
|
73
|
+
service_url.query_values = given_url_parameters unless given_url_parameters.nil? || given_url_parameters.empty?
|
74
|
+
service_url.to_s
|
75
|
+
end
|
76
|
+
|
77
|
+
# Default HTML rendering
|
78
|
+
#
|
79
|
+
# @retun [String] markup to render
|
80
|
+
def to_html
|
81
|
+
"<iframe #{html_dom_properties}></iframe>"
|
82
|
+
end
|
83
|
+
|
84
|
+
# Renders the set of HTML attributes
|
85
|
+
#
|
86
|
+
# @return [String] string of dom properties
|
87
|
+
def html_dom_properties
|
88
|
+
html_attributes.map { |k, v| render_param(k, v) }.compact.join(" ")
|
89
|
+
end
|
90
|
+
|
91
|
+
# Default set of HTML attributes for default iframe element
|
92
|
+
#
|
93
|
+
# @return [Hash]
|
94
|
+
def html_attributes
|
95
|
+
{
|
96
|
+
title: alt_text,
|
97
|
+
src: service_url,
|
98
|
+
width: width,
|
99
|
+
height: height,
|
100
|
+
class: class_name,
|
101
|
+
frameborder: "0",
|
102
|
+
webkitallowfullscreen: true,
|
103
|
+
mozallowfullscreen: true,
|
104
|
+
allowfullscreen: true
|
105
|
+
}
|
106
|
+
end
|
107
|
+
|
108
|
+
def render
|
109
|
+
if wrapper
|
110
|
+
sprintf(wrapper, to_html)
|
111
|
+
else
|
112
|
+
to_html
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
private
|
117
|
+
|
118
|
+
# Renders HTML5 attribute, meant to be used with `Hash.map`
|
119
|
+
#
|
120
|
+
# @param attribute [Symbol, String]
|
121
|
+
# @param value [true, String, false] `true` if you want only the attribute. `false`, `nil` or empty String to skip attribute
|
122
|
+
#
|
123
|
+
# @return [String] attribute="value"
|
124
|
+
def render_param(attribute, value)
|
125
|
+
if value == true
|
126
|
+
attribute.to_s
|
127
|
+
elsif !value || value.to_s.empty?
|
128
|
+
nil
|
129
|
+
else
|
130
|
+
"#{attribute}=\"#{value}\""
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module MarkdownVideos::Services
|
2
|
+
|
3
|
+
class VimeoService < ServiceBase
|
4
|
+
|
5
|
+
def self.regexp
|
6
|
+
/(https?:\/\/(?:(?:player\.)?vimeo.com\/(?:video\/)?)([0-9]{4,16})\??([\w\-\=]+)?)/
|
7
|
+
end
|
8
|
+
|
9
|
+
def url
|
10
|
+
"https://player.vimeo.com/video/#{resource_id}"
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module MarkdownVideos::Services
|
2
|
+
|
3
|
+
class YoutubeService < ServiceBase
|
4
|
+
|
5
|
+
def self.regexp
|
6
|
+
/(https?:\/\/(?:youtu.be\/|www.youtube.com\/(?:watch\?v=|embed\/))([\w\-]{4,16})\??([\w\-\=]+)?)/
|
7
|
+
end
|
8
|
+
|
9
|
+
def width
|
10
|
+
560
|
11
|
+
end
|
12
|
+
|
13
|
+
def height
|
14
|
+
315
|
15
|
+
end
|
16
|
+
|
17
|
+
def url
|
18
|
+
"https://www.youtube.com/embed/#{resource_id}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def url_parameters
|
22
|
+
[:start]
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -1,33 +1,21 @@
|
|
1
1
|
module MarkdownVideos
|
2
2
|
|
3
|
-
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
# regexp: Regexp must capture in 1) title, 2) full url and 3) video id
|
7
|
-
# markup: HTML markup rendered with first %s being altertive text and second %s being the video URL (iFrame src)
|
8
|
-
# and third %s being class attribute declaration location (make sure there is only one space after, not before)
|
9
|
-
# url: URL of service included in the markup, with first %s corresponding to video's ID
|
10
|
-
# url_parameters: List of authorized URL parameters
|
11
|
-
#
|
3
|
+
# This file `require` the ServiceBase class
|
4
|
+
# and all `_service` files present in services folder
|
12
5
|
|
13
|
-
|
6
|
+
require_relative "services/service_base"
|
14
7
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
markup: '<iframe width="560" height="315" title="%s" src="%s"%s frameborder="0" allowfullscreen></iframe>',
|
19
|
-
url: "https://www.youtube.com/embed/%s",
|
20
|
-
url_parameters: [:start]
|
21
|
-
},
|
8
|
+
Dir[File.expand_path("../services/*_service.rb", __FILE__)].each do |path|
|
9
|
+
require path
|
10
|
+
end
|
22
11
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
url: "https://player.vimeo.com/video/%s",
|
28
|
-
url_parameters: []
|
29
|
-
}
|
12
|
+
# Build a static list of available Service classes
|
13
|
+
service_classes = MarkdownVideos::Services.constants.select do |class_name|
|
14
|
+
MarkdownVideos::Services.const_get(class_name).is_a?(Class) && class_name =~ /Service$/
|
15
|
+
end
|
30
16
|
|
31
|
-
|
17
|
+
SERVICES = service_classes.map do |class_name|
|
18
|
+
Object.const_get("MarkdownVideos::Services::#{class_name}")
|
19
|
+
end
|
32
20
|
|
33
21
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: markdown_videos
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Capripot
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-03-
|
11
|
+
date: 2016-03-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|
@@ -52,7 +52,7 @@ dependencies:
|
|
52
52
|
- - ~>
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '3.4'
|
55
|
-
description: Markdown syntax
|
55
|
+
description: Markdown syntax parser to render embed services
|
56
56
|
email: capripot@gmail.com
|
57
57
|
executables: []
|
58
58
|
extensions: []
|
@@ -63,6 +63,9 @@ files:
|
|
63
63
|
- lib/markdown_videos/configuration.rb
|
64
64
|
- lib/markdown_videos/renderer.rb
|
65
65
|
- lib/markdown_videos/services.rb
|
66
|
+
- lib/markdown_videos/services/service_base.rb
|
67
|
+
- lib/markdown_videos/services/vimeo_service.rb
|
68
|
+
- lib/markdown_videos/services/youtube_service.rb
|
66
69
|
- lib/markdown_videos/version.rb
|
67
70
|
homepage: https://github.com/capripot/markdown_videos
|
68
71
|
licenses:
|
@@ -76,7 +79,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
76
79
|
requirements:
|
77
80
|
- - ! '>='
|
78
81
|
- !ruby/object:Gem::Version
|
79
|
-
version: '2.
|
82
|
+
version: '2.1'
|
80
83
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
84
|
requirements:
|
82
85
|
- - ! '>='
|
@@ -88,6 +91,6 @@ rubygems_version: 2.2.3
|
|
88
91
|
signing_key:
|
89
92
|
specification_version: 4
|
90
93
|
summary: A gem that provides ability to parse any string containing image markdown
|
91
|
-
syntax into appropriate
|
94
|
+
syntax into appropriate HTML embed service based on URL.
|
92
95
|
test_files: []
|
93
96
|
has_rdoc: false
|